diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/SSH_TEST.yml b/.github/workflows/SSH_TEST.yml new file mode 100644 index 0000000..f60ff7d --- /dev/null +++ b/.github/workflows/SSH_TEST.yml @@ -0,0 +1,20 @@ +name: SSH Connection Test + +on: + workflow_dispatch: + +jobs: + test-ssh-connection: + runs-on: ubuntu-latest + steps: + - name: Setup SSH Keys and Test SSH Connection + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts + ssh -o BatchMode=yes -o ConnectTimeout=5 ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} "echo SSH connection successful" + env: + SERVER_IP: ${{ secrets.SERVER_IP }} + SERVER_USER: ${{ secrets.SERVER_USER }} + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml new file mode 100644 index 0000000..6cce596 --- /dev/null +++ b/.github/workflows/maven-publish.yml @@ -0,0 +1,62 @@ +name: Public release +# +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + type: choice + options: + - info + - warning + - debug +permissions: + contents: write +jobs: + build-and-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # To ensure tags are fetched as well + token: ${{ secrets.GITHUB_TOKEN }} # Użyj GITHUB_TOKEN do checkout + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build with Maven and Auto-Versioning + run: mvn -B build-helper:parse-version versions:set versions:commit package --file pom.xml + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: minecraft-plugin + path: target/*.jar + - name: Extract version and artifact name + id: extract_info + run: | + JAR_NAME=$(ls target/*.jar) + ARTIFACT_NAME=$(basename $JAR_NAME) + VERSION=$(echo $ARTIFACT_NAME | grep -oP '(?<=-)\d+\.\d+\.\d+(?=-SNAPSHOT)') + echo "::set-output name=version::v$VERSION" + echo "::set-output name=artifact_name::$ARTIFACT_NAME" + - name: Create and Push Tag + run: | + git config user.name "GitHub Actions" + git config user.email "github-actions@users.noreply.github.com" + git tag ${{ steps.extract_info.outputs.version }} + git push https://x-access-token:${{ secrets.BE_ACCESS_TOKEN }}@github.com/${{ github.repository }} ${{ steps.extract_info.outputs.version }} + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + name: ${{ steps.extract_info.outputs.artifact_name }} + tag_name: ${{ steps.extract_info.outputs.version }} + files: target/*.jar + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..d924bd2 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,142 @@ +name: Java CI with Maven, Auto-Versioning, and Release +# +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + type: choice + options: + - info + - warning + - debug +permissions: + contents: write +jobs: + build-and-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # To ensure tags are fetched as well + token: ${{ secrets.GITHUB_TOKEN }} # Użyj GITHUB_TOKEN do checkout + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build with Maven and Auto-Versioning + run: mvn -B build-helper:parse-version versions:set versions:commit package --file pom.xml + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: minecraft-plugin + path: target/*.jar + - name: Extract version and artifact name + id: extract_info + run: | + JAR_NAME=$(ls target/*.jar) + ARTIFACT_NAME=$(basename $JAR_NAME) + VERSION=$(echo $ARTIFACT_NAME | grep -oP '(?<=-)\d+\.\d+\.\d+(?=-SNAPSHOT)') + echo "::set-output name=version::v$VERSION" + echo "::set-output name=artifact_name::$ARTIFACT_NAME" + - name: Create and Push Tag + run: | + git config user.name "GitHub Actions" + git config user.email "github-actions@users.noreply.github.com" + git tag ${{ steps.extract_info.outputs.version }} + git push https://x-access-token:${{ secrets.BE_ACCESS_TOKEN }}@github.com/${{ github.repository }} ${{ steps.extract_info.outputs.version }} + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + name: ${{ steps.extract_info.outputs.artifact_name }} + tag_name: ${{ steps.extract_info.outputs.version }} + files: target/*.jar + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + backup-plugins: + needs: build-and-release + runs-on: ubuntu-latest + steps: + - name: Setup SSH Keys + run: | + mkdir -p ~/.ssh + echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts + env: + SERVER_IP: ${{ secrets.SERVER_IP }} + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Test SSH Connection + run: | + echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh -o BatchMode=yes -o ConnectTimeout=5 $SERVER_USER@$SERVER_IP "echo SSH connection successful" + env: + SERVER_IP: ${{ secrets.SERVER_IP }} + SERVER_USER: ${{ secrets.SERVER_USER }} + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Backup Current Plugins + run: | + DATE=$(date +%Y%m%d-%H%M%S) + BACKUP_FILE="minecraft-plugins-backup-$DATE.tgz" + ssh $SERVER_USER@$SERVER_IP "tar czvf $PLUGINS_BACKUP_PATH/$BACKUP_FILE -C $SERVER_PATH ." + env: + SERVER_IP: ${{ secrets.SERVER_IP }} + SERVER_USER: ${{ secrets.SERVER_USER }} + SERVER_PATH: ${{ secrets.SERVER_PATH }} + PLUGINS_BACKUP_PATH: ${{ secrets.PLUGINS_BACKUP_PATH }} + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + + + deploy-to-server: + needs: [build-and-release, backup-plugins] + runs-on: ubuntu-latest + steps: + - name: Setup SSH directory and accept server host key + run: | + mkdir -p ~/.ssh + ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts + env: + SERVER_IP: ${{ secrets.SERVER_IP }} + + - name: Download Artifact + uses: actions/download-artifact@v3 + with: + name: minecraft-plugin + - name: List downloaded files + run: | + ls -R + # Lub, aby znaleźć wszystkie pliki JAR w bieżącym katalogu roboczym i jego podkatalogach: + find . -name "*.jar" + + - name: Remove Previous Plugin Versions from Server + env: + SERVER_IP: ${{ secrets.SERVER_IP }} + SERVER_USER: ${{ secrets.SERVER_USER }} + SERVER_PATH: ${{ secrets.SERVER_PATH }} + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh $SERVER_USER@$SERVER_IP "rm -f $SERVER_PATH/BetterElo-*.jar" + + + - name: Deploy JAR to Server + env: + SERVER_IP: ${{ secrets.SERVER_IP }} + SERVER_USER: ${{ secrets.SERVER_USER }} + SERVER_PATH: ${{ secrets.SERVER_PATH }} + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + scp ./BetterElo-*.jar $SERVER_USER@$SERVER_IP:$SERVER_PATH + if: ${{ always() }} diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml index 0d03cd8..de3145c 100644 --- a/.idea/jarRepositories.xml +++ b/.idea/jarRepositories.xml @@ -1,16 +1,31 @@ + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 236d270..cdfdf8b 100644 --- a/README.md +++ b/README.md @@ -1,80 +1,90 @@ # BetterElo +https://www.spigotmc.org/resources/betterelo.114648/ + Minecraft PvP Elo rank system Plugin created by Grzybol Minecraft version 1.18.2+ Dependencies: PlaceholderAPI, BetterRanks -## Player Commands - -There are no special permissions required to use the following Player commands. - -### BetterElo commands: - -- `/be` - - [ENG] Returns your ranking info. - - [PL] Zwraca info o Twoim rankingu - -- `/be ` - - [ENG] Returns ranking info about the given player. - - [PL] Zwraca info rankingu danego gracza. - -- `/be info` - - [ENG] Returns plugin info. - - [PL] Zwraca info o pluginie. - -- `/be top` - - [ENG] Returns ranking info about the player at the given position. - - [PL] Zwraca info o graczu na danym miejscu w rankingu. - -- `/be top10` - - [ENG] Returns top 10 players from the ranking. - - [PL] Zwraca info o top 10 graczy rankingu. - -- `/be claim` - - [ENG] Claim your rewards! Remember to empty your inventory!! - - [PL] Odbierz swoje nagrody! Pamiętaj wyczyścić ekwipunek przed!! - -- `/be timeleft` - - [ENG] Returns time left to the giveaway. - - [PL] Zwraca pozostały czas do rozdania nagród. - -- `/be daily` - - [ENG] Returns top 10 daily ranking. - - [PL] Zwraca info o top 10 rankingu dziennego. - -- `/be weekly` - - [ENG] Returns top 10 weekly ranking. - - [PL] Zwraca info o top 10 rankingu tygodniowego. - -- `/be monthly` - - [ENG] Returns top 10 monthly ranking. - - [PL] Zwraca info o top 10 rankingu miesięcznego. - -## Only for OP - -- `/be setrewards` - - Opens rewards GUI configuration for all timed rankings (daily, weekly, monthly) and positions (top1, top2, top3, top4-10). IMPORTANT! "Reset" button is resetting the specified ranking type timer without handing out prizes. "Redeem" is both resetting the timer and handing out prizes. - -- `/be ban ` -- `/be add
` -- `/be sub
` - -## Placeholders - -**IMPORTANT!! I hardcoded 10s interval for checking placeholders - lemme know if you want it to be configurable in config file** -- `%be_player%` returns the player's main ranking points -- `%be_player_daily%` returns the player's daily ranking points -- `%be_player_weekly%` returns the player's weekly ranking points -- `%be_player_monthly%` returns the player's monthly ranking points -- `%be_rank%` returns the player's main ranking -- `%be_rank_daily%` returns the player's daily ranking -- `%be_rank_weekly%` returns the player's weekly ranking -- `%be_rank_monthly%` returns the player's monthly ranking -- `%be_player_top%` returns the player's nickname at position `` in ranking -- `%be_points_top%` returns the player's points at position `` in ranking -- `%be_daily_tl%` returns time left on daily rewards timer - automatically converts to D-M-S format -- `%be_weekly_tl%` returns time left on weekly rewards timer - automatically converts to D-M-S format -- `%be_monthly_tl%` returns time left on monthly rewards timer - automatically converts to D-M-S format +## Plugin Commands + +### Player Commands +- **/be** - Returns your ranking information. +- **/be ``** - Returns ranking information about the specified player. +- **/be info** - Returns information about the plugin. +- **/be top ``** - Returns ranking information about the player at the specified position. +- **/be top10** - Returns information about the top 10 players in the ranking. +- **/be claim** - Claim your rewards! Remember to empty your equipment before claiming!! +- **/be timeleft** - Returns the remaining time until the giveaway. +- **/be daily** - Returns information about the top 10 daily ranking. +- **/be weekly** - Returns information about the top 10 weekly ranking. +- **/be monthly** - Returns information about the top 10 monthly ranking. +- **/be event** - Returns information about the event. +- **/be reroll** - Opens the Re-Roll GUI for AvgDmg bonus items. + +### Administrator Commands +- **/be setrewards** - Opens a GUI for changing the rewards. +- **/be reload** - Reloads the config file. +- **/be ban ``** - Resets the player's ranking to 1000 and redistributes remaining points to victims. +- **/be add ` `** - Adds points to the specified player in a specific ranking (main, daily, weekly, monthly). +- **/be sub ` `** - Subtracts points from the specified player in a specific ranking. +- **/be startevent ` `** - Sets up the duration and time unit for an event. +- **/be stopevent** - Stops the current event (if active). +- **/be holo ``** - Creates a hologram at your position. +- **/be holo delete ``** - Deletes the specified hologram. +- **/be antyweb ``** - Creates an anti-web effect with the given radius. +- **/be firework ``** - Creates an Infinite Firework with the given power. +- **/be flamethrower ` `** - Adds a Flamethrower effect. +- **/be zephyr ``** - Adds a Zephyr effect. +- **/be addspawner ` `** - Creates a custom mob spawner. +- **/be droptable ``** - Opens a GUI to create a new drop table. +- **/be spawnmob ` `** - Spawns the specified custom mob. +- **/be enchantitem** - Gives you 1x Enchant Item. +- **/be forcespawn ``** - Forces a respawn of the specified spawner. + +## PlaceholderAPI Integration + +This plugin integrates with PlaceholderAPI to provide various placeholders that can be used in other plugins or parts of your server setup. Here's a list of available placeholders and their descriptions: + +### General Placeholders +- **%be_player%** - Returns the main ranking points of the player. +- **%be_rank%** - Returns the main rank of the player. + +### Time Left Placeholders +- **%be_daily_tl%** - Returns the remaining time for daily rewards. +- **%be_weekly_tl%** - Returns the remaining time for weekly rewards. +- **%be_monthly_tl%** - Returns the remaining time for monthly rewards. +- **%be_event_tl%** - Returns the remaining time for the current event, if active. + +### Player Specific Ranking Points +- **%be_player_daily%** - Returns the daily ranking points of the player. +- **%be_player_weekly%** - Returns the weekly ranking points of the player. +- **%be_player_monthly%** - Returns the monthly ranking points of the player. +- **%be_player_event%** - Returns the event ranking points of the player, if an event is active. + +### Player Specific Ranks +- **%be_rank_daily%** - Returns the daily rank of the player. +- **%be_rank_weekly%** - Returns the weekly rank of the player. +- **%be_rank_monthly%** - Returns the monthly rank of the player. +- **%be_rank_event%** - Returns the event rank of the player, if an event is active. + +### Top Player Placeholders +- **%be_points_top{n}%** - Returns the points of the player at the nth position in the main ranking. +- **%be_player_top{n}%** - Returns the name of the player at the nth position in the main ranking. + +### Daily, Weekly, Monthly, and Event Specific +- **%be_daily_points_top{n}%** - Returns the points of the player at the nth position in the daily ranking. +- **%be_weekly_points_top{n}%** - Returns the points of the player at the nth position in the weekly ranking. +- **%be_monthly_points_top{n}%** - Returns the points of the player at the nth position in the monthly ranking. +- **%be_event_points_top{n}%** - Returns the points of the player at the nth position in the event ranking, if an event is active. + +### Miscellaneous +- **%be_daily_player_top{n}%** - Returns the name of the player at the nth position in the daily ranking. +- **%be_weekly_player_top{n}%** - Returns the name of the player at the nth position in the weekly ranking. +- **%be_monthly_player_top{n}%** - Returns the name of the player at the nth position in the monthly ranking. +- **%be_event_player_top{n}%** - Returns the name of the player at the nth position in the event ranking, if an event is active. + +These placeholders can be used to display dynamic content related to rankings and events within your server. Ensure that PlaceholderAPI is installed and configured properly to utilize these placeholders. diff --git a/pom.xml b/pom.xml index 39a762b..f37732b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ betterbox.mine.game BetterElo - 3.1.53-SNAPSHOT + 4.9.1-SNAPSHOT jar BetterElo @@ -18,6 +18,32 @@ + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + + org.bstats + + betterbox.mine.game.betterelo + + + + + + package + + shade + + + false + + + + + org.apache.maven.plugins maven-jar-plugin @@ -30,6 +56,7 @@ + org.apache.maven.plugins maven-compiler-plugin @@ -40,22 +67,9 @@ - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - package - - shade - - - false - - - - + + + org.codehaus.mojo @@ -90,6 +104,14 @@ + + jitpack.io + https://jitpack.io + + + codemc-repo + https://repo.codemc.io/repository/maven-public/ + papermc-repo https://repo.papermc.io/repository/maven-public/ @@ -102,30 +124,76 @@ placeholderapi https://repo.extendedclip.com/content/repositories/placeholderapi/ + + sk89q-repo + https://maven.enginehub.org/repo/ + + + + + me.filoghost.holographicdisplays + holographicdisplays-api + 3.0.0 + provided + + net.kyori adventure-platform-bukkit 4.3.2 + org.eclipse.jetty jetty-server 9.4.43.v20210629 + io.papermc.paper paper-api 1.18.2-R0.1-SNAPSHOT provided + me.clip placeholderapi 2.11.4 provided + + + com.sk89q.worldedit + worldedit-bukkit + 7.2.0 + provided + + + + + com.sk89q.worldguard + worldguard-bukkit + 7.0.4 + provided + + + + org.bstats + bstats-bukkit + 3.0.2 + compile + + + + com.github.Grzybol + ElasticBuffer + v1.1.87 + provided + + diff --git a/qodana.yaml b/qodana.yaml new file mode 100644 index 0000000..9481a5b --- /dev/null +++ b/qodana.yaml @@ -0,0 +1,31 @@ +#-------------------------------------------------------------------------------# +# Qodana analysis is configured by qodana.yaml file # +# https://www.jetbrains.com/help/qodana/qodana-yaml.html # +#-------------------------------------------------------------------------------# +version: "1.0" + +#Specify inspection profile for code analysis +profile: + name: qodana.starter + +#Enable inspections +#include: +# - name: + +#Disable inspections +#exclude: +# - name: +# paths: +# - + +projectJDK: corretto-17 #(Applied in CI/CD pipeline) + +#Execute shell command before Qodana execution (Applied in CI/CD pipeline) +#bootstrap: sh ./prepare-qodana.sh + +#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) +#plugins: +# - id: #(plugin id can be found at https://plugins.jetbrains.com) + +#Specify Qodana linter for analysis (Applied in CI/CD pipeline) +linter: jetbrains/qodana-jvm-community:latest diff --git a/src/main/java/betterbox/mine/game/betterelo/BetterElo.java b/src/main/java/betterbox/mine/game/betterelo/BetterElo.java index adacc6e..d6a2f04 100644 --- a/src/main/java/betterbox/mine/game/betterelo/BetterElo.java +++ b/src/main/java/betterbox/mine/game/betterelo/BetterElo.java @@ -1,21 +1,59 @@ package betterbox.mine.game.betterelo; +import com.sk89q.worldguard.WorldGuard; +import com.sk89q.worldguard.protection.flags.Flags; +import me.clip.placeholderapi.libs.kyori.adventure.platform.facet.Facet; +import org.betterbox.elasticBuffer.ElasticBuffer; +import org.betterbox.elasticBuffer.ElasticBufferAPI; +import org.bstats.bukkit.Metrics; import org.bukkit.*; +import org.bukkit.attribute.Attribute; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.title.Title; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; + +import java.io.Console; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.text.DecimalFormat; +import java.time.Duration; import java.util.*; import java.util.concurrent.TimeUnit; +import com.sk89q.worldguard.protection.flags.Flag; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.flags.registry.FlagConflictException; +import com.sk89q.worldguard.protection.flags.registry.FlagRegistry; +import org.checkerframework.checker.units.qual.C; + public final class BetterElo extends JavaPlugin { + HashMap mobTasks = new HashMap<>(); + private static BetterElo instance; + public ElasticBuffer elasticBuffer; private PluginLogger pluginLogger; private DataManager dataManager; + public final Map customMobsMap = new HashMap<>(); + public int eventDuration; + public boolean isEventEnabled; + public String eventUnit; private Placeholders placeholders; + private CustomMobs customMobs; + private CustomMobsFileManager customMobsFileManager; private CheaterCheckScheduler cheaterCheckScheduler; private BetterRanksCheaters betterRanksCheaters; private GuiManager guiManager; @@ -27,12 +65,47 @@ public final class BetterElo extends JavaPlugin { private PlayerKillDatabase PKDB; private BetterEloCommand betterEloCommand; private ExtendedConfigManager configManager; - private final Map rewardStates = new HashMap<>(); + public Map rewardStates = new HashMap<>(); + public boolean useHolographicDisplays; + //public static final Flag NO_ELO_FLAG = new StateFlag("noElo", false); + public static StateFlag IS_ELO_ALLOWED; + private String folderPath; + public NamespacedKey mobDefenseKey,mobDamageKey,averageDamageKey; + private boolean isElasticEnabled=false; + public Utils utils; + @Override + public void onLoad() { + getLogger().info("Registering custom WorldGuard flags."); + FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); + try { + StateFlag allowElo = new StateFlag("allowElo", false); + registry.register(allowElo); + IS_ELO_ALLOWED = allowElo; // only set our field if there was no error + getLogger().info("Custom WorldGuard flags registered."); + } catch (Exception e) { + getLogger().info("NoElo flag registration exception: " + e); + } + } + @Override public void onEnable() { + int pluginId = 22747; // Zamień na rzeczywisty ID twojego pluginu na bStats + Metrics metrics = new Metrics(this, pluginId); + this.mobDefenseKey = new NamespacedKey(this, "mob_defense"); + this.mobDamageKey = new NamespacedKey(this, "mob_damage"); + this.averageDamageKey = new NamespacedKey(this, "average_damage"); + instance = this; + createPluginFolders(); + createExampleDropTablesFiles(); + createExampleDropsFiles(); + createExampleMobsFiles(); + createExampleConfigFiles(); // Inicjalizacja PluginLoggera Set defaultLogLevels = EnumSet.of(PluginLogger.LogLevel.INFO,PluginLogger.LogLevel.DEBUG, PluginLogger.LogLevel.WARNING, PluginLogger.LogLevel.ERROR); - pluginLogger = new PluginLogger(getDataFolder().getAbsolutePath(), defaultLogLevels,this); + folderPath = getDataFolder().getAbsolutePath(); + pluginLogger = new PluginLogger(folderPath, defaultLogLevels,this,this); + loadElasticBuffer(); + Utils utils = new Utils(this,pluginLogger); pluginLogger.log(PluginLogger.LogLevel.INFO,"BetterElo: onEnable: Starting BetterElo plugin"); pluginLogger.log(PluginLogger.LogLevel.INFO,"Plugin created by "+this.getDescription().getAuthors()); pluginLogger.log(PluginLogger.LogLevel.INFO,"Plugin version "+this.getDescription().getVersion()); @@ -58,8 +131,7 @@ public void onEnable() { fileRewardManager = new FileRewardManager(this, pluginLogger); // Jeśli FileRewardManager wymaga inicjalizacji, dodaj tutaj // Inicjalizacja GuiManager - guiManager = new GuiManager(fileRewardManager, pluginLogger, this, dataManager); - getServer().getPluginManager().registerEvents(guiManager, this); + // Inicjalizacja Placeholders placeholders = new Placeholders(dataManager, this); if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) { @@ -68,13 +140,24 @@ public void onEnable() { } else { pluginLogger.log(PluginLogger.LogLevel.WARNING,"BetterElo: onEnable: Warning: PlaceholderAPI not found, placeholders will NOT be available."); } + + + + customMobsFileManager = new CustomMobsFileManager(folderPath,this, pluginLogger); + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: calling customMobsFileManager.loadSpawners()"); + customMobsFileManager.loadSpawners(); + customMobs = new CustomMobs(pluginLogger,this,customMobsFileManager, fileRewardManager,this ); + pluginLogger.log(PluginLogger.LogLevel.INFO,"Starting spawners scheduler..."); + customMobs.startSpawnerScheduler(); + + guiManager = new GuiManager(fileRewardManager, pluginLogger, this, dataManager, customMobsFileManager, customMobs, this,utils); // Rejestracja komendy betterRanksCheaters = new BetterRanksCheaters(this,pluginLogger); CheaterCheckScheduler cheaterCheckScheduler = new CheaterCheckScheduler(this, betterRanksCheaters, getServer().getScheduler(), pluginLogger); // Rejestracja listenera eventów - event = new Event(dataManager, pluginLogger,this,betterRanksCheaters,configManager); + event = new Event(dataManager, pluginLogger,this,betterRanksCheaters,configManager,this,customMobs,fileRewardManager,guiManager,customMobsFileManager,utils); getServer().getPluginManager().registerEvents(event, this); - getCommand("be").setExecutor(new BetterEloCommand(this, dataManager, guiManager, pluginLogger, this, configManager,event,PKDB)); + getCommand("be").setExecutor(new BetterEloCommand(this, dataManager, guiManager, pluginLogger, this, configManager,event,PKDB, customMobs, customMobsFileManager)); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: Plugin BetterElo został włączony pomyślnie."); // Inicjalizacja RewardManagera (kod z konstruktora RewardManager) rewardStates.put("daily", true); @@ -82,18 +165,18 @@ public void onEnable() { rewardStates.put("monthly", true); // Inicjalizacja nagród i ich harmonogramów (kod z metody onEnable z klasy RewardManager) loadRewards(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: Planowanie nagród dziennych..."); + pluginLogger.log(PluginLogger.LogLevel.INFO,"Scheduling daily ranking rewards..."); scheduleRewards("daily", TimeUnit.DAYS.toMillis(1), false); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: Planowanie nagród tygodniowych..."); + pluginLogger.log(PluginLogger.LogLevel.INFO,"Scheduling weekly ranking rewards..."); scheduleRewards("weekly", TimeUnit.DAYS.toMillis(7), false); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: Planowanie nagród miesięcznych..."); + pluginLogger.log(PluginLogger.LogLevel.INFO,"Scheduling monthly ranking rewards..."); scheduleRewards("monthly", 0, true); - File dataFolder = this.getDataFolder(); + File dataFolder = new File(getDataFolder(),"data"); File databaseFile = new File(dataFolder, "database.txt"); - WebRankingServer server = new WebRankingServer(databaseFile.getAbsolutePath(), 39378,pluginLogger); + //WebRankingServer server = new WebRankingServer(databaseFile.getAbsolutePath(), 39378,pluginLogger); - server.startServer(); + //server.startServer(); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: web ranking server started"); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: starting ChatNotifier every 30min"); @@ -102,6 +185,7 @@ public void onEnable() { // Uzyskaj dostęp do loggera pluginu java.util.logging.Logger logger = this.getLogger(); + // Użyj loggera do rejestrowania wiadomości logger.info("[BetterElo] Running"); logger.info("[BetterElo] Author " + this.getDescription().getAuthors()); @@ -112,21 +196,218 @@ public void onEnable() { pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: calling cheaterCheckScheduler.startScheduler()"); cheaterCheckScheduler.startScheduler(); + pluginLogger.log(PluginLogger.LogLevel.INFO,"Checking HolographicDisplays..."); + useHolographicDisplays = Bukkit.getPluginManager().isPluginEnabled("HolographicDisplays"); + if(useHolographicDisplays){ + pluginLogger.log(PluginLogger.LogLevel.INFO,"HolographicDisplays found."); + }else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING,"HolographicDisplays not found! Some feature might not be available"); + } + killAllCustomMobs(); + + checkMobsExistence(); + + + ElasticBuffer elasticBuffer = ElasticBuffer.getInstance(); // Załóżmy, że ElasticBuffer udostępnia singleton. + ElasticBufferAPI api = new ElasticBufferAPI(elasticBuffer); + api.log("Test log sent using ElasticBufferAPI from BetterElo","INFO","BetterElo",null); + //api.log + + } + public void createPluginFolders() { + // Lista folderów do utworzenia + String[] folders = {"customDrops", "customDropTables", "customMobs", "logs","data"}; + + // Tworzenie folderów, jeśli nie istnieją + for (String folderName : folders) { + File folder = new File(getDataFolder(), folderName); + if (!folder.exists()) { + folder.mkdirs(); // Metoda mkdirs() tworzy folder oraz wszystkie wymagane nadrzędne foldery + getLogger().severe("Catalogs "+folders.toString()+" created!"); + } + } + } + private void createExampleDropsFiles() { + // Tworzenie docelowego folderu, jeśli nie istnieje + File customFolder = new File(getDataFolder(), "customDrops"); + if (!customFolder.exists()) { + customFolder.mkdirs(); + } + + // Lokalizacja docelowego pliku konfiguracyjnego + String[] fileNames = {"ExampleDropTable_item0.yml", "ExampleDropTable_item1.yml", "ExampleDropTable_item2.yml", "ExampleDropTable_item3.yml", "ExampleDropTable_item4.yml", "ExampleDropTable_item5.yml"}; // Dodaj więcej nazw plików jak potrzebujesz + + for (String fileName : fileNames) { + File file = new File(customFolder, fileName); + if (!file.exists()) { + try (InputStream in = getResource("customDrops/" + fileName)) { + if (in == null) { + getLogger().severe("Resource 'customDrops/" + fileName + "' not found."); + continue; + } + Files.copy(in, file.toPath()); + } catch (IOException e) { + getLogger().severe("Could not save " + fileName + " to " + file + ": " + e.getMessage()); + } + } + } + } + private void createExampleDropTablesFiles() { + // Tworzenie docelowego folderu, jeśli nie istnieje + File customFolder = new File(getDataFolder(), "customDropTables"); + if (!customFolder.exists()) { + customFolder.mkdirs(); + } + + // Lokalizacja docelowego pliku konfiguracyjnego + String[] fileNames = {"ExampleDropTable.yml"}; + + for (String fileName : fileNames) { + File file = new File(customFolder, fileName); + if (!file.exists()) { + try (InputStream in = getResource("customDropTables/" + fileName)) { + if (in == null) { + getLogger().severe("Resource 'customDropTables/" + fileName + "' not found."); + continue; + } + Files.copy(in, file.toPath()); + } catch (IOException e) { + getLogger().severe("Could not save " + fileName + " to " + file + ": " + e.getMessage()); + } + } + } + } + private void createExampleConfigFiles() { + // Tworzenie docelowego folderu, jeśli nie istnieje + File customFolder = getDataFolder(); + if (!customFolder.exists()) { + customFolder.mkdirs(); + } + // Lokalizacja docelowego pliku konfiguracyjnego + String[] fileNames = {"config.yml"}; + + for (String fileName : fileNames) { + File file = new File(customFolder, fileName); + if (!file.exists()) { + try (InputStream in = getResource(fileName)) { + if (in == null) { + getLogger().severe(fileName + "' not found."); + continue; + } + Files.copy(in, file.toPath()); + } catch (IOException e) { + getLogger().severe("Could not save " + fileName + " to " + file + ": " + e.getMessage()); + } + } + } } + private void createExampleMobsFiles() { + // Tworzenie docelowego folderu, jeśli nie istnieje + File customFolder = new File(getDataFolder(), "customMobs"); + if (!customFolder.exists()) { + customFolder.mkdirs(); + } + + // Lokalizacja docelowego pliku konfiguracyjnego + String[] fileNames = {"Marksman.yml","Panda.yml"}; + + for (String fileName : fileNames) { + File file = new File(customFolder, fileName); + if (!file.exists()) { + try (InputStream in = getResource("customMobs/" + fileName)) { + if (in == null) { + getLogger().severe("Resource 'customMobs/" + fileName + "' not found."); + continue; + } + Files.copy(in, file.toPath()); + } catch (IOException e) { + getLogger().severe("Could not save " + fileName + " to " + file + ": " + e.getMessage()); + } + } + } + } + + @Override public void onDisable() { + saveCustomMobsToCache(); + removeAndKillAllCustomMobs(); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onDisable: Zapisywanie danych przed wyłączeniem pluginu..."); dataManager.saveDataToFile(); dataManager.saveDataToFileDaily(); dataManager.saveDataToFileWeekly(); dataManager.saveDataToFileMonthly(); + dataManager.saveDataToFileEvent(); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onDisable: Plugin BetterElo został wyłączony."); // Wyłączanie nagród (kod z metody onDisable z klasy RewardManager) if (dailyTask != null) dailyTask.cancel(); if (weeklyTask != null) weeklyTask.cancel(); if (monthlyTask != null) monthlyTask.cancel(); + + //customMobs.stopSpawnerScheduler(); + } + public void saveCustomMobsToCache() { + List mobNames = new ArrayList<>(); + for (World world : Bukkit.getWorlds()) { + for (Entity entity : world.getEntities()) { + if (entity.hasMetadata("CustomMob")) { + String customName = entity.getName(); + if (!customName.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.saveCustomMobsToCache saving entity "+customName); + mobNames.add(customName); + } + } + } + } + + File cacheFile = new File(getDataFolder(), "customMobsCache.yml"); + YamlConfiguration cacheConfig = YamlConfiguration.loadConfiguration(cacheFile); + cacheConfig.set("customMobNames", mobNames); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.saveCustomMobsToCache data to save: " + mobNames); + + try { + cacheConfig.save(cacheFile); + } catch (IOException e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterElo.saveCustomMobsToCache IOException: " + e.getMessage()); + } } + public void loadAndKillCustomMobsFromCache() { + File cacheFile = new File(getDataFolder(), "customMobsCache.yml"); + YamlConfiguration cacheConfig = YamlConfiguration.loadConfiguration(cacheFile); + List mobNames = cacheConfig.getStringList("customMobNames"); + int killedMobsCount = 0; + + if (mobNames == null || mobNames.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.saveCustomMobsToCache cache is empty!"); + return; + } // Jeśli nie ma danych, zakończ metodę + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.saveCustomMobsToCache mobs from cache: "+mobNames); + for (World world : Bukkit.getWorlds()) { + for (Entity entity : world.getEntities()) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.saveCustomMobsToCache checking entity "+entity.getName()); + //entity.getName(); + if (mobNames.contains(entity.getName())) { + entity.remove(); + killedMobsCount++; + //customMobs.decreaseMobCount(); + } + } + } + + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.loadAndKillCustomMobsFromCache killed " + killedMobsCount + " mobs"); + + // Opcjonalnie: wyczyść plik cache po wczytaniu + cacheConfig.set("customMobNames", new ArrayList()); + try { + cacheConfig.save(cacheFile); + } catch (IOException e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterElo.loadAndKillCustomMobsFromCache IOException: " + e.getMessage()); + } + } + + + // Dodajemy nowe metody do uzyskania pozostałego czasu dla nagród public long getRemainingTimeForRewards(String period) { //pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: getRemainingTimeForRewards: period: "+period); @@ -144,6 +425,15 @@ public long getRemainingTimeForRewards(String period) { case "monthly": useNextMonthTime = true; break; + case "event": + if(Objects.equals(eventUnit, "h")) { + periodMillis = TimeUnit.HOURS.toMillis(eventDuration); + }else if(Objects.equals(eventUnit, "m")){ + periodMillis = TimeUnit.MINUTES.toMillis(eventDuration); + }else{ + pluginLogger.log(PluginLogger.LogLevel.ERROR,"BetterElo.getRemainingTimeForRewards: eventUnit: "+eventUnit); + } + break; default: throw new IllegalArgumentException("Invalid period: " + period); } @@ -160,7 +450,7 @@ public long getRemainingTimeForRewards(String period) { } } - private void loadRewards() { + public void loadRewards() { for (String rewardType : rewardStates.keySet()) { File rewardFile = new File(getDataFolder(), rewardType + ".yml"); if (!rewardFile.exists()) { @@ -202,45 +492,84 @@ public void updateLastScheduledTime(String period) { saveConfig(); } - private void scheduleRewards(String period, long periodMillis, boolean useNextMonthTime) { + public void scheduleRewards(String period, long periodMillis, boolean useNextMonthTime) { FileConfiguration config = getConfig(); long lastScheduledTime = config.getLong(period + "LastScheduledTime", System.currentTimeMillis()); long delay; - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: scheduleRewards: period: "+period+" periodMillis: "+periodMillis+" LastScheduledTime: "+lastScheduledTime); - if (useNextMonthTime) { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(lastScheduledTime); - calendar.add(Calendar.MONTH, 1); - delay = (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000 * 20; - } else { - delay = (periodMillis - (System.currentTimeMillis() - lastScheduledTime)) / 1000 * 20; - } + try{ + pluginLogger.log(PluginLogger.LogLevel.RANKING_REWARDS, "BetterElo: scheduleRewards: period: " + period + " periodMillis: " + periodMillis + " LastScheduledTime: " + lastScheduledTime); + if (useNextMonthTime) { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(lastScheduledTime); + calendar.add(Calendar.MONTH, 1); + delay = (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000 * 20; + } else { + delay = (periodMillis - (System.currentTimeMillis() - lastScheduledTime)) / 1000 * 20; + } - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: scheduleRewards: period: "+period+" periodMillis: "+periodMillis+" Computed delay: " + delay); + pluginLogger.log(PluginLogger.LogLevel.RANKING_REWARDS, "BetterElo: scheduleRewards: period: " + period + " periodMillis: " + periodMillis + " Computed delay: " + delay); - if (delay < 0) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: scheduleRewards: Negative delay detected, starting rewardAndReschedule"); - rewardAndReschedule(period, periodMillis, useNextMonthTime); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: scheduleRewards: BukkitRunnable: rewardAndReschedule done"); - return; - } - - new BukkitRunnable() { - @Override - public void run() { - if (rewardStates.get(period)) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: scheduleRewards: BukkitRunnable: starting rewardAndReschedule"); - rewardAndReschedule(period, periodMillis, useNextMonthTime); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: scheduleRewards: BukkitRunnable: rewardAndReschedule done"); - } + if (delay < 0) { + pluginLogger.log(PluginLogger.LogLevel.RANKING_REWARDS, "BetterElo: scheduleRewards: Negative delay detected, starting rewardAndReschedule"); + rewardAndReschedule(period, periodMillis, useNextMonthTime); + pluginLogger.log(PluginLogger.LogLevel.INFO, "Ranking "+period+" has finished!"); + return; } - }.runTaskLater(this, delay); + //saveConfig(); + new BukkitRunnable() { + @Override + public void run() { + if (rewardStates.get(period)) { + pluginLogger.log(PluginLogger.LogLevel.RANKING_REWARDS, "BetterElo: scheduleRewards: BukkitRunnable: starting rewardAndReschedule"); + rewardAndReschedule(period, periodMillis, useNextMonthTime); + pluginLogger.log(PluginLogger.LogLevel.RANKING_REWARDS, "BetterElo: scheduleRewards: BukkitRunnable: rewardAndReschedule done"); + } + } + }.runTaskLater(this, delay); + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterElo: scheduleRewards exception: "+e.getMessage()); + } + } + public static BetterElo getInstance() { + return instance; + } + public CustomMobs.CustomMob getCustomMob(String mobName) { + // Zwróć customowego moba na podstawie nazwy + return customMobsMap.get(mobName); + } + public void stopEvent(){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.stopEvent called"); + if(isEventEnabled) { + pluginLogger.log(PluginLogger.LogLevel.INFO, "Event ended - removing data."); + FileConfiguration config = getConfig(); + config.set("eventLastScheduledTime", null); + rewardStates.remove("event"); + loadRewards(); + isEventEnabled = false; + saveConfig(); + } + else{ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.stopEvent event not active"); + } } private void rewardAndReschedule(String period, long periodMillis, boolean useNextMonthTime) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.rewardAndReschedule called"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.rewardAndReschedule calling notifyTopPlayers("+period+")"); + notifyTopPlayers(period); pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardAndReschedule: Starting rewardTopPlayers"); rewardTopPlayers(period); pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardAndReschedule: rewardTopPlayers done"); pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardAndReschedule: Starting updateLastScheduledTime"); + if(period.equals("event")){ + pluginLogger.log(PluginLogger.LogLevel.INFO, "Event ended - removing data."); + FileConfiguration config = getConfig(); + config.set(period + "LastScheduledTime", null); + rewardStates.remove("event"); + loadRewards(); + isEventEnabled=false; + saveConfig(); + return; + } updateLastScheduledTime(period); pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardAndReschedule: updateLastScheduledTime done"); pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardAndReschedule: starting scheduleRewards"); @@ -251,16 +580,25 @@ public void rewardTopPlayers(String rewardType) { pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterElo: rewardTopPlayers: rewardType: "+rewardType); for (int i = 1; i <= 10; i++) { String playerName = null; - if(rewardType.equals("daily")){ - playerName = dataManager.getPlayerAtPosition(i,dataManager.dailyPlayerPoints); + switch (rewardType) { + case "daily": + playerName = dataManager.getPlayerAtPosition(i, dataManager.dailyPlayerPoints); - }else if(rewardType.equals("weekly")){ - playerName = dataManager.getPlayerAtPosition(i,dataManager.weeklyPlayerPoints); + break; + case "weekly": + playerName = dataManager.getPlayerAtPosition(i, dataManager.weeklyPlayerPoints); - }else if(rewardType.equals("monthly")){ - playerName = dataManager.getPlayerAtPosition(i,dataManager.monthlyPayerPoints); + break; + case "monthly": + playerName = dataManager.getPlayerAtPosition(i, dataManager.monthlyPayerPoints); + break; + case "event": + playerName = dataManager.getPlayerAtPosition(i, dataManager.eventPlayerPoints); + break; } if (playerName != null) { + String foramttedMessage = ChatColor.GOLD +""+ ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Rewarding player "+ChatColor.GOLD+ ChatColor.BOLD +playerName+ChatColor.AQUA +" in "+ChatColor.GOLD+ChatColor.BOLD+rewardType+" ranking for reaching "+ ChatColor.GOLD+ChatColor.BOLD+"TOP"+i; + Bukkit.getServer().broadcastMessage(foramttedMessage); OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName); if (offlinePlayer != null && offlinePlayer.hasPlayedBefore()) { // Ustaw odpowiedni subType zależnie od pozycji gracza @@ -281,9 +619,20 @@ public void rewardTopPlayers(String rewardType) { Player player = offlinePlayer.getPlayer(); if (player != null && player.isOnline()) { for (ItemStack rewardItem : rewardItems) { + // Dodaj lore jeśli przedmiot jest na liście eventItemsPlaceholder + if (configManager.eventItemsPlaceholder.contains(rewardItem.getType().toString())) { + ItemMeta itemMeta = rewardItem.getItemMeta(); + List lore = itemMeta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + lore.add(ChatColor.GRAY + "Reward for "+ChatColor.GOLD+ChatColor.BOLD + player.getName()); + itemMeta.setLore(lore); + rewardItem.setItemMeta(itemMeta); + } if (player.getInventory().firstEmpty() != -1) { player.getInventory().addItem(rewardItem); - pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterElo: rewardTopPlayers: Nagradzanie gracza: " + player.getName()); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Rewarding player: " + player.getName()); } else { pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterElo: rewardTopPlayers: No space in inventory for player: " + player.getName()); break; @@ -302,27 +651,38 @@ public void rewardTopPlayers(String rewardType) { pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: No player at position: " + i); } } - if(rewardType.equals("daily")){ - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Clearing the daily ranking"); - dataManager.dailyPlayerPoints.clear(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Saving the daily ranking"); - dataManager.saveDataToFileDaily(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Resetting the daily ranking timer"); - updateLastScheduledTime(rewardType); - }else if(rewardType.equals("weekly")){ - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Clearing the weekly ranking"); - dataManager.weeklyPlayerPoints.clear(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Saving the weekly ranking"); - dataManager.saveDataToFileWeekly(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Resetting the weekly ranking timer"); - updateLastScheduledTime(rewardType); - }else if(rewardType.equals("monthly")){ - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Clearing the monthly ranking"); - dataManager.monthlyPayerPoints.clear(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Saving the monthly ranking"); - dataManager.saveDataToFileMonthly(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Resetting the monthly ranking timer"); - updateLastScheduledTime(rewardType); + switch (rewardType) { + case "daily": + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Clearing the daily ranking"); + dataManager.dailyPlayerPoints.clear(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Saving the daily ranking"); + dataManager.saveDataToFileDaily(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Resetting the daily ranking timer"); + updateLastScheduledTime(rewardType); + break; + case "weekly": + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Clearing the weekly ranking"); + dataManager.weeklyPlayerPoints.clear(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Saving the weekly ranking"); + dataManager.saveDataToFileWeekly(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Resetting the weekly ranking timer"); + updateLastScheduledTime(rewardType); + break; + case "monthly": + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Clearing the monthly ranking"); + dataManager.monthlyPayerPoints.clear(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Saving the monthly ranking"); + dataManager.saveDataToFileMonthly(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Resetting the monthly ranking timer"); + updateLastScheduledTime(rewardType); + break; + case "event": + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Clearing the event ranking"); + dataManager.eventPlayerPoints.clear(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Saving the event ranking"); + dataManager.saveDataToFileEvent(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: rewardTopPlayers: Resetting the event ranking timer"); + break; } } private void saveOfflineReward(String playerName, List rewardItems) { @@ -354,5 +714,362 @@ private void saveOfflineReward(String playerName, List rewardItems) { pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterElo: saveOfflineReward: Exception while saving rewards: " + e); } } + public void notifyTopPlayers(String period) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.notifyTopPlayers called with period=" + period); + DecimalFormat df = new DecimalFormat("#.##"); + Duration fadeIn = Duration.ofMillis(500); // czas pojawiania się + Duration stay = Duration.ofSeconds(5); // czas wyświetlania + Duration fadeOut = Duration.ofMillis(500); // czas znikania + Title.Times times = Title.Times.times(fadeIn, stay, fadeOut); + Component rankingNotificationTileComponent = Component.text(ChatColor.GOLD + "" + ChatColor.BOLD + period.toUpperCase() + " ranking has ended!"); + Component rankingNotificationSubtileComponent; + // Notify all players + for (Player player : Bukkit.getOnlinePlayers()){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL2, "BetterElo.notifyTopPlayers." + period+" notifying "+player.getName()); + double points = dataManager.getPoints(player.getUniqueId().toString(),period); + int rank = dataManager.getPlayerRank(player.getUniqueId().toString(),period); + rankingNotificationSubtileComponent = Component.text(ChatColor.AQUA + "Your position: " + ChatColor.RED+""+ChatColor.BOLD+rank+". "+ChatColor.AQUA +"Your points: "+ ChatColor.RED+""+ChatColor.BOLD+points); + Title killerTitle = Title.title(rankingNotificationTileComponent, rankingNotificationSubtileComponent, times); + player.showTitle(killerTitle); + } + } + public void notiyBannedPlayer(String bannedPlayer){ + Player player = Bukkit.getPlayer(bannedPlayer); + DecimalFormat df = new DecimalFormat("#.##"); + + Duration fadeIn = Duration.ofMillis(300); // czas pojawiania się + Duration stay = Duration.ofMillis(10000); // czas wyświetlania + Duration fadeOut = Duration.ofMillis(5000); // czas znikania + Title.Times times = Title.Times.times(fadeIn, stay, fadeOut); + Component BannedTitleComponent = Component.text(ChatColor.DARK_RED +"!!!"+ChatColor.BLACK+""+ChatColor.BOLD+"CHEATER"+ChatColor.DARK_RED +"!!!"); + Component BannedSubtitleComponent = Component.text(ChatColor.GREEN +"Buy unban on website "+ChatColor.GOLD+ChatColor.BOLD+" BetterBox.top" ); + // Notify the killer + Title bannedTitle = Title.title(BannedTitleComponent,BannedSubtitleComponent,times); + if (player !=null) { + player.showTitle(bannedTitle); + }else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "Banned player "+bannedPlayer+" is offline - cannot send notification"); + } + + } + public void killAllCustomMobs() { + + int killedMobCount=0; + for (World world : Bukkit.getWorlds()) { + for (LivingEntity entity : world.getLivingEntities()) { + if (entity.hasMetadata("CustomMob")) { + // Zabijamy niestandardowego zombiaka + entity.remove(); + killedMobCount++; + } + } + } + pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterElo.killAllCustomMobs killed "+killedMobCount+" custom mobs."); + } + public void removeAndKillAllCustomMobs() { + for (CustomMobs.CustomMob customMob : customMobsMap.values()) { + // Sprawdzanie, czy encja jest nadal żywa przed próbą jej zabicia + if (customMob.entity != null && !customMob.entity.isDead()) { + customMob.entity.remove(); // Usuwa encję z świata + + } + } + for (CustomMobs.CustomMob customMob : customMobsMap.values()) { + // Sprawdzanie, czy encja jest nadal żywa przed próbą jej zabicia + if (customMob.entity != null && !customMob.entity.isDead()) { + customMob.entity.remove(); // Usuwa encję z świata + + } + } + customMobsMap.clear(); // Czyści mapę po usunięciu wszystkich encji + } + public void registerCustomMob(Entity entity, CustomMobs.CustomMob customMob) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "BetterElo.registerCustomMob calleed. entity: "+entity+", customMob: "+customMob); + schedulePercentageHealthRegeneration(customMob.entity, customMob.regenSeconds, customMob.regenPercent); + customMobsMap.put(entity, customMob); + } + public void unregisterCustomMob(Entity entity) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "BetterElo.unregisterCustomMob calleed. entity: "+entity); + customMobsMap.remove(entity); + if (mobTasks.containsKey(entity)) { + mobTasks.get(entity).cancel(); // Anuluje zadanie + mobTasks.remove(entity); // Usuwa referencję do zadania z mapy + } + } + public void schedulePercentageHealthRegeneration(LivingEntity mob, int regenSeconds, double regenPercentage) { + // Usuń istniejące zadanie regeneracji dla tego moba, jeśli istnieje + if (mobTasks.containsKey(mob)) { + mobTasks.get(mob).cancel(); + } + + // Utwórz nowe zadanie regeneracji + BukkitTask task = new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() - mob.getLastDamage() >= regenSeconds * 1000L) { // Przekształcenie sekund na milisekundy + double maxHealth = mob.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + double regenAmount = maxHealth * (regenPercentage / 100.0); + double newHealth = Math.min(mob.getHealth() + regenAmount, maxHealth); + mob.setHealth(newHealth); + } + } + }.runTaskTimer(this, 0L, regenSeconds * 20L); // Uruchamia zadanie co regenSeconds sekund + + // Przechowuje zadanie dla tego moba + mobTasks.put(mob, task); + } + + // Opcjonalnie, metoda do anulowania zadania regeneracji dla moba + public void cancelHealthRegeneration(LivingEntity mob) { + if (mobTasks.containsKey(mob)) { + mobTasks.get(mob).cancel(); + mobTasks.remove(mob); + } + } + + public CustomMobs.CustomMob getCustomMobFromEntity(Entity entity) { + return customMobsMap.get(entity); + } + public void checkMobsExistence() { + new BukkitRunnable() { + @Override + public void run() { + // Użyj iteratora, aby uniknąć ConcurrentModificationException podczas usuwania + Iterator> iterator = customMobsMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + if (entry.getKey().isDead() || !entry.getKey().isValid()) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "BetterElo. mob "+entry.getKey()+" is dead or does not exists, removing from the list and from the spawner "+entry.getValue().spawnerName); + // Mob nie istnieje, więc możemy go usunąć z mapy + customMobs.decreaseMobCount(entry.getValue().spawnerName); + iterator.remove(); + String spawnerName = entry.getValue().spawnerName; + customMobs.spawnedMobsMap.remove(entry.getKey().getUniqueId()); + + + if(!entry.getKey().isValid()){ + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "BetterElo.checkMobsExistence mob "+entry.getKey()+" does not exists! SpawnerName: "+spawnerName); + if (spawnerName != null) { + + Map spawnersData = customMobsFileManager.spawnersData; + CustomMobsFileManager.SpawnerData spawnerData = spawnersData.get(spawnerName); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "BetterElo.checkMobsExistence mob "+entry.getKey()+" does not exists! spawnerData.spawnedMobCount: "+spawnerData.spawnedMobCount); + if (spawnerData.spawnedMobCount == 0) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "BetterElo.checkMobsExistence resetting cooldown on spawner: "+spawnerName); + customMobs.spawnerLastSpawnTimes.put(spawnerName, System.currentTimeMillis() - spawnerData.cooldown * 1000L); + } + } + } + + // Tutaj możesz również zaimplementować logikę re-spawnu lub inne akcje + } + } + } + }.runTaskTimer(this, 0L, 20L * 10); // Uruchom co 1 minutę (20 ticków = 1 sekunda) + } + public void addMobDefenseAttribute(ItemStack item, int value){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.addMobDefenseAttribute called with value: "+value); + if (item != null) { + if(!item.hasItemMeta()){ + item.setItemMeta(Bukkit.getItemFactory().getItemMeta(item.getType())); + } + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + dataContainer.set(mobDefenseKey, PersistentDataType.INTEGER, value); + item.setItemMeta(meta); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.addMobDefenseAttribute value "+value+" was added to the item "+item); + }else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterElo.addMobDefenseAttribute null item!"+item); + } + } + public void addMobDamageAttribute(ItemStack item, String value,String transactionID){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.addMobDamageAttribute called with value: "+value,transactionID); + if (item != null) { + if(!item.hasItemMeta()){ + item.setItemMeta(Bukkit.getItemFactory().getItemMeta(item.getType())); + } + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + dataContainer.set(mobDamageKey, PersistentDataType.STRING, value); + item.setItemMeta(meta); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.addMobDamageAttribute value "+value+" was added to the item "+item,transactionID); + }else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterElo.addMobDamageAttribute null item!"+item,transactionID); + } + } + public void addAverageDamageAttribute(ItemStack item, int value){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.addAverageDamageAttribute called with value: "+value); + if (item != null) { + if(!item.hasItemMeta()){ + item.setItemMeta(Bukkit.getItemFactory().getItemMeta(item.getType())); + } + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + dataContainer.set(averageDamageKey, PersistentDataType.INTEGER, value); + item.setItemMeta(meta); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.addAverageDamageAttribute value "+value+" was added to the item "+item); + }else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterElo.addAverageDamageAttribute null item!"+item); + } + } + public int[] getMobDamageAttribute(ItemStack item) { + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(mobDamageKey, PersistentDataType.STRING)) { + String damageRange = dataContainer.get(mobDamageKey, PersistentDataType.STRING); + String[] parts = damageRange.split("-"); + int minDamage = Integer.parseInt(parts[0]); + int maxDamage = Integer.parseInt(parts[1]); + return new int[]{minDamage, maxDamage}; + } + } + return new int[]{0, 0}; + } + + public int getMobDefenseAttribute(List wornItems) { + int totalDefense = 0; + + for (ItemStack item : wornItems) { + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(mobDefenseKey, PersistentDataType.INTEGER)) { + totalDefense += dataContainer.get(mobDefenseKey, PersistentDataType.INTEGER); + } + } + } + + return totalDefense; + } + + public int getAverageDamageAttribute(List wornItems, String transactionID) { + int totalDamage = 0; + + for (ItemStack item : wornItems) { + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(averageDamageKey, PersistentDataType.INTEGER)) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.getAverageDamageAttribute: adding damage: "+dataContainer.get(averageDamageKey, PersistentDataType.INTEGER),transactionID); + totalDamage += dataContainer.get(averageDamageKey, PersistentDataType.INTEGER); + } + } + } + + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.getAverageDamageAttribute: totalDamage: "+totalDamage,transactionID); + return totalDamage; + } + public int getAverageDamageAttribute(ItemStack item) { + int totalDamage = 0; + + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(averageDamageKey, PersistentDataType.INTEGER)) { + totalDamage += dataContainer.get(averageDamageKey, PersistentDataType.INTEGER); + } + } + + return totalDamage; + } + public boolean hasMobDamageAttribute(ItemStack item) { + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(mobDamageKey, PersistentDataType.STRING)) { + return true; + } + } + return false; + } + public boolean hasMobDefenseAttribute(ItemStack item) { + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(mobDefenseKey, PersistentDataType.INTEGER)) { + return true; + } + } + return false; + } + public boolean hasAverageDamageAttribute(ItemStack item) { + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(averageDamageKey, PersistentDataType.INTEGER)) { + return true; + } + } + return false; + } + private void loadElasticBuffer(){ + try{ + PluginManager pm = Bukkit.getPluginManager(); + Plugin[] plugins = pm.getPlugins(); + StringBuilder enabledPlugins = new StringBuilder("Enabled plugins: "); + StringBuilder disabledPlugins = new StringBuilder("Disabled plugins: "); + for (Plugin plugin : plugins) { + if (plugin.isEnabled()) { + enabledPlugins.append(plugin.getName()).append(", "); + } else { + disabledPlugins.append(plugin.getName()).append(", "); + } + } + // Zalogowanie włączonych pluginów + pluginLogger.log(PluginLogger.LogLevel.INFO, enabledPlugins.toString()); + // Zalogowanie wyłączonych pluginów + pluginLogger.log(PluginLogger.LogLevel.INFO, "Bukkit.getPluginManager().getPlugin(\"ElasticBuffer\").isEnabled():"+Bukkit.getPluginManager().getPlugin("ElasticBuffer").isEnabled()+",Bukkit.getPluginManager().getPlugin(\"ElasticBuffer\").isNaggable(): "+Bukkit.getPluginManager().getPlugin("ElasticBuffer").isNaggable()); + pluginLogger.log(PluginLogger.LogLevel.INFO, disabledPlugins.toString()); + pluginLogger.log(PluginLogger.LogLevel.INFO, "[BetterElo] Initializing basic components..."); + try { + // Opóźnienie o 5 sekund, aby dać ElasticBuffer czas na pełną inicjalizację + Thread.sleep(1000); + } catch (InterruptedException e) { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "[BetterElo] Initialization delay interrupted: " + e.getMessage()); + Thread.currentThread().interrupt(); // Przywrócenie statusu przerwania wątku + } + elasticBuffer = (ElasticBuffer) pm.getPlugin("ElasticBuffer"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "elasticBuffer: " + elasticBuffer); + //assert elasticBuffer != null; + elasticBuffer.receiveLog("BetterElo initialized successfully! Starting schedulers", "INFO", getDescription().getName(),null); + + elasticBuffer.sendLogs(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "LOGS SENT"); + pluginLogger.isElasticBufferEnabled=true; + pluginLogger.api= new ElasticBufferAPI(elasticBuffer); + pluginLogger.elasticBuffer=elasticBuffer; + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR, "ElasticBufferAPI instance found via ServicesManager, exception: "+e.getMessage()); + } + } + public ElasticBuffer getElasticBuffer(){return elasticBuffer;} + + public static int rollDamage(int maxValue) { + //pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo.rollDamage called with maxValue: "+maxValue); + double[] weights = new double[maxValue - maxValue / 2 + 1]; + double totalWeight = 0; + double mean = 3 * maxValue / 4.5; // Peak at 3/4 of maxValue + double stdDev = maxValue / 12.0; // Standard deviation + + for (int x = maxValue / 2; x <= maxValue; x++) { + double exponent = -Math.pow(x - mean, 2) / (2 * Math.pow(stdDev, 2)); + weights[x - maxValue / 2] = Math.exp(exponent); + totalWeight += weights[x - maxValue / 2]; + } + + Random random = new Random(); + double randomValue = random.nextDouble() * totalWeight; + double cumulativeWeight = 0; + + for (int x = maxValue / 2; x <= maxValue; x++) { + cumulativeWeight += weights[x - maxValue / 2]; + if (randomValue <= cumulativeWeight) { + return x; + } + } + + return maxValue; // Shouldn't be reached + } } diff --git a/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java b/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java index a22dac4..0f63b25 100644 --- a/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java +++ b/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java @@ -1,23 +1,25 @@ package betterbox.mine.game.betterelo; -import org.bukkit.OfflinePlayer; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; +import me.filoghost.holographicdisplays.api.HolographicDisplaysAPI; +import me.filoghost.holographicdisplays.api.hologram.Hologram; +import org.bukkit.*; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; import java.io.File; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; +import java.util.concurrent.TimeUnit; public class BetterEloCommand implements CommandExecutor { @@ -29,17 +31,26 @@ public class BetterEloCommand implements CommandExecutor { private final BetterElo betterElo; private final ExtendedConfigManager configManager; private final Event event; + private final CustomMobsFileManager customMobsFileManager; private final PlayerKillDatabase PKDB; - - public BetterEloCommand(JavaPlugin plugin, DataManager dataManager, GuiManager guiManager, PluginLogger pluginLogger, BetterElo betterElo, ExtendedConfigManager configManager,Event event, PlayerKillDatabase PKDB) { + private Hologram hologramMain; + private Hologram hologramDaily; + private Hologram hologramWeekly; + private Hologram hologramMonthly; + private Hologram hologramEvent; + private CustomMobs customMobs; + private BukkitTask eventHoloTask; + + public BetterEloCommand(JavaPlugin plugin, DataManager dataManager, GuiManager guiManager, PluginLogger pluginLogger, BetterElo betterElo, ExtendedConfigManager configManager, Event event, PlayerKillDatabase PKDB, CustomMobs customMobs, CustomMobsFileManager customMobsFileManager) { this.dataManager = dataManager; this.plugin = plugin; - + this.customMobs = customMobs; this.guiManager = guiManager; // Inicjalizujemy referencję do GuiManager this.pluginLogger = pluginLogger; this.betterElo = betterElo; // Inicjalizujemy referencję do BetterElo this.configManager = configManager; this.event = event; + this.customMobsFileManager = customMobsFileManager; this.PKDB = PKDB; @@ -47,12 +58,14 @@ public BetterEloCommand(JavaPlugin plugin, DataManager dataManager, GuiManager g @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + String transactionID = UUID.randomUUID().toString(); switch (args.length) { case 0: if (sender instanceof Player) { Player player = (Player) sender; int rank = dataManager.getPlayerRank(player.getUniqueId().toString()); double points = dataManager.getPoints(player.getUniqueId().toString(), "main"); + points = (double)Math.round(points*100)/100; sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + "Your rank: " + ChatColor.GREEN + rank); sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + "Your points: " + ChatColor.GREEN + points); } else { @@ -61,36 +74,80 @@ public boolean onCommand(CommandSender sender, Command command, String label, St break; case 1: switch (args[0].toLowerCase()) { + case "checkitem": + if(sender instanceof Player){ + Player player = (Player) sender; + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + if(itemInHand!=null){ + ItemMeta itemMeta = itemInHand.getItemMeta(); + if(itemMeta!=null){ + int avgdmg = betterElo.getAverageDamageAttribute(itemInHand); + int[] dmg = betterElo.getMobDamageAttribute(itemInHand); + sender.sendMessage("avgdmg: "+avgdmg+" dmg: "+dmg[0]+"-"+dmg[1]); + } + } + } + break; + case "enchantitem": + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand.onCommand enchantitem called, sender: "+sender); + if(!sender.isOp()){ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + break; + } + createEncahntItem(sender); + break; + case "reroll": + if(sender.isOp() || sender.hasPermission("betterelo.reroll")) { + handleRerollCommand(sender); + }else{ + noPermission(sender); + } + break; + case "killallmobs": + if(!sender.isOp()){ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + break; + } + betterElo.killAllCustomMobs(); + break; + case "addelytra": + if (sender instanceof Player) { + Player player = (Player) sender; + if(!player.isOp()){ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + break; + } + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + if(itemInHand.getType() != Material.AIR && itemInHand.getType().toString().contains("CHESTPLATE")) { + addElytraLore(player,itemInHand); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Elytra effect added."); + } + }else{ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " This command can be used only by as a player."); + } + break; + case "stopevent": + if(sender.isOp()){ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Event stopped,data removed."); + betterElo.stopEvent(); + }else{ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + } + break; case "info": sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Better Elo system for BetterBox."); sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Author: "+plugin.getDescription().getAuthors()); sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Version: "+plugin.getDescription().getVersion()); break; case "help": - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " List of player commands:"); - sender.sendMessage(ChatColor.AQUA + "/be " + ChatColor.GREEN + "- Returns your ranking info/Zwraca info o Twoim rankingu"); - sender.sendMessage(ChatColor.AQUA + "/be " + ChatColor.GREEN + "- Returns ranking info about given player./Zwraca info rankingu danego gracza."); - sender.sendMessage(ChatColor.AQUA + "/be info " + ChatColor.GREEN + "- Returns plugin info./Zwraca info o pluginie."); - sender.sendMessage(ChatColor.AQUA + "/be top " + ChatColor.GREEN + "- Returns ranking info about player at given position./Zwraca info o graczu na danym miejscu w rankingu"); - sender.sendMessage(ChatColor.AQUA + "/be top10 " + ChatColor.GREEN + "- Returns top10 players from ranking/Zwraca info o top10 graczy rankingu"); - sender.sendMessage(ChatColor.AQUA + "/be claim " + ChatColor.GREEN + "- Claim your rewards! Remember to empty your eq!!!/Odbierz swoje nagrody! Pamiętaj wyczyścić eq przed!!"); - sender.sendMessage(ChatColor.AQUA + "/be timeleft " + ChatColor.GREEN + "- Returns time left to giveaway/Zwraca pozostały czas do rozdania nagród"); - sender.sendMessage(ChatColor.AQUA + "/be daily " + ChatColor.GREEN + "- Returns top10 daily ranking/Zwraca info o top10 rankingu dziennego"); - sender.sendMessage(ChatColor.AQUA + "/be weekly " + ChatColor.GREEN + "- Returns top10 weekly ranking/Zwraca info o top10 rankingu tygodniowego"); - sender.sendMessage(ChatColor.AQUA + "/be monthly " + ChatColor.GREEN + "- Returns top10 monthly ranking/Zwraca info o top10 rankingu miesięcznego"); - if(sender.isOp()){ - sender.sendMessage(ChatColor.AQUA + "/be setrewards " + ChatColor.GREEN + "- Opens a GUI for changing the rewards"); - sender.sendMessage(ChatColor.AQUA + "/be reload " + ChatColor.GREEN + "- Reloads the config file "); - sender.sendMessage(ChatColor.AQUA + "/be ban " + ChatColor.GREEN + "- resetting the player's rankings to 1000 and redeeming remaining poits to victims."); - sender.sendMessage(ChatColor.AQUA + "/be add " + ChatColor.GREEN + "- adding points to given player in specific ranking (main,daily,weekly,monthly)"); - sender.sendMessage(ChatColor.AQUA + "/be sub " + ChatColor.GREEN + "- subtracting points from given player in specific ranking (main,daily,weekly,monthly)"); - } + handleHelpCommand(sender); break; case "top10": sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Top 10 players in the ranking:"); for (int i = 1; i <= 10; i++) { String playerName = dataManager.getPlayerAtPosition(i, dataManager.playerPoints); double points = dataManager.getPointsAtPosition(i, dataManager.playerPoints); + points = (double)Math.round(points*100)/100; if (playerName != null) { sender.sendMessage(ChatColor.AQUA.toString() + i + ". " + ChatColor.GREEN + playerName + ChatColor.AQUA + " - Points: " + ChatColor.GREEN + points); } @@ -101,6 +158,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St for (int i = 1; i <= 10; i++) { String playerName = dataManager.getPlayerAtPosition(i, dataManager.dailyPlayerPoints); double points = dataManager.getPointsAtPosition(i, dataManager.dailyPlayerPoints); + points = (double)Math.round(points*100)/100; if (playerName != null) { sender.sendMessage(ChatColor.AQUA.toString() + i + ". " + ChatColor.GREEN + playerName + ChatColor.AQUA + " - Points: " + ChatColor.GREEN + points); } @@ -111,6 +169,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St for (int i = 1; i <= 10; i++) { String playerName = dataManager.getPlayerAtPosition(i, dataManager.weeklyPlayerPoints); double points = dataManager.getPointsAtPosition(i, dataManager.weeklyPlayerPoints); + points = (double)Math.round(points*100)/100; if (playerName != null) { sender.sendMessage(ChatColor.AQUA.toString() + i + ". " + ChatColor.GREEN + playerName + ChatColor.AQUA + " - Points: " + ChatColor.GREEN + points); } @@ -121,6 +180,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St for (int i = 1; i <= 10; i++) { String playerName = dataManager.getPlayerAtPosition(i, dataManager.monthlyPayerPoints); double points = dataManager.getPointsAtPosition(i, dataManager.monthlyPayerPoints); + points = (double)Math.round(points*100)/100; if (playerName != null) { sender.sendMessage(ChatColor.AQUA.toString() + i + ". " + ChatColor.GREEN + playerName + ChatColor.AQUA + " - Points: " + ChatColor.GREEN + points); } @@ -144,7 +204,6 @@ public boolean onCommand(CommandSender sender, Command command, String label, St if (rewardItems != null && !rewardItems.isEmpty()) { for (ItemStack item : rewardItems) { player.getInventory().addItem(item); - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Rewards claimed!"); pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterEloCommand: claim: player: " + player.getName() + " reward: " + item); } rewardsConfig.set(playerName, null); // Usuń przyznane nagrody z pliku @@ -154,44 +213,39 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } catch (IOException e) { pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterEloCommand: claim: Error while saving rewards configuration: " + e); } + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Rewards claimed!"); + }else { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " No rewards assigned."); } - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " No rewards assigned."); - pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterEloCommand: claim: player: " + player.getName() + " No rewards assigned."); + break; case "timeleft": - if (!(sender instanceof Player)) { - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " This command can only be used by online players."); - return true; - } - - player = (Player) sender; - - long dailyTimeLeft = betterElo.getRemainingTimeForRewards("daily"); - long weeklyTimeLeft = betterElo.getRemainingTimeForRewards("weekly"); - long monthlyTimeLeft = betterElo.getRemainingTimeForRewards("monthly"); - - player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Remaining time for daily rewards: " + ChatColor.GREEN + formatTime(dailyTimeLeft)); - player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Remaining time for weekly rewards: " + ChatColor.GREEN + formatTime(weeklyTimeLeft)); - player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Remaining time for monthly rewards: " + ChatColor.GREEN + formatTime(monthlyTimeLeft)); + handleTimeLeft(sender); break; case "setrewards": - pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterEloCommand: Player " + sender.getName() + " issued command /be setrewards"); - if (!sender.hasPermission("betterelo.setrewards")) { - pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterEloCommand: Player " + sender.getName() + " was denied access to command /be setrewards"); - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); - return true; + handleSetRewards(sender); + break; + case "reload": + handleReloadCommand(sender, transactionID); + break; + case "event": + if(sender.isOp()){ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " to start the event use /be event "); } - pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterEloCommand: Player " + sender.getName() + " was granted access to command /be setrewards"); - if (!(sender instanceof Player)) { - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " This command can only be used by online players."); - return true; + if(sender instanceof Player){ + if(betterElo.isEventEnabled){ + player = (Player) sender; + double points = dataManager.getPoints(player.getUniqueId().toString(), "event"); + points = (double)Math.round(points*100)/100; + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + "Event active! Time left: "+formatTime(betterElo.getRemainingTimeForRewards("event"))); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + "Your rank: "+dataManager.getPlayerRank(player.getUniqueId().toString(), "event")); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + "Your points: "+points); + } + else { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + "Event is not active!"); + } } - - player = (Player) sender; - guiManager.openMainGui(player); // Otwieramy główne menu GUI dla gracza break; - case "reload": - return handleReloadCommand(sender); default: // /be - Information about a specific player's rank and points @@ -215,6 +269,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } double points = dataManager.getPoints(playerUUID, "main"); + points = (double)Math.round(points*100)/100; sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Player " + ChatColor.GREEN + playerName + ChatColor.AQUA + " is ranked " + ChatColor.GREEN + rank + ChatColor.AQUA + " in main ranking."); sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Player's points: " + ChatColor.GREEN + points+ ChatColor.AQUA + " in main ranking."); sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Player " + ChatColor.GREEN + playerName + ChatColor.AQUA + " is ranked " + ChatColor.GREEN + dataManager.getPlayerRank(playerUUID,"daily") + ChatColor.AQUA + "."); @@ -227,25 +282,201 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } break; case 2: - if (args[0].equalsIgnoreCase("top")) { - // /be top - Displays the nickname and points of the player in position n in the ranking - try { - int position = Integer.parseInt(args[1]); - String playerName = dataManager.getPlayerAtPosition(position, dataManager.playerPoints); - double points = dataManager.getPointsAtPosition(position, dataManager.playerPoints); - if (playerName != null) { - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Player in position " + ChatColor.GREEN + position + ": " + ChatColor.GREEN + playerName); - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Player's points: " + ChatColor.GREEN + points); - } else { - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " No player in position " + ChatColor.GREEN + position + ChatColor.DARK_RED + " in the ranking."); + switch (args[0].toLowerCase()) { + case "forcespawn": + if(sender.isOp()||sender.hasPermission("betterelo.forcespawn")){ + customMobs.spawnerForceSpawn(args[1]); } - } catch (NumberFormatException e) { - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " Please enter a valid ranking position number."); + break; + case "droptable": + if(sender.isOp()||sender.hasPermission("betterelo.droptable")){ + handleCreateDropTable(sender,args[1]); } + break; + case "antyweb": + if ((sender.hasPermission("betterelo.antyweb") || sender.isOp()) && sender instanceof Player) { + Player player = ((Player) sender).getPlayer(); + assert player != null; + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + if (itemInHand.getType().isAir()) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + "You must hold an item in your hand to add Antyweb lore!"); + return true; + } + int radius; + try { + // Spróbuj przekonwertować argument na liczbę + radius = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED +"Invalid radius! Please provide a number."); + return true; + } + addAntywebLore(player, itemInHand, radius); + } + break; + case "zephyr": + if ((sender.hasPermission("betterelo.zephyr") || sender.isOp()) && sender instanceof Player) { + Player player = ((Player) sender).getPlayer(); + assert player != null; + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + if (itemInHand.getType().isAir()) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + "You must hold an item in your hand to add Zephyr lore!"); + return true; + } + int power; + try { + // Spróbuj przekonwertować argument na liczbę + power = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED +"Invalid radius! Please provide a number."); + return true; + } + addZephyrLore(player, itemInHand, power); + } + break; + case "holo": + if (sender.isOp()) { + if (sender instanceof Player) { + Player player = (Player) sender; + Location where = player.getLocation();// The location where the hologram will be placed + HolographicDisplaysAPI api = HolographicDisplaysAPI.get(plugin); // The API instance for your plugin + + if (args[1].equals("event")) { + if (hologramEvent == null) { + HoloTop(dataManager.eventPlayerPoints, where, api); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Holo for Event created!"); + } else { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " Holo for Event already exists!!"); + } + } + } else { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + "Event is not active!"); + } + } + break; + case "top": + try { + int position = Integer.parseInt(args[1]); + String playerName = dataManager.getPlayerAtPosition(position, dataManager.playerPoints); + double points = dataManager.getPointsAtPosition(position, dataManager.playerPoints); + points = (double)Math.round(points*100)/100; + if (playerName != null) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Player in position " + ChatColor.GREEN + position + ": " + ChatColor.GREEN + playerName); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Player's points: " + ChatColor.GREEN + points); + } else { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " No player in position " + ChatColor.GREEN + position + ChatColor.DARK_RED + " in the ranking."); + } + } catch (NumberFormatException e) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " Please enter a valid ranking position number."); + } + break; + case "ban": + if (sender.isOp()) { + handleBanCommand(sender, args[1]); + betterElo.notiyBannedPlayer(args[1]); + }else{ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + "You don't have permission to use that command!"); + } + break; + case "firework": + if(sender.isOp()){ + try { + int power = Integer.parseInt(args[1]); + Player player = (Player) sender; + createInfiniteFireworkItem(player,power); + // Tutaj możesz wykonać logikę, jeśli args[1] jest liczbą całkowitą + } catch (NumberFormatException e) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + "Command usage /be firework - where power is INT!"); + } + return true; + }else{ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + } + break; + default: + // Obsługa dla przypadków, gdy żadna z opcji nie pasuje do argumentu + // Możesz dodać tutaj odpowiednią logikę lub komunikat błędu + break; } - if(args[0].equalsIgnoreCase("ban")){ - handleBanCommand(sender,args[1]); + case 3: + if (sender.isOp()) { + switch (args[0]) { + case "spawnmob": + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "BetterEloCommand.OnCommand calling handleCustomMobsCommands(sender)"); + try { + handleCustomMobsCommands(sender, args[1], Integer.parseInt(args[2])); + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterEloCommand.OnCommand spawnmob command generated exception: " + e); + } + break; + + case "startevent": + int eventDuration; + try { + eventDuration = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid event duration: " + args[1]); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " Invalid event duration!"); + return true; + } + + String eventUnit = args[2]; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand.onCommand.event called. Duration:" + args[1] + " timeUnit:" + args[2]); + betterElo.eventDuration = eventDuration; + betterElo.eventUnit = eventUnit; + betterElo.isEventEnabled = true; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterElo: onEnable: Planowanie nagród event..."); + + long periodMillis = 0; + switch (eventUnit) { + case "h": + periodMillis = TimeUnit.HOURS.toMillis(eventDuration); + break; + case "m": + periodMillis = TimeUnit.MINUTES.toMillis(eventDuration); + break; + default: + pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterEloCommand.onCommand.event: eventUnit: " + eventUnit); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " Invalid time unit!"); + return true; + } + + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand.onCommand.event: scheduling event rewards periodMillis:" + periodMillis); + betterElo.scheduleRewards("event", periodMillis, false); + betterElo.rewardStates.put("event", true); + betterElo.loadRewards(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand.onCommand.event: calling betterElo.updateLastScheduledTime(event)"); + betterElo.updateLastScheduledTime("event"); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Event started! Duration " + eventDuration + " " + eventUnit); + break; + + case "setattribute": + Player player = (Player) sender; + ItemStack item = player.getInventory().getItemInMainHand(); + if(item!=null&&!item.getType().equals("AIR")){ + switch (args[1]){ + case "mobdefense": + betterElo.addMobDefenseAttribute(item, Integer.parseInt(args[2])); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " MobDefense attribute set with value "+args[2]); + break; + case "mobdamage": + betterElo.addMobDamageAttribute(item, args[2],transactionID); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " mobdamage attribute set with value "+args[2]); + break; + case "averagedamage": + betterElo.addAverageDamageAttribute(item, Integer.parseInt(args[2])); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " averagedamage attribute set with value "+args[2]); + break; + } + } + + default: + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + break; + } + } else { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + return true; } break; case 4: @@ -256,10 +487,29 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } break; + case 6: + if(args[0].equalsIgnoreCase("addspawner")) { + try { + handleAddSpawnerCommand(sender, args[1], args[2], Integer.parseInt(args[3]), Integer.parseInt(args[4]),Integer.parseInt(args[5])); + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "BetterEloCommand.onCommand.addspawner exception " + e.getMessage()); + } + } + } return true; } + private void handleCustomMobsCommands(CommandSender sender, String mobName, int mobCount){ + String transactionID = UUID.randomUUID().toString(); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS,"BetterEloCommand.handleCustomMobsCommands called, sender: "+sender.getName()+", mobName: "+mobName+", mobCount: "+mobCount); + if(sender.isOp() && sender instanceof Player) { + customMobs.spawnModifiedZombie((Player) sender,mobName,mobCount,transactionID); + }else{ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + + } + } private boolean handleAddPointsCommand(CommandSender sender, String player, Double points, String rankingType){ pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterEloCommand: handleAddPointsCommand called by "+sender.getName()); if(sender.isOp()) { @@ -286,13 +536,18 @@ private boolean handleSubtractPointsCommand(CommandSender sender, String player, } } - private boolean handleReloadCommand(CommandSender sender){ + private boolean handleReloadCommand(CommandSender sender,String transactionID){ if(sender.hasPermission("betterelo.reload")){ configManager.ReloadConfig(); - sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " BetterRanks config reloaded!"); + pluginLogger.log(PluginLogger.LogLevel.INFO,"BetterElo config.yml reloaded!",transactionID); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " BetterElo config reloaded!",transactionID); + customMobsFileManager.loadSpawners(); + pluginLogger.log(PluginLogger.LogLevel.INFO,"BetterElo spawners.yml reloaded",transactionID); + customMobs.loadCustomMobs(transactionID); + //customMobsFileManager.loadCustomDrops(); return true; }else { - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterEloCommand: handleReloadCommand: sender " + sender + " dont have permission to use /br tl"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterEloCommand: handleReloadCommand: sender " + sender + " dont have permission to use /br tl",transactionID); sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED +"You don't have permission to use this command!"); return false; } @@ -300,6 +555,7 @@ private boolean handleReloadCommand(CommandSender sender){ private boolean handleBanCommand(CommandSender sender, String banName) { pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand: handleBanCommand called with parameters "+banName); if (sender.hasPermission("betterelo.ban")) { + /* if (!(sender instanceof Player)) { sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED +"You don't have permission to use this command!"); @@ -307,6 +563,8 @@ private boolean handleBanCommand(CommandSender sender, String banName) { return false; } + */ + Player player = (Player) sender; pluginLogger.log(PluginLogger.LogLevel.INFO, "Banning "+banName+". Points in main ranking: "+dataManager.getPoints(getOfflinePlayerUUID(banName),"main")+", points to redeem "+(dataManager.getPoints(getOfflinePlayerUUID(banName),"main")-1000d)); pluginLogger.log(PluginLogger.LogLevel.INFO, "Banning "+banName+". Points in daily ranking: "+dataManager.getPoints(getOfflinePlayerUUID(banName),"daily")+", points to redeem "+(dataManager.getPoints(getOfflinePlayerUUID(banName),"daily")-1000d)); @@ -402,7 +660,242 @@ private String formatTime(long millis) { long minutes = seconds / 60; long hours = minutes / 60; long days = hours / 24; - return String.format("%d days, %d hours, %d minutes, %d seconds", days, hours % 24, minutes % 60, seconds % 60); + + StringBuilder formattedTime = new StringBuilder(); + + if (days > 0) { + formattedTime.append(days).append("d "); + } + if (hours % 24 > 0) { + formattedTime.append(hours % 24).append("h "); + } + if (minutes % 60 > 0) { + formattedTime.append(minutes % 60).append("m "); + } + if (seconds % 60 > 0 || formattedTime.length() == 0) { + formattedTime.append(seconds % 60).append("s"); + } + + return formattedTime.toString().trim(); // Usunięcie ewentualnych spacji na końcu + } + private void HoloTop(Map playerPoints, Location location,HolographicDisplaysAPI api){ + pluginLogger.log(PluginLogger.LogLevel.COMMAND, "BetterEloCommand.HoloTop called"); + if(eventHoloTask ==null||eventHoloTask.isCancelled()){ + eventHoloTask = new BukkitRunnable() { + + public void run() { + hologramEvent = api.createHologram(location); + hologramMain.getLines().insertText(0, ChatColor.GOLD + "" + ChatColor.BOLD + "EVENT RANKING"); + hologramMain.getLines().insertText(1, ChatColor.GOLD + "" + ChatColor.BOLD + "TOP 1 - " + ChatColor.RED + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(1, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.RED + ((double) Math.round(dataManager.getPointsAtPosition(1, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(2, ChatColor.GOLD + "" + ChatColor.BOLD + "TOP 2 - " + ChatColor.GREEN + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(2, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.GREEN + ((double) Math.round(dataManager.getPointsAtPosition(2, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(3, ChatColor.GOLD + "" + ChatColor.BOLD + "TOP 3 - " + ChatColor.AQUA + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(3, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.AQUA + ((double) Math.round(dataManager.getPointsAtPosition(3, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(4, ChatColor.WHITE + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(4, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.WHITE + ((double) Math.round(dataManager.getPointsAtPosition(4, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(5, ChatColor.WHITE + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(5, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.WHITE + ((double) Math.round(dataManager.getPointsAtPosition(5, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(6, ChatColor.WHITE + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(6, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.WHITE + ((double) Math.round(dataManager.getPointsAtPosition(6, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(7, ChatColor.WHITE + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(7, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.WHITE + ((double) Math.round(dataManager.getPointsAtPosition(7, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(8, ChatColor.WHITE + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(8, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.WHITE + ((double) Math.round(dataManager.getPointsAtPosition(8, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(9, ChatColor.WHITE + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(9, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.WHITE + ((double) Math.round(dataManager.getPointsAtPosition(9, playerPoints) * 100) / 100)); + hologramMain.getLines().insertText(10, ChatColor.WHITE + "" + ChatColor.BOLD + dataManager.getPlayerAtPosition(10, playerPoints) + ChatColor.GOLD + "" + ChatColor.BOLD + "|| POINTS:" + ChatColor.BOLD + "" + ChatColor.WHITE + ((double) Math.round(dataManager.getPointsAtPosition(10, playerPoints) * 100) / 100)); + hologramEvent.delete(); + } + }.runTaskTimer(plugin, 0L, 200L); // Pierwszy argument to odroczenie (po jakim czasie ma rozpocząć się pierwsze wykonanie zadania), a drugi to okres między kolejnymi wykonaniami w tickach (20 ticków = 1 sekunda) + } + } + private void handleHelpCommand(CommandSender sender){ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " List of player commands:"); + sender.sendMessage(ChatColor.AQUA + "/be " + ChatColor.GREEN + "- Returns your ranking info/Zwraca info o Twoim rankingu"); + sender.sendMessage(ChatColor.AQUA + "/be " + ChatColor.GREEN + "- Returns ranking info about given player./Zwraca info rankingu danego gracza."); + sender.sendMessage(ChatColor.AQUA + "/be info " + ChatColor.GREEN + "- Returns plugin info./Zwraca info o pluginie."); + sender.sendMessage(ChatColor.AQUA + "/be top " + ChatColor.GREEN + "- Returns ranking info about player at given position./Zwraca info o graczu na danym miejscu w rankingu"); + sender.sendMessage(ChatColor.AQUA + "/be top10 " + ChatColor.GREEN + "- Returns top10 players from ranking/Zwraca info o top10 graczy rankingu"); + sender.sendMessage(ChatColor.AQUA + "/be claim " + ChatColor.GREEN + "- Claim your rewards! Remember to empty your eq!!!/Odbierz swoje nagrody! Pamiętaj wyczyścić eq przed!!"); + sender.sendMessage(ChatColor.AQUA + "/be timeleft " + ChatColor.GREEN + "- Returns time left to giveaway/Zwraca pozostały czas do rozdania nagród"); + sender.sendMessage(ChatColor.AQUA + "/be daily " + ChatColor.GREEN + "- Returns top10 daily ranking/Zwraca info o top10 rankingu dziennego"); + sender.sendMessage(ChatColor.AQUA + "/be weekly " + ChatColor.GREEN + "- Returns top10 weekly ranking/Zwraca info o top10 rankingu tygodniowego"); + sender.sendMessage(ChatColor.AQUA + "/be monthly " + ChatColor.GREEN + "- Returns top10 monthly ranking/Zwraca info o top10 rankingu miesięcznego"); + sender.sendMessage(ChatColor.AQUA + "/be event " + ChatColor.GREEN + "- Returns event info/Zwraca info o evencie"); + sender.sendMessage(ChatColor.AQUA + "/be reroll " + ChatColor.GREEN + "- Open Re-Roll GUI for AvgDmg bonus items"); + if(sender.isOp()){ + sender.sendMessage(ChatColor.AQUA + "/be setrewards " + ChatColor.GREEN + "- Opens a GUI for changing the rewards"); + sender.sendMessage(ChatColor.AQUA + "/be reload " + ChatColor.GREEN + "- Reloads the config file "); + sender.sendMessage(ChatColor.AQUA + "/be ban " + ChatColor.GREEN + "- resetting the player's rankings to 1000 and redeeming remaining poits to victims."); + sender.sendMessage(ChatColor.AQUA + "/be add " + ChatColor.GREEN + "- adding points to given player in specific ranking (main,daily,weekly,monthly)"); + sender.sendMessage(ChatColor.AQUA + "/be sub " + ChatColor.GREEN + "- subtracting points from given player in specific ranking (main,daily,weekly,monthly)"); + sender.sendMessage(ChatColor.AQUA + "/be startevent " + ChatColor.GREEN + "- setting up event duration and time unit "); + sender.sendMessage(ChatColor.AQUA + "/be stopevent " + ChatColor.GREEN + "- Stops current event (if active)."); + sender.sendMessage(ChatColor.AQUA + "/be antyweb " + ChatColor.GREEN + "- creates antyweb effect with given radius"); + sender.sendMessage(ChatColor.AQUA + "/be addspawner " + ChatColor.GREEN + "- creates custom mob spawner"); + sender.sendMessage(ChatColor.AQUA + "/be droptable - opens a GUI to create new drop table"); + sender.sendMessage(ChatColor.AQUA + "/be spawnmob - spawn given custom mob"); + sender.sendMessage(ChatColor.AQUA + "/be enchantitem - gives you 1x Enchant Item"); + sender.sendMessage(ChatColor.AQUA + "/be forcespawn - forces a respawn of a given spawner"); + sender.sendMessage(ChatColor.AQUA + "/be setattribute mobdefense/mobdamage/avaragedamage x - adds custom attribute with x value to the item in hand"); + } + } + private void handleTimeLeft(CommandSender sender){ + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " This command can only be used by online players."); + return; + } + + Player player = (Player) sender; + + long dailyTimeLeft = betterElo.getRemainingTimeForRewards("daily"); + long weeklyTimeLeft = betterElo.getRemainingTimeForRewards("weekly"); + long monthlyTimeLeft = betterElo.getRemainingTimeForRewards("monthly"); + + + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Remaining time for daily rewards: " + ChatColor.GREEN + formatTime(dailyTimeLeft)); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Remaining time for weekly rewards: " + ChatColor.GREEN + formatTime(weeklyTimeLeft)); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Remaining time for monthly rewards: " + ChatColor.GREEN + formatTime(monthlyTimeLeft)); + if(betterElo.isEventEnabled){ + long eventTimeLeft = betterElo.getRemainingTimeForRewards("event"); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Remaining time for event rewards: " + ChatColor.GREEN + formatTime(eventTimeLeft)); + + } + } + private void handleSetRewards(CommandSender sender){ + pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterEloCommand: Player " + sender.getName() + " issued command /be setrewards"); + if (!sender.hasPermission("betterelo.setrewards")) { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterEloCommand: Player " + sender.getName() + " was denied access to command /be setrewards"); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + return ; + } + pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterEloCommand: Player " + sender.getName() + " was granted access to command /be setrewards"); + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " This command can only be used by online players."); + return ; + } + + Player player = (Player) sender; + guiManager.openMainGui(player); // Otwieramy główne menu GUI dla gracza + } + private void handleCreateDropTable(CommandSender sender,String dropTableName){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand: Player " + sender.getName() + " issued command /be droptable "+dropTableName); + if (!sender.hasPermission("betterelo.droptable")||!sender.isOp()) { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterEloCommand: Player " + sender.getName() + " was denied access to command /be droptable"); + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command!"); + return ; + } + pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterEloCommand: Player " + sender.getName() + " was granted access to command /be droptable"); + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " This command can only be used by online players."); + return ; + } + + Player player = (Player) sender; + guiManager.openDroptableGui(player,dropTableName); // Otwieramy główne menu GUI dla gracza + } + public void handleRerollCommand (CommandSender sender){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand.handleRerollCommand called, sender: "+sender); + if(sender instanceof Player){ + Player player = (Player) sender; + guiManager.openReRollGui(player); + } + } + + private void createEncahntItem(CommandSender sender){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "BetterEloCommand.createEncahntItem called, sender: "+sender); + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " This command can only be used by online players."); + return ; + } + Player player = (Player) sender; + ItemStack enchantItem = Utils.getEnchantItem(); + player.getInventory().addItem(enchantItem); + } + public void addAntywebLore(Player player, ItemStack itemStack, int radius) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null) { + return; // Przerwij, jeśli nie można pobrać metadanych przedmiotu + } + String antywebLore = ChatColor.GOLD + "" + ChatColor.BOLD + "Antyweb " + radius; + List lore = itemMeta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + lore.add(antywebLore); + itemMeta.setLore(lore); + itemStack.setItemMeta(itemMeta); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Added Antyweb lore with radius "+radius); + + } + public void addZephyrLore(Player player, ItemStack itemStack, int power) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null) { + return; // Przerwij, jeśli nie można pobrać metadanych przedmiotu + } + String zephyrLore = ChatColor.GOLD + "" + ChatColor.BOLD + "Zephyr " + power; + List lore = itemMeta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + lore.add(zephyrLore); + itemMeta.setLore(lore); + itemStack.setItemMeta(itemMeta); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Added Zephyr lore with power "+power); + + } + public void addFlamethrowerLore(Player player, ItemStack itemStack, int radius, int distance) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null) { + return; // Przerwij, jeśli nie można pobrać metadanych przedmiotu + } + String flamethrowerLore = ChatColor.GOLD + "" + ChatColor.BOLD + "Flamethrower " + radius+"/"+distance; + List lore = itemMeta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + lore.add(flamethrowerLore); + itemMeta.setLore(lore); + itemStack.setItemMeta(itemMeta); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Added Antyweb lore with radius "+radius); + + } + public void addElytraLore(Player player, ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + if (itemMeta == null) { + return; // Przerwij, jeśli nie można pobrać metadanych przedmiotu + } + String antywebLore = ChatColor.GOLD + "" + ChatColor.BOLD + "Elytra effect" ; + List lore = itemMeta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + lore.add(antywebLore); + itemMeta.setLore(lore); + itemStack.setItemMeta(itemMeta); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.AQUA + " Added Elytra effect"); + + } + + + private static void createInfiniteFireworkItem(Player player,int power) { + //ItemStack firework = createInfiniteFireworkItem(); + ItemStack firework = new ItemStack(Material.FIREWORK_ROCKET, 1); + FireworkMeta meta = (FireworkMeta) firework.getItemMeta(); + meta.setDisplayName("Infinite Firework"); + meta.setLore(java.util.Arrays.asList("§6§lInfinite usage")); // Gold bold "Infinite usage"; + meta.setPower(power); + firework.setItemMeta(meta); + player.getInventory().addItem(firework); + } + public void handleAddSpawnerCommand(CommandSender sender, String spawnerName, String mobName, int spawnerCooldown,int mobCount, int maxMobs) { + if (sender instanceof Player) { + Player player = (Player) sender; + if (player.isOp()) { + Location targetLocation = player.getTargetBlock(null, 100).getLocation(); + customMobsFileManager.saveSpawner(targetLocation,spawnerName,mobName,spawnerCooldown,mobCount, maxMobs); + } else { + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission!"); + } + } else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterEloCommand:handleAddSpawnerCommand this is only-player command!"); + } + } + private void noPermission(CommandSender sender){ + sender.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.DARK_RED + " You don't have permission to use that command"); } } diff --git a/src/main/java/betterbox/mine/game/betterelo/BetterRanksCheaters.java b/src/main/java/betterbox/mine/game/betterelo/BetterRanksCheaters.java index a81535e..3969601 100644 --- a/src/main/java/betterbox/mine/game/betterelo/BetterRanksCheaters.java +++ b/src/main/java/betterbox/mine/game/betterelo/BetterRanksCheaters.java @@ -22,7 +22,7 @@ public BetterRanksCheaters(JavaPlugin plugin, PluginLogger pluginLogger) { } public void CheckCheatersFromBetterRanks() { - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL3, "CheckCheatersFromBetterRanks called"); + pluginLogger.log(PluginLogger.LogLevel.CHEATERS, "CheckCheatersFromBetterRanks called"); Plugin betterRanksPlugin = plugin.getServer().getPluginManager().getPlugin("BetterRanks"); if (betterRanksPlugin == null || !betterRanksPlugin.isEnabled()) { pluginLogger.log(PluginLogger.LogLevel.WARNING, "BetterRanks plugin is not found or is disabled."); @@ -46,20 +46,20 @@ public void CheckCheatersFromBetterRanks() { FileConfiguration config = YamlConfiguration.loadConfiguration(configFile); Set playerNames = config.getKeys(false); - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL3, "BetterRanksCheaters: CheckCheatersFromBetterRanks checking.."); + pluginLogger.log(PluginLogger.LogLevel.CHEATERS, "BetterRanksCheaters: CheckCheatersFromBetterRanks checking.."); cheatersList.clear(); for (String playerName : playerNames) { String rank = config.getString(playerName + ".rank"); if (rank != null && rank.equalsIgnoreCase("CHEATER")) { cheatersList.add(playerName); - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL3, "BetterRanksCheaters: CheckCheatersFromBetterRanks: adding cheater " + playerName); + pluginLogger.log(PluginLogger.LogLevel.CHEATERS, "BetterRanksCheaters: CheckCheatersFromBetterRanks: adding cheater " + playerName); } } - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL3, "BetterRanksCheaters: CheckCheatersFromBetterRanks: Cheaters found: " + cheatersList); + pluginLogger.log(PluginLogger.LogLevel.CHEATERS, "BetterRanksCheaters: CheckCheatersFromBetterRanks: Cheaters found: " + cheatersList); } public List getCheatersList() { - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL3, "BetterRanksCheaters: getCheatersList called"); + pluginLogger.log(PluginLogger.LogLevel.CHEATERS, "BetterRanksCheaters: getCheatersList called"); return cheatersList; } } diff --git a/src/main/java/betterbox/mine/game/betterelo/ChatNotifier.java b/src/main/java/betterbox/mine/game/betterelo/ChatNotifier.java index f90575e..31aed5a 100644 --- a/src/main/java/betterbox/mine/game/betterelo/ChatNotifier.java +++ b/src/main/java/betterbox/mine/game/betterelo/ChatNotifier.java @@ -1,5 +1,6 @@ package betterbox.mine.game.betterelo; +import org.bukkit.ChatColor; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.Bukkit; @@ -15,11 +16,11 @@ public ChatNotifier(BetterElo plugin) { public void run() { // Wiadomość, którą chcesz wysłać String message = " Remember to use /be claim to claim your rewards!"; - String prefix = "[BetterElo]"; + String prefix = ChatColor.GOLD+""+ChatColor.BOLD +"[BetterElo]"; broadcastFormattedChatMessage(prefix + message); - message = " Use /shop to get our Item-Shop link"; + message = ChatColor.AQUA+" Use /shop to get our Item-Shop link"; broadcastFormattedChatMessage(prefix + message); - message = " Use /discord to get our Discord link"; + message = ChatColor.AQUA+" Use /discord to get our Discord link"; broadcastFormattedChatMessage(prefix + message); } diff --git a/src/main/java/betterbox/mine/game/betterelo/CheaterCheckScheduler.java b/src/main/java/betterbox/mine/game/betterelo/CheaterCheckScheduler.java index d04d807..ddefd9d 100644 --- a/src/main/java/betterbox/mine/game/betterelo/CheaterCheckScheduler.java +++ b/src/main/java/betterbox/mine/game/betterelo/CheaterCheckScheduler.java @@ -15,11 +15,11 @@ public CheaterCheckScheduler(Plugin plugin, BetterRanksCheaters betterRanksCheat this.betterRanksCheaters = betterRanksCheaters; this.scheduler = scheduler; this.pluginLogger = pluginLogger; - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "CheaterCheckScheduler called"); + pluginLogger.log(PluginLogger.LogLevel.CHEATERS, "CheaterCheckScheduler called"); } public void startScheduler() { - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL2, "startScheduler called"); + pluginLogger.log(PluginLogger.LogLevel.CHEATERS, "startScheduler called for betterRanksCheaters.CheckCheatersFromBetterRanks()"); int delay = 0; // Opóźnienie początkowe (0 ticków) int period = 100; // Okres w tickach (20 ticków to 1 sekunda) diff --git a/src/main/java/betterbox/mine/game/betterelo/CustomMobs.java b/src/main/java/betterbox/mine/game/betterelo/CustomMobs.java new file mode 100644 index 0000000..3df8977 --- /dev/null +++ b/src/main/java/betterbox/mine/game/betterelo/CustomMobs.java @@ -0,0 +1,691 @@ +package betterbox.mine.game.betterelo; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.*; +import org.bukkit.attribute.Attribute; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.*; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +import java.util.UUID; + +public class CustomMobs { + private Map customMobsMap = new HashMap<>(); + private Map formattingMap = new HashMap<>(); + private final PluginLogger pluginLogger; + private final JavaPlugin plugin; + private final BetterElo betterElo; + private final FileRewardManager fileRewardManager; + private final CustomMobsFileManager fileManager; + private BukkitTask spawnerTask; + public Map spawnerLastSpawnTimes = new HashMap<>(); // Mapa przechowująca czas ostatniego respa mobów z każdego spawnera + public Map spawnedMobsMap = new HashMap<>(); + + static class CustomMob { + String mobName, dropTableName, spawnerName; + boolean dropEMKS; + EntityType entityType; + LivingEntity entity; + ItemStack helmet, chestplate, leggings, boots, weapon; + //HashMap< Double,ItemStack> dropTable; + List dropTable; + double armor, speed, attackDamage, EMKSchance, regenPercent, knockbackResistance, eloPoints, eloMultiplier; + String passengerMobName; // Nowe pole dla nazwy pasażera + int hp, attackSpeed, defense, regenSeconds; + Map customMetadata; // Nowe pole do przechowywania niestandardowych metadanych + JavaPlugin plugin; + CustomMobsFileManager dropFileManager; + + CustomMob(JavaPlugin plugin, CustomMobsFileManager dropFileManager, String mobName, EntityType entityType, ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots, ItemStack weapon, double armor, int hp, double speed, double attackDamage, int attackSpeed, Map customMetadata, String dropTableName, int defense, String passengerMobName, int regenSeconds,double regenPercent, double knockbackResistance, double eloPoints, double eloMultiplier) { + this.plugin = plugin; + this.regenSeconds=regenSeconds; + this.regenPercent=regenPercent; + this.passengerMobName=passengerMobName; + this.mobName = mobName; + this.entity = entity; + if (weapon != null) { + this.weapon = weapon; + } else { + //plugin.getLogger().warning(mobName + " does not have weapon set. Setting AIR"); + this.weapon = new ItemStack(Material.AIR); + } + + this.entityType = entityType; + if (helmet != null) { + this.helmet = helmet; + } + if (chestplate != null) { + this.chestplate = chestplate; + } + if (leggings != null) { + this.leggings = leggings; + } + if (boots != null) { + this.boots = boots; + } + this.dropFileManager = dropFileManager; + this.dropTableName = dropTableName; + //this.dropTable = dropFileManager.loadCustomDrops(dropTableName); + this.dropTable = dropFileManager.loadCustomDropsv2(dropTableName); + this.armor = armor; + this.hp = hp; + this.attackSpeed = attackSpeed; + this.speed = speed; + this.defense = defense; + this.attackDamage = attackDamage; + this.customMetadata = customMetadata; + this.knockbackResistance = knockbackResistance; + this.eloPoints = eloPoints; + this.eloMultiplier = eloMultiplier; + //setupMob(); + } + + CustomMob(JavaPlugin plugin, CustomMobsFileManager dropFileManager, String mobName, EntityType entityType, double armor, int hp, double speed, double attackDamage, int attackSpeed, Map customMetadata, String dropTableName, int defense, int regenSeconds,double regenPercent, double knockbackResistance, double eloPoints, double eloMultiplier) { + this.plugin = plugin; + this.regenSeconds=regenSeconds; + this.regenPercent=regenPercent; + this.mobName = mobName; + this.entity = entity; + this.entityType = entityType; + this.dropFileManager = dropFileManager; + this.dropTableName = dropTableName; + //this.dropTable = dropFileManager.loadCustomDrops(dropTableName); + this.dropTable = dropFileManager.loadCustomDropsv2(dropTableName); + this.armor = armor; + this.hp = hp; + this.attackSpeed = attackSpeed; + this.speed = speed; + this.defense = defense; + this.attackDamage = attackDamage; + this.customMetadata = customMetadata; + this.knockbackResistance = knockbackResistance; + this.eloPoints = eloPoints; + this.eloMultiplier = eloMultiplier; + //setupMob(); + } + CustomMob(JavaPlugin plugin, CustomMobsFileManager dropFileManager, String mobName, EntityType entityType, double armor, int hp, double speed, double attackDamage, int attackSpeed, Map customMetadata, String dropTableName, int defense, String passengerMobName,int regenSeconds,double regenPercent, double knockbackResistance, double eloPoints, double eloMultiplier) { + this.plugin = plugin; + this.regenSeconds=regenSeconds; + this.knockbackResistance = knockbackResistance; + this.regenPercent=regenPercent; + this.mobName = mobName; + this.entity = entity; + this.entityType = entityType; + this.dropFileManager = dropFileManager; + this.dropTableName = dropTableName; + //this.dropTable = dropFileManager.loadCustomDrops(dropTableName); + this.dropTable = dropFileManager.loadCustomDropsv2(dropTableName); + this.passengerMobName = passengerMobName; + this.armor = armor; + this.hp = hp; + this.attackSpeed = attackSpeed; + this.speed = speed; + this.defense = defense; + this.attackDamage = attackDamage; + this.customMetadata = customMetadata; + this.eloPoints = eloPoints; + this.eloMultiplier = eloMultiplier; + //setupMob(); + } + + // Metoda do stworzenia i ustawienia encji moba + public void spawnMob(Location location) { + if (this.entityType == null) { + plugin.getLogger().warning("EntityType not set for " + mobName); + return; + } + this.entity = (LivingEntity) location.getWorld().spawnEntity(location, entityType); + + setupMob(); // Teraz wywołujemy setupMob() po stworzeniu encji + ((BetterElo) plugin).registerCustomMob(this.entity, this); + + } + public Entity getEntity(){ + return entity; + } + + + public CustomMob cloneForSpawn(Location spawnLocation, String mobType) { + + CustomMob newMob = null; + if (mobType.equals("SKELETON") || mobType.equals("ZOMBIE") || mobType.equals("STRAY")|| mobType.equals("HUSK")|| mobType.equals("WITHER_SKELETON")) { + newMob = new CustomMob(this.plugin, this.dropFileManager, this.mobName, this.entityType, + this.helmet.clone(), this.chestplate.clone(), + this.leggings.clone(), this.boots.clone(), this.weapon.clone(), + this.armor, this.hp, this.speed, + this.attackDamage, this.attackSpeed, new HashMap<>(this.customMetadata), this.dropTableName, this.defense, this.passengerMobName, this.regenSeconds, this.regenPercent, this.knockbackResistance, this.eloPoints, this.eloMultiplier); + newMob.spawnMob(spawnLocation); + } else { + newMob = new CustomMob(this.plugin, this.dropFileManager, this.mobName, this.entityType, + this.armor, this.hp, this.speed, + this.attackDamage, this.attackSpeed, new HashMap<>(this.customMetadata), this.dropTableName, this.defense, this.regenSeconds, this.regenPercent, this.knockbackResistance, this.eloPoints, this.eloMultiplier); + newMob.spawnMob(spawnLocation); + } + return newMob; + } + public CustomMob cloneForSpawn(Location spawnLocation) { + + CustomMob newMob = null; + newMob = new CustomMob(this.plugin, this.dropFileManager, this.mobName, this.entityType, + this.armor, this.hp, this.speed, + this.attackDamage, this.attackSpeed, new HashMap<>(this.customMetadata), this.dropTableName, this.defense, this.passengerMobName, this.regenSeconds, this.regenPercent, this.knockbackResistance, this.eloPoints, this.eloMultiplier); + newMob.spawnMob(spawnLocation); + + return newMob; + } + + private void setupMob() { + if (entity == null) { + plugin.getLogger().warning("Encja nie została stworzona dla " + mobName); + return; + } + //this.dropTable = dropFileManager.loadCustomDrops(mobName); + // Ustawienie wyposażenia i atrybutów + entity.getEquipment().setHelmet(helmet); + entity.getEquipment().setChestplate(chestplate); + entity.getEquipment().setLeggings(leggings); + entity.getEquipment().setBoots(boots); + entity.setPersistent(true); + if (weapon != null) { + entity.getEquipment().setItemInMainHand(weapon); + } else { + //plugin.getLogger().warning(mobName + " does not have weapon set. Setting AIR"); + entity.getEquipment().setItemInMainHand(new ItemStack(Material.AIR)); + } + entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(hp); + entity.setHealth(hp); + entity.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(speed); + entity.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(attackDamage); + entity.getAttribute(Attribute.GENERIC_KNOCKBACK_RESISTANCE).setBaseValue(knockbackResistance); // Ustawienie knockbackResistance + //plugin.getLogger().info("attackSpeed: "+attackSpeed); + //entity.getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(attackSpeed); + + if (customMetadata.containsKey("MobName")){ + entity.setCustomName(FormatUtil.applyFormatting(customMetadata.get("MobName").toString())); + }else{ + entity.setCustomName(mobName); + } + + + entity.setCustomNameVisible(true); + + // Ustawianie niestandardowych metadanych + customMetadata.forEach((key, value) -> entity.setMetadata(key, new FixedMetadataValue(plugin, value))); + entity.setMetadata("armor", new FixedMetadataValue(plugin, armor)); + entity.setMetadata("defense", new FixedMetadataValue(plugin, defense)); + } + + public String getMobName() { + return this.mobName; + } + + + + } + public enum ChatColor { + BLACK("&0"), + DARK_BLUE("&1"), + DARK_GREEN("&2"), + DARK_AQUA("&3"), + DARK_RED("&4"), + DARK_PURPLE("&5"), + GOLD("&6"), + GRAY("&7"), + DARK_GRAY("&8"), + BLUE("&9"), + GREEN("&a"), + AQUA("&b"), + RED("&c"), + LIGHT_PURPLE("&d"), + YELLOW("&e"), + WHITE("&f"), + OBFUSCATED("&k"), + BOLD("&l"), + STRIKETHROUGH("&m"), + UNDERLINE("&n"), + ITALIC("&o"), + RESET("&r"); + + private final String code; + + ChatColor(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public static String translateAlternateColorCodes(String message) { + for (ChatColor color : values()) { + message = message.replace(color.getCode(), color.name()); + } + return message; + } + } + public static class FormatUtil { + public static String applyFormatting(String input) { + return ChatColor.translateAlternateColorCodes(input); + } + } + + public static void main(String[] args) { + String input = "&6<est"; + String formatted = FormatUtil.applyFormatting(input); + System.out.println(formatted); // Wypisze coś w stylu "GOLD BOLD test" jeśli zaimplementujesz odpowiednie zamiany w ChatColor.translateAlternateColorCodes + } + + + + public CustomMobs(PluginLogger pluginLogger, JavaPlugin plugin, CustomMobsFileManager fileManager, FileRewardManager fileRewardManager, BetterElo betterElo) { + this.plugin = plugin; + this.betterElo = betterElo; + this.pluginLogger = pluginLogger; + this.fileManager = fileManager; + this.fileRewardManager = fileRewardManager; + loadCustomMobs(UUID.randomUUID().toString()); + } + + public void spawnModifiedZombie(Player player, String mobName, int mobCount,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnModifiedZombie called, player: " + player.getName() + ", mobName: " + mobName + ", mobCount: " + mobCount); + Location playerLocation = player.getLocation(); + //World world = player.getWorld(); + for (int i = 0; i < mobCount; i++) { + spawnCustomMob(playerLocation, mobName,transactionID); + } + } + + public void updateCustomMobName(LivingEntity mob,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.updateZombieCustomName called, mob.getName(): " + mob.getName(),transactionID); + if (!mob.hasMetadata("MobName")) { + return; + } + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.updateZombieCustomName mobName: " + mob.getName() + ", currentHP: " + mob.getHealth() + ", maxHP: " + mob.getMaxHealth(),transactionID); + List values = mob.getMetadata("MobName"); + MetadataValue value = values.get(0); + String customName = value.asString(); + Component nameComponent; + + nameComponent = Component.text(FormatUtil.applyFormatting(customName)) + .append(Component.text(" HP: " + Math.round(mob.getHealth()) + "/" + Math.round(mob.getMaxHealth()), NamedTextColor.WHITE)); + + + mob.customName(nameComponent); + mob.setCustomNameVisible(true); + } + + + + /* + public static int dropAverageDamage() { + // Używamy funkcji wykładniczej do zmniejszenia prawdopodobieństwa wyższych wartości + double x = -Math.log(random.nextDouble()) / 5; // Zmniejszamy stromość rozkładu + int bonus = (int) Math.round(x * 70); // Zwiększamy zakres skalowania, ale nadal ograniczamy do 60 + + // Ograniczamy wartość bonusu do maksymalnie 60% + bonus = Math.min(bonus, 60); + + return bonus; + } + + */ + + public void spawnCustomMobFromSpawner() { + String transactionID = UUID.randomUUID().toString(); + Map spawnersData = fileManager.spawnersData; + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnCustomMobFromSpawner called. Loaded spawners: " + spawnersData,transactionID); + // Sprawdzenie, czy istnieją spawnerzy w pliku + if (spawnersData.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "No spawners found in spawners.yml.",transactionID); + return; + } + + long currentTime = System.currentTimeMillis(); + + for (Map.Entry entry : spawnersData.entrySet()) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner checking spawner: " + entry,transactionID); + String spawnerName = entry.getKey(); + CustomMobsFileManager.SpawnerData spawnerData = entry.getValue(); + Location location = getLocationFromString(spawnerData.location); + + while (location.getBlock().getType() != Material.AIR) { + location.add(0, 1, 0); // Zwiększ y o 1 + if (location.getBlockY() > location.getWorld().getMaxHeight()) { + // Jeśli przekraczamy maksymalną wysokość, przerwij pętlę, aby uniknąć pętli nieskończonej + System.out.println("Reached the top of the world without finding an AIR block."); + break; + } + } + location.add(0, 1, 0); + + // Sprawdzenie cooldownu + if (!canSpawnMobs(spawnerName, fileManager.getSpawnerCooldown(spawnerName),transactionID)) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "Spawner " + spawnerName + " is on cooldown. Current spawnedMobCount: " + spawnerData.spawnedMobCount,transactionID); + continue; // Skip spawning if on cooldown + } + + // Spawnowanie zombiaków na podanej lokalizacji + if (location != null) { + World world = location.getWorld(); + if (world != null) { + int mobCount = spawnerData.mobCount; + // Get the remaining slots for spawning mobs + int maxMobs = fileManager.getSpawnerMaxMobs(spawnerName); + int remainingSlots = Math.max(0, maxMobs - spawnerData.spawnedMobCount); + String mobName = fileManager.getSpawnerMobName(spawnerName); + //pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner "+spawnerName+", maxMobs: "+maxMobs+", remaining slots: "+remainingSlots); + if (remainingSlots == 0) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner 0 remaining slots for " + spawnerName,transactionID); + continue; + } + + int mobsToSpawn = Math.min(mobCount, remainingSlots); + int spawnedMobs = 0; + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner " + spawnerName + ", maxMobs: " + maxMobs + ", remaining slots: " + remainingSlots + ", mobsToSpawn: " + mobsToSpawn + ", spawnerData.spawnedMobCount: " + spawnerData.spawnedMobCount,transactionID); + for (int i = 0; i < mobsToSpawn; i++) { + spawnCustomMob(location, spawnerName, mobName,transactionID); + spawnerData.spawnedMobCount++; + spawnedMobs++; + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner spawnedMobs: " + spawnedMobs,transactionID); + // Ustawianie czasu ostatniego respa mobów z tego spawnera + spawnerLastSpawnTimes.put(spawnerName, currentTime); + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid world specified for spawner " + spawnerName,transactionID); + } + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid location specified for spawner " + spawnerName,transactionID); + } + } + } + + public void spawnerForceSpawn(String spawnerName) { + String transactionID = UUID.randomUUID().toString(); + //pluginLogger.log(PluginLogger.LogLevel.INFO, "CustomMobs.spawnerForceSpawn called with " + spawnerName+" spawnedMobsMap"+spawnedMobsMap.toString()); + + Map spawnersData = fileManager.spawnersData; + if (spawnedMobsMap == null || spawnedMobsMap.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "CustomMobs.spawnerForceSpawn. The spawnedMobsMap is empty or null.",transactionID); + }else { + try { + + Iterator> iterator = spawnedMobsMap.entrySet().iterator(); + //CustomMob customMob = betterElo.getCustomMobFromEntity(entity) ; + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn. Checking key " + entry.getKey() + " with value " + entry.getValue(),transactionID); + if (spawnerName.equals(entry.getValue())) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn. " + spawnerName + " matching key " + entry.getKey() + ", value " + entry.getValue(),transactionID); + Entity entity = Bukkit.getServer().getEntity(entry.getKey()); + if (entity != null && !entity.isDead()) { + entity.remove(); // Usuwa encję z świata + + iterator.remove(); // Bezpieczne usuwanie wpisu podczas iteracji + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn. Removing living mob from spawner" + spawnerName,transactionID); + } + } + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.spawnerForceSpawn exception: " + e.getMessage(),transactionID); + } + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn called. Loaded spawners: " + spawnersData); + // Sprawdzenie, czy istnieją spawnerzy w pliku + if (spawnersData.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "No spawners found in spawners.yml.",transactionID); + return; + } + + long currentTime = System.currentTimeMillis(); + + for (Map.Entry entry : spawnersData.entrySet()) { + if(!entry.getKey().equals(spawnerName)){ + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn checking spawner: " + entry,transactionID); + continue; + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn spawner: " + spawnerName+" found.",transactionID); + CustomMobsFileManager.SpawnerData spawnerData = entry.getValue(); + Location location = getLocationFromString(spawnerData.location); + + + // Spawnowanie zombiaków na podanej lokalizacji + if (location != null) { + World world = location.getWorld(); + if (world != null) { + int mobCount = spawnerData.mobCount; + + String mobName = fileManager.getSpawnerMobName(spawnerName); + //pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner "+spawnerName+", maxMobs: "+maxMobs+", remaining slots: "+remainingSlots); + int spawnedMobs = 0; + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn " + spawnerName + ", spawnerData.spawnedMobCount: " + spawnerData.spawnedMobCount,transactionID); + for (int i = 0; i < mobCount; i++) { + spawnCustomMob(location, spawnerName, mobName,transactionID); + spawnerData.spawnedMobCount++; + spawnedMobs++; + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn spawnedMobs: " + spawnedMobs,transactionID); + // Ustawianie czasu ostatniego respa mobów z tego spawnera + spawnerLastSpawnTimes.put(spawnerName, currentTime); + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid world specified for spawner " + spawnerName,transactionID); + } + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid location specified for spawner " + spawnerName,transactionID); + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn spawnedMobsMap"+spawnedMobsMap.toString(),transactionID); + } + } + + public Location getLocationFromString(String locationString) { + try { + String[] parts = locationString.split(","); + if (parts.length == 4) { + World world = Bukkit.getWorld(parts[0]); + double x = Double.parseDouble(parts[1]); + double y = Double.parseDouble(parts[2]); + double z = Double.parseDouble(parts[3]); + //pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.getLocationFromString locationString: "+locationString+", "); + return new Location(world, x, y, z); + } else { + return null; + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Error parsing location string: " + e.getMessage()); + return null; + } + } + + public void startSpawnerScheduler() { + spawnerTask = new BukkitRunnable() { + @Override + public void run() { + spawnCustomMobFromSpawner(); + } + }.runTaskTimer(plugin, 0, 300); // Interval converted to ticks (1 second) + } + + public void stopSpawnerScheduler() { + if (spawnerTask != null) { + spawnerTask.cancel(); + } + } + private boolean canSpawnMobs(String spawnerName, int cooldown,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.canSpawnMobs " + spawnerName + " cooldown: "+cooldown,transactionID); + if (!spawnerLastSpawnTimes.containsKey(spawnerName)) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.canSpawnMobs check passed, spawner not on the list, return true",transactionID); + return true; + } + long lastUsage = spawnerLastSpawnTimes.get(spawnerName); + long currentTime = System.currentTimeMillis(); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.canSpawnMobs spawnerName: "+spawnerName+", lastUsage: "+lastUsage+", currentTime: "+currentTime+", timeleft: "+(cooldown-((currentTime-lastUsage)/1000)),transactionID); + return (currentTime - lastUsage) >= (cooldown*1000L); + } + public void decreaseMobCount(String spawnerName) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS,"CustomMobs.decreaseMobCount called spawnerName: "+spawnerName); + if (fileManager.spawnersData.containsKey(spawnerName)) { + CustomMobsFileManager.SpawnerData spawnerData = fileManager.spawnersData.get(spawnerName); + if(spawnerData.spawnedMobCount>0) { + spawnerData.spawnedMobCount--; // Zmniejszenie liczby mobów o 1 + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS,"CustomMobs.decreaseMobCount decreased spawnedMobCount for "+spawnerName+". Current spawnedMobCount: "+spawnerData.spawnedMobCount); + }else{ + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS,"CustomMobs.decreaseMobCount spawnedMobCount for "+spawnerName+" in lower than 0, setting 0. Current spawnedMobCount: "+spawnerData.spawnedMobCount); + spawnerData.spawnedMobCount=0; + } + + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Spawner " + spawnerName + " not found."); + } + } + private Location adjustLocationToAirAbove(Location startLocation) { + // Zaczynamy od aktualnej lokalizacji + Location currentLocation = startLocation.clone(); + while (currentLocation.getBlock().getType() != Material.AIR && currentLocation.getY() < currentLocation.getWorld().getMaxHeight()) { + // Przesuń o jeden blok w górę + currentLocation.add(0, 1, 0); + } + return currentLocation; + } + public void saveCustomMobData(CustomMob customMob) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS,"CustomMobs.saveCustomMobData called"); + File customMobsFolder = new File(plugin.getDataFolder(), "customMobs"); + if (!customMobsFolder.exists()) { + customMobsFolder.mkdirs(); + } + + File mobFile = new File(customMobsFolder, customMob.getMobName() + ".yml"); + YamlConfiguration mobData = new YamlConfiguration(); + + // Zapisz podstawowe dane moba + mobData.set("type", customMob.entity.getType().toString()); // Dodano typ moba + mobData.set("mobName", customMob.mobName); + mobData.set("armor", customMob.armor); + mobData.set("hp", customMob.hp); + mobData.set("speed", customMob.speed); + mobData.set("attackDamage", customMob.attackDamage); + mobData.set("customMetadata", customMob.customMetadata); + + // Zapisz wyposażenie i zaklęcia + fileManager.saveItemStackData(mobData, "equipment.helmet", customMob.helmet); + fileManager.saveItemStackData(mobData, "equipment.chestplate", customMob.chestplate); + fileManager.saveItemStackData(mobData, "equipment.leggings", customMob.leggings); + fileManager.saveItemStackData(mobData, "equipment.boots", customMob.boots); + + try { + mobData.save(mobFile); + } catch (IOException e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR,"CustomMobs.saveCustomMobData exception "+e.getMessage()); + } + } + + // Metoda pomocnicza do zapisywania danych ItemStack, w tym zaklęć + public void loadCustomMobs(String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS,"CustomMobs.loadCustomMobs called.",transactionID); + // Wczytaj customowe moby i przechowaj je w pamięci + // Dla każdego pliku moba w folderze customMobs + for (File mobFile : fileManager.getCustomMobFiles()) { + if (!mobFile.getName().equals("customMobs/spawners.yml")) + { + try { + CustomMob customMob = fileManager.loadCustomMob(plugin, fileRewardManager, mobFile,transactionID); + if (customMob != null) { + customMobsMap.put(customMob.getMobName(), customMob); + }else + { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.loadCustomMobs could not load custom mob "+customMob,transactionID); + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.loadCustomMobs exception: " + e.getMessage(),transactionID); + } + } + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.loadCustomMobs spawners.yml file detected, skipping",transactionID); + } + } + + + public Entity getEntityForCustomMob(CustomMob customMob) { + // Sprawdzenie, czy przypisana encja do moba istnieje + if (customMob != null && customMob.entity != null) { + return customMob.entity; // Zwróć encję, jeśli jest już przypisana + } + // W przypadku braku encji, możemy zwrócić null lub rozważyć inne działanie, np. logowanie + return null; // Zwróć null, jeśli encja nie jest ustawiona + } + + public void spawnCustomMob(Location location, String spawnerName, String mobName,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob called, mobName: " + mobName+", spawnerName: "+spawnerName+", location: "+location,transactionID); + CustomMob templateMob = customMobsMap.get(mobName); + if (templateMob != null) { + Location adjustedLocation = adjustLocationToAirAbove(location); + CustomMob newMob=null; + + if(templateMob.passengerMobName!=null){ + newMob = templateMob.cloneForSpawn(adjustedLocation); + newMob.customMetadata.put("SpawnerName", spawnerName); + newMob.spawnerName = spawnerName; + CustomMob passengerTemplateMob = customMobsMap.get(templateMob.passengerMobName); + if(passengerTemplateMob!=null) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob spawning newMob.passengerMobName: "+newMob.passengerMobName,transactionID); + CustomMob newPassengerMob = passengerTemplateMob.cloneForSpawn(adjustedLocation, passengerTemplateMob.entityType.toString()); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob newMob.passengerMobName: "+newMob.passengerMobName+" spawned, adding as passenger",transactionID); + newMob.entity.addPassenger(newPassengerMob.entity); + newPassengerMob.customMetadata.put("SpawnerName", spawnerName); + newPassengerMob.spawnerName = spawnerName; + spawnedMobsMap.put(newPassengerMob.entity.getUniqueId(), spawnerName); + } + }else{ + newMob = templateMob.cloneForSpawn(adjustedLocation, templateMob.entityType.toString()); + newMob.customMetadata.put("SpawnerName", spawnerName); + newMob.spawnerName = spawnerName; + } + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobs.spawnCustomMob newMob.dropTablename: "+newMob.dropTableName+", newMob.dropTable: "+newMob.dropTable,transactionID); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob newMob.spawnerName: "+newMob.spawnerName,transactionID); + try{ + spawnedMobsMap.put(newMob.entity.getUniqueId(), spawnerName); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Mob spawned with UUID: " + newMob.entity.getUniqueId() + ", spawnerName:" + newMob.spawnerName,transactionID); + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.spawnCustomMob exception: "+e.getMessage(),transactionID); + } + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.spawnCustomMob failed, mob not found: " + mobName,transactionID); + } + } + public void spawnCustomMob(Location location, String mobName,String transactionID) { + + CustomMob templateMob = customMobsMap.get(mobName); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob called, mobName: " + mobName+", location: "+location+", mobtype: "+templateMob.entityType.toString(),transactionID); + if (templateMob != null) { + Location adjustedLocation = adjustLocationToAirAbove(location); + CustomMob newMob = null; + + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob newMob.passengerMobName: "+templateMob.passengerMobName); + if(templateMob.passengerMobName!=null){ + newMob = templateMob.cloneForSpawn(adjustedLocation); + CustomMob passengerTemplateMob = customMobsMap.get(templateMob.passengerMobName); + if(passengerTemplateMob!=null) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob spawning newMob.passengerMobName: "+newMob.passengerMobName); + CustomMob newPassengerMob = passengerTemplateMob.cloneForSpawn(adjustedLocation, passengerTemplateMob.entityType.toString()); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob newMob.passengerMobName: "+newMob.passengerMobName+" spawned, adding as passenger"); + newMob.entity.addPassenger(newPassengerMob.entity); + } + }else{ + newMob = templateMob.cloneForSpawn(adjustedLocation, templateMob.entityType.toString()); + } + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.spawnCustomMob failed, mob not found: " + mobName); + } + } + + + + + +} diff --git a/src/main/java/betterbox/mine/game/betterelo/CustomMobsFileManager.java b/src/main/java/betterbox/mine/game/betterelo/CustomMobsFileManager.java new file mode 100644 index 0000000..4f24435 --- /dev/null +++ b/src/main/java/betterbox/mine/game/betterelo/CustomMobsFileManager.java @@ -0,0 +1,574 @@ +package betterbox.mine.game.betterelo; + +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.*; + +import org.bukkit.Location; + +public class CustomMobsFileManager { + private JavaPlugin plugin; + private PluginLogger pluginLogger; + private File spawnersFile; + public Map spawnersData = new HashMap<>(); + + + public CustomMobsFileManager(String folderPath, JavaPlugin plugin, PluginLogger pluginLogger) { + + this.plugin = plugin; + this.pluginLogger = pluginLogger; + CreateCustomMobsFolder(folderPath); + CreateSpawnersFile(folderPath); + + + } + // Klasa wewnętrzna do przechowywania danych spawnera + static class SpawnerData { + String spawnerName; + int maxDistance; + String location; + String mobName; + int cooldown; + int mobCount; + int spawnedMobCount; // Counter for spawned mobs + int maxMobs; + String passengerMobName; // Nazwa CustomMob jako pasażer + + SpawnerData(String spawnerName, String location, String mobName, int cooldown, int mobCount, int maxMobs, int maxDistance) { + this.spawnerName = spawnerName; + this.location = location; + this.mobName = mobName; + this.cooldown = cooldown; + this.mobCount = mobCount; + this.maxMobs = maxMobs; + this.maxDistance = maxDistance; + this.spawnedMobCount = 0; // Initialize the spawned mob counter to 0 + } + SpawnerData(String spawnerName, String location, String mobName, String passengerMobName, int cooldown, int mobCount, int maxMobs, int maxDistance) { + this.spawnerName = spawnerName; + this.location = location; + this.mobName = mobName; + this.passengerMobName = passengerMobName; // Inicjalizacja z nazwą CustomMob jako pasażer + this.cooldown = cooldown; + this.mobCount = mobCount; + this.maxMobs = maxMobs; + this.maxDistance = maxDistance; + this.spawnedMobCount = 0; + } + public int getSpawnedMobCount() { + return this.spawnedMobCount; + } + public int getMaxMobs() { + return this.maxMobs; + } + public int getMobsPerSpawn() { + return this.mobCount; + } + public int getCooldown() { + return this.cooldown; + } + public int getMaxDistance() {return this.maxDistance;} + } + public class DropItem { + private double dropChance; + private ItemStack itemStack; + private boolean avgDmgBonus; + private int maxDamage; + + public DropItem(double dropChance, ItemStack itemStack, boolean avgDmgBonus) { + this.dropChance = dropChance; + this.itemStack = itemStack; + this.avgDmgBonus = avgDmgBonus; + } + + public DropItem(double dropChance, ItemStack itemStack, boolean avgDmgBonus, int maxDamage) { + this.dropChance = dropChance; + this.maxDamage = maxDamage; + this.itemStack = itemStack; + this.avgDmgBonus = avgDmgBonus; + } + public double getDropChance() { + return dropChance; + } + + public void setDropChance(double dropChance) { + this.dropChance = dropChance; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + } + + public boolean isAvgDmgBonus() { + return avgDmgBonus; + } + + public int getMaxDamage() { + return maxDamage; + } + + public boolean hasmaxDamage() { + return maxDamage>0; + } + + public void setAvgDmgBonus(boolean avgDmgBonus) { + this.avgDmgBonus = avgDmgBonus; + } + } + + + private void CreateCustomMobsFolder(String folderPath) { + try { + File customMobsFolder = new File(folderPath, "customMobs"); + if (!customMobsFolder.exists()) { + customMobsFolder.mkdirs(); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobsFileManager.CreateCustomMobsFolder folder created."); + } else { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobsFileManager.CreateCustomMobsFolder folder already exists."); + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobsFileManager.CreateCustomMobsFolder exception: " + e.getMessage()); + } + } + private void CreateExampleSpawnersFile(File spawnersFile){ + try (InputStream in = plugin.getResource("customMobs/spawners.yml")) { + if (in == null) { + plugin.getLogger().severe("Resource 'customDropTables/spawners.yml not found."); + return; + } + Files.copy(in, spawnersFile.toPath()); + } catch (IOException e) { + plugin.getLogger().severe("Could not save spawners.yml to " + spawnersFile + ": " + e.getMessage()); + } + } + private void CreateSpawnersFile(String folderPath) { + try { + String spawnersFileName = "spawners.yml"; + spawnersFile = new File(folderPath + File.separator + "customMobs", spawnersFileName); + if (!spawnersFile.exists()) { + CreateExampleSpawnersFile(spawnersFile); + } else { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "CustomMobsFileManager.CreateSpawnersFile file already exists."); + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobsFileManager.CreateSpawnersFile exception: " + e.getMessage()); + } + } + + public void loadSpawners() { + if (spawnersFile == null) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Spawners file is not initialized."); + return; + } + FileConfiguration config = YamlConfiguration.loadConfiguration(spawnersFile); + pluginLogger.log(PluginLogger.LogLevel.INFO, "CustomMobsFileManager.loadSpawners "); + ConfigurationSection spawnersSection = config.getConfigurationSection("spawners"); + if (spawnersSection == null) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "No spawners defined in spawners.yml."); + return; + } + + for (String key : spawnersSection.getKeys(false)) { + ConfigurationSection spawnerSection = spawnersSection.getConfigurationSection(key); + if (spawnerSection != null) { + String location = spawnerSection.getString("location"); + String mobName = spawnerSection.getString("mobName"); + int cooldown = spawnerSection.getInt("cooldown"); + int mobCount = spawnerSection.getInt("mobsPerSpawn"); + int maxMobs = spawnerSection.getInt("maxMobs"); + //default 20 blocks + int maxDistance = 20; + if(spawnerSection.contains("maxDistance")) { + maxDistance = spawnerSection.getInt("maxDistance"); + } + + String passengerMobName = spawnerSection.getString("passengerMobName", null); + + // Zapisywanie danych spawnera do struktury w pamięci + spawnersData.put(key, new SpawnerData(key, location, mobName, passengerMobName, cooldown, mobCount, maxMobs, maxDistance)); + pluginLogger.log(PluginLogger.LogLevel.INFO, "Spawner " + key + " loaded with passenger " + passengerMobName); + } + } + pluginLogger.log(PluginLogger.LogLevel.INFO, "Loaded spawners data from file."); + } + + public void saveSpawner(Location location, String spawnerName, String mobName, int cooldown, int mobCount, int maxMobs) { + FileConfiguration config = YamlConfiguration.loadConfiguration(spawnersFile); + + // Zapisywanie danych spawnera + String path = "spawners." + spawnerName; + config.set(path + ".location", location.getWorld().getName() + "," + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ()); + config.set(path + ".mobName", mobName); + config.set(path + ".cooldown", cooldown); + config.set(path + ".mobsPerSpawn", mobCount); + config.set(path + ".maxMobs", maxMobs); + try { + config.save(spawnersFile); + pluginLogger.log(PluginLogger.LogLevel.INFO, "Spawner " + spawnerName + " saved to file."); + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Could not save spawner " + spawnerName + " to file: " + e.getMessage()); + } + + } + public int getMaxDistance(String spawnerName){ + if (spawnersData.containsKey(spawnerName)) { + // Retrieve the SpawnerData object corresponding to the spawnerName + SpawnerData spawnerData = spawnersData.get(spawnerName); + // Return the cooldown value + //pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "Spawner '" + spawnerName + "' spawnerData.maxDistance: "+spawnerData.maxDistance); + return spawnerData.maxDistance; + } else { + // If the spawnerName is not found, log an error and return a default value or throw an exception + pluginLogger.log(PluginLogger.LogLevel.ERROR, "getMaxDistance Spawner '" + spawnerName + "' not found."); + return 20; // or any other default value that indicates an error + } + } + public String getSpawnerMobName(String spawnerName){ + if (spawnersData.containsKey(spawnerName)) { + // Retrieve the SpawnerData object corresponding to the spawnerName + SpawnerData spawnerData = spawnersData.get(spawnerName); + // Return the cooldown value + return spawnerData.mobName; + } else { + // If the spawnerName is not found, log an error and return a default value or throw an exception + pluginLogger.log(PluginLogger.LogLevel.ERROR, "getSpawnerMobName Spawner '" + spawnerName + "' not found."); + return null; // or any other default value that indicates an error + } + } + public String getSpawnerLocation(String spawnerName){ + if (spawnersData.containsKey(spawnerName)) { + // Retrieve the SpawnerData object corresponding to the spawnerName + SpawnerData spawnerData = spawnersData.get(spawnerName); + // Return the cooldown value + return spawnerData.location; + } else { + // If the spawnerName is not found, log an error and return a default value or throw an exception + pluginLogger.log(PluginLogger.LogLevel.ERROR, "getSpawnerLocation Spawner '" + spawnerName + "' not found."); + return null; // or any other default value that indicates an error + } + } + public int getSpawnerCooldown(String spawnerName) { + // Check if the spawnerName exists in the spawnersData map + if (spawnersData.containsKey(spawnerName)) { + // Retrieve the SpawnerData object corresponding to the spawnerName + SpawnerData spawnerData = spawnersData.get(spawnerName); + // Return the cooldown value + return spawnerData.cooldown; + } else { + // If the spawnerName is not found, log an error and return a default value or throw an exception + pluginLogger.log(PluginLogger.LogLevel.ERROR, "getSpawnerCooldown Spawner '" + spawnerName + "' not found."); + return -1; // or any other default value that indicates an error + } + } + public int getSpawnerMaxMobs(String spawnerName){ + if (spawnersData.containsKey(spawnerName)) { + // Retrieve the SpawnerData object corresponding to the spawnerName + SpawnerData spawnerData = spawnersData.get(spawnerName); + // Return the cooldown value + return spawnerData.maxMobs; + } else { + // If the spawnerName is not found, log an error and return a default value or throw an exception + pluginLogger.log(PluginLogger.LogLevel.ERROR, "getSpawnerMaxMobs Spawner '" + spawnerName + "' not found."); + return -1; // or any other default value that indicates an error + } + } + public void saveItemStackData(YamlConfiguration mobData, String path, ItemStack itemStack) { + mobData.set(path + ".type", itemStack.getType().toString()); + if (!itemStack.getEnchantments().isEmpty()) { + for (Map.Entry enchant : itemStack.getEnchantments().entrySet()) { + mobData.set(path + ".enchants." + enchant.getKey().getKey().getKey(), enchant.getValue()); + } + } + } + + public CustomMobs.CustomMob loadCustomMob(JavaPlugin plugin, FileRewardManager dropFileManager, File mobFile, String transactionID) { + //String transactionID = UUID.randomUUID().toString(); + //File customMobsFolder = new File(plugin.getDataFolder(), "customMobs"); + //File mobFile = new File(customMobsFolder, mobName + ".yml"); + + if (!mobFile.exists()) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Mob file '" + mobFile.toString() + "' not found.",transactionID); + //plugin.getLogger().warning("Plik dla mobka " + mobFile.toString() + " nie istnieje!"); + return null; + } + + try{ + YamlConfiguration mobData = YamlConfiguration.loadConfiguration(mobFile); + String entityTypeString = mobData.getString("type"); + ItemStack helmet=null; + ItemStack chestplate=null; + ItemStack leggings=null; + ItemStack boots=null; + ItemStack weapon=null; + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob entityTypeString: "+entityTypeString,transactionID); + if (entityTypeString.equals("SKELETON")||entityTypeString.equals("ZOMBIE")|| entityTypeString.equals("STRAY")|| entityTypeString.equals("WITHER_SKELETON") || entityTypeString.equals("HUSK")) {// Wczytanie wyposażenia z pliku + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob mob is ZOMBIE or SKELETON",transactionID); + helmet = loadItemStack(mobData, "equipment.helmet"); + chestplate = loadItemStack(mobData, "equipment.chestplate"); + leggings = loadItemStack(mobData, "equipment.leggings"); + boots = loadItemStack(mobData, "equipment.boots"); + weapon = loadItemStack(mobData, "equipment.weapon"); + } + // Wczytanie pozostałych danych + double armor = 1; + int hp = mobData.getInt("hp"); + double speed = mobData.getDouble("speed"); + double attackDamage = mobData.getDouble("attackDamage"); + int attackSpeed = 1; + int regenSeconds= 5; + double regenPercent = 5, knockbackResistance=0, eloPoints=0, eloMultiplier=0; + int defense = 0; + String passengerMobName=null; + + if(mobData.contains("attackSpeed")){ + attackSpeed = mobData.getInt("attackSpeed"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded AttackSpeed:" + attackSpeed,transactionID); + } + if(mobData.contains("defense")){ + defense = mobData.getInt("defense"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded defense:" + defense,transactionID); + } + if(mobData.contains("armor")){ + armor = mobData.getDouble("armor"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded armor:" + armor,transactionID); + } + if(mobData.contains("passengerMobName")){ + passengerMobName = mobData.getString("passengerMobName"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded passengerMobName:" + passengerMobName,transactionID); + } + if(mobData.contains("regenSeconds")){ + regenSeconds = mobData.getInt("regenSeconds"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded regenSeconds:" + regenSeconds,transactionID); + } + if(mobData.contains("regenPercent")){ + regenPercent = mobData.getInt("regenPercent"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded regenPercent:" + regenPercent,transactionID); + } + if(mobData.contains("knockbackResistance")){ + knockbackResistance = mobData.getDouble("knockbackResistance"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded knockbackResistance:" + knockbackResistance,transactionID); + } + if(mobData.contains("eloPoints")){ + eloPoints = mobData.getDouble("eloPoints"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded eloPoints:" + eloPoints,transactionID); + } + if(mobData.contains("eloMultiplier")){ + eloMultiplier = mobData.getDouble("eloMultiplier"); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob loaded eloMultiplier:" + eloMultiplier,transactionID); + } + + String mobName = mobData.getString("mobName"); + String dropTableName = mobData.getString("dropTable"); + + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob armor:" + armor + ", hp: " + hp + ", speed: " + speed + ", attackDamage: " + attackDamage + ", type: " + entityTypeString+", dropTablename: "+dropTableName+", passengerMobName: "+passengerMobName+", regenSeconds: "+regenSeconds+", regenPercent: "+regenPercent+", knockbackResistance: "+knockbackResistance+", eloPoints: "+eloPoints+", eloMultiplier: "+eloMultiplier,transactionID); + EntityType entityType = EntityType.valueOf(entityTypeString); + + // Wczytanie niestandardowych metadanych i ustawienie spawnerName + Map customMetadata = (Map) mobData.getConfigurationSection("customMetadata").getValues(false); + //customMetadata.put("SpawnerName", spawnerName); // Dopisanie nazwy spawnera + + // Utworzenie instancji CustomMob + // Zakładamy, że LivingEntity jest nullem, ponieważ tworzymy moba bez konkretnej encji w świecie + CustomMobs.CustomMob customMob=null; + if (entityTypeString.equals("SKELETON")||entityTypeString.equals("ZOMBIE")|| entityTypeString.equals("STRAY")|| entityTypeString.equals("WITHER_SKELETON")|| entityTypeString.equals("HUSK")){ + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob mob is ZOMBIE or SKELETON or STRAY",transactionID); + customMob = new CustomMobs.CustomMob(plugin, this, mobName, entityType, helmet, chestplate, leggings, boots,weapon, armor, hp, speed, attackDamage,attackSpeed, customMetadata, dropTableName, defense,null, regenSeconds,regenPercent,knockbackResistance, eloPoints, eloMultiplier); + if(passengerMobName!=null) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob passengerMobName: " + passengerMobName,transactionID); + customMob = new CustomMobs.CustomMob(plugin, this, mobName, entityType, helmet, chestplate, leggings, boots,weapon, armor, hp, speed, attackDamage,attackSpeed, customMetadata, dropTableName, defense, passengerMobName, regenSeconds,regenPercent,knockbackResistance, eloPoints, eloMultiplier); + } + }else if(passengerMobName!=null){ + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob passengerMobName: "+passengerMobName,transactionID); + customMob = new CustomMobs.CustomMob(plugin, this, mobName, entityType, armor, hp, speed, attackDamage,attackSpeed, customMetadata, dropTableName, defense,passengerMobName, regenSeconds,regenPercent,knockbackResistance, eloPoints, eloMultiplier); + } + else{ + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob normal mob",transactionID); + customMob = new CustomMobs.CustomMob(plugin, this, mobName, entityType, armor, hp, speed, attackDamage,attackSpeed, customMetadata, dropTableName, defense, regenSeconds,regenPercent,knockbackResistance, eloPoints, eloMultiplier); + + } + + pluginLogger.log(PluginLogger.LogLevel.DROP,"CustomMobsFileManager.loadCustomMob customMob.dropTablename: "+customMob.dropTableName,transactionID); + + return customMob; + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR,"CustomMobsFileManager.loadCustomMob exception: " + e.getMessage(),transactionID); + } + return null; + + } + + private ItemStack loadItemStack(YamlConfiguration mobData, String path) { + String transactionID = UUID.randomUUID().toString(); + if (!mobData.contains(path + ".type")) return null; // Zabezpieczenie przed brakiem danych + + Material material = Material.valueOf(mobData.getString(path + ".type")); + ItemStack itemStack = new ItemStack(material); + + // Wczytanie zaklęć + if (mobData.contains(path + ".enchants")) { + ConfigurationSection enchantsSection = mobData.getConfigurationSection(path + ".enchants"); + for (String key : enchantsSection.getKeys(false)) { + try { + Enchantment enchantment = Enchantment.getByKey(org.bukkit.NamespacedKey.minecraft(key.toLowerCase())); + if (enchantment != null) { + + itemStack.addEnchantment(enchantment, enchantsSection.getInt(key)); + + } + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid enchant "+key.toLowerCase()+" in "+mobData.getString("mobName"),transactionID); + } + } + } + try {// Ustawienie przedmiotu jako niezniszczalnego + if (mobData.contains(path + ".unbreakable") && mobData.getBoolean(path + ".unbreakable")) { + ItemMeta meta = itemStack.getItemMeta(); + meta.setUnbreakable(true); + itemStack.setItemMeta(meta); + } + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR, "cannot read unbreakable from file. Exception: "+e.getMessage(),transactionID); + } + + // Wczytanie atrybutów armor i damage + try { + ItemMeta meta = itemStack.getItemMeta(); + if (mobData.contains(path + ".attributes.damage")) { + meta.addAttributeModifier(Attribute.GENERIC_ATTACK_DAMAGE, new AttributeModifier(UUID.randomUUID(), "generic.attackDamage", mobData.getDouble(path + ".attributes.damage"), AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HAND)); + } + if (mobData.contains(path + ".attributes.armor")) { + meta.addAttributeModifier(Attribute.GENERIC_ARMOR, new AttributeModifier(UUID.randomUUID(), "generic.armor", mobData.getDouble(path + ".attributes.armor"), AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.CHEST)); + } + itemStack.setItemMeta(meta); + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Error reading attributes from file. Exception: " + e.getMessage(),transactionID); + } + + return itemStack; + } + public List getCustomMobFiles() { + + List customMobFiles = new ArrayList<>(); + File customMobsFolder = new File(plugin.getDataFolder(), "customMobs"); + + if (customMobsFolder.exists() && customMobsFolder.isDirectory()) { + File[] files = customMobsFolder.listFiles(); + + if (files != null) { + for (File file : files) { + if (file.isFile() && file.getName().endsWith(".yml") &&!file.getName().equalsIgnoreCase("customMobs/spawners.yml")) { + customMobFiles.add(file); + } + } + } + } + + return customMobFiles; + } + public HashMap loadCustomDrops(String dropTableName) { + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops called, dropTableName: " + dropTableName); + HashMap drops = new HashMap<>(); + File dropTableFile = new File(plugin.getDataFolder() + File.separator + "customDropTables", dropTableName + ".yml"); + if (!dropTableFile.exists()) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "loadCustomDrops dropTable " + dropTableName + " does not exist!"); + return drops; + } + + YamlConfiguration dropTableConfig = YamlConfiguration.loadConfiguration(dropTableFile); + + dropTableConfig.getKeys(false).forEach(key -> { + String itemPath = dropTableConfig.getString(key + ".itemPath"); + double dropChance = dropTableConfig.getDouble(key + ".dropChance"); + boolean AvgDmgBonus = dropTableConfig.getBoolean(key + ".avgDmgBonus"); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops itemPath: " + itemPath+", dropChance: "+dropChance+", avgDmgBonus: "+AvgDmgBonus); + File itemFile = new File(plugin.getDataFolder(), itemPath); + if (itemFile.exists()) { + try { + FileConfiguration itemConfig = YamlConfiguration.loadConfiguration(itemFile); + ItemStack itemStack = itemConfig.getItemStack("item"); + if (itemStack != null) { + if(AvgDmgBonus){ + ItemMeta meta = itemStack.getItemMeta(); + List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); + //List lore = new ArrayList<>(); + assert lore != null; + lore.add("AvgDmgBonus"); + meta.setLore(lore); + itemStack.setItemMeta(meta); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops added AvgDmgBonus lore "); + } + drops.put(dropChance, itemStack); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops item: " + itemStack); + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Nie można wczytać przedmiotu z pliku: " + itemPath + ". Błąd: " + e.getMessage()); + } + } + }); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops drops: " + drops); + return drops; + } + + public List loadCustomDropsv2(String dropTableName) { + String transactionID = UUID.randomUUID().toString(); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops called, dropTableName: " + dropTableName,transactionID); + List drops = new ArrayList<>(); + File dropTableFile = new File(plugin.getDataFolder() + File.separator + "customDropTables", dropTableName + ".yml"); + if (!dropTableFile.exists()) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "loadCustomDrops dropTable " + dropTableName + " does not exist!",transactionID); + return drops; + } + + YamlConfiguration dropTableConfig = YamlConfiguration.loadConfiguration(dropTableFile); + + dropTableConfig.getKeys(false).forEach(key -> { + String itemPath = dropTableConfig.getString(key + ".itemPath"); + double dropChance = dropTableConfig.getDouble(key + ".dropChance"); + int maxDamage = dropTableConfig.getInt(key + ".maxDamage"); + boolean avgDmgBonus = dropTableConfig.getBoolean(key + ".avgDmgBonus"); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops itemPath: " + itemPath+", dropChance: "+dropChance+", avgDmgBonus: "+avgDmgBonus,transactionID); + File itemFile = new File(plugin.getDataFolder(), itemPath); + if (itemFile.exists()) { + try { + FileConfiguration itemConfig = YamlConfiguration.loadConfiguration(itemFile); + ItemStack itemStack = itemConfig.getItemStack("item"); + if (itemStack != null) { + DropItem dropItem; + if(maxDamage>0){ + dropItem = new DropItem(dropChance, itemStack, avgDmgBonus,maxDamage); + }else { + dropItem = new DropItem(dropChance, itemStack, avgDmgBonus); + } + drops.add(dropItem); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops item: " + itemStack,transactionID); + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Nie można wczytać przedmiotu z pliku: " + itemPath + ". Błąd: " + e.getMessage(),transactionID); + } + } + }); + pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobsFileManager.loadCustomDrops drops: " + drops,transactionID); + return drops; + } + + +} diff --git a/src/main/java/betterbox/mine/game/betterelo/DataManager.java b/src/main/java/betterbox/mine/game/betterelo/DataManager.java index 922b3a5..af749ab 100644 --- a/src/main/java/betterbox/mine/game/betterelo/DataManager.java +++ b/src/main/java/betterbox/mine/game/betterelo/DataManager.java @@ -8,39 +8,47 @@ public class DataManager { private final JavaPlugin plugin; private final File dataFolder; + private final File pluginDataFolder; private final File databaseFile; private final File dailyDatabaseFile; private final File weeklyDatabaseFile; private final File monthlyDatabaseFile; + private final File eventDatabasefile; public final Map playerPoints = new HashMap<>(); public final Map dailyPlayerPoints = new HashMap<>(); public final Map weeklyPlayerPoints = new HashMap<>(); public final Map monthlyPayerPoints = new HashMap<>(); + public final Map eventPlayerPoints = new HashMap<>(); private final PluginLogger pluginLogger; // Dodajemy referencję do PluginLogger private final Map> allPlayerPoints = new HashMap<>(); public DataManager(JavaPlugin plugin, PluginLogger pluginLogger) { this.plugin = plugin; this.pluginLogger = pluginLogger; // Inicjalizujemy PluginLogger - this.dataFolder = plugin.getDataFolder(); + this.pluginDataFolder = plugin.getDataFolder(); + this.dataFolder = new File(pluginDataFolder,"data"); this.databaseFile = new File(dataFolder, "database.txt"); this.dailyDatabaseFile = new File(dataFolder, "daily_database.txt"); this.weeklyDatabaseFile = new File(dataFolder, "weekly_database.txt"); this.monthlyDatabaseFile = new File(dataFolder, "monthly_database.txt"); + this.eventDatabasefile = new File(dataFolder, "event_database.txt"); allPlayerPoints.put("main", playerPoints); allPlayerPoints.put("daily", dailyPlayerPoints); allPlayerPoints.put("weekly", weeklyPlayerPoints); allPlayerPoints.put("monthly", monthlyPayerPoints); + allPlayerPoints.put("event", eventPlayerPoints); } public void setPoints(String playerUUID, double points, String ranking_type) { if (ranking_type.equals("main")) playerPoints.put(playerUUID, points); if (ranking_type.equals("daily")) dailyPlayerPoints.put(playerUUID, points); if (ranking_type.equals("weekly")) weeklyPlayerPoints.put(playerUUID, points); if (ranking_type.equals("monthly")) monthlyPayerPoints.put(playerUUID, points); + if (ranking_type.equals("event")) eventPlayerPoints.put(playerUUID, points); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"DataManager: setPoints: zapisywanie do bazy.."); saveDataToFile(); // Zapisz zmienione dane do pliku saveDataToFileDaily(); // Zapisz zmienione dane do pliku saveDataToFileWeekly(); // Zapisz zmienione dane do pliku saveDataToFileMonthly(); // Zapisz zmienione dane do pliku + saveDataToFileEvent(); // Zapisz zmienione dane do pliku } public double getPoints(String playerUUID, String ranking_type) { @@ -69,6 +77,7 @@ public void initializeDatabaseFile() { initializeFile(dailyDatabaseFile, "dailyDatabaseFile"); initializeFile(weeklyDatabaseFile, "weeklyDatabaseFile"); initializeFile(monthlyDatabaseFile, "monthlyDatabaseFile"); + initializeFile(eventDatabasefile, "eventDatabaseFile"); } private void initializeFile(File file, String fileName) { if (!file.exists()) { @@ -77,8 +86,9 @@ private void initializeFile(File file, String fileName) { file.createNewFile(); } catch (IOException e) { - pluginLogger.log(PluginLogger.LogLevel.ERROR,"DataManager: initializeFile: error: "+e); - e.printStackTrace(); + pluginLogger.log(PluginLogger.LogLevel.ERROR,"DataManager: initializeFile: error: "+e.getMessage()); + + ; } } } @@ -119,6 +129,9 @@ public int getPlayerRank(String playerUUID, String ranking) { case "monthly": sortedPlayers = sortPlayersByPoints(this.monthlyPayerPoints); break; + case "event": + sortedPlayers = sortPlayersByPoints(this.eventPlayerPoints); + break; } @@ -137,6 +150,7 @@ public void loadDataFromFile() { dailyPlayerPoints.clear(); weeklyPlayerPoints.clear(); monthlyPayerPoints.clear(); + eventPlayerPoints.clear(); try (BufferedReader reader = new BufferedReader(new FileReader(databaseFile))) { String line; while ((line = reader.readLine()) != null) { @@ -190,6 +204,19 @@ public void loadDataFromFile() { } catch (IOException e) { pluginLogger.log(PluginLogger.LogLevel.ERROR,"DataManager: loadDataFromFile: error: "+e); } + try (BufferedReader reader = new BufferedReader(new FileReader(eventDatabasefile))) { + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split(":"); + if (parts.length == 2) { + String playerUUID = parts[0]; + double points = Double.parseDouble(parts[1]); + eventPlayerPoints.put(playerUUID, points); + } + } + } catch (IOException e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR,"DataManager: loadDataFromFile: error: "+e); + } // Używamy nowego loggera do zapisywania wiadomości debugujących pluginLogger.log(PluginLogger.LogLevel.DEBUG,"DataManager: loadDataFromFile: Data loaded"); @@ -245,6 +272,23 @@ public void saveDataToFileMonthly() { // Używamy nowego loggera do zapisywania wiadomości debugujących pluginLogger.log(PluginLogger.LogLevel.DEBUG,"DataManager: saveDataToFileMonthly saved"); } + public void saveDataToFileEvent() { + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"DataManager: saveDataToFileEvent called"); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(eventDatabasefile))) { + for (Map.Entry entry : eventPlayerPoints.entrySet()) { + String playerUUID = entry.getKey(); + double points = entry.getValue(); + if (!playerUUID.equals("AIR")) { + writer.write(playerUUID + ":" + points); + writer.newLine(); + } + } + } catch (IOException e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR,"DataManager: saveDataToFileEvent: error: "+e); + } + // Używamy nowego loggera do zapisywania wiadomości debugujących + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"DataManager: saveDataToFileEvent saved"); + } public void saveDataToFile() { pluginLogger.log(PluginLogger.LogLevel.DEBUG,"DataManager: saveDataToFile called"); try (BufferedWriter writer = new BufferedWriter(new FileWriter(databaseFile))) { @@ -277,6 +321,9 @@ public double getExtremeElo(String ranking_type, boolean isMax) { case "monthly": playerPointsMap = monthlyPayerPoints; // Poprawienie literówki z "monthlyPayerPoints" break; + case "event": + playerPointsMap = eventPlayerPoints; // Poprawienie literówki z "monthlyPayerPoints" + break; default: break; } @@ -372,6 +419,8 @@ public boolean playerExists(String playerUUID,String reward_type) { case "monthly": return monthlyPayerPoints.containsKey(playerUUID); + case "event": + return eventPlayerPoints.containsKey(playerUUID); default: return playerPoints.containsKey(playerUUID); diff --git a/src/main/java/betterbox/mine/game/betterelo/Event.java b/src/main/java/betterbox/mine/game/betterelo/Event.java index 3965754..342f2bc 100644 --- a/src/main/java/betterbox/mine/game/betterelo/Event.java +++ b/src/main/java/betterbox/mine/game/betterelo/Event.java @@ -1,41 +1,83 @@ package betterbox.mine.game.betterelo; - +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.WorldGuard; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.flags.Flags; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.RegionContainer; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import io.papermc.paper.event.entity.EntityMoveEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.title.Title; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.OfflinePlayer; +import org.bukkit.*; import org.bukkit.block.Block; -import org.bukkit.entity.Player; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.*; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.*; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.projectiles.ProjectileSource; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.Nullable; + import java.text.DecimalFormat; import java.time.Duration; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; public class Event implements Listener { private final DataManager dataManager; private final JavaPlugin plugin; private final PluginLogger pluginLogger; + private final BetterElo betterElo; + private Map lastAttackTimes = new HashMap<>(); private BetterRanksCheaters cheaters; private ExtendedConfigManager configManager; + private HashMap lastFireworkUsage = new HashMap<>(); + private HashMap lastZephyrUsage = new HashMap<>(); + private HashMap lastFlameUsage = new HashMap<>(); + private CustomMobs customMobs; + private CustomMobsFileManager customMobsFileManager; + private GuiManager guiManager; + private FileRewardManager fileRewardManager; + private int deathEventCounter; + private final Random random = new Random(); + //public final long cooldownMillis = 1500; // 1.5s + public Utils utils; - public Event(DataManager dataManager, PluginLogger pluginLogger, JavaPlugin plugin, BetterRanksCheaters cheaters, ExtendedConfigManager configManager) { + public Event(DataManager dataManager, PluginLogger pluginLogger, JavaPlugin plugin, BetterRanksCheaters cheaters, ExtendedConfigManager configManager, BetterElo betterElo, CustomMobs customMobs, FileRewardManager fileRewardManager, GuiManager guiManager, CustomMobsFileManager customMobsFileManager,Utils utils) { this.dataManager = dataManager; + this.fileRewardManager = fileRewardManager; this.pluginLogger = pluginLogger; + this.betterElo = betterElo; this.plugin = plugin; this.cheaters = cheaters; this.configManager = configManager; + this.customMobs = customMobs; + this.customMobsFileManager = customMobsFileManager; + this.guiManager = guiManager; + this.utils = utils; + Bukkit.getPluginManager().registerEvents(this, plugin); } @EventHandler @@ -77,8 +119,8 @@ public void onPlayerJoin(PlayerJoinEvent event) { } } - private double handleKillEvent(String rankingType, Player victim, Player killer) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent called with parameters: " + rankingType+" "+victim+" "+killer); + private double handleKillEvent(String rankingType, Player victim, Player killer,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent called with parameters: " + rankingType+" "+victim+" "+killer,transactionID); double pointsEarned = 0; if (killer != null && !killer.equals(victim)) { @@ -87,23 +129,76 @@ private double handleKillEvent(String rankingType, Player victim, Player killer) double killerElo = getElo(killer.getUniqueId().toString(), rankingType); double maxElo = getMaxElo(rankingType); double minElo = dataManager.getMinElo(rankingType); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent: rankingType: " + rankingType + " loaded variables: maxElo:" + maxElo + " minElo: " + minElo + " victimElo:" + victimElo + " victim name: " + victim.getName() + " killerElo:" + killerElo + " killer name: " + killer.getName()); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent: rankingType: " + rankingType + " loaded variables: maxElo:" + maxElo + " minElo: " + minElo + " victimElo:" + victimElo + " victim name: " + victim.getName() + " killerElo:" + killerElo + " killer name: " + killer.getName(),transactionID); double basePoints = 100; - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent calling calculatePointsEarned with parameters: basePoints " + basePoints + " killerElo " + killerElo + " victimElo " + victimElo + " maxElo " + maxElo + " minElo " + minElo); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent calling calculatePointsEarned with parameters: basePoints " + basePoints + " killerElo " + killerElo + " victimElo " + victimElo + " maxElo " + maxElo + " minElo " + minElo,transactionID); pointsEarned = calculatePointsEarned(basePoints, killerElo, victimElo, maxElo, minElo); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent: pointsEarned: " + pointsEarned + "rankingType: " + rankingType); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent: pointsEarned: " + pointsEarned + "rankingType: " + rankingType,transactionID); // Zapisz informacje do bazy danych PlayerKillDatabase playerKillDatabase = new PlayerKillDatabase(pluginLogger); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent calling saveKillData"); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent calling saveKillData",transactionID); playerKillDatabase.saveKillData(rankingType, victim.getName(), killer.getName(), pointsEarned, killerElo, victimElo); // Dodaj punkty graczowi, który zabił - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent calling addPoints with parameters: " + killer.getUniqueId().toString() + " " + pointsEarned + " " + rankingType); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent calling addPoints with parameters: " + killer.getUniqueId().toString() + " " + pointsEarned + " " + rankingType,transactionID); addPoints(killer, pointsEarned, rankingType); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent calling subtractPoints with parameters: " + victim.getUniqueId().toString() + " " + pointsEarned + " " + rankingType); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent calling subtractPoints with parameters: " + victim.getUniqueId().toString() + " " + pointsEarned + " " + rankingType,transactionID); subtractPoints(victim, pointsEarned, rankingType); + pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterElo.Event.handleKillEvent: rankingType: " + rankingType + ", maxElo:" + maxElo + " minElo: " + minElo + " victimElo:" + victimElo + " victimName: " + victim.getName() + " killerElo:" + killerElo + " killerName: " + killer.getName()+", pointsEarned: "+pointsEarned,transactionID); + } + return pointsEarned; + } + private double handleMobKillEvent(String rankingType, CustomMobs.CustomMob victim, Player killer,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent called with parameters: " + rankingType+" "+victim+" "+killer,transactionID); + + double pointsEarned = 0; + double victimElo = victim.eloPoints; + double eloMultiplier = victim.eloMultiplier; + double killerElo = getElo(killer.getUniqueId().toString(), rankingType); + double maxElo = getMaxElo(rankingType); + double minElo = dataManager.getMinElo(rankingType); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent: rankingType: " + rankingType + ", loaded variables: maxElo:" + maxElo + ", minElo: " + minElo + ", victimElo:" + victimElo + ", eloMultiplier: "+eloMultiplier,transactionID); + double basePoints = 100; + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent calling calculatePointsEarned with parameters: basePoints " + basePoints + " killerElo " + killerElo + " victimElo " + victimElo + " maxElo " + maxElo + " minElo " + minElo,transactionID); + pointsEarned = eloMultiplier * calculatePointsEarned(basePoints, killerElo, victimElo, maxElo, minElo); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent: pointsEarned: " + pointsEarned + "rankingType: " + rankingType,transactionID); + addPoints(killer, pointsEarned, rankingType); + pluginLogger.log(PluginLogger.LogLevel.INFO, "Event.handleMobKillEvent basePoints " + basePoints + " killerElo " + killerElo + " victimElo(mob) " + victimElo + " maxElo " + maxElo + " minElo " + minElo+", mobName: "+killer.getName()+" pointsEarned: "+pointsEarned,transactionID); + return pointsEarned; + } + private void handleRankingPointsFromMobKill(Player killer, CustomMobs.CustomMob victim, String ranking,String transactionID) { + if (dataManager.getPoints(killer.getUniqueId().toString(), ranking) - victim.eloPoints < 1000) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.handleRankingPointsFromMobKill calling handleKillEvent with parameters: " + ranking + " " + victim + " " + killer,transactionID); + double pointsEarned = handleMobKillEvent(ranking, victim, killer,transactionID); + if (ranking.equals("main")) { + notifyPlayerAboutPoints(killer, pointsEarned, victim.eloMultiplier, true); + } + } else { + killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Your Elo difference in the " + ranking + " ranking is too big! No reward for this one."); + } + } + private void handleRankingPointsFromMobDeath(CustomMobs.CustomMob killer,Player victim, String ranking,String transactionID) { + if (dataManager.getPoints(victim.getUniqueId().toString(), ranking) - killer.eloPoints < 1000) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.handleRankingPointsFromMobKill calling handleKillEvent with parameters: " + ranking + " " + victim + " " + killer,transactionID); + double pointsEarned = handleDeathFromCustomMobEvent(ranking, victim, killer,transactionID); } + } + private double handleDeathFromCustomMobEvent(String rankingType, Player victim, CustomMobs.CustomMob killer,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent called with parameters: " + rankingType+" "+victim+" "+killer,transactionID); + + double pointsEarned = 0; + double victimElo = getElo(victim.getUniqueId().toString(), rankingType); + double eloMultiplier = killer.eloMultiplier; + double killerElo = killer.eloPoints; + double maxElo = getMaxElo(rankingType); + double minElo = dataManager.getMinElo(rankingType); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent: rankingType: " + rankingType + ", loaded variables: maxElo:" + maxElo + ", minElo: " + minElo + ", victimElo:" + victimElo + ", eloMultiplier: "+eloMultiplier,transactionID); + double basePoints = 100; + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent calling calculatePointsEarned with parameters: basePoints " + basePoints + " killerElo " + killerElo + " victimElo " + victimElo + " maxElo " + maxElo + " minElo " + minElo,transactionID); + pointsEarned = eloMultiplier * calculatePointsEarned(basePoints, killerElo, victimElo, maxElo, minElo); + pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterElo.Event.handleKillEvent: pointsEarned(lost): " + pointsEarned + "rankingType: " + rankingType+", victim: "+victim.getName()+", mob: "+killer.getMobName()); + subtractPoints(victim, pointsEarned, rankingType); return pointsEarned; } @@ -113,39 +208,24 @@ private double handleKillEvent(String rankingType, Player victim, Player killer) // Metoda do aktualizacji czasu ostatniego uderzenia public void updateLastHitTime(Player player) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: updateLastHitTime called"); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: updateLastHitTime saving "+player.getUniqueId()+" "+System.currentTimeMillis()); + //pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: updateLastHitTime saving "+player.getUniqueId()+" "+System.currentTimeMillis()); lastHitTime.put(player.getUniqueId(), System.currentTimeMillis()); } // Sprawdź, czy śmierć nastąpiła w wyniku walki private boolean deathDueToCombat(Player player) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: deathDueToCombat called"); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: deathDueToCombat called"); Long lastHit = lastHitTime.get(player.getUniqueId()); return lastHit != null && (System.currentTimeMillis() - lastHit <= 10000); // 10 sekund } - @EventHandler - public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onEntityDamageByEntity called"); - if (event.getDamager() instanceof Player && event.getEntity() instanceof Player) { - - Player damager = (Player) event.getDamager(); - Player victim = (Player) event.getEntity(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onEntityDamageByEntity: calling updateLastHitTime(damager) "+damager); - // Aktualizacja czasu ostatniego uderzenia - updateLastHitTime(damager); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onEntityDamageByEntity: calling updateLastHitTime(victim) "+victim); - updateLastHitTime(victim); - } - } // Metoda do znalezienia ostatniego napastnika private Player getLastAttacker(Player victim) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: getLastAttacker called with parameters: " + victim); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: getLastAttacker called with parameters: " + victim); try { Player lastAttacker = null; long lastAttackTime = 0; - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: getLastAttacker: checking online players"); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: getLastAttacker: checking online players"); // Iterowanie przez wszystkich graczy i znajdowanie tego, który ostatnio uderzył ofiarę for (Player player : plugin.getServer().getOnlinePlayers()) { UUID playerId = player.getUniqueId(); @@ -159,7 +239,7 @@ private Player getLastAttacker(Player victim) { } } } - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: getLastAttacker: lastAttacker " + lastAttacker); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: getLastAttacker: lastAttacker " + lastAttacker); return lastAttacker; @@ -169,93 +249,129 @@ private Player getLastAttacker(Player victim) { } } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST) public void onPlayerDeath(PlayerDeathEvent event) { + String transactionID = UUID.randomUUID().toString(); + Player victim = event.getEntity(); + if (victim.hasMetadata("handledDeath")) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath event already handled! victim: "+victim.getName(),transactionID); + return; + } + victim.setMetadata("handledDeath", new FixedMetadataValue(plugin, true)); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> victim.removeMetadata("handledDeath", plugin), 1L); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.handleKillEvent added handledDeath metadata to "+victim.getName(),transactionID); + if (cheaters.getCheatersList().contains(victim.getName())) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: handleKillEvent: returning 0 points because either " + victim + " " + cheaters.getCheatersList().contains(victim.getName()) + " has CHEATER rank in BetterRanks.",transactionID); + return; + } + if(!Utils.isEloAllowed(victim,victim.getLocation())){ + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath noElo zone!",transactionID); + //killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "No elo reward in this zone!"); + return; + } + + + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { - Player victim = event.getEntity(); Player killer = victim.getKiller(); - if (!cheaters.getCheatersList().contains(victim.getName()) && !cheaters.getCheatersList().contains(killer.getName())) { - - - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath called with parameters: " + event); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath: victim: " + victim + " killer: " + killer); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling deathDueToCombat(victim)"); - if (killer == null && deathDueToCombat(victim)) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath killer is null"); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath: deathDueToCombat(victim): " + deathDueToCombat(victim) + " victim: " + victim); - // Znajdź ostatniego gracza, który uderzył ofiarę - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling getLastAttacker(victim)"); + String[] rankings = {"main", "daily", "weekly", "monthly"}; + boolean eventEnabled = betterElo.isEventEnabled; + if (killer == null && deathDueToCombat(victim)) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath: killer is null, deathDueToCombat(victim): " + deathDueToCombat(victim) + " victim: " + victim+", calling getLastAttacker(victim)",transactionID); Player lastAttacker = getLastAttacker(victim); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath: lastAttacker " + lastAttacker); - - if (lastAttacker != null) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath: calling handleKillEvent" + lastAttacker); - // Oblicz punkty zdobyte/wtracone w wyniku "wirtualnej" walki - double pointsEarned = handleKillEvent("main", victim, lastAttacker); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling handleKillEvent with parameters: daily " + victim + " " + lastAttacker); - handleKillEvent("daily", victim, lastAttacker); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling handleKillEvent with parameters: weekly " + victim + " " + lastAttacker); - handleKillEvent("weekly", victim, lastAttacker); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling handleKillEvent with parameters: monthly " + victim + " " + lastAttacker); - handleKillEvent("monthly", victim, lastAttacker); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling notifyPlayersAboutPoints(lastAttacker, victim, pointsEarned)"); - // Powiadom graczy o zmianie punktów - notifyPlayersAboutPoints(lastAttacker, victim, pointsEarned); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath: lastAttacker " + lastAttacker,transactionID); + if (lastAttacker == null) { return; + }else{ + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath setting killer=lastAttacker ",transactionID); + killer=lastAttacker; } + }else if(killer==null && !deathDueToCombat(victim)){ + EntityDamageEvent lastDamageCause = victim.getLastDamageCause(); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath: killer is null, deathDueToCombat(victim)=false, lastDamageCause="+lastDamageCause.toString(),transactionID); + if (lastDamageCause instanceof EntityDamageByEntityEvent) { + EntityDamageByEntityEvent damageByEntityEvent = (EntityDamageByEntityEvent) lastDamageCause; + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath: damageByEntityEvent="+damageByEntityEvent.toString(),transactionID); + Entity damager = damageByEntityEvent.getDamager(); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath: damager="+damager.toString()); + // Sprawdzenie, czy damager jest projectilem + if (damager instanceof Projectile) { + Projectile projectile = (Projectile) damager; + ProjectileSource shooter = projectile.getShooter(); + + if (shooter instanceof Entity) { + damager = (Entity) shooter; + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath: shooter="+damager.toString(),transactionID); + } + } + CustomMobs.CustomMob customMob = betterElo.getCustomMobFromEntity(damager); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath: customMob="+customMob.toString(),transactionID); + if (customMob!=null){ + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath killer: "+customMob.mobName+", mobElo: "+customMob.eloPoints,transactionID); + for (String ranking : rankings) { + handleRankingPointsFromMobDeath(customMob, victim, ranking,transactionID); + } + if (eventEnabled) { + handleRankingPointsFromMobDeath(customMob, victim, "event",transactionID); + } + } return; + } + } + if (cheaters.getCheatersList().contains(victim.getName()) || cheaters.getCheatersList().contains(killer.getName())) { + pluginLogger.log(PluginLogger.LogLevel.INFO, "Event: handleKillEvent: returning 0 points because either " + victim + " " + cheaters.getCheatersList().contains(victim.getName()) + " or " + killer + " " + cheaters.getCheatersList().contains(killer.getName()) + " has CHEATER rank in BetterRanks.",transactionID); + return; + } + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath: victim: " + victim + " killer: " + killer,transactionID); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath calling deathDueToCombat(victim)",transactionID); + String victimUUID = victim.getUniqueId().toString(); String killerUUID = killer.getUniqueId().toString(); - if (dataManager.getPoints(killerUUID, "main") - dataManager.getPoints(victimUUID, "main") < 1000) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling handleKillEvent with parameters: main " + victim + " " + killer); - double pointsEarned = handleKillEvent("main", victim, killer); - assert killer != null; - notifyPlayersAboutPoints(killer, victim, pointsEarned); - } else { - killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Your Elo difference in the Main ranking is too big! No reward for this one."); - } - if (dataManager.getPoints(killerUUID, "daily") - dataManager.getPoints(victimUUID, "daily") < 1000) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling handleKillEvent with parameters: daily " + victim + " " + killer); - handleKillEvent("daily", victim, killer); - } else { - killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Your Elo difference in the Daily ranking is too big! No reward for this one."); - } - if (dataManager.getPoints(killerUUID, "weekly") - dataManager.getPoints(victimUUID, "weekly") < 1000) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling handleKillEvent with parameters: weekly " + victim + " " + killer); - handleKillEvent("weekly", victim, killer); - } else { - killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Your Elo difference in the Weekly ranking is too big! No reward for this one."); + + for (String ranking : rankings) { + handleRankingPoints(killer, victim, killerUUID, victimUUID, ranking,transactionID); } - if (dataManager.getPoints(killerUUID, "monthly") - dataManager.getPoints(victimUUID, "monthly") < 1000) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: onPlayerDeath calling handleKillEvent with parameters: monthly " + victim + " " + killer); - handleKillEvent("monthly", victim, killer); - } else { - killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Your Elo difference in the Monthly ranking is too big! No reward for this one."); + + if (eventEnabled) { + handleRankingPoints(killer, victim, killerUUID, victimUUID, "event",transactionID); } + //PLAYER DEATH FROM CUSTOM MOB + + + + - } else { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: handleKillEvent: returning 0 points because either " + victim + " " + cheaters.getCheatersList().contains(victim.getName()) + " or " + killer + " " + cheaters.getCheatersList().contains(killer.getName()) + " has CHEATER rank in BetterRanks."); - } } catch (Exception e) { - pluginLogger.log(PluginLogger.LogLevel.ERROR, "Event: onPlayerDeath exception " + e + " " + e.getMessage()); + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Event: onPlayerDeath exception " + e + " " + e.getMessage(),transactionID); } - }); -} + }); + } + private void handleRankingPoints(Player killer, Player victim, String killerUUID, String victimUUID, String ranking,String transactionID) { + if (dataManager.getPoints(killerUUID, ranking) - dataManager.getPoints(victimUUID, ranking) < 1000) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath calling handleKillEvent with parameters: " + ranking + " " + victim + " " + killer,transactionID); + double pointsEarned = handleKillEvent(ranking, victim, killer,transactionID); + if (ranking.equals("main")) { + notifyPlayersAboutPoints(killer, victim, pointsEarned,transactionID); + } + } else { + killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Your Elo difference in the " + ranking + " ranking is too big! No reward for this one.",transactionID); + } + } - private void notifyPlayersAboutPoints(Player killer, Player victim, double pointsEarned) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: notifyPlayersAboutPoints called with parameters: "+killer+" "+victim+" "+pointsEarned); + private void notifyPlayersAboutPoints(Player killer, Player victim, double pointsEarned,String transactionID) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: notifyPlayersAboutPoints called with parameters: "+killer+" "+victim+" "+pointsEarned,transactionID); DecimalFormat df = new DecimalFormat("#.##"); Duration fadeIn = Duration.ofMillis(300); // czas pojawiania się Duration stay = Duration.ofMillis(900); // czas wyświetlania Duration fadeOut = Duration.ofMillis(300); // czas znikania Title.Times times = Title.Times.times(fadeIn, stay, fadeOut); - Component killerTitleComponent = Component.text(ChatColor.GREEN +""+ChatColor.BOLD+ "+"+df.format(pointsEarned)+" Elo"); + Component killerTitleComponent = Component.text(ChatColor.GREEN +""+ChatColor.BOLD+ "+"+df.format((double)Math.round(pointsEarned*100)/100)+" Elo"); Component killerSubtitleComponent = Component.text(ChatColor.GOLD +"Victim: "+victim.getName()); // Notify the killer Title killerTitle = Title.title(killerTitleComponent,killerSubtitleComponent,times); @@ -263,7 +379,7 @@ private void notifyPlayersAboutPoints(Player killer, Player victim, double point victim.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.RED + "You have lost "+ChatColor.DARK_RED + "" + ChatColor.BOLD +df.format(pointsEarned)+" Elo"); } - private void notifyPlayerAboutPoints(Player player, double pointsEarned) { + private void notifyPlayerAboutPoints(Player player, double pointsEarned, double blockReward, boolean adding) { pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: notifyPlayersAboutPoints called with parameters: "+player+" "+pointsEarned); DecimalFormat df = new DecimalFormat("#.##"); @@ -271,8 +387,13 @@ private void notifyPlayerAboutPoints(Player player, double pointsEarned) { Duration stay = Duration.ofMillis(900); // czas wyświetlania Duration fadeOut = Duration.ofMillis(300); // czas znikania Title.Times times = Title.Times.times(fadeIn, stay, fadeOut); - Component killerTitleComponent = Component.text(ChatColor.GREEN +""+ChatColor.BOLD+ "+"+df.format(pointsEarned)+" Elo"); - Component killerSubtitleComponent = Component.text(ChatColor.GOLD +"Current Elo: "+dataManager.getPoints(player.getUniqueId().toString(),"main")); + Component killerTitleComponent; + if (adding) { + killerTitleComponent = Component.text(ChatColor.GREEN + "" + ChatColor.BOLD + "+" + df.format((double) Math.round(pointsEarned * 100) / 100) + " Elo"); + }else{ + killerTitleComponent = Component.text(ChatColor.DARK_RED + "" + ChatColor.BOLD + "-" + df.format((double) Math.round(pointsEarned * 100) / 100) + " Elo"); + } + Component killerSubtitleComponent = Component.text(ChatColor.GOLD +"Elo multiplier: x"+blockReward); // Notify the killer Title killerTitle = Title.title(killerTitleComponent,killerSubtitleComponent,times); player.showTitle(killerTitle); @@ -281,14 +402,29 @@ private void notifyPlayerAboutPoints(Player player, double pointsEarned) { private double calculatePointsEarned(double base, double killerelo, double victimelo, double maxElo, double minElo) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: calculatePointsEarned called with parameters : base "+base+" elo1 "+killerelo+" elo2 "+victimelo+" maxElo "+maxElo+" minElo "+minElo); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT,"Event: calculatePointsEarned called with parameters : base "+base+" elo1 "+killerelo+" elo2 "+victimelo+" maxElo "+maxElo+" minElo "+minElo); double eloDifference = killerelo - victimelo; + if(maxElovictimelo){ + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT,"Event.calculatePointsEarned minElo>victimelo, setting minElo=victimelo"); + minElo=victimelo; + }else if(minElo>killerelo){ + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT,"Event.calculatePointsEarned minElo>killerelo, setting minElo=killerelo"); + minElo=killerelo; + } double normalizedDifference = eloDifference / (maxElo - minElo + 1); double points = base * (1 - normalizedDifference); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: calculatePointsEarned: eloDifference: "+eloDifference+" normalizedDifference: "+normalizedDifference+" points: "+points+" maxElo: "+maxElo+" minElo: "+minElo); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: calculatePointsEarned: PointsEarnedOut: "+(double)Math.round(points*100)); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: calculatePointsEarned: PointsEarnedOut/100: "+(double)Math.round(points*100)/100); - return (double)Math.round(points*100)/100; + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT,"Event: calculatePointsEarned: eloDifference: "+eloDifference+" normalizedDifference: "+normalizedDifference+" points: "+points+" maxElo: "+maxElo+" minElo: "+minElo); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT,"Event: calculatePointsEarned: PointsEarnedOut: "+(double)Math.round(points*100)); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT,"Event: calculatePointsEarned: PointsEarnedOut/100: "+(double)Math.round(points*100)/100); + return points; + //return (double)Math.round(points*100)/100; } private double calculatePointsEarnedFromBlock(double base, double playerElo,double blockReward, double maxElo, double minElo) { pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: calculatePointsEarnedFromBlock called with parameters : base "+base+" playerElo "+playerElo+" blockReward "+blockReward+" maxElo "+maxElo+" minElo "+minElo); @@ -300,7 +436,8 @@ private double calculatePointsEarnedFromBlock(double base, double playerElo,doub pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4, "Event: calculatePointsEarnedFromBlock: eloDifference: "+eloDifference+", S: "+S+", points: "+points); pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: calculatePointsEarnedFromBlock: PointsEarnedOut: "+(double)Math.round(points*100)); pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: calculatePointsEarnedFromBlock: PointsEarnedOut/100: "+(double)Math.round(points*100)/100); - return (double)Math.round(points*100)/100; + return points; + //return (double)Math.round(points*100)/100; } else { return 0; @@ -314,32 +451,33 @@ private void updatePoints(String playerUUID, double points, String rankingType, currentPoints = isAdding ? currentPoints + points : currentPoints - points; pluginLogger.log(PluginLogger.LogLevel.DEBUG,String.format("Event: %sPoints: currentPoints: %sAfter: %s", (isAdding ? "add" : "subtract"), rankingType, currentPoints)); - dataManager.setPoints(playerUUID, Math.round(currentPoints * 100) / 100.0, rankingType); + dataManager.setPoints(playerUUID, currentPoints, rankingType); + //dataManager.setPoints(playerUUID, Math.round(currentPoints * 100) / 100.0, rankingType); pluginLogger.log(PluginLogger.LogLevel.DEBUG,String.format("Event: %sPoints: currentPoints: %s ranking saved", (isAdding ? "add" : "subtract"), rankingType)); } public void addPoints(String playerUUID, double points, String rankingType) { OfflinePlayer player = Bukkit.getOfflinePlayer(playerUUID); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: addPoints: playerUUID: "+player.getName()+" rankingType: "+rankingType+" points: "+points); - pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName() +" earned "+points+" in "+rankingType+" ranking"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: addPoints: playerUUID: "+player.getName()+" rankingType: "+rankingType+" points: "+points); + //pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName() +" earned "+points+" in "+rankingType+" ranking"); updatePoints(playerUUID, points, rankingType, true); } public void subtractPoints(String playerUUID, double points, String rankingType) { OfflinePlayer player = Bukkit.getOfflinePlayer(playerUUID); - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: subtractPoints: playerUUID: "+playerUUID+" rankingType: "+rankingType+" points: "+points); - pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName()+" lost "+points+" in "+rankingType+" ranking"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: subtractPoints: playerUUID: "+playerUUID+" rankingType: "+rankingType+" points: "+points); + //pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName()+" lost "+points+" in "+rankingType+" ranking"); updatePoints(playerUUID, points, rankingType, false); } public void addPoints(OfflinePlayer player, double points, String rankingType) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: addPoints: player: "+player.getName()+" rankingType: "+rankingType+" points: "+points); - pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName() +" earned "+points+" in "+rankingType+" ranking"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: addPoints: player: "+player.getName()+" rankingType: "+rankingType+" points: "+points); + //pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName() +" earned "+points+" in "+rankingType+" ranking"); updatePoints(player.getUniqueId().toString(), points, rankingType, true); } public void subtractPoints(OfflinePlayer player, double points, String rankingType) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event: subtractPoints: player: "+player.getName()+" rankingType: "+rankingType+" points: "+points); - pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName()+" lost "+points+" in "+rankingType+" ranking"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: subtractPoints: player: "+player.getName()+" rankingType: "+rankingType+" points: "+points); + //pluginLogger.log(PluginLogger.LogLevel.INFO,"Player "+player.getName()+" lost "+points+" in "+rankingType+" ranking"); updatePoints(player.getUniqueId().toString(), points, rankingType, false); } @@ -355,58 +493,58 @@ private double getMaxElo(String rankingType) { @EventHandler public void onBreak(BlockBreakEvent event) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"onBlockBreak called"); + pluginLogger.log(PluginLogger.LogLevel.BLOCK_BREAK, "onBlockBreak called"); Block block = event.getBlock(); + String blockType = block.getType().toString(); - // Sprawdź, czy blok zniszczony przez gracza znajduje się na liście nagród - String blockType = block.getType().toString(); + if (configManager.getBlockRewards().containsKey(blockType)) { + if (block.getMetadata("placed_by_player").stream().anyMatch(MetadataValue::asBoolean)) { + pluginLogger.log(PluginLogger.LogLevel.BLOCK_BREAK, "onBlockBreak: block was placed by a player"); + return; + } - if (configManager.getBlockRewards().containsKey(blockType)) { - for (MetadataValue meta : block.getMetadata("placed_by_player")) { - if (meta.asBoolean()) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"onBlockBreak: block was placed by a player"); - return; - } - } - double blockReward = configManager.getBlockRewards().get(blockType); - Player player = event.getPlayer(); - String uuid = player.getUniqueId().toString(); - double base = configManager.blockBase; - - double playerElo = dataManager.getPoints(uuid,"main"); - double pointsEarnedMain = calculatePointsEarnedFromBlock(base,playerElo,blockReward, dataManager.getMaxElo("main"), dataManager.getMinElo("main")); - addPoints(uuid,pointsEarnedMain,"main"); - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: onBlockBreak: player: "+player.getName()+", blockType: "+blockType+", pointsEarned: "+pointsEarnedMain+", ranking main"); - - playerElo = dataManager.getPoints(uuid,"daily"); - double pointsEarned = calculatePointsEarnedFromBlock(base,playerElo,blockReward, dataManager.getMaxElo("daily"), dataManager.getMinElo("daily")); - addPoints(uuid,pointsEarned,"daily"); - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: onBlockBreak: player: "+player.getName()+", blockType: "+blockType+", pointsEarned: "+pointsEarned+", ranking daily"); - - playerElo = dataManager.getPoints(uuid,"weekly"); - pointsEarned = calculatePointsEarnedFromBlock(base,playerElo,blockReward, dataManager.getMaxElo("weekly"), dataManager.getMinElo("weekly")); - addPoints(uuid,pointsEarned,"weekly"); - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: onBlockBreak: player: "+player.getName()+", blockType: "+blockType+", pointsEarned: "+pointsEarned+", ranking weekly"); - - playerElo = dataManager.getPoints(uuid,"monthly"); - pointsEarned = calculatePointsEarnedFromBlock(base,playerElo,blockReward, dataManager.getMaxElo("monthly"), dataManager.getMinElo("monthly")); - addPoints(uuid,pointsEarned,"monthly"); - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event: onBlockBreak: player: "+player.getName()+", blockType: "+blockType+", pointsEarned: "+pointsEarned+", ranking monthly"); - - if(pointsEarnedMain>0.001) { - notifyPlayerAboutPoints(player, pointsEarnedMain); - } + double blockReward = configManager.getBlockRewards().get(blockType); + Player player = event.getPlayer(); + String uuid = player.getUniqueId().toString(); + double base = configManager.blockBase; + + if (!Utils.isEloAllowed(player, player.getLocation())) { + //pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL2, "Event: onPlayerDeath noElo zone!"); + //player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "No elo reward in this zone!"); + return; } - else{ - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Block "+blockType+" is not on the list"); + + updatePlayerPoints(uuid, player, base, blockReward, "main"); + updatePlayerPoints(uuid, player, base, blockReward, "daily"); + updatePlayerPoints(uuid, player, base, blockReward, "weekly"); + updatePlayerPoints(uuid, player, base, blockReward, "monthly"); + + if (betterElo.isEventEnabled) { + updatePlayerPoints(uuid, player, base, blockReward, "event"); } + } else { + pluginLogger.log(PluginLogger.LogLevel.BLOCK_BREAK, "Block " + blockType + " is not on the list"); + } + } + + private void updatePlayerPoints(String uuid, Player player, double base, double blockReward, String ranking) { + double playerElo = dataManager.getPoints(uuid, ranking); + double pointsEarned = calculatePointsEarnedFromBlock(base, playerElo, blockReward, dataManager.getMaxElo(ranking), dataManager.getMinElo(ranking)); + addPoints(uuid, pointsEarned, ranking); + pluginLogger.log(PluginLogger.LogLevel.BLOCK_BREAK, "Event: onBlockBreak: player: " + player.getName() + ", pointsEarned: " + pointsEarned + ", ranking " + ranking); + if (ranking.equals("main") && pointsEarned > 0.001) { + notifyPlayerAboutPoints(player, pointsEarned, blockReward, true); + } } // Metoda do dodawania metadanych do bloku podczas stawiania przez gracza @EventHandler public void onBlockPlace(BlockPlaceEvent event) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4,"Event.onBlockPlace: called"); + pluginLogger.log(PluginLogger.LogLevel.BLOCK_PLACE,"Event.onBlockPlace: called"); + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) { + return; // Exit if the player is in Creative mode + } try { Block block = event.getBlockPlaced(); Player player = event.getPlayer(); @@ -422,7 +560,1116 @@ public void onBlockPlace(BlockPlaceEvent event) { pluginLogger.log(PluginLogger.LogLevel.ERROR,"Event.onBlockPlace: "+e.getMessage()); } } + private LivingEntity getTargetEntity(Player player) { + // Prosta implementacja do uzyskania celu ataku gracza + // Można użyć ray tracingu, aby określić, w co gracz celuje + Vector direction = player.getEyeLocation().getDirection().normalize(); + for (int i = 0; i < 5; i++) { // Sprawdzenie w promieniu 5 bloków + Vector targetPos = player.getEyeLocation().add(direction.clone().multiply(i)).toVector(); + for (LivingEntity entity : player.getWorld().getLivingEntities()) { + if (entity.getLocation().toVector().distance(targetPos) < 1.0) { // Sprawdzenie odległości od celu + return entity; + } + } + } + return null; + } + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerInteract(PlayerInteractEvent event) { + + /* + if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) { + if(betterElo.hasMobDamageAttribute(event.getPlayer().getInventory().getItemInMainHand())) { + Player player = event.getPlayer(); + LivingEntity target = getTargetEntity(player); // Musisz zaimplementować tę metodę do uzyskania celu + if (target != null) { + double damage = 2.0; // Ustawienie wartości obrażeń + target.damage(damage, player); + } + } + } + + */ + + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT,"Event.onPlayerInteract called"); + Player player = event.getPlayer(); + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + int removeradius = 0; + + + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + double flamethrowerCooldown = (double) (configManager.flamethrowerCooldown) /1000; + if (canUseFlamethrower(player)) { + if(hasFlamethrowerLore(player)) { + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.onPlayerInteract hasFlamethrowerLore passed"); + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Cooldown " + flamethrowerCooldown + "s"); + lastFlameUsage.put(player, System.currentTimeMillis()); + return; + } + } + + } + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.checking canUseZephyr"); + if(canUseZephyr(player) && event.getAction() == Action.RIGHT_CLICK_AIR) { + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.canUseZephyr passed"); + hasZephyrLore(player); + + } + + + if (hasAntywebLore(itemInHand) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT,"Event.onPlayerInteract antywebcheck passed"); + removeradius = getAntywebRadius(itemInHand); + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT,"Event.onPlayerInteract removeradius "+removeradius); + Location clickedBlockLocation = Objects.requireNonNull(event.getClickedBlock()).getLocation(); + double totalCost=0; + double cost=configManager.antywebCost; + // Iteruj po blokach w promieniu 3 od klikniętego bloku + for (int x = -removeradius; x <= removeradius; x++) { + for (int y = -removeradius; y <= removeradius; y++) { + for (int z = -removeradius; z <= removeradius; z++) { + Location location = clickedBlockLocation.clone().add(x, y, z); + Block block = location.getBlock(); + + // Sprawdź, czy blok to pajęczyna + if (block.getType() == Material.COBWEB) { + + // Usuń pajęczynę + for (MetadataValue meta : block.getMetadata("placed_by_player")) { + if (meta.asBoolean()) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG_LVL4, "onPlayerInteract: cobweb was placed by a player"); + block.setType(Material.AIR); + subtractPoints(player, cost, "main"); + subtractPoints(player, cost, "daily"); + subtractPoints(player, cost, "weekly"); + subtractPoints(player, cost, "monthly"); + if(betterElo.isEventEnabled){ + subtractPoints(player, cost, "event"); + } + totalCost=totalCost+cost; + } + + } + + } + } + } + } + if(totalCost>0){ + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.AQUA + "Elo cost for removing webs: " + ChatColor.DARK_RED + ChatColor.BOLD + totalCost); + } + return; + } + + + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT,"Event.onPlayerInteract checking if its infinite firework"); + ItemStack item = event.getItem(); + + + double fireworkCooldown = (double) (configManager.fireworkCooldown) /1000; + if (item != null && item.getType() == Material.FIREWORK_ROCKET) { + if(event.getAction() != Action.RIGHT_CLICK_AIR) { + event.setCancelled(true); + return; + } + Location location = player.getLocation(); + Location blockBelowLocation = location.clone().subtract(0, 1, 0); + boolean isNotOnGround = blockBelowLocation.getBlock().isPassable(); + + ItemStack chestplate = player.getInventory().getChestplate(); + if(chestplate == null ){ + event.setCancelled(true); + return; + } + if (chestplate.getType().toString().contains("ELYTRA") || hasElytraLore(chestplate)) { + + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT,"Event.onPlayerInteract player is not wearing Elytra!"); + + + + + + + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.onPlayerInteract firework item check passed"); + ItemMeta meta = item.getItemMeta(); + if (meta != null && meta.hasLore()) { + if (!canUseFirework(player)) { + event.setCancelled(true); + return; + + }else{ + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] "+ChatColor.DARK_RED+"Cooldown "+fireworkCooldown+"s"); + } + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.onPlayerInteract firework has lore check passed"); + if (meta.getLore().contains("§6§lInfinite usage")) {// Gold bold "Infinite usage" + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.onPlayerInteract firework has formatted lore check passed"); + if (isNotOnGround) { + lastFireworkUsage.put(player, System.currentTimeMillis()); + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.onPlayerInteract isNotOnGround check passed"); + event.setCancelled(true); // Cancel the event so the firework isn't consumed + FireworkMeta fireworkMeta = (FireworkMeta) item.getItemMeta(); + int power = fireworkMeta.getPower(); + launchFireworkEffect(event.getPlayer()); + applyBoosterEffect(event.getPlayer(), power); + } else { + pluginLogger.log(PluginLogger.LogLevel.PLAYER_INTERACT, "Event.onPlayerInteract isNotOnGround check failed"); + event.setCancelled(true); + } + } + } + }else{ + event.setCancelled(true); + return; + } + } + + + } + private static void launchFireworkEffect(Player player) { + + Location location = player.getLocation(); + player.getWorld().playSound(location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH,SoundCategory.AMBIENT, 1.0f, 1.0f); + } + private static void applyBoosterEffect(Player player,int power) { + + Vector velocity = player.getLocation().getDirection().multiply(power); + player.setVelocity(velocity); + } + private static void applyZephyrEffect(Player player,int power) { + + Vector velocity = player.getLocation().getDirection().multiply(power); + player.setVelocity(velocity); + } + public boolean hasElytraLore(ItemStack itemStack) { + pluginLogger.log(PluginLogger.LogLevel.ELYTRA_CHECK,"Event.hasElytraLore called"); + if (itemStack == null || !itemStack.hasItemMeta()) { + pluginLogger.log(PluginLogger.LogLevel.ELYTRA_CHECK,"Event.hasElytraLore itemmeta check failed"); + return false; + } + + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null || !itemMeta.hasLore()) { + pluginLogger.log(PluginLogger.LogLevel.ELYTRA_CHECK,"Event.hasElytraLore lore check failed"); + return false; + } + + for (String lore : itemMeta.getLore()) { + pluginLogger.log(PluginLogger.LogLevel.ELYTRA_CHECK,"Event.hasElytraLore Elytra check triggered, checking lore and foramtting"); + if (lore != null && lore.contains("§6§lElytra effect")) { + return true; + } + } + + return false; + } + public boolean hasZephyrLore(Player player) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.hasZephyrLore called, player "+player.getName()); + ItemStack itemStack = player.getInventory().getItemInMainHand(); + if (itemStack == null || !itemStack.hasItemMeta()) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.hasZephyrLore itemmeta check failed"); + return false; + } + + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null || !itemMeta.hasLore()) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.hasZephyrLore lore check failed"); + return false; + } + + for (String lore : itemMeta.getLore()) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.hasZephyrLore Zephyr check triggered, checking lore and foramtting"); + if (lore != null && lore.startsWith("§6§lZephyr")) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.hasZephyrLore itemInHand: "+itemStack.displayName()); + if(player.getInventory().getChestplate()!=null){ + ItemStack chestplate = player.getInventory().getChestplate(); + try { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR, "Event.hasZephyrLore chestplate: " + chestplate.displayName()); + if (chestplate.getType().toString().contains("ELYTRA") || hasElytraLore(chestplate)) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR, "Event.hasZephyrLore player " + player.getName() + " is wearing Elytra! Aborting"); + player.sendMessage((ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "You cannot use Zephyr while wearing Elytra!")); + return false; + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Event.hasZephyrLore exception: " + e.getMessage()); + } + }else{ + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR, "Event.hasZephyrLore player: "+player.getName()+" is not wearing chestplate."); + } + String[] parts = lore.split(" "); + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.hasZephyrLore Zephyr power "+parts[1]); + if (parts.length == 2){ + int power = Integer.parseInt(parts[1]); + applyBoosterEffect(player,power); + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.hasZephyrLore adding player "+player.getName()+" to the lastZephyrUsage list"); + lastZephyrUsage.put(player, System.currentTimeMillis()); + // Stwórz nowe zadanie BukkitRunnable, które zatrzyma gracza po 0,75 sekundy + new BukkitRunnable() { + @Override + public void run() { + // Ustawienie wektora prędkości na bardzo małą wartość w kierunku obecnym dla gracza, aby "wyzerować" ruch + player.setVelocity(new Vector(0, -0.0784000015258789, 0)); // Minimalna wartość, by gracze nie utknęli w powietrzu + } + }.runTaskLater(betterElo, 10L); // 15 ticków = 0,75 sekundy + } + return true; + } + } + + return false; + } + private boolean canUseZephyr(Player player) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.canUseZephyr called"); + if (!lastZephyrUsage.containsKey(player)) { + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.canUseZephyr PLAYER NOT LISTED"); + return true; + } + long lastUsage = lastZephyrUsage.get(player); + long currentTime = System.currentTimeMillis(); + pluginLogger.log(PluginLogger.LogLevel.ZEPHYR,"Event.canUseZephyr lastUsage: "+lastUsage+" currentTime: "+currentTime); + return (currentTime - lastUsage) >= configManager.zephyrCooldown; + } + public boolean hasAntywebLore(ItemStack itemStack) { + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.hasAntywebLore called"); + if (itemStack == null || !itemStack.hasItemMeta()) { + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.hasAntywebLore itemmeta check failed"); + return false; + } + + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null || !itemMeta.hasLore()) { + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.hasAntywebLore lore check failed"); + return false; + } + + for (String lore : itemMeta.getLore()) { + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.hasAntywebLore Antyweb check triggered, checking lore"); + if (lore != null && lore.contains("Antyweb")) { + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.hasAntywebLore Antyweb check triggered, checking formatting"); + // Sprawdź, czy lore zawiera słowo "Antyweb" i czy ma odpowiednie formatowanie + String[] parts = lore.split(" "); + if (parts.length == 2 && parts[0].equals(ChatColor.GOLD + "" + ChatColor.BOLD + "Antyweb")) { + try { + // Sprawdź, czy druga część to liczba całkowita + Integer.parseInt(parts[1]); + return true; + } catch (NumberFormatException ignored) { + pluginLogger.log(PluginLogger.LogLevel.ERROR,"Event.hasAntywebLore Antyweb value not INT!"); + } + } + } + } + + return false; + } + private boolean canUseFirework(Player player) { + if (!lastFireworkUsage.containsKey(player)) { + return true; // Gracz jeszcze nie używał fajerwerka + } + long lastUsage = lastFireworkUsage.get(player); + long currentTime = System.currentTimeMillis(); + return (currentTime - lastUsage) >= configManager.fireworkCooldown; + } + public Integer getAntywebRadius(ItemStack itemStack) { + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.getAntywebRadius called"); + if (itemStack == null || !itemStack.hasItemMeta()) { + return null; + } + + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null || !itemMeta.hasLore()) { + return null; + } + + for (String lore : itemMeta.getLore()) { + // Sprawdź, czy linia lore zawiera napis "Antyweb" i czy zawiera formatowanie + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.getAntywebRadius Antyweb check triggered, checking lore"); + if (lore != null && lore.contains("Antyweb")) { + pluginLogger.log(PluginLogger.LogLevel.ANTYWEB,"Event.getAntywebRadius Antyweb check triggered, checking formatting"); + // Sprawdź, czy lore zawiera słowo "Antyweb" i czy ma odpowiednie formatowanie + String[] parts = lore.split(" "); + if (parts.length == 2 && parts[0].equals(ChatColor.GOLD + "" + ChatColor.BOLD + "Antyweb")) { + // Wyodrębnij promień z linii lore + try { + return Integer.parseInt(parts[1]); + } catch (NumberFormatException e) { + // Jeśli nie można przekonwertować na liczbę, zwróć null + return null; + } + } + } + } + + return null; + } + public boolean hasFlamethrowerLore(Player player) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.hasFlamethrowerLore called"); + ItemStack itemStack = player.getInventory().getItemInMainHand(); + if (itemStack == null || !itemStack.hasItemMeta()) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.hasFlamethrowerLore itemmeta check failed"); + return false; + } + + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null || !itemMeta.hasLore()) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.hasFlamethrowerLore lore check failed"); + return false; + } + + for (String lore : itemMeta.getLore()) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.hasFlamethrowerLore Flamethrower check triggered, checking lore"); + if (lore != null && lore.contains("Flamethrower")) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.hasFlamethrowerLore Flamethrower check triggered, checking formatting"); + // Sprawdź, czy lore zawiera słowo "Flamethrower" i czy ma odpowiednie formatowanie + String[] parts = lore.split(" "); + if (parts.length == 2 && parts[0].equals(ChatColor.GOLD + "" + ChatColor.BOLD + "Flamethrower")) { + try { + // Sprawdź, czy druga część to format: X/Y + String[] range = parts[1].split("/"); + if (range.length == 2) { + int diameter = Integer.parseInt(range[0]); + int rangeValue = Integer.parseInt(range[1]); + + // Podpal graczy w okolicy + ignitePlayersInArea(player,diameter,rangeValue); + lastFlameUsage.put(player, System.currentTimeMillis()); + return true; + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Event.hasFlamethrowerLore Lore value format incorrect!"); + } + } catch (NumberFormatException ignored) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Event.hasFlamethrowerLore Lore value not INT!"); + } + } + } + } + + return false; + } + public void ignitePlayersInArea(Player player, int diameter, int range) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER,"ignitePlayersInArea called player:"+player.getName()+" diameter:"+diameter+" range:"+range); + // Pobierz blok, na który gracz aktualnie wskazuje + Set transparent = new HashSet<>(Arrays.asList(Material.AIR, Material.WATER)); // Zdefiniuj przezroczyste bloki, które mają być ignorowane. + Block clickedBlock = player.getTargetBlock(transparent,range); + if (clickedBlock == null) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "No block in player's sight within range: " + range + ". IgnitePlayersInArea aborted for " + player.getName() + "."); + return; // Jeśli gracz nie wskazuje na żaden blok, zakończ działanie funkcji + } + Location clickLocation = clickedBlock.getLocation(); + // Oblicz i zaloguj odległość od gracza rzucającego zaklęcie do klikniętego bloku + double distanceFromCaster = clickLocation.distance(player.getLocation()); + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.ignitePlayersInArea called for player: " + player.getName() + " at click location: " + clickLocation.toString() + ", caster distance from click location: " + distanceFromCaster + ", with diameter: " + diameter + " and range: " + range); + if(isPvPDeniedAtLocation(player,clickLocation)){ + player.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] "+ChatColor.DARK_RED+"Ypu cannot use that in non-pvp zones!"); + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "PVP Denied"); + return; + } + // Iteruj przez wszystkich graczy online w tym samym świecie + for (Player target : player.getWorld().getPlayers()) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Checking player: " + target.getName() + " for potential ignition."); + + // Sprawdź, czy gracz znajduje się w obszarze podpalenia + double distanceToTarget = target.getLocation().distance(clickLocation); + if (distanceToTarget <= diameter && target!=player) { + // Podpal gracza + target.setFireTicks(20 * 5); // Podpal na 5 sekund + //target.sendMessage(ChatColor.RED + "Zostałeś podpalony przez gracza " + player.getName() + "!"); + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Player " + target.getName() + " ignited within diameter. Distance from click location: " + distanceToTarget); + } else { + // Dodajemy logowanie dla sytuacji, gdy gracz jest poza zasięgiem podpalenia + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Player " + target.getName() + " is outside the ignition diameter: " + diameter + ". Distance from click location: " + distanceToTarget); + } + } + } + + + + + private boolean canUseFlamethrower(Player player) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.canUseFlamethrower called. player: "+player.getName()); + if (!lastFlameUsage.containsKey(player)) { + pluginLogger.log(PluginLogger.LogLevel.FLAMETHROWER, "Event.canUseFlamethrower player "+player.getName()+" not on the list. return true"); + return true; // Gracz jeszcze nie używał fajerwerka + } + long lastUsage = lastFlameUsage.get(player); + long currentTime = System.currentTimeMillis(); + return (currentTime - lastUsage) >= configManager.fireworkCooldown; + } + + public boolean isPvPDeniedAtLocation(Player player, Location location) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event.isPvPDeniedAtLocation called"); + try { + com.sk89q.worldedit.world.World weWorld = BukkitAdapter.adapt(location.getWorld()); + + RegionContainer container = com.sk89q.worldguard.WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionManager regions = container.get(weWorld); + + if (regions == null) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.isPvPDeniedAtLocation No regions in world."); + return false; + } else { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.isPvPDeniedAtLocation Found regions: " + regions); + } + + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + + ApplicableRegionSet regionSet = regions.getApplicableRegions(BukkitAdapter.asBlockVector(location)); + + StateFlag.State pvpState = regionSet.queryState(localPlayer, Flags.PVP); + boolean isPvPDenied = pvpState == StateFlag.State.DENY; + + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.isPvPDeniedAtLocation PvP Denied at location: " + location + " is " + isPvPDenied); + + return isPvPDenied; + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Event.isPvPDeniedAtLocation: "+e.toString()); + return false; + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onMobDeath(EntityDeathEvent event) { + String transactionID = UUID.randomUUID().toString(); + //pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS,"CustomMobs.onMobDeath called"); + LivingEntity entity = event.getEntity(); + CustomMobs.CustomMob customMob; + if (entity.hasMetadata("DeathHandled")) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.onMobDeath mobDeath already processed!",transactionID); + return; // Zdarzenie śmierci zostało już obsłużone, więc nic nie rób + } + //CustomMobs.CustomMob customMob = entity; + if (entity.hasMetadata("CustomMob")) { + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.onMobDeath CustomMob metadata check passed",transactionID); + List drops = event.getDrops(); + drops.clear(); // Usuwa standardowy drop, jeśli chcesz + // Tutaj zakładamy, że niestandardowa nazwa moba jest kluczem do dropTable + if (entity.hasMetadata("MobName")) { + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath MobName check passed",transactionID); + List values = entity.getMetadata("MobName"); + // Zakładając, że pierwsza wartość jest właściwą wartością dla twojego pluginu + String mobName = values.get(0).asString(); + + // Załadowanie dropTable dla tego moba + //HashMap dropTable = fileRewardManager.loadCustomDrops(mobName); + customMob = betterElo.getCustomMobFromEntity(entity); + if(customMob!=null) + { + + + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath customMob.dropTable: "+customMob.dropTable,transactionID); + //HashMap dropTable = customMob.dropTable; + List dropTable = customMob.dropTable; + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath dropTable: "+dropTable,transactionID); + + // Iteracja przez dropTable i decydowanie, czy dodawać przedmiot + for (CustomMobsFileManager.DropItem dropItem : dropTable) { + double rolledCance = Math.random(); + double dropChance = dropItem.getDropChance()/100; + if ( rolledCance< dropChance) { // entry.getKey() to szansa na drop + ItemStack item = dropItem.getItemStack(); + ItemMeta meta = item.getItemMeta(); + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath dropItem.isAvgDmgBonus(): "+dropItem.isAvgDmgBonus(),transactionID); + if (dropItem.isAvgDmgBonus()) { + + int AvgDmgBonus = Utils.dropAverageDamage(); + + List lore = meta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + lore.add("§6§lAverage Damage +"+AvgDmgBonus+"%"); + meta.setLore(lore); + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath item: "+item,transactionID); + item.setItemMeta(meta); + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath AvgDmgBonus: "+AvgDmgBonus+", hasAverageDamageAttribute(item):"+betterElo.hasAverageDamageAttribute(item),transactionID); + betterElo.addAverageDamageAttribute(item,AvgDmgBonus); + meta = item.getItemMeta(); + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath AvgDmgBonus: "+AvgDmgBonus+", hasAverageDamageAttribute(item):"+betterElo.hasAverageDamageAttribute(item)+", getAverageDamageAttribute: "+betterElo.getAverageDamageAttribute(item),transactionID); + + } + + + if(dropItem.hasmaxDamage()){ + int maxDamage = betterElo.rollDamage(dropItem.getMaxDamage()); + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath loadedMaxDamage: "+maxDamage,transactionID); + int minDamage = betterElo.rollDamage(maxDamage); + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath minDamage: "+minDamage+", maxDamage: "+maxDamage,transactionID); + List lore = meta.getLore(); + if (lore == null) { + lore = new ArrayList<>(); + } + lore.set(0,"§6§lMob Damage "+minDamage+"-"+maxDamage); + meta.setLore(lore); + item.setItemMeta(meta); + betterElo.addMobDamageAttribute(item,minDamage+"-"+maxDamage,transactionID); + + } + + + + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath item: "+item,transactionID); + drops.add(item); + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath drops.toArray()[0]: "+drops.toArray()[0],transactionID); + + pluginLogger.log(PluginLogger.LogLevel.DROP, "Event.onMobDeath Added item from dropTable to the drops. dropChance: "+dropChance+", rolledChance: "+rolledCance,transactionID); + }else{ + pluginLogger.log(PluginLogger.LogLevel.DROP,"Event.onMobDeath Item from dropTable not added, chance failed. dropChance: "+dropChance+", rolledChance: "+rolledCance,transactionID); + } + } + pluginLogger.log(PluginLogger.LogLevel.INFO , "Event.onMobDeath player: "+event.getEntity().getKiller().getName()+", mobName: "+mobName+", rolledDrop: "+Utils.formatDroppedItems(drops),transactionID); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try{ + Player killer = event.getEntity().getKiller(); + if(!Utils.isEloAllowed(killer,killer.getLocation())){ + //pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath noElo zone!"); + killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "No elo reward in this zone!",transactionID); + return; + } + String[] rankings = {"main", "daily", "weekly", "monthly"}; + boolean eventEnabled = betterElo.isEventEnabled; + + for (String ranking : rankings) { + handleRankingPointsFromMobKill(killer, customMob, ranking,transactionID); + } + + if (eventEnabled) { + handleRankingPointsFromMobKill(killer, customMob, "event",transactionID); + } + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR , "Event.onMobDeath exception: "+e.getMessage(),transactionID); + } + }); + + + + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS,"Event.onMobDeath customMob.mobName: "+customMob.mobName+", customMob.spawnerName: "+customMob.spawnerName,transactionID); + if(customMob.spawnerName!=null){ + + customMobs.decreaseMobCount(customMob.spawnerName); + } + betterElo.unregisterCustomMob(entity); + }else { + pluginLogger.log(PluginLogger.LogLevel.WARNING,"Event.onMobDeath customMob object is null!",transactionID); + } + } else { + customMob = null; + } + + + entity.setMetadata("DeathHandled", new FixedMetadataValue(plugin, true)); + } else { + customMob = null; + } + + + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + String transactionID = UUID.randomUUID().toString(); + long startTime = System.nanoTime(); + Entity damagerEntity = event.getDamager(); + Entity victimEntity = event.getEntity(); + + if (damagerEntity.hasMetadata("handledDamage")) { + //pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onEntityDamageByEntity event already handled!",transactionID); + return; + } + if (damagerEntity instanceof Player){ + damagerEntity.setMetadata("handledDamage", new FixedMetadataValue(plugin, true)); + + new BukkitRunnable() { + @Override + public void run() { + new BukkitRunnable() { + @Override + public void run() { + damagerEntity.removeMetadata("handledDamage", BetterElo.getInstance()); + } + }.runTask(BetterElo.getInstance()); + } + }.runTaskLaterAsynchronously(BetterElo.getInstance(), 1L); + } + if (damagerEntity instanceof Player && victimEntity instanceof Player && !event.isCancelled()) { + Player damager = (Player) event.getDamager(); + Player victim = (Player) event.getEntity(); + int averageDamageBonusPercent = betterElo.getAverageDamageAttribute(Utils.getPlayerEquippedItems((Player) event.getDamager()),transactionID); + double totalDamage = event.getDamage() + event.getDamage() * ((double) averageDamageBonusPercent /100); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onEntityDamageByEntity event.getDamage(): "+event.getDamage()+", averageDamageBonusPercent: "+averageDamageBonusPercent+", totalDamage: "+totalDamage,transactionID); + event.setDamage(totalDamage); + updateLastHitTime(damager); + updateLastHitTime(victim); + }else if (victimEntity.hasMetadata("CustomMob") && damagerEntity instanceof Player){ + Player damager = (Player) event.getDamager(); + + String key = damager.getUniqueId() + ":" + victimEntity.getUniqueId(); + long currentTime = System.currentTimeMillis(); + Long lastAttackTime = lastAttackTimes.get(key); + + String metadataKey = "last-attack-time-" + victimEntity.getUniqueId().toString(); + + // Sprawdzenie, czy metadane istnieją i czy ostatni atak był mniej niż 10 ticków temu + + if (lastAttackTime != null && (currentTime - lastAttackTime) < 500) { + event.setCancelled(true); + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Player " + damager.getName() + " tried to hit too fast!",transactionID); + return; + } + + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.onEntityDamageByEntity custom mob damage by player detected",transactionID); + + int[] damageRange = betterElo.getMobDamageAttribute(damager.getInventory().getItemInMainHand()); + int avgBonus = betterElo.getAverageDamageAttribute(Utils.getPlayerEquippedItems((Player) event.getDamager()),transactionID); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.onEntityDamageByEntity damageRange: "+damageRange.toString()+", avgBonus: "+avgBonus,transactionID); + customEntityDamageEvent(event,damageRange[0],damageRange[1],avgBonus,transactionID); + removePlayerPlacedBlocksAsync(victimEntity,transactionID); + + lastAttackTimes.put(key, currentTime); + + Bukkit.getScheduler().runTaskLater(BetterElo.getInstance(), () -> { + ((LivingEntity)event.getEntity()).setNoDamageTicks(0); + //((Player) event.getEntity()).damage(1D); + }, 1L); + + }else if (damagerEntity.hasMetadata("CustomMob") && victimEntity instanceof Player) { + int customArmorBonus =betterElo.getMobDefenseAttribute(Utils.getPlayerEquippedItems((Player) victimEntity)); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.EntityDamageEvent getFinalDamage: "+event.getFinalDamage()+", customArmorBonus: "+customArmorBonus,transactionID); + event.setDamage(event.getFinalDamage()*(1-(0.004*customArmorBonus))); + + } + + if (victimEntity instanceof LivingEntity) { + LivingEntity entity = (LivingEntity) event.getEntity(); + if (entity.hasMetadata("CustomMob")) { + new BukkitRunnable() { + @Override + public void run() { + new BukkitRunnable() { + @Override + public void run() { + if (!entity.isDead()) { + customMobs.updateCustomMobName(entity,transactionID); + } + } + }.runTask(BetterElo.getInstance()); + } + }.runTaskLaterAsynchronously(BetterElo.getInstance(), 1L); + + } + } + + long endTime = System.nanoTime(); + long duration = endTime - startTime; + double durationInMillis = duration / 1_000_000.0; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onEntityDamageByEntity execution time: " + durationInMillis + " ms",transactionID); + + + + + } + public void customDamageHandling(Player damager, Player victim, double initialDamage) { + int averageDamageBonusPercent = betterElo.getAverageDamageAttribute(Utils.getPlayerEquippedItems(damager),null); + double totalDamage = initialDamage + initialDamage * averageDamageBonusPercent; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "customDamageHandling initialDamage: " + initialDamage + ", averageDamageBonusPercent: " + averageDamageBonusPercent + ", totalDamage: " + totalDamage); + victim.damage(totalDamage, damager); + updateLastHitTime(damager); + updateLastHitTime(victim); + } + public void customEntityDamageEvent(EntityDamageByEntityEvent event,int minDamage, int maxDamage, int averageDamageBonusPercent,String transactionID){ + long timer; + double armor=1,defense=0; + double averageDamage = (double) (minDamage + maxDamage) / 2; // Średnia wartość obrażeń + int bonusDamage = (int) (averageDamage * (averageDamageBonusPercent / 100.0)); // Obliczenie bonusu + double totalDamage = minDamage + random.nextInt(maxDamage - minDamage + 1) + bonusDamage; // Całkowite obrażenia + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.customEntityDamageEvent minDamage: "+minDamage+", maxDamage: "+maxDamage+", averageDamage: "+averageDamage+", averageDamageBonusPercent: "+averageDamageBonusPercent+", bonusDamage: "+bonusDamage,transactionID); + CustomMobs.CustomMob customMob = null; + customMob = betterElo.getCustomMobFromEntity(event.getEntity()); + if(customMob!=null) + { + defense = customMob.defense; + armor = customMob.armor; + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.customEntityDamageEvent from customMob object - defense: "+defense+", armor: "+armor,transactionID); + + } + double defDmgReduction= (1-(0.01*defense)); + double finalDamage =event.getFinalDamage()+((totalDamage-armor)*defDmgReduction); + if(finalDamage<=0) + finalDamage=0; + event.setDamage(finalDamage); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.customEntityDamageEvent finalDamage: "+finalDamage+", totalDamage: " + totalDamage+", bonusDamage: "+bonusDamage+", defDmgReduction(1-(0.01*defense)): "+defDmgReduction+", armor: "+armor,transactionID); + } + public void removePlayerPlacedBlocksAsync(Entity entity,String transactionID) { + // Asynchronicznie przygotowujesz dane + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + List blocksToRemove = new ArrayList<>(); + Block baseBlock = entity.getLocation().getBlock(); + + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 2; y++) { + for (int z = -1; z <= 1; z++) { + Block relBlock = baseBlock.getRelative(x, y, z); + if (relBlock.hasMetadata("placed_by_player")) { + blocksToRemove.add(relBlock); + } + } + } + } + + // Synchroniczne usuwanie bloków w głównym wątku + Bukkit.getScheduler().runTask(plugin, () -> { + for (Block block : blocksToRemove) { + block.setType(Material.AIR); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Removing player-placed block at " + block.getLocation(),transactionID); + } + }); + }); + } + @EventHandler(priority = EventPriority.LOW) + public void onInventoryClick(InventoryClickEvent event) { + String transactionID = UUID.randomUUID().toString(); + Player player = (Player) event.getWhoClicked(); + String playerName = player.getName(); + String playerUUID = player.getUniqueId().toString(); + if (player.hasMetadata("avgDmgRerolled")) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick avgDmgRerolled event already handled!",transactionID,playerName,playerUUID); + return; + } + + // Sprawdzamy, czy event to przeciąganie przedmiotu + if (!event.isCancelled()) { + ItemStack cursorItem = event.getCursor(); // przedmiot, który gracz trzyma myszką + ItemStack destinationItem = event.getCurrentItem(); // przedmiot na miejscu docelowym w ekwipunku + + if (cursorItem != null && Utils.isEnchantItem(cursorItem)) { + //pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick: Enchant item detected. cursorItem: " + cursorItem.getItemMeta().getLore() + ", hasMobDamageAttribute: " + betterElo.hasMobDamageAttribute(cursorItem) + ", hasAverageDamageAttribute: " + betterElo.hasAverageDamageAttribute(destinationItem) + ", hasMonDamage " + betterElo.hasMobDamageAttribute(destinationItem) + ", lore: " + destinationItem.getItemMeta().getLore(),transactionID,playerName,playerUUID); + if (destinationItem != null && betterElo.hasMobDamageAttribute(destinationItem) && betterElo.hasAverageDamageAttribute(destinationItem)) { + + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick: Mob damage and average damage bonus detected.",transactionID,playerName,playerUUID); + player.setMetadata("avgDmgRerolled", new FixedMetadataValue(plugin, true)); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + @Override + public void run() { + player.removeMetadata("avgDmgRerolled", plugin); + } + }, 1L); + + + + int avgDmg = Utils.dropAverageDamage(); + ItemStack newDestination = destinationItem.clone(); + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick: Rerolling average damage bonus. New bonus: " + avgDmg,transactionID,playerName,playerUUID); + utils.updateAverageDamage(newDestination, avgDmg); + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick: Item updated with new average damage bonus. newItem avgbonus: " + betterElo.getAverageDamageAttribute(destinationItem),transactionID,playerName,playerUUID); + + /* + event.setCursor(cursorItem); + if(cursorItem.getAmount() <=1) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick: Rerolling average damage bonus. cursorItem amount: " + cursorItem.getAmount(),transactionID,playerName,playerUUID); + event.setCursor(null); + } + else { + cursorItem.setAmount(cursorItem.getAmount() - 1); + event.setCursor(cursorItem); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick: Rerolling average damage bonus. cursorItem amount: " + cursorItem.getAmount(),transactionID,playerName,playerUUID); + } + + */ + + cursorItem.setAmount(cursorItem.getAmount() - 1); + event.setCursor(cursorItem.getAmount() > 0 ? cursorItem : null); + event.setCurrentItem(newDestination); + event.setCancelled(true); + + + // Informacja dla gracza + if (avgDmg >= 50) { + event.getWhoClicked().sendMessage(ChatColor.GREEN + "New average damage bonus: " + ChatColor.DARK_RED + "" + ChatColor.BOLD + avgDmg + "%"); + } else if (avgDmg >= 40) { + event.getWhoClicked().sendMessage(ChatColor.GREEN + "New average damage bonus: " + ChatColor.RED + "" + ChatColor.BOLD + avgDmg + "%"); + } else if (avgDmg >= 30) { + event.getWhoClicked().sendMessage(ChatColor.GREEN + "New average damage bonus: " + ChatColor.GOLD + "" + ChatColor.BOLD + avgDmg + "%"); + } else if (avgDmg >= 20) { + event.getWhoClicked().sendMessage(ChatColor.GREEN + "New average damage bonus: " + ChatColor.BOLD + avgDmg + "%"); + }else { + event.getWhoClicked().sendMessage(ChatColor.GREEN + "New average damage bonus: " + avgDmg + "%"); + } + return; + + } + + } + } + + + if(event.getCurrentItem()==null){ + return; + } + if(event.getCurrentItem().getType() == Material.GRAY_STAINED_GLASS_PANE || event.getCurrentItem().getType() == Material.GREEN_WOOL){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick green wool or blank pane clicked, cancelling..",transactionID,playerName,playerUUID); + event.setCancelled(true); + + } + + ItemStack currentItem = event.getCurrentItem(); + Inventory playerInventory = player.getInventory(); + ItemStack[] savedInventory = playerInventory.getContents(); + + String title = event.getView().getTitle(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick called. title:"+title,transactionID,playerName,playerUUID); + if (!Arrays.asList("Set Rewards", "Add Items", "Select Top", "AvgDmg bonus change").contains(title)) { + return; + } + + + + + if (currentItem == null || currentItem.getType() == Material.AIR) { + return; + } + Inventory inv; + //String rewardTypeTemp = currentItem.getItemMeta().getDisplayName(); + switch (title) { + case "Set Rewards": + event.setCancelled(true); + guiManager.periodType = currentItem.getItemMeta().getDisplayName(); + if (guiManager.periodType.equals("dropTable")) { + List currentRewards = fileRewardManager.loadRewards(); + inv = Bukkit.createInventory(null, 36, "Add Items"); + currentRewards.forEach(inv::addItem); + guiManager.createItem(inv, Material.GREEN_WOOL, 35, "Save", "Save drop table"); + player.openInventory(inv); + break; + } + guiManager.openSubGui(player); + break; + case "Select Top": + event.setCancelled(true); + guiManager.rewardType = currentItem.getItemMeta().getDisplayName(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"Event.onInventoryClick: rewardType:" + guiManager.rewardType + " periodType:" + guiManager.periodType,transactionID,playerName,playerUUID); + fileRewardManager.setRewardType(guiManager.periodType, guiManager.rewardType); + List currentRewards = fileRewardManager.loadRewards(); + inv = Bukkit.createInventory(null, 36, "Add Items"); + currentRewards.forEach(inv::addItem); + guiManager.createItem(inv, Material.GREEN_WOOL, 35, "Save", "Save rewards"); + //createItem(inv, Material.ORANGE_WOOL, 34, "Reset", "Resetuj czas"); + //createItem(inv, Material.YELLOW_WOOL, 33, "Reedem", "Rozdaj nagrody"); + player.openInventory(inv); + break; + case "Add Items": + //save button check + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick Add Items",transactionID,playerName,playerUUID); + if (currentItem.getType() == Material.GREEN_WOOL && (event.getSlot() == 53)) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick Add Items - save called.",transactionID,playerName,playerUUID); + event.setCancelled(true); + Inventory inventory = event.getInventory(); + List itemsToSave = new ArrayList<>(); + for (int i = 0; i < inventory.getSize(); i++) { + if (i == 53) { // Pomijamy slot przycisku "Save" + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick save button, skipping.",transactionID,playerName,playerUUID); + continue; + } + ItemStack item = inventory.getItem(i); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick save: item: " + item,transactionID,playerName,playerUUID); + if (item != null && item.getType() != Material.AIR) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick no air save: item: " + item,transactionID,playerName,playerUUID); + itemsToSave.add(item); + } + + } + + String fileName = guiManager.periodType + "_" + guiManager.dropTable; + + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick guiManager.periodType=" + guiManager.periodType,transactionID,playerName,playerUUID); + if (guiManager.periodType.equals("dropTable")) { + fileName = guiManager.dropTable; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick droptable: " + fileName,transactionID,playerName,playerUUID); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick calling fileRewardManager.saveCustomDrops(" + fileName + ",itemsToSave)",transactionID,playerName,playerUUID); + fileRewardManager.saveCustomDrops(fileName, itemsToSave); + } else { + fileRewardManager.saveCustomDrops(fileName, itemsToSave); + } + + } + if (currentItem.getType() == Material.GREEN_WOOL && event.getSlot() == 35) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick Add Items - save called.",transactionID,playerName,playerUUID); + event.setCancelled(true); + Inventory inventory = event.getInventory(); + List itemsToSave = new ArrayList<>(); + for (int i = 0; i < inventory.getSize(); i++) { + if (i != 35) { // Pomijamy slot przycisku "Save" + ItemStack item = inventory.getItem(i); + if (item != null && item.getType() != Material.AIR) { + itemsToSave.add(item); + } + } + } + + String fileName = guiManager.periodType + "_" + guiManager.rewardType; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClick calling fileRewardManager.saveRewards(" + fileName + ",itemsToSave)",transactionID,playerName,playerUUID); + fileRewardManager.saveRewards(fileName, itemsToSave); + + } + break; + case "AvgDmg bonus change": + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick Average Damage bonus re-roll",transactionID,playerName,playerUUID); + + if (currentItem.getType() == Material.GREEN_WOOL && event.getSlot() == 5) { + playerInventory.setContents(savedInventory); + event.setCancelled(true); + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick Average Damage bonus re-roll clicked",transactionID,playerName,playerUUID); + Inventory inventory = event.getInventory(); + ItemStack item0 = inventory.getItem(3); + if (item0 != null && item0.hasItemMeta()) { + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick reroll, betterElo.hasMobDamageAttribute(item0): "+betterElo.hasMobDamageAttribute(item0)+", betterElo.hasAverageDamageAttribute(item0): "+betterElo.hasAverageDamageAttribute(item0),transactionID,playerName,playerUUID); + ItemStack result = item0.clone(); + ItemMeta resultMeta = result.getItemMeta(); + List lore = new ArrayList<>(resultMeta.getLore()); + if (betterElo.hasMobDamageAttribute(item0) && betterElo.hasAverageDamageAttribute(item0)) { + if (Utils.checkAndRemoveEnchantItem(player)) { + int avgDmg = Utils.dropAverageDamage(); + betterElo.addAverageDamageAttribute(result, avgDmg); + resultMeta = result.getItemMeta(); + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick reroll, player paid, re-rolling...",transactionID,playerName,playerUUID); + for (int i = 0; i < lore.size(); i++) { + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick lore i="+i,transactionID,playerName,playerUUID); + if (lore.get(i).contains("Average Damage")) { + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick lore i="+i+" contains Average Damage, setting avgDmg: "+avgDmg,transactionID,playerName,playerUUID); + lore.set(i,"§6§lAverage Damage +" + avgDmg + "%"); + } + } + } + player.setMetadata("avgDmgRerolled", new FixedMetadataValue(plugin, true)); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + @Override + public void run() { + player.removeMetadata("avgDmgRerolled", plugin); + } + }, 1L); + + + resultMeta.setLore(lore); + result.setItemMeta(resultMeta); + inventory.setItem(3, result); + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick result placed back in slot 3",transactionID,playerName,playerUUID); + } + pluginLogger.log(PluginLogger.LogLevel.REROLL, "Event.onInventoryClick reroll, player has no money for the re-roll.",transactionID,playerName,playerUUID); + + + ItemStack greenWoolItem = inventory.getItem(5); + + if (greenWoolItem != null && greenWoolItem.hasItemMeta()) { + ItemMeta greenWoolMeta = greenWoolItem.getItemMeta(); + List greenWoolLore = greenWoolMeta.hasLore() ? new ArrayList<>(greenWoolMeta.getLore()) : new ArrayList<>(); + String avgDmgLine = lore.stream().filter(line -> line.contains("Average Damage")).findFirst().orElse("Average Damage +0%"); + + // Ustalanie indeksów dla "current bonus:" i wartości + int bonusIndex = -1; + for (int i = 0; i < greenWoolLore.size(); i++) { + if (greenWoolLore.get(i).equals("current bonus:")) { + bonusIndex = i; + break; + } + } + + if (bonusIndex != -1 && bonusIndex + 1 < greenWoolLore.size()) { + // Aktualizujemy istniejącą wartość jeśli jest miejsce w lore + greenWoolLore.set(bonusIndex + 1, "<" + avgDmgLine + ">"); + } else if (bonusIndex == -1) { + // Dodajemy nowe linie jeśli "current bonus:" nie istnieje + greenWoolLore.add("current bonus:"); + greenWoolLore.add("<" + avgDmgLine + ">"); + } else { + // Jeśli "current bonus:" jest na końcu listy, dodajemy wartość + greenWoolLore.add("<" + avgDmgLine + ">"); + } + + greenWoolMeta.setLore(greenWoolLore); + greenWoolItem.setItemMeta(greenWoolMeta); + inventory.setItem(5, greenWoolItem); + + + } + } + } + break; + } + + + } + + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + Player player = (Player) event.getPlayer(); + Inventory closedInventory = event.getInventory(); + + // Check if the closed inventory is the same one we're interested in + if (event.getView().getTitle().equalsIgnoreCase("AvgDmg bonus change")) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClose: Checking items in closed GUI"); + + ItemStack itemInSlot0 = closedInventory.getItem(3); + if (itemInSlot0 != null) { + ItemMeta meta = itemInSlot0.getItemMeta(); + //if (meta.getLore().stream().anyMatch(line -> line.contains("Average Damage"))) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClose: Item with 'Average damage' found in slot 0"); + + // Optional: Directly give back the item to the player's inventory + if (player.getInventory().addItem(itemInSlot0).size() == 0) { + // Item successfully added to player's inventory + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClose: Item returned to player inventory"); + closedInventory.clear(3); // Clear the slot after returning item + } else { + // Inventory full, drop item at player's location + player.getWorld().dropItem(player.getLocation(), itemInSlot0); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.onInventoryClose: Inventory full, item dropped at player's location"); + closedInventory.clear(3); // Clear the slot + } + //} + } + } + } + @EventHandler + public void onEntityMove(EntityMoveEvent event) { + Entity entity = event.getEntity(); + CustomMobs.CustomMob customMob = null; + customMob = betterElo.getCustomMobFromEntity(entity); + + if (customMob != null) { + Location entityLocation = entity.getLocation(); + if (customMob.spawnerName!=null) { + String spawnerLocationString = customMobsFileManager.getSpawnerLocation(customMob.spawnerName); + Location spawnerLocation = customMobs.getLocationFromString(spawnerLocationString); + int maxDistance = customMobsFileManager.getMaxDistance(customMob.spawnerName); + if(maxDistance==0){ + maxDistance=20; + } + if (spawnerLocation==null){ + return; + } + if (entityLocation.distance(spawnerLocation) > maxDistance) { + // Teleportacja entity z powrotem do spawnerLocation + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "Event.onEntityMove teleporting mob: "+customMob.mobName); + while (spawnerLocation.getBlock().getType() != Material.AIR) { + spawnerLocation.add(0, 1, 0); // Zwiększ y o 1 + if (spawnerLocation.getBlockY() > spawnerLocation.getWorld().getMaxHeight()) { + // Jeśli przekraczamy maksymalną wysokość, przerwij pętlę, aby uniknąć pętli nieskończonej + System.out.println("Reached the top of the world without finding an AIR block."); + break; + } + } + spawnerLocation.add(0, 1, 0); + entity.teleport(spawnerLocation); + } + } + + + + + } + } + + } + diff --git a/src/main/java/betterbox/mine/game/betterelo/ExtendedConfigManager.java b/src/main/java/betterbox/mine/game/betterelo/ExtendedConfigManager.java index e5b5220..64c7991 100644 --- a/src/main/java/betterbox/mine/game/betterelo/ExtendedConfigManager.java +++ b/src/main/java/betterbox/mine/game/betterelo/ExtendedConfigManager.java @@ -3,6 +3,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.plugin.java.JavaPlugin; +import javax.servlet.annotation.HandlesTypes; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -13,10 +14,16 @@ public class ExtendedConfigManager { private JavaPlugin plugin; private PluginLogger pluginLogger; List logLevels = null; + List eventItemsPlaceholder = null; + Set enabledEventItemsPlaceholder; private File configFile = null; Set enabledLogLevels; public Double blockBase = 0.1; + public Double antywebCost = 0.1; + public int fireworkCooldown = 1500; + public int zephyrCooldown = 1500; + public int flamethrowerCooldown = 1500; public ExtendedConfigManager(JavaPlugin plugin, PluginLogger pluginLogger) { this.plugin = plugin; @@ -77,7 +84,7 @@ public void ReloadConfig() { } catch (IllegalArgumentException e) { // Jeśli podano nieprawidłowy poziom logowania, zaloguj błąd - plugin.getServer().getLogger().warning("Invalid log level in config: " + level); + pluginLogger.log(PluginLogger.LogLevel.ERROR,"Invalid log level in config: " + level+", exception: "+e.getMessage()); } } pluginLogger.setEnabledLogLevels(enabledLogLevels); @@ -119,6 +126,126 @@ public void ReloadConfig() { //blockBaseSection.set("value", 0.1); plugin.saveConfig(); } + antywebCost = plugin.getConfig().getDouble("antyweb_elo_cost"); + if (plugin.getConfig().contains("antyweb_elo_cost")){ + if (plugin.getConfig().isDouble("antyweb_elo_cost")){ + antywebCost = plugin.getConfig().getDouble("antyweb_elo_cost"); + } + else { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: antyweb_elo_cost incorrect! Restoring default"); + plugin.getConfig().set("antyweb_elo_cost", 1.5); + plugin.saveConfig(); + } + } + else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: antyweb_elo_cost section not found in config! Creating new section.."); + plugin.getConfig().createSection("antyweb_elo_cost"); + plugin.getConfig().set("antyweb_elo_cost", 0.1); + //blockBaseSection.set("value", 0.1); + plugin.saveConfig(); + } + + //Firework cooldown + fireworkCooldown = plugin.getConfig().getInt("Infinite_firework_cooldown"); + if (plugin.getConfig().contains("Infinite_firework_cooldown")){ + if (plugin.getConfig().isInt("Infinite_firework_cooldown")){ + fireworkCooldown = plugin.getConfig().getInt("Infinite_firework_cooldown"); + } + else { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: Infinite_firework_cooldown incorrect! Restoring default"); + plugin.getConfig().set("Infinite_firework_cooldown", 1500); + plugin.saveConfig(); + } + } + else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: Infinite_firework_cooldown section not found in config! Creating new section.."); + plugin.getConfig().createSection("Infinite_firework_cooldown"); + plugin.getConfig().set("Infinite_firework_cooldown", 1500); + //blockBaseSection.set("value", 0.1); + plugin.saveConfig(); + } + + //Flamethrower cooldown + flamethrowerCooldown = plugin.getConfig().getInt("Flamethrower_cooldown"); + if (plugin.getConfig().contains("Flamethrower_cooldown")){ + if (plugin.getConfig().isInt("Flamethrower_cooldown")){ + flamethrowerCooldown = plugin.getConfig().getInt("Flamethrower_cooldown"); + } + else { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: Flamethrower_cooldown incorrect! Restoring default"); + plugin.getConfig().set("Flamethrower_cooldown", 1500); + plugin.saveConfig(); + } + } + else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: Flamethrower_cooldown section not found in config! Creating new section.."); + plugin.getConfig().createSection("Flamethrower_cooldown"); + plugin.getConfig().set("Flamethrower_cooldown", 1500); + plugin.saveConfig(); + } + + //Zephyr cooldown + zephyrCooldown = plugin.getConfig().getInt("Zephyr_cooldown"); + if (plugin.getConfig().contains("Zephyr_cooldown")){ + if (plugin.getConfig().isInt("Zephyr_cooldown")){ + zephyrCooldown = plugin.getConfig().getInt("Zephyr_cooldown"); + } + else { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: Zephyr_cooldown incorrect! Restoring default"); + plugin.getConfig().set("Zephyr_cooldown", 1500); + plugin.saveConfig(); + } + } + else{ + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: Zephyr_cooldown section not found in config! Creating new section.."); + plugin.getConfig().createSection("Zephyr_cooldown"); + plugin.getConfig().set("Zephyr_cooldown", 1500); + plugin.saveConfig(); + } + + + + + + + + //wczytywanie listy itemow do ktorych bedzie przypisywana nazwa gracza przy rozdaniu nagrod +/* + ConfigurationSection eventItemsSection = plugin.getConfig().getConfigurationSection("event_items_with_username"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"extendedConfigManager.ReloadConfig checking event_items_with_username section"); + if (eventItemsSection != null) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"extendedConfigManager.ReloadConfig event_items_with_username section not null"); + // Jeśli sekcja istnieje, odczytaj jej zawartość i zapisz w pamięci + for (String eventItem : eventItemsSection.getKeys(false)) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"extendedConfigManager.ReloadConfig event_items_with_username section checking item "+eventItem); + String ItemID = plugin.getConfig().getString("event_items_with_username." +eventItem); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, eventItem+":"+ ItemID); + eventItemsPlaceholder.add(ItemID); + } + } else { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: event_items_with_username section not found in config! Creating new section.."); + eventItemsSection = plugin.getConfig().createSection("event_items_with_username"); + //eventItemsSection.setComments("event_items_with_username", Collections.singletonList("To the lore of these items will be added a name of the player that received the item")); + plugin.saveConfig(); + } + + */ +// Wczytywanie listy itemów, do których będzie przypisywana nazwa gracza przy rozdaniu nagród + List eventItemsWithUsername = plugin.getConfig().getStringList("event_items_with_username"); + if (eventItemsWithUsername == null || eventItemsWithUsername.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "ConfigManager: ReloadConfig: event_items_with_username section not found in config or is empty! Creating new section with default values."); + // Tutaj możesz ustawić domyślne wartości, jeśli lista jest pusta lub nie istnieje + plugin.getConfig().set("event_items_with_username", Arrays.asList("DIAMOND_PICKAXE")); // Przykład domyślnych wartości + plugin.saveConfig(); + } else { + // Lista istnieje i ma elementy, logowanie lub inne operacje + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "event_items_with_username loaded: " + eventItemsWithUsername.toString()); + // Możesz tutaj przypisać wczytaną listę do zmiennej klasy, jeśli potrzebujesz + this.eventItemsPlaceholder = eventItemsWithUsername; + } + + + } diff --git a/src/main/java/betterbox/mine/game/betterelo/FileRewardManager.java b/src/main/java/betterbox/mine/game/betterelo/FileRewardManager.java index ce6dea8..6f4dd3c 100644 --- a/src/main/java/betterbox/mine/game/betterelo/FileRewardManager.java +++ b/src/main/java/betterbox/mine/game/betterelo/FileRewardManager.java @@ -7,12 +7,18 @@ import java.io.IOException; import org.bukkit.entity.Player; +import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; import java.util.List; import java.util.ArrayList; +import java.util.Map; +import java.util.stream.Collectors; +import org.bukkit.attribute.AttributeModifier; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.configuration.ConfigurationSection;; @@ -22,15 +28,17 @@ public class FileRewardManager { private final PluginLogger pluginLogger; // Dodajemy referencję do PluginLogger private String rewardType; + private File dataFolder; public FileRewardManager(JavaPlugin plugin, PluginLogger pluginLogger) { this.plugin = plugin; this.pluginLogger = pluginLogger; // Inicjalizujemy PluginLogger pluginLogger.log(PluginLogger.LogLevel.DEBUG,"FileRewardManager: Inicjalizacja"); + dataFolder = new File(plugin.getDataFolder(),"data"); } public void setRewardType(String rewardType,String subType) { - pluginLogger.log(PluginLogger.LogLevel.DEBUG,"FileRewardManager: getRewardType: rewardType: "+rewardType+" subType: "+subType); + pluginLogger.log(PluginLogger.LogLevel.DEBUG,"FileRewardManager: setRewardType: rewardType: "+rewardType+" subType: "+subType); this.rewardType = rewardType + "_" + subType; } @@ -41,7 +49,23 @@ public String getRewardType() { } public List loadRewards() { - File rewardsFile = new File(plugin.getDataFolder(), rewardType + ".yml"); + + File rewardsFile = new File(dataFolder, rewardType + ".yml"); + if (!rewardsFile.exists()) { + return new ArrayList<>(); // return empty list if the file does not exist + } + FileConfiguration config = YamlConfiguration.loadConfiguration(rewardsFile); + List rewards = new ArrayList<>(); + for (String key : config.getConfigurationSection("items").getKeys(false)) { + ItemStack item = config.getItemStack("items." + key); + if (item != null && item.getType() != Material.AIR) { + rewards.add(item); + } + } + return rewards; + } + public List loadReRollCost() { + File rewardsFile = new File(dataFolder, "reroll.yml"); if (!rewardsFile.exists()) { return new ArrayList<>(); // return empty list if the file does not exist } @@ -56,7 +80,7 @@ public List loadRewards() { return rewards; } public List loadRewards(Player player) { - File rewardsFile = new File(plugin.getDataFolder(), rewardType + ".yml"); + File rewardsFile = new File(dataFolder, rewardType + ".yml"); if (!rewardsFile.exists()) { return new ArrayList<>(); // return empty list if the file does not exist } @@ -65,7 +89,7 @@ public List loadRewards(Player player) { } public List getReward(String rewardType) { // Załaduj konfigurację z pliku dla danego typu nagrody - File rewardFile = new File(plugin.getDataFolder(), rewardType + ".yml"); + File rewardFile = new File(dataFolder, rewardType + ".yml"); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"FileRewardManager: getReward: rewardType:" + rewardType); FileConfiguration rewardConfig = YamlConfiguration.loadConfiguration(rewardFile); // Pobierz dane o nagrodzie z pliku konfiguracyjnego @@ -96,4 +120,97 @@ public List getReward(String rewardType) { pluginLogger.log(PluginLogger.LogLevel.DEBUG,"FileRewardManager: getReward: items:" + rewards); return rewards; } + public void saveRewards(String fileName, List rewards) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "FileRewardManager.saveRewards called. fileName: "+fileName); + File rewardsFile = new File(dataFolder, fileName + ".yml"); + if (!rewardsFile.getParentFile().exists()) { + rewardsFile.getParentFile().mkdirs(); // Tworzy katalog, jeśli nie istnieje + } + FileConfiguration config = YamlConfiguration.loadConfiguration(rewardsFile); + + ConfigurationSection itemsSection = config.createSection("items"); + int index = 0; + for (ItemStack item : rewards) { + itemsSection.set("item" + index, item); // Zapisuje każdy element pod kluczem itemX, gdzie X to indeks elementu + index++; + } + + try { + config.save(rewardsFile); // Zapisuje konfigurację do pliku + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "FileRewardManager: saveRewards: Zapisano nagrody do " + fileName + ".yml"); + } catch (IOException e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "FileRewardManager: saveRewards: Nie udało się zapisać nagród: " + e.getMessage()); + } + } + public void saveCustomDrops(String fileName, List rewards) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "FileRewardManager.saveCustomDrops called, fileName: "+fileName); + File customDropsFolder = new File(plugin.getDataFolder() + File.separator + "customDrops"); + if (!customDropsFolder.exists()) { + pluginLogger.log(PluginLogger.LogLevel.INFO, "customDropsFolder does not exist, creating a new one"); + customDropsFolder.mkdirs(); + } + + File customDropTablesFolder = new File(plugin.getDataFolder() + File.separator + "customDropTables"); + if (!customDropTablesFolder.exists()) { + pluginLogger.log(PluginLogger.LogLevel.INFO, "customDropTablesFolder does not exist, creating a new one"); + customDropTablesFolder.mkdirs(); + } + + File dropTableFile = new File(customDropTablesFolder, fileName + ".yml"); + pluginLogger.log(PluginLogger.LogLevel.INFO, "Droptable will be saved to "+fileName+".yml"); + FileConfiguration dropTableConfig = new YamlConfiguration(); + + int index = 0; + for (ItemStack item : rewards) { + if (item == null) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "ItemStack is null at index: " + index); + continue; + } + ; + String itemFileName = fileName + "_item" + index + ".yml"; + pluginLogger.log(PluginLogger.LogLevel.INFO, "Droptable "+fileName+", itemFileName "+itemFileName+", index "+index+", saving item: "+item.getItemMeta().toString()); + + try { + File itemFile = new File(customDropsFolder, itemFileName); + itemFile.createNewFile(); + FileConfiguration itemConfig = YamlConfiguration.loadConfiguration(itemFile); + itemConfig.set("item", item); + itemConfig.save(itemFile); + + // Dodaj wpis do pliku tabeli dropów + String itemPath = "customDrops/" + itemFileName; + dropTableConfig.set("Item" + index + ".itemPath", itemPath); + dropTableConfig.set("Item" + index + ".dropChance", 0.00); // Tutaj można ustawić faktyczną szansę na drop + String itemNameString = item.getType().toString(); + dropTableConfig.set("Item" + index + ".itemName", itemNameString); // Tutaj można ustawić faktyczną szansę na drop + dropTableConfig.set("Item" + index + ".avgDmgBonus", false); // Tutaj można ustawić faktyczną szansę na drop + if(item.getItemMeta().hasLore()) { + String itemDisplayName = item.getItemMeta().displayName().toString(); + dropTableConfig.set("Item" + index + ".displayName", itemDisplayName); // Tutaj można ustawić faktyczną szansę na drop + if(item.getItemMeta().hasLore()) { + dropTableConfig.set("Item" + index + ".description", item.getItemMeta().lore().get(1)); // Tutaj można ustawić faktyczną szansę na drop + } + } + + + index++; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "dropTableConfig with index "+index+" saved"); + + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Cannot save the item : "+index +", error: "+ e.getMessage()); + } + } + + try { + dropTableConfig.save(dropTableFile); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "dropTableConfig saved "); + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Nie można zapisać tabeli dropów: " + e.getMessage()); + } + } + + + + + } diff --git a/src/main/java/betterbox/mine/game/betterelo/GuiManager.java b/src/main/java/betterbox/mine/game/betterelo/GuiManager.java index 398a359..b9a0772 100644 --- a/src/main/java/betterbox/mine/game/betterelo/GuiManager.java +++ b/src/main/java/betterbox/mine/game/betterelo/GuiManager.java @@ -1,28 +1,48 @@ package betterbox.mine.game.betterelo; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; +import org.bukkit.event.EventPriority; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import java.util.Arrays; +import org.bukkit.plugin.java.JavaPlugin; + +import java.awt.*; +import java.util.*; import java.util.List; import java.util.stream.Collectors; -public class GuiManager implements Listener { +public class GuiManager{ private final FileRewardManager fileRewardManager; private final BetterElo mainClass; private final PluginLogger pluginLogger; public String periodType = null; + public String rewardType; + public String dropTable; + private final CustomMobsFileManager mobsFileManager; + private CustomMobs customMobs; + private JavaPlugin plugin; + private Random random = new Random(); + private static Utils utils; + private final DataManager dataManager; - public GuiManager(FileRewardManager fileRewardManager, PluginLogger pluginLogger, BetterElo mainClass, DataManager dataManager) { + public GuiManager(FileRewardManager fileRewardManager, PluginLogger pluginLogger, BetterElo mainClass, DataManager dataManager, CustomMobsFileManager mobsFileManager, CustomMobs customMobs, JavaPlugin plugin, Utils utils) { this.fileRewardManager = fileRewardManager; this.dataManager = dataManager; this.pluginLogger = pluginLogger; this.mainClass = mainClass; + this.mobsFileManager=mobsFileManager; + this.customMobs = customMobs; + this.plugin = plugin; + this.utils = utils; } public void openSubGui(Player player) { Inventory subInv = Bukkit.createInventory(null, 9, "Select Top"); @@ -33,13 +53,22 @@ public void openSubGui(Player player) { player.openInventory(subInv); } public void openMainGui(Player player) { - Inventory inv = Bukkit.createInventory(null, 9, "Set Rewards"); + Inventory inv = Bukkit.createInventory(null, 18, "Set Rewards"); createItem(inv, Material.APPLE, 1, "daily", "Daily Reward"); createItem(inv, Material.BREAD, 3, "weekly", "Weekly Reward"); createItem(inv, Material.DIAMOND, 5, "monthly", "Monthly Reward"); + createItem(inv, Material.EMERALD, 7, "event", "Event Reward"); + //createItem(inv, Material.EMERALD, 14, "dropTable", "Create new Drop Table"); player.openInventory(inv); } - private void createItem(Inventory inv, Material material, int slot, String name, String description) { + public void openDroptableGuiOld(Player player, String dropTableName) { + dropTable= dropTableName; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.openDroptableGui called. dropTableName:"+dropTableName+", dropTable: "+dropTable); + Inventory inv = Bukkit.createInventory(null, 9, "Set Rewards"); + createItem(inv, Material.EMERALD, 4, "dropTable", "Create new Drop Table"); + player.openInventory(inv); + } + public void createItem(Inventory inv, Material material, int slot, String name, String description) { ItemStack item = new ItemStack(material); ItemMeta meta = item.getItemMeta(); meta.setDisplayName(name); @@ -47,77 +76,77 @@ private void createItem(Inventory inv, Material material, int slot, String name, item.setItemMeta(meta); inv.setItem(slot, item); } - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - String title = event.getView().getTitle(); - if (!Arrays.asList("Set Rewards", "Add Items", "Select Top").contains(title)) { - return; - } - Player player = (Player) event.getWhoClicked(); - ItemStack currentItem = event.getCurrentItem(); - if (currentItem == null || currentItem.getType() == Material.AIR) { - return; - } - String rewardType = currentItem.getItemMeta().getDisplayName(); - pluginLogger.log("GuiManager: onInventoryClick: rewardType: "+rewardType+" periodType: "+periodType); - if (title.equals("Set Rewards")) { - event.setCancelled(true); - periodType = currentItem.getItemMeta().getDisplayName(); - openSubGui(player); - } else if (title.equals("Select Top")) { - event.setCancelled(true); - rewardType = currentItem.getItemMeta().getDisplayName(); - pluginLogger.log("GuiManager: onInventoryClick: rewardType: " + rewardType + " periodType: " + periodType); - fileRewardManager.setRewardType(periodType, rewardType); - List currentRewards = fileRewardManager.loadRewards(); - Inventory inv = Bukkit.createInventory(null, 36, "Add Items"); - currentRewards.forEach(inv::addItem); - createItem(inv, Material.GREEN_WOOL, 35, "Save", "Zapisz przedmioty"); - createItem(inv, Material.ORANGE_WOOL, 34, "Reset", "Resetuj czas"); - createItem(inv, Material.YELLOW_WOOL, 33, "Reedem", "Rozdaj nagrody"); - player.openInventory(inv); - } else if (title.equals("Add Items")) { - if (List.of("Save", "Reset", "Reedem").contains(rewardType)) { - event.setCancelled(true); - Inventory inv = event.getInventory(); - - switch (periodType) { - case "daily": - case "weekly": - case "monthly": - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager: onInventoryClick: Reset: " + periodType + " starting dataManager.updateLastScheduledTime"); - mainClass.updateLastScheduledTime(periodType); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager: onInventoryClick: Reset: " + periodType + " dataManager.updateLastScheduledTime done, clearing points map"); - - switch (periodType) { - case "daily": - dataManager.dailyPlayerPoints.clear(); - dataManager.saveDataToFileDaily(); - break; - case "weekly": - dataManager.weeklyPlayerPoints.clear(); - dataManager.saveDataToFileWeekly(); - break; - case "monthly": - dataManager.monthlyPayerPoints.clear(); - dataManager.saveDataToFileMonthly(); - break; - } - - player.sendMessage("Zresetowano nagrode : " + periodType); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager: onInventoryClick: Reset: done"); - break; - default: - pluginLogger.log(PluginLogger.LogLevel.WARNING, "GuiManager: onInventoryClick: Reset: Wrong reward type:" + periodType); - player.sendMessage("Nieznany typ nagrody: " + periodType); - return; - } - player.sendMessage(fileRewardManager.getRewardType() + " last scheduled time has been reset!"); - } else if ("Reedem".equals(rewardType)) { - mainClass.rewardTopPlayers(periodType); - pluginLogger.log("GuiManager: onInventoryClick: Reedem: periodType: " + periodType); - player.sendMessage("Nagrody zostały przyznane!"); - } // Jeśli nie jest to przycisk funkcji, pozwól graczowi przesuwać przedmioty + public void openDroptableGui(Player player, String dropTableName) { + dropTable = dropTableName; + periodType = "dropTable"; + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.openDroptableGui called. dropTableName:" + dropTableName + ", dropTable: " + dropTable); + + Inventory inv = Bukkit.createInventory(null, 54, "Add Items"); // Zwiększ rozmiar inwentarza, aby pomieścić więcej przedmiotów + /* + HashMap drops = mobsFileManager.loadCustomDrops(dropTableName); // Wczytaj przedmioty z tabeli dropów + + // Umieść przedmioty w oknie GUI + drops.values().forEach(inv::addItem); + + */ + + List drops = mobsFileManager.loadCustomDropsv2(dropTableName); // Wczytaj przedmioty z tabeli dropów + + // Umieść przedmioty w oknie GUI + drops.stream().map(CustomMobsFileManager.DropItem::getItemStack).forEach(inv::addItem); + + // Dodaj przycisk do zapisania tabeli dropów + createItem(inv, Material.GREEN_WOOL, 53, "Save", "Save drop table"); + + player.openInventory(inv); + } + + public void openCustomSmithingTable(Player player) { + Inventory smithingTable = Bukkit.createInventory(player, InventoryType.SMITHING, "Re-roll Average Damage bonus"); + + // Ustawienie początkowych przedmiotów w GUI (przykładowo, można ustawić puste sloty lub zablokowane sloty) + ItemStack item1 = new ItemStack(Material.AIR); // Pierwszy slot na materiał + ItemStack item2 = new ItemStack(Material.AIR); // Drugi slot na narzędzie + smithingTable.setItem(0, item1); // Pierwszy slot + smithingTable.setItem(1, item2); // Drugi slot + + // Otworzenie ekwipunku dla gracza + player.openInventory(smithingTable); + } + + public void openReRollGui(Player player){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.openReRollGui called, player: "+player.getName()); + Inventory inv = Bukkit.createInventory(null, 9, "AvgDmg bonus change"); + Material blank = Material.GRAY_STAINED_GLASS_PANE; + createItem(inv, blank, 0, "", ""); + createItem(inv, blank, 1, "", ""); + createItem(inv, blank, 2, "", ""); + createItem(inv, blank, 4, "", ""); + createItem(inv, Material.GREEN_WOOL, 5, "Re-Roll Average Damage bonus", "Cost: 1x "+ChatColor.DARK_PURPLE+""+ChatColor.BOLD+"Enchant Item"); + createItem(inv, blank, 6, "", ""); + createItem(inv, blank, 7, "", ""); + createItem(inv, blank, 8, "", ""); + //createItem(inv, blank, 0, "", ""); + //createItem(inv, Material.EMERALD, 14, "dropTable", "Create new Drop Table"); + player.openInventory(inv); + } + public boolean checkAndRemoveBetterCoins(Player player) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveBetterCoins called, player : "+player); + Inventory inventory = player.getInventory(); + ItemStack betterCoinStack = Utils.getBetterCoinStack(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveBetterCoins betterCoinStack: "+betterCoinStack); + // Sprawdź, czy gracz ma co najmniej 64 BetterCoin w ekwipunku + if (inventory.containsAtLeast(betterCoinStack, 64)) { + // Usuń 64 sztuki BetterCoin z ekwipunku gracza + inventory.removeItem(betterCoinStack); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveBetterCoins 64 BetterCoin found, removing : "+betterCoinStack); + return true; } + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveBetterCoins 64 BetterCoin not found"); + return false; } + + + + } diff --git a/src/main/java/betterbox/mine/game/betterelo/Placeholders.java b/src/main/java/betterbox/mine/game/betterelo/Placeholders.java index c4b29ce..edad079 100644 --- a/src/main/java/betterbox/mine/game/betterelo/Placeholders.java +++ b/src/main/java/betterbox/mine/game/betterelo/Placeholders.java @@ -70,6 +70,7 @@ private String processRankingPlaceholder(String identifier, String prefix, Map enabledLogLevels; // Zbiór aktywnych poziomów logowania - + public ElasticBuffer elasticBuffer; + private final BetterElo betterElo; + public boolean isElasticBufferEnabled=false; + public ElasticBufferAPI api; // Enumeracja dla poziomów logowania public enum LogLevel { - INFO, WARNING, ERROR, DEBUG, DEBUG_LVL2, DEBUG_LVL3,DEBUG_LVL4 + INFO, WARNING, ERROR,CUSTOM_MOBS, DEBUG, DEBUG_LVL2, DEBUG_LVL3,DEBUG_LVL4,CHEATERS, RANKING_REWARDS ,FLAMETHROWER,DROP,SPAWNERS, ZEPHYR, KILL_EVENT, COMMAND, PLACEHOLDER, BLOCK_BREAK, BLOCK_PLACE, PLAYER_INTERACT, ELYTRA_CHECK, ANTYWEB, REROLL } - public PluginLogger(String folderPath, Set enabledLogLevels, JavaPlugin plugin) { + public PluginLogger(String folderPath, Set enabledLogLevels, JavaPlugin plugin,BetterElo betterElo) { this.enabledLogLevels = enabledLogLevels; this.plugin = plugin; + this.betterElo=betterElo; // Tworzenie folderu dla logów, jeśli nie istnieje File logFolder = new File(folderPath,"logs"); if (!logFolder.exists()) { @@ -57,7 +63,51 @@ public void log(String message) { public void log(LogLevel level, String message) { if (enabledLogLevels.contains(level)) { // Dodanie timestampu i poziomu logowania do wiadomości - String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()); + String logMessage = timestamp + " [" + level + "] - " + message; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(logFile, true))) { + writer.write(logMessage); + writer.newLine(); + } catch (IOException e) { + plugin.getLogger().severe("PluginLogger: log: Could not write to log file!"+e.getMessage()); + } + if(isElasticBufferEnabled){ + try{ + api.log(message,level.toString(),plugin.getDescription().getName(),null); + //elasticBuffer.receiveLog(message,level.toString(),plugin.getDescription().getName(),null); + }catch (Exception e) { + plugin.getLogger().severe("PluginLogger: log: Could not write to log file!" + e.getMessage()); + } + } + + } + } + public void log(LogLevel level, String message,String transactionID) { + if (enabledLogLevels.contains(level)) { + // Dodanie timestampu i poziomu logowania do wiadomości + String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()); + String logMessage = timestamp + " [" + level + "] - " + message; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(logFile, true))) { + writer.write(logMessage); + writer.newLine(); + } catch (IOException e) { + plugin.getLogger().severe("PluginLogger: log: Could not write to log file!"+e.getMessage()); + } + if(isElasticBufferEnabled){ + try{ + elasticBuffer.receiveLog(message,level.toString(),plugin.getDescription().getName(),transactionID); + }catch (Exception e) { + plugin.getLogger().severe("PluginLogger: log: Could not write to log file!" + e.getMessage()); + } + } + } + } + public void log(LogLevel level, String message,String transactionID,String playerName,String uuid) { + if (enabledLogLevels.contains(level)) { + // Dodanie timestampu i poziomu logowania do wiadomości + String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()); String logMessage = timestamp + " [" + level + "] - " + message; try (BufferedWriter writer = new BufferedWriter(new FileWriter(logFile, true))) { @@ -66,6 +116,13 @@ public void log(LogLevel level, String message) { } catch (IOException e) { plugin.getLogger().severe("PluginLogger: log: Could not write to log file!"+e.getMessage()); } + if(isElasticBufferEnabled){ + try{ + elasticBuffer.receiveLog(message,level.toString(),plugin.getDescription().getName(),transactionID,playerName,uuid); + }catch (Exception e) { + plugin.getLogger().severe("PluginLogger: log: Could not write to log file!" + e.getMessage()); + } + } } } @@ -75,6 +132,11 @@ public void setEnabledLogLevels(Set configEnabledLogLevels) { log("Enabled Log levels "+ Arrays.toString(enabledLogLevels.toArray())); } + public void setEnabledEventItems(Set configEnabledEventItems) { + this.enabledLogLevels = configEnabledEventItems; + log("Enabled Log levels "+ Arrays.toString(enabledLogLevels.toArray())); + + } } diff --git a/src/main/java/betterbox/mine/game/betterelo/Utils.java b/src/main/java/betterbox/mine/game/betterelo/Utils.java new file mode 100644 index 0000000..fe21051 --- /dev/null +++ b/src/main/java/betterbox/mine/game/betterelo/Utils.java @@ -0,0 +1,242 @@ +package betterbox.mine.game.betterelo; + +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.WorldGuard; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.RegionContainer; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class Utils { + static PluginLogger pluginLogger; + static BetterElo betterElo; + private static final Random random = new Random(); + public Utils(BetterElo plugin,PluginLogger pluginLogger) { + this.pluginLogger = pluginLogger; + this.betterElo = plugin; + pluginLogger.log(PluginLogger.LogLevel.INFO, "Utils constructor called"); + + } + public void updateAverageDamage(ItemStack item,int avgDmg) { + if (item != null && item.hasItemMeta()) { + pluginLogger.log(PluginLogger.LogLevel.REROLL, "updateAverageDamage called, betterElo.hasMobDamageAttribute(item): " + betterElo.hasMobDamageAttribute(item) + ", betterElo.hasAverageDamageAttribute(item): " + betterElo.hasAverageDamageAttribute(item)); + + if (betterElo.hasMobDamageAttribute(item) && betterElo.hasAverageDamageAttribute(item)) { + ItemMeta itemMeta = item.getItemMeta(); + List lore = new ArrayList<>(itemMeta.getLore()); + + + pluginLogger.log(PluginLogger.LogLevel.REROLL, "updateAverageDamage, re-rolling average damage..."); + + for (int i = 0; i < lore.size(); i++) { + pluginLogger.log(PluginLogger.LogLevel.REROLL, "updateAverageDamage lore i=" + i); + if (lore.get(i).contains("Average Damage")) { + pluginLogger.log(PluginLogger.LogLevel.REROLL, "updateAverageDamage lore i=" + i + " contains Average Damage, setting avgDmg: " + avgDmg); + lore.set(i, "§6§lAverage Damage +" + avgDmg + "%"); + } + } + + itemMeta.setLore(lore); + item.setItemMeta(itemMeta); + betterElo.addAverageDamageAttribute(item, avgDmg); + } + } + } + public static int dropAverageDamage() { + double rand = random.nextDouble(); + double x = Math.pow(-Math.log(rand), 0.44) * 18; // Adjusted exponential transformation and scale + int bonus = (int) x; + bonus = Math.min(bonus, 60); + if(bonus==0){ + bonus=1; + } + return bonus; + } + public static List getPlayerEquippedItems(Player player) { + EntityEquipment equipment = player.getEquipment(); + List equippedItems = new ArrayList<>(); + + if (equipment != null) { + // Dodawanie przedmiotu trzymanego w głównej ręce + if (equipment.getItemInMainHand() != null) { + equippedItems.add(equipment.getItemInMainHand()); + } + // Dodawanie przedmiotu trzymanego w pomocniczej ręce + if (equipment.getItemInOffHand() != null) { + equippedItems.add(equipment.getItemInOffHand()); + } + // Dodawanie elementów zbroi + for (ItemStack item : equipment.getArmorContents()) { + if (item != null) { + equippedItems.add(item); + } + } + + } + return equippedItems; + } + public static double getTotalAvgDmgBonus(List equippedItems) { + double totalAverageDamageBonus = 0; + if (equippedItems == null) { + return totalAverageDamageBonus; + } + for (ItemStack item : equippedItems) { + if (item != null && item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer dataContainer = meta.getPersistentDataContainer(); + if (dataContainer.has(betterElo.averageDamageKey, PersistentDataType.INTEGER)) { + int damageBonus = dataContainer.get(betterElo.averageDamageKey, PersistentDataType.INTEGER); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.TotalAvgDmgBonus read damageBonus: " + damageBonus); + totalAverageDamageBonus += damageBonus; + } + } + } + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Event.TotalAvgDmgBonus total calculated averageDamageBonus: " + totalAverageDamageBonus); + return totalAverageDamageBonus; + } + static ItemStack getBetterCoinStack() { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.getBetterCoinStack called"); + Material material = Material.HONEYCOMB; + int amount = 64; + + ItemStack stack = new ItemStack(material, amount); + ItemMeta meta = stack.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.GOLD+"BetterCoin"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.getBetterCoinStack meta.getDisplayName(): "+meta.getDisplayName()); + //Component displayNameComponent = new Component("BetterCoin"); + List lore = List.of(ChatColor.YELLOW+ "Valuable currency you can use to buy items."); + meta.setLore(lore); + stack.setItemMeta(meta); + } + return stack; + } + public static boolean checkAndRemoveEnchantItem(Player player) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveEnchantItem called, player : "+player); + Inventory inventory = player.getInventory(); + ItemStack enchantItemStack = getEnchantItem(); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveEnchantItem betterCoinStack: "+enchantItemStack); + // Sprawdź, czy gracz ma co najmniej 64 BetterCoin w ekwipunku + if (inventory.containsAtLeast(enchantItemStack, 1)) { + // Usuń 64 sztuki BetterCoin z ekwipunku gracza + inventory.removeItem(enchantItemStack); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveEnchantItem 1 Enchant Item found, removing : "+enchantItemStack); + return true; + } + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.checkAndRemoveEnchantItem 1 Enchant Item not found"); + return false; + } + public static ItemStack getEnchantItem(){ + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.getEnchantItem called"); + Material material = Material.GHAST_TEAR; + int amount = 1; + + ItemStack stack = new ItemStack(material, amount); + ItemMeta meta = stack.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.DARK_PURPLE+""+ ChatColor.BOLD+"Enchant Item"); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.getEnchantItem meta.getDisplayName(): "+meta.getDisplayName()); + //Component displayNameComponent = new Component("BetterCoin"); + List lore = List.of(ChatColor.GRAY+ "Removes current the Average Damage bonus",ChatColor.GRAY+ " from the item and adds new one."); + meta.setLore(lore); + // Dodajemy niestandardowy enchant, który nie wpływa na działanie itemu + meta.addEnchant(Enchantment.LUCK, 1, true); + + // Ukrywamy wszystkie informacje o zaklęciach na itemie + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + + stack.setItemMeta(meta); + } + return stack; + } + public static boolean isEnchantItem(ItemStack itemStack) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.isEnchantItem called, itemStack: " + itemStack); + + if (itemStack == null) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.isEnchantItem itemStack is null"); + return false; + } + + ItemStack enchantItemStack = Utils.getEnchantItem(); // Zakładam, że metoda getEnchantItem zwraca referencyjny ItemStack + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.isEnchantItem enchantItemStack: " + enchantItemStack); + + // Sprawdź, czy przekazany itemStack ma ten sam typ i enchanty co enchantItemStack + if (itemStack.getType() == enchantItemStack.getType() && itemStack.getEnchantments().equals(enchantItemStack.getEnchantments())) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.isEnchantItem item matches the criteria"); + return true; + } + + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "GuiManager.isEnchantItem item does not match the criteria"); + return false; + } + public static String formatDroppedItems(List drops) { + StringBuilder sb = new StringBuilder(); + for (ItemStack itemStack : drops) { + String itemName; + // Sprawdź, czy przedmiot ma niestandardową nazwę + if (itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName()) { + itemName = itemStack.getItemMeta().getDisplayName(); + } else { + // Użyj domyślnej nazwy materiału + itemName = itemStack.getType().toString(); + } + int quantity = itemStack.getAmount(); + sb.append(itemName).append(":").append(quantity).append(", "); + } + // Usuń ostatni przecinek i spację, jeśli istnieją + if (sb.length() > 0) { + sb.setLength(sb.length() - 2); + } + return sb.toString(); + } + public static boolean isEloAllowed(Player player, Location location) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.isEloAllowed called"); + try { + com.sk89q.worldedit.world.World weWorld = BukkitAdapter.adapt(location.getWorld()); + + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionManager regions = container.get(weWorld); + + if (regions == null) { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.isEloAllowed No regions in world."); + return true; // Jeśli nie ma regionów, domyślnie zezwalaj na Elo + } else { + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.isEloAllowed Found regions: " + regions); + } + + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + + ApplicableRegionSet regionSet = regions.getApplicableRegions(BukkitAdapter.asBlockVector(location)); + + // Zmieniamy sprawdzanie z flagi PVP na Twoją niestandardową flagę noElo + StateFlag.State EloState = regionSet.queryState(localPlayer, BetterElo.IS_ELO_ALLOWED); + boolean isEloAllowed = EloState != StateFlag.State.DENY; // Jeśli flaga noElo jest ustawiona na DENY, Elo nie jest dozwolone + + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event.isEloAllowed Elo Allowed at location: " + location + " is " + isEloAllowed); + + return isEloAllowed; + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Event.isEloAllowed: " + e.toString()); + return false; + } + } + +} diff --git a/src/main/java/betterbox/mine/game/betterelo/WebRankingServer.java b/src/main/java/betterbox/mine/game/betterelo/WebRankingServer.java deleted file mode 100644 index c3577ad..0000000 --- a/src/main/java/betterbox/mine/game/betterelo/WebRankingServer.java +++ /dev/null @@ -1,139 +0,0 @@ -package betterbox.mine.game.betterelo; - -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpExchange; - -import java.io.*; -import java.net.InetSocketAddress; -import java.util.*; - -public class WebRankingServer { - - private final String databasePath; - private final int port; - private final PluginLogger pluginLogger; - - public WebRankingServer(String databasePath, int port, PluginLogger pluginLogger) { - this.databasePath = databasePath; - this.port = port; - this.pluginLogger = pluginLogger; - } - - public void startServer() { - try { - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "WebRankingServer: startServer: starting server on port " + port + "."); - HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); - server.createContext("/ranking", new RankingHandler(databasePath)); - server.start(); - pluginLogger.log(PluginLogger.LogLevel.DEBUG, "WebRankingServer: startServer: server started successfully."); - } catch (IOException e) { - pluginLogger.log(PluginLogger.LogLevel.ERROR, "WebRankingServer: startServer: failed to start server: " + e.getMessage()); - - } - } - - static class RankingHandler implements HttpHandler { - - private final String databasePath; - - public RankingHandler(String databasePath) { - this.databasePath = databasePath; - } - - @Override - public void handle(HttpExchange exchange) throws IOException { - try { - String response = generateHtmlResponse(); - exchange.sendResponseHeaders(200, response.getBytes().length); - try (OutputStream os = exchange.getResponseBody()) { - os.write(response.getBytes()); - } - } catch (Exception e) { - String errorMsg = "RankingHandler: handle: error handling HTTP exchange: " + e.getMessage(); - //pluginLogger.log(PluginLogger.LogLevel.DEBUG,"WebRankingServer: startServer: server started successfully."); - System.err.println(errorMsg); // Log to server console, replace with a logger if available. - e.printStackTrace(); - exchange.sendResponseHeaders(500, errorMsg.getBytes().length); - try (OutputStream os = exchange.getResponseBody()) { - os.write(errorMsg.getBytes()); - } - } - } - - - private String generateHtmlResponse() throws IOException { - StringBuilder html = new StringBuilder(); - html.append("BetterBox Main Ranking"); - html.append("

Main Player Ranking

"); - html.append("
    "); - - List players = new ArrayList<>(); - - try (BufferedReader reader = new BufferedReader(new FileReader(databasePath))) { - String line; - while ((line = reader.readLine()) != null) { - String[] parts = line.split(":"); - if (parts.length == 2) { - try { - double score = Double.parseDouble(parts[1].trim()); - players.add(new PlayerData(parts[0], score)); - } catch (NumberFormatException e) { - e.printStackTrace(); - } - } - } - } - - players.sort(Comparator.comparingDouble(PlayerData::getScore).reversed()); - - double totalScore = 0.0; - - for (PlayerData player : players) { - String cssClass; - if (player.getScore() < 0) { - cssClass = "low"; - } else if (player.getScore() <= 2500) { - cssClass = "medium"; - } else { - cssClass = "high"; - } - - html.append(String.format(Locale.US, "
  • %s: %.2f
  • ", cssClass, player.getName(), player.getScore())); - totalScore += player.getScore(); - } - - // Calculate and display the additional statistics - double averageScore = players.isEmpty() ? 0 : totalScore / players.size(); - html.append(String.format(Locale.US, "

Total Players: %d

", players.size())); - html.append(String.format(Locale.US, "

Total Score: %.2f

", totalScore)); - html.append(String.format(Locale.US, "

Average Score: %.2f

", averageScore)); - html.append(""); - - return html.toString(); - } - - - static class PlayerData { - private final String name; - private final double score; // Zmieniamy typ danych na double - - public PlayerData(String name, double score) { - this.name = name; - this.score = score; - } - - public String getName() { - return name; - } - - public double getScore() { // Zmieniamy typ zwracanej wartości na double - return score; - } - } - } -} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..dd66947 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,44 @@ +# DO NOT CHANGE THIS PART!!! +# ######################################### +dailyLastScheduledTime: 1720757055869 +weeklyLastScheduledTime: 1720745355824 +monthlyLastScheduledTime: 1718815517777 +# ######################################### +log_level: +- INFO +- WARNING +- ERROR +# - SPAWNERS +# - KILL_EVENT +# - CUSTOM_MOBS +# - DEBUG +# - RANKING_REWARDS + +blocks_rewards: + DIAMOND_ORE: 1.3 + DIAMOND_BLOCK: 1.3 + EMERALD_ORE: 1.2 + EMERALD_BLOCK: 1.2 + GOLD_ORE: 1.1 + GOLD_BLOCK: 1.1 + IRON_ORE: 1 + IRON_BLOCK: 1 + BEACON: 100 + YELLOW_GLAZED_TERRACOTTA: 10 + NETHERITE_BLOCK: 1.6 + CRYING_OBSIDIAN: 1.5 + OBSIDIAN: 1.4 + YELLOW_WOOL: 20 + COBBLESTONE: 0.1 + PURPLE_WOOL: 0.5 +block_base: 0.1 +antyweb_elo_cost: 0.1 +Infinite_firework_cooldown: 450 +Flamethrower_cooldown: 1500 +Zephyr_cooldown: 1500 +event_items_with_username: +- DIAMOND_PICKAXE +- DIAMOND_AXE +- GOLDEN_AXE +- IRON_AXE +- STONE_AXE diff --git a/src/main/resources/customDropTables/ExampleDropTable.yml b/src/main/resources/customDropTables/ExampleDropTable.yml new file mode 100644 index 0000000..e6989cc --- /dev/null +++ b/src/main/resources/customDropTables/ExampleDropTable.yml @@ -0,0 +1,130 @@ +Item0: + itemPath: customDrops/ExampleDropTable_item0.yml + dropChance: 50.0 + # itemName and description is purely for user information, not needed for the plugin itself + itemName: TranslatableComponentImpl{key="chat.square_brackets", args=[TextComponentImpl{content="", + style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, + italic=true, color=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}, + children=[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, bold=not_set, + strikethrough=not_set, underlined=not_set, italic=not_set, color=null, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="BetterCoin", + style=StyleImpl{obfuscated=false, bold=false, strikethrough=false, underlined=false, + italic=false, color=NamedTextColor{name="gold", value="#ffaa00"}, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[]}]}]}], style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="white", + value="#ffffff"}, clickEvent=null, hoverEvent=HoverEvent{action=show_item, value=ShowItem{item=KeyImpl{namespace="minecraft", + value="honeycomb"}, count=1, nbt={display:{Lore:['{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"yellow","text":"Valuable + currency you can use to buy items."}],"text":""}'],Name:'{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"BetterCoin"}],"text":""}'}}}}, + insertion=null, font=null}, children=[]} + avgDmgBonus: false + description: '[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=null, + clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="Valuable + currency you can use to buy items.", style=StyleImpl{obfuscated=false, bold=false, + strikethrough=false, underlined=false, italic=false, color=NamedTextColor{name="yellow", + value="#ffff55"}, clickEvent=null, hoverEvent=null, insertion=null, font=null}, + children=[]}]}]' +Item1: + itemPath: customDrops/ExampleDropTable_item1.yml + dropChance: 100.0 + # itemName and description is purely for user information, not needed for the plugin itself + itemName: TranslatableComponentImpl{key="chat.square_brackets", args=[TextComponentImpl{content="", + style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, + italic=true, color=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}, + children=[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, bold=not_set, + strikethrough=not_set, underlined=not_set, italic=not_set, color=null, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="Coin", + style=StyleImpl{obfuscated=false, bold=false, strikethrough=false, underlined=false, + italic=false, color=NamedTextColor{name="gold", value="#ffaa00"}, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[]}]}]}], style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="white", + value="#ffffff"}, clickEvent=null, hoverEvent=HoverEvent{action=show_item, value=ShowItem{item=KeyImpl{namespace="minecraft", + value="sunflower"}, count=1, nbt={display:{Lore:['{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"yellow","text":"Currency + you can use to buy items."}],"text":""}'],Name:'{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Coin"}],"text":""}'}}}}, + insertion=null, font=null}, children=[]} + avgDmgBonus: false + description: '[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=null, + clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="Currency + you can use to buy items.", style=StyleImpl{obfuscated=false, bold=false, strikethrough=false, + underlined=false, italic=false, color=NamedTextColor{name="yellow", value="#ffff55"}, + clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[]}]}]' +Item2: + itemPath: customDrops/ExampleDropTable_item2.yml + dropChance: 100.0 + # itemName and description is purely for user information, not needed for the plugin itself + itemName: TranslatableComponentImpl{key="chat.square_brackets", args=[TextComponentImpl{content="", + style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, + italic=true, color=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}, + children=[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, bold=not_set, + strikethrough=not_set, underlined=not_set, italic=not_set, color=null, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="Shears + LvL12", style=StyleImpl{obfuscated=false, bold=true, strikethrough=false, underlined=false, + italic=false, color=NamedTextColor{name="gold", value="#ffaa00"}, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[]}]}]}], style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="aqua", + value="#55ffff"}, clickEvent=null, hoverEvent=HoverEvent{action=show_item, value=ShowItem{item=KeyImpl{namespace="minecraft", + value="shears"}, count=1, nbt={Damage:0,Enchantments:[{id:"minecraft:efficiency",lvl:11s}],HideFlags:1,Unbreakable:1b,display:{Lore:['{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Antyweb + 2"}],"text":""}'],Name:'{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Shears + LvL12"}],"text":""}'}}}}, insertion=null, font=null}, children=[]} + avgDmgBonus: false + description: '[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=null, + clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="Antyweb + 2", style=StyleImpl{obfuscated=false, bold=true, strikethrough=false, underlined=false, + italic=false, color=NamedTextColor{name="gold", value="#ffaa00"}, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[]}]}]' +Item3: + itemPath: customDrops/ExampleDropTable_item3.yml + avgDmgBonus: true + dropChance: 100.0 + # itemName and description is purely for user information, not needed for the plugin itself + itemName: TranslatableComponentImpl{key="chat.square_brackets", args=[TextComponentImpl{content="", + style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, + italic=true, color=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}, + children=[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, bold=not_set, + strikethrough=not_set, underlined=not_set, italic=not_set, color=null, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="Example + Item", style=StyleImpl{obfuscated=false, bold=true, strikethrough=false, underlined=false, + italic=false, color=NamedTextColor{name="dark_purple", value="#aa00aa"}, clickEvent=null, + hoverEvent=null, insertion=null, font=null}, children=[]}]}]}], style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="white", + value="#ffffff"}, clickEvent=null, hoverEvent=HoverEvent{action=show_item, value=ShowItem{item=KeyImpl{namespace="minecraft", + value="netherite_sword"}, count=1, nbt={Damage:0,display:{Lore:['{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Mob + Damage 20-100"}],"text":""}'],Name:'{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"dark_purple","text":"Example + Item"}],"text":""}'}}}}, insertion=null, font=null}, children=[]} + description: '[TextComponentImpl{content="", style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=null, + clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[TextComponentImpl{content="Mob + Damage 20-100", style=StyleImpl{obfuscated=false, bold=true, strikethrough=false, + underlined=false, italic=false, color=NamedTextColor{name="gold", value="#ffaa00"}, + clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[]}]}]' +Item4: + itemPath: customDrops/ExampleDropTable_item4.yml + dropChance: 100.0 + itemName: TranslatableComponentImpl{key="chat.square_brackets", args=[TextComponentImpl{content="", + style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, + italic=not_set, color=null, clickEvent=null, hoverEvent=null, insertion=null, + font=null}, children=[TranslatableComponentImpl{key="block.minecraft.beacon", + args=[], style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, + underlined=not_set, italic=not_set, color=null, clickEvent=null, hoverEvent=null, + insertion=null, font=null}, children=[]}]}], style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="aqua", + value="#55ffff"}, clickEvent=null, hoverEvent=HoverEvent{action=show_item, value=ShowItem{item=KeyImpl{namespace="minecraft", + value="beacon"}, count=6, nbt=null}}, insertion=null, font=null}, children=[]} + avgDmgBonus: false +Item5: + itemPath: customDrops/ExampleDropTable_item5.yml + dropChance: 100.0 + itemName: TranslatableComponentImpl{key="chat.square_brackets", args=[TextComponentImpl{content="", + style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, + italic=not_set, color=null, clickEvent=null, hoverEvent=null, insertion=null, + font=null}, children=[TranslatableComponentImpl{key="item.minecraft.enchanted_golden_apple", + args=[], style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, + underlined=not_set, italic=not_set, color=null, clickEvent=null, hoverEvent=null, + insertion=null, font=null}, children=[]}]}], style=StyleImpl{obfuscated=not_set, + bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=NamedTextColor{name="light_purple", + value="#ff55ff"}, clickEvent=null, hoverEvent=HoverEvent{action=show_item, value=ShowItem{item=KeyImpl{namespace="minecraft", + value="enchanted_golden_apple"}, count=11, nbt=null}}, insertion=null, font=null}, + children=[]} + avgDmgBonus: false diff --git a/src/main/resources/customDrops/ExampleDropTable_item0.yml b/src/main/resources/customDrops/ExampleDropTable_item0.yml new file mode 100644 index 0000000..b95779c --- /dev/null +++ b/src/main/resources/customDrops/ExampleDropTable_item0.yml @@ -0,0 +1,11 @@ +item: + ==: org.bukkit.inventory.ItemStack + v: 2975 + type: HONEYCOMB + meta: + ==: ItemMeta + meta-type: UNSPECIFIC + display-name: '{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"BetterCoin"}],"text":""}' + lore: + - '{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"yellow","text":"Valuable + currency you can use to buy items."}],"text":""}' diff --git a/src/main/resources/customDrops/ExampleDropTable_item1.yml b/src/main/resources/customDrops/ExampleDropTable_item1.yml new file mode 100644 index 0000000..4328d92 --- /dev/null +++ b/src/main/resources/customDrops/ExampleDropTable_item1.yml @@ -0,0 +1,11 @@ +item: + ==: org.bukkit.inventory.ItemStack + v: 2975 + type: SUNFLOWER + meta: + ==: ItemMeta + meta-type: UNSPECIFIC + display-name: '{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Coin"}],"text":""}' + lore: + - '{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"yellow","text":"Currency + you can use to buy items."}],"text":""}' diff --git a/src/main/resources/customDrops/ExampleDropTable_item2.yml b/src/main/resources/customDrops/ExampleDropTable_item2.yml new file mode 100644 index 0000000..fbda68f --- /dev/null +++ b/src/main/resources/customDrops/ExampleDropTable_item2.yml @@ -0,0 +1,17 @@ +item: + ==: org.bukkit.inventory.ItemStack + v: 2975 + type: SHEARS + meta: + ==: ItemMeta + meta-type: UNSPECIFIC + display-name: '{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Shears + LvL12"}],"text":""}' + lore: + - '{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Antyweb + 2"}],"text":""}' + enchants: + DIG_SPEED: 11 + ItemFlags: + - HIDE_ENCHANTS + Unbreakable: true diff --git a/src/main/resources/customDrops/ExampleDropTable_item3.yml b/src/main/resources/customDrops/ExampleDropTable_item3.yml new file mode 100644 index 0000000..95058bd --- /dev/null +++ b/src/main/resources/customDrops/ExampleDropTable_item3.yml @@ -0,0 +1,14 @@ +item: + ==: org.bukkit.inventory.ItemStack + v: 2975 + type: NETHERITE_SWORD + meta: + ==: ItemMeta + meta-type: UNSPECIFIC + display-name: '{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"dark_purple","text":"Example + Item"}],"text":""}' + lore: + - '{"extra":[{"bold":true,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gold","text":"Mob + Damage 20-100"}],"text":""}' + PublicBukkitValues: + betterelo:mob_damage: 20-100 diff --git a/src/main/resources/customDrops/ExampleDropTable_item4.yml b/src/main/resources/customDrops/ExampleDropTable_item4.yml new file mode 100644 index 0000000..0010bfb --- /dev/null +++ b/src/main/resources/customDrops/ExampleDropTable_item4.yml @@ -0,0 +1,5 @@ +item: + ==: org.bukkit.inventory.ItemStack + v: 2975 + type: BEACON + amount: 6 diff --git a/src/main/resources/customDrops/ExampleDropTable_item5.yml b/src/main/resources/customDrops/ExampleDropTable_item5.yml new file mode 100644 index 0000000..87eac1d --- /dev/null +++ b/src/main/resources/customDrops/ExampleDropTable_item5.yml @@ -0,0 +1,5 @@ +item: + ==: org.bukkit.inventory.ItemStack + v: 2975 + type: ENCHANTED_GOLDEN_APPLE + amount: 11 diff --git a/src/main/resources/customMobs/Marksman.yml b/src/main/resources/customMobs/Marksman.yml new file mode 100644 index 0000000..5e9d59f --- /dev/null +++ b/src/main/resources/customMobs/Marksman.yml @@ -0,0 +1,44 @@ +type: SKELETON # ENTITY TYPE +mobName: Marksman # Mob Name used in the plugin +armor: 5.0 # x points of dmg reduction +hp: 300 +speed: 0.4 # movement speed +attackDamage: 10 +dropTable: ExampleDropTable # tbh I don't remember which one is used in the plugin - unnecessary fields will be removed in the future releases +defense: 30 # x% damage reduction +regenSeconds: 10 +regenPercent: 20 +knockbackResistance: 5.0 +eloPoints: 1500 +eloMultiplier: 0.6 +customMetadata: + CustomMob: true # leave this always as true!! + MobName: EXAMPLE BOSS - Panda # displayname COLORS/FORMATTING NOT SUPPORTED YET + DropTable: ExampleDropTable # tbh I don't remember which one is used in the plugin - unnecessary fields will be removed in the future releases +equipment: + helmet: + type: LEATHER_HELMET + unbreakable: true + attributes: + armor: 0 + chestplate: + type: LEATHER_CHESTPLATE + unbreakable: true + attributes: + armor: 0 + leggings: + type: LEATHER_LEGGINGS + unbreakable: true + attributes: + armor: 0 + boots: + type: LEATHER_BOOTS + unbreakable: true + attributes: + armor: 0 + weapon: + type: BOW + enchants: + power: 5 + attributes: + damage: 10 \ No newline at end of file diff --git a/src/main/resources/customMobs/Panda.yml b/src/main/resources/customMobs/Panda.yml new file mode 100644 index 0000000..3fd4201 --- /dev/null +++ b/src/main/resources/customMobs/Panda.yml @@ -0,0 +1,18 @@ +type: PANDA # ENTITY TYPE +mobName: Panda # Mob Name used in the plugin +armor: 0.0 # x points of dmg reduction +hp: 500 +speed: 0.4 # movement speed +attackDamage: 10 +dropTable: ExampleDropTable # tbh I don't remember which one is used in the plugin - unnecessary fields will be removed in the future releases +defense: 95 # x% damage reduction +passengerMobName: Marksman +knockbackResistance: 5.0 +regenSeconds: 30 +regenPercent: 30 +eloPoints: 3500 +eloMultiplier: 3.0 +customMetadata: + CustomMob: true # leave this always as true!! + MobName: EXAMPLE BOSS - Panda # displayname COLORS/FORMATTING NOT SUPPORTED YET + DropTable: ExampleDropTable # tbh I don't remember which one is used in the plugin - unnecessary fields will be removed in the future releases diff --git a/src/main/resources/customMobs/spawners.yml b/src/main/resources/customMobs/spawners.yml new file mode 100644 index 0000000..e511969 --- /dev/null +++ b/src/main/resources/customMobs/spawners.yml @@ -0,0 +1,8 @@ +spawners: + # t1_1: + # location: world,x,y,z + # mobName: NameOfTheMob + # cooldown: 60 + # mobsPerSpawn: 1 + # maxMobs: 3 + # maxDistance: 20 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index fc23d4c..f2ebe27 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,53 +4,73 @@ main: betterbox.mine.game.betterelo.BetterElo api-version: 1.18 description: PvP Elo with configurable rewards. https://github.com/Grzybol/BetterElo author: Grzybol -depend: [PlaceholderAPI] +depend: + - PlaceholderAPI + - WorldGuard +softdepend: + - HolographicDisplays + - ElasticBuffer commands: be: description: Komenda do ogólnego zarządzania rankingiem graczy. usage: /be aliases: - betterelo - be-info: + be info: description: Informacje o pluginie. usage: /be info - be-help: + be help: description: Command list usage: /be help - be-player: + be player: description: Informacje o miejscu w rankingu i punktach gracza. usage: /be - be-top: + be top: description: Nick gracza i jego punkty z pozycji n w rankingu. usage: /be top - be-top10: + be top10: description: Wyświetla top 10 graczy i ich punkty. usage: /be top10 - be-setrewards: + be setrewards: description: Otwiera interfejs GUI do ustawiania nagród. usage: /be setrewards permission: betterelo.setrewards - be-daily: + be daily: description: Włącza lub wyłącza codzienne nagrody. usage: /be daily - be-weekly: + be weekly: description: Włącza lub wyłącza tygodniowe nagrody. usage: /be weekly - be-monthly: + be monthly: description: Włącza lub wyłącza miesięczne nagrody. usage: /be monthly - be-timeleft: + be timeleft: description: pokazuje reszte czasu do rozdania nagród. usage: /be timeleft - be-claim: + be claim: description: Komenda do odbierania nagród offline. usage: /be claim - be-add: + be add: description: Komenda do dodawania punktów graczowi. usage: /be add - be-sub: + be sub: description: Komenda do odbierania punktów graczowi. usage: /be sub + be event: + description: creating event + usage: /be event + be stopevent: + description: removing event + usage: /be stopevent + be holo: + description: Holo management + usage: /be holo + be antyweb: + description: Add antyweb to item + usage: /be antyweb x + be setattribute: + description: Add attribute to the item in hand. + usage: /be setattribute mobdefense/mobdamage/averagedamage X permissions: betterelo.setrewards: description: Daje dostęp do komendy /be setrewards. @@ -70,4 +90,18 @@ permissions: betterelo.ban: description: Deletes player. default: op + betterelo.antyweb: + description: Antyweb + default: op + betterelo.zephyr: + description: Zephyr + default: op + betterelo.flamethrower: + description: flamethrower + default: op + betterelo.reroll: + description: Grants access to /be reroll + default: op + +