diff --git a/.github/workflows/check_gradle_all.yaml b/.github/workflows/check_gradle_all.yaml index c8f15b0497..e51c7cd11b 100644 --- a/.github/workflows/check_gradle_all.yaml +++ b/.github/workflows/check_gradle_all.yaml @@ -5,6 +5,10 @@ on: pull_request: types: [ opened, synchronize, reopened ] +permissions: + contents: read + checks: write + jobs: check_gradle: name: 🐘 Check Gradle @@ -23,5 +27,29 @@ jobs: - name: 🐘 Setup Gradle uses: gradle/actions/setup-gradle@v3 + - name: 💾 Cache paperweight + uses: actions/cache@v4 + with: + path: '**/.gradle/caches/paperweight' + key: paperweight-${{ hashFiles('gradle/libs.versions.toml') }} + restore-keys: | + paperweight- + - name: 🐘 Gradle Check run: CI=true ./gradlew check --scan + + - name: 📊 Publish Test Report + if: always() + uses: mikepenz/action-junit-report@v4 + with: + report_paths: '**/build/test-results/test/TEST-*.xml' + require_tests: false + check_name: 'JUnit Test Report' + + - name: 🗃️ Upload Test Reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-reports + path: '**/build/reports/tests/test/' + retention-days: 7 diff --git a/.gitignore b/.gitignore index 7fc5bed910..80bfb52284 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ bin/ .gradle build run +logs temp diff --git a/PrivateConfig b/PrivateConfig index ec03578927..2941940e8d 160000 --- a/PrivateConfig +++ b/PrivateConfig @@ -1 +1 @@ -Subproject commit ec03578927fc0394afcf08ceb35c1b02caa18539 +Subproject commit 2941940e8d892f4b82c921d868bdf8cdf9670bfa diff --git a/README.md b/README.md index 42abf342bd..a6c72b8ac4 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,22 @@ This monorepo will eventually contain all civ projects and development ## Developing Locally -### Plugins +### Tests +JUnit 5 tests live under `src/test/` in any plugin. They run via `useJUnitPlatform()` +(configured in [`plugins/build.gradle.kts`](plugins/build.gradle.kts)) and execute on +every PR through the [Gradle Check All](.github/workflows/check_gradle_all.yaml) workflow. + +To run the suite locally: + +```sh +./gradlew check # runs tests for every plugin +./gradlew :plugins:civmodcore-paper:test --rerun-tasks # one plugin +``` + +civmodcore-paper uses MockBukkit per https://docs.mockbukkit.org/docs/en/user_guide/advanced/paperweight, +which keeps paperweight on `compileOnly` so MockBukkit owns the test +classpath. Trade-off: NMS (`net.minecraft.*`) is not available at test +time, so anything that needs NMS has to live in production code only. ### Containers A docker compose stack is provided to help test containers built from diff --git a/ansible/files/gamma-config/bukkit.yml b/ansible/files/gamma-config/bukkit.yml index da99ecda1b..a14515790f 100644 --- a/ansible/files/gamma-config/bukkit.yml +++ b/ansible/files/gamma-config/bukkit.yml @@ -22,7 +22,7 @@ chunk-gc: ticks-per: axolotl-spawns: 4800 animal-spawns: 4800 - monster-spawns: 100 + monster-spawns: 70 water-spawns: 1200 water-ambient-spawns: 4800 water-underground-creature-spawns: 7200 diff --git a/ansible/files/gamma-config/ops.json b/ansible/files/gamma-config/ops.json index 095e9ad81b..4e674dbbbc 100644 --- a/ansible/files/gamma-config/ops.json +++ b/ansible/files/gamma-config/ops.json @@ -16,11 +16,5 @@ "name": "Okx", "level": 4, "bypassesPlayerLimit": true - }, - { - "uuid": "7d4af441-a721-4e4c-9848-4e92a679f182", - "name": "HaKr_", - "level": 4, - "bypassesPlayerLimit": true } ] diff --git a/ansible/files/gamma-config/plugins/Bastion/config.yml b/ansible/files/gamma-config/plugins/Bastion/config.yml index 5dfb5a7a54..ef9d4f056e 100644 --- a/ansible/files/gamma-config/plugins/Bastion/config.yml +++ b/ansible/files/gamma-config/plugins/Bastion/config.yml @@ -47,7 +47,7 @@ bastions: pearls: block: true blockMidair: false - scaleFactor: 1 + scaleFactor: 0 requireMaturity: true consumeOnBlock: false damageFirstBastion: true @@ -101,3 +101,46 @@ bastions: damageFirstBastion: true explodeOnBlock: true explodeOnBlockStrength: 0 + mob: + block: + material: FLETCHING_TABLE + durability: 0 + name: Mob Repellator + lore: + - Blocks mob spawns in a 96 block radius cylinder + squarefield: false + effectRadius: 80 + includeY: true + startScaleFactor: 250 + finalScaleFactor: 1 + warmupTime: 86400000 + erosionPerDay: 0 + regenPerDay: 5 + blocksToErode: -1 + placementCooldown: 2000 + destroyOnRemove: false + onlyDirectDestroy: true + blockReinforcements: false + blockMobs: true + destroyOnRemoveWhileImmature: true + proximityDamageRange: 25 + proximityDamageFactor: 0.5 + overlay_name: Mo + blockLiquids: false + pearls: + block: false + blockMidair: false + scaleFactor: 1 + requireMaturity: true + consumeOnBlock: true + damageFirstBastion: true + allowPearlingOut: true + elytra: + block: false + scaleFactor: 1 + requireMaturity: true + destroyOnBlock: false + damageOnBlock: true + damageFirstBastion: true + explodeOnBlock: true + explodeOnBlockStrength: 0 diff --git a/ansible/files/gamma-config/plugins/Citadel/config.yml b/ansible/files/gamma-config/plugins/Citadel/config.yml index 448c85165f..03bfb234b4 100644 --- a/ansible/files/gamma-config/plugins/Citadel/config.yml +++ b/ansible/files/gamma-config/plugins/Citadel/config.yml @@ -421,6 +421,7 @@ reinforcementBreakMultipliers: - WOODEN_STAIRS - ALL_SIGNS - WOODEN_BUTTONS + - WOODEN_SHELVES - multiplier: 2 types: - FURNACE @@ -446,6 +447,24 @@ reinforcementBreakMultipliers: - WAXED_EXPOSED_COPPER_DOOR - WAXED_OXIDIZED_COPPER_DOOR - WAXED_WEATHERED_COPPER_DOOR + - COPPER_BARS + - EXPOSED_COPPER_BARS + - OXIDIZED_COPPER_BARS + - WEATHERED_COPPER_BARS + - WAXED_COPPER_BARS + - WAXED_EXPOSED_COPPER_BARS + - WAXED_OXIDIZED_COPPER_BARS + - WAXED_WEATHERED_COPPER_BARS + - COPPER_CHAIN + - EXPOSED_COPPER_CHAIN + - OXIDIZED_COPPER_CHAIN + - WEATHERED_COPPER_CHAIN + - WAXED_COPPER_CHAIN + - WAXED_EXPOSED_COPPER_CHAIN + - WAXED_OXIDIZED_COPPER_CHAIN + - WAXED_WEATHERED_COPPER_CHAIN + tags: + - COPPER_CHESTS - custom-key: meteoric_iron_axe_silk multipliers: - multiplier: 2.5 @@ -468,6 +487,7 @@ reinforcementBreakMultipliers: - WOODEN_STAIRS - ALL_SIGNS - WOODEN_BUTTONS + - WOODEN_SHELVES - multiplier: 2 types: - FURNACE @@ -493,6 +513,24 @@ reinforcementBreakMultipliers: - WAXED_EXPOSED_COPPER_DOOR - WAXED_OXIDIZED_COPPER_DOOR - WAXED_WEATHERED_COPPER_DOOR + - COPPER_BARS + - EXPOSED_COPPER_BARS + - OXIDIZED_COPPER_BARS + - WEATHERED_COPPER_BARS + - WAXED_COPPER_BARS + - WAXED_EXPOSED_COPPER_BARS + - WAXED_OXIDIZED_COPPER_BARS + - WAXED_WEATHERED_COPPER_BARS + - COPPER_CHAIN + - EXPOSED_COPPER_CHAIN + - OXIDIZED_COPPER_CHAIN + - WEATHERED_COPPER_CHAIN + - WAXED_COPPER_CHAIN + - WAXED_EXPOSED_COPPER_CHAIN + - WAXED_OXIDIZED_COPPER_CHAIN + - WAXED_WEATHERED_COPPER_CHAIN + tags: + - COPPER_CHESTS # number of times a tool can break a reinforcement before it gets damaged by one durability # set to 0 to disable diff --git a/ansible/files/gamma-config/plugins/FactoryMod/config.yml b/ansible/files/gamma-config/plugins/FactoryMod/config.yml index feef9f4449..220e4fc435 100644 --- a/ansible/files/gamma-config/plugins/FactoryMod/config.yml +++ b/ansible/files/gamma-config/plugins/FactoryMod/config.yml @@ -16,6 +16,35 @@ log_inventories: true force_include_default: true can_upgrade: true factories: + kinetics: + type: FCC + name: Kinetics Factory + citadelBreakReduction: 1.0 + setupcost: + wind_essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 64 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: §fWind Essence + breeze_rod: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREEZE_ROD + amount: 4 + heavy_core: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HEAVY_CORE + amount: 1 + recipes: + - charge_wind_essence + - make_maces + - make_mob_repellators + - repair_kinetics_factory meteoric_iron_sword: type: FCC name: Meteoric Iron Sword Smith @@ -1666,6 +1695,7 @@ factories: - grow_sculk - grow_sculk_vein - kill_bush + - grow_dry_grass - root_dirt - melt_ice - form_tube_coral_block @@ -1745,6 +1775,30 @@ factories: - weather_copper_trapdoors - weather_exposed_copper_trapdoors - weather_weathered_copper_trapdoors + - make_copper_chests + - wax_copper_chests + - wax_exposed_copper_chests + - wax_weathered_copper_chests + - wax_oxidized_copper_chests + - weather_copper_chests + - weather_exposed_copper_chests + - weather_weathered_copper_chests + - make_copper_bars + - wax_copper_bars + - wax_exposed_copper_bars + - wax_weathered_copper_bars + - wax_oxidized_copper_bars + - weather_copper_bars + - weather_exposed_copper_bars + - weather_weathered_copper_bars + - make_copper_chain + - wax_copper_chain + - wax_exposed_copper_chain + - wax_weathered_copper_chain + - wax_oxidized_copper_chain + - weather_copper_chain + - weather_exposed_copper_chain + - weather_weathered_copper_chain - make_copper_workshop_kit - repair_copper_workshop - repair_copper_workshop_kit @@ -9154,7 +9208,7 @@ recipes: chain: v: 3839 ==: org.bukkit.inventory.ItemStack - type: CHAIN + type: IRON_CHAIN amount: 64 make_lantern: production_time: 4s @@ -12909,31 +12963,36 @@ recipes: ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - make_copper_trapdoors: + make_copper_chests: production_time: 4s - name: Make Copper Trap Doors + name: Make Copper Chests type: PRODUCTION input: copper_block: v: 3839 ==: org.bukkit.inventory.ItemStack type: COPPER_BLOCK - amount: 16 + amount: 32 + chest: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: CHEST + amount: 48 output: - copper_trapdoor: + copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: COPPER_TRAPDOOR - amount: 64 - wax_copper_trapdoors: + type: COPPER_CHEST + amount: 48 + wax_copper_chests: production_time: 4s - name: Wax Copper Trap Doors + name: Wax Copper Chests type: PRODUCTION input: - copper_trapdoor: + copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: COPPER_TRAPDOOR + type: COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -12941,20 +13000,20 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_copper_trapdoor: + waxed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_COPPER_TRAPDOOR + type: WAXED_COPPER_CHEST amount: 64 - wax_exposed_copper_trapdoors: + wax_exposed_copper_chests: production_time: 4s - name: Wax Exposed Copper Trap Doors + name: Wax Exposed Copper Chests type: PRODUCTION input: - exposed_copper_trapdoor: + exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: EXPOSED_COPPER_TRAPDOOR + type: EXPOSED_COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -12962,20 +13021,20 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_exposed_copper_trapdoor: + waxed_exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_EXPOSED_COPPER_TRAPDOOR + type: WAXED_EXPOSED_COPPER_CHEST amount: 64 - wax_weathered_copper_trapdoors: + wax_weathered_copper_chests: production_time: 4s - name: Wax Weathered Copper Trap Doors + name: Wax Weathered Copper Chests type: PRODUCTION input: - weathered_copper_trapdoor: + weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WEATHERED_COPPER_TRAPDOOR + type: WEATHERED_COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -12983,20 +13042,20 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_weathered_copper_trapdoor: + waxed_weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_WEATHERED_COPPER_TRAPDOOR + type: WAXED_WEATHERED_COPPER_CHEST amount: 64 - wax_oxidized_copper_trapdoors: + wax_oxidized_copper_chests: production_time: 4s - name: Wax Oxidized Copper Trap Doors + name: Wax Oxidized Copper Chests type: PRODUCTION input: - oxidized_copper_trapdoor: + oxidized_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: OXIDIZED_COPPER_TRAPDOOR + type: OXIDIZED_COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -13004,21 +13063,21 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_oxidized_copper_trapdoor: + waxed_oxidized_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_OXIDIZED_COPPER_TRAPDOOR + type: WAXED_OXIDIZED_COPPER_CHEST amount: 64 - weather_copper_trapdoors: + weather_copper_chests: production_time: 4s fuel_consumption_intervall: 2s - name: Weather Copper Trap Doors + name: Weather Copper Chests type: PRODUCTION input: - copper_trapdoor: + copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: COPPER_TRAPDOOR + type: COPPER_CHEST amount: 64 water_bucket: v: 3839 @@ -13026,26 +13085,26 @@ recipes: type: WATER_BUCKET amount: 1 output: - exposed_copper_trapdoor: + exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: EXPOSED_COPPER_TRAPDOOR + type: EXPOSED_COPPER_CHEST amount: 64 bucket: v: 3839 ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - weather_exposed_copper_trapdoors: + weather_exposed_copper_chests: production_time: 6s fuel_consumption_intervall: 2s - name: Weather Exposed Copper Trap Doors + name: Weather Exposed Copper Chests type: PRODUCTION input: - exposed_copper_trapdoor: + exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: EXPOSED_COPPER_TRAPDOOR + type: EXPOSED_COPPER_CHEST amount: 64 water_bucket: v: 3839 @@ -13053,26 +13112,26 @@ recipes: type: WATER_BUCKET amount: 1 output: - weathered_copper_trapdoor: + weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WEATHERED_COPPER_TRAPDOOR + type: WEATHERED_COPPER_CHEST amount: 64 bucket: v: 3839 ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - weather_weathered_copper_trapdoors: + weather_weathered_copper_chests: production_time: 8s fuel_consumption_intervall: 2s - name: Weather Weathered Copper Trap Doors + name: Weather Weathered Copper Chests type: PRODUCTION input: - weathered_copper_trapdoor: + weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WEATHERED_COPPER_TRAPDOOR + type: WEATHERED_COPPER_CHEST amount: 64 water_bucket: v: 3839 @@ -13080,25 +13139,41 @@ recipes: type: WATER_BUCKET amount: 1 output: - oxidized_copper_trapdoor: + oxidized_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: OXIDIZED_COPPER_TRAPDOOR + type: OXIDIZED_COPPER_CHEST amount: 64 bucket: v: 3839 ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - make_copper_workshop_kit: + make_copper_bars: production_time: 4s - name: Make Copper Workshop Repair Kit + name: Make Copper Bars type: PRODUCTION input: copper_block: v: 3839 ==: org.bukkit.inventory.ItemStack type: COPPER_BLOCK + amount: 4 + output: + copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BARS + amount: 256 + wax_copper_bars: + production_time: 4s + name: Wax Copper Bars + type: PRODUCTION + input: + copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BARS amount: 64 honeycomb: v: 3839 @@ -13106,64 +13181,591 @@ recipes: type: HONEYCOMB amount: 16 output: - kit: + waxed_copper_bars: v: 3839 ==: org.bukkit.inventory.ItemStack - type: BARREL + type: WAXED_COPPER_BARS + amount: 64 + wax_exposed_copper_bars: + production_time: 4s + name: Wax Exposed Copper Bars + type: PRODUCTION + input: + exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_BARS + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_EXPOSED_COPPER_BARS + amount: 64 + wax_weathered_copper_bars: + production_time: 4s + name: Wax Weathered Copper Bars + type: PRODUCTION + input: + weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_BARS + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_WEATHERED_COPPER_BARS + amount: 64 + wax_oxidized_copper_bars: + production_time: 4s + name: Wax Oxidized Copper Bars + type: PRODUCTION + input: + oxidized_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_BARS + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_oxidized_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_OXIDIZED_COPPER_BARS + amount: 64 + weather_copper_bars: + production_time: 4s + fuel_consumption_intervall: 2s + name: Weather Copper Bars + type: PRODUCTION + input: + copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BARS + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET amount: 1 - meta: - meta-type: UNSPECIFIC - ==: ItemMeta - display-name: Copper Workshop Repair Kit - lore: - - One kit will repair a Copper Workshop to full health. - repair_copper_workshop: + output: + exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_BARS + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_exposed_copper_bars: + production_time: 6s + fuel_consumption_intervall: 2s + name: Weather Exposed Copper Bars + type: PRODUCTION + input: + exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_BARS + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_BARS + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_weathered_copper_bars: + production_time: 8s + fuel_consumption_intervall: 2s + name: Weather Weathered Copper Bars + type: PRODUCTION + input: + weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_BARS + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + oxidized_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_BARS + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + make_copper_chain: production_time: 4s - name: Repair Factory - type: REPAIR + name: Make Copper Chain + type: PRODUCTION input: copper_block: v: 3839 ==: org.bukkit.inventory.ItemStack type: COPPER_BLOCK + amount: 3 + output: + copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_CHAIN + amount: 64 + wax_copper_chain: + production_time: 4s + name: Wax Copper Chain + type: PRODUCTION + input: + copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_CHAIN amount: 64 honeycomb: v: 3839 ==: org.bukkit.inventory.ItemStack type: HONEYCOMB amount: 16 - health_gained: 10000 - repair_copper_workshop_kit: + output: + waxed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_COPPER_CHAIN + amount: 64 + wax_exposed_copper_chain: production_time: 4s - name: Repair Factory using Repair Kit - type: REPAIR + name: Wax Exposed Copper Chain + type: PRODUCTION input: - kit: + exposed_copper_chain: v: 3839 ==: org.bukkit.inventory.ItemStack - type: BARREL - amount: 1 - meta: - meta-type: UNSPECIFIC - ==: ItemMeta - display-name: Copper Workshop Repair Kit - lore: - - One kit will repair a Copper Workshop to full health. - health_gained: 10000 - crack_fossil: - type: RANDOM - name: Crack Fossil - production_time: 1s - fuel_consumption_intervall: 4s + type: EXPOSED_COPPER_CHAIN + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_exposed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_EXPOSED_COPPER_CHAIN + amount: 64 + wax_weathered_copper_chain: + production_time: 4s + name: Wax Weathered Copper Chain + type: PRODUCTION input: - fossil: + weathered_copper_chain: v: 3839 ==: org.bukkit.inventory.ItemStack - type: PRISMARINE_SHARD - amount: 1 - meta: - meta-type: UNSPECIFIC - ==: ItemMeta + type: WEATHERED_COPPER_CHAIN + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_weathered_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_WEATHERED_COPPER_CHAIN + amount: 64 + wax_oxidized_copper_chain: + production_time: 4s + name: Wax Oxidized Copper Chain + type: PRODUCTION + input: + oxidized_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_CHAIN + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_oxidized_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_OXIDIZED_COPPER_CHAIN + amount: 64 + weather_copper_chain: + production_time: 4s + fuel_consumption_intervall: 2s + name: Weather Copper Chain + type: PRODUCTION + input: + copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_CHAIN + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + exposed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_CHAIN + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_exposed_copper_chain: + production_time: 6s + fuel_consumption_intervall: 2s + name: Weather Exposed Copper Chain + type: PRODUCTION + input: + exposed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_CHAIN + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + weathered_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_CHAIN + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_weathered_copper_chain: + production_time: 8s + fuel_consumption_intervall: 2s + name: Weather Weathered Copper Chain + type: PRODUCTION + input: + weathered_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_CHAIN + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + oxidized_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_CHAIN + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + make_copper_trapdoors: + production_time: 4s + name: Make Copper Trap Doors + type: PRODUCTION + input: + copper_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BLOCK + amount: 16 + output: + copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_TRAPDOOR + amount: 64 + wax_copper_trapdoors: + production_time: 4s + name: Wax Copper Trap Doors + type: PRODUCTION + input: + copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_COPPER_TRAPDOOR + amount: 64 + wax_exposed_copper_trapdoors: + production_time: 4s + name: Wax Exposed Copper Trap Doors + type: PRODUCTION + input: + exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_EXPOSED_COPPER_TRAPDOOR + amount: 64 + wax_weathered_copper_trapdoors: + production_time: 4s + name: Wax Weathered Copper Trap Doors + type: PRODUCTION + input: + weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_WEATHERED_COPPER_TRAPDOOR + amount: 64 + wax_oxidized_copper_trapdoors: + production_time: 4s + name: Wax Oxidized Copper Trap Doors + type: PRODUCTION + input: + oxidized_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_oxidized_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_OXIDIZED_COPPER_TRAPDOOR + amount: 64 + weather_copper_trapdoors: + production_time: 4s + fuel_consumption_intervall: 2s + name: Weather Copper Trap Doors + type: PRODUCTION + input: + copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_TRAPDOOR + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_TRAPDOOR + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_exposed_copper_trapdoors: + production_time: 6s + fuel_consumption_intervall: 2s + name: Weather Exposed Copper Trap Doors + type: PRODUCTION + input: + exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_TRAPDOOR + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_TRAPDOOR + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_weathered_copper_trapdoors: + production_time: 8s + fuel_consumption_intervall: 2s + name: Weather Weathered Copper Trap Doors + type: PRODUCTION + input: + weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_TRAPDOOR + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + oxidized_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_TRAPDOOR + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + make_copper_workshop_kit: + production_time: 4s + name: Make Copper Workshop Repair Kit + type: PRODUCTION + input: + copper_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BLOCK + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + kit: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BARREL + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Copper Workshop Repair Kit + lore: + - One kit will repair a Copper Workshop to full health. + repair_copper_workshop: + production_time: 4s + name: Repair Factory + type: REPAIR + input: + copper_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BLOCK + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + health_gained: 10000 + repair_copper_workshop_kit: + production_time: 4s + name: Repair Factory using Repair Kit + type: REPAIR + input: + kit: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BARREL + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Copper Workshop Repair Kit + lore: + - One kit will repair a Copper Workshop to full health. + health_gained: 10000 + crack_fossil: + type: RANDOM + name: Crack Fossil + production_time: 1s + fuel_consumption_intervall: 4s + input: + fossil: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PRISMARINE_SHARD + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta display-name: §3Fossil lore: - Crack me in a factory for a prize! @@ -14088,33 +14690,40 @@ recipes: type: BEACON amount: 1 diamond_horse_armor: - chance: 0.00012 + chance: 0.0001 diamond_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: DIAMOND_HORSE_ARMOR amount: 1 golden_horse_armor: - chance: 0.00012 + chance: 0.0001 golden_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: GOLDEN_HORSE_ARMOR amount: 1 iron_horse_armor: - chance: 0.00012 + chance: 0.0001 iron_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: IRON_HORSE_ARMOR amount: 1 leather_horse_armor: - chance: 0.00012 + chance: 0.0001 leather_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: LEATHER_HORSE_ARMOR amount: 1 + copper_horse_armor: + chance: 0.0001 + copper_horse_armor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_HORSE_ARMOR + amount: 1 jukebox: chance: 0.0092974999 jukebox: @@ -14450,6 +15059,28 @@ recipes: ==: org.bukkit.inventory.ItemStack type: DEAD_BUSH amount: 16 + grow_dry_grass: + production_time: 4s + fuel_consumption_intervall: 1s + name: Grow dry grass + type: PRODUCTION + input: + sand: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: SAND + amount: 64 + cobweb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COBWEB + amount: 64 + output: + short_dry_grass: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: SHORT_DRY_GRASS + amount: 32 root_dirt: production_time: 4s fuel_consumption_intervall: 1s @@ -16733,3 +17364,113 @@ recipes: type: LAPIS_BLOCK amount: 56 health_gained: 10000 + charge_wind_essence: + production_time: 4s + name: Charge Wind Essence + type: PRODUCTION + input: + wind_essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 4 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: §fWind Essence + diamond: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: DIAMOND + amount: 3 + quartz: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: QUARTZ + amount: 32 + output: + wind_charge: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WIND_CHARGE + amount: 4 + make_maces: + production_time: 4s + name: Make Maces + type: PRODUCTION + input: + breeze_rod: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREEZE_ROD + amount: 3 + heavy_core: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HEAVY_CORE + amount: 3 + output: + mace: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: MACE + amount: 5 + repair_kinetics_factory: + production_time: 4s + name: Repair Factory + type: REPAIR + input: + wind_essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 8 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: §fWind Essence + breeze_rod: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREEZE_ROD + amount: 1 + health_gained: 10000 + make_mob_repellators: + forceInclude: true + production_time: 4s + name: Make Mob Repellators + type: PRODUCTION + input: + heavy_core: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HEAVY_CORE + amount: 1 + diamond: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: DIAMOND + amount: 64 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 24 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + output: + mob_repellator: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: FLETCHING_TABLE + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Mob Repellator + lore: + - Blocks mob spawns in a 96 block radius cylinder + amount: 4 diff --git a/ansible/files/gamma-config/plugins/Finale/config.yml b/ansible/files/gamma-config/plugins/Finale/config.yml index 17505f25eb..2e3c34ae89 100644 --- a/ansible/files/gamma-config/plugins/Finale/config.yml +++ b/ansible/files/gamma-config/plugins/Finale/config.yml @@ -91,13 +91,22 @@ gapples: #allows adjusting the attack damage of any item by its spigot material identifier weaponModification: + mace: + material: MACE + damage: 6 + armourDamageMultiplier: 2.5 netheriteAxe: material: NETHERITE_AXE - damage: 5.75 - armourDamageMultiplier: 1.78 + damage: 6 diamondAxe: material: DIAMOND_AXE damage: 5 + copperAxe: + material: COPPER_AXE + damage: 5 + copperSword: + material: COPPER_SWORD + damage: 5 ironAxe: material: IRON_AXE damage: 4 @@ -642,3 +651,8 @@ meteoricIronSlowness: true fireworkExplosions: false rebalanceTntMinecart: true + +mace: + cooldown: 800 + max_damage: 38 + wind_cooldown: 3 diff --git a/ansible/files/gamma-config/plugins/ItemExchange/config.yml b/ansible/files/gamma-config/plugins/ItemExchange/config.yml index b9b476989b..9f07d03d82 100644 --- a/ansible/files/gamma-config/plugins/ItemExchange/config.yml +++ b/ansible/files/gamma-config/plugins/ItemExchange/config.yml @@ -6,6 +6,13 @@ debug: false supportedBlocks: - "CHEST" - "TRAPPED_CHEST" + - "COPPER_CHEST" + - "EXPOSED_COPPER_CHEST" + - "OXIDIZED_COPPER_CHEST" + - "WEATHERED_COPPER_CHEST" + - "WAXED_COPPER_CHEST" + - "WAXED_EXPOSED_COPPER_CHEST" + - "WAXED_OXIDIZED_COPPER_CHEST" - "BARREL" - "DISPENSER" - "DROPPER" @@ -16,6 +23,13 @@ supportedBlocks: successButtonBlocks: - "CHEST" - "TRAPPED_CHEST" + - "COPPER_CHEST" + - "EXPOSED_COPPER_CHEST" + - "OXIDIZED_COPPER_CHEST" + - "WEATHERED_COPPER_CHEST" + - "WAXED_COPPER_CHEST" + - "WAXED_EXPOSED_COPPER_CHEST" + - "WAXED_OXIDIZED_COPPER_CHEST" - "BARREL" - "ENDER_CHEST" @@ -25,6 +39,10 @@ createShopFromChest: true ruleItem: "STONE_BUTTON" repairables: + - "COPPER_HELMET" + - "COPPER_CHESTPLATE" + - "COPPER_LEGGINGS" + - "COPPER_BOOTS" - "NETHERITE_HELMET" - "NETHERITE_CHESTPLATE" - "NETHERITE_LEGGINGS" @@ -49,6 +67,11 @@ repairables: - "LEATHER_CHESTPLATE" - "LEATHER_LEGGINGS" - "LEATHER_BOOTS" + - "COPPER_PICKAXE" + - "COPPER_AXE" + - "COPPER_HOE" + - "COPPER_SHOVEL" + - "COPPER_SWORD" - "NETHERITE_SWORD" - "DIAMOND_SWORD" - "GOLDEN_SWORD" diff --git a/ansible/files/gamma-config/plugins/MythicMobs/RandomSpawns/BleezeSpawns.yml b/ansible/files/gamma-config/plugins/MythicMobs/RandomSpawns/BleezeSpawns.yml new file mode 100644 index 0000000000..1d1e2dc630 --- /dev/null +++ b/ansible/files/gamma-config/plugins/MythicMobs/RandomSpawns/BleezeSpawns.yml @@ -0,0 +1,11 @@ +RandomBleeze: + Type: Bleeze + Worlds: world + Chance: 0.0002 + Priority: 1 + Action: REPLACE + Biomes: DESERT,ERODED_BADLANDS,SAVANNA,SAVANNA_PLATEAU,BADLANDS + Conditions: + - outside true + - heightabove{h=30} true + - blockTypeInRadius{type=OBSIDIAN;amount=>0;radius=5} false diff --git a/ansible/files/gamma-config/plugins/MythicMobs/RandomSpawns/ExampleRandomSpawns.yml b/ansible/files/gamma-config/plugins/MythicMobs/RandomSpawns/ExampleRandomSpawns.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/files/gamma-config/plugins/MythicMobs/mobs/Bleeze.yml b/ansible/files/gamma-config/plugins/MythicMobs/mobs/Bleeze.yml new file mode 100644 index 0000000000..a9f312affb --- /dev/null +++ b/ansible/files/gamma-config/plugins/MythicMobs/mobs/Bleeze.yml @@ -0,0 +1,62 @@ +Bleeze: + Type: BLAZE + Display: '&4&lBleeze' + Health: 600 + Damage: 16 + Drops: + - heavy_core 1 0.5 + Skills: + - setvariable{var=caster.minions;type=INTEGER;val=0} @self ~onSpawn + - geyser{type=LAVA;height=3;speed=40} @target 0.05 + - skill{s=WitherFire} @PlayersInRadius{r=25} ~onTimer:300 0.4 + - skill{s=BreezeMinionSwarm} @self 0.1 + - skill{s=BreezeAttack} @target 0.2 + - recoil{r=30;pitch=-1to1} @target 0.05 + - damage{amount=25} @trigger ~onBowHit + - projectile{onTick=Fireball-Tick;onHit=Fireball-Hit;v=8;i=1;hR=1;vR=1;hnp=true} @target 0.1 + - projectile{onTick=Fireball-Tick;onHit=Fireball-Hit;v=8;i=1;hR=1;vR=1;hnp=true} @target ~onTimer:60 0.3 + - skill{s=BreezePull} @self 0.1 + BossBar: + Enabled: true + Title: '&4&lBleeze' + Range: 25 + Color: RED + Style: SOLID + Options: + AlwaysShowName: true + MaxCombatDistance: 25 + PreventOtherDrops: true + KnockbackResistance: 0.1 + Despawn: NEVER + DigOutOfGround: true + DamageModifiers: + - PROJECTILE 0.25 + AITargetSelectors: + - clear + - players + +BleezeMinion: + Type: BREEZE + Health: 120 + Drops: + - paper{name="Wind Essence"} 0-5 + - breeze_rod 1 0.2 + Skills: + - geyser{type=LAVA;height=2;speed=20} @target 0.01 + - skill{s=BreezeMinionAttack} @target 0.2 + - damage{amount=16} @trigger ~onBowHit + - ignite{ticks=40} @trigger ~onBowHit + - projectile{onTick=Fireball-Tick-Weak;onHit=Fireball-Hit-Weak;v=8;i=1;hR=1;vR=1;hnp=true} @target ~onTimer:120 0.3 + Options: + MaxCombatDistance: 25 + PreventOtherDrops: true + Despawn: NEVER + DigOutOfGround: true + DamageModifiers: + - FIRE 0 + - LAVA 0 + - FIRE_TICK 0 + - PROJECTILE 0.5 + AITargetSelectors: + - clear + - players diff --git a/ansible/files/gamma-config/plugins/MythicMobs/skills/BleezeSkills.yml b/ansible/files/gamma-config/plugins/MythicMobs/skills/BleezeSkills.yml new file mode 100644 index 0000000000..fb47fd11fb --- /dev/null +++ b/ansible/files/gamma-config/plugins/MythicMobs/skills/BleezeSkills.yml @@ -0,0 +1,62 @@ +WitherFire: + CancelIfNoTargets: true + TargetConditions: + - isburning true + Cooldown: 1 + Skills: + - potion{type=WITHER;duration=100;level=2} @target +BreezeAttack: + Cooldown: 8 + Conditions: + - targetwithin{d=25} + Skills: + - teleport @target + - effect:sound{s=mob.endermen.portal;volume=1.0;pitch=0.5} + - delay 10 + - damage{amount=12;ignorearmor=true} @PlayersInRadius{r=5} + - throw{velocity=10;velocityY=5} @PlayersInRadius{r=5} + - effect:explosion @Self +BreezePull: + Cooldown: 15 + Skills: + - forcepull{spread=5} @PlayersInRadius{r=30} + - damage{amount=5;ignorearmor=true} @PlayersInRadius{r=30} + - ignite{ticks=200} @PlayersInRadius{r=30} +BreezeMinionSwarm: + Cooldown: 30 + Conditions: + - variableinrange{var=caster.minions;value=<21} + Skills: + - variableadd{var=caster.minions;amount=3} + - summon{mob=BleezeMinion;amount=1;noise=5} @Self + - delay 20 + - summon{mob=BleezeMinion;amount=1;noise=5} @Self + - delay 20 + - summon{mob=BleezeMinion;amount=1;noise=5} @Self +BreezeMinionAttack: + Cooldown: 12 + Conditions: + - targetwithin{d=25} + Skills: + - damage{amount=16;ignorearmor=true} @target + - throw{velocity=10;velocityY=15} @target + - effect:explosion @Self + - ignite{ticks=100} @target + +Fireball-Tick: + Skills: + - effect:particles{p=lava;amount=6;speed=0;hS=0.2;vS=0.2} @origin +Fireball-Hit: + Skills: + - damage{amount=40} + - potion{type=SLOW;duration=100;lvl=2} + - ignite{ticks=100} @target + +Fireball-Tick-Weak: + Skills: + - effect:particles{p=lava;amount=4;speed=0;hS=0.2;vS=0.2} @origin +Fireball-Hit-Weak: + Skills: + - damage{amount=30} + - potion{type=SLOW;duration=100;lvl=2} + - ignite{ticks=100} @target diff --git a/ansible/files/gamma-config/plugins/SimpleAdminHacks/config.yml b/ansible/files/gamma-config/plugins/SimpleAdminHacks/config.yml index 5aefb7309b..b73c7de7f4 100644 --- a/ansible/files/gamma-config/plugins/SimpleAdminHacks/config.yml +++ b/ansible/files/gamma-config/plugins/SimpleAdminHacks/config.yml @@ -337,6 +337,14 @@ hacks: minDepthToMatch: 2 watchedMaterials: - CHEST + - TRAPPED_CHEST + - COPPER_CHEST + - EXPOSED_COPPER_CHEST + - OXIDIZED_COPPER_CHEST + - WEATHERED_COPPER_CHEST + - WAXED_COPPER_CHEST + - WAXED_EXPOSED_COPPER_CHEST + - WAXED_OXIDIZED_COPPER_CHEST - FURNACE - JUKEBOX - NOTE_BLOCK @@ -620,3 +628,11 @@ hacks: enabled: false NetheriteCrafting: enabled: true + NameLocker: + enabled: true + BrewIndex: + enabled: true + ServerLinksHack: + enabled: true + discordUrl: https://discord.gg/civmc + patreonUrl: https://patreon.com/Civ_MC diff --git a/ansible/files/gamma-config/plugins/SuperVanish/config.yml b/ansible/files/gamma-config/plugins/SuperVanish/config.yml index 0ab791a7b0..39ce1e71c6 100644 --- a/ansible/files/gamma-config/plugins/SuperVanish/config.yml +++ b/ansible/files/gamma-config/plugins/SuperVanish/config.yml @@ -3,7 +3,7 @@ ############# Invisibility Features ############## InvisibilityFeatures: # Should invisible players get night vision? (client-side; Requires ProtocolLib) - NightVisionEffect: true + NightVisionEffect: false # Should SV disable damage for invisible players? DisableDamage: true # Should SV disable hunger for invisible players? diff --git a/ansible/files/gamma-config/plugins/TAB/config.yml b/ansible/files/gamma-config/plugins/TAB/config.yml index 7ad411a842..41521215d3 100644 --- a/ansible/files/gamma-config/plugins/TAB/config.yml +++ b/ansible/files/gamma-config/plugins/TAB/config.yml @@ -10,7 +10,7 @@ header-footer: - '&9Modmail at &6reddit.com/r/civmc' - '&a%tps% TPS &r&6discord.gg/nDnsU6vJqg' - '&cPatreon: &6patreon.com/Civ_MC' - - '&6Admins: Wingzero54, RedDevel, Okx, HaKr_' + - '&6Admins: Wingzero54, RedDevel, Okx' per-world: world1: header: diff --git a/ansible/files/gamma-config/server.properties b/ansible/files/gamma-config/server.properties index 149cc477d3..3a4c6a4ba3 100644 --- a/ansible/files/gamma-config/server.properties +++ b/ansible/files/gamma-config/server.properties @@ -57,4 +57,4 @@ enforce-secure-profile=false resource-pack-sha1= spawn-protection=0 max-world-size=29999984 -enable-code-of-conduct=true +enable-code-of-conduct=false diff --git a/ansible/files/gamma-config/spigot.yml b/ansible/files/gamma-config/spigot.yml index be0d9f9f61..ac76ec15b3 100644 --- a/ansible/files/gamma-config/spigot.yml +++ b/ansible/files/gamma-config/spigot.yml @@ -102,7 +102,7 @@ world-settings: entity-tracking-range: players: 160 animals: 64 - monsters: 32 + monsters: 48 misc: 96 other: 96 ticks-per: diff --git a/ansible/files/paper-config/bukkit.yml b/ansible/files/paper-config/bukkit.yml index facbdcabbd..8e7e451c90 100644 --- a/ansible/files/paper-config/bukkit.yml +++ b/ansible/files/paper-config/bukkit.yml @@ -22,7 +22,7 @@ chunk-gc: ticks-per: axolotl-spawns: 4800 animal-spawns: 4800 - monster-spawns: 100 + monster-spawns: 70 water-spawns: 1200 water-ambient-spawns: 4800 water-underground-creature-spawns: 7200 diff --git a/ansible/files/paper-config/ops.json b/ansible/files/paper-config/ops.json index 095e9ad81b..4e674dbbbc 100644 --- a/ansible/files/paper-config/ops.json +++ b/ansible/files/paper-config/ops.json @@ -16,11 +16,5 @@ "name": "Okx", "level": 4, "bypassesPlayerLimit": true - }, - { - "uuid": "7d4af441-a721-4e4c-9848-4e92a679f182", - "name": "HaKr_", - "level": 4, - "bypassesPlayerLimit": true } ] diff --git a/ansible/files/paper-config/plugins/Bastion/config.yml b/ansible/files/paper-config/plugins/Bastion/config.yml index 693ea90ac0..0cd3709538 100644 --- a/ansible/files/paper-config/plugins/Bastion/config.yml +++ b/ansible/files/paper-config/plugins/Bastion/config.yml @@ -47,7 +47,7 @@ bastions: pearls: block: true blockMidair: false - scaleFactor: 1 + scaleFactor: 0 requireMaturity: true consumeOnBlock: false damageFirstBastion: true @@ -101,3 +101,46 @@ bastions: damageFirstBastion: true explodeOnBlock: true explodeOnBlockStrength: 0 + mob: + block: + material: FLETCHING_TABLE + durability: 0 + name: Mob Repellator + lore: + - Blocks mob spawns in a 96 block radius cylinder + squarefield: false + effectRadius: 96 + includeY: true + startScaleFactor: 250 + finalScaleFactor: 1 + warmupTime: 86400000 + erosionPerDay: 0 + regenPerDay: 5 + blocksToErode: -1 + placementCooldown: 2000 + destroyOnRemove: false + onlyDirectDestroy: true + blockReinforcements: false + blockMobs: true + destroyOnRemoveWhileImmature: true + proximityDamageRange: 25 + proximityDamageFactor: 0.5 + overlay_name: Mo + blockLiquids: false + pearls: + block: false + blockMidair: false + scaleFactor: 1 + requireMaturity: true + consumeOnBlock: true + damageFirstBastion: true + allowPearlingOut: true + elytra: + block: false + scaleFactor: 1 + requireMaturity: true + destroyOnBlock: false + damageOnBlock: true + damageFirstBastion: true + explodeOnBlock: true + explodeOnBlockStrength: 0 diff --git a/ansible/files/paper-config/plugins/FactoryMod/config.yml b/ansible/files/paper-config/plugins/FactoryMod/config.yml index 2409a30de1..dcb974cdae 100644 --- a/ansible/files/paper-config/plugins/FactoryMod/config.yml +++ b/ansible/files/paper-config/plugins/FactoryMod/config.yml @@ -16,6 +16,35 @@ log_inventories: true force_include_default: true can_upgrade: true factories: + kinetics: + type: FCC + name: Kinetics Factory + citadelBreakReduction: 1.0 + setupcost: + wind_essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 64 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: §fWind Essence + breeze_rod: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREEZE_ROD + amount: 4 + heavy_core: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HEAVY_CORE + amount: 1 + recipes: + - charge_wind_essence + - make_maces + - make_mob_repellators + - repair_kinetics_factory meteoric_iron_sword: type: FCC name: Meteoric Iron Sword Smith @@ -1674,6 +1703,7 @@ factories: - grow_sculk - grow_sculk_vein - kill_bush + - grow_dry_grass - root_dirt - melt_ice - form_tube_coral_block @@ -1753,6 +1783,30 @@ factories: - weather_copper_trapdoors - weather_exposed_copper_trapdoors - weather_weathered_copper_trapdoors + - make_copper_chests + - wax_copper_chests + - wax_exposed_copper_chests + - wax_weathered_copper_chests + - wax_oxidized_copper_chests + - weather_copper_chests + - weather_exposed_copper_chests + - weather_weathered_copper_chests + - make_copper_bars + - wax_copper_bars + - wax_exposed_copper_bars + - wax_weathered_copper_bars + - wax_oxidized_copper_bars + - weather_copper_bars + - weather_exposed_copper_bars + - weather_weathered_copper_bars + - make_copper_chain + - wax_copper_chain + - wax_exposed_copper_chain + - wax_weathered_copper_chain + - wax_oxidized_copper_chain + - weather_copper_chain + - weather_exposed_copper_chain + - weather_weathered_copper_chain - make_copper_workshop_kit - repair_copper_workshop - repair_copper_workshop_kit @@ -9134,7 +9188,7 @@ recipes: chain: v: 3839 ==: org.bukkit.inventory.ItemStack - type: CHAIN + type: IRON_CHAIN amount: 64 make_lantern: production_time: 4s @@ -12844,31 +12898,36 @@ recipes: ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - make_copper_trapdoors: + make_copper_chests: production_time: 4s - name: Make Copper Trap Doors + name: Make Copper Chests type: PRODUCTION input: copper_block: v: 3839 ==: org.bukkit.inventory.ItemStack type: COPPER_BLOCK - amount: 16 + amount: 32 + chest: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: CHEST + amount: 48 output: - copper_trapdoor: + copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: COPPER_TRAPDOOR - amount: 64 - wax_copper_trapdoors: + type: COPPER_CHEST + amount: 48 + wax_copper_chests: production_time: 4s - name: Wax Copper Trap Doors + name: Wax Copper Chests type: PRODUCTION input: - copper_trapdoor: + copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: COPPER_TRAPDOOR + type: COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -12876,20 +12935,20 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_copper_trapdoor: + waxed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_COPPER_TRAPDOOR + type: WAXED_COPPER_CHEST amount: 64 - wax_exposed_copper_trapdoors: + wax_exposed_copper_chests: production_time: 4s - name: Wax Exposed Copper Trap Doors + name: Wax Exposed Copper Chests type: PRODUCTION input: - exposed_copper_trapdoor: + exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: EXPOSED_COPPER_TRAPDOOR + type: EXPOSED_COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -12897,20 +12956,20 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_exposed_copper_trapdoor: + waxed_exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_EXPOSED_COPPER_TRAPDOOR + type: WAXED_EXPOSED_COPPER_CHEST amount: 64 - wax_weathered_copper_trapdoors: + wax_weathered_copper_chests: production_time: 4s - name: Wax Weathered Copper Trap Doors + name: Wax Weathered Copper Chests type: PRODUCTION input: - weathered_copper_trapdoor: + weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WEATHERED_COPPER_TRAPDOOR + type: WEATHERED_COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -12918,20 +12977,20 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_weathered_copper_trapdoor: + waxed_weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_WEATHERED_COPPER_TRAPDOOR + type: WAXED_WEATHERED_COPPER_CHEST amount: 64 - wax_oxidized_copper_trapdoors: + wax_oxidized_copper_chests: production_time: 4s - name: Wax Oxidized Copper Trap Doors + name: Wax Oxidized Copper Chests type: PRODUCTION input: - oxidized_copper_trapdoor: + oxidized_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: OXIDIZED_COPPER_TRAPDOOR + type: OXIDIZED_COPPER_CHEST amount: 64 honeycomb: v: 3839 @@ -12939,21 +12998,21 @@ recipes: type: HONEYCOMB amount: 16 output: - waxed_oxidized_copper_trapdoor: + waxed_oxidized_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WAXED_OXIDIZED_COPPER_TRAPDOOR + type: WAXED_OXIDIZED_COPPER_CHEST amount: 64 - weather_copper_trapdoors: + weather_copper_chests: production_time: 4s fuel_consumption_intervall: 2s - name: Weather Copper Trap Doors + name: Weather Copper Chests type: PRODUCTION input: - copper_trapdoor: + copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: COPPER_TRAPDOOR + type: COPPER_CHEST amount: 64 water_bucket: v: 3839 @@ -12961,26 +13020,26 @@ recipes: type: WATER_BUCKET amount: 1 output: - exposed_copper_trapdoor: + exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: EXPOSED_COPPER_TRAPDOOR + type: EXPOSED_COPPER_CHEST amount: 64 bucket: v: 3839 ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - weather_exposed_copper_trapdoors: + weather_exposed_copper_chests: production_time: 6s fuel_consumption_intervall: 2s - name: Weather Exposed Copper Trap Doors + name: Weather Exposed Copper Chests type: PRODUCTION input: - exposed_copper_trapdoor: + exposed_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: EXPOSED_COPPER_TRAPDOOR + type: EXPOSED_COPPER_CHEST amount: 64 water_bucket: v: 3839 @@ -12988,26 +13047,26 @@ recipes: type: WATER_BUCKET amount: 1 output: - weathered_copper_trapdoor: + weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WEATHERED_COPPER_TRAPDOOR + type: WEATHERED_COPPER_CHEST amount: 64 bucket: v: 3839 ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - weather_weathered_copper_trapdoors: + weather_weathered_copper_chests: production_time: 8s fuel_consumption_intervall: 2s - name: Weather Weathered Copper Trap Doors + name: Weather Weathered Copper Chests type: PRODUCTION input: - weathered_copper_trapdoor: + weathered_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: WEATHERED_COPPER_TRAPDOOR + type: WEATHERED_COPPER_CHEST amount: 64 water_bucket: v: 3839 @@ -13015,25 +13074,41 @@ recipes: type: WATER_BUCKET amount: 1 output: - oxidized_copper_trapdoor: + oxidized_copper_chest: v: 3839 ==: org.bukkit.inventory.ItemStack - type: OXIDIZED_COPPER_TRAPDOOR + type: OXIDIZED_COPPER_CHEST amount: 64 bucket: v: 3839 ==: org.bukkit.inventory.ItemStack type: BUCKET amount: 1 - make_copper_workshop_kit: + make_copper_bars: production_time: 4s - name: Make Copper Workshop Repair Kit + name: Make Copper Bars type: PRODUCTION input: copper_block: v: 3839 ==: org.bukkit.inventory.ItemStack type: COPPER_BLOCK + amount: 4 + output: + copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BARS + amount: 256 + wax_copper_bars: + production_time: 4s + name: Wax Copper Bars + type: PRODUCTION + input: + copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BARS amount: 64 honeycomb: v: 3839 @@ -13041,64 +13116,591 @@ recipes: type: HONEYCOMB amount: 16 output: - kit: + waxed_copper_bars: v: 3839 ==: org.bukkit.inventory.ItemStack - type: BARREL + type: WAXED_COPPER_BARS + amount: 64 + wax_exposed_copper_bars: + production_time: 4s + name: Wax Exposed Copper Bars + type: PRODUCTION + input: + exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_BARS + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_EXPOSED_COPPER_BARS + amount: 64 + wax_weathered_copper_bars: + production_time: 4s + name: Wax Weathered Copper Bars + type: PRODUCTION + input: + weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_BARS + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_WEATHERED_COPPER_BARS + amount: 64 + wax_oxidized_copper_bars: + production_time: 4s + name: Wax Oxidized Copper Bars + type: PRODUCTION + input: + oxidized_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_BARS + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_oxidized_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_OXIDIZED_COPPER_BARS + amount: 64 + weather_copper_bars: + production_time: 4s + fuel_consumption_intervall: 2s + name: Weather Copper Bars + type: PRODUCTION + input: + copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BARS + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET amount: 1 - meta: - meta-type: UNSPECIFIC - ==: ItemMeta - display-name: Copper Workshop Repair Kit - lore: - - One kit will repair a Copper Workshop to full health. - repair_copper_workshop: + output: + exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_BARS + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_exposed_copper_bars: + production_time: 6s + fuel_consumption_intervall: 2s + name: Weather Exposed Copper Bars + type: PRODUCTION + input: + exposed_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_BARS + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_BARS + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_weathered_copper_bars: + production_time: 8s + fuel_consumption_intervall: 2s + name: Weather Weathered Copper Bars + type: PRODUCTION + input: + weathered_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_BARS + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + oxidized_copper_bars: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_BARS + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + make_copper_chain: production_time: 4s - name: Repair Factory - type: REPAIR + name: Make Copper Chain + type: PRODUCTION input: copper_block: v: 3839 ==: org.bukkit.inventory.ItemStack type: COPPER_BLOCK + amount: 3 + output: + copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_CHAIN + amount: 64 + wax_copper_chain: + production_time: 4s + name: Wax Copper Chain + type: PRODUCTION + input: + copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_CHAIN amount: 64 honeycomb: v: 3839 ==: org.bukkit.inventory.ItemStack type: HONEYCOMB amount: 16 - health_gained: 10000 - repair_copper_workshop_kit: + output: + waxed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_COPPER_CHAIN + amount: 64 + wax_exposed_copper_chain: production_time: 4s - name: Repair Factory using Repair Kit - type: REPAIR + name: Wax Exposed Copper Chain + type: PRODUCTION input: - kit: + exposed_copper_chain: v: 3839 ==: org.bukkit.inventory.ItemStack - type: BARREL - amount: 1 - meta: - meta-type: UNSPECIFIC - ==: ItemMeta - display-name: Copper Workshop Repair Kit - lore: - - One kit will repair a Copper Workshop to full health. - health_gained: 10000 - crack_fossil: - type: RANDOM - name: Crack Fossil - production_time: 1s - fuel_consumption_intervall: 4s + type: EXPOSED_COPPER_CHAIN + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_exposed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_EXPOSED_COPPER_CHAIN + amount: 64 + wax_weathered_copper_chain: + production_time: 4s + name: Wax Weathered Copper Chain + type: PRODUCTION input: - fossil: + weathered_copper_chain: v: 3839 ==: org.bukkit.inventory.ItemStack - type: PRISMARINE_SHARD - amount: 1 - meta: - meta-type: UNSPECIFIC - ==: ItemMeta + type: WEATHERED_COPPER_CHAIN + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_weathered_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_WEATHERED_COPPER_CHAIN + amount: 64 + wax_oxidized_copper_chain: + production_time: 4s + name: Wax Oxidized Copper Chain + type: PRODUCTION + input: + oxidized_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_CHAIN + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_oxidized_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_OXIDIZED_COPPER_CHAIN + amount: 64 + weather_copper_chain: + production_time: 4s + fuel_consumption_intervall: 2s + name: Weather Copper Chain + type: PRODUCTION + input: + copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_CHAIN + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + exposed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_CHAIN + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_exposed_copper_chain: + production_time: 6s + fuel_consumption_intervall: 2s + name: Weather Exposed Copper Chain + type: PRODUCTION + input: + exposed_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_CHAIN + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + weathered_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_CHAIN + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_weathered_copper_chain: + production_time: 8s + fuel_consumption_intervall: 2s + name: Weather Weathered Copper Chain + type: PRODUCTION + input: + weathered_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_CHAIN + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + oxidized_copper_chain: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_CHAIN + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + make_copper_trapdoors: + production_time: 4s + name: Make Copper Trap Doors + type: PRODUCTION + input: + copper_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BLOCK + amount: 16 + output: + copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_TRAPDOOR + amount: 64 + wax_copper_trapdoors: + production_time: 4s + name: Wax Copper Trap Doors + type: PRODUCTION + input: + copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_COPPER_TRAPDOOR + amount: 64 + wax_exposed_copper_trapdoors: + production_time: 4s + name: Wax Exposed Copper Trap Doors + type: PRODUCTION + input: + exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_EXPOSED_COPPER_TRAPDOOR + amount: 64 + wax_weathered_copper_trapdoors: + production_time: 4s + name: Wax Weathered Copper Trap Doors + type: PRODUCTION + input: + weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_WEATHERED_COPPER_TRAPDOOR + amount: 64 + wax_oxidized_copper_trapdoors: + production_time: 4s + name: Wax Oxidized Copper Trap Doors + type: PRODUCTION + input: + oxidized_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_TRAPDOOR + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + waxed_oxidized_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WAXED_OXIDIZED_COPPER_TRAPDOOR + amount: 64 + weather_copper_trapdoors: + production_time: 4s + fuel_consumption_intervall: 2s + name: Weather Copper Trap Doors + type: PRODUCTION + input: + copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_TRAPDOOR + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_TRAPDOOR + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_exposed_copper_trapdoors: + production_time: 6s + fuel_consumption_intervall: 2s + name: Weather Exposed Copper Trap Doors + type: PRODUCTION + input: + exposed_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EXPOSED_COPPER_TRAPDOOR + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_TRAPDOOR + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + weather_weathered_copper_trapdoors: + production_time: 8s + fuel_consumption_intervall: 2s + name: Weather Weathered Copper Trap Doors + type: PRODUCTION + input: + weathered_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WEATHERED_COPPER_TRAPDOOR + amount: 64 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + output: + oxidized_copper_trapdoor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: OXIDIZED_COPPER_TRAPDOOR + amount: 64 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + make_copper_workshop_kit: + production_time: 4s + name: Make Copper Workshop Repair Kit + type: PRODUCTION + input: + copper_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BLOCK + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + output: + kit: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BARREL + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Copper Workshop Repair Kit + lore: + - One kit will repair a Copper Workshop to full health. + repair_copper_workshop: + production_time: 4s + name: Repair Factory + type: REPAIR + input: + copper_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BLOCK + amount: 64 + honeycomb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HONEYCOMB + amount: 16 + health_gained: 10000 + repair_copper_workshop_kit: + production_time: 4s + name: Repair Factory using Repair Kit + type: REPAIR + input: + kit: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BARREL + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Copper Workshop Repair Kit + lore: + - One kit will repair a Copper Workshop to full health. + health_gained: 10000 + crack_fossil: + type: RANDOM + name: Crack Fossil + production_time: 1s + fuel_consumption_intervall: 4s + input: + fossil: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PRISMARINE_SHARD + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta display-name: §3Fossil lore: - Crack me in a factory for a prize! @@ -14023,33 +14625,40 @@ recipes: type: BEACON amount: 1 diamond_horse_armor: - chance: 0.00012 + chance: 0.0001 diamond_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: DIAMOND_HORSE_ARMOR amount: 1 golden_horse_armor: - chance: 0.00012 + chance: 0.0001 golden_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: GOLDEN_HORSE_ARMOR amount: 1 iron_horse_armor: - chance: 0.00012 + chance: 0.0001 iron_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: IRON_HORSE_ARMOR amount: 1 leather_horse_armor: - chance: 0.00012 + chance: 0.0001 leather_horse_armor: v: 3839 ==: org.bukkit.inventory.ItemStack type: LEATHER_HORSE_ARMOR amount: 1 + copper_horse_armor: + chance: 0.0001 + copper_horse_armor: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_HORSE_ARMOR + amount: 1 jukebox: chance: 0.0092974999 jukebox: @@ -14490,6 +15099,28 @@ recipes: ==: org.bukkit.inventory.ItemStack type: DEAD_BUSH amount: 16 + grow_dry_grass: + production_time: 4s + fuel_consumption_intervall: 1s + name: Grow dry grass + type: PRODUCTION + input: + sand: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: SAND + amount: 64 + cobweb: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COBWEB + amount: 64 + output: + short_dry_grass: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: SHORT_DRY_GRASS + amount: 32 root_dirt: production_time: 4s fuel_consumption_intervall: 1s @@ -16773,3 +17404,113 @@ recipes: type: LAPIS_BLOCK amount: 56 health_gained: 10000 + charge_wind_essence: + production_time: 4s + name: Charge Wind Essence + type: PRODUCTION + input: + wind_essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 4 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: §fWind Essence + diamond: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: DIAMOND + amount: 3 + quartz: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: QUARTZ + amount: 32 + output: + wind_charge: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WIND_CHARGE + amount: 4 + make_maces: + production_time: 4s + name: Make Maces + type: PRODUCTION + input: + breeze_rod: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREEZE_ROD + amount: 3 + heavy_core: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HEAVY_CORE + amount: 3 + output: + mace: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: MACE + amount: 5 + repair_kinetics_factory: + production_time: 4s + name: Repair Factory + type: REPAIR + input: + wind_essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 8 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: §fWind Essence + breeze_rod: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREEZE_ROD + amount: 1 + health_gained: 10000 + make_mob_repellators: + forceInclude: true + production_time: 4s + name: Make Mob Repellators + type: PRODUCTION + input: + heavy_core: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: HEAVY_CORE + amount: 1 + diamond: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: DIAMOND + amount: 64 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 24 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + output: + mob_repellator: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: FLETCHING_TABLE + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Mob Repellator + lore: + - Blocks mob spawns in a 96 block radius cylinder + amount: 4 diff --git a/ansible/files/paper-config/plugins/Finale/config.yml b/ansible/files/paper-config/plugins/Finale/config.yml index 17505f25eb..776dbeb22a 100644 --- a/ansible/files/paper-config/plugins/Finale/config.yml +++ b/ansible/files/paper-config/plugins/Finale/config.yml @@ -91,13 +91,22 @@ gapples: #allows adjusting the attack damage of any item by its spigot material identifier weaponModification: + mace: + material: MACE + damage: 6 + armourDamageMultiplier: 2 netheriteAxe: material: NETHERITE_AXE - damage: 5.75 - armourDamageMultiplier: 1.78 + damage: 6 diamondAxe: material: DIAMOND_AXE damage: 5 + copperAxe: + material: COPPER_AXE + damage: 5 + copperSword: + material: COPPER_SWORD + damage: 5 ironAxe: material: IRON_AXE damage: 4 @@ -642,3 +651,9 @@ meteoricIronSlowness: true fireworkExplosions: false rebalanceTntMinecart: true + + +mace: + cooldown: 800 + max_damage: 38 + wind_cooldown: 3 diff --git a/ansible/files/paper-config/plugins/ItemExchange/config.yml b/ansible/files/paper-config/plugins/ItemExchange/config.yml index b9b476989b..d1a83441b9 100644 --- a/ansible/files/paper-config/plugins/ItemExchange/config.yml +++ b/ansible/files/paper-config/plugins/ItemExchange/config.yml @@ -6,6 +6,13 @@ debug: false supportedBlocks: - "CHEST" - "TRAPPED_CHEST" + - "COPPER_CHEST" + - "EXPOSED_COPPER_CHEST" + - "OXIDIZED_COPPER_CHEST" + - "WEATHERED_COPPER_CHEST" + - "WAXED_COPPER_CHEST" + - "WAXED_EXPOSED_COPPER_CHEST" + - "WAXED_OXIDIZED_COPPER_CHEST" - "BARREL" - "DISPENSER" - "DROPPER" @@ -16,6 +23,13 @@ supportedBlocks: successButtonBlocks: - "CHEST" - "TRAPPED_CHEST" + - "COPPER_CHEST" + - "EXPOSED_COPPER_CHEST" + - "OXIDIZED_COPPER_CHEST" + - "WEATHERED_COPPER_CHEST" + - "WAXED_COPPER_CHEST" + - "WAXED_EXPOSED_COPPER_CHEST" + - "WAXED_OXIDIZED_COPPER_CHEST" - "BARREL" - "ENDER_CHEST" diff --git a/ansible/files/paper-config/plugins/MobLimit/config.yml b/ansible/files/paper-config/plugins/MobLimit/config.yml index 33e5348b99..8f7410440f 100644 --- a/ansible/files/paper-config/plugins/MobLimit/config.yml +++ b/ansible/files/paper-config/plugins/MobLimit/config.yml @@ -1,6 +1,10 @@ chunk: -1 global: -1 reasons: + build_coppergolem: + copper_golem: + count: 6 + radius: 32 breeding: pig: dumb: true diff --git a/ansible/files/paper-config/plugins/MythicMobs/RandomSpawns/BleezeSpawns.yml b/ansible/files/paper-config/plugins/MythicMobs/RandomSpawns/BleezeSpawns.yml new file mode 100644 index 0000000000..62a94d1e23 --- /dev/null +++ b/ansible/files/paper-config/plugins/MythicMobs/RandomSpawns/BleezeSpawns.yml @@ -0,0 +1,11 @@ +RandomBleeze: + Type: Bleeze + Worlds: world + Chance: 0.002 + Priority: 1 + Action: REPLACE + Biomes: DESERT,ERODED_BADLANDS,SAVANNA,SAVANNA_PLATEAU,BADLANDS + Conditions: + - outside true + - heightabove{h=30} true + - blockTypeInRadius{type=OBSIDIAN;amount=>0;radius=5} false diff --git a/ansible/files/paper-config/plugins/MythicMobs/RandomSpawns/ExampleRandomSpawns.yml b/ansible/files/paper-config/plugins/MythicMobs/RandomSpawns/ExampleRandomSpawns.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/files/paper-config/plugins/MythicMobs/mobs/Bleeze.yml b/ansible/files/paper-config/plugins/MythicMobs/mobs/Bleeze.yml new file mode 100644 index 0000000000..2c4045f663 --- /dev/null +++ b/ansible/files/paper-config/plugins/MythicMobs/mobs/Bleeze.yml @@ -0,0 +1,56 @@ +Bleeze: + Type: BLAZE + Display: '&4&lBleeze' + Health: 600 + Damage: 16 + Drops: + - heavy_core 1 0.5 + Skills: + - setvariable{var=caster.minions;type=INTEGER;val=0} @self ~onSpawn + - geyser{type=LAVA;height=3;speed=40} @target 0.05 + - skill{s=WitherFire} @PlayersInRadius{r=25} ~onTimer:300 0.4 + - skill{s=BreezeMinionSwarm} @self 0.1 + - skill{s=BreezeAttack} @target 0.2 + - recoil{r=30;pitch=-1to1} @target 0.05 + - damage{amount=25} @trigger ~onBowHit + - projectile{onTick=Fireball-Tick;onHit=Fireball-Hit;v=8;i=1;hR=1;vR=1;hnp=true} @target 0.1 + - projectile{onTick=Fireball-Tick;onHit=Fireball-Hit;v=8;i=1;hR=1;vR=1;hnp=true} @target ~onTimer:60 0.3 + - skill{s=BreezePull} @self 0.1 + BossBar: + Enabled: true + Title: '&4&lBleeze' + Range: 25 + Color: RED + Style: SOLID + Options: + AlwaysShowName: true + MaxCombatDistance: 25 + PreventOtherDrops: true + KnockbackResistance: 0.1 + Despawn: NEVER + DigOutOfGround: true + DamageModifiers: + - PROJECTILE 0.25 + +BleezeMinion: + Type: BREEZE + Health: 120 + Drops: + - paper{name="Wind Essence"} 0-5 + - breeze_rod 1 0.2 + Skills: + - geyser{type=LAVA;height=2;speed=20} @target 0.01 + - skill{s=BreezeMinionAttack} @target 0.2 + - damage{amount=16} @trigger ~onBowHit + - ignite{ticks=40} @trigger ~onBowHit + - projectile{onTick=Fireball-Tick-Weak;onHit=Fireball-Hit-Weak;v=8;i=1;hR=1;vR=1;hnp=true} @target ~onTimer:120 0.3 + Options: + MaxCombatDistance: 25 + PreventOtherDrops: true + Despawn: NEVER + DigOutOfGround: true + DamageModifiers: + - FIRE 0 + - LAVA 0 + - FIRE_TICK 0 + - PROJECTILE 0.5 diff --git a/ansible/files/paper-config/plugins/MythicMobs/skills/BleezeSkills.yml b/ansible/files/paper-config/plugins/MythicMobs/skills/BleezeSkills.yml new file mode 100644 index 0000000000..fb47fd11fb --- /dev/null +++ b/ansible/files/paper-config/plugins/MythicMobs/skills/BleezeSkills.yml @@ -0,0 +1,62 @@ +WitherFire: + CancelIfNoTargets: true + TargetConditions: + - isburning true + Cooldown: 1 + Skills: + - potion{type=WITHER;duration=100;level=2} @target +BreezeAttack: + Cooldown: 8 + Conditions: + - targetwithin{d=25} + Skills: + - teleport @target + - effect:sound{s=mob.endermen.portal;volume=1.0;pitch=0.5} + - delay 10 + - damage{amount=12;ignorearmor=true} @PlayersInRadius{r=5} + - throw{velocity=10;velocityY=5} @PlayersInRadius{r=5} + - effect:explosion @Self +BreezePull: + Cooldown: 15 + Skills: + - forcepull{spread=5} @PlayersInRadius{r=30} + - damage{amount=5;ignorearmor=true} @PlayersInRadius{r=30} + - ignite{ticks=200} @PlayersInRadius{r=30} +BreezeMinionSwarm: + Cooldown: 30 + Conditions: + - variableinrange{var=caster.minions;value=<21} + Skills: + - variableadd{var=caster.minions;amount=3} + - summon{mob=BleezeMinion;amount=1;noise=5} @Self + - delay 20 + - summon{mob=BleezeMinion;amount=1;noise=5} @Self + - delay 20 + - summon{mob=BleezeMinion;amount=1;noise=5} @Self +BreezeMinionAttack: + Cooldown: 12 + Conditions: + - targetwithin{d=25} + Skills: + - damage{amount=16;ignorearmor=true} @target + - throw{velocity=10;velocityY=15} @target + - effect:explosion @Self + - ignite{ticks=100} @target + +Fireball-Tick: + Skills: + - effect:particles{p=lava;amount=6;speed=0;hS=0.2;vS=0.2} @origin +Fireball-Hit: + Skills: + - damage{amount=40} + - potion{type=SLOW;duration=100;lvl=2} + - ignite{ticks=100} @target + +Fireball-Tick-Weak: + Skills: + - effect:particles{p=lava;amount=4;speed=0;hS=0.2;vS=0.2} @origin +Fireball-Hit-Weak: + Skills: + - damage{amount=30} + - potion{type=SLOW;duration=100;lvl=2} + - ignite{ticks=100} @target diff --git a/ansible/files/paper-config/plugins/SimpleAdminHacks/config.yml b/ansible/files/paper-config/plugins/SimpleAdminHacks/config.yml index 0ab2de2882..ebd8563ffc 100644 --- a/ansible/files/paper-config/plugins/SimpleAdminHacks/config.yml +++ b/ansible/files/paper-config/plugins/SimpleAdminHacks/config.yml @@ -340,6 +340,14 @@ hacks: minDepthToMatch: 2 watchedMaterials: - CHEST + - TRAPPED_CHEST + - COPPER_CHEST + - EXPOSED_COPPER_CHEST + - OXIDIZED_COPPER_CHEST + - WEATHERED_COPPER_CHEST + - WAXED_COPPER_CHEST + - WAXED_EXPOSED_COPPER_CHEST + - WAXED_OXIDIZED_COPPER_CHEST - FURNACE - JUKEBOX - NOTE_BLOCK @@ -497,6 +505,7 @@ hacks: - ==: org.bukkit.inventory.ItemStack type: COOKIE amount: 32 + v: 3839 meta: ==: ItemMeta meta-type: UNSPECIFIC @@ -504,8 +513,9 @@ hacks: - "Gift from the Admins as you" - "begin your journey on CivMC" - ==: org.bukkit.inventory.ItemStack - type: BED + type: RED_BED amount: 1 + v: 3839 meta: ==: ItemMeta meta-type: UNSPECIFIC @@ -514,8 +524,9 @@ hacks: - "Be sure to get a good night's" - "rest soon." - ==: org.bukkit.inventory.ItemStack - type: BOAT + type: OAK_BOAT amount: 1 + v: 3839 meta: ==: ItemMeta meta-type: UNSPECIFIC @@ -524,6 +535,7 @@ hacks: - ==: org.bukkit.inventory.ItemStack type: MINECART amount: 1 + v: 3839 meta: ==: ItemMeta meta-type: UNSPECIFIC @@ -620,10 +632,18 @@ hacks: Trowel: enabled: true MobCulling: - enabled: false - turtleAllowance: 100 + enabled: true + turtleAllowance: 200 turtleMaxAge: 360000 - striderAllowance: 100 + striderAllowance: 200 striderMaxAge: 360000 NetheriteCrafting: enabled: true + NameLocker: + enabled: true + BrewIndex: + enabled: true + ServerLinksHack: + enabled: true + discordUrl: https://discord.gg/civmc + patreonUrl: https://patreon.com/Civ_MC diff --git a/ansible/files/paper-config/plugins/SuperVanish/config.yml b/ansible/files/paper-config/plugins/SuperVanish/config.yml index 0ab791a7b0..39ce1e71c6 100644 --- a/ansible/files/paper-config/plugins/SuperVanish/config.yml +++ b/ansible/files/paper-config/plugins/SuperVanish/config.yml @@ -3,7 +3,7 @@ ############# Invisibility Features ############## InvisibilityFeatures: # Should invisible players get night vision? (client-side; Requires ProtocolLib) - NightVisionEffect: true + NightVisionEffect: false # Should SV disable damage for invisible players? DisableDamage: true # Should SV disable hunger for invisible players? diff --git a/ansible/files/paper-config/plugins/TAB/config.yml b/ansible/files/paper-config/plugins/TAB/config.yml index 28d8c8264e..09551c712b 100644 --- a/ansible/files/paper-config/plugins/TAB/config.yml +++ b/ansible/files/paper-config/plugins/TAB/config.yml @@ -10,7 +10,7 @@ header-footer: - '&9Modmail at &6reddit.com/r/civmc' - '&a%tps% TPS &r&6discord.gg/nDnsU6vJqg' - '&cPatreon: &6patreon.com/Civ_MC' - - '&6Admins: Wingzero54, RedDevel, Okx, HaKr_' + - '&6Admins: Wingzero54, RedDevel, Okx' per-world: world1: header: diff --git a/ansible/files/paper-config/server.properties b/ansible/files/paper-config/server.properties index f960322983..1be2a1f5bd 100644 --- a/ansible/files/paper-config/server.properties +++ b/ansible/files/paper-config/server.properties @@ -57,4 +57,4 @@ enforce-secure-profile=false resource-pack-sha1= spawn-protection=0 max-world-size=29999984 -enable-code-of-conduct=true +enable-code-of-conduct=false diff --git a/ansible/files/paper-config/spigot.yml b/ansible/files/paper-config/spigot.yml index 924df58696..0cc21b4b43 100644 --- a/ansible/files/paper-config/spigot.yml +++ b/ansible/files/paper-config/spigot.yml @@ -102,7 +102,7 @@ world-settings: entity-tracking-range: players: 160 animals: 64 - monsters: 32 + monsters: 48 misc: 96 other: 96 ticks-per: diff --git a/ansible/files/pvp-config/asp-server.jar b/ansible/files/pvp-config/asp-server.jar index e979860848..4a7af878f1 100644 Binary files a/ansible/files/pvp-config/asp-server.jar and b/ansible/files/pvp-config/asp-server.jar differ diff --git a/ansible/files/pvp-config/plugins/Finale/config.yml b/ansible/files/pvp-config/plugins/Finale/config.yml index abdeb40de4..bc4214ac3a 100644 --- a/ansible/files/pvp-config/plugins/Finale/config.yml +++ b/ansible/files/pvp-config/plugins/Finale/config.yml @@ -91,13 +91,22 @@ gapples: #allows adjusting the attack damage of any item by its spigot material identifier weaponModification: + mace: + material: MACE + damage: 6 + armourDamageMultiplier: 2 netheriteAxe: material: NETHERITE_AXE - damage: 5.75 - armourDamageMultiplier: 1.78 + damage: 6 diamondAxe: material: DIAMOND_AXE damage: 5 + copperAxe: + material: COPPER_AXE + damage: 5 + copperSword: + material: COPPER_SWORD + damage: 5 ironAxe: material: IRON_AXE damage: 4 @@ -642,3 +651,8 @@ meteoricIronSlowness: true fireworkExplosions: true rebalanceTntMinecart: true + +mace: + cooldown: 800 + max_damage: 38 + wind_cooldown: 3 diff --git a/ansible/files/pvp-config/plugins/SimpleAdminHacks/config.yml b/ansible/files/pvp-config/plugins/SimpleAdminHacks/config.yml index 0c52aed7b2..ca742031e0 100644 --- a/ansible/files/pvp-config/plugins/SimpleAdminHacks/config.yml +++ b/ansible/files/pvp-config/plugins/SimpleAdminHacks/config.yml @@ -312,18 +312,11 @@ hacks: ############################################################ BadBoyWatch: # tracks players breaking these blocks and logs information - enabled: true + enabled: false trackingDepth: 16 clearOnMatch: true minDepthToMatch: 2 - watchedMaterials: - - CHEST - - FURNACE - - JUKEBOX - - NOTE_BLOCK - - BEACON - - SPONGE - - HOPPER + watchedMaterials: [] CTAnnounce: enabled: true delay: 10000 @@ -591,3 +584,11 @@ hacks: enabled: false NetheriteCrafting: enabled: true + NameLocker: + enabled: true + BrewIndex: + enabled: true + ServerLinksHack: + enabled: true + discordUrl: https://discord.gg/civmc + patreonUrl: https://patreon.com/Civ_MC diff --git a/ansible/files/pvp-config/plugins/SuperVanish/config.yml b/ansible/files/pvp-config/plugins/SuperVanish/config.yml index 0ab791a7b0..39ce1e71c6 100644 --- a/ansible/files/pvp-config/plugins/SuperVanish/config.yml +++ b/ansible/files/pvp-config/plugins/SuperVanish/config.yml @@ -3,7 +3,7 @@ ############# Invisibility Features ############## InvisibilityFeatures: # Should invisible players get night vision? (client-side; Requires ProtocolLib) - NightVisionEffect: true + NightVisionEffect: false # Should SV disable damage for invisible players? DisableDamage: true # Should SV disable hunger for invisible players? diff --git a/ansible/files/pvp-config/plugins/TAB/config.yml b/ansible/files/pvp-config/plugins/TAB/config.yml index 18282114ac..c3e6016bef 100644 --- a/ansible/files/pvp-config/plugins/TAB/config.yml +++ b/ansible/files/pvp-config/plugins/TAB/config.yml @@ -10,7 +10,7 @@ header-footer: - '&9Modmail at &6reddit.com/r/civmc' - '&a%tps% TPS &r&6discord.gg/nDnsU6vJqg' - '&cPatreon: &6patreon.com/Civ_MC' - - '&6Admins: Wingzero54, RedDevel, Okx, HaKr_' + - '&6Admins: Wingzero54, RedDevel, Okx' per-world: {} # https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Tablist-name-formatting diff --git a/ansible/src/gamma-plugins/BreweryX-3.6.3.jar b/ansible/src/gamma-plugins/BreweryX-3.6.3.jar new file mode 120000 index 0000000000..1fc600a1fb --- /dev/null +++ b/ansible/src/gamma-plugins/BreweryX-3.6.3.jar @@ -0,0 +1 @@ +../paper-plugins/BreweryX-3.6.3.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/CraftEnhance-2.6.0.0.jar b/ansible/src/gamma-plugins/CraftEnhance-2.6.0.0.jar deleted file mode 120000 index 64dd16e2af..0000000000 --- a/ansible/src/gamma-plugins/CraftEnhance-2.6.0.0.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/CraftEnhance-2.6.0.0.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/CraftEnhance-2.6.0.1.jar b/ansible/src/gamma-plugins/CraftEnhance-2.6.0.1.jar new file mode 120000 index 0000000000..edc50b12a3 --- /dev/null +++ b/ansible/src/gamma-plugins/CraftEnhance-2.6.0.1.jar @@ -0,0 +1 @@ +../paper-plugins/CraftEnhance-2.6.0.1.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/Insights-6.19.7.jar b/ansible/src/gamma-plugins/Insights-6.19.7.jar deleted file mode 120000 index 84a42c6f0a..0000000000 --- a/ansible/src/gamma-plugins/Insights-6.19.7.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/Insights-6.19.7.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/Insights-6.20.2.jar b/ansible/src/gamma-plugins/Insights-6.20.2.jar new file mode 120000 index 0000000000..4547812f1d --- /dev/null +++ b/ansible/src/gamma-plugins/Insights-6.20.2.jar @@ -0,0 +1 @@ +../paper-plugins/Insights-6.20.2.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/MythicMobs-5.11.2.jar b/ansible/src/gamma-plugins/MythicMobs-5.11.2.jar new file mode 120000 index 0000000000..57a8ccec69 --- /dev/null +++ b/ansible/src/gamma-plugins/MythicMobs-5.11.2.jar @@ -0,0 +1 @@ +../paper-plugins/MythicMobs-5.11.2.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/TAB v5.2.5.jar b/ansible/src/gamma-plugins/TAB v5.2.5.jar deleted file mode 120000 index 8f6e4d480b..0000000000 --- a/ansible/src/gamma-plugins/TAB v5.2.5.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/TAB v5.2.5.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/TAB v5.5.0.jar b/ansible/src/gamma-plugins/TAB v5.5.0.jar new file mode 120000 index 0000000000..169e33cdf9 --- /dev/null +++ b/ansible/src/gamma-plugins/TAB v5.5.0.jar @@ -0,0 +1 @@ +../paper-plugins/TAB v5.5.0.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/ViaBackwards-5.6.0.jar b/ansible/src/gamma-plugins/ViaBackwards-5.6.0.jar deleted file mode 120000 index 637808307a..0000000000 --- a/ansible/src/gamma-plugins/ViaBackwards-5.6.0.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/ViaBackwards-5.6.0.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/ViaBackwards-5.8.1.jar b/ansible/src/gamma-plugins/ViaBackwards-5.8.1.jar new file mode 120000 index 0000000000..6a39bb8858 --- /dev/null +++ b/ansible/src/gamma-plugins/ViaBackwards-5.8.1.jar @@ -0,0 +1 @@ +../paper-plugins/ViaBackwards-5.8.1.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/ViaVersion-5.6.0.jar b/ansible/src/gamma-plugins/ViaVersion-5.6.0.jar deleted file mode 120000 index 48b7a01d44..0000000000 --- a/ansible/src/gamma-plugins/ViaVersion-5.6.0.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/ViaVersion-5.6.0.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/ViaVersion-5.8.1.jar b/ansible/src/gamma-plugins/ViaVersion-5.8.1.jar new file mode 120000 index 0000000000..3026516623 --- /dev/null +++ b/ansible/src/gamma-plugins/ViaVersion-5.8.1.jar @@ -0,0 +1 @@ +../paper-plugins/ViaVersion-5.8.1.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/orebfuscator-plugin-5.5.4.jar b/ansible/src/gamma-plugins/orebfuscator-plugin-5.5.4.jar deleted file mode 120000 index 697da6fe10..0000000000 --- a/ansible/src/gamma-plugins/orebfuscator-plugin-5.5.4.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/orebfuscator-plugin-5.5.4.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/orebfuscator-plugin.jar b/ansible/src/gamma-plugins/orebfuscator-plugin.jar new file mode 120000 index 0000000000..c299f79245 --- /dev/null +++ b/ansible/src/gamma-plugins/orebfuscator-plugin.jar @@ -0,0 +1 @@ +../paper-plugins/orebfuscator-plugin.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/packetevents-spigot-2.11.2.jar b/ansible/src/gamma-plugins/packetevents-spigot-2.11.2.jar new file mode 120000 index 0000000000..d3fc91ea53 --- /dev/null +++ b/ansible/src/gamma-plugins/packetevents-spigot-2.11.2.jar @@ -0,0 +1 @@ +../paper-plugins/packetevents-spigot-2.11.2.jar \ No newline at end of file diff --git a/ansible/src/gamma-plugins/worldedit-bukkit-7.3.16.jar b/ansible/src/gamma-plugins/worldedit-bukkit-7.3.16.jar deleted file mode 120000 index 0f32ace369..0000000000 --- a/ansible/src/gamma-plugins/worldedit-bukkit-7.3.16.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/worldedit-bukkit-7.3.16.jar \ No newline at end of file diff --git a/ansible/src/paper-plugins/BreweryX-3.6.0.jar b/ansible/src/paper-plugins/BreweryX-3.6.0.jar deleted file mode 100644 index 1cb8598b10..0000000000 Binary files a/ansible/src/paper-plugins/BreweryX-3.6.0.jar and /dev/null differ diff --git a/ansible/src/gamma-plugins/BreweryX-3.6.0.jar b/ansible/src/paper-plugins/BreweryX-3.6.3.jar similarity index 87% rename from ansible/src/gamma-plugins/BreweryX-3.6.0.jar rename to ansible/src/paper-plugins/BreweryX-3.6.3.jar index 1cb8598b10..ac84b7cd89 100644 Binary files a/ansible/src/gamma-plugins/BreweryX-3.6.0.jar and b/ansible/src/paper-plugins/BreweryX-3.6.3.jar differ diff --git a/ansible/src/paper-plugins/CraftEnhance-2.6.0.0.jar b/ansible/src/paper-plugins/CraftEnhance-2.6.0.1.jar similarity index 65% rename from ansible/src/paper-plugins/CraftEnhance-2.6.0.0.jar rename to ansible/src/paper-plugins/CraftEnhance-2.6.0.1.jar index 67d90ea5e8..34d1eb3b0f 100644 Binary files a/ansible/src/paper-plugins/CraftEnhance-2.6.0.0.jar and b/ansible/src/paper-plugins/CraftEnhance-2.6.0.1.jar differ diff --git a/ansible/src/paper-plugins/DiscordSRV-Build-1.30.0.jar b/ansible/src/paper-plugins/DiscordSRV-Build-1.30.4.jar similarity index 89% rename from ansible/src/paper-plugins/DiscordSRV-Build-1.30.0.jar rename to ansible/src/paper-plugins/DiscordSRV-Build-1.30.4.jar index ab4ab92bfb..c5af6c27a3 100644 Binary files a/ansible/src/paper-plugins/DiscordSRV-Build-1.30.0.jar and b/ansible/src/paper-plugins/DiscordSRV-Build-1.30.4.jar differ diff --git a/ansible/src/paper-plugins/Insights-6.19.7.jar b/ansible/src/paper-plugins/Insights-6.20.2.jar similarity index 72% rename from ansible/src/paper-plugins/Insights-6.19.7.jar rename to ansible/src/paper-plugins/Insights-6.20.2.jar index dc61aa2b27..861d324ce5 100644 Binary files a/ansible/src/paper-plugins/Insights-6.19.7.jar and b/ansible/src/paper-plugins/Insights-6.20.2.jar differ diff --git a/ansible/src/paper-plugins/InvSee++.jar b/ansible/src/paper-plugins/InvSee++.jar index 638d47f784..e4fc8e2975 100644 Binary files a/ansible/src/paper-plugins/InvSee++.jar and b/ansible/src/paper-plugins/InvSee++.jar differ diff --git a/ansible/src/paper-plugins/MythicMobs-5.11.2.jar b/ansible/src/paper-plugins/MythicMobs-5.11.2.jar new file mode 100644 index 0000000000..0fb0b1d2aa Binary files /dev/null and b/ansible/src/paper-plugins/MythicMobs-5.11.2.jar differ diff --git a/ansible/src/paper-plugins/ProtocolLib.jar b/ansible/src/paper-plugins/ProtocolLib.jar index 0db5bc6d17..2200ac0434 100644 Binary files a/ansible/src/paper-plugins/ProtocolLib.jar and b/ansible/src/paper-plugins/ProtocolLib.jar differ diff --git a/ansible/src/paper-plugins/TAB v5.2.5.jar b/ansible/src/paper-plugins/TAB v5.5.0.jar similarity index 53% rename from ansible/src/paper-plugins/TAB v5.2.5.jar rename to ansible/src/paper-plugins/TAB v5.5.0.jar index b2ff7808fb..460a124e58 100644 Binary files a/ansible/src/paper-plugins/TAB v5.2.5.jar and b/ansible/src/paper-plugins/TAB v5.5.0.jar differ diff --git a/ansible/src/paper-plugins/ViaBackwards-5.6.0.jar b/ansible/src/paper-plugins/ViaBackwards-5.8.1.jar similarity index 62% rename from ansible/src/paper-plugins/ViaBackwards-5.6.0.jar rename to ansible/src/paper-plugins/ViaBackwards-5.8.1.jar index 4c31689e99..db31cb5d3a 100644 Binary files a/ansible/src/paper-plugins/ViaBackwards-5.6.0.jar and b/ansible/src/paper-plugins/ViaBackwards-5.8.1.jar differ diff --git a/ansible/src/paper-plugins/ViaVersion-5.6.0.jar b/ansible/src/paper-plugins/ViaVersion-5.8.1.jar similarity index 79% rename from ansible/src/paper-plugins/ViaVersion-5.6.0.jar rename to ansible/src/paper-plugins/ViaVersion-5.8.1.jar index 9693bc7729..e03b4b2bac 100644 Binary files a/ansible/src/paper-plugins/ViaVersion-5.6.0.jar and b/ansible/src/paper-plugins/ViaVersion-5.8.1.jar differ diff --git a/ansible/src/paper-plugins/orebfuscator-plugin-5.5.4.jar b/ansible/src/paper-plugins/orebfuscator-plugin-5.5.4.jar deleted file mode 100644 index e8f7c42565..0000000000 Binary files a/ansible/src/paper-plugins/orebfuscator-plugin-5.5.4.jar and /dev/null differ diff --git a/ansible/src/paper-plugins/orebfuscator-plugin.jar b/ansible/src/paper-plugins/orebfuscator-plugin.jar new file mode 100644 index 0000000000..62682a6e86 Binary files /dev/null and b/ansible/src/paper-plugins/orebfuscator-plugin.jar differ diff --git a/ansible/src/paper-plugins/packetevents-spigot-2.11.2.jar b/ansible/src/paper-plugins/packetevents-spigot-2.11.2.jar new file mode 100644 index 0000000000..dffab79430 Binary files /dev/null and b/ansible/src/paper-plugins/packetevents-spigot-2.11.2.jar differ diff --git a/ansible/src/paper-plugins/worldedit-bukkit-7.3.16.jar b/ansible/src/paper-plugins/worldedit-bukkit-7.4.0.jar similarity index 52% rename from ansible/src/paper-plugins/worldedit-bukkit-7.3.16.jar rename to ansible/src/paper-plugins/worldedit-bukkit-7.4.0.jar index bb9e8e6b3a..9ed5396f52 100644 Binary files a/ansible/src/paper-plugins/worldedit-bukkit-7.3.16.jar and b/ansible/src/paper-plugins/worldedit-bukkit-7.4.0.jar differ diff --git a/ansible/src/proxy-plugins/ajQueue-2.9.0-all.jar b/ansible/src/proxy-plugins/ajQueue-2.9.0-all.jar new file mode 100644 index 0000000000..686bae0e3e Binary files /dev/null and b/ansible/src/proxy-plugins/ajQueue-2.9.0-all.jar differ diff --git a/ansible/src/pvp-plugins/BreweryX-3.6.0.jar b/ansible/src/pvp-plugins/BreweryX-3.6.0.jar deleted file mode 100644 index 1cb8598b10..0000000000 Binary files a/ansible/src/pvp-plugins/BreweryX-3.6.0.jar and /dev/null differ diff --git a/ansible/src/pvp-plugins/BreweryX-3.6.3.jar b/ansible/src/pvp-plugins/BreweryX-3.6.3.jar new file mode 120000 index 0000000000..1fc600a1fb --- /dev/null +++ b/ansible/src/pvp-plugins/BreweryX-3.6.3.jar @@ -0,0 +1 @@ +../paper-plugins/BreweryX-3.6.3.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/TAB v5.2.5.jar b/ansible/src/pvp-plugins/TAB v5.2.5.jar deleted file mode 120000 index 8f6e4d480b..0000000000 --- a/ansible/src/pvp-plugins/TAB v5.2.5.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/TAB v5.2.5.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/TAB v5.5.0.jar b/ansible/src/pvp-plugins/TAB v5.5.0.jar new file mode 120000 index 0000000000..169e33cdf9 --- /dev/null +++ b/ansible/src/pvp-plugins/TAB v5.5.0.jar @@ -0,0 +1 @@ +../paper-plugins/TAB v5.5.0.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/ViaBackwards-5.6.0.jar b/ansible/src/pvp-plugins/ViaBackwards-5.6.0.jar deleted file mode 120000 index 637808307a..0000000000 --- a/ansible/src/pvp-plugins/ViaBackwards-5.6.0.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/ViaBackwards-5.6.0.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/ViaBackwards-5.8.1.jar b/ansible/src/pvp-plugins/ViaBackwards-5.8.1.jar new file mode 120000 index 0000000000..6a39bb8858 --- /dev/null +++ b/ansible/src/pvp-plugins/ViaBackwards-5.8.1.jar @@ -0,0 +1 @@ +../paper-plugins/ViaBackwards-5.8.1.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/ViaVersion-5.6.0.jar b/ansible/src/pvp-plugins/ViaVersion-5.6.0.jar deleted file mode 120000 index 48b7a01d44..0000000000 --- a/ansible/src/pvp-plugins/ViaVersion-5.6.0.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/ViaVersion-5.6.0.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/ViaVersion-5.8.1.jar b/ansible/src/pvp-plugins/ViaVersion-5.8.1.jar new file mode 120000 index 0000000000..3026516623 --- /dev/null +++ b/ansible/src/pvp-plugins/ViaVersion-5.8.1.jar @@ -0,0 +1 @@ +../paper-plugins/ViaVersion-5.8.1.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/asp-plugin-4.0.0-SNAPSHOT.jar b/ansible/src/pvp-plugins/asp-plugin-4.2.0-SNAPSHOT.jar similarity index 66% rename from ansible/src/pvp-plugins/asp-plugin-4.0.0-SNAPSHOT.jar rename to ansible/src/pvp-plugins/asp-plugin-4.2.0-SNAPSHOT.jar index 1441d730db..ffe96c737a 100644 Binary files a/ansible/src/pvp-plugins/asp-plugin-4.0.0-SNAPSHOT.jar and b/ansible/src/pvp-plugins/asp-plugin-4.2.0-SNAPSHOT.jar differ diff --git a/ansible/src/pvp-plugins/packetevents-spigot-2.11.2.jar b/ansible/src/pvp-plugins/packetevents-spigot-2.11.2.jar new file mode 120000 index 0000000000..d3fc91ea53 --- /dev/null +++ b/ansible/src/pvp-plugins/packetevents-spigot-2.11.2.jar @@ -0,0 +1 @@ +../paper-plugins/packetevents-spigot-2.11.2.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/worldedit-bukkit-7.3.16.jar b/ansible/src/pvp-plugins/worldedit-bukkit-7.3.16.jar deleted file mode 120000 index 0f32ace369..0000000000 --- a/ansible/src/pvp-plugins/worldedit-bukkit-7.3.16.jar +++ /dev/null @@ -1 +0,0 @@ -../paper-plugins/worldedit-bukkit-7.3.16.jar \ No newline at end of file diff --git a/ansible/src/pvp-plugins/worldedit-bukkit-7.4.0.jar b/ansible/src/pvp-plugins/worldedit-bukkit-7.4.0.jar new file mode 100644 index 0000000000..9ed5396f52 Binary files /dev/null and b/ansible/src/pvp-plugins/worldedit-bukkit-7.4.0.jar differ diff --git a/ansible/src/pvp-plugins/worldguard-bukkit-7.0.14-dist.jar b/ansible/src/pvp-plugins/worldguard-bukkit-7.0.15.jar similarity index 89% rename from ansible/src/pvp-plugins/worldguard-bukkit-7.0.14-dist.jar rename to ansible/src/pvp-plugins/worldguard-bukkit-7.0.15.jar index 8658cb0035..d655d6507a 100644 Binary files a/ansible/src/pvp-plugins/worldguard-bukkit-7.0.14-dist.jar and b/ansible/src/pvp-plugins/worldguard-bukkit-7.0.15.jar differ diff --git a/ansible/templates/stacks/minecraft.yml.j2 b/ansible/templates/stacks/minecraft.yml.j2 index 392b811578..cf86864a11 100644 --- a/ansible/templates/stacks/minecraft.yml.j2 +++ b/ansible/templates/stacks/minecraft.yml.j2 @@ -3,7 +3,7 @@ version: '3.8' services: waterfall: - image: itzg/mc-proxy:java24 + image: itzg/mc-proxy:java25 restart: unless-stopped tty: true stdin_open: true @@ -24,7 +24,7 @@ services: protocol: udp mode: host environment: - VELOCITY_VERSION: '3.4.0-SNAPSHOT' + VELOCITY_VERSION: '3.5.0-SNAPSHOT' TYPE: 'VELOCITY' REPLACE_ENV_VARIABLES: 'true' @@ -55,13 +55,12 @@ services: # Config & Plugins - /opt/stacks/minecraft/proxy-config:/config - /opt/stacks/minecraft/proxy-plugins:/plugins - - /opt/PrivateConfig/proxy/plugins/ajQueue-2.9.0-all.jar:/config/plugins/ajQueue-2.9.0-all.jar - /opt/PrivateConfig/proxy/config/nuvotifier/config.toml:/config/plugins/nuvotifier/config.toml - /opt/PrivateConfig/proxy/config/nuvotifier/rsa/public.key:/config/plugins/nuvotifier/rsa/public.key - /opt/PrivateConfig/proxy/config/nuvotifier/rsa/private.key:/config/plugins/nuvotifier/rsa/private.key paper: - image: itzg/minecraft-server:stable-java24-graalvm + image: itzg/minecraft-server:stable-java25 restart: unless-stopped tty: true stdin_open: true @@ -75,9 +74,9 @@ services: mode: host environment: TYPE: 'paper' - VERSION: '1.21.8' + VERSION: '1.21.11' EULA: 'TRUE' - PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.8/builds/156/downloads/leaf-1.21.8-156.jar' + PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.11/builds/62/downloads/leaf-1.21.11-62.jar' REMOVE_OLD_MODS: 'TRUE' COPY_CONFIG_DEST: '/data' @@ -88,7 +87,6 @@ services: INIT_MEMORY: '{{setting.minecraft.resources.memory}}' MAX_MEMORY: '{{setting.minecraft.resources.memory}}' USE_MEOWICE_FLAGS: 'TRUE' - USE_MEOWICE_GRAALVM_FLAGS: 'TRUE' STOP_DURATION: 3600 CIV_SECUREBOOT_ENABLE: 'true' @@ -130,7 +128,8 @@ services: - /opt/stacks/minecraft/paper-plugins:/plugins # Private Config & Plugins - /opt/PrivateConfig/paper/plugins/Vulcan.jar:/config/plugins/Vulcan.jar - - /opt/PrivateConfig/paper/plugins/packetevents-spigot-2.10.1.jar:/config/plugins/packetevents-spgiot-2.10.1.jar + - /opt/PrivateConfig/paper/plugins/NM.jar:/config/plugins/NM.jar + - /opt/PrivateConfig/paper/config/NM/config.yml:/config/plugins/NM/config.yml - /opt/PrivateConfig/paper/config/Vulcan/config.yml:/config/plugins/Vulcan/config.yml - /opt/PrivateConfig/paper/config/HiddenOre/config.yml:/config/plugins/HiddenOre/config.yml - /opt/PrivateConfig/paper/config/KiraBukkitGateway/config.yml:/config/plugins/KiraBukkitGateway/config.yml @@ -141,7 +140,6 @@ services: - /opt/PrivateConfig/paper/config/Terra/packs/CivMC:/config/plugins/Terra/packs/CivMC - /opt/PrivateConfig/paper/config/DiscordSRV/config.yml:/config/plugins/DiscordSRV/config.yml - /opt/PrivateConfig/paper/config/DiscordSRV/alerts.yml:/config/plugins/DiscordSRV/alerts.yml - - /opt/PrivateConfig/paper/config/MythicMobs:/config/plugins/MythicMobs - /opt/PrivateConfig/paper/config/EvenMoreFish/baits:/config/plugins/EvenMoreFish/baits - /opt/PrivateConfig/paper/config/EvenMoreFish/rods:/config/plugins/EvenMoreFish/rods - /opt/PrivateConfig/paper/config/EvenMoreFish/rarities:/config/plugins/EvenMoreFish/rarities @@ -159,7 +157,7 @@ services: memory: '{{setting.minecraft.resources.memory_limit}}' gamma: - image: itzg/minecraft-server:stable-java24-graalvm + image: itzg/minecraft-server:stable-java25 restart: unless-stopped tty: true stdin_open: true @@ -177,9 +175,9 @@ services: mode: host environment: TYPE: 'paper' - VERSION: '1.21.8' + VERSION: '1.21.11' EULA: 'TRUE' - PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.8/builds/156/downloads/leaf-1.21.8-156.jar' + PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.11/builds/62/downloads/leaf-1.21.11-62.jar' REMOVE_OLD_MODS: 'TRUE' COPY_CONFIG_DEST: '/data' @@ -190,7 +188,6 @@ services: INIT_MEMORY: '{{setting.minecraft.resources.gamma_memory}}' MAX_MEMORY: '{{setting.minecraft.resources.gamma_memory}}' USE_MEOWICE_FLAGS: 'TRUE' - USE_MEOWICE_GRAALVM_FLAGS: 'TRUE' STOP_DURATION: 3600 CIV_SECUREBOOT_ENABLE: 'true' @@ -237,7 +234,6 @@ services: - /opt/PrivateConfig/gamma/config/Heliodor/config.yml:/config/plugins/Heliodor/config.yml - /opt/PrivateConfig/gamma/config/HiddenOre/config.yml:/config/plugins/HiddenOre/config.yml - /opt/PrivateConfig/paper/plugins/Vulcan.jar:/config/plugins/Vulcan.jar - - /opt/PrivateConfig/paper/plugins/packetevents-spigot-2.10.1.jar:/config/plugins/packetevents-spgiot-2.10.1.jar - /opt/PrivateConfig/paper/config/Vulcan/config.yml:/config/plugins/Vulcan/config.yml - /opt/PrivateConfig/gamma/config/BreweryX/config.yml:/config/plugins/BreweryX/config.yml - /opt/PrivateConfig/gamma/config/BreweryX/cauldron.yml:/config/plugins/BreweryX/cauldron.yml @@ -257,7 +253,7 @@ services: memory: '{{setting.minecraft.resources.gamma_memory_limit}}' pvp: - image: itzg/minecraft-server:stable-java24-graalvm + image: itzg/minecraft-server:stable-java25 restart: unless-stopped tty: true stdin_open: true @@ -271,7 +267,7 @@ services: mode: host environment: TYPE: 'paper' - VERSION: '1.21.8' + VERSION: '1.21.11' EULA: 'TRUE' PAPER_CUSTOM_JAR: 'asp-server.jar' @@ -284,7 +280,6 @@ services: INIT_MEMORY: '{{setting.minecraft.resources.pvp_memory}}' MAX_MEMORY: '{{setting.minecraft.resources.pvp_memory}}' USE_MEOWICE_FLAGS: 'TRUE' - USE_MEOWICE_GRAALVM_FLAGS: 'TRUE' STOP_DURATION: 3600 CIV_SERVER_NAME: prod-server @@ -323,7 +318,6 @@ services: - /opt/stacks/minecraft/pvp-plugins:/plugins # Private Config & Plugins - /opt/PrivateConfig/paper/plugins/Vulcan.jar:/config/plugins/Vulcan.jar - - /opt/PrivateConfig/paper/plugins/packetevents-spigot-2.10.1.jar:/config/plugins/packetevents-spgiot-2.10.1.jar - /opt/PrivateConfig/paper/config/Vulcan/config.yml:/config/plugins/Vulcan/config.yml - /opt/PrivateConfig/paper/config/BreweryX/config.yml:/config/plugins/BreweryX/config.yml - /opt/PrivateConfig/paper/config/BreweryX/cauldron.yml:/config/plugins/BreweryX/cauldron.yml diff --git a/build.gradle.kts b/build.gradle.kts index e385c3b9d2..7b18a7a670 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,6 +21,7 @@ allprojects { repositories { mavenCentral() + maven(url = "https://mvn.lumine.io/repository/maven-public/") maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://repo.papermc.io/repository/maven-public/") maven("https://oss.sonatype.org/content/repositories/snapshots") @@ -29,7 +30,6 @@ allprojects { maven("https://repo.codemc.io/repository/maven-public/") maven("https://repo.dmulloy2.net/repository/public") maven("https://repo.infernalsuite.com/repository/maven-snapshots/") - maven("https://repo.rapture.pw/repository/maven-releases/") maven("https://jitpack.io") maven("https://repo.ajg0702.us/releases") } diff --git a/containers/provisioning/mariadb/docker-entrypoint-initdb.d/0100_create_databases.sql b/containers/provisioning/mariadb/docker-entrypoint-initdb.d/0100_create_databases.sql index 7968b1f0c8..a8805155ae 100755 --- a/containers/provisioning/mariadb/docker-entrypoint-initdb.d/0100_create_databases.sql +++ b/containers/provisioning/mariadb/docker-entrypoint-initdb.d/0100_create_databases.sql @@ -13,6 +13,7 @@ CREATE DATABASE exilepearl; CREATE DATABASE realisticbiomes; CREATE DATABASE heliodor; CREATE DATABASE nameapi; +CREATE DATABASE civproxy; GRANT ALL PRIVILEGES ON `donum`.* TO 'mariadb'@'%'; GRANT ALL PRIVILEGES ON `banstick`.* TO 'mariadb'@'%'; @@ -29,6 +30,7 @@ GRANT ALL PRIVILEGES ON `exilepearl`.* TO 'mariadb'@'%'; GRANT ALL PRIVILEGES ON `realisticbiomes`.* TO 'mariadb'@'%'; GRANT ALL PRIVILEGES ON `heliodor`.* TO 'mariadb'@'%'; GRANT ALL PRIVILEGES ON `nameapi`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `civproxy`.* TO 'mariadb'@'%'; CREATE DATABASE pvp_civduties; CREATE DATABASE pvp_civmodcore; diff --git a/docker-compose.private.yml b/docker-compose.private.yml index 8b56c2363e..30eae54205 100644 --- a/docker-compose.private.yml +++ b/docker-compose.private.yml @@ -9,10 +9,7 @@ services: proxy: environment: - REMOVE_OLD_MODS_EXCLUDE: "ajQueue-2.9.0-all.jar" SYNC_SKIP_NEWER_IN_DESTINATION: "true" - volumes: - - ./PrivateConfig/proxy/plugins/ajQueue-2.9.0-all.jar:/config/plugins/ajQueue-2.9.0-all.jar paper: environment: diff --git a/docker-compose.yml b/docker-compose.yml index 0a53906483..e196cd6aa6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: ################# proxy: - image: itzg/mc-proxy:java24 + image: itzg/mc-proxy:java25 restart: on-failure tty: true stdin_open: true @@ -17,8 +17,10 @@ services: condition: service_healthy postgres: condition: service_healthy + rabbitmq: + condition: service_healthy environment: - VELOCITY_VERSION: '3.4.0-SNAPSHOT' + VELOCITY_VERSION: '3.5.0-SNAPSHOT' TYPE: 'VELOCITY' REMOVE_OLD_MODS: 'TRUE' @@ -30,6 +32,10 @@ services: CIV_POSTGRES_USERNAME: postgres CIV_POSTGRES_PASSWORD: postgres + CIV_RABBITMQ_HOST: rabbitmq + CIV_RABBITMQ_USERNAME: rabbitmq + CIV_RABBITMQ_PASSWORD: rabbitmq + CIV_TIMEOUT_TIME: 3000000 CIV_PVP_HOSTNAME: 'pvp.localhost' CIV_GAMMA_HOSTNAME: 'mini.localhost' @@ -40,15 +46,18 @@ services: CIV_MYSQL_HOST: mariadb CIV_MYSQL_USERNAME: mariadb CIV_MYSQL_PASSWORD: mariadb + + JVM_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5008 ports: - "25565:25577" + - "5008:5008" volumes: - ./containers/data/proxy:/server - ./ansible/files/proxy-config:/config - ./ansible/build/proxy-plugins:/plugins paper: - image: itzg/minecraft-server:stable-java24-graalvm + image: itzg/minecraft-server:stable-java25 restart: on-failure tty: true stdin_open: true @@ -57,11 +66,13 @@ services: condition: service_healthy postgres: condition: service_healthy + rabbitmq: + condition: service_healthy environment: TYPE: 'paper' - VERSION: '1.21.8' + VERSION: '1.21.11' EULA: 'TRUE' - PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.8/builds/156/downloads/leaf-1.21.8-156.jar' + PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.11/builds/62/downloads/leaf-1.21.11-62.jar' REMOVE_OLD_MODS: 'TRUE' COPY_CONFIG_DEST: '/data' @@ -87,6 +98,10 @@ services: CIV_DATABASE_PREFIX: '' + CIV_RABBITMQ_HOST: rabbitmq + CIV_RABBITMQ_USERNAME: rabbitmq + CIV_RABBITMQ_PASSWORD: rabbitmq + CIV_SECUREBOOT_ENABLE: 'false' JVM_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 @@ -100,7 +115,7 @@ services: - ./ansible/build/paper-plugins:/plugins gamma: - image: itzg/minecraft-server:stable-java24-graalvm + image: itzg/minecraft-server:stable-java25 restart: on-failure tty: true stdin_open: true @@ -109,11 +124,13 @@ services: condition: service_healthy postgres: condition: service_healthy + rabbitmq: + condition: service_healthy environment: TYPE: 'paper' - VERSION: '1.21.8' + VERSION: '1.21.11' EULA: 'TRUE' - PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.8/builds/156/downloads/leaf-1.21.8-156.jar' + PAPER_DOWNLOAD_URL: 'https://api.leafmc.one/v2/projects/leaf/versions/1.21.11/builds/62/downloads/leaf-1.21.11-62.jar' REMOVE_OLD_MODS: 'TRUE' COPY_CONFIG_DEST: '/data' @@ -139,6 +156,10 @@ services: CIV_DATABASE_PREFIX: 'gamma_' + CIV_RABBITMQ_HOST: rabbitmq + CIV_RABBITMQ_USERNAME: rabbitmq + CIV_RABBITMQ_PASSWORD: rabbitmq + JVM_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5007 CIV_WATCHDOG_TIMEOUT_TIME: 6000 CIV_FORWARDING_SECRET: '1234' @@ -150,7 +171,7 @@ services: - ./ansible/build/gamma-plugins:/plugins pvp: - image: itzg/minecraft-server:stable-java24-graalvm + image: itzg/minecraft-server:stable-java25 restart: on-failure tty: true stdin_open: true @@ -159,9 +180,11 @@ services: condition: service_healthy postgres: condition: service_healthy + rabbitmq: + condition: service_healthy environment: TYPE: 'paper' - VERSION: '1.21.8' + VERSION: '1.21.11' EULA: 'TRUE' PAPER_CUSTOM_JAR: 'asp-server.jar' @@ -188,6 +211,10 @@ services: CIV_DATABASE_PREFIX: 'pvp_' + CIV_RABBITMQ_HOST: rabbitmq + CIV_RABBITMQ_USERNAME: rabbitmq + CIV_RABBITMQ_PASSWORD: rabbitmq + JVM_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006 CIV_WATCHDOG_TIMEOUT_TIME: 6000 CIV_FORWARDING_SECRET: '1234' @@ -244,6 +271,23 @@ services: - ./containers/provisioning/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro - ./containers/data/postgres:/var/lib/postgresql/data + rabbitmq: + image: rabbitmq:3.9.16-management + restart: on-failure + healthcheck: + test: [ "CMD", "rabbitmq-diagnostics", "ping" ] + interval: 60s + timeout: 10s + retries: 5 + start_period: 40s + start_interval: 5s + ports: + - "5672:5672" + - "15672:15672" + environment: + RABBITMQ_DEFAULT_USER: rabbitmq + RABBITMQ_DEFAULT_PASS: rabbitmq + ################## ### Monitoring ### ################## diff --git a/docs/wiki/index.md b/docs/wiki/index.md index 7691d24f66..606d4ad2c9 100644 --- a/docs/wiki/index.md +++ b/docs/wiki/index.md @@ -51,6 +51,7 @@ Below are explanations on the plugins CivMC uses, and detailed information about * [Heliodor](./plugins/unique/heliodor) - Unique high value resource and its various uses. * [Transport Changes](./plugins/unique/Transport) - Faster rails, copper rails, faster horses and disabled elytras. * [Chunk Limits](./plugins/unique/chunklimits) - Limits how many things you can place in a chunk, e.g. redstone. +* [Bleeze](./plugins/unique/bleeze) - Mini boss to obtain maces #### __Recreational__ diff --git a/docs/wiki/plugins/fun/brewery.md b/docs/wiki/plugins/fun/brewery.md index fd4892ed87..c8dfb059c6 100644 --- a/docs/wiki/plugins/fun/brewery.md +++ b/docs/wiki/plugins/fun/brewery.md @@ -494,14 +494,19 @@ or by way of donating a high amount to the server via patreon. | Leo's Orange Creamsicle | 6 | 8 | 800023 | | Colton's Love Martini | 3 | 8 | 800024 | | Golden Pick Stout | 4 | 7 | 800025 | -| Katz Catnip Kaffee 6 | 8 | 8 | 800026 | +| Katz Catnip Kaffe | 8 | 8 | 800026 | | Astro's Pill | 6 | 7 | 800027 | | Jeremy's Slippy-Sloppy Screwdriver | 3 | 8 | 800028 | | Trizzzx's Worcestershire sauce | 4 | 8 | 800029 | | StrawBeary Dreams | 6 | 8 | 800030 | | Pisco Sour | 3 | 6 | 800031 | - - +| OmaKnight's Melomel | 4 | 7 | 800032 | +| Turtle Tea | 4 | 8 | 800033 | +| Doktah's Lucky Brew | 2 | 8 | 800034 | +| Lalibo's Volcanic Margarita | 4 | 7 | 800035 | +| Hallucinnefo | 5 | 7 | 800036 | +| OreSprayer Stubby | 4 | 7 | 800037 | + ## List of Custom Ingredients | # | Name | Texture ID | diff --git a/docs/wiki/plugins/unique/bleeze.md b/docs/wiki/plugins/unique/bleeze.md new file mode 100644 index 0000000000..ed9f59d677 --- /dev/null +++ b/docs/wiki/plugins/unique/bleeze.md @@ -0,0 +1,21 @@ +--- +title: Bleeze +description: Mini boss to get maces and wind charges +--- + +# Bleeze +The bleeze is a flying mini-boss that can be found in hot, arid environments, such as deserts or savanna. It is no easy fight! Be sure to bring potions! + +The bleeze will summon breezes which drop wind essence and breeze rods. The wind essence can be used in a **Kinetics Factory** to craft wind charges. + +![Wind charge recipe](media/wind.png) + +Wind charges have a cooldown of 3 seconds compared to half a second in vanilla + +Each bleeze also has a guaranteed heavy core drop. Bleezes will never spawn in the rain and will leave this world if it ever starts raining! + +# Mace + +Maces can be crafted with one breeze rod and one wind charge, or more efficiently in the Kinetics Factory. Their damage is capped at approximately 9 blocks of fall height (5.5 hearts vs full netherite with strength 2) + +Maces deal 2x damage to armour, and have a 60-second cooldown. diff --git a/docs/wiki/plugins/unique/media/wind.png b/docs/wiki/plugins/unique/media/wind.png new file mode 100644 index 0000000000..e6aceecbc9 Binary files /dev/null and b/docs/wiki/plugins/unique/media/wind.png differ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fa2938765b..dfc20f9c10 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -paper = "1.21.8-R0.1-SNAPSHOT" -junit = "5.8.2" +paper = "1.21.11-R0.1-SNAPSHOT" +junit = "6.0.3" nuotifier = "2.7.2" velocity = "3.4.0-SNAPSHOT" configurate = "4.2.0" @@ -38,16 +38,25 @@ aswm-api = { group = "com.infernalsuite.asp", name = "api", version = "4.0.0-SNA worldedit = { group = "com.sk89q.worldedit", name = "worldedit-bukkit", version = "7.2.8" } hikaricp = { group = "com.zaxxer", name = "HikariCP", version = "5.0.1" } fastutil = { group = "it.unimi.dsi", name = "fastutil", version = "8.5.8" } -protocollib = { group = "com.comphenix.protocol", name = "ProtocolLib", version = "5.3.0" } +protocollib = { group = "net.dmulloy2", name = "ProtocolLib", version = "5.4.0" } barapi = { group = "me.confuser", name = "BarAPI", version = "3.5" } ipaddress = { group = "com.github.seancfoley", name = "ipaddress", version = "2.0.2" } jsoup = { group = "org.jsoup", name = "jsoup", version = "1.18.3" } junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" } junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit" } +junit-platform-launcher = { group = "org.junit.platform", name = "junit-platform-launcher", version.ref = "junit" } +mockbukkit = { group = "org.mockbukkit.mockbukkit", name = "mockbukkit-v1.21", version = "4.108.0" } slf4j-api = { group = "org.slf4j", name = "slf4j-api", version = "2.0.17" } +mythic-dist = { group = "io.lumine", name = "Mythic-Dist", version = "5.6.1" } +packetevents-spigot = { group = "com.github.retrooper", name = "packetevents-spigot", version = "2.11.2" } +placeholderapi = { group = "me.clip", name = "placeholderapi", version = "2.11.6" } +rtree2 = { group = "com.github.davidmoten", name = "rtree2", version = "0.9.3" } +ajQueue-api = { group = "us.ajg0702.queue.api", name = "api", version = "2.8.0" } +mariadb-client = { group = "org.mariadb.jdbc", name = "mariadb-java-client", version = "3.5.6" } + [bundles] -junit = ["junit-api", "junit-engine"] +junit = ["junit-api", "junit-engine", "junit-platform-launcher"] nuvotifier = ["nuvotifier-api", "nuvotifier-bukkit"] diff --git a/libraries/name-api/build.gradle.kts b/libraries/name-api/build.gradle.kts index b7af74bf37..d3836cb7bd 100644 --- a/libraries/name-api/build.gradle.kts +++ b/libraries/name-api/build.gradle.kts @@ -8,6 +8,6 @@ version = "1.0.0" dependencies { api(libs.hikaricp) api(libs.configurate.yaml) - api("org.mariadb.jdbc:mariadb-java-client:3.5.6") + api(libs.mariadb.client) implementation(libs.slf4j.api) } diff --git a/libraries/name-api/src/main/java/net/civmc/nameapi/Migrator.java b/libraries/name-api/src/main/java/net/civmc/nameapi/Migrator.java index 44312605de..15aa952a84 100644 --- a/libraries/name-api/src/main/java/net/civmc/nameapi/Migrator.java +++ b/libraries/name-api/src/main/java/net/civmc/nameapi/Migrator.java @@ -56,9 +56,10 @@ public void migrate(Connection connection) throws SQLException { } if (maxId != minId) { - PreparedStatement setMigrationId = connection.prepareStatement("REPLACE INTO migations (namespace, id) VALUES (?, ?)"); + PreparedStatement setMigrationId = connection.prepareStatement("REPLACE INTO migrations (namespace, id) VALUES (?, ?)"); setMigrationId.setString(1, entry.getKey()); setMigrationId.setInt(2, maxId); + setMigrationId.executeUpdate(); } } connection.setAutoCommit(true); diff --git a/plugins/bastion-paper/build.gradle.kts b/plugins/bastion-paper/build.gradle.kts index 360c479c3a..df786c0b0b 100644 --- a/plugins/bastion-paper/build.gradle.kts +++ b/plugins/bastion-paper/build.gradle.kts @@ -12,4 +12,5 @@ dependencies { compileOnly(project(":plugins:civmodcore-paper")) compileOnly(project(":plugins:namelayer-paper")) compileOnly(project(":plugins:citadel-paper")) + compileOnly(libs.mythic.dist) } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java b/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java index a121c8288f..20f3f77aec 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java @@ -8,6 +8,7 @@ import isaac.bastion.listeners.BastionInteractListener; import isaac.bastion.listeners.CitadelListener; import isaac.bastion.listeners.ElytraListener; +import isaac.bastion.listeners.MobListener; import isaac.bastion.listeners.ModeListener; import isaac.bastion.listeners.NameLayerListener; import isaac.bastion.manager.BastionBlockManager; @@ -15,10 +16,12 @@ import isaac.bastion.storage.BastionGroupStorage; import isaac.bastion.storage.Database; import isaac.bastion.utils.BastionSettingManager; +import java.util.ArrayList; import java.util.LinkedList; import java.util.logging.Level; import org.bukkit.configuration.ConfigurationSection; import vg.civcraft.mc.civmodcore.ACivMod; +import vg.civcraft.mc.civmodcore.commands.CommandManager; import vg.civcraft.mc.civmodcore.dao.DatabaseCredentials; import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; import vg.civcraft.mc.namelayer.GroupManager.PlayerType; @@ -32,6 +35,7 @@ public final class Bastion extends ACivMod { private static BastionGroupStorage groupStorage; private static BastionSettingManager settingManager; private static CommonSettings commonSettings; + private CommandManager commandManager; @Override public void onEnable() { @@ -69,6 +73,8 @@ private void registerListeners() { getServer().getPluginManager().registerEvents(new BastionDamageListener(), this); getServer().getPluginManager().registerEvents(new BastionInteractListener(), this); getServer().getPluginManager().registerEvents(new ElytraListener(), this); + MobListener mobListener = new MobListener(blockManager); + getServer().getPluginManager().registerEvents(mobListener, this); getServer().getPluginManager().registerEvents(new BastionBreakListener(blockStorage, blockManager), this); getServer().getPluginManager().registerEvents(new NameLayerListener(blockStorage), this); getServer().getPluginManager().registerEvents(new CitadelListener(), this); @@ -113,9 +119,11 @@ private void setupDatabase() { //Sets up the command managers private void setupCommands() { - getCommand("Bastion").setExecutor(new BastionCommandManager()); + commandManager = new CommandManager(this); + commandManager.getCommandCompletions().registerCompletion("bastionTypes", + context -> new ArrayList<>(BastionType.getTypeNames())); + commandManager.registerCommand(new BastionCommandManager()); getCommand("bsi").setExecutor(new ModeChangeCommand(Mode.INFO)); - getCommand("bsd").setExecutor(new ModeChangeCommand(Mode.DELETE)); getCommand("bso").setExecutor(new ModeChangeCommand(Mode.NORMAL)); getCommand("bsb").setExecutor(new ModeChangeCommand(Mode.BASTION)); getCommand("bsf").setExecutor(new ModeChangeCommand(Mode.OFF)); diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java index 51d6fab445..bc030438a7 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java @@ -2,6 +2,8 @@ import java.util.LinkedHashMap; import java.util.List; +import java.util.SequencedMap; +import java.util.Set; import java.util.logging.Level; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; @@ -10,51 +12,54 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; -public class BastionType { +public class BastionType implements Comparable { - private static LinkedHashMap types = new LinkedHashMap<>(); + private static final SequencedMap types = new LinkedHashMap<>(); private static String defaultType; private static int maxRadius = 0; - private String name; - private String itemName; - private List lore; - private String shortName; - private boolean square; - private int effectRadius; - private int radiusSquared; - private boolean includeY; - private int startScaleFactor; - private double finalScaleFactor; - private long warmupTime; - private int erosionTime; - private long placementCooldown; - private boolean destroyOnRemove; - private boolean onlyDirectDestruction; - private boolean blockPearls; - private boolean blockMidair; - private int pearlScale; - private boolean pearlRequireMature; - private boolean consumeOnBlock; - private int blocksToErode; - private boolean blockElytra; - private boolean destroyElytra; - private boolean damageElytra; - private int elytraScale; - private boolean elytraRequireMature; - private boolean explodeOnBlock; - private double explodeOnBlockStrength; - private boolean damageFirstBastion; - private int regenTime; - private boolean allowPearlingOut; - private boolean blockReinforcements; - private Material material; - private boolean destroyOnRemoveWhileImmature; - private int proximityDamageRange; - private double proximityDamageFactor; - - private String overLayName; + private final String name; + private final String itemName; + private final List lore; + private final String shortName; + private final boolean square; + private final int effectRadius; + private final int radiusSquared; + private final boolean includeY; + private final int startScaleFactor; + private final double finalScaleFactor; + private final long warmupTime; + private final int erosionTime; + private final long placementCooldown; + private final boolean destroyOnRemove; + private final boolean onlyDirectDestruction; + private final boolean blockPearls; + private final boolean blockMidair; + private final int pearlScale; + private final boolean pearlRequireMature; + private final boolean consumeOnBlock; + private final int blocksToErode; + private final boolean blockElytra; + private final boolean destroyElytra; + private final boolean damageElytra; + private final int elytraScale; + private final boolean elytraRequireMature; + private final boolean explodeOnBlock; + private final double explodeOnBlockStrength; + private final boolean damageFirstBastion; + private final int regenTime; + private final boolean allowPearlingOut; + private final boolean blockReinforcements; + private final boolean blockMobs; + private final Material material; + private final boolean destroyOnRemoveWhileImmature; + private final int proximityDamageRange; + private final double proximityDamageFactor; + private final boolean blockLiquids; + + private final String overlayName; public BastionType( String name, @@ -92,7 +97,8 @@ public BastionType( boolean destroyOnRemoveWhileImmature, int proximityDamageRange, double proximityDamageFactor, - String overLayName + String overlayName, + boolean blockMobs, boolean blockLiquids ) { this.name = name; this.material = material; @@ -130,9 +136,11 @@ public BastionType( this.destroyOnRemoveWhileImmature = destroyOnRemoveWhileImmature; this.proximityDamageFactor = proximityDamageFactor; this.proximityDamageRange = proximityDamageRange; - this.overLayName = overLayName; + this.overlayName = overlayName; + this.blockMobs = blockMobs; maxRadius = effectRadius > maxRadius ? effectRadius : maxRadius; + this.blockLiquids = blockLiquids; } /** @@ -196,7 +204,7 @@ public boolean canPearlOut() { * @return Name to use in HUD to describe type */ public String getOverlayName() { - return overLayName; + return overlayName; } /** @@ -374,6 +382,10 @@ public boolean isBlockReinforcements() { return blockReinforcements; } + public boolean isBlockMobs() { + return blockMobs; + } + @Override public int hashCode() { return name.hashCode(); @@ -381,8 +393,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { - if (!(obj instanceof BastionType)) return false; - BastionType other = (BastionType) obj; + if (!(obj instanceof BastionType other)) return false; return other.getName().equals(name); } @@ -488,6 +499,17 @@ public boolean isDestroyOnRemoveWhileImmature() { return destroyOnRemoveWhileImmature; } + public boolean isBlockLiquids() { + return blockLiquids; + } + + /** + * @return The names of all registered bastion types + */ + public static Set getTypeNames() { + return types.keySet(); + } + /** * @return The default bastion type */ @@ -553,11 +575,15 @@ public static BastionType getBastionType(ConfigurationSection config) { double explodeOnBlockStrength = config.getDouble("elytra.explodeOnBlockStrength"); boolean destroyOnRemoveWhileImmature = config.getBoolean("destroyOnRemoveWhileImmature", true); String overlayName = config.getString("overlay_name"); + + boolean blockMobs = config.getBoolean("blockMobs", false); + boolean blockLiquids = config.getBoolean("blockLiquids", true); + return new BastionType(name, itemName, material, lore, shortName, square, effectRadius, includeY, startScaleFactor, finalScaleFactor, warmupTime, erosionTime, placementCooldown, destroyOnRemove, blockPearls, blockMidair, scaleFactor, requireMaturity, consumeOnBlock, blocksToErode, blockElytra, destroyElytra, damageElytra, elytraScale, elytraRequireMature, explodeOnBlock, explodeOnBlockStrength, damageFirstBastion, regenTime, onlyDirectDestroy, allowPearlingOut, blockReinforcements, destroyOnRemoveWhileImmature, - proximityDamageRange, proximityDamageFactor, overlayName); + proximityDamageRange, proximityDamageFactor, overlayName, blockMobs, blockLiquids); } @Override @@ -587,4 +613,9 @@ public String toString() { sb.append("]"); return sb.toString(); } + + @Override + public int compareTo(@NotNull BastionType o) { + return name.compareTo(o.name); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java index 405a858d53..261de60344 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java @@ -1,46 +1,43 @@ package isaac.bastion.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandCompletion; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Default; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.Subcommand; +import co.aikar.commands.annotation.Syntax; import isaac.bastion.Bastion; -import java.io.InputStream; -import java.util.Scanner; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; +import isaac.bastion.BastionType; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; -public class BastionCommandManager implements CommandExecutor { - - @Override - public boolean onCommand(CommandSender sender, Command command, - String label, String[] args) { - if (args.length > 0) { - if (args[0].equalsIgnoreCase("License")) { - InputStream input = getClass().getResourceAsStream("/License.txt"); - sender.sendMessage(convertStreamToString(input)); - return true; - } else if (args[0].equalsIgnoreCase("about")) { - sender.sendMessage(ChatColor.GREEN + "Bastion version " + Bastion.getPlugin().getDescription().getVersion()); - return true; - } - } - return false; +@CommandAlias("bastion") +public class BastionCommandManager extends BaseCommand { + @Subcommand("about") + @Description("Shows Bastion version information.") + @Default + public void about(final CommandSender sender) { + sender.sendMessage(Component.text("Bastion version " + Bastion.getPlugin().getPluginMeta().getVersion(), NamedTextColor.GREEN)); } - @SuppressWarnings("resource") - public static String convertStreamToString(InputStream is) { - if (is == null) { - return ""; - } - Scanner s = new Scanner(is).useDelimiter("\\A"); - String ret = ""; - try { - ret = s.hasNext() ? s.next() : ""; - } catch (IllegalStateException ise) { - ret = ""; - } finally { - s.close(); - ret = ""; + @Subcommand("give") + @Description("Gives a bastion of the specified type.") + @Syntax("") + @CommandCompletion("@bastionTypes") + @CommandPermission("Bastion.admin") + public void give(final Player player, final String typeName) { + BastionType type = BastionType.getBastionType(typeName); + if (type == null) { + player.sendMessage(Component.text("Unknown bastion type: " + typeName, NamedTextColor.RED)); + return; } - return ret; + ItemStack item = type.getItemRepresentation(); + player.getInventory().addItem(item); + player.sendMessage(Component.text("Gave 1 " + type.getName() + " bastion.", NamedTextColor.GREEN)); } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java index c5f4801a8b..9805f11662 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java @@ -10,7 +10,7 @@ public class PlayersStates { static public enum Mode { - NORMAL, INFO, DELETE, OFF, BASTION, MATURE + NORMAL, INFO, OFF, BASTION, MATURE } static private Map playersModes = new HashMap<>(); diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java index 2af0080a94..4f589408a6 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java @@ -9,6 +9,7 @@ import java.util.Iterator; import java.util.logging.Level; import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.ExplosionResult; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -79,8 +80,11 @@ public void onBlockBreak(BlockBreakEvent event) { } } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEntityExplode(EntityExplodeEvent event) { + if (event.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK || event.getExplosionResult() == ExplosionResult.KEEP) { + return; + } Iterator iterator = event.blockList().iterator(); HashSet blocks = new HashSet<>(); while (iterator.hasNext()) { diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java index d1827bae01..62bc9f550e 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java @@ -12,6 +12,8 @@ import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; @@ -19,6 +21,8 @@ import org.bukkit.block.BlockState; import org.bukkit.block.data.type.Dispenser; import org.bukkit.entity.EnderPearl; +import org.bukkit.entity.Player; +import org.bukkit.entity.WindCharge; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -28,6 +32,7 @@ import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -118,11 +123,15 @@ private void handlePistonEvent(BlockPistonEvent event, List blocks) { public void onBucketEmpty(PlayerBucketEmptyEvent event) { Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getBlock().getLocation(), event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); - if (!blocking.isEmpty()) { + for (BastionBlock bastion : blocking) { + if (!bastion.getType().isBlockLiquids()) { + continue; + } event.setCancelled(true); if (!Bastion.getSettingManager().getIgnorePlacementMessages(event.getPlayer().getUniqueId())) { event.getPlayer().sendMessage(ChatColor.RED + "Emptying bucket prevented by Bastion"); } + break; } } @@ -148,6 +157,52 @@ public void onDispense(BlockDispenseEvent event) { } } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void handleWind(ProjectileLaunchEvent event) { + if (!(event.getEntity() instanceof WindCharge charge)) { + return; + } + if (!(charge.getShooter() instanceof Player player) || player.hasPermission("Bastion.bypass")) { + return; + } + + Location location = event.getEntity().getLocation(); + Set blocking = blockManager.getBlockingBastionsWithoutPermission(location, player.getUniqueId(), + PermissionType.getPermission(Permissions.BASTION_PEARL)); + + blocking.removeIf(bastion -> bastion.getType().isOnlyDirectDestruction() || !bastion.getType().isBlockPearls() + || (bastion.getType().isRequireMaturity() && !bastion.isMature())); + + if (!blocking.isEmpty()) { + player.sendMessage(Component.text("Wind charge blocked by Bastion Block", NamedTextColor.RED)); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void handleWind(ExplosionPrimeEvent event) { + if (!(event.getEntity() instanceof WindCharge charge)) { + return; + } + if (!(charge.getShooter() instanceof Player player) || player.hasPermission("Bastion.bypass")) { + return; + } + + Location location = event.getEntity().getLocation(); + Set blocking = blockManager.getBlockingBastionsWithoutPermission(location, player.getUniqueId(), + PermissionType.getPermission(Permissions.BASTION_PEARL)); + + blocking.removeIf(bastion -> bastion.getType().isOnlyDirectDestruction() || !bastion.getType().isBlockPearls() + || (bastion.getType().isRequireMaturity() && !bastion.isMature())); + + if (!blocking.isEmpty()) { + player.sendMessage(Component.text("Wind charge blocked by Bastion Block", NamedTextColor.RED)); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void handleEnderPearlLanded(PlayerTeleportEvent event) { if (event.getCause() != TeleportCause.ENDER_PEARL) { diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java index dec2b73d8d..f8e311ddc8 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java @@ -85,19 +85,6 @@ public void onBlockClicked(PlayerInteractEvent event) { TextComponent toSend = blockManager.infoMessageComponent(dev, block.getRelative(event.getBlockFace()), block, player); player.spigot().sendMessage(toSend); - } else if (PlayersStates.playerInMode(player, Mode.DELETE)) { - BastionBlock bastionBlock = blockStorage.getBastionBlock(block.getLocation()); - - if (bastionBlock == null) { - return; - } - - if (bastionBlock.canRemove(player)) { - TextComponent toSend = blockManager.bastionDeletedMessageComponent(bastionBlock); - bastionBlock.destroy(); - player.spigot().sendMessage(toSend); - event.setCancelled(true); - } } else if (PlayersStates.playerInMode(player, Mode.MATURE)) { BastionBlock bastionBlock = blockStorage.getBastionBlock(block.getLocation()); diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/MobListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/MobListener.java new file mode 100644 index 0000000000..02e6aa8c9a --- /dev/null +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/MobListener.java @@ -0,0 +1,74 @@ +package isaac.bastion.listeners; + +import com.destroystokyo.paper.event.entity.EntityPathfindEvent; +import com.destroystokyo.paper.event.entity.SlimePathfindEvent; +import io.lumine.mythic.bukkit.events.MythicMobSpawnEvent; +import isaac.bastion.BastionBlock; +import isaac.bastion.manager.BastionBlockManager; +import java.util.Set; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Slime; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; + +public class MobListener implements Listener { + + private final BastionBlockManager blockManager; + + public MobListener(BastionBlockManager blockManager) { + this.blockManager = blockManager; + } + + // Fix for https://git.lumine.io/mythiccraft/MythicMobs/-/issues/2158, otherwise only one listener would be necessary + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void on(MythicMobSpawnEvent event) { + if (!event.getMobType().getInternalName().equals("Bleeze")) { + return; + } + Set preblocking = blockManager.getBlockingBastions(event.getLocation(), b -> b.getType().isBlockMobs() && b.isMature()); + if (preblocking.isEmpty()) { + return; + } + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void on(CreatureSpawnEvent event) { + if (event.getSpawnReason() != CreatureSpawnEvent.SpawnReason.NATURAL) { + return; + } + if (!(event.getEntity() instanceof Monster)) { + return; + } + Set preblocking = blockManager.getBlockingBastions(event.getLocation(), b -> b.getType().isBlockMobs() && b.isMature()); + if (preblocking.isEmpty()) { + return; + } + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onEntityPathfind(EntityPathfindEvent event) { + if (!(event.getEntity() instanceof Monster)) { + return; + } + Set blocking = blockManager.getBlockingBastions(event.getLoc(), b -> b.getType().isBlockMobs() && b.isMature()); + if (blocking.isEmpty()) { + return; + } + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onSlimePathfind(SlimePathfindEvent event) { + Slime slime = event.getEntity(); + Set blocking = blockManager.getBlockingBastions(slime.getLocation(), b -> b.getType().isBlockMobs() && b.isMature()); + if (blocking.isEmpty()) { + return; + } + event.setCancelled(true); + } +} diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java index f1128d83dc..8546975a85 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java @@ -6,10 +6,11 @@ import isaac.bastion.Permissions; import isaac.bastion.utils.BastionSettingManager; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -107,37 +108,41 @@ private void updateDisplayedInformation(Player player, Location location) { } return; } - Set alliedBastions = new HashSet<>(); - Set enemyBastions = new HashSet<>(); + + SortedMap alliedBastions = new TreeMap<>(); + SortedMap enemyBastions = new TreeMap<>(); for (BastionBlock bastion : bastionBlocks) { if (NameLayerAPI.getGroupManager().hasAccess(bastion.getGroup(), player.getUniqueId(), placePerm)) { - alliedBastions.add(bastion.getType()); + alliedBastions.merge(bastion.getType(), bastion.isMature(), Boolean::logicalAnd); } else { - enemyBastions.add(bastion.getType()); + enemyBastions.merge(bastion.getType(), bastion.isMature(), Boolean::logicalAnd); } } if (!alliedBastions.isEmpty() && !enemyBastions.isEmpty()) { updateDisplaySetting(player, String.format("%s%sConflict Bastion %s[%s] %s[%s]", ChatColor.YELLOW, ChatColor.BOLD, - ChatColor.GREEN, buildBastionTypeList(alliedBastions), ChatColor.RED, - buildBastionTypeList(enemyBastions))); + ChatColor.GREEN, buildBastionTypeList(alliedBastions, ChatColor.GREEN), + ChatColor.RED, buildBastionTypeList(enemyBastions, ChatColor.RED))); return; } if (!alliedBastions.isEmpty()) { updateDisplaySetting(player, - String.format("%sAlly Bastion [%s]", ChatColor.GREEN, buildBastionTypeList(alliedBastions))); + String.format("%sAlly Bastion [%s]", ChatColor.GREEN, buildBastionTypeList(alliedBastions, ChatColor.GREEN))); return; } - updateDisplaySetting(player, String.format("%s%sEnemy Bastion [%s]", ChatColor.RED, ChatColor.BOLD, - buildBastionTypeList(enemyBastions))); + updateDisplaySetting(player, String.format("%s%sHostile Bastion [%s]", ChatColor.RED, ChatColor.BOLD, + buildBastionTypeList(enemyBastions, ChatColor.RED))); } - private String buildBastionTypeList(Set types) { + private String buildBastionTypeList(SortedMap types, ChatColor baseColor) { List identifiers = new ArrayList<>(); - for (BastionType type : types) { - identifiers.add(type.getOverlayName()); + for (Map.Entry entry : types.entrySet()) { + String name = entry.getKey().getOverlayName(); + if (!entry.getValue()) { + name = ChatColor.ITALIC + name + baseColor; + } + identifiers.add(name); } - Collections.sort(identifiers); return String.join(",", identifiers); } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java index d59fa08dd0..efa9fe731f 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java @@ -63,11 +63,7 @@ private void erodeFromAction(Player player, Set blocking, Cause ca if (cause == Cause.PEARL && !block.getType().isBlockPearls()) { continue; } - Set set = typeMap.get(block.getType()); - if (set == null) { - set = new HashSet<>(); - typeMap.put(block.getType(), set); - } + Set set = typeMap.computeIfAbsent(block.getType(), k -> new HashSet<>()); set.add(block); } @@ -168,25 +164,17 @@ public Set getBlockingBastions(Location loc) { public Set getEnteredGroupFields(Location source, Collection target) { Set result = new HashSet<>(); for (Location loc : target) { - for (BastionBlock b : getBlockingBastions(loc)) { + for (BastionBlock b : getBlockingBastions(loc, b -> b.getType().isBlockLiquids())) { result.add(b.getGroup()); } } - for (BastionBlock b : getBlockingBastions(source)) { + for (BastionBlock b : getBlockingBastions(source, b -> b.getType().isBlockLiquids())) { result.remove(b.getGroup()); } return result; } - public Set getBlockingBastions(Set locs) { - Set result = new HashSet<>(); - for (Location loc : locs) { - result.addAll(getBlockingBastions(loc)); - } - return result; - } - public Set getBlockingBastionsWithoutPermission(Set locs, UUID player, PermissionType permission) { Set result = new HashSet<>(); diff --git a/plugins/bastion-paper/src/main/resources/config.yml b/plugins/bastion-paper/src/main/resources/config.yml index 1dc8f0340d..4fbd8456d2 100644 --- a/plugins/bastion-paper/src/main/resources/config.yml +++ b/plugins/bastion-paper/src/main/resources/config.yml @@ -41,7 +41,7 @@ bastions: destroyOnRemoveWhileImmature: true pearls: block: false - blockMidair: fakse + blockMidair: false scaleFactor: 1 requireMaturity: true consumeOnBlock: false diff --git a/plugins/bastion-paper/src/main/resources/plugin.yml b/plugins/bastion-paper/src/main/resources/plugin.yml index 4a6fa1162e..6703aecbff 100644 --- a/plugins/bastion-paper/src/main/resources/plugin.yml +++ b/plugins/bastion-paper/src/main/resources/plugin.yml @@ -4,20 +4,13 @@ main: isaac.bastion.Bastion author: spaceFountain authors: [ Rourke750, ProgrammerDan, Maxopoly, TealNerd, Aleksey-Terzi ] depend: [ CivModCore, Citadel, NameLayer ] +softdepend: [ MythicMobs ] api-version: 1.21.3 commands: - Bastion: - description: Base command for Bastion - usage: /Bastion - permission: Bastion.normal bsi: description: Gives info on blocks that are clicked usage: /bsi and right click a block permission: Bastion.normal - bsd: - description: Removes Bastion Block when clicked - usage: /bsd and right click a block - permission: Bastion.normal bso: description: Returns to normal usage: /bso set the mode back to normal diff --git a/plugins/build.gradle.kts b/plugins/build.gradle.kts index df8ba83777..2f8c21ed8e 100644 --- a/plugins/build.gradle.kts +++ b/plugins/build.gradle.kts @@ -32,6 +32,10 @@ subprojects { enabled = false } + tasks.withType { + useJUnitPlatform() + } + configure { val githubActor = System.getenv("GITHUB_ACTOR") val githubToken = System.getenv("GITHUB_TOKEN") diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java index 0f4fd64fe3..9883229aa2 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java @@ -13,6 +13,7 @@ import com.aleksey.castlegates.utils.ParticleHelper; import com.aleksey.castlegates.utils.PowerResultHelper; import org.bukkit.ChatColor; +import org.bukkit.ExplosionResult; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -117,6 +118,9 @@ public void handleBlockPhysics(BlockPhysicsEvent event) { } public void handleEntityExplode(EntityExplodeEvent event) { + if (event.getExplosionResult() == ExplosionResult.KEEP || event.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) { + return; + } for (Block block : event.blockList()) { _bridgeManager.removeGear(new BlockCoord(block)); } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java index b41832d887..0777887120 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java @@ -4,6 +4,7 @@ package com.aleksey.castlegates.listener; +import com.aleksey.castlegates.CastleGates; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -13,8 +14,6 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; -import com.aleksey.castlegates.CastleGates; - public class EntityListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java index 34a626ecae..c8a1fa4fb6 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java @@ -8,20 +8,15 @@ import isaac.bastion.Bastion; import isaac.bastion.BastionBlock; import isaac.bastion.manager.BastionBlockManager; - import java.util.LinkedList; import java.util.List; import java.util.Set; - import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; - import vg.civcraft.mc.citadel.Citadel; import vg.civcraft.mc.citadel.ReinforcementManager; import vg.civcraft.mc.citadel.model.Reinforcement; -import vg.civcraft.mc.namelayer.GroupManager; -import vg.civcraft.mc.namelayer.group.Group; import vg.civcraft.mc.namelayer.GroupManager.PlayerType; import vg.civcraft.mc.namelayer.permission.PermissionType; @@ -63,7 +58,7 @@ public boolean canUndraw(List players, List bridgeBlocks, ICitade private boolean hasBastionAccess(List players, Block block, ICitadel citadel) { PermissionType perm = PermissionType.getPermission(PERMISSION_UNDRAW); Location loc = block.getLocation(); - Set bastions = _blockManager.getBlockingBastions(loc); + Set bastions = _blockManager.getBlockingBastions(loc, b -> b.getType().isBlockLiquids()); if (bastions == null) return true; diff --git a/plugins/citadel-paper/build.gradle.kts b/plugins/citadel-paper/build.gradle.kts index 96052f0ea0..7ff75c5ec4 100644 --- a/plugins/citadel-paper/build.gradle.kts +++ b/plugins/citadel-paper/build.gradle.kts @@ -12,5 +12,5 @@ dependencies { compileOnly(project(":plugins:civmodcore-paper")) compileOnly(project(":plugins:namelayer-paper")) - compileOnly(libs.protocollib) + compileOnly(libs.packetevents.spigot) } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java index 66691f343c..76a6404195 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java @@ -128,12 +128,6 @@ private static BaseComponent addCoordsHoverComponent(BaseComponent component, Lo return component; } - public static void debugLog(String msg) { - if (Citadel.getInstance().getConfigManager().isDebugEnabled()) { - Citadel.getInstance().getLogger().info(msg); - } - } - public static boolean consumeReinforcementItems(Player player, ReinforcementType type, boolean consumeExtra) { ItemMap toRemove = new ItemMap(type.getItem()); if (consumeExtra) { diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java index df5423f3ad..ad3b58a135 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java @@ -5,6 +5,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.AmethystCluster; @@ -135,39 +136,35 @@ public static Reinforcement getReinforcementProtecting(Block block) { if (reinforcement != null) { return reinforcement; } - switch (block.getType()) { - // Chests are awkward since you can place both sides of a double chest - // independently, which isn't true for - // beds, plants, or doors, so this needs to be accounted for and - // "getResponsibleBlock()" isn't appropriate - // for the following logic: that both sides protect each other; that if either - // block is reinforced, then - // the chest as a whole remains protected. - case CHEST: - case TRAPPED_CHEST: { - Chest chest = (Chest) block.getBlockData(); - BlockFace facing = chest.getFacing(); - switch (chest.getType()) { - case LEFT: { - BlockFace face = WorldUtils.turnClockwise(facing); - return getReinforcementAt(block.getLocation().add(face.getDirection())); - } - case RIGHT: { - BlockFace face = WorldUtils.turnAntiClockwise(facing); - return getReinforcementAt(block.getLocation().add(face.getDirection())); - } - default: { - return null; - } + // Chests are awkward since you can place both sides of a double chest + // independently, which isn't true for + // beds, plants, or doors, so this needs to be accounted for and + // "getResponsibleBlock()" isn't appropriate + // for the following logic: that both sides protect each other; that if either + // block is reinforced, then + // the chest as a whole remains protected. + if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(block.getType())) { + Chest chest = (Chest) block.getBlockData(); + BlockFace facing = chest.getFacing(); + switch (chest.getType()) { + case LEFT: { + BlockFace face = WorldUtils.turnClockwise(facing); + return getReinforcementAt(block.getLocation().add(face.getDirection())); } - } - default: { - Block responsible = getResponsibleBlock(block); - if (Objects.equals(block, responsible)) { + case RIGHT: { + BlockFace face = WorldUtils.turnAntiClockwise(facing); + return getReinforcementAt(block.getLocation().add(face.getDirection())); + } + default: { return null; } - return getReinforcementAt(responsible.getLocation()); } + } else { + Block responsible = getResponsibleBlock(block); + if (Objects.equals(block, responsible)) { + return null; + } + return getReinforcementAt(responsible.getLocation()); } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java index af727577c8..f184c80c0b 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java @@ -17,6 +17,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; import java.util.logging.Logger; import org.bukkit.Bukkit; @@ -103,11 +104,21 @@ public void enable() { } scheduler.scheduleWithFixedDelay(() -> { - saveChangesToDB(); + try { + saveChangesToDB(); + } catch (RuntimeException ex) { + logger.log(Level.SEVERE, "Saving changes to db"); + ex.printStackTrace(); + } }, SAVE_CHANGES_INTERVAL_MS, SAVE_CHANGES_INTERVAL_MS, TimeUnit.MILLISECONDS); scheduler.scheduleWithFixedDelay(() -> { - unloadChunkTask(); + try { + unloadChunkTask(); + } catch (RuntimeException ex) { + logger.log(Level.SEVERE, "Unlocking chunks"); + ex.printStackTrace(); + } }, UNLOAD_INTERVAL_MS, UNLOAD_INTERVAL_MS, TimeUnit.MILLISECONDS); startLoadChunkThread(); diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java index b278d852d0..4ee784807c 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java @@ -1,8 +1,10 @@ package vg.civcraft.mc.citadel.listener; import com.destroystokyo.paper.MaterialTags; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -19,6 +21,7 @@ import org.bukkit.block.data.type.Comparator; import org.bukkit.block.data.type.Dispenser; import org.bukkit.block.data.type.Lectern; +import org.bukkit.block.data.type.Shelf; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -53,6 +56,8 @@ import vg.civcraft.mc.civmodcore.inventory.items.MaterialUtils; import vg.civcraft.mc.civmodcore.utilities.DoubleInteractFixer; import vg.civcraft.mc.civmodcore.world.WorldUtils; +import vg.civcraft.mc.namelayer.GroupManager; +import vg.civcraft.mc.namelayer.NameLayerAPI; import vg.civcraft.mc.namelayer.group.Group; public class BlockListener implements Listener { @@ -348,7 +353,7 @@ public void openContainer(PlayerInteractEvent e) { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void preventBypassChestAccess(BlockPlaceEvent e) { Material mat = e.getBlock().getType(); - if (mat != Material.CHEST && mat != Material.TRAPPED_CHEST) { + if (mat != Material.CHEST && mat != Material.TRAPPED_CHEST && !Tag.COPPER_CHESTS.isTagged(mat)) { return; } for (Block rel : WorldUtils.getPlanarBlockSides(e.getBlock(), true)) { @@ -761,31 +766,123 @@ public void preventTakingBooks(PlayerInteractEvent pie) { if (type != Material.CHISELED_BOOKSHELF) { return; } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (relevant.getType() != Material.AIR && !Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(relevant.getType())) { + boolean hasItem = p.getInventory().getItemInMainHand().getType() != Material.AIR || p.getInventory().getItemInOffHand().getType() != Material.AIR; + if (p.isSneaking() && hasItem) { return; } Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { + if (rein == null || rein.isInsecure()) { return; } if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to " + - (Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(relevant.getType()) ? "place books in this shelf" : "take books from this shelf")); + p.sendMessage(ChatColor.RED + "You do not have permission to interact with this bookshelf"); pie.setCancelled(true); } } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventShelfUse(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + Material type = block.getType(); + if (!Tag.WOODEN_SHELVES.isTagged(type)) { + return; + } + + Player p = pie.getPlayer(); + boolean hasItem = p.getInventory().getItemInMainHand().getType() != Material.AIR || p.getInventory().getItemInOffHand().getType() != Material.AIR; + if (p.isSneaking() && hasItem) { + return; + } + + List shelves = getConnectedShelves(block); + int reinforcementGroup = -1; + boolean unreinforced = false; + boolean insecure = true; + + for (Block shelf : shelves) { + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(shelf); + if (rein != null) { + if (unreinforced) { + p.sendMessage(Component.text("Shelf is broken; a shelf is unreinforced.", NamedTextColor.RED)); + pie.setCancelled(true); + return; + } + insecure &= rein.isInsecure(); + if (reinforcementGroup == -1) { + reinforcementGroup = rein.getGroupId(); + } else if (reinforcementGroup != rein.getGroupId()) { + p.sendMessage(Component.text("Shelf is broken; reinforcements are on different groups.", NamedTextColor.RED)); + pie.setCancelled(true); + return; + } + } else { + if (reinforcementGroup != -1) { + p.sendMessage(Component.text("Shelf is broken; a shelf is unreinforced.", NamedTextColor.RED)); + pie.setCancelled(true); + return; + } + unreinforced = true; + } + } + if (!unreinforced && !insecure && !NameLayerAPI.getGroupManager().hasAccess(GroupManager.getGroup(reinforcementGroup), p.getUniqueId(), CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(Component.text("You do not have permission to use this shelf", NamedTextColor.RED)); + pie.setCancelled(true); + } + } + + private List getConnectedShelves(Block block) { + Shelf shelf = (Shelf) block.getBlockData(); + return switch (shelf.getSideChain()) { + case UNCONNECTED -> List.of(block); + case CENTER -> { + List shelves = new ArrayList<>(); + shelves.add(block); + Block left = block.getRelative(shelf.getFacing().getModZ(), 0, shelf.getFacing().getModX()); + if (left.getBlockData() instanceof Shelf) { + shelves.add(left); + } + Block right = block.getRelative(-shelf.getFacing().getModZ(), 0, -shelf.getFacing().getModX()); + if (right.getBlockData() instanceof Shelf) { + shelves.add(right); + } + yield shelves; + } + case RIGHT -> { + List shelves = new ArrayList<>(); + shelves.add(block); + Block centre = block.getRelative(shelf.getFacing().getModZ(), 0, shelf.getFacing().getModX()); + if (centre.getBlockData() instanceof Shelf) { + shelves.add(centre); + Block left = centre.getRelative(shelf.getFacing().getModZ(), 0, shelf.getFacing().getModX()); + if (left.getBlockData() instanceof Shelf) { + shelves.add(left); + } + } + yield shelves; + } + case LEFT -> { + List shelves = new ArrayList<>(); + shelves.add(block); + Block centre = block.getRelative(-shelf.getFacing().getModZ(), 0, -shelf.getFacing().getModX()); + if (centre.getBlockData() instanceof Shelf) { + shelves.add(centre); + Block right = centre.getRelative(-shelf.getFacing().getModZ(), 0, -shelf.getFacing().getModX()); + if (right.getBlockData() instanceof Shelf) { + shelves.add(right); + } + } + yield shelves; + } + }; + } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void preventDusting(PlayerInteractEvent pie) { // Maybe this should be changed to brushing? The two terms seem to be used interchangeably. if (!pie.hasBlock()) { diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java index facdb5cbc0..c79226aaa5 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java @@ -1,12 +1,11 @@ package vg.civcraft.mc.citadel.listener; +import io.papermc.paper.event.entity.ItemTransportingEntityValidateTargetEvent; +import io.papermc.paper.event.player.PlayerOpenSignEvent; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.UUID; - - -import io.papermc.paper.event.player.PlayerOpenSignEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -21,6 +20,7 @@ import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Mob; import org.bukkit.entity.Player; +import org.bukkit.entity.WindCharge; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -149,28 +149,47 @@ public void explode(EntityExplodeEvent eee) { if (rein == null) { continue; } - ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein, null, null), eee.getEntity()); - if (!rein.isBroken()) { - iterator.remove(); + switch (eee.getExplosionResult()) { + case TRIGGER_BLOCK -> { + if (rein.isInsecure()) { + continue; + } + if (eee.getEntity() instanceof WindCharge charge && charge.getShooter() instanceof Player shooter && rein.hasPermission(shooter, CitadelPermissionHandler.getBypass())) { + continue; + } + iterator.remove(); + } + case DESTROY, DESTROY_WITH_DECAY -> { + ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein, null, null), eee.getEntity()); + if (!rein.isBroken()) { + iterator.remove(); + } + } } } } private List getGolemBlocks(EntityType type, Block base) { - ArrayList blocks = new ArrayList<>(); - blocks.add(base); - base = base.getRelative(BlockFace.UP); - blocks.add(base); - if (type == EntityType.IRON_GOLEM) { - for (BlockFace face : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, - BlockFace.WEST}) { - Block arm = base.getRelative(face); - if (arm.getType() == Material.IRON_BLOCK) - blocks.add(arm); + List blocks = new ArrayList<>(); + if (type == EntityType.COPPER_GOLEM) { + blocks.add(base); + base = base.getRelative(BlockFace.UP); + blocks.add(base); + } else { + blocks.add(base); + base = base.getRelative(BlockFace.UP); + blocks.add(base); + if (type == EntityType.IRON_GOLEM) { + for (BlockFace face : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, + BlockFace.WEST}) { + Block arm = base.getRelative(face); + if (arm.getType() == Material.IRON_BLOCK) + blocks.add(arm); + } } + base = base.getRelative(BlockFace.UP); + blocks.add(base); } - base = base.getRelative(BlockFace.UP); - blocks.add(base); return blocks; } @@ -225,7 +244,7 @@ public void powderedSnowPickup(PlayerBucketFillEvent event) { public void spawn(CreatureSpawnEvent cse) { EntityType type = cse.getEntityType(); if (type != EntityType.IRON_GOLEM && type != EntityType.SNOW_GOLEM && type != EntityType.WITHER - && type != EntityType.SILVERFISH) { + && type != EntityType.SILVERFISH && type != EntityType.COPPER_GOLEM) { return; } for (Block block : getGolemBlocks(type, cse.getLocation().getBlock())) { @@ -236,6 +255,14 @@ public void spawn(CreatureSpawnEvent cse) { } } + @EventHandler(priority = EventPriority.LOW) + public void blockCopperGolem(ItemTransportingEntityValidateTargetEvent itevte) { + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(itevte.getBlock()); + if (rein != null && !rein.isInsecure()) { + itevte.setAllowed(false); + } + } + // ------------------------------------------------------------ // Hanging Entities // ------------------------------------------------------------ diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java index ee24a917ca..b9f5ffe4c6 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java @@ -2,7 +2,6 @@ import org.bukkit.Location; import org.bukkit.block.Chest; -import org.bukkit.block.Container; import org.bukkit.block.DoubleChest; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java index a917b4a2db..808ce42e87 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java @@ -1,29 +1,29 @@ package vg.civcraft.mc.citadel.model; -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.WrappedDataValue; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import io.papermc.paper.adventure.AdventureComponent; +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.protocol.entity.data.EntityData; +import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; +import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; +import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag; +import com.github.retrooper.packetevents.util.Vector3d; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.TreeMap; import java.util.UUID; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import net.minecraft.world.entity.PositionMoveRotation; -import net.minecraft.world.entity.Relative; -import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; @@ -37,9 +37,9 @@ public class HologramManager { // good measure private static final double HOLOOFFSET = 0.55 * Math.sqrt(2); - private Map> holograms; - private Set activeHolos; - private CitadelSettingManager settingMan; + private final Map> holograms; + private final Set activeHolos; + private final CitadelSettingManager settingMan; public HologramManager(CitadelSettingManager settingMan) { this.holograms = new HashMap<>(); @@ -107,13 +107,13 @@ private void updateHolograms() { private class PlayerHolo { - private Player player; + private final Player player; private int hologramId; - private Reinforcement reinforcement; + private final Reinforcement reinforcement; private long timeStamp; - private boolean hasPermission; + private final boolean hasPermission; private Location cachedPlayerLocation; - private long cullDelay; + private final long cullDelay; public PlayerHolo(Player player, Reinforcement reinforcement) { this.player = player; @@ -134,53 +134,39 @@ void show() { this.hologramId = Bukkit.getUnsafe().nextEntityId(); - ProtocolManager protocolLib = ProtocolLibrary.getProtocolManager(); - PacketContainer fakeEntity = protocolLib.createPacket(PacketType.Play.Server.SPAWN_ENTITY); Location location = getHoloLocation(reinforcement, player); - fakeEntity.getIntegers() - .write(0, hologramId) - .write(1, 0) - .write(2, 0) - .write(3, 0) - .write(4, 0); - - fakeEntity.getUUIDs().write(0, UUID.randomUUID()); - - fakeEntity.getEntityTypeModifier() - .write(0, EntityType.TEXT_DISPLAY); - - fakeEntity.getDoubles() - .write(0, location.getX()) - .write(1, location.getY()) - .write(2, location.getZ()); - - fakeEntity.getBytes() - .write(0, (byte) 0) - .write(1, (byte) 0) - .write(2, (byte) 0); - - protocolLib.sendServerPacket(player, fakeEntity); + Vector3d position = new Vector3d(location.getX(), location.getY(), location.getZ()); + + WrapperPlayServerSpawnEntity spawnPacket = new WrapperPlayServerSpawnEntity( + hologramId, + Optional.of(UUID.randomUUID()), + EntityTypes.TEXT_DISPLAY, + position, + 0f, // pitch + 0f, // yaw + 0f, // headYaw + 0, // data + Optional.of(Vector3d.zero()) + ); + + PacketEvents.getAPI().getPlayerManager().sendPacket(player, spawnPacket); sendUpdatePacket(); cachedPlayerLocation = player.getLocation(); } private void sendUpdatePacket() { - ProtocolManager protocolLib = ProtocolLibrary.getProtocolManager(); - - PacketContainer fakeMetadata = protocolLib.createPacket(PacketType.Play.Server.ENTITY_METADATA); - fakeMetadata.getIntegers().write(0, hologramId); - - List values = new ArrayList<>(); - values.add(new WrappedDataValue(10, WrappedDataWatcher.Registry.get(Integer.class), 2)); - values.add(new WrappedDataValue(15, WrappedDataWatcher.Registry.get(Byte.class), (byte) 3)); - values.add(new WrappedDataValue(23, WrappedDataWatcher.Registry.getChatComponentSerializer(), - new AdventureComponent(createHoloContent()))); -// values.add(new WrappedDataValue(25, WrappedDataWatcher.Registry.get(Integer.class), 0)); - // Add shadow when MC-260529 is fixed - values.add(new WrappedDataValue(27, WrappedDataWatcher.Registry.get(Byte.class), (byte) (0x02))); - fakeMetadata.getDataValueCollectionModifier().write(0, values); - - protocolLib.sendServerPacket(player, fakeMetadata); + List> metadata = new ArrayList<>(); + // Index 10: Interpolation duration (INT) - for display entities + metadata.add(new EntityData<>(10, EntityDataTypes.INT, 2)); + // Index 15: Billboard constraint (BYTE) - 3 = CENTER (always faces player) + metadata.add(new EntityData<>(15, EntityDataTypes.BYTE, (byte) 3)); + // Index 23: Text content (ADV_COMPONENT) - the hologram text + metadata.add(new EntityData<>(23, EntityDataTypes.ADV_COMPONENT, createHoloContent())); + // Index 27: Display entity flags (BYTE) - 0x02 = see through + metadata.add(new EntityData<>(27, EntityDataTypes.BYTE, (byte) 0x02)); + + WrapperPlayServerEntityMetadata metadataPacket = new WrapperPlayServerEntityMetadata(hologramId, metadata); + PacketEvents.getAPI().getPlayerManager().sendPacket(player, metadataPacket); } private Component createHoloContent() { @@ -221,27 +207,21 @@ void updateLocation() { && current.getBlockZ() == cachedPlayerLocation.getBlockZ()) { return; } + cachedPlayerLocation = current; Location updated = getHoloLocation(reinforcement, player); - ProtocolManager protocolLib = ProtocolLibrary.getProtocolManager(); - - PacketContainer fakeTeleport = protocolLib.createPacket(PacketType.Play.Server.ENTITY_TELEPORT); - fakeTeleport.getIntegers().write(0, hologramId); - - fakeTeleport.getModifier().withType(PositionMoveRotation.class) - .write(0, - new PositionMoveRotation( - new Vec3(updated.getX(), updated.getY(), updated.getZ()), - new Vec3(0, 0, 0), - 0, - 0)); - - fakeTeleport.getModifier().withType(Set.class) - .write(0, Relative.DELTA); - - fakeTeleport.getBooleans() - .write(0, false); - - protocolLib.sendServerPacket(player, fakeTeleport); + Vector3d position = new Vector3d(updated.getX(), updated.getY(), updated.getZ()); + + WrapperPlayServerEntityTeleport teleportPacket = new WrapperPlayServerEntityTeleport( + hologramId, + position, + Vector3d.zero(), + 0f, // yaw + 0f, // pitch + RelativeFlag.NONE, + false + ); + + PacketEvents.getAPI().getPlayerManager().sendPacket(player, teleportPacket); } void refreshTimestamp() { @@ -252,12 +232,9 @@ void delete() { if (hologramId == 0) { return; } - ProtocolManager protocolLib = ProtocolLibrary.getProtocolManager(); - - PacketContainer fakeDestroy = protocolLib.createPacket(PacketType.Play.Server.ENTITY_DESTROY); - fakeDestroy.getIntLists().write(0, List.of(hologramId)); - protocolLib.sendServerPacket(player, fakeDestroy); + WrapperPlayServerDestroyEntities destroyPacket = new WrapperPlayServerDestroyEntities(hologramId); + PacketEvents.getAPI().getPlayerManager().sendPacket(player, destroyPacket); hologramId = 0; } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java index 45ea5e538c..f50eae37e5 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java @@ -52,20 +52,55 @@ public void handleInteractBlock(PlayerInteractEvent e) { return; } Player player = e.getPlayer(); - // does the player have an item? - if (e.getItem() == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You have nothing in your hand to reinforce with", + // does the player have permission to reinforce on that group + if (!NameLayerAPI.getGroupManager().hasAccess(group, player.getUniqueId(), + CitadelPermissionHandler.getReinforce())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You seem to have lost permission to reinforce on " + group.getName(), e.getClickedBlock().getLocation()); + Citadel.getInstance().getStateManager().setState(player, null); return; } - ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(e.getItem(), player.getWorld().getName()); - // is it a valid item to reinforce with - if (type == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You can not reinforce with this item", + // resolve reinforcement type from held item (may be null if not holding material) + ReinforcementType type = null; + if (e.getItem() != null) { + type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(e.getItem(), player.getWorld().getName()); + } + Block block = ReinforcementLogic.getResponsibleBlock(e.getClickedBlock()); + Reinforcement rein = ReinforcementLogic.getReinforcementAt(block.getLocation()); + // if there is no existing reinforcement and no material to create one, nothing to do + // if reinforcement exists, check if player has permission to edit it + if (rein != null && !rein.hasPermission(player, CitadelPermissionHandler.getBypass())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You do not have permission to bypass this reinforcement", e.getClickedBlock().getLocation()); return; } - Block block = ReinforcementLogic.getResponsibleBlock(e.getClickedBlock()); + // not holding reinforcement material: only allow group transfer on existing reinforcement + if (type == null) { + if (rein == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You need to hold a valid reinforcement material to reinforce a new block", + e.getClickedBlock().getLocation()); + return; + } + if (group.getGroupId() != rein.getGroup().getGroupId()) { + ReinforcementGroupChangeEvent rgce = new ReinforcementGroupChangeEvent(player, rein, group); + Bukkit.getPluginManager().callEvent(rgce); + if (!rgce.isCancelled()) { + rein.setGroup(group); + CitadelUtility.sendAndLog(player, ChatColor.GREEN, + "Updated group to " + ChatColor.LIGHT_PURPLE + group.getName(), + e.getClickedBlock().getLocation()); + } + } else { + CitadelUtility.sendAndLog(player, ChatColor.YELLOW, + "This reinforcement is already on " + group.getName(), + e.getClickedBlock().getLocation()); + } + return; + } + // holding reinforcement material: full reinforce/upgrade/transfer logic // can the item reinforce the clicked block if (!type.canBeReinforced(block.getType())) { CitadelUtility.sendAndLog(player, ChatColor.RED, @@ -79,31 +114,12 @@ public void handleInteractBlock(PlayerInteractEvent e) { type.getName() + " cannot reinforce in this dimension", block.getLocation()); return; } - // does the player have permission to reinforce on that group - if (!NameLayerAPI.getGroupManager().hasAccess(group, e.getPlayer().getUniqueId(), - CitadelPermissionHandler.getReinforce())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "You seem to have lost permission to reinforce on " + group.getName(), - e.getClickedBlock().getLocation()); - Citadel.getInstance().getStateManager().setState(e.getPlayer(), null); - return; - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - // if reinforcement exists, check if player has permission to edit it - if (rein != null) { - if (!rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getBypass())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "You do not have permission to bypass this reinforcement", - e.getClickedBlock().getLocation()); - return; - } - } Reinforcement newRein = null; if (rein == null || rein.getType() != type) { // check inventory for reinforcement item ItemMap toConsume = new ItemMap(type.getItem()); if (!toConsume.isContainedIn(player.getInventory())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, "No reinforcing item found in your inventory?", + CitadelUtility.sendAndLog(player, ChatColor.RED, "No reinforcing item found in your inventory?", e.getClickedBlock().getLocation()); return; } @@ -116,7 +132,7 @@ public void handleInteractBlock(PlayerInteractEvent e) { } // consume item from inventory if (!toConsume.removeSafelyFrom(player.getInventory())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, + CitadelUtility.sendAndLog(player, ChatColor.RED, "Failed to remove reinforcement item from your inventory", e.getClickedBlock().getLocation()); return; @@ -151,7 +167,7 @@ public void handleInteractBlock(PlayerInteractEvent e) { Bukkit.getPluginManager().callEvent(rcte); if (!rcte.isCancelled()) { if (rein.rollForItemReturn()) { - giveReinforcement(rein.getLocation().clone().add(0.5, 0.5, 0.5), e.getPlayer(), rein.getType()); + giveReinforcement(rein.getLocation().clone().add(0.5, 0.5, 0.5), player, rein.getType()); } rein.setType(type); rein.setHealth(type.getHealth()); diff --git a/plugins/citadel-paper/src/main/resources/plugin.yml b/plugins/citadel-paper/src/main/resources/plugin.yml index f370162953..fc50b02b78 100644 --- a/plugins/citadel-paper/src/main/resources/plugin.yml +++ b/plugins/citadel-paper/src/main/resources/plugin.yml @@ -15,7 +15,7 @@ depend: - NameLayer - CivModCore softdepend: - - ProtocolLib + - packetevents description: Citadel allows you to make blocks difficult to break. When a block is reinforced, it must be broken many times before it is destroyed. api-version: 1.21.3 permissions: diff --git a/plugins/civchat2-paper/build.gradle.kts b/plugins/civchat2-paper/build.gradle.kts index c0ee8cbaf7..7026978c46 100644 --- a/plugins/civchat2-paper/build.gradle.kts +++ b/plugins/civchat2-paper/build.gradle.kts @@ -12,5 +12,5 @@ dependencies { compileOnly(project(":plugins:civmodcore-paper")) compileOnly(project(":plugins:banstick-paper")) compileOnly(project(":plugins:namelayer-paper")) - compileOnly("me.clip:placeholderapi:2.11.6") + compileOnly(libs.placeholderapi) } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/prefix/StarManager.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/prefix/StarManager.java index 66b5cc3919..7d6ae46e60 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/prefix/StarManager.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/prefix/StarManager.java @@ -60,7 +60,12 @@ public HoverEventSource hover(Player player) { rank = "None"; } - return HoverEvent.showText(Component.text("Rank: " + rank + "\nJoined: " + joined)); + String text = "Rank: " + rank + "\nJoined: " + joined; + if (player.hasPermission("rankedpvpstar")) { + text += "\nTop 10 in ranked PvP"; + } + + return HoverEvent.showText(Component.text(text)); } public String getPrefix(Player player) { @@ -76,6 +81,8 @@ public String getPrefix(Player player) { return ChatColor.RED + STAR; } + int purpleStars = player.hasPermission("rankedpvpstar") ? 1 : 0; + int greenStars = 0; if (player.hasPermission("civchat.powerplayer")) { greenStars = 4; @@ -88,19 +95,22 @@ public String getPrefix(Player player) { } StringBuilder stars = new StringBuilder(); + if (playtimeStars) { long firstPlayed = getJoined(player); int yellowStars = firstPlayed == 0 ? 0 : (int) LocalDateTime.ofInstant(Instant.ofEpochMilli(firstPlayed), ZoneId.systemDefault()).until(LocalDateTime.now(), ChronoUnit.YEARS); - yellowStars = Math.max(0, yellowStars - greenStars); + yellowStars = Math.max(0, yellowStars - greenStars - purpleStars); if (yellowStars > 0) { stars.append(ChatColor.YELLOW); + stars.append(STAR.repeat(yellowStars)); } - stars.append(STAR.repeat(yellowStars)); } if (greenStars > 0) { - stars.append(ChatColor.GREEN); + stars.append(ChatColor.GREEN).append(STAR.repeat(greenStars)); + } + if (purpleStars > 0) { + stars.append(ChatColor.LIGHT_PURPLE).append(STAR.repeat(purpleStars)); } - stars.append(STAR.repeat(greenStars)); return stars.toString(); } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java index 7c295c38de..0b5b6d4bdd 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java @@ -1,5 +1,9 @@ package vg.civcraft.mc.civduties.listeners; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -31,7 +35,7 @@ public PlayerListener() { this.vaultManager = CivDuties.getInstance().getVaultManager(); } - @EventHandler(priority = EventPriority.LOWEST) + @EventHandler public void playerQuitEvent(PlayerQuitEvent event) { Player player = event.getPlayer(); if (modeManager.isInDuty(player)) { @@ -58,6 +62,9 @@ public void playerJoinEvent(PlayerJoinEvent event) { } vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CivDuties.getInstance(), () -> { + player.sendMessage(Component.text("You are in duty mode.", NamedTextColor.LIGHT_PURPLE, TextDecoration.BOLD)); + }, 10L); } } diff --git a/plugins/civmodcore-paper/build.gradle.kts b/plugins/civmodcore-paper/build.gradle.kts index 5e6859b531..432db9b5f5 100644 --- a/plugins/civmodcore-paper/build.gradle.kts +++ b/plugins/civmodcore-paper/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { paperDevBundle(libs.versions.paper) } - api("com.github.davidmoten:rtree2:0.9.3") + api(libs.rtree2) api(libs.aikar.acf) api(libs.aikar.taskchain) api(libs.hikaricp) @@ -21,4 +21,11 @@ dependencies { compileOnly(libs.fastutil) testImplementation(libs.bundles.junit) + testImplementation(libs.mockbukkit) + testImplementation("io.papermc.paper:paper-api:${libs.versions.paper.get()}") +} + +// https://docs.mockbukkit.org/docs/en/user_guide/advanced/paperweight +paperweight { + addServerDependencyTo = configurations.named(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME).map { setOf(it) } } diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/config/ConfigParser.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/config/ConfigParser.java index eb4b8717a5..c0b279b024 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/config/ConfigParser.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/config/ConfigParser.java @@ -1,7 +1,6 @@ package vg.civcraft.mc.civmodcore.config; import java.util.logging.Logger; -import org.bukkit.ChatColor; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.Plugin; @@ -30,7 +29,7 @@ public ConfigParser(final Plugin plugin) { * @return Returns true if the config was successfully parsed. */ public final boolean parse() { - this.logger.info(ChatColor.BLUE + "Parsing config."); + this.logger.info("Parsing config."); this.plugin.saveDefaultConfig(); FileConfiguration config = this.plugin.getConfig(); // Parse debug value @@ -42,7 +41,7 @@ public final boolean parse() { // Allow child class parsing final boolean worked = parseInternal(config); if (worked) { - this.logger.info(ChatColor.BLUE + "Config parsed."); + this.logger.info("Config parsed."); } else { this.logger.warning("Failed to parse config!"); } diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/ClonedInventory.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/ClonedInventory.java index 93138ab5ce..351098a8c3 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/ClonedInventory.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/ClonedInventory.java @@ -5,9 +5,9 @@ import java.util.ListIterator; import java.util.Spliterator; import java.util.function.Consumer; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.craftbukkit.inventory.util.CraftInventoryCreator; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; @@ -256,7 +256,7 @@ public static ClonedInventory cloneInventory(final Inventory inventory, final bo return (ClonedInventory) inventory; } final ItemStack[] contents = inventory.getStorageContents().clone(); - Inventory clone = Bukkit.createInventory(inventory.getHolder(), contents.length); + Inventory clone = CraftInventoryCreator.INSTANCE.createInventory(inventory.getHolder(), contents.length); for (int i = 0; i < contents.length; i++) { final ItemStack item = contents[i]; if (item != null) { diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/InventoryUtils.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/InventoryUtils.java index 70cc20ff14..b3bae27499 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/InventoryUtils.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/InventoryUtils.java @@ -12,13 +12,6 @@ public final class InventoryUtils { - public static final int CHEST_1_ROW = 9; - public static final int CHEST_2_ROWS = 9 * 2; - public static final int CHEST_3_ROWS = 9 * 3; - public static final int CHEST_4_ROWS = 9 * 4; - public static final int CHEST_5_ROWS = 9 * 5; - public static final int CHEST_6_ROWS = 9 * 6; - /** * Tests an inventory to see if it's valid. * diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockPos.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockPos.java new file mode 100644 index 0000000000..d8fd474181 --- /dev/null +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockPos.java @@ -0,0 +1,5 @@ +package vg.civcraft.mc.civmodcore.utilities; + +public record BlockPos(int x, int y, int z) { + +} diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockPosPdc.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockPosPdc.java new file mode 100644 index 0000000000..bdf993571c --- /dev/null +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockPosPdc.java @@ -0,0 +1,87 @@ +package vg.civcraft.mc.civmodcore.utilities; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.bukkit.Chunk; +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public class BlockPosPdc { + + public static boolean addBlock(Chunk chunk, NamespacedKey key, int x, int y, int z) { + PersistentDataContainer chunkPdc = chunk.getPersistentDataContainer(); + int[] ints = chunkPdc.get(key, PersistentDataType.INTEGER_ARRAY); + if (ints != null) { + for (int i = 0; i < ints.length - 2; i += 3) { + if (ints[i] == x && ints[i + 1] == y && ints[i + 2] == z) { + return false; + } + } + } + IntList list = ints == null ? new IntArrayList() : new IntArrayList(ints); + list.add(x); + list.add(y); + list.add(z); + + chunkPdc.set(key, PersistentDataType.INTEGER_ARRAY, list.toIntArray()); + return true; + } + + public static boolean testBlock(Chunk chunk, NamespacedKey key, int x, int y, int z) { + PersistentDataContainer chunkPdc = chunk.getPersistentDataContainer(); + int[] ints = chunkPdc.get(key, PersistentDataType.INTEGER_ARRAY); + if (ints == null) { + return false; + } + + for (int i = 0; i < ints.length - 2; i += 3) { + if (ints[i] == x && ints[i + 1] == y && ints[i + 2] == z) { + return true; + } + } + return false; + } + + public static boolean removeBlock(Chunk chunk, NamespacedKey key, int x, int y, int z) { + PersistentDataContainer chunkPdc = chunk.getPersistentDataContainer(); + int[] ints = chunkPdc.get(key, PersistentDataType.INTEGER_ARRAY); + if (ints == null) { + return false; + } + + IntList list = new IntArrayList(ints); + int index = -1; + for (int i = 0; i < list.size() - 2; i += 3) { + if (list.getInt(i) == x && list.getInt(i + 1) == y && list.getInt(i + 2) == z) { + index = i; + break; + } + } + if (index == -1) { + return false; + } + + list.removeElements(index, index + 3); + chunkPdc.set(key, PersistentDataType.INTEGER_ARRAY, list.toIntArray()); + return true; + } + + public static List getBlocks(Chunk chunk, NamespacedKey key) { + PersistentDataContainer chunkPdc = chunk.getPersistentDataContainer(); + int[] ints = chunkPdc.get(key, PersistentDataType.INTEGER_ARRAY); + if (ints == null) { + return Collections.emptyList(); + } + + List blocks = new ArrayList<>(ints.length / 3); + for (int i = 0; i < ints.length - 2; i += 3) { + blocks.add(new BlockPos(ints[i], ints[i + 1], ints[i + 2])); + } + + return Collections.unmodifiableList(blocks); + } +} diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/BlockProtector.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockProtector.java similarity index 97% rename from plugins/heliodor-paper/src/main/java/net/civmc/heliodor/BlockProtector.java rename to plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockProtector.java index 17cd8d609e..679f96cc1a 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/BlockProtector.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/utilities/BlockProtector.java @@ -1,4 +1,4 @@ -package net.civmc.heliodor; +package vg.civcraft.mc.civmodcore.utilities; import java.util.ArrayList; import java.util.List; diff --git a/plugins/civmodcore-paper/src/test/java/vg/civcraft/mc/civmodcore/items/ItemMetaTests.java b/plugins/civmodcore-paper/src/test/java/vg/civcraft/mc/civmodcore/items/ItemMetaTests.java index e4eec2edb7..b358d04800 100644 --- a/plugins/civmodcore-paper/src/test/java/vg/civcraft/mc/civmodcore/items/ItemMetaTests.java +++ b/plugins/civmodcore-paper/src/test/java/vg/civcraft/mc/civmodcore/items/ItemMetaTests.java @@ -4,104 +4,63 @@ import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.MockBukkit; import vg.civcraft.mc.civmodcore.chat.ChatUtils; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; public class ItemMetaTests { - private static final ItemStack TEMPLATE_ITEM = new ItemStack(Material.STICK); + private ItemStack templateItem; - // TODO: Who knows. -// /** -// * Tests whether a basic string display name can match with a component. -// */ -// @Test -// public void testBasicDisplayNameEquality() { -// // Setup -// final var formerItem = NullUtils.isNotNull(NBTSerialization.processItem(TEMPLATE_ITEM, (nbt) -> { -// final var display = new NBTCompound(); -// display.setString("Name", "Hello!"); -// nbt.setCompound("display-name", display); -// })); -// final var latterItem = TEMPLATE_ITEM.clone(); -// ItemUtils.setComponentDisplayName(latterItem, Component.text("Hello!")); -// // Check -// System.out.println(formerItem); -// System.out.println(latterItem); -// Assertions.assertTrue(ChatUtils.areComponentsEqual( -// ItemUtils.getComponentDisplayName(formerItem), -// ItemUtils.getComponentDisplayName(latterItem))); -// } + @BeforeEach + public void setUp() { + MockBukkit.mock(); + templateItem = new ItemStack(Material.STICK); + } - // TODO: Who knows. -// /** -// * Tests whether a json primitive display name can match with a component. -// */ -// @Test -// public void testBasicJsonPrimitiveDisplayNameEquality() { -// // Setup -// final var formerItem = NullUtils.isNotNull(NBTSerialization.processItem(TEMPLATE_ITEM, (nbt) -> { -// final var display = new NBTCompound(); -// display.setString("Name", "\"Hello!\""); -// nbt.setCompound("display", display); -// })); -// final var latterItem = TEMPLATE_ITEM.clone(); -// ItemUtils.handleItemMeta(latterItem, (ItemMeta meta) -> { -// meta.displayName(Component.text("Hello!")); -// return true; -// }); -// // Check -// System.out.println(formerItem); -// System.out.println(latterItem); -// Assertions.assertTrue(ChatUtils.areComponentsEqual( -// ItemUtils.getComponentDisplayName(formerItem), -// ItemUtils.getComponentDisplayName(latterItem))); -// } + @AfterEach + public void tearDown() { + MockBukkit.unmock(); + } - /** - * How do different API methods of setting the display name fare? - */ @Test @SuppressWarnings("deprecation") public void testAdvancedDisplayNameEquality() { - // Setup - final var formerItem = TEMPLATE_ITEM.clone(); + final var formerItem = templateItem.clone(); ItemUtils.handleItemMeta(formerItem, (ItemMeta meta) -> { meta.setDisplayName("Hello!"); return true; }); - final var latterItem = TEMPLATE_ITEM.clone(); + final var latterItem = templateItem.clone(); ItemUtils.handleItemMeta(latterItem, (ItemMeta meta) -> { meta.displayName(Component.text("Hello!")); return true; }); - // Check Assertions.assertTrue(ChatUtils.areComponentsEqual( ItemUtils.getComponentDisplayName(formerItem), ItemUtils.getComponentDisplayName(latterItem))); Assertions.assertTrue(ItemUtils.areItemsSimilar(formerItem, latterItem)); } - /** - * Tests whether {@link ChatUtils#isBaseComponent(Component)} works. - */ @Test + @Disabled("Paper's switch to native Component display names removed the legacy/Adventure split this assertion relied on") @SuppressWarnings("deprecation") public void testBaseComponent() { - // Setup - final var formerItem = TEMPLATE_ITEM.clone(); + final var formerItem = templateItem.clone(); ItemUtils.handleItemMeta(formerItem, (ItemMeta meta) -> { meta.setDisplayName("Hello!"); return true; }); - final var latterItem = TEMPLATE_ITEM.clone(); + final var latterItem = templateItem.clone(); ItemUtils.handleItemMeta(latterItem, (ItemMeta meta) -> { meta.displayName(Component.text("Hello!")); return true; }); - // Check Assertions.assertTrue(ChatUtils.isBaseComponent( ItemUtils.getComponentDisplayName(formerItem))); Assertions.assertFalse(ChatUtils.isBaseComponent( diff --git a/plugins/civmodcore-paper/src/test/java/vg/civcraft/mc/civmodcore/nbt/NBTTests.java b/plugins/civmodcore-paper/src/test/java/vg/civcraft/mc/civmodcore/nbt/NBTTests.java deleted file mode 100644 index 01fa75d237..0000000000 --- a/plugins/civmodcore-paper/src/test/java/vg/civcraft/mc/civmodcore/nbt/NBTTests.java +++ /dev/null @@ -1,91 +0,0 @@ -package vg.civcraft.mc.civmodcore.nbt; - -import net.minecraft.nbt.CompoundTag; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class NBTTests { - @Test - public void testStringSerialization() { - // Setup - String STRING_KEY = "test_string"; - String expectedString = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " + - "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation " + - "ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in " + - "voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " + - "proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; - // Process - final var nbt = new NbtCompound(); - nbt.setString(STRING_KEY, expectedString); - // Check - Assertions.assertEquals(expectedString, nbt.getString(STRING_KEY, null)); - } - - @Test - public void testStringArraySerialization() { - // Setup - String STRING_ARRAY_KEY = "test_string_array"; - String[] expectedStringArray = {"one", "two", "three"}; - // Process - final var nbt = new NbtCompound(); - nbt.setStringArray(STRING_ARRAY_KEY, expectedStringArray); - // Check - Assertions.assertArrayEquals(expectedStringArray, nbt.getStringArray(STRING_ARRAY_KEY, false)); - } - - @Test - public void testByteSerialization() { - // Setup - String STRING_KEY = "test_byte"; - String expectedString = "Ultricies leo integer malesuada nunc vel risus commodo viverra. Fames ac turpis " + - "egestas sed tempus urna. Sollicitudin nibh sit amet commodo. Cras sed felis eget velit aliquet " + - "sagittis. Convallis tellus id interdum velit laoreet id donec ultrices. Mauris nunc congue nisi " + - "vitae suscipit tellus mauris a diam. Leo vel fringilla est ullamcorper. Justo nec ultrices dui " + - "sapien eget mi. Nisl vel pretium lectus quam id leo in. Nisi vitae suscipit tellus mauris a diam. " + - "Proin fermentum leo vel orci porta non pulvinar. Facilisis magna etiam tempor orci eu lobortis " + - "elementum nibh tellus. Aliquet eget sit amet tellus cras adipiscing enim."; - // Process - final var nbt = new NbtCompound(); - nbt.setString(STRING_KEY, expectedString); - final byte[] data = NbtUtils.toBytes(nbt.internal()); - final CompoundTag actual = NbtUtils.fromBytes(data); - // Check - Assertions.assertNotNull(actual); - Assertions.assertEquals(expectedString, actual.getString(STRING_KEY).orElseThrow()); - } - - @Test - public void testNullSerialization() { - // Setup - String STRING_KEY = "test_null_string"; - // Process - final var nbt = new NbtCompound(); - nbt.setString(STRING_KEY, null); - final byte[] data = NbtUtils.toBytes(nbt.internal()); - final var actual = new NbtCompound(NbtUtils.fromBytes(data)); - // Check - Assertions.assertNull(actual.getString(STRING_KEY, null)); - } - - @Test - public void testNBTClearing() { - // Setup - String STRING_KEY = "test_clear"; - String expectedString = "In hac habitasse platea dictumst quisque sagittis purus. Consectetur purus ut " + - "faucibus pulvinar elementum integer enim neque. Scelerisque eleifend donec pretium vulputate " + - "sapien nec. In cursus turpis massa tincidunt dui ut ornare lectus. Imperdiet massa tincidunt " + - "nunc pulvinar sapien et ligula ullamcorper. Lorem sed risus ultricies tristique nulla aliquet enim " + - "tortor at. Arcu odio ut sem nulla. Etiam non quam lacus suspendisse. Tincidunt tortor aliquam " + - "nulla facilisi cras. Magna ac placerat vestibulum lectus mauris. Tortor at auctor urna nunc id. " + - "Turpis egestas pretium aenean pharetra magna ac placerat vestibulum lectus. Faucibus in ornare " + - "quam viverra orci sagittis. Lectus proin nibh nisl condimentum id venenatis a. Diam in arcu cursus " + - "euismod. Cras semper auctor neque vitae tempus. Leo a diam sollicitudin tempor id eu. Non sodales " + - "neque sodales ut etiam. Elementum integer enim neque volutpat ac tincidunt vitae semper quis."; - // Process - final var nbt = new NbtCompound(); - nbt.setString(STRING_KEY, expectedString); - nbt.clear(); - // Check - Assertions.assertNull(nbt.getString(STRING_KEY, null)); - } -} diff --git a/plugins/civproxy-velocity/build.gradle.kts b/plugins/civproxy-velocity/build.gradle.kts index 5bf5b0fdeb..d319952481 100644 --- a/plugins/civproxy-velocity/build.gradle.kts +++ b/plugins/civproxy-velocity/build.gradle.kts @@ -4,11 +4,11 @@ plugins { version = "1.0.0" dependencies { - compileOnly("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT") - compileOnly("us.ajg0702.queue.api:api:2.8.0") + compileOnly(libs.velocity.api) + compileOnly(libs.ajQueue.api) api(libs.hikaricp) api(libs.configurate.yaml) compileOnly(libs.luckperms.api) - annotationProcessor("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT") + annotationProcessor(libs.velocity.api) api(project(":libraries:name-api")) } diff --git a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayer.java b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayer.java index 1bceb69a61..1970d5dd2e 100644 --- a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayer.java +++ b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayer.java @@ -1,11 +1,11 @@ package net.minelink.ctplus.nms; +import com.google.common.collect.ImmutableMultimap; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; - import java.util.Map; import java.util.UUID; - +import com.mojang.authlib.properties.PropertyMap; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ClientInformation; import net.minecraft.server.level.ServerLevel; @@ -31,12 +31,13 @@ public NpcIdentity getNpcIdentity() { public static NpcPlayer valueOf(Player player) { MinecraftServer minecraftServer = MinecraftServer.getServer(); ServerLevel worldServer = ((CraftWorld) player.getWorld()).getHandle(); - GameProfile gameProfile = new GameProfile(UUID.randomUUID(), NpcNameGeneratorFactory.getNameGenerator().generate(player)); ClientInformation clientInformation = ((CraftPlayer) player).getHandle().clientInformation(); - for (Map.Entry entry : ((CraftPlayer) player).getProfile().getProperties().entries()) { - gameProfile.getProperties().put(entry.getKey(), entry.getValue()); + ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); + for (Map.Entry entry : ((CraftPlayer) player).getProfile().properties().entries()) { + builder.put(entry.getKey(), entry.getValue()); } + GameProfile gameProfile = new GameProfile(UUID.randomUUID(), NpcNameGeneratorFactory.getNameGenerator().generate(player), new PropertyMap(builder.build())); NpcPlayer npcPlayer = new NpcPlayer(minecraftServer, worldServer, gameProfile, clientInformation); npcPlayer.identity = new NpcIdentity(player); diff --git a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayerHelperImpl.java b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayerHelperImpl.java index b57e7eef4a..50a0cf43d1 100644 --- a/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayerHelperImpl.java +++ b/plugins/combattagplus-paper/src/main/java/net/minelink/ctplus/nms/NpcPlayerHelperImpl.java @@ -5,7 +5,6 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.EnumMap; import java.util.List; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtIo; @@ -18,6 +17,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.NameAndId; import net.minecraft.util.ProblemReporter; import net.minecraft.world.ItemStackWithSlot; import net.minecraft.world.entity.EntityEquipment; @@ -27,9 +27,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.storage.PlayerDataStorage; -import net.minecraft.world.level.storage.TagValueInput; import net.minecraft.world.level.storage.TagValueOutput; -import net.minecraft.world.level.storage.ValueInput; import net.minelink.ctplus.compat.base.NpcIdentity; import net.minelink.ctplus.compat.base.NpcPlayerHelper; import org.bukkit.Bukkit; @@ -47,7 +45,8 @@ public Player spawn(Player player) { Location l = player.getLocation(); npcPlayer.spawnIn(worldServer); - npcPlayer.forceSetPositionRotation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); + npcPlayer.snapTo(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); + npcPlayer.connection.resetPosition(); npcPlayer.gameMode.setLevel(worldServer); npcPlayer.invulnerableTime = 0; @@ -124,7 +123,7 @@ public void updateEquipment(Player player) { List> list = Lists.newArrayList(); list.add(Pair.of(slot, item)); Packet packet = new ClientboundSetEquipmentPacket(entity.getId(), list); - entity.level().chunkSource.broadcast(entity, packet); + entity.level().chunkSource.sendToTrackingPlayers(entity, packet); } } @@ -141,7 +140,7 @@ public void syncOffline(Player player) { if (p != null && p.isOnline()) return; PlayerDataStorage worldStorage = ((CraftWorld) Bukkit.getWorlds().getFirst()).getHandle().getServer().playerDataStorage; - CompoundTag playerNbt = worldStorage.load(identity.getName(), identity.getId().toString(), ProblemReporter.DISCARDING).orElse(null); + CompoundTag playerNbt = worldStorage.load(new NameAndId(identity.getId(), identity.getName())).orElse(null); playerNbt.putShort("Air", (short) entity.getAirSupply()); // Health is now just a float; fractional is not stored separately. (1.12) diff --git a/plugins/exilepearl-paper/build.gradle.kts b/plugins/exilepearl-paper/build.gradle.kts index 09dbd03380..735f8d4088 100644 --- a/plugins/exilepearl-paper/build.gradle.kts +++ b/plugins/exilepearl-paper/build.gradle.kts @@ -18,5 +18,5 @@ dependencies { compileOnly(project(":plugins:banstick-paper")) compileOnly(project(":plugins:randomspawn-paper")) - compileOnly(files("../../ansible/src/paper-plugins/BreweryX-3.6.0.jar")) + compileOnly(files("../../ansible/src/paper-plugins/BreweryX-3.6.3.jar")) } diff --git a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/ExilePearlApi.java b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/ExilePearlApi.java index f9249e169c..eb8872c3cd 100644 --- a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/ExilePearlApi.java +++ b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/ExilePearlApi.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.UUID; import net.minelink.ctplus.compat.base.NpcIdentity; -import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -75,6 +74,11 @@ public interface ExilePearlApi extends Plugin, PearlAccess, PearlLogger, PlayerP */ boolean isPlayerTagged(UUID uid); + /** + * Gets whether a player would spawn a combat tagger on logout + */ + boolean wouldSpawnNpc(Player player); + /** * Gets a player as a tagged NPC entity. *

diff --git a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/core/ExilePearlCore.java b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/core/ExilePearlCore.java index 4d097af8ab..84f61ba143 100644 --- a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/core/ExilePearlCore.java +++ b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/core/ExilePearlCore.java @@ -25,6 +25,7 @@ import isaac.bastion.manager.BastionBlockManager; import net.minelink.ctplus.CombatTagPlus; import net.minelink.ctplus.compat.base.NpcIdentity; +import net.minelink.ctplus.task.SafeLogoutTask; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; @@ -506,6 +507,29 @@ public boolean isPlayerTagged(UUID uid) { return false; } + @Override + public boolean wouldSpawnNpc(Player player) { + if (player.isDead()) return false; + + UUID uid = player.getUniqueId(); + boolean isTagged = combatTag.getTagManager().isTagged(uid); + if (!isTagged && !combatTag.getSettings().alwaysSpawn()) return false; + + // Do nothing if player is not within enabled world + if (combatTag.getSettings().getDisabledWorlds().contains(player.getWorld().getName())) return false; + + // Do nothing if a player logs off in combat in a WorldGuard protected region + if (!combatTag.getHookManager().isPvpEnabledAt(player.getLocation())) return false; + + // Do nothing if player has permission + if (player.hasPermission("ctplus.bypass.tag")) return false; + + // Do nothing if player has safely logged out + if (SafeLogoutTask.isFinished(player)) return false; + + return true; + } + @Override public NpcIdentity getPlayerAsTaggedNpc(Player player) { if (isCombatTagEnabled()) { diff --git a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/holder/BlockHolder.java b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/holder/BlockHolder.java index 6e0db620ca..485256f6b0 100644 --- a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/holder/BlockHolder.java +++ b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/holder/BlockHolder.java @@ -8,6 +8,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Nameable; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Container; @@ -88,7 +89,7 @@ public HolderVerifyResult validate(final ExilePearl pearl) { //double chests sometimes don't load their inventories properly if the chunk has just been loaded. //To fix this, we have to manually check for the other chest half adjacent to this one - if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST) { + if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(block.getType())) { for (Block relative : WorldUtils.getPlanarBlockSides(block, true)) { if (relative.getType() != block.getType()) { continue; diff --git a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/listener/PlayerListener.java b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/listener/PlayerListener.java index 337b951cce..0114139639 100644 --- a/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/listener/PlayerListener.java +++ b/plugins/exilepearl-paper/src/main/java/com/devotedmc/ExilePearl/listener/PlayerListener.java @@ -1,6 +1,5 @@ package com.devotedmc.ExilePearl.listener; -import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent; import com.devotedmc.ExilePearl.ExilePearl; import com.devotedmc.ExilePearl.ExilePearlApi; import com.devotedmc.ExilePearl.ExileRule; @@ -27,7 +26,9 @@ import java.util.logging.Level; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import net.minelink.ctplus.Npc; import net.minelink.ctplus.compat.base.NpcIdentity; +import net.minelink.ctplus.event.NpcDespawnEvent; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Chunk; @@ -268,19 +269,17 @@ public void onInventoryMoveItemEvent(InventoryMoveItemEvent e) { * * @param event The event args */ - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + @EventHandler(priority = EventPriority.MONITOR) public void onPlayerQuit(PlayerQuitEvent event) { Player imprisoner = event.getPlayer(); - // Don't drop if the player is tagged - if (pearlApi.isPlayerTagged(imprisoner.getUniqueId())) { + if (pearlApi.wouldSpawnNpc(imprisoner)) { return; } Location loc = imprisoner.getLocation(); Inventory inv = imprisoner.getInventory(); removePearlFromInventory(inv, loc); - imprisoner.saveData(); } public void removePearlFromInventory(Inventory inv, Location loc) { @@ -296,17 +295,14 @@ public void removePearlFromInventory(Inventory inv, Location loc) { } } - @EventHandler - public void onNPCDespawn(EntityRemoveFromWorldEvent event) { - Entity entity = event.getEntity(); - if (!(entity instanceof Player player)) { - return; - } - if (!entity.hasMetadata("NPC")) { + @EventHandler(priority = EventPriority.LOW) + public void onNPCDespawn(NpcDespawnEvent event) { + Npc npc = event.getNpc(); + Player player = npc.getEntity(); + if (Bukkit.getPlayer(npc.getIdentity().getId()) != null) { return; } removePearlFromInventory(player.getInventory(), player.getLocation()); - player.saveData(); } /** @@ -1309,8 +1305,8 @@ public void loadConfig(PearlConfig config) { ItemStack resultItem = new ItemStack(Material.STONE_BUTTON, 1); ItemMeta im = resultItem.getItemMeta(); // TODO: This should use the new enchantment glint component, but because exilepearl - // depends on the unbreaking enchantment to determine whether or not something is a pearl (why?????), it does not - im.addEnchant(Enchantment.UNBREAKING, 1, true); + // depends on the unbreaking enchantment to determine whether or not something is a pearl (why?????), it does not + im.addEnchant(Enchantment.UNBREAKING, 1, true); im.addItemFlags(ItemFlag.HIDE_ENCHANTS); resultItem.setItemMeta(im); diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java index 344749d9c9..f04a7fc9df 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java @@ -25,6 +25,7 @@ import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.Container; import org.bukkit.block.Dispenser; @@ -94,6 +95,7 @@ public FactoryModManager(FactoryMod plugin, Material factoryInteractionMaterial, possibleInteractionBlock.add(Material.CRAFTING_TABLE); possibleInteractionBlock.add(Material.FURNACE); possibleInteractionBlock.add(Material.CHEST); + possibleInteractionBlock.addAll(Tag.COPPER_CHESTS.getValues()); possibleInteractionBlock.add(Material.BARREL); possibleInteractionBlock.add(Material.TRAPPED_CHEST); diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 008366211d..7e0ccacae1 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -5,8 +5,6 @@ import com.github.igotyou.FactoryMod.events.RecipeExecuteEvent; import com.github.igotyou.FactoryMod.interactionManager.IInteractionManager; import com.github.igotyou.FactoryMod.powerManager.FurnacePowerManager; -import com.github.igotyou.FactoryMod.utility.Direction; -import com.github.igotyou.FactoryMod.utility.IIOFInventoryProvider; import com.github.igotyou.FactoryMod.powerManager.IPowerManager; import com.github.igotyou.FactoryMod.recipes.IRecipe; import com.github.igotyou.FactoryMod.recipes.InputRecipe; @@ -17,8 +15,11 @@ import com.github.igotyou.FactoryMod.repairManager.IRepairManager; import com.github.igotyou.FactoryMod.repairManager.PercentageHealthRepairManager; import com.github.igotyou.FactoryMod.structures.FurnCraftChestStructure; +import com.github.igotyou.FactoryMod.utility.Direction; +import com.github.igotyou.FactoryMod.utility.IIOFInventoryProvider; import com.github.igotyou.FactoryMod.utility.IOSelector; import com.github.igotyou.FactoryMod.utility.LoggingUtils; +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -26,15 +27,14 @@ import java.util.Map; import java.util.UUID; import java.util.function.Function; - -import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Barrel; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Chest; -import org.bukkit.block.Barrel; import org.bukkit.block.Furnace; import org.bukkit.entity.Player; import org.bukkit.inventory.FurnaceInventory; @@ -108,7 +108,7 @@ public FurnCraftChestFactory(IInteractionManager im, IRepairManager rm, IPowerMa */ public Inventory getInventory() { // do not need to check for barrels because they are not included in the getChest() function, which is used for double chest detection/force loading - if (getChest().getType() != Material.CHEST && getChest().getType() != Material.TRAPPED_CHEST) { + if (getChest().getType() != Material.CHEST && getChest().getType() != Material.TRAPPED_CHEST && !Tag.COPPER_CHESTS.isTagged(getChest().getType())) { return null; } Chest chestBlock = (Chest) (getChest().getState()); @@ -144,7 +144,7 @@ private void getInventoriesForIoType(List combinedInvList, BlockFace facing = getFacing(); for (BlockFace relativeFace : ioTypeFunc.apply(getFurnaceIOSelector()).apply(facing)) { Block relBlock = fblock.getRelative(relativeFace); - if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(relBlock.getType())) { combinedInvList.add(((Chest) relBlock.getState()).getInventory()); } if (relBlock.getType() == Material.BARREL) { @@ -154,7 +154,7 @@ private void getInventoriesForIoType(List combinedInvList, Block tblock = fccs.getCraftingTable(); for (BlockFace relativeFace : ioTypeFunc.apply(getTableIOSelector()).apply(facing)) { Block relBlock = tblock.getRelative(relativeFace); - if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(relBlock.getType())) { combinedInvList.add(((Chest) relBlock.getState()).getInventory()); } if (relBlock.getType() == Material.BARREL) { diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/Sorter.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/Sorter.java index 41a0368100..775d4f5ab0 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/Sorter.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/Sorter.java @@ -14,6 +14,7 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; @@ -171,7 +172,7 @@ public void sortStack() { for (BlockFace bf : WorldUtils.ALL_SIDES) { if (center.getRelative(bf).getState() instanceof InventoryHolder) { Block b = center.getRelative(bf); - if (b.getType() == Material.CHEST || b.getType() == Material.TRAPPED_CHEST) { + if (b.getType() == Material.CHEST || b.getType() == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(b.getType())) { // load adjacent chunk for double chest MultiBlockStructure.getAdjacentBlocks(b); } diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/CompactItemListener.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/CompactItemListener.java index 068bdbebd0..a3eca28630 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/CompactItemListener.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/CompactItemListener.java @@ -4,6 +4,8 @@ import com.github.igotyou.FactoryMod.events.FactoryActivateEvent; import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; import io.papermc.paper.event.player.PlayerLoomPatternSelectEvent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; @@ -168,6 +170,25 @@ public void cartographyCopyEvent(InventoryClickEvent e) { } } + /** + * Prevents players from using compacted items in stonecutters + */ + @EventHandler + public void stonecutterEvent(InventoryClickEvent e) { + if (e.getCurrentItem() == null) return; + + if (e.getCurrentItem().getType() == Material.AIR) return; + + if (e.getInventory().getType() == InventoryType.STONECUTTER) { + if (e.getSlotType() == InventoryType.SlotType.RESULT) { + if (isCompacted(e.getInventory().getItem(0))) { + e.setCancelled(true); + e.getWhoClicked().sendMessage(Component.text("You can not use compacted items in a stonecutter", NamedTextColor.RED)); + } + } + } + } + private boolean isCompacted(ItemStack is) { if (is == null) { return false; diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java index 68555f5fc2..7e6ccbcc2c 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java @@ -5,8 +5,10 @@ import com.github.igotyou.FactoryMod.powerManager.FurnacePowerManager; import com.github.igotyou.FactoryMod.structures.MultiBlockStructure; import java.util.List; +import org.bukkit.ExplosionResult; import org.bukkit.GameMode; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Furnace; @@ -94,6 +96,9 @@ public void redstoneChange(BlockRedstoneEvent evt) { */ @EventHandler(priority = EventPriority.HIGHEST) public void explosionListener(EntityExplodeEvent e) { + if (e.getExplosionResult() == ExplosionResult.KEEP || e.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) { + return; + } List blocks = e.blockList(); for (Block block : blocks) { if (manager.isPossibleInteractionBlock(block.getType())) { @@ -131,7 +136,7 @@ public void playerInteract(PlayerInteractEvent evt) { factory.getInteractionManager().rightClick(player, block, blockFace); } else { // check if chest is other half of double chest - if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST) { + if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(block.getType())) { for (Block b : MultiBlockStructure.searchForBlockOnSides(block, block.getType())) { Factory f = manager.getFactoryAt(b); if (f != null) { @@ -150,7 +155,7 @@ public void playerInteract(PlayerInteractEvent evt) { } } else { // check if chest is other half of double chest - if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST) { + if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(block.getType())) { for (Block b : MultiBlockStructure.searchForBlockOnAllSides(block, block.getType())) { Factory f = manager.getFactoryAt(b); if (f != null) { diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java index f62df27f92..fa241ac833 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java @@ -2,13 +2,13 @@ import com.github.igotyou.FactoryMod.FactoryMod; import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; - -import java.util.*; - import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; +import java.util.*; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import vg.civcraft.mc.civmodcore.inventory.ClonedInventory; +import vg.civcraft.mc.civmodcore.inventory.InventoryUtils; import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; import vg.civcraft.mc.civmodcore.inventory.items.MetaUtils; @@ -69,6 +69,12 @@ public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChe for (ItemStack is : inputInv.getContents()) { if (is != null) { if (compactable(is, im)) { + ItemStack compacted = is.clone(); + compactStack(compacted); + if (!InventoryUtils.safelyAddItemsToInventory( + ClonedInventory.cloneInventory(outputInv), new ItemStack[]{compacted})) { + return false; // does not fit in chest + } if (input.removeSafelyFrom(inputInv)) { compact(is, inputInv, outputInv); } diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java index e3624713ca..a4a6eb82c8 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java @@ -1,16 +1,16 @@ package com.github.igotyou.FactoryMod.recipes; import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import java.util.Objects; - -import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import vg.civcraft.mc.civmodcore.inventory.ClonedInventory; +import vg.civcraft.mc.civmodcore.inventory.InventoryUtils; import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; @@ -21,7 +21,7 @@ */ public class DecompactingRecipe extends InputRecipe { - private String compactedLore; + private final String compactedLore; public DecompactingRecipe(String identifier, ItemMap input, String name, int productionTime, String compactedLore) { @@ -46,18 +46,23 @@ public boolean enoughMaterialAvailable(Inventory inputInv) { @Override public EffectFeasibility evaluateEffectFeasibility(Inventory inputInv, Inventory outputInv) { - boolean isFeasible = Arrays.stream(inputInv.getContents()) - .filter(Objects::nonNull) - .filter(this::isDecompactable) - .map(it -> { - ItemStack removeClone = it.clone(); - removeClone.setAmount(1); - removeCompactLore(removeClone); - ItemMap toAdd = new ItemMap(removeClone); - toAdd.addItemAmount(removeClone, CompactingRecipe.getCompactStackSize(removeClone.getType())); - return toAdd; - }) - .allMatch(it -> it.fitsIn(outputInv)); + boolean isFeasible = true; + for (ItemStack itemStack : inputInv.getContents()) { + if (itemStack != null) { + if (isDecompactable(itemStack)) { + ItemStack removeClone = itemStack.clone(); + removeClone.setAmount(1); + removeCompactLore(removeClone); + ItemMap toAdd = new ItemMap(); + toAdd.addItemAmount(removeClone, CompactingRecipe.getCompactStackSize(removeClone.getType())); + if (!InventoryUtils.safelyAddItemsToInventory( + ClonedInventory.cloneInventory(outputInv), toAdd.getItemStackRepresentation().toArray(new ItemStack[0]))) { + isFeasible = false; + break; + } + } + } + } return new EffectFeasibility( isFeasible, isFeasible ? null : "it ran out of storage space" @@ -78,16 +83,17 @@ public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChe ItemMap toAdd = new ItemMap(); removeCompactLore(removeClone); toAdd.addItemAmount(removeClone, CompactingRecipe.getCompactStackSize(removeClone.getType())); - if (toAdd.fitsIn(outputInv)) { //fits in chest - if (input.removeSafelyFrom(inputInv)) { //remove extra input - if (toRemove.removeSafelyFrom(inputInv)) { //remove one compacted item - for (ItemStack add : toAdd.getItemStackRepresentation()) { - outputInv.addItem(add); - } + ItemStack[] itemsToAdd = toAdd.getItemStackRepresentation().toArray(new ItemStack[0]); + if (!InventoryUtils.safelyAddItemsToInventory( + ClonedInventory.cloneInventory(outputInv), itemsToAdd)) { + return false; // does not fit in chest + } + if (input.removeSafelyFrom(inputInv)) { //remove extra input + if (toRemove.removeSafelyFrom(inputInv)) { //remove one compacted item + for (ItemStack add : toAdd.getItemStackRepresentation()) { + outputInv.addItem(add); } } - } else { // does not fit in chest - return false; } break; } diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/EffectFeasibility.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/EffectFeasibility.java old mode 100755 new mode 100644 diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java index 2298f9ff09..037672dc6b 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java @@ -12,6 +12,8 @@ import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import vg.civcraft.mc.civmodcore.inventory.ClonedInventory; +import vg.civcraft.mc.civmodcore.inventory.InventoryUtils; import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; @@ -21,11 +23,11 @@ */ public class ProductionRecipe extends InputRecipe { - private ItemMap output; - private ItemStack recipeRepresentation; - private ProductionRecipeModifier modifier; - private Random rng; - private DecimalFormat decimalFormatting; + private final ItemMap output; + private final ItemStack recipeRepresentation; + private final ProductionRecipeModifier modifier; + private final Random rng; + private final DecimalFormat decimalFormatting; public ProductionRecipe( String identifier, @@ -48,15 +50,6 @@ public ItemMap getOutput() { return output; } - public ItemMap getAdjustedOutput(int rank, int runs) { - ItemMap im = output.clone(); - if (modifier != null) { - im.multiplyContent(modifier.getFactor(rank, runs)); - return im; - } - return im; - } - public ItemMap getGuaranteedOutput(int rank, int runs) { if (modifier == null) { return output.clone(); @@ -69,10 +62,6 @@ public ItemMap getGuaranteedOutput(int rank, int runs) { return adjusted; } - public int getCurrentMultiplier(Inventory i) { - return input.getMultiplesContainedIn(i); - } - @Override public List getOutputRepresentation(Inventory i, FurnCraftChestFactory fccf) { if (i == null || fccf == null) { @@ -91,7 +80,7 @@ public List getOutputRepresentation(Inventory i, FurnCraftChestFactor } int possibleRuns = input.getMultiplesContainedIn(i); for (ItemStack is : stacks) { - ItemUtils.addLore(is, ChatColor.GREEN + "Enough materials for " + String.valueOf(possibleRuns) + " runs"); + ItemUtils.addLore(is, ChatColor.GREEN + "Enough materials for " + possibleRuns + " runs"); } return stacks; } @@ -104,16 +93,9 @@ public List getInputRepresentation(Inventory i, FurnCraftChestFactory return createLoredStacksForInfo(i); } - public List getGuaranteedOutput(Inventory i, FurnCraftChestFactory fccf) { - if (i == null) { - return input.getItemStackRepresentation(); - } - return createLoredStacksForInfo(i); - } - @Override public EffectFeasibility evaluateEffectFeasibility(Inventory inputInv, Inventory outputInv) { - boolean isFeasible = input.fitsIn(outputInv); + boolean isFeasible = InventoryUtils.safelyAddItemsToInventory(ClonedInventory.cloneInventory(outputInv), output.getItemStackRepresentation().toArray(new ItemStack[0])); String reasonSnippet = isFeasible ? null : "it ran out of storage space"; return new EffectFeasibility( isFeasible, @@ -140,8 +122,9 @@ public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChe } } if (toRemove.isContainedIn(inputInv)) { - if (!toAdd.fitsIn(outputInv)) { // does not fit in chest - return false; + ItemStack[] itemsToAdd = toAdd.getItemStackRepresentation().toArray(new ItemStack[0]); + if (!InventoryUtils.safelyAddItemsToInventory(ClonedInventory.cloneInventory(outputInv), itemsToAdd)) { + return false; // does not fit in chest } if (toRemove.removeSafelyFrom(inputInv)) { for (ItemStack is : toAdd.getItemStackRepresentation()) { diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java index 10fde22ae1..f18e5bd47c 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java @@ -4,6 +4,7 @@ import java.util.List; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -26,6 +27,9 @@ public FurnCraftChestStructure(Block center) { LinkedList chestBlocks = new LinkedList<>(); chestBlocks.addAll(searchForBlockOnAllSides(center, Material.CHEST)); chestBlocks.addAll(searchForBlockOnAllSides(center, Material.TRAPPED_CHEST)); + for (Material chest : Tag.COPPER_CHESTS.getValues()) { + chestBlocks.addAll(searchForBlockOnAllSides(center, chest)); + } chestBlocks.addAll(searchForBlockOnAllSides(center, Material.BARREL)); for (Block b : chestBlocks) { BlockFace chestFace = center.getFace(b); @@ -56,7 +60,8 @@ public void recheckComplete() { && chest != null && (chest.getBlock().getType() == Material.CHEST || chest.getBlock().getType() == Material.TRAPPED_CHEST - || chest.getBlock().getType() == Material.BARREL); + || chest.getBlock().getType() == Material.BARREL + || Tag.COPPER_CHESTS.isTagged(chest.getBlock().getType())); } public boolean isComplete() { @@ -79,6 +84,10 @@ public Block getChest() { Material.CHEST); MultiBlockStructure.searchForBlockOnAllSides(chest.getBlock(), Material.TRAPPED_CHEST); + for (Material type : Tag.COPPER_CHESTS.getValues()) { + MultiBlockStructure.searchForBlockOnAllSides(chest.getBlock(), + type); + } // not necessary to check for more blocks if the "chest" is a barrel because it cannot be double @@ -90,7 +99,8 @@ public boolean relevantBlocksDestroyed() { && furnace.getBlock().getType() != Material.FURNACE && chest.getBlock().getType() != Material.CHEST && chest.getBlock().getType() != Material.TRAPPED_CHEST - && chest.getBlock().getType() != Material.BARREL; + && chest.getBlock().getType() != Material.BARREL + && !Tag.COPPER_CHESTS.isTagged(chest.getBlock().getType()); } public List getRelevantBlocks() { diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java index 76cc4cfddc..e372ad317a 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java @@ -24,6 +24,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.configuration.ConfigurationSection; @@ -216,7 +217,8 @@ private void loadFromFile(File f, Map eggs) { sortedList.add(center); //we cant guarantee that this will work, it might very well fail for partially broken factories, but it's the best thing I got if (blocks.get(0).getBlock().getType() == Material.CHEST - || blocks.get(0).getBlock().getType() == Material.TRAPPED_CHEST) { + || blocks.get(0).getBlock().getType() == Material.TRAPPED_CHEST + || Tag.COPPER_CHESTS.isTagged(blocks.get(0).getBlock().getType())) { sortedList.add(blocks.get(1)); sortedList.add(blocks.get(0)); } else { diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java index cdae3aced4..0df8c63042 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java @@ -12,6 +12,7 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; @@ -64,7 +65,7 @@ private Clickable getIoButton(Direction dir) { private Clickable getIoClickable(Material adjacentType, Direction dir, String dirLabel) { IOSelector.IOState dirState = ioSelector.getState(dir); - boolean chestMissing = adjacentType != Material.CHEST && adjacentType != Material.TRAPPED_CHEST && adjacentType != Material.BARREL; + boolean chestMissing = adjacentType != Material.CHEST && adjacentType != Material.TRAPPED_CHEST && adjacentType != Material.BARREL && !Tag.COPPER_CHESTS.isTagged(adjacentType); ItemStack display; if (chestMissing) { display = new ItemStack(Material.BARRIER); diff --git a/plugins/finale-paper/build.gradle.kts b/plugins/finale-paper/build.gradle.kts index 967894b2a5..a3c3afed31 100644 --- a/plugins/finale-paper/build.gradle.kts +++ b/plugins/finale-paper/build.gradle.kts @@ -14,6 +14,6 @@ dependencies { compileOnly(project(":plugins:namelayer-paper")) compileOnly(project(":plugins:citadel-paper")) compileOnly(project(":plugins:combattagplus-paper")) - - compileOnly(libs.protocollib) + compileOnly(libs.mythic.dist) + compileOnly(libs.packetevents.spigot) } diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/ConfigParser.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/ConfigParser.java index 8568d23c6b..07e268e149 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/ConfigParser.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/ConfigParser.java @@ -58,6 +58,10 @@ public class ConfigParser { private CombatConfig combatConfig; private boolean fireworkExplosions; + private int maceCooldown; + private double maceMaxDamage; + private float windCooldown; + public ConfigParser(Finale plugin) { this.plugin = plugin; } @@ -110,6 +114,19 @@ public boolean isFireworkExplosions() { return fireworkExplosions; } + public int getMaceCooldown() { + return maceCooldown; + } + + public double getMaceMaxDamage() { + return maceMaxDamage; + } + + public float getWindCooldown() { + return windCooldown; + } + + public FinaleManager parse() { plugin.info("Parsing Finale config..."); plugin.saveDefaultConfig(); @@ -180,6 +197,10 @@ public FinaleManager parse() { fireworkExplosions = config.getBoolean("fireworkExplosions"); rebalanceTntMinecart = config.getBoolean("rebalanceTntMinecart"); + maceCooldown = config.getInt("mace.cooldown"); + maceMaxDamage = config.getInt("mace.max_damage"); + windCooldown = config.getInt("mace.wind_cooldown"); + // Initialize the manager manager = new FinaleManager(debug, attackEnabled, attackSpeed, invulTicksEnabled, invulnerableTicks, regenEnabled, ctpOnLogin, regenhandler, weapMod, armourMod, allyHandler, arrowHandler, tridentHandler, shieldHandler, crossbowHandler, gappleHandler, potionHandler, tippedArrowMod, blockRestrictionHandler, combatConfig, warpFruitTracker); diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/Finale.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/Finale.java index a640305a65..e68d65cf8d 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/Finale.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/Finale.java @@ -1,6 +1,5 @@ package com.github.maxopoly.finale; -import com.comphenix.protocol.ProtocolLibrary; import com.github.maxopoly.finale.command.AllyCommand; import com.github.maxopoly.finale.command.CardinalCommand; import com.github.maxopoly.finale.command.CombatConfigCommand; @@ -16,6 +15,7 @@ import com.github.maxopoly.finale.listeners.EnchantmentDisableListener; import com.github.maxopoly.finale.listeners.FinaleListener; import com.github.maxopoly.finale.listeners.GappleListener; +import com.github.maxopoly.finale.listeners.MaceListener; import com.github.maxopoly.finale.listeners.MeteoricIronSlownessListener; import com.github.maxopoly.finale.listeners.NetheriteFireResistanceListener; import com.github.maxopoly.finale.listeners.PearlCoolDownListener; @@ -28,6 +28,7 @@ import com.github.maxopoly.finale.listeners.VelocityFixListener; import com.github.maxopoly.finale.listeners.WarpFruitListener; import com.github.maxopoly.finale.listeners.WeaponModificationListener; +import com.github.maxopoly.finale.mob.BleezeAI; import com.github.maxopoly.finale.overlay.ScoreboardHUD; import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; @@ -81,13 +82,10 @@ private void initExternalManagers() { @Override public void onDisable() { if (manager != null) { - manager.getAllyHandler().save(); - manager.getAllyHandler().shutdown(); + manager.unregister(); } HandlerList.unregisterAll(this); - ProtocolLibrary.getProtocolManager().removePacketListeners(this); - ProtocolLibrary.getProtocolManager().getAsynchronousManager().unregisterAsyncHandlers(this); Bukkit.getScheduler().cancelTasks(this); } @@ -134,6 +132,12 @@ private void registerListener() { } Bukkit.getPluginManager().registerEvents(new CrossbowListener(config.isFireworkExplosions()), this); Bukkit.getPluginManager().registerEvents(new GappleListener(), this); + + getServer().getPluginManager().registerEvents(new MaceListener(config.getMaceCooldown(), config.getMaceMaxDamage(), config.getWindCooldown()), this); + + if (getServer().getPluginManager().isPluginEnabled("MythicMobs")) { + new BleezeAI().start(); + } } public PearlCoolDownListener getPearlCoolDownListener() { diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/FinaleManager.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/FinaleManager.java index f880e84c7d..25e57bbd80 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/FinaleManager.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/FinaleManager.java @@ -1,27 +1,34 @@ package com.github.maxopoly.finale; -import com.comphenix.protocol.ProtocolLibrary; import com.github.maxopoly.finale.combat.AsyncPacketHandler; import com.github.maxopoly.finale.combat.CPSHandler; import com.github.maxopoly.finale.combat.CombatConfig; import com.github.maxopoly.finale.combat.SprintHandler; -import com.github.maxopoly.finale.misc.*; +import com.github.maxopoly.finale.misc.ArmourModifier; +import com.github.maxopoly.finale.misc.BlockRestrictionHandler; +import com.github.maxopoly.finale.misc.GappleHandler; +import com.github.maxopoly.finale.misc.SaturationHealthRegenHandler; +import com.github.maxopoly.finale.misc.ShieldHandler; +import com.github.maxopoly.finale.misc.TippedArrowModifier; +import com.github.maxopoly.finale.misc.TridentHandler; +import com.github.maxopoly.finale.misc.WeaponModifier; import com.github.maxopoly.finale.misc.ally.AllyHandler; import com.github.maxopoly.finale.misc.arrow.ArrowHandler; import com.github.maxopoly.finale.misc.crossbow.CrossbowHandler; import com.github.maxopoly.finale.misc.warpfruit.WarpFruitTracker; import com.github.maxopoly.finale.potion.PotionHandler; - +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.event.PacketListenerCommon; +import com.github.retrooper.packetevents.event.PacketListenerPriority; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; - -import org.bukkit.Bukkit; import org.bukkit.event.entity.EntityDamageEvent; public class FinaleManager { + private final PacketListenerCommon listenerCommon; private boolean debug; private boolean attackSpeedEnabled; private double attackSpeed; @@ -82,7 +89,7 @@ public FinaleManager(boolean debug, boolean attackSpeedEnabled, double attackSpe this.sprintHandler = new SprintHandler(); this.combatHandler = new AsyncPacketHandler(combatConfig); - ProtocolLibrary.getProtocolManager().addPacketListener(this.combatHandler); + this.listenerCommon = PacketEvents.getAPI().getEventManager().registerListener(this.combatHandler, PacketListenerPriority.HIGH); } public AsyncPacketHandler getCombatHandler() { @@ -184,4 +191,11 @@ public WarpFruitTracker getWarpFruitTracker() { public Set getChemtrails() { return chemtrails; } + + public void unregister() { + allyHandler.save(); + allyHandler.shutdown(); + + PacketEvents.getAPI().getEventManager().unregisterListener(listenerCommon); + } } diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/AsyncPacketHandler.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/AsyncPacketHandler.java index 0d5dca5688..dfc907daff 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/AsyncPacketHandler.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/AsyncPacketHandler.java @@ -1,27 +1,25 @@ package com.github.maxopoly.finale.combat; -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.wrappers.BlockPosition; -import com.comphenix.protocol.wrappers.EnumWrappers; -import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction; -import com.comphenix.protocol.wrappers.EnumWrappers.Hand; -import com.comphenix.protocol.wrappers.EnumWrappers.PlayerDigType; -import com.comphenix.protocol.wrappers.WrappedEnumEntityUseAction; import com.github.maxopoly.finale.Finale; +import com.github.retrooper.packetevents.event.PacketListener; +import com.github.retrooper.packetevents.event.PacketReceiveEvent; +import com.github.retrooper.packetevents.protocol.packettype.PacketType; +import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; +import com.github.retrooper.packetevents.protocol.player.DiggingAction; +import com.github.retrooper.packetevents.protocol.player.InteractionHand; +import com.github.retrooper.packetevents.util.Vector3i; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientAnimation; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging; import com.google.common.collect.Sets; - import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; - import net.md_5.bungee.api.ChatColor; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.damagesource.DamageSources; import net.minecraft.world.entity.ai.attributes.Attributes; import org.bukkit.Bukkit; @@ -33,7 +31,6 @@ import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Damageable; -import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -41,36 +38,34 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitRunnable; -public class AsyncPacketHandler extends PacketAdapter implements Listener { +public class AsyncPacketHandler implements Listener, PacketListener { - private CombatConfig cc; + private final CombatConfig cc; public AsyncPacketHandler(CombatConfig cc) { - super(Finale.getPlugin(), ListenerPriority.HIGH, PacketType.Play.Client.USE_ENTITY, PacketType.Play.Client.ARM_ANIMATION, PacketType.Play.Client.BLOCK_DIG, PacketType.Play.Client.ENTITY_ACTION); - this.cc = cc; Bukkit.getPluginManager().registerEvents(this, Finale.getPlugin()); } - private Set isDigging = Sets.newConcurrentHashSet(); - private Map lastRemovals = new ConcurrentHashMap<>(); - private Map lastStartBreaks = new ConcurrentHashMap<>(); + private final Set isDigging = Sets.newConcurrentHashSet(); + private final Map lastRemovals = new ConcurrentHashMap<>(); + private final Map lastStartBreaks = new ConcurrentHashMap<>(); @Override - public void onPacketReceiving(PacketEvent event) { - PacketType packetType = event.getPacketType(); + public void onPacketReceive(PacketReceiveEvent event) { + PacketTypeCommon packetType = event.getPacketType(); CPSHandler cpsHandler = Finale.getPlugin().getManager().getCPSHandler(); - if (packetType == PacketType.Play.Client.USE_ENTITY) { + if (packetType == PacketType.Play.Client.INTERACT_ENTITY) { Player attacker = event.getPlayer(); World world = attacker.getWorld(); - PacketContainer packet = event.getPacket(); - StructureModifier actions = packet.getEnumEntityUseActions(); - EntityUseAction action = actions.read(0).getAction(); + ServerLevel level = ((CraftWorld) world).getHandle(); + + WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event); - if (action != EntityUseAction.ATTACK) { + if (packet.getAction() != WrapperPlayClientInteractEntity.InteractAction.ATTACK) { return; } event.setCancelled(true); @@ -78,15 +73,13 @@ public void onPacketReceiving(PacketEvent event) { @Override public void run() { - Entity entity = packet.getEntityModifier(event).read(0); + CraftEntity entity = level.getEntity(packet.getEntityId()).getBukkitEntity(); Damageable target = entity instanceof Damageable ? (Damageable) entity : null; if (target == null || target.isDead() || target.isInvulnerable() || !world.getUID().equals(target.getWorld().getUID()) || !(target instanceof LivingEntity)) { - if (entity instanceof CraftEntity craftEntity) { - DamageSources damageSources = ((CraftWorld) world).getHandle().damageSources(); - craftEntity.getHandle().hurt(damageSources.playerAttack(((CraftPlayer) attacker).getHandle()), (float) ((CraftPlayer) attacker).getHandle().getAttribute(Attributes.ATTACK_DAMAGE).getValue()); - } + DamageSources damageSources = ((CraftWorld) world).getHandle().damageSources(); + entity.getHandle().hurt(damageSources.playerAttack(((CraftPlayer) attacker).getHandle()), (float) ((CraftPlayer) attacker).getHandle().getAttribute(Attributes.ATTACK_DAMAGE).getValue()); return; } @@ -101,41 +94,51 @@ public void run() { return; } - CombatUtil.attack(attacker, ((CraftEntity) target).getHandle()); + if (attacker.getGameMode() == GameMode.SPECTATOR) { + attacker.setSpectatorTarget(target); + } else { + CombatUtil.attack(attacker, ((CraftEntity) target).getHandle()); + } } }.runTask(Finale.getPlugin()); } else if (packetType == PacketType.Play.Client.ENTITY_ACTION) { + WrapperPlayClientEntityAction packet = new WrapperPlayClientEntityAction(event); Player player = event.getPlayer(); - PacketContainer packet = event.getPacket(); - EnumWrappers.PlayerAction playerAction = packet.getPlayerActions().read(0); + WrapperPlayClientEntityAction.Action playerAction = packet.getAction(); SprintHandler sprintHandler = Finale.getPlugin().getManager().getSprintHandler(); - if (playerAction == EnumWrappers.PlayerAction.START_SPRINTING) { + if (playerAction == WrapperPlayClientEntityAction.Action.START_SPRINTING) { sprintHandler.startSprinting(player); - } else if (playerAction == EnumWrappers.PlayerAction.STOP_SPRINTING) { + } else if (playerAction == WrapperPlayClientEntityAction.Action.STOP_SPRINTING) { sprintHandler.stopSprinting(player); } - } else if (packetType == PacketType.Play.Client.ARM_ANIMATION) { + } else if (packetType == PacketType.Play.Client.ANIMATION) { Player attacker = event.getPlayer(); - PacketContainer packet = event.getPacket(); - Hand hand = packet.getHands().getValues().get(0); - if (hand == Hand.MAIN_HAND && !isDigging.contains(attacker.getUniqueId())) { + WrapperPlayClientAnimation packet = new WrapperPlayClientAnimation(event); + InteractionHand hand = packet.getHand(); + if (hand == InteractionHand.MAIN_HAND && !isDigging.contains(attacker.getUniqueId())) { Block targetBlock = attacker.getTargetBlockExact(4); if (targetBlock != null && targetBlock.getType() != Material.AIR) { return; } cpsHandler.updateClicks(attacker); } - } else if (packetType == PacketType.Play.Client.BLOCK_DIG) { + } else if (packetType == PacketType.Play.Client.PLAYER_DIGGING) { Player attacker = event.getPlayer(); + WrapperPlayClientPlayerDigging packet = new WrapperPlayClientPlayerDigging(event); + DiggingAction digType = packet.getAction(); + if (digType == DiggingAction.STAB) { + // no spears + event.setCancelled(true); + return; + } + if (attacker.getGameMode() != GameMode.SURVIVAL) { return; } - PacketContainer packet = event.getPacket(); - BlockPosition position = packet.getBlockPositionModifier().getValues().get(0); - PlayerDigType digType = packet.getPlayerDigTypes().getValues().get(0); - if (digType == PlayerDigType.START_DESTROY_BLOCK) { + Vector3i position = packet.getBlockPosition(); + if (digType == DiggingAction.START_DIGGING) { Block block = attacker.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); if (block.getType() == Material.BEDROCK || block.getType() == Material.BARRIER && !isDigging.contains(attacker.getUniqueId())) { isDigging.add(attacker.getUniqueId()); @@ -160,7 +163,7 @@ public void run() { cpsHandler.updateClicks(attacker); } } - } else if (digType == PlayerDigType.ABORT_DESTROY_BLOCK || digType == PlayerDigType.STOP_DESTROY_BLOCK) { + } else if (digType == DiggingAction.CANCELLED_DIGGING || digType == DiggingAction.FINISHED_DIGGING) { isDigging.remove(attacker.getUniqueId()); lastRemovals.put(attacker.getUniqueId(), System.currentTimeMillis()); } diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/CombatUtil.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/CombatUtil.java index 9eb37c1bfc..2caeb62aec 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/CombatUtil.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/CombatUtil.java @@ -3,10 +3,8 @@ import com.github.maxopoly.finale.Finale; import com.github.maxopoly.finale.combat.event.CritHitEvent; import com.github.maxopoly.finale.combat.knockback.KnockbackStrategy; - import java.util.Iterator; import java.util.List; - import net.minecraft.core.Holder; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; @@ -25,7 +23,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.boss.EnderDragonPart; +import net.minecraft.world.entity.boss.enderdragon.EnderDragonPart; import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentHelper; @@ -86,6 +84,7 @@ public static void attack(ServerPlayer attacker, Entity victim) { } dealtExtraKnockback = true; } + damage += attacker.getWeaponItem().getItem().getAttackDamageBonus(victim, damage, damagesource); boolean shouldCrit = shouldDamage && attacker.fallDistance > 0 && attacker.fallDistance > (float) (attacker.yOld - attacker.getY()) && !attacker.onGround() && !attacker.onClimbable() && !attacker.isInWater() && !attacker.hasEffect(MobEffects.BLINDNESS) && !attacker.isPassenger() && victim instanceof LivingEntity; @@ -157,7 +156,9 @@ public static void attack(ServerPlayer attacker, Entity victim) { } world.playSound(attacker, attacker.getX(), attacker.getY(), attacker.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, attacker.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility - attacker.sweepAttack(); + double d = -Mth.sin(attacker.getYRot() * (float) (Math.PI / 180.0)); + double d11 = Mth.cos(attacker.getYRot() * (float) (Math.PI / 180.0)); + attacker.level().sendParticles(ParticleTypes.SWEEP_ATTACK, attacker.getX() + d, attacker.getY(0.5), attacker.getZ() + d11, 0, d, 0.0, d11, 0.0); } if (victim instanceof ServerPlayer && victim.hurtMarked) { diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/knockback/StandardKnockback.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/knockback/StandardKnockback.java index 336b53ced8..5ad1ad591d 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/knockback/StandardKnockback.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/combat/knockback/StandardKnockback.java @@ -30,7 +30,7 @@ public void handleKnockback(Player attacker, Entity entity, float knockbackLevel double z = (-Mth.cos(attacker.getYRot() * 0.017453292F)); strength *= 1.0D - victim.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE); if (strength > 0.0) { - victim.hasImpulse = true; + victim.needsSync = true; Vec3 vec3d = victim.getDeltaMovement(); Vec3 vec3d1 = (new Vec3(x, 0.0D, z)).normalize().scale(strength); diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/DamageListener.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/DamageListener.java index 59f012085e..e8d883fb77 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/DamageListener.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/DamageListener.java @@ -105,7 +105,6 @@ public void damageEntity(EntityDamageByEntityEvent e) { if (sharpnessLevel != 0 && sharpnessModifier != null) { double damage = sharpnessModifier.modify(e.getDamage(), sharpnessLevel); e.setDamage(damage); -// Bukkit.broadcast(Component.text(damage + " -> " + e.getFinalDamage())); } } } diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/MaceListener.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/MaceListener.java new file mode 100644 index 0000000000..142d90134b --- /dev/null +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/MaceListener.java @@ -0,0 +1,65 @@ +package com.github.maxopoly.finale.listeners; + +import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent; +import io.papermc.paper.datacomponent.DataComponentTypes; +import io.papermc.paper.datacomponent.item.UseCooldown; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.entity.WindCharge; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; + +public class MaceListener implements Listener { + + private final int cooldown; + private final double maxDamage; + private final float windCooldown; + + public MaceListener(int cooldown, double maxDamage, float windCooldown) { + this.cooldown = cooldown; + this.maxDamage = maxDamage; + this.windCooldown = windCooldown; + } + + @EventHandler + public void on(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player damagerPlayer)) { + return; + } + + ItemStack item = damagerPlayer.getInventory().getItemInMainHand(); + if (item.getType() != Material.MACE) { + return; + } + + if (damagerPlayer.getCooldown(Material.MACE) > 0) { + event.setCancelled(true); + return; + } + + event.setDamage(Math.min(event.getDamage(), maxDamage)); + + damagerPlayer.setCooldown(Material.MACE, cooldown); + item.damage(2, damagerPlayer); + } + + @EventHandler + public void on(PlayerLaunchProjectileEvent event) { + if (!(event.getProjectile() instanceof WindCharge)) { + return; + } + + ItemStack item = event.getItemStack(); + item.setData(DataComponentTypes.USE_COOLDOWN, UseCooldown.useCooldown(windCooldown).build()); + } + + @EventHandler + public void on(PlayerJoinEvent event) { + // cooldowns reset on relog for some reason, so just automatically apply max cooldown + // better would be to work out how long the cooldown should actually be + event.getPlayer().setCooldown(Material.MACE, cooldown); + } +} diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/TridentListener.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/TridentListener.java index 9429c94900..87a1499bf0 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/TridentListener.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/TridentListener.java @@ -1,9 +1,7 @@ package com.github.maxopoly.finale.listeners; -import com.destroystokyo.paper.event.entity.ProjectileCollideEvent; import com.github.maxopoly.finale.Finale; import com.github.maxopoly.finale.misc.TridentHandler; -import net.minecraft.world.entity.projectile.ThrownTrident; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/WeaponModificationListener.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/WeaponModificationListener.java index 65ac1d8722..bd90255dcd 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/WeaponModificationListener.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/listeners/WeaponModificationListener.java @@ -6,6 +6,7 @@ import com.github.maxopoly.finale.misc.TippedArrowModifier; import com.github.maxopoly.finale.misc.WeaponModifier; import java.util.List; +import io.papermc.paper.datacomponent.DataComponentTypes; import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -43,6 +44,9 @@ public void weaponMod(InventoryClickEvent e) { } public void update(ItemStack is) { + // no spears + is.unsetData(DataComponentTypes.KINETIC_WEAPON); + ItemMeta im = is.getItemMeta(); ArmourModifier armourMod = Finale.getPlugin().getManager().getArmourModifier(); diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/misc/ArmourModifier.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/misc/ArmourModifier.java index ec2ee494f2..8fff49f608 100644 --- a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/misc/ArmourModifier.java +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/misc/ArmourModifier.java @@ -2,11 +2,8 @@ import java.util.HashMap; import java.util.Map; - import org.bukkit.Material; -import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; -import org.bukkit.persistence.PersistentDataType; import vg.civcraft.mc.civmodcore.inventory.CustomItem; public class ArmourModifier { diff --git a/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/mob/BleezeAI.java b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/mob/BleezeAI.java new file mode 100644 index 0000000000..ec66d88b38 --- /dev/null +++ b/plugins/finale-paper/src/main/java/com/github/maxopoly/finale/mob/BleezeAI.java @@ -0,0 +1,106 @@ +package com.github.maxopoly.finale.mob; + +import com.github.maxopoly.finale.Finale; +import io.lumine.mythic.bukkit.MythicBukkit; +import io.lumine.mythic.core.mobs.ActiveMob; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.concurrent.ThreadLocalRandom; +import org.bukkit.Bukkit; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; +import org.bukkit.util.Vector; + +public class BleezeAI { + + private final Map dataMap = new WeakHashMap<>(); + + static class BleezeData { + private int aiStopTicks; + private int headHitTicks; + } + + public void start() { + Bukkit.getScheduler().runTaskTimer(Finale.getPlugin(), () -> { + for (ActiveMob mob : MythicBukkit.inst().getMobManager().getActiveMobs()) { + if (!mob.getType().getInternalName().equals("Bleeze")) { + if (mob.getType().getInternalName().equals("BleezeMinion")) { + mob.getEntity().getBukkitEntity().leaveVehicle(); + } + continue; + } + + Mob entity = (Mob) mob.getEntity().getBukkitEntity(); + + entity.leaveVehicle(); + + if (entity.getWorld().getWeatherDuration() > 1) { + Biome biome = entity.getWorld().getBiome(entity.getLocation()); + if (biome != Biome.DESERT && biome != Biome.ERODED_BADLANDS && biome != Biome.SAVANNA && biome != Biome.SAVANNA_PLATEAU && biome != Biome.BADLANDS) { + entity.remove(); + continue; + } + } + + if (entity.getTarget() instanceof Blaze) { + entity.setTarget(null); + } + + BleezeData bleezeData = dataMap.computeIfAbsent(entity, k -> new BleezeData()); + + if (!entity.getEyeLocation().getBlock().getRelative(BlockFace.UP).isPassable()) { + bleezeData.headHitTicks += 1; + } + + if (bleezeData.headHitTicks >= 40) { + Block highest = entity.getWorld().getHighestBlockAt(entity.getLocation()); + entity.teleport(highest.getLocation().add(0.5, 1, 0.5)); + bleezeData.headHitTicks = 0; + } + + if (bleezeData.aiStopTicks > 0) { + bleezeData.aiStopTicks--; + continue; + } + + if (ThreadLocalRandom.current().nextInt(750) == 0) { + bleezeData.aiStopTicks = 320; + continue; + } + + if (entity.getTarget() == null) { + continue; + } + + Vector vec3 = entity.getVelocity(); + double d = vec3.getY(); + LivingEntity target = entity.getTarget(); + if (entity.getY() < target.getY() + 5.0 && ThreadLocalRandom.current().nextBoolean()) { + d = Math.max(0.0, d); + d += 0.1 - d * 0.6F; + } + + vec3 = new Vector(vec3.getX(), d, vec3.getZ()); + Vector vec31 = new Vector(target.getX() - entity.getX(), 0.0, target.getZ() - entity.getZ()); + if (vec31.lengthSquared() > 11 * 11) { + Vector vec32 = vec31.normalize(); + vec3 = vec3.add(new Vector(vec32.getX() * 0.1 - vec3.getX() * 0.6, 0.0, vec32.getZ() * 0.1 - vec3.getZ() * 0.6)); + } else if (vec31.lengthSquared() < 7 * 7) { + Vector vec32 = vec31.normalize().multiply(-1); + vec3 = vec3.add(new Vector(vec32.getX() * 0.1 - vec3.getX() * 0.6, 0.0, vec32.getZ() * 0.1 - vec3.getZ() * 0.6)); + } + entity.setVelocity(vec3); + + if (entity.getY() < entity.getTarget().getY() + 5) { + if (ThreadLocalRandom.current().nextInt(3) == 0) { + entity.setVelocity(entity.getVelocity().add(new Vector(0, 0.08f, 0))); + } + } + } + }, 0, 1); + } +} diff --git a/plugins/finale-paper/src/main/resources/config.yml b/plugins/finale-paper/src/main/resources/config.yml index f9a5986b00..b9854baaa5 100644 --- a/plugins/finale-paper/src/main/resources/config.yml +++ b/plugins/finale-paper/src/main/resources/config.yml @@ -95,12 +95,21 @@ gappleCooldown: cooldown: 16s #allows adjusting the attack damage of any item by its spigot material identifier weaponModification: + mace: + material: MACE + damage: 6 netheriteAxe: material: NETHERITE_AXE damage: 6 diamondAxe: material: DIAMOND_AXE damage: 5 + copperAxe: + material: COPPER_AXE + damage: 5 + copperSword: + material: COPPER_SWORD + damage: 7 ironAxe: material: IRON_AXE damage: 4 @@ -402,6 +411,11 @@ enhancedArrows: - LUCK - SLOW_FALLING +mace: + cooldown: 1200 + max_damage: 38 + wind_cooldown: 3 + # customize tipped arrows tippedArrows: night_vision: &nightvision diff --git a/plugins/finale-paper/src/main/resources/plugin.yml b/plugins/finale-paper/src/main/resources/plugin.yml index 8e9770aa59..c03181b25d 100644 --- a/plugins/finale-paper/src/main/resources/plugin.yml +++ b/plugins/finale-paper/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ main: com.github.maxopoly.finale.Finale author: Maxopoly version: ${version} depend: [CivModCore, ProtocolLib] -softdepend: [CombatTagPlus, Citadel, Bastion] +softdepend: [CombatTagPlus, Citadel, Bastion, MythicMobs] api-version: 1.21.3 permissions: finale.op: diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/HeliodorPlugin.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/HeliodorPlugin.java index b803a8969d..c8702722a8 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/HeliodorPlugin.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/HeliodorPlugin.java @@ -30,6 +30,7 @@ import vg.civcraft.mc.civmodcore.ACivMod; import vg.civcraft.mc.civmodcore.dao.DatabaseCredentials; import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; +import vg.civcraft.mc.civmodcore.utilities.BlockProtector; import vg.civcraft.mc.civmodcore.world.locations.chunkmeta.api.BlockBasedChunkMetaView; import vg.civcraft.mc.civmodcore.world.locations.chunkmeta.api.ChunkMetaAPI; import vg.civcraft.mc.civmodcore.world.locations.chunkmeta.block.table.TableBasedDataObject; diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/farmbeacon/FarmBeaconListener.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/farmbeacon/FarmBeaconListener.java index 486232528d..1523e532d0 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/farmbeacon/FarmBeaconListener.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/farmbeacon/FarmBeaconListener.java @@ -1,8 +1,7 @@ package net.civmc.heliodor.farmbeacon; -import net.civmc.heliodor.BlockProtector; +import vg.civcraft.mc.civmodcore.utilities.BlockProtector; import net.civmc.heliodor.HeliodorPlugin; -import net.civmc.heliodor.backpack.Backpack; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.block.Beacon; diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/heliodor/PickaxeBreakListener.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/heliodor/PickaxeBreakListener.java index 92c9a4ec27..8ec35d4ef0 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/heliodor/PickaxeBreakListener.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/heliodor/PickaxeBreakListener.java @@ -52,7 +52,7 @@ public PickaxeBreakListener(VeinCache cache, int meteoricIronLow, int meteoricIr .formatted(meteoricIronLow, meteoricIronHigh, meteoricIronHigh - spawnRadius))); } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void on(BlockBreakEvent event) { Block block = event.getBlock(); ChunkPos chunkPos = new ChunkPos(block.getChunk().getX(), block.getChunk().getZ()); diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIron.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIron.java index 169902be0c..91a6c78f9d 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIron.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIron.java @@ -1,19 +1,15 @@ package net.civmc.heliodor.meteoriciron; -import net.civmc.heliodor.HeliodorPlugin; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.inventory.CraftingRecipe; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.Recipe; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.recipe.CraftingBookCategory; -import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; import vg.civcraft.mc.civmodcore.inventory.CustomItem; import java.util.List; diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIronTools.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIronTools.java index 3978ebf743..13c1b423ec 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIronTools.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/meteoriciron/MeteoricIronTools.java @@ -157,6 +157,7 @@ static ItemStack createAxe(boolean silk) { tool.addRule(Tag.PLANKS, 1000f, true); tool.addRule(Tag.WOODEN_SLABS, 1000f, true); tool.addRule(Tag.WOODEN_STAIRS, 1000f, true); + tool.addRule(Tag.WOODEN_SHELVES, 30f, true); tool.addRule(Material.CRAFTING_TABLE, 30f, true); tool.addRule(Material.IRON_DOOR, 50f, true); tool.addRule(Material.IRON_TRAPDOOR, 50f, true); @@ -180,7 +181,27 @@ static ItemStack createAxe(boolean silk) { tool.addRule(Material.WAXED_COPPER_DOOR, 30f, true); tool.addRule(Material.WAXED_EXPOSED_COPPER_DOOR, 30f, true); tool.addRule(Material.WAXED_OXIDIZED_COPPER_DOOR, 30f, true); - tool.addRule(Material.WAXED_WEATHERED_COPPER_DOOR, 30f, true); + tool.addRule(Material.COPPER_CHEST, 30f, true); + tool.addRule(Material.EXPOSED_COPPER_CHEST, 30f, true); + tool.addRule(Material.OXIDIZED_COPPER_CHEST, 30f, true); + tool.addRule(Material.WEATHERED_COPPER_CHEST, 30f, true); + tool.addRule(Material.WAXED_COPPER_CHEST, 30f, true); + tool.addRule(Material.WAXED_EXPOSED_COPPER_CHEST, 30f, true); + tool.addRule(Material.WAXED_OXIDIZED_COPPER_CHEST, 30f, true); + tool.addRule(Material.COPPER_BARS, 30f, true); + tool.addRule(Material.EXPOSED_COPPER_BARS, 30f, true); + tool.addRule(Material.OXIDIZED_COPPER_BARS, 30f, true); + tool.addRule(Material.WEATHERED_COPPER_BARS, 30f, true); + tool.addRule(Material.WAXED_COPPER_BARS, 30f, true); + tool.addRule(Material.WAXED_EXPOSED_COPPER_BARS, 30f, true); + tool.addRule(Material.WAXED_OXIDIZED_COPPER_BARS, 30f, true); + tool.addRule(Material.COPPER_CHAIN, 30f, true); + tool.addRule(Material.EXPOSED_COPPER_CHAIN, 30f, true); + tool.addRule(Material.OXIDIZED_COPPER_CHAIN, 30f, true); + tool.addRule(Material.WEATHERED_COPPER_CHAIN, 30f, true); + tool.addRule(Material.WAXED_COPPER_CHAIN, 30f, true); + tool.addRule(Material.WAXED_EXPOSED_COPPER_CHAIN, 30f, true); + tool.addRule(Material.WAXED_OXIDIZED_COPPER_CHAIN, 30f, true); tool.addRule(Tag.MINEABLE_AXE, 8f, true); meta.setTool(tool); meta.setMaxDamage(48_600); diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/OrePredicate.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/OrePredicate.java index a818199f58..f5fdce599c 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/OrePredicate.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/OrePredicate.java @@ -4,8 +4,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.NamespacedKey; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; +import vg.civcraft.mc.civmodcore.utilities.BlockPosPdc; public class OrePredicate implements Predicate { @@ -17,21 +16,9 @@ public OrePredicate(NamespacedKey oreLocationsKey) { @Override public boolean test(Location location) { - PersistentDataContainer chunkPdc = location.getChunk().getPersistentDataContainer(); - int[] ints = chunkPdc.get(oreLocationsKey, PersistentDataType.INTEGER_ARRAY); - if (ints == null) { - return false; - } - if (location.getBlock().getType() != Material.RAW_IRON_BLOCK) { return false; } - - for (int i = 0; i < ints.length; i += 3) { - if (ints[i] == location.getBlockX() && ints[i + 1] == location.getBlockY() && ints[i + 2] == location.getBlockZ()) { - return true; - } - } - return false; + return BlockPosPdc.testBlock(location.getChunk(), oreLocationsKey, location.getBlockX(), location.getBlockY(), location.getBlockZ()); } } diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/OreBreakListener.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/OreBreakListener.java index a38dfde4e5..5869d29b45 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/OreBreakListener.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/OreBreakListener.java @@ -1,7 +1,5 @@ package net.civmc.heliodor.vein.listener; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; import net.civmc.heliodor.meteoriciron.MeteoricIron; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -10,8 +8,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; +import vg.civcraft.mc.civmodcore.utilities.BlockPosPdc; public class OreBreakListener implements Listener { @@ -25,27 +22,10 @@ public OreBreakListener(NamespacedKey oreLocationsKey) { public void on(BlockBreakEvent event) { Block block = event.getBlock(); - PersistentDataContainer chunkPdc = block.getChunk().getPersistentDataContainer(); - int[] ints = chunkPdc.get(oreLocationsKey, PersistentDataType.INTEGER_ARRAY); - if (ints == null) { + if (!BlockPosPdc.removeBlock(block.getChunk(), oreLocationsKey, block.getX(), block.getY(), block.getZ())) { return; } - IntList list = new IntArrayList(ints); - int index = -1; - for (int i = 0; i < list.size(); i += 3) { - if (list.getInt(i) == block.getX() && list.getInt(i + 1) == block.getY() && list.getInt(i + 2) == block.getZ()) { - index = i; - break; - } - } - if (index == -1) { - return; - } - - list.removeElements(index, index + 3); - chunkPdc.set(oreLocationsKey, PersistentDataType.INTEGER_ARRAY, list.toIntArray()); - if (block.getType() != Material.RAW_IRON_BLOCK) { return; } diff --git a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/VeinBreakListener.java b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/VeinBreakListener.java index 59adfe0db6..7c4cefca6e 100644 --- a/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/VeinBreakListener.java +++ b/plugins/heliodor-paper/src/main/java/net/civmc/heliodor/vein/listener/VeinBreakListener.java @@ -1,10 +1,13 @@ package net.civmc.heliodor.vein.listener; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; import net.civmc.heliodor.HeliodorPlugin; -import net.civmc.heliodor.vein.data.Vein; import net.civmc.heliodor.vein.VeinCache; +import net.civmc.heliodor.vein.data.Vein; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextDecoration; @@ -20,14 +23,8 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.java.JavaPlugin; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ThreadLocalRandom; +import vg.civcraft.mc.civmodcore.utilities.BlockPosPdc; public class VeinBreakListener implements Listener { @@ -41,7 +38,7 @@ public VeinBreakListener(NamespacedKey oreLocationsKey, VeinCache dao) { this.dao = dao; } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void on(BlockBreakEvent event) { Block block = event.getBlock(); if (!Tag.BASE_STONE_OVERWORLD.isTagged(block.getType()) @@ -92,14 +89,7 @@ public void on(BlockBreakEvent event) { oreBlock.setType(Material.RAW_IRON_BLOCK); event.getPlayer().sendMessage(Component.text("You found a chunk of meteoric iron", NamedTextColor.GRAY, TextDecoration.ITALIC)); - PersistentDataContainer chunkPdc = oreBlock.getChunk().getPersistentDataContainer(); - int[] ints = chunkPdc.get(oreLocationsKey, PersistentDataType.INTEGER_ARRAY); - IntList list = ints == null ? new IntArrayList() : new IntArrayList(ints); - list.add(oreBlock.getX()); - list.add(oreBlock.getY()); - list.add(oreBlock.getZ()); - - chunkPdc.set(oreLocationsKey, PersistentDataType.INTEGER_ARRAY, list.toIntArray()); + BlockPosPdc.addBlock(oreBlock.getChunk(), oreLocationsKey, oreBlock.getX(), oreBlock.getY(), oreBlock.getZ()); this.minedBlocksCache.computeIfAbsent(ChunkPos.from(oreBlock.getChunk()), k -> new ArrayList<>()).add(oreBlock.getLocation()); JavaPlugin.getPlugin(HeliodorPlugin.class).getLogger() diff --git a/plugins/hiddenore-paper/src/main/java/com/github/devotedmc/hiddenore/listeners/BlockBreakListener.java b/plugins/hiddenore-paper/src/main/java/com/github/devotedmc/hiddenore/listeners/BlockBreakListener.java index a2ea1ecfa1..b6bb6a37b8 100644 --- a/plugins/hiddenore-paper/src/main/java/com/github/devotedmc/hiddenore/listeners/BlockBreakListener.java +++ b/plugins/hiddenore-paper/src/main/java/com/github/devotedmc/hiddenore/listeners/BlockBreakListener.java @@ -1,10 +1,22 @@ package com.github.devotedmc.hiddenore.listeners; -import com.github.devotedmc.hiddenore.util.FakePlayer; +import com.github.devotedmc.hiddenore.BlockConfig; +import com.github.devotedmc.hiddenore.Config; +import com.github.devotedmc.hiddenore.DropConfig; +import com.github.devotedmc.hiddenore.HiddenOre; +import com.github.devotedmc.hiddenore.ToolConfig; +import com.github.devotedmc.hiddenore.VeinConfig; +import com.github.devotedmc.hiddenore.events.HiddenOreEvent; +import com.github.devotedmc.hiddenore.events.HiddenOreGenerateEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.UUID; +import java.util.logging.Level; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.ChatColor; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; @@ -21,21 +33,6 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.UUID; -import java.util.logging.Level; - -import com.github.devotedmc.hiddenore.BlockConfig; -import com.github.devotedmc.hiddenore.DropConfig; -import com.github.devotedmc.hiddenore.HiddenOre; -import com.github.devotedmc.hiddenore.Config; -import com.github.devotedmc.hiddenore.ToolConfig; -import com.github.devotedmc.hiddenore.VeinConfig; -import com.github.devotedmc.hiddenore.events.HiddenOreEvent; -import com.github.devotedmc.hiddenore.events.HiddenOreGenerateEvent; - /** * Heart of ore generation, handles breaks. * @@ -64,9 +61,9 @@ public void onBlockBreak(BlockBreakEvent event) { } public static void spoofBlockBreak(Location playerLoc, Block block, ItemStack inHand) { - HiddenOre.getPlugin().getBreakListener().doBlockBreak( - new BlockBreakEvent(block, new FakePlayer(playerLoc, inHand)) - ); +// HiddenOre.getPlugin().getBreakListener().doBlockBreak( +// new BlockBreakEvent(block, new FakePlayer(playerLoc, inHand)) +// ); } /** diff --git a/plugins/hiddenore-paper/src/main/java/com/github/devotedmc/hiddenore/util/FakePlayer.java b/plugins/hiddenore-paper/src/main/java/com/github/devotedmc/hiddenore/util/FakePlayer.java deleted file mode 100644 index 0417b4a2ad..0000000000 --- a/plugins/hiddenore-paper/src/main/java/com/github/devotedmc/hiddenore/util/FakePlayer.java +++ /dev/null @@ -1,4074 +0,0 @@ -package com.github.devotedmc.hiddenore.util; - -import com.destroystokyo.paper.ClientOption; -import com.destroystokyo.paper.Title; -import com.destroystokyo.paper.block.TargetBlockInfo; -import com.destroystokyo.paper.block.TargetBlockInfo.FluidMode; -import com.destroystokyo.paper.entity.TargetEntityInfo; -import com.destroystokyo.paper.profile.PlayerProfile; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -import io.papermc.paper.connection.PlayerGameConnection; -import io.papermc.paper.datacomponent.DataComponentType; -import io.papermc.paper.entity.LookAnchor; -import io.papermc.paper.entity.PlayerGiveResult; -import io.papermc.paper.entity.TeleportFlag; -import io.papermc.paper.math.Position; -import io.papermc.paper.threadedregions.scheduler.EntityScheduler; -import io.papermc.paper.world.damagesource.CombatTracker; -import net.kyori.adventure.bossbar.BossBar; -import net.kyori.adventure.identity.Identity; -import net.kyori.adventure.key.Key; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.util.TriState; -import net.md_5.bungee.api.chat.BaseComponent; -import org.bukkit.BanEntry; -import org.bukkit.Chunk; -import org.bukkit.DyeColor; -import org.bukkit.Effect; -import org.bukkit.EntityEffect; -import org.bukkit.FluidCollisionMode; -import org.bukkit.GameMode; -import org.bukkit.Input; -import org.bukkit.Instrument; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.Note; -import org.bukkit.Particle; -import org.bukkit.Server; -import org.bukkit.ServerLinks; -import org.bukkit.Sound; -import org.bukkit.SoundCategory; -import org.bukkit.Statistic; -import org.bukkit.WeatherType; -import org.bukkit.World; -import org.bukkit.WorldBorder; -import org.bukkit.advancement.Advancement; -import org.bukkit.advancement.AdvancementProgress; -import org.bukkit.attribute.Attribute; -import org.bukkit.attribute.AttributeInstance; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.PistonMoveReaction; -import org.bukkit.block.Sign; -import org.bukkit.block.TileState; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.sign.Side; -import org.bukkit.conversations.Conversation; -import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.damage.DamageSource; -import org.bukkit.entity.*; -import org.bukkit.entity.memory.MemoryKey; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityRegainHealthEvent; -import org.bukkit.event.inventory.InventoryCloseEvent.Reason; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerResourcePackStatusEvent.Status; -import org.bukkit.event.player.PlayerTeleportEvent; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; -import org.bukkit.inventory.EntityEquipment; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.InventoryView.Property; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.MainHand; -import org.bukkit.inventory.Merchant; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.map.MapView; -import org.bukkit.metadata.MetadataValue; -import org.bukkit.permissions.Permission; -import org.bukkit.permissions.PermissionAttachment; -import org.bukkit.permissions.PermissionAttachmentInfo; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.plugin.Plugin; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.util.BoundingBox; -import org.bukkit.util.RayTraceResult; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Range; -import org.jetbrains.annotations.Unmodifiable; -import org.jetbrains.annotations.UnmodifiableView; - -@SuppressWarnings("removal") -public class FakePlayer implements Player { - - private final ItemStack inHand; - private final Location location; - - public FakePlayer(final Location location, final ItemStack inHand) { - this.inHand = inHand; - this.location = location; - } - - @Override - public String getName() { - return "Spoof"; - } - - @Override - public PlayerInventory getInventory() { - return new PlayerInventory() { - - @Override - public int getSize() { - return 0; - } - - @Override - public int getMaxStackSize() { - return 0; - } - - @Override - public void setMaxStackSize(int size) { - } - - @Override - public ItemStack getItem(int index) { - return null; - } - - @Override - public HashMap addItem(ItemStack... items) throws IllegalArgumentException { - return new HashMap<>(); - } - - @Override - public HashMap removeItem(ItemStack... items) throws IllegalArgumentException { - return new HashMap<>(); - } - - @Override - public ItemStack[] getContents() { - return null; - } - - @Override - public void setContents(ItemStack[] items) throws IllegalArgumentException { - } - - @Override - public ItemStack[] getStorageContents() { - return null; - } - - @Override - public void setStorageContents(ItemStack[] items) throws IllegalArgumentException { - } - - @Override - public boolean contains(Material material) throws IllegalArgumentException { - return false; - } - - @Override - public boolean contains(ItemStack item) { - return false; - } - - @Override - public boolean contains(Material material, int amount) throws IllegalArgumentException { - return false; - } - - @Override - public boolean contains(ItemStack item, int amount) { - return false; - } - - @Override - public boolean containsAtLeast(ItemStack item, int amount) { - return false; - } - - @Override - public HashMap all(Material material) throws IllegalArgumentException { - return new HashMap<>(); - } - - @Override - public HashMap all(ItemStack item) { - return new HashMap<>(); - } - - @Override - public int first(Material material) throws IllegalArgumentException { - return 0; - } - - @Override - public int first(ItemStack item) { - return 0; - } - - @Override - public int firstEmpty() { - return 0; - } - - @Override - public void remove(Material material) throws IllegalArgumentException { - } - - @Override - public void remove(ItemStack item) { - } - - @Override - public void clear(int index) { - } - - @Override - public void clear() { - } - - @Override - public int close() { - return 0; - } - - @Override - public List getViewers() { - return new ArrayList<>(); - } - - @Override - public InventoryType getType() { - return InventoryType.PLAYER; - } - - @Override - public ListIterator iterator() { - return null; - } - - @Override - public ListIterator iterator(int index) { - return null; - } - - @Override - public Location getLocation() { - return location; - } - - @Override - public ItemStack[] getArmorContents() { - return null; - } - - @Override - public ItemStack[] getExtraContents() { - return null; - } - - @Override - public ItemStack getHelmet() { - return null; - } - - @Override - public ItemStack getChestplate() { - return null; - } - - @Override - public ItemStack getLeggings() { - return null; - } - - @Override - public ItemStack getBoots() { - return null; - } - - @Override - public void setItem(int index, ItemStack item) { - } - - @Override - public void setArmorContents(ItemStack[] items) { - } - - @Override - public void setExtraContents(ItemStack[] items) { - } - - @Override - public void setHelmet(ItemStack helmet) { - } - - @Override - public void setChestplate(ItemStack chestplate) { - } - - @Override - public void setLeggings(ItemStack leggings) { - } - - @Override - public void setBoots(ItemStack boots) { - } - - @Override - public ItemStack getItemInMainHand() { - return inHand; - } - - @Override - public void setItemInMainHand(ItemStack item) { - } - - @Override - public ItemStack getItemInOffHand() { - return null; - } - - @Override - public void setItemInOffHand(ItemStack item) { - } - - @Override - public ItemStack getItemInHand() { - return inHand; - } - - @Override - public void setItemInHand(ItemStack stack) { - } - - @Override - public int getHeldItemSlot() { - return 0; - } - - @Override - public void setHeldItemSlot(int slot) { - } - - @Override - public HumanEntity getHolder() { - return null; - } - - @Override - public void setItem(EquipmentSlot slot, ItemStack item) { - } - - @Override - public ItemStack getItem(EquipmentSlot slot) { - return null; - } - - @Override - public InventoryHolder getHolder(boolean arg0) { - return null; - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public HashMap removeItemAnySlot(ItemStack... arg0) throws IllegalArgumentException { - return null; - } - }; - } - - @Override - public Inventory getEnderChest() { - return null; - } - - @Override - public MainHand getMainHand() { - return null; - } - - @Override - public boolean setWindowProperty(Property prop, int value) { - return false; - } - - @Override - public int getEnchantmentSeed() { - return 0; - } - - @Override - public void setEnchantmentSeed(int i) { - - } - - @Override - public InventoryView getOpenInventory() { - return null; - } - - @Override - public InventoryView openInventory(Inventory inventory) { - return null; - } - - @Override - public InventoryView openWorkbench(Location location, boolean force) { - return null; - } - - @Override - public InventoryView openEnchanting(Location location, boolean force) { - return null; - } - - @Override - public void openInventory(InventoryView inventory) { - } - - @Override - public InventoryView openMerchant(Villager trader, boolean force) { - return null; - } - - @Override - public void closeInventory() { - } - - @Override - public ItemStack getItemInHand() { - return inHand; - } - - @Override - public void setItemInHand(ItemStack item) { - } - - @Override - public ItemStack getItemOnCursor() { - return null; - } - - @Override - public void setItemOnCursor(ItemStack item) { - } - - @Override - public boolean isSleeping() { - return false; - } - - @Override - public boolean isClimbing() { - return false; - } - - @Override - public int getSleepTicks() { - return 0; - } - - @Override - public GameMode getGameMode() { - return null; - } - - @Override - public void setGameMode(GameMode mode) { - } - - @Override - public boolean isBlocking() { - return false; - } - - @Override - public int getExpToLevel() { - return 0; - } - - @Override - public double getEyeHeight() { - return 0; - } - - @Override - public double getEyeHeight(boolean ignoreSneaking) { - return 0; - } - - @Override - public Location getEyeLocation() { - return location; - } - - @Override - public List getLineOfSight(Set transparent, int maxDistance) { - return null; - } - - public Block getTargetBlock(HashSet transparent, int maxDistance) { - return null; - } - - @Override - public Block getTargetBlock(Set transparent, int maxDistance) { - return null; - } - - public List getLastTwoTargetBlocks(HashSet transparent, int maxDistance) { - return null; - } - - @Override - public List getLastTwoTargetBlocks(Set transparent, int maxDistance) { - return null; - } - - @Override - public int getRemainingAir() { - return 0; - } - - @Override - public void setRemainingAir(int ticks) { - } - - @Override - public int getMaximumAir() { - return 0; - } - - @Override - public void setMaximumAir(int ticks) { - } - - @Override - public int getMaximumNoDamageTicks() { - return 0; - } - - @Override - public void setMaximumNoDamageTicks(int ticks) { - } - - @Override - public double getLastDamage() { - return 0; - } - - @Override - public void setLastDamage(double damage) { - - } - - @Override - public int getNoDamageTicks() { - - return 0; - } - - @Override - public void setNoDamageTicks(int ticks) { - - } - - @Override - public int getNoActionTicks() { - return 0; - } - - @Override - public void setNoActionTicks(int i) { - - } - - @Override - public Player getKiller() { - - return null; - } - - @Override - public boolean addPotionEffect(PotionEffect effect) { - - return false; - } - - @Override - public boolean addPotionEffect(PotionEffect effect, boolean force) { - - return false; - } - - @Override - public boolean addPotionEffects(Collection effects) { - - return false; - } - - @Override - public boolean hasPotionEffect(PotionEffectType type) { - - return false; - } - - @Override - public void removePotionEffect(PotionEffectType type) { - - } - - @Override - public Collection getActivePotionEffects() { - - return null; - } - - @Override - public boolean clearActivePotionEffects() { - return false; - } - - @Override - public boolean hasLineOfSight(Entity other) { - - return false; - } - - @Override - public boolean hasLineOfSight(@NotNull Location location) { - return false; - } - - @Override - public boolean getRemoveWhenFarAway() { - - return false; - } - - @Override - public void setRemoveWhenFarAway(boolean remove) { - - } - - @Override - public EntityEquipment getEquipment() { - - return null; - } - - @Override - public void setCanPickupItems(boolean pickup) { - - } - - @Override - public boolean getCanPickupItems() { - - return false; - } - - @Override - public boolean isLeashed() { - - return false; - } - - @Override - public Entity getLeashHolder() throws IllegalStateException { - - return null; - } - - @Override - public boolean setLeashHolder(Entity holder) { - - return false; - } - - @Override - public boolean isGliding() { - - return false; - } - - @Override - public void setGliding(boolean gliding) { - - } - - @Override - public void setAI(boolean ai) { - - } - - @Override - public boolean hasAI() { - - return false; - } - - @Override - public void setCollidable(boolean collidable) { - - } - - @Override - public boolean isCollidable() { - - return false; - } - - @Override - public AttributeInstance getAttribute(Attribute attribute) { - - return null; - } - - @Override - public void registerAttribute(@NotNull Attribute attribute) { - - } - - @Override - public Location getLocation() { - return location; - } - - @Override - public Location getLocation(Location loc) { - return location; - } - - @Override - public void setVelocity(Vector velocity) { - - } - - @Override - public Vector getVelocity() { - - return null; - } - - @Override - public World getWorld() { - return location.getWorld(); - } - - @Override - public boolean teleport(Location location) { - - return false; - } - - @Override - public boolean teleport(Location location, TeleportCause cause) { - - return false; - } - - @Override - public boolean teleport(Entity destination) { - - return false; - } - - @Override - public boolean teleport(Entity destination, TeleportCause cause) { - - return false; - } - - @Override - public @NotNull CompletableFuture teleportAsync(@NotNull Location location, @NotNull PlayerTeleportEvent.TeleportCause teleportCause, @NotNull TeleportFlag @NotNull ... teleportFlags) { - return null; - } - - @Override - public List getNearbyEntities(double x, double y, double z) { - - return null; - } - - @Override - public int getEntityId() { - - return 0; - } - - @Override - public int getFireTicks() { - - return 0; - } - - @Override - public int getMaxFireTicks() { - - return 0; - } - - @Override - public void setFireTicks(int ticks) { - - } - - @Override - public void setVisualFire(boolean bl) { - - } - - @Override - public void setVisualFire(@NotNull TriState fire) { - - } - - @Override - public boolean isVisualFire() { - return false; - } - - @Override - public @NotNull TriState getVisualFire() { - return null; - } - - @Override - public int getFreezeTicks() { - return 0; - } - - @Override - public int getMaxFreezeTicks() { - return 0; - } - - @Override - public void setFreezeTicks(int i) { - - } - - @Override - public boolean isFrozen() { - return false; - } - - @Override - public boolean isFreezeTickingLocked() { - return false; - } - - @Override - public void lockFreezeTicks(boolean locked) { - - } - - @Override - public void remove() { - - } - - @Override - public boolean isDead() { - - return false; - } - - @Override - public boolean isValid() { - - return false; - } - - @Override - public Server getServer() { - - return null; - } - - @Override - public Entity getPassenger() { - - return null; - } - - @Override - public boolean setPassenger(Entity passenger) { - - return false; - } - - @Override - public boolean isEmpty() { - - return false; - } - - @Override - public boolean eject() { - - return false; - } - - @Override - public @NotNull ItemStack getPickItemStack() { - return null; - } - - @Override - public float getFallDistance() { - - return 0; - } - - @Override - public void setFallDistance(float distance) { - - } - - @Override - public void setLastDamageCause(EntityDamageEvent event) { - - } - - @Override - public EntityDamageEvent getLastDamageCause() { - - return null; - } - - @Override - public UUID getUniqueId() { - - return null; - } - - @Override - public int getTicksLived() { - - return 0; - } - - @Override - public void setTicksLived(int value) { - - } - - @Override - public void playEffect(EntityEffect type) { - - } - - @Override - public EntityType getType() { - - return null; - } - - @Override - public @NotNull Sound getSwimSound() { - return null; - } - - @Override - public @NotNull Sound getSwimSplashSound() { - return null; - } - - @Override - public @NotNull Sound getSwimHighSpeedSplashSound() { - return null; - } - - @Override - public boolean isInsideVehicle() { - - return false; - } - - @Override - public boolean leaveVehicle() { - - return false; - } - - @Override - public Entity getVehicle() { - - return null; - } - - @Override - public void setCustomName(String name) { - - } - - @Override - public @Nullable - Component customName() { - return null; - } - - @Override - public void customName(@Nullable Component component) { - - } - - @Override - public String getCustomName() { - - return "Spoof"; - } - - @Override - public void setCustomNameVisible(boolean flag) { - - } - - @Override - public boolean isCustomNameVisible() { - - return false; - } - - @Override - public void setVisibleByDefault(boolean b) { - - } - - @Override - public boolean isVisibleByDefault() { - return false; - } - - @Override - public @NotNull Set getTrackedBy() { - return null; - } - - @Override - public boolean isTrackedBy(@NotNull Player player) { - return false; - } - - @Override - public void setGlowing(boolean flag) { - - } - - @Override - public boolean isGlowing() { - - return false; - } - - @Override - public void setInvulnerable(boolean flag) { - - } - - @Override - public boolean isInvulnerable() { - - return false; - } - - @Override - public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { - - } - - @Override - public List getMetadata(String metadataKey) { - - return null; - } - - @Override - public boolean hasMetadata(String metadataKey) { - - return false; - } - - @Override - public void removeMetadata(String metadataKey, Plugin owningPlugin) { - - } - - @Override - public void sendMessage(String message) { - - } - - @Override - public void sendMessage(String[] messages) { - - } - - @Override - public boolean isPermissionSet(String name) { - - return false; - } - - @Override - public boolean isPermissionSet(Permission perm) { - - return false; - } - - @Override - public boolean hasPermission(String name) { - - return false; - } - - @Override - public boolean hasPermission(Permission perm) { - - return false; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { - - return null; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin) { - - return null; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { - - return null; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin, int ticks) { - - return null; - } - - @Override - public void removeAttachment(PermissionAttachment attachment) { - - } - - @Override - public void recalculatePermissions() { - - } - - @Override - public Set getEffectivePermissions() { - - return null; - } - - @Override - public boolean isOp() { - - return false; - } - - @Override - public void setOp(boolean value) { - - } - - @Override - public void damage(double amount) { - - } - - @Override - public void damage(double amount, Entity source) { - - } - - @Override - public void damage(double v, @NotNull DamageSource damageSource) { - - } - - @Override - public double getHealth() { - - return 0; - } - - @Override - public void setHealth(double health) { - - } - - @Override - public void heal(double amount, @NotNull EntityRegainHealthEvent.RegainReason reason) { - - } - - @Override - public double getMaxHealth() { - - return 0; - } - - @Override - public void setMaxHealth(double health) { - - } - - @Override - public void resetMaxHealth() { - - } - - @Override - public T launchProjectile(Class projectile) { - - return null; - } - - @Override - public T launchProjectile(Class projectile, Vector velocity) { - - return null; - } - - @Override - public @NotNull T launchProjectile(@NotNull Class aClass, @org.jetbrains.annotations.Nullable Vector vector, @org.jetbrains.annotations.Nullable Consumer consumer) { - return null; - } - - @Override - public boolean isConversing() { - - return false; - } - - @Override - public void acceptConversationInput(String input) { - - } - - @Override - public boolean beginConversation(Conversation conversation) { - - return false; - } - - @Override - public void abandonConversation(Conversation conversation) { - - } - - @Override - public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { - - } - - @Override - public boolean isOnline() { - - return false; - } - - @Override - public boolean isConnected() { - return false; - } - - @Override - public boolean isBanned() { - - return false; - } - - @Override - public > @org.jetbrains.annotations.Nullable E ban(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Date date, @org.jetbrains.annotations.Nullable String s1) { - return null; - } - - @Override - public > @org.jetbrains.annotations.Nullable E ban(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Instant instant, @org.jetbrains.annotations.Nullable String s1) { - return null; - } - - @Override - public > @org.jetbrains.annotations.Nullable E ban(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Duration duration, @org.jetbrains.annotations.Nullable String s1) { - return null; - } - - @Override - public boolean isWhitelisted() { - - return false; - } - - @Override - public void setWhitelisted(boolean value) { - - } - - @Override - public Player getPlayer() { - - return null; - } - - @Override - public long getFirstPlayed() { - - return 0; - } - - @Override - public long getLastPlayed() { - - return 0; - } - - @Override - public boolean hasPlayedBefore() { - - return false; - } - - @Override - public Map serialize() { - - return null; - } - - @Override - public void sendPluginMessage(Plugin source, String channel, byte[] message) { - - } - - @Override - public Set getListeningPluginChannels() { - - return null; - } - - @Override - public @NotNull Identity identity() { - return Player.super.identity(); - } - - @Override - public @UnmodifiableView @NotNull Iterable activeBossBars() { - return null; - } - - @Override - public @NotNull Component displayName() { - return Component.text("Spoof"); - } - - @Override - public void displayName(@Nullable Component component) { - - } - - @Override - public String getDisplayName() { - return "Spoof"; - } - - @Override - public void setDisplayName(String name) { - - } - - @Override - public void playerListName(@Nullable Component component) { - - } - - @Override - public @Nullable Component playerListName() { - return null; - } - - @Override - public @Nullable Component playerListHeader() { - return null; - } - - @Override - public @Nullable Component playerListFooter() { - return null; - } - - @Override - public String getPlayerListName() { - return "Spoof"; - } - - @Override - public void setPlayerListName(String name) { - - } - - @Override - public int getPlayerListOrder() { - return 0; - } - - @Override - public void setPlayerListOrder(int order) { - - } - - @Override - public void setCompassTarget(Location loc) { - - } - - @Override - public Location getCompassTarget() { - - return null; - } - - @Override - public InetSocketAddress getAddress() { - - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable InetSocketAddress getHAProxyAddress() { - return null; - } - - @Override - public boolean isTransferred() { - return false; - } - - @Override - public @NotNull CompletableFuture retrieveCookie(@NotNull NamespacedKey key) { - return null; - } - - @Override - public void storeCookie(@NotNull NamespacedKey key, @NotNull byte[] value) { - - } - - @Override - public void transfer(@NotNull String host, int port) { - - } - - @Override - public void sendRawMessage(String message) { - - } - - @Override - public void kickPlayer(String message) { - - } - - @Override - public void kick() { - - } - - @Override - public void kick(@Nullable Component component) { - - } - - @Override - public void kick(@Nullable Component component, - PlayerKickEvent.Cause cause) { - - } - - @Override - public > @org.jetbrains.annotations.Nullable E ban(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Date date, @org.jetbrains.annotations.Nullable String s1, boolean b) { - return null; - } - - @Override - public > @org.jetbrains.annotations.Nullable E ban(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Instant instant, @org.jetbrains.annotations.Nullable String s1, boolean b) { - return null; - } - - @Override - public > @org.jetbrains.annotations.Nullable E ban(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Duration duration, @org.jetbrains.annotations.Nullable String s1, boolean b) { - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable BanEntry banIp(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Date date, @org.jetbrains.annotations.Nullable String s1, boolean b) { - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable BanEntry banIp(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Instant instant, @org.jetbrains.annotations.Nullable String s1, boolean b) { - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable BanEntry banIp(@org.jetbrains.annotations.Nullable String s, @org.jetbrains.annotations.Nullable Duration duration, @org.jetbrains.annotations.Nullable String s1, boolean b) { - return null; - } - - @Override - public void chat(String msg) { - - } - - @Override - public boolean performCommand(String command) { - - return false; - } - - @Override - public boolean isSneaking() { - - return false; - } - - @Override - public void setSneaking(boolean sneak) { - - } - - @Override - public void setPose(@NotNull Pose pose, boolean b) { - - } - - @Override - public boolean hasFixedPose() { - return false; - } - - @Override - public boolean isSprinting() { - - return false; - } - - @Override - public void setSprinting(boolean sprinting) { - - } - - @Override - public void saveData() { - - } - - @Override - public void loadData() { - - } - - @Override - public void setSleepingIgnored(boolean isSleeping) { - - } - - @Override - public boolean isSleepingIgnored() { - - return false; - } - - @Override - public void playNote(Location loc, byte instrument, byte note) { - - } - - @Override - public void playNote(Location loc, Instrument instrument, Note note) { - - } - - @Override - public void playSound(Location location, Sound sound, float volume, float pitch) { - - } - - @Override - public void playSound(Location location, String sound, float volume, float pitch) { - - } - - @Override - public void playEffect(Location loc, Effect effect, int data) { - - } - - @Override - public void playEffect(Location loc, Effect effect, T data) { - - } - - @Override - public boolean breakBlock(@NotNull Block block) { - return false; - } - - @Override - public void sendBlockChange(Location loc, Material material, byte data) { - - } - - @Override - public void sendSignChange(Location loc, String[] lines) throws IllegalArgumentException { - - } - - @Override - public void sendMap(MapView map) { - - } - - @Override - public void showWinScreen() { - - } - - @Override - public boolean hasSeenWinScreen() { - return false; - } - - @Override - public void setHasSeenWinScreen(boolean b) { - - } - - @Override - public void updateInventory() { - - } - - @Override - public @Nullable GameMode getPreviousGameMode() { - return null; - } - - @Override - public void incrementStatistic(Statistic statistic) throws IllegalArgumentException { - - } - - @Override - public void decrementStatistic(Statistic statistic) throws IllegalArgumentException { - - } - - @Override - public void incrementStatistic(Statistic statistic, int amount) throws IllegalArgumentException { - - } - - @Override - public void decrementStatistic(Statistic statistic, int amount) throws IllegalArgumentException { - - } - - @Override - public void setStatistic(Statistic statistic, int newValue) throws IllegalArgumentException { - - } - - @Override - public int getStatistic(Statistic statistic) throws IllegalArgumentException { - - return 0; - } - - @Override - public void incrementStatistic(Statistic statistic, Material material) throws IllegalArgumentException { - - } - - @Override - public void decrementStatistic(Statistic statistic, Material material) throws IllegalArgumentException { - - } - - @Override - public int getStatistic(Statistic statistic, Material material) throws IllegalArgumentException { - - return 0; - } - - @Override - public void incrementStatistic(Statistic statistic, Material material, int amount) throws IllegalArgumentException { - - } - - @Override - public void decrementStatistic(Statistic statistic, Material material, int amount) throws IllegalArgumentException { - - } - - @Override - public void setStatistic(Statistic statistic, Material material, int newValue) throws IllegalArgumentException { - - } - - @Override - public void incrementStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException { - - } - - @Override - public void decrementStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException { - - } - - @Override - public int getStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException { - - return 0; - } - - @Override - public void incrementStatistic(Statistic statistic, EntityType entityType, int amount) - throws IllegalArgumentException { - - } - - @Override - public void decrementStatistic(Statistic statistic, EntityType entityType, int amount) { - - } - - @Override - public void setStatistic(Statistic statistic, EntityType entityType, int newValue) { - - } - - @Override - public void setPlayerTime(long time, boolean relative) { - - } - - @Override - public long getPlayerTime() { - - return 0; - } - - @Override - public long getPlayerTimeOffset() { - - return 0; - } - - @Override - public boolean isPlayerTimeRelative() { - - return false; - } - - @Override - public void resetPlayerTime() { - - } - - @Override - public void setPlayerWeather(WeatherType type) { - - } - - @Override - public WeatherType getPlayerWeather() { - - return null; - } - - @Override - public void resetPlayerWeather() { - - } - - @Override - public void giveExp(int amount) { - - } - - @Override - public int getExpCooldown() { - return 0; - } - - @Override - public void setExpCooldown(int i) { - - } - - @Override - public void giveExpLevels(int amount) { - - } - - @Override - public float getExp() { - - return 0; - } - - @Override - public void setExp(float exp) { - - } - - @Override - public int getLevel() { - - return 0; - } - - @Override - public void setLevel(int level) { - - } - - @Override - public int getTotalExperience() { - - return 0; - } - - @Override - public void setTotalExperience(int exp) { - - } - - @Override - public @Range(from = 0L, to = 2147483647L) int calculateTotalExperiencePoints() { - return 0; - } - - @Override - public void setExperienceLevelAndProgress(@Range(from = 0L, to = 2147483647L) int i) { - - } - - @Override - public int getExperiencePointsNeededForNextLevel() { - return 0; - } - - @Override - public float getExhaustion() { - - return 0; - } - - @Override - public void setExhaustion(float value) { - - } - - @Override - public float getSaturation() { - - return 0; - } - - @Override - public void setSaturation(float value) { - - } - - @Override - public int getFoodLevel() { - - return 0; - } - - @Override - public void setFoodLevel(int value) { - - } - - @Override - public int getSaturatedRegenRate() { - return 0; - } - - @Override - public void setSaturatedRegenRate(int i) { - - } - - @Override - public int getUnsaturatedRegenRate() { - return 0; - } - - @Override - public void setUnsaturatedRegenRate(int i) { - - } - - @Override - public int getStarvationRate() { - return 0; - } - - @Override - public void setStarvationRate(int i) { - - } - - @Override - public @org.jetbrains.annotations.Nullable Location getLastDeathLocation() { - return null; - } - - @Override - public void setLastDeathLocation(@org.jetbrains.annotations.Nullable Location location) { - - } - - @Override - public @org.jetbrains.annotations.Nullable Firework fireworkBoost(@NotNull ItemStack itemStack) { - return null; - } - - @Override - public Location getBedSpawnLocation() { - - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable Location getRespawnLocation() { - return null; - } - - @Override - public @org.jspecify.annotations.Nullable Location getRespawnLocation(boolean loadLocationAndValidate) { - return null; - } - - @Override - public void setBedSpawnLocation(Location location) { - - } - - @Override - public void setRespawnLocation(@org.jetbrains.annotations.Nullable Location location) { - - } - - @Override - public void setBedSpawnLocation(Location location, boolean force) { - - } - - @Override - public void setRespawnLocation(@org.jetbrains.annotations.Nullable Location location, boolean b) { - - } - - @Override - public Collection getEnderPearls() { - return null; - } - - @Override - public Input getCurrentInput() { - return null; - } - - @Override - public boolean getAllowFlight() { - - return false; - } - - @Override - public void setAllowFlight(boolean flight) { - - } - - @Override - public void setFlyingFallDamage(@NotNull TriState triState) { - - } - - @Override - public @NotNull TriState hasFlyingFallDamage() { - return null; - } - - @Override - public void hidePlayer(Plugin plugin, Player player) { - - } - - @Override - public void hidePlayer(Player player) { - - } - - @Override - public void showPlayer(Plugin plugin, Player player) { - - } - - @Override - public void showPlayer(Player player) { - - } - - @Override - public boolean canSee(Player player) { - - return false; - } - - @Override - public void hideEntity(Plugin plugin, Entity entity) { - - } - - @Override - public void showEntity(Plugin plugin, Entity entity) { - - } - - @Override - public boolean canSee(Entity entity) { - return false; - } - - @Override - public boolean isListed(@NotNull Player player) { - return false; - } - - @Override - public boolean unlistPlayer(@NotNull Player player) { - return false; - } - - @Override - public boolean listPlayer(@NotNull Player player) { - return false; - } - - @Override - public boolean isOnGround() { - - return false; - } - - @Override - public boolean isFlying() { - - return false; - } - - @Override - public void setFlying(boolean value) { - - } - - @Override - public void setFlySpeed(float value) throws IllegalArgumentException { - - } - - @Override - public void setWalkSpeed(float value) throws IllegalArgumentException { - - } - - @Override - public float getFlySpeed() { - - return 0; - } - - @Override - public float getWalkSpeed() { - - return 0; - } - - @Override - public void setTexturePack(String url) { - - } - - @Override - public void setResourcePack(String url) { - - } - - @Override - public Scoreboard getScoreboard() { - - return null; - } - - @Override - public void setScoreboard(Scoreboard scoreboard) throws IllegalArgumentException, IllegalStateException { - - } - - @Override - public @Nullable WorldBorder getWorldBorder() { - return null; - } - - @Override - public void setWorldBorder(@Nullable WorldBorder border) { - - } - - @Override - public boolean isHealthScaled() { - - return false; - } - - @Override - public void setHealthScaled(boolean scale) { - - } - - @Override - public void setHealthScale(double scale) throws IllegalArgumentException { - - } - - @Override - public double getHealthScale() { - - return 0; - } - - @Override - public void sendHealthUpdate(double v, int i, float v1) { - - } - - @Override - public void sendHealthUpdate() { - - } - - @Override - public Entity getSpectatorTarget() { - - return null; - } - - @Override - public void setSpectatorTarget(Entity entity) { - - } - - @Override - public void sendTitle(String title, String subtitle) { - - } - - @Override - public void resetTitle() { - - } - - @Override - public void spawnParticle(Particle particle, Location location, int count) { - - } - - @Override - public void spawnParticle(Particle particle, double x, double y, double z, int count) { - - } - - @Override - public void spawnParticle(Particle particle, Location location, int count, T data) { - - } - - @Override - public void spawnParticle(Particle particle, double x, double y, double z, int count, T data) { - - } - - @Override - public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, - double offsetZ) { - - } - - @Override - public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, - double offsetY, double offsetZ) { - - } - - @Override - public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, - double offsetZ, T data) { - - } - - @Override - public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, - double offsetY, double offsetZ, T data) { - - } - - @Override - public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, - double offsetZ, double extra) { - - } - - @Override - public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, - double offsetY, double offsetZ, double extra) { - - } - - @Override - public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, - double offsetZ, double extra, T data) { - - } - - @Override - public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, - double offsetY, double offsetZ, double extra, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int i, double v, double v1, double v2, double v3, @org.jetbrains.annotations.Nullable T t, boolean b) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double v, double v1, double v2, int i, double v3, double v4, double v5, double v6, @org.jetbrains.annotations.Nullable T t, boolean b) { - - } - - @Override - public Spigot spigot() { - return null; - } - - @Override - public void sendEntityEffect(@NotNull EntityEffect effect, @NotNull Entity target) { - - } - - @Override - public PlayerGiveResult give(Collection items, boolean dropIfFull) { - return null; - } - - @Override - public int getDeathScreenScore() { - return 0; - } - - @Override - public void setDeathScreenScore(int score) { - - } - - @Override - public PlayerGameConnection getConnection() { - return null; - } - - @Override - public Component name() { - return null; - } - - @Override - public Component teamDisplayName() { - return null; - } - - @Override - public boolean isSilent() { - return false; - } - - @Override - public void setSilent(boolean flag) { - } - - @Override - public boolean hasGravity() { - return false; - } - - @Override - public void setGravity(boolean gravity) { - } - - @Override - public void stopSound(Sound sound) { - } - - @Override - public void stopSound(String sound) { - } - - @Override - public int getCooldown(Material arg0) { - return 0; - } - - @Override - public Entity getShoulderEntityLeft() { - return null; - } - - @Override - public Entity getShoulderEntityRight() { - return null; - } - - @Override - public boolean hasCooldown(Material arg0) { - return false; - } - - @Override - public boolean isHandRaised() { - return false; - } - - @Override - public @NotNull EquipmentSlot getHandRaised() { - return null; - } - - @Override - public @Nullable ItemStack getItemInUse() { - return null; - } - - @Override - public int getItemInUseTicks() { - return 0; - } - - @Override - public void setItemInUseTicks(int i) { - - } - - @Override - public InventoryView openMerchant(Merchant arg0, boolean arg1) { - return null; - } - - @Override - public void setCooldown(Material arg0, int arg1) { - - } - - @Override - public boolean isDeeplySleeping() { - return false; - } - - @Override - public boolean hasCooldown(ItemStack item) { - return false; - } - - @Override - public int getCooldown(ItemStack item) { - return 0; - } - - @Override - public void setCooldown(ItemStack item, int ticks) { - - } - - @Override - public int getCooldown(Key key) { - return 0; - } - - @Override - public void setCooldown(Key key, int ticks) { - - } - - @Override - public void setShoulderEntityLeft(Entity arg0) { - - } - - @Override - public void setShoulderEntityRight(Entity arg0) { - - } - - @Override - public PotionEffect getPotionEffect(PotionEffectType arg0) { - return null; - } - - @Override - public boolean addPassenger(Entity arg0) { - return false; - } - - @Override - public boolean addScoreboardTag(String arg0) { - return false; - } - - @Override - public double getHeight() { - return 1.0; - } - - @Override - public List getPassengers() { - return null; - } - - @Override - public int getPortalCooldown() { - return 0; - } - - @Override - public Set getScoreboardTags() { - return null; - } - - @Override - public double getWidth() { - return 0.33; - } - - @Override - public boolean removePassenger(Entity arg0) { - return false; - } - - @Override - public boolean removeScoreboardTag(String arg0) { - return false; - } - - @Override - public void setPortalCooldown(int arg0) { - - } - - @Override - public AdvancementProgress getAdvancementProgress(Advancement arg0) { - return null; - } - - @Override - public String getLocale() { - return null; - } - - @Override - public void playSound(Location arg0, Sound arg1, SoundCategory arg2, float arg3, float arg4) { - - } - - @Override - public void playSound(Location arg0, String arg1, SoundCategory arg2, float arg3, float arg4) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory soundCategory, float v, float v1, long l) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull String s, @NotNull SoundCategory soundCategory, float v, float v1, long l) { - - } - - @Override - public void playSound(@NotNull Entity entity, @NotNull Sound sound, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Entity entity, @NotNull String s, float v, float v1) { - - } - - @Override - public void playSound(@NotNull Entity entity, @NotNull Sound sound, - @NotNull SoundCategory category, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Entity entity, @NotNull String s, @NotNull SoundCategory soundCategory, float v, float v1) { - - } - - @Override - public void playSound(@NotNull Entity entity, @NotNull Sound sound, @NotNull SoundCategory soundCategory, float v, float v1, long l) { - - } - - @Override - public void playSound(@NotNull Entity entity, @NotNull String s, @NotNull SoundCategory soundCategory, float v, float v1, long l) { - - } - - @Override - public void sendTitle(String arg0, String arg1, int arg2, int arg3, int arg4) { - - } - - @Override - public void setResourcePack(String arg0, byte[] arg1) { - - } - - @Override - public void setResourcePack(@NotNull String url, - @Nullable byte[] hash, - @Nullable String prompt) { - } - - @Override - public void setResourcePack(@NotNull String url, @Nullable byte[] hash, boolean force) { - - } - - @Override - public void setResourcePack(@NotNull String url, @Nullable byte[] hash, - @Nullable String prompt, boolean force) { - - } - - @Override - public void setResourcePack(@NotNull String url, @Nullable byte[] hash, - @Nullable Component prompt, boolean force) { - - } - - @Override - public void setResourcePack(@NotNull UUID uuid, @NotNull String s, @org.jetbrains.annotations.Nullable byte[] bytes, @org.jetbrains.annotations.Nullable String s1, boolean b) { - - } - - @Override - public void setResourcePack(@NotNull UUID uuid, @NotNull String s, byte @org.jetbrains.annotations.Nullable [] bytes, @org.jetbrains.annotations.Nullable Component component, boolean b) { - - } - - @Override - public void stopSound(Sound arg0, SoundCategory arg1) { - - } - - @Override - public void stopSound(String arg0, SoundCategory arg1) { - - } - - @Override - public void stopSound(@NotNull SoundCategory soundCategory) { - - } - - @Override - public void stopAllSounds() { - - } - - @Override - public PistonMoveReaction getPistonMoveReaction() { - return null; - } - - @Override - public boolean isSwimming() { - return false; - } - - @Override - public void setSwimming(boolean arg0) { - - } - - @Override - public void sendBlockChange(Location arg0, BlockData arg1) { - - } - - @Override - public void sendBlockChanges(@NotNull Collection collection) { - - } - - @Override - public void sendBlockChanges(@NotNull Collection collection, boolean b) { - - } - - @Override - public void sendBlockDamage(@NotNull Location location, float f) { - - } - - @Override - public void sendMultiBlockChange(@NotNull Map map) { - - } - - @Override - public void sendBlockDamage(@NotNull Location location, float v, @NotNull Entity entity) { - - } - - @Override - public void sendBlockDamage(@NotNull Location location, float v, int i) { - - } - - @Override - public void sendEquipmentChange(LivingEntity livingEntity, EquipmentSlot equipmentSlot, ItemStack itemStack) { - - } - - @Override - public void sendEquipmentChange(@NotNull LivingEntity livingEntity, @NotNull Map map) { - - } - - @Override - public void sendSignChange(@NotNull Location location, @org.jetbrains.annotations.Nullable List list, @NotNull DyeColor dyeColor, boolean b) throws IllegalArgumentException { - - } - - @Override - public boolean isRiptiding() { - return false; - } - - @Override - public void setRiptiding(boolean riptiding) { - - } - - @Override - public boolean isPersistent() { - return false; - } - - @Override - public void setPersistent(boolean arg0) { - } - - @Override - public String getPlayerListFooter() { - return null; - } - - @Override - public String getPlayerListHeader() { - return null; - } - - @Override - public void setPlayerListFooter(String arg0) { - } - - @Override - public void setPlayerListHeader(String arg0) { - } - - @Override - public void setPlayerListHeaderFooter(String arg0, String arg1) { - } - - @Override - public void updateCommands() { - } - - @Override - public boolean sleep(Location location, boolean force) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void wakeup(boolean setSpawnLocation) { - // TODO Auto-generated method stub - - } - - @Override - public void startRiptideAttack(int duration, float attackStrength, @Nullable ItemStack attackItem) { - - } - - @Override - public Location getBedLocation() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean discoverRecipe(NamespacedKey recipe) { - // TODO Auto-generated method stub - return false; - } - - @Override - public int discoverRecipes(Collection recipes) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public boolean undiscoverRecipe(NamespacedKey recipe) { - // TODO Auto-generated method stub - return false; - } - - @Override - public int undiscoverRecipes(Collection recipes) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public Block getTargetBlockExact(int maxDistance) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Block getTargetBlockExact(int maxDistance, FluidCollisionMode fluidCollisionMode) { - // TODO Auto-generated method stub - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(double maxDistance) { - // TODO Auto-generated method stub - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(double maxDistance, FluidCollisionMode fluidCollisionMode) { - // TODO Auto-generated method stub - return null; - } - - @Override - public T getMemory(MemoryKey memoryKey) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setMemory(MemoryKey memoryKey, T memoryValue) { - // TODO Auto-generated method stub - - } - - @Override - public @org.jetbrains.annotations.Nullable Sound getHurtSound() { - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable Sound getDeathSound() { - return null; - } - - @Override - public @NotNull Sound getFallDamageSound(int i) { - return null; - } - - @Override - public @NotNull Sound getFallDamageSoundSmall() { - return null; - } - - @Override - public @NotNull Sound getFallDamageSoundBig() { - return null; - } - - @Override - public @NotNull Sound getDrinkingSound(@NotNull ItemStack itemStack) { - return null; - } - - @Override - public @NotNull Sound getEatingSound(@NotNull ItemStack itemStack) { - return null; - } - - @Override - public boolean canBreatheUnderwater() { - return false; - } - - @Override - public double getAbsorptionAmount() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void setAbsorptionAmount(double arg0) { - // TODO Auto-generated method stub - - } - - @Override - public BoundingBox getBoundingBox() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setRotation(float yaw, float pitch) { - // TODO Auto-generated method stub - - } - - @Override - public boolean teleport(@NotNull Location location, @NotNull PlayerTeleportEvent.TeleportCause teleportCause, @NotNull TeleportFlag @NotNull ... teleportFlags) { - return false; - } - - @Override - public void lookAt(double v, double v1, double v2, @NotNull LookAnchor lookAnchor) { - - } - - @Override - public void lookAt(@NotNull Entity entity, @NotNull LookAnchor lookAnchor, @NotNull LookAnchor lookAnchor1) { - - } - - @Override - public void showElderGuardian(boolean b) { - - } - - @Override - public int getWardenWarningCooldown() { - return 0; - } - - @Override - public void setWardenWarningCooldown(int i) { - - } - - @Override - public int getWardenTimeSinceLastWarning() { - return 0; - } - - @Override - public void setWardenTimeSinceLastWarning(int i) { - - } - - @Override - public int getWardenWarningLevel() { - return 0; - } - - @Override - public void setWardenWarningLevel(int i) { - - } - - @Override - public void increaseWardenWarningLevel() { - - } - - @Override - public @NotNull Duration getIdleDuration() { - return null; - } - - @Override - public void resetIdleDuration() { - - } - - @Override - public @NotNull @Unmodifiable Set getSentChunkKeys() { - return Collections.emptySet(); - } - - @Override - public @NotNull @Unmodifiable Set getSentChunks() { - return Collections.emptySet(); - } - - @Override - public boolean isChunkSent(long l) { - return false; - } - - @Override - public BlockFace getFacing() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pose getPose() { - // TODO Auto-generated metod stub - return null; - } - - @Override - public @NotNull SpawnCategory getSpawnCategory() { - return null; - } - - @Override - public boolean isInWorld() { - return false; - } - - @Override - public @org.jetbrains.annotations.Nullable String getAsString() { - return ""; - } - - @Override - public @org.jetbrains.annotations.Nullable EntitySnapshot createSnapshot() { - return null; - } - - @Override - public @NotNull Entity copy() { - return null; - } - - @Override - public @NotNull Entity copy(@NotNull Location location) { - return null; - } - - @Override - public PersistentDataContainer getPersistentDataContainer() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void sendSignChange(Location loc, String[] lines, DyeColor dyeColor) throws IllegalArgumentException { - // TODO Auto-generated method stub - - } - - @Override - public void sendSignChange(@NotNull Location location, - @Nullable String[] strings, - @NotNull DyeColor dyeColor, boolean bl) - throws IllegalArgumentException { - - } - - @Override - public void sendBlockUpdate(@NotNull Location location, @NotNull TileState tileState) throws IllegalArgumentException { - - } - - @Override - public void sendPotionEffectChange(@NotNull LivingEntity livingEntity, @NotNull PotionEffect potionEffect) { - - } - - @Override - public void sendPotionEffectChangeRemove(@NotNull LivingEntity livingEntity, @NotNull PotionEffectType potionEffectType) { - - } - - @Override - public int getClientViewDistance() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public @NotNull Locale locale() { - return Locale.ENGLISH; - } - - @Override - public int getPing() { - return 0; - } - - @Override - public void openBook(ItemStack book) { - // TODO Auto-generated method stub - - } - - @Override - public float getAttackCooldown() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public boolean hasDiscoveredRecipe(NamespacedKey recipe) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set getDiscoveredRecipes() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void attack(Entity target) { - // TODO Auto-generated method stub - - } - - @Override - public void swingMainHand() { - // TODO Auto-generated method stub - - } - - @Override - public void swingOffHand() { - // TODO Auto-generated method stub - - } - - @Override - public void playHurtAnimation(float v) { - - } - - @Override - public Set getCollidableExemptions() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void sendExperienceChange(float progress) { - // TODO Auto-generated method stub - - } - - @Override - public void sendExperienceChange(float progress, int level) { - // TODO Auto-generated method stub - - } - - @Override - public void closeInventory(Reason arg0) { - // TODO Auto-generated method stub - - } - - @Override - public boolean dropItem(boolean arg0) { - // TODO Auto-generated method stub - return false; - } - - @Override - public @org.jspecify.annotations.Nullable Item dropItem(int slot, int amount, boolean throwRandomly, @org.jspecify.annotations.Nullable Consumer entityOperation) { - return null; - } - - @Override - public @org.jspecify.annotations.Nullable Item dropItem(EquipmentSlot slot, int amount, boolean throwRandomly, @org.jspecify.annotations.Nullable Consumer entityOperation) { - return null; - } - - @Override - public @org.jspecify.annotations.Nullable Item dropItem(ItemStack itemStack, boolean throwRandomly, @org.jspecify.annotations.Nullable Consumer entityOperation) { - return null; - } - - @Override - public Location getPotentialBedLocation() { - // TODO Auto-generated method stub - return null; - } - - @Override - public @org.jspecify.annotations.Nullable Location getPotentialRespawnLocation() { - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable FishHook getFishHook() { - return null; - } - - @Override - public InventoryView openAnvil(Location arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public InventoryView openCartographyTable(Location arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public InventoryView openGrindstone(Location arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public InventoryView openLoom(Location arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void openSign(Sign arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void openSign(@NotNull Sign sign, @NotNull Side side) { - - } - - @Override - public void openVirtualSign(Position block, Side side) { - - } - - @Override - public void showDemoScreen() { - - } - - @Override - public boolean isAllowingServerListings() { - return false; - } - - @Override - public InventoryView openSmithingTable(Location arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public InventoryView openStonecutter(Location arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Entity releaseLeftShoulderEntity() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Entity releaseRightShoulderEntity() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void clearActiveItem() { - // TODO Auto-generated method stub - - } - - @Override - public int getActiveItemRemainingTime() { - return 0; - } - - @Override - public void setActiveItemRemainingTime(@Range(from = 0L, to = 2147483647L) int i) { - - } - - @Override - public boolean hasActiveItem() { - return false; - } - - @Override - public int getActiveItemUsedTime() { - return 0; - } - - @Override - public @NotNull EquipmentSlot getActiveItemHand() { - return null; - } - - @Override - public float getSidewaysMovement() { - return 0; - } - - @Override - public float getUpwardsMovement() { - return 0; - } - - @Override - public float getForwardsMovement() { - return 0; - } - - @Override - public void startUsingItem(@NotNull EquipmentSlot equipmentSlot) { - - } - - @Override - public void completeUsingActiveItem() { - - } - - @Override - public ItemStack getActiveItem() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getArrowCooldown() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getArrowsInBody() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getArrowsStuck() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public EntityCategory getCategory() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getHandRaisedTime() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public float getHurtDirection() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getItemUseRemainingTime() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getShieldBlockingDelay() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public Block getTargetBlock(int arg0, FluidMode arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public BlockFace getTargetBlockFace(int arg0, FluidMode arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable BlockFace getTargetBlockFace(int i, @NotNull FluidCollisionMode fluidCollisionMode) { - return null; - } - - @Override - public TargetBlockInfo getTargetBlockInfo(int arg0, FluidMode arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Entity getTargetEntity(int arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public TargetEntityInfo getTargetEntityInfo(int arg0, boolean arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public @org.jetbrains.annotations.Nullable RayTraceResult rayTraceEntities(int i, boolean b) { - return null; - } - - @Override - public boolean isInvisible() { - // TODO Auto-generated method stub - return false; - } - - @Override - public void setNoPhysics(boolean b) { - - } - - @Override - public boolean hasNoPhysics() { - return false; - } - - @Override - public boolean isJumping() { - // TODO Auto-generated method stub - return false; - } - - @Override - public void playPickupItemAnimation(Item arg0, int arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void setArrowCooldown(int arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setArrowsInBody(int arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setArrowsInBody(int i, boolean b) { - - } - - @Override - public void setNextArrowRemoval(@Range(from = 0L, to = 2147483647L) int i) { - - } - - @Override - public int getNextArrowRemoval() { - return 0; - } - - @Override - public int getBeeStingerCooldown() { - return 0; - } - - @Override - public void setBeeStingerCooldown(int i) { - - } - - @Override - public int getBeeStingersInBody() { - return 0; - } - - @Override - public void setBeeStingersInBody(int i) { - - } - - @Override - public void setNextBeeStingerRemoval(@Range(from = 0L, to = 2147483647L) int i) { - - } - - @Override - public int getNextBeeStingerRemoval() { - return 0; - } - - @Override - public void setArrowsStuck(int arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setHurtDirection(float arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void knockback(double v, double v1, double v2) { - - } - - @Override - public void broadcastSlotBreak(@NotNull EquipmentSlot equipmentSlot) { - - } - - @Override - public void broadcastSlotBreak(@NotNull EquipmentSlot equipmentSlot, @NotNull Collection collection) { - - } - - @Override - public @NotNull ItemStack damageItemStack(@NotNull ItemStack itemStack, int i) { - return null; - } - - @Override - public void damageItemStack(@NotNull EquipmentSlot equipmentSlot, int i) { - - } - - @Override - public float getBodyYaw() { - return 0; - } - - @Override - public void setBodyYaw(float v) { - - } - - @Override - public boolean canUseEquipmentSlot(@NotNull EquipmentSlot equipmentSlot) { - return false; - } - - @Override - public @NotNull CombatTracker getCombatTracker() { - return null; - } - - @Override - public void setInvisible(boolean arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setJumping(boolean arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setKiller(Player arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setShieldBlockingDelay(int arg0) { - // TODO Auto-generated method stub - - } - - @Override - public boolean fromMobSpawner() { - // TODO Auto-generated method stub - return false; - } - - @Override - public Chunk getChunk() { - // TODO Auto-generated method stub - return null; - } - - @Override - public SpawnReason getEntitySpawnReason() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isUnderWater() { - return false; - } - - @Override - public Location getOrigin() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isInBubbleColumn() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isInLava() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isInRain() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isInWater() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isInWaterOrBubbleColumn() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isInWaterOrRain() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isInWaterOrRainOrBubbleColumn() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isTicking() { - // TODO Auto-generated method stub - return false; - } - - @Override - public void sendMessage(UUID arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void sendMessage(UUID arg0, String[] arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void sendRawMessage(UUID arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public long getLastLogin() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public long getLastSeen() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getProtocolVersion() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public InetSocketAddress getVirtualHost() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int applyMending(int arg0) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public Firework boostElytra(ItemStack arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void sendOpLevel(byte b) { - - } - - @Override - public void addAdditionalChatCompletions(@NotNull Collection collection) { - - } - - @Override - public void removeAdditionalChatCompletions(@NotNull Collection collection) { - - } - - @Override - public @NotNull Set getTrackedPlayers() { - return null; - } - - @Override - public boolean spawnAt(Location location, SpawnReason spawnReason) { - return false; - } - - @Override - public boolean isInPowderedSnow() { - return false; - } - - @Override - public double getX() { - return 0; - } - - @Override - public double getY() { - return 0; - } - - @Override - public double getZ() { - return 0; - } - - @Override - public float getPitch() { - return 0; - } - - @Override - public float getYaw() { - return 0; - } - - @Override - public boolean collidesAt(@NotNull Location location) { - return false; - } - - @Override - public boolean wouldCollideUsing(@NotNull BoundingBox boundingBox) { - return false; - } - - @Override - public @NotNull EntityScheduler getScheduler() { - return null; - } - - @Override - public @NotNull String getScoreboardEntryName() { - return null; - } - - @Override - public void broadcastHurtAnimation(@NotNull Collection players) { - - } - - @Override - public boolean getAffectsSpawning() { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getClientBrandName() { - // TODO Auto-generated method stub - return null; - } - - @Override - public T getClientOption(ClientOption arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public float getCooldownPeriod() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public float getCooledAttackStrength(float arg0) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public PlayerProfile getPlayerProfile() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getResourcePackHash() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Status getResourcePackStatus() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getViewDistance() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void giveExp(int arg0, boolean arg1) { - // TODO Auto-generated method stub - - } - - @Override - public boolean hasResourcePack() { - // TODO Auto-generated method stub - return false; - } - - @Override - public void addResourcePack(@NotNull UUID uuid, @NotNull String s, @org.jetbrains.annotations.Nullable byte[] bytes, @org.jetbrains.annotations.Nullable String s1, boolean b) { - - } - - @Override - public void removeResourcePack(@NotNull UUID uuid) { - - } - - @Override - public void removeResourcePacks() { - - } - - @Override - public void hideTitle() { - // TODO Auto-generated method stub - - } - - @Override - public void sendHurtAnimation(float v) { - - } - - @Override - public void sendLinks(@NotNull ServerLinks serverLinks) { - - } - - @Override - public void addCustomChatCompletions(@NotNull Collection collection) { - - } - - @Override - public void removeCustomChatCompletions(@NotNull Collection collection) { - - } - - @Override - public void setCustomChatCompletions(@NotNull Collection collection) { - - } - - @Override - public void resetCooldown() { - // TODO Auto-generated method stub - - } - - @Override - public void sendActionBar(String arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void sendActionBar(BaseComponent... arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void sendActionBar(char arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void sendTitle(Title arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setAffectsSpawning(boolean arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setPlayerListHeaderFooter(BaseComponent[] arg0, BaseComponent[] arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void setPlayerListHeaderFooter(BaseComponent arg0, BaseComponent arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void setPlayerProfile(PlayerProfile arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setResourcePack(String arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void setResourcePack(@NotNull String string, - @NotNull String string2, boolean bl) { - - } - - @Override - public void setResourcePack(@NotNull String string, - @NotNull String string2, boolean bl, - @Nullable Component component) { - - } - - @Override - public void setSubtitle(BaseComponent[] arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setSubtitle(BaseComponent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setTitleTimes(int arg0, int arg1, int arg2) { - // TODO Auto-generated method stub - - } - - @Override - public void setViewDistance(int arg0) { - // TODO Auto-generated method stub - - } - - @Override - public int getSimulationDistance() { - return 0; - } - - @Override - public void setSimulationDistance(int simulationDistance) { - - } - - @Override - public int getNoTickViewDistance() { - return 0; - } - - @Override - public void setNoTickViewDistance(int i) { - - } - - @Override - public int getSendViewDistance() { - return 0; - } - - @Override - public void setSendViewDistance(int i) { - - } - - @Override - public void showTitle(BaseComponent[] arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void showTitle(BaseComponent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void showTitle(BaseComponent[] arg0, BaseComponent[] arg1, int arg2, int arg3, int arg4) { - // TODO Auto-generated method stub - - } - - @Override - public void showTitle(BaseComponent arg0, BaseComponent arg1, int arg2, int arg3, int arg4) { - // TODO Auto-generated method stub - - } - - @Override - public void updateTitle(Title arg0) { - // TODO Auto-generated method stub - - } - - @Override - public @NotNull TriState getFrictionState() { - return null; - } - - @Override - public void setFrictionState(@NotNull TriState triState) { - - } - - @Override - public @org.jspecify.annotations.Nullable T getData(DataComponentType.Valued type) { - return null; - } - - @Override - public @org.jspecify.annotations.Nullable T getDataOrDefault(DataComponentType.Valued type, @org.jspecify.annotations.Nullable T fallback) { - return null; - } - - @Override - public boolean hasData(DataComponentType type) { - return false; - } -} diff --git a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/commands/InfoCommand.java b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/commands/InfoCommand.java index 88f152d032..15e439209e 100644 --- a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/commands/InfoCommand.java +++ b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/commands/InfoCommand.java @@ -1,8 +1,5 @@ package com.untamedears.jukealert.commands; -import static com.untamedears.jukealert.util.JAUtility.findLookingAtOrClosestSnitch; - - import co.aikar.commands.BaseCommand; import co.aikar.commands.annotation.CommandAlias; import co.aikar.commands.annotation.Description; @@ -15,6 +12,7 @@ import com.untamedears.jukealert.model.actions.abstr.SnitchAction; import com.untamedears.jukealert.model.appender.SnitchLogAppender; import com.untamedears.jukealert.util.JAUtility; +import static com.untamedears.jukealert.util.JAUtility.findLookingAtOrClosestSnitch; import com.untamedears.jukealert.util.JukeAlertPermissionHandler; import java.util.ArrayList; import java.util.LinkedList; @@ -23,10 +21,10 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; - import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -183,7 +181,30 @@ public void sendSnitchLog( String playerName, boolean censor) { SnitchLogAppender logAppender = snitch.getAppender(SnitchLogAppender.class); - List logs = new ArrayList<>(logAppender.getFullLogs()); + if (snitch.getId() == -1) { + displaySnitchLog(player, snitch, logAppender.getFullLogs(), offset, pageLength, actionType, playerName, censor); + } + Bukkit.getScheduler().runTaskAsynchronously(JukeAlert.getInstance(), () -> { + final List actions = logAppender.loadLogs(); + Bukkit.getScheduler().runTask(JukeAlert.getInstance(), () -> { + if (!player.isOnline()) { + return; + } + displaySnitchLog(player, snitch, actions, offset, pageLength, actionType, playerName, censor); + }); + }); + } + + private void displaySnitchLog( + Player player, + Snitch snitch, + List logs, + int offset, + int pageLength, + String actionType, + String playerName, + boolean censor) { + logs = new ArrayList<>(logs); if (playerName != null) { String playerNameLowered = playerName.toLowerCase(); List logCopy = new LinkedList<>(); diff --git a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/database/JukeAlertDAO.java b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/database/JukeAlertDAO.java index 1c95cc0ea4..eb7ba13a06 100644 --- a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/database/JukeAlertDAO.java +++ b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/database/JukeAlertDAO.java @@ -23,9 +23,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import java.util.concurrent.Callable; import java.util.function.Consumer; @@ -344,6 +346,9 @@ public void loadAll(@NotNull final Consumer callback) { final SnitchTypeManager snitchTypeManager = JukeAlert.getInstance().getSnitchConfigManager(); final SnitchManager snitchManager = JukeAlert.getInstance().getSnitchManager(); final WorldIDManager worldIDManager = CivModCorePlugin.getInstance().getWorldIdManager(); + + Set unknownWorldIds = new HashSet<>(); + try (final Connection connection = this.db.getConnection(); final PreparedStatement statement = connection.prepareStatement( "SELECT ja_snitches.id, x, y, z, world_id, type_id, group_id, name, last_refresh, toggle_lever, placer FROM ja_snitches" + @@ -358,8 +363,10 @@ public void loadAll(@NotNull final Consumer callback) { final short snitchWorldID = results.getShort(5); final World snitchWorld = worldIDManager.getWorldByInternalID(snitchWorldID); if (snitchWorld == null) { - this.logger.warning( - "Could not load world [" + snitchWorldID + "] for snitch [" + snitchID + "]"); + if (unknownWorldIds.add(snitchWorldID)) { + this.logger.warning( + "Could not load world [" + snitchWorldID + "] for snitch [" + snitchID + "]"); + } continue; } final int snitchTypeID = results.getInt(6); diff --git a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/gui/SnitchLogGUI.java b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/gui/SnitchLogGUI.java index 1e89775236..9c3cfc30b6 100644 --- a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/gui/SnitchLogGUI.java +++ b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/gui/SnitchLogGUI.java @@ -16,6 +16,7 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextDecoration; import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -53,17 +54,8 @@ private boolean INTERNAL_hasPermission(@NotNull final PermissionType permission) return this.snitch.hasPermission(this.player.getUniqueId(), permission); } - private List INTERNAL_constructContent() { - if (this.logAppender == null) { - final var item = new ItemStack(Material.BARRIER); - ItemUtils.setComponentDisplayName(item, Component.text() - .decoration(TextDecoration.ITALIC, false) - .color(NamedTextColor.RED) - .content("This snitch can not create logs") - .build()); - return MoreCollectionUtils.asLazyList(Collections.singletonList(() -> new DecorationStack(item))); - } - final var actions = this.logAppender.getFullLogs(); + private @NotNull List INTERNAL_constructContent( + final @NotNull List actions) { if (actions.isEmpty()) { final var item = new ItemStack(Material.BARRIER); ItemUtils.setComponentDisplayName(item, Component.text() @@ -232,9 +224,41 @@ public void clicked(@NotNull final Player clicker) { } public void showScreen() { - if (this.buttonCache == null) { - this.buttonCache = INTERNAL_constructContent(); + if (this.buttonCache != null) { + INTERNAL_showScreenWithContent(); + return; + } + if (this.logAppender == null) { + final var item = new ItemStack(Material.BARRIER); + ItemUtils.setComponentDisplayName(item, Component.text() + .decoration(TextDecoration.ITALIC, false) + .color(NamedTextColor.RED) + .content("This snitch can not create logs") + .build()); + this.buttonCache = MoreCollectionUtils.asLazyList( + Collections.singletonList(() -> new DecorationStack(item))); + INTERNAL_showScreenWithContent(); + return; } + SnitchLogAppender logAppender = snitch.getAppender(SnitchLogAppender.class); + if (snitch.getId() == -1) { + this.buttonCache = INTERNAL_constructContent(logAppender.getFullLogs()); + INTERNAL_showScreenWithContent(); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(JukeAlert.getInstance(), () -> { + final List actions = logAppender.loadLogs(); + Bukkit.getScheduler().runTask(JukeAlert.getInstance(), () -> { + if (!this.player.isOnline()) { + return; + } + this.buttonCache = INTERNAL_constructContent(actions); + INTERNAL_showScreenWithContent(); + }); + }); + } + + private void INTERNAL_showScreenWithContent() { final var view = new MultiPageView(this.player, this.buttonCache, StringUtils.substring(this.snitch.getName(), 0, 32), true); if (this.logAppender != null) { diff --git a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/listener/LoggableActionListener.java b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/listener/LoggableActionListener.java index a9b1e89485..20a2c7bae3 100644 --- a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/listener/LoggableActionListener.java +++ b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/listener/LoggableActionListener.java @@ -21,6 +21,7 @@ import com.untamedears.jukealert.model.actions.impl.LogoutAction; import com.untamedears.jukealert.model.actions.impl.MountEntityAction; import com.untamedears.jukealert.model.actions.impl.OpenContainerAction; +import com.untamedears.jukealert.model.actions.impl.PlaceVehicleAction; import com.untamedears.jukealert.util.JukeAlertPermissionHandler; import java.util.Collection; import java.util.HashSet; @@ -60,6 +61,7 @@ import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDismountEvent; import org.bukkit.event.entity.EntityMountEvent; +import org.bukkit.event.entity.EntityPlaceEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerBucketFillEvent; @@ -179,6 +181,20 @@ public void onDestroyVehicle(VehicleDestroyEvent event) { player.getUniqueId(), event.getVehicle().getLocation(), getEntityName(event.getVehicle()))); } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlaceVehicle(EntityPlaceEvent event) { + Player player = event.getPlayer(); + if (player == null) { + return; + } + Entity entity = event.getEntity(); + if (!(entity instanceof Vehicle vehicle) || vehicle.getSpawnCategory() != SpawnCategory.MISC) { + return; + } + handlePlayerAction(player, s -> new PlaceVehicleAction(System.currentTimeMillis(), s, + player.getUniqueId(), entity.getLocation(), getVehiclePlaceName(entity))); + } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEnterVehicle(VehicleEnterEvent event) { if (event.getEntered().getType() != EntityType.PLAYER || event.getVehicle().getSpawnCategory() != SpawnCategory.MISC) { @@ -267,7 +283,7 @@ public void onOpenInventory(InventoryOpenEvent event) { location, material)); } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + @EventHandler(priority = EventPriority.MONITOR) public void playerJoinEvent(PlayerJoinEvent event) { Player player = event.getPlayer(); Set covering = new HashSet<>(snitchManager.getSnitchesCovering(event.getPlayer().getLocation())); @@ -275,7 +291,7 @@ public void playerJoinEvent(PlayerJoinEvent event) { insideFields.put(event.getPlayer().getUniqueId(), covering); } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + @EventHandler(priority = EventPriority.LOW) public void playerQuitEvent(PlayerQuitEvent event) { handleSnitchLogout(event.getPlayer()); } @@ -361,4 +377,12 @@ private String getVehicleName(Vehicle vehicle) { } } + private String getVehiclePlaceName(Entity entity) { + if (entity instanceof Boat boat) { + return boat.getBoatMaterial().name(); + } else { + return entity.getType().toString(); + } + } + } diff --git a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/actions/LoggedActionFactory.java b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/actions/LoggedActionFactory.java index 1ca0c6ef45..8265f31d72 100644 --- a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/actions/LoggedActionFactory.java +++ b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/actions/LoggedActionFactory.java @@ -21,6 +21,7 @@ import com.untamedears.jukealert.model.actions.impl.LogoutAction; import com.untamedears.jukealert.model.actions.impl.MountEntityAction; import com.untamedears.jukealert.model.actions.impl.OpenContainerAction; +import com.untamedears.jukealert.model.actions.impl.PlaceVehicleAction; import it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap; @@ -131,6 +132,10 @@ private void registerInternalProviders() { (snitch, player, loc, time, victim) -> new MountEntityAction( time, snitch, player, loc, victim)); + registerProvider(PlaceVehicleAction.ID, + (snitch, player, loc, time, victim) -> new PlaceVehicleAction( + time, snitch, player, loc, victim)); + registerProvider(OpenContainerAction.ID, (snitch, player, loc, time, victim) -> new OpenContainerAction( time, snitch, player, loc, Material.valueOf(victim))); diff --git a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/actions/impl/PlaceVehicleAction.java b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/actions/impl/PlaceVehicleAction.java new file mode 100644 index 0000000000..e2ad524c54 --- /dev/null +++ b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/actions/impl/PlaceVehicleAction.java @@ -0,0 +1,46 @@ +package com.untamedears.jukealert.model.actions.impl; + +import com.untamedears.jukealert.model.Snitch; +import com.untamedears.jukealert.model.actions.abstr.LoggablePlayerVictimAction; +import com.untamedears.jukealert.util.JAUtility; +import java.util.UUID; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import vg.civcraft.mc.civmodcore.inventory.gui.DecorationStack; +import vg.civcraft.mc.civmodcore.inventory.gui.IClickable; +import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; + +public class PlaceVehicleAction extends LoggablePlayerVictimAction { + + public static final String ID = "PLACE_VEHICLE"; + + public PlaceVehicleAction(long time, Snitch snitch, UUID player, Location location, String victim) { + super(time, snitch, player, location, victim); + } + + @Override + public IClickable getGUIRepresentation() { + ItemStack is = new ItemStack(getVehicle()); + super.enrichGUIItem(is); + return new DecorationStack(is); + } + + /** + * @return Material of the vehicle placed + */ + public Material getVehicle() { + return JAUtility.getVehicle(victim); + } + + @Override + public String getIdentifier() { + return ID; + } + + @Override + public String getChatRepresentationIdentifier() { + return "Placed " + ItemUtils.getItemName(getVehicle()); + } + +} diff --git a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/appender/SnitchLogAppender.java b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/appender/SnitchLogAppender.java index b0e4b65380..358069d4eb 100644 --- a/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/appender/SnitchLogAppender.java +++ b/plugins/jukealert-paper/src/main/java/com/untamedears/jukealert/model/appender/SnitchLogAppender.java @@ -42,13 +42,16 @@ public SnitchLogAppender(final Snitch snitch, @NotNull public List getFullLogs() { final List actions = getSnitch().getId() == -1 ? - new ArrayList<>(this.pendingActions.keySet()) : - JukeAlert.getInstance().getDAO().loadLogs( - getSnitch(), getMaximumActionAge(), this.config.getHardCap()); + new ArrayList<>(this.pendingActions.keySet()) : loadLogs(); actions.sort(ACTION_COMPARATOR); return actions; } + public List loadLogs() { + return JukeAlert.getInstance().getDAO().loadLogs( + getSnitch(), getMaximumActionAge(), this.config.getHardCap()); + } + /** * Deletes ALL logs for this snitch. */ diff --git a/plugins/kiragateway-velocity/src/main/java/net/civmc/kiragatewayvelocity/commands/DiscordAuth.java b/plugins/kiragateway-velocity/src/main/java/net/civmc/kiragatewayvelocity/commands/DiscordAuth.java index c97461945e..f89b705370 100644 --- a/plugins/kiragateway-velocity/src/main/java/net/civmc/kiragatewayvelocity/commands/DiscordAuth.java +++ b/plugins/kiragateway-velocity/src/main/java/net/civmc/kiragatewayvelocity/commands/DiscordAuth.java @@ -26,7 +26,7 @@ public void execute(final Invocation invocation) { RabbitCommands rabbit = KiraGateway.getInstance().getRabbit(); rabbit.sendAuthCode(code, player.getUsername(), player.getUniqueId()); source.sendMessage(mm.deserialize(String.format( - "Your code is '%s'. Execute '/auth %s' in the official discord to authenticate and link your account. Note that upper/lower case does not matter.", + "Your code is '%s'. Execute '/auth %s' in the official discord to authenticate and link your account. Note that upper/lower case does not matter. This code will expire in 5 minutes.", code, code, code))); } else { source.sendMessage(mm.deserialize("This command can only be run by a player.")); diff --git a/plugins/kitpvp-paper/build.gradle.kts b/plugins/kitpvp-paper/build.gradle.kts index 20de300c48..96cd1d5a10 100644 --- a/plugins/kitpvp-paper/build.gradle.kts +++ b/plugins/kitpvp-paper/build.gradle.kts @@ -12,9 +12,9 @@ dependencies { compileOnly(project(":plugins:civmodcore-paper")) compileOnly(project(":plugins:finale-paper")) - compileOnly("net.luckperms:api:5.4") + compileOnly(libs.luckperms.api) - compileOnly(files("../../ansible/src/paper-plugins/BreweryX-3.6.0.jar")) + compileOnly(files("../../ansible/src/paper-plugins/BreweryX-3.6.3.jar")) compileOnly(libs.aswm.api) - compileOnly("me.clip:placeholderapi:2.11.6") + compileOnly(libs.placeholderapi) } diff --git a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/KitPvpPlugin.java b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/KitPvpPlugin.java index 4833acc8bb..991c317d70 100644 --- a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/KitPvpPlugin.java +++ b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/KitPvpPlugin.java @@ -93,7 +93,7 @@ public void onEnable() { PrivateArenaListener privateArenaListener = new PrivateArenaListener(spawnProvider, manager); getServer().getPluginManager().registerEvents(privateArenaListener, this); getCommand("arena").setExecutor(new ArenaCommand(this, arenaDao, ranked, queueManager, manager, privateArenaListener)); - getServer().getPluginManager().registerEvents(new RespawnListener(manager), this); + getServer().getPluginManager().registerEvents(new RespawnListener(manager, this), this); Bukkit.getScheduler().runTaskTimer(this, new ArenaCleaner(manager), 20 * 60, 20 * 60); } catch (SQLException e) { throw new RuntimeException(e); diff --git a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/arena/RespawnListener.java b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/arena/RespawnListener.java index 6cdf3f7dc0..9578650c34 100644 --- a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/arena/RespawnListener.java +++ b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/arena/RespawnListener.java @@ -1,32 +1,74 @@ package net.civmc.kitpvp.arena; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.plugin.java.JavaPlugin; public class RespawnListener implements Listener { + private static final int INVULNERABILITY_TICKS = 5 * 20; + private final ArenaManager manager; + private final JavaPlugin plugin; + private final Set invulnerablePlayers = new HashSet<>(); - public RespawnListener(ArenaManager manager) { + public RespawnListener(final ArenaManager manager, final JavaPlugin plugin) { this.manager = manager; + this.plugin = plugin; } - @EventHandler - public void on(PlayerRespawnEvent event) { - World world = event.getPlayer().getWorld(); - String worldName = world.getName(); + public void on(final PlayerRespawnEvent event) { + final Player player = event.getPlayer(); + final World world = player.getWorld(); + final String worldName = world.getName(); if (manager.isArena(worldName)) { - for (LoadedArena arena : manager.getArenas()) { + for (final LoadedArena arena : manager.getArenas()) { if (manager.getArenaName(arena).equals(worldName)) { - Location spawn = arena.arena().spawn().clone(); + final Location spawn = arena.arena().spawn().clone(); spawn.setWorld(world); event.setRespawnLocation(spawn); + grantInvulnerability(player); } } } } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void on(final EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player player)) { + return; + } + if (invulnerablePlayers.contains(player.getUniqueId())) { + event.setCancelled(true); + } + } + + @EventHandler + public void on(final PlayerChangedWorldEvent event) { + invulnerablePlayers.remove(event.getPlayer().getUniqueId()); + } + + @EventHandler + public void on(final PlayerQuitEvent event) { + invulnerablePlayers.remove(event.getPlayer().getUniqueId()); + } + + private void grantInvulnerability(final Player player) { + final UUID uuid = player.getUniqueId(); + invulnerablePlayers.add(uuid); + Bukkit.getScheduler().runTaskLater(plugin, () -> invulnerablePlayers.remove(uuid), INVULNERABILITY_TICKS); + } } diff --git a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/EnchantmentGui.java b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/EnchantmentGui.java index 0bd2d911c7..435c30ee24 100644 --- a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/EnchantmentGui.java +++ b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/EnchantmentGui.java @@ -54,7 +54,8 @@ public void addItems(ClickableInventory inventory) { && !enchantment.isCursed() && enchantment != Enchantment.BANE_OF_ARTHROPODS && enchantment != Enchantment.SMITE - && enchantment != Enchantment.MENDING) { + && enchantment != Enchantment.MENDING + && enchantment != Enchantment.WIND_BURST) { for (Enchantment currentEnchantment : kitItem.getEnchantments().keySet()) { if (currentEnchantment.conflictsWith(enchantment) && currentEnchantment != enchantment) { slot++; diff --git a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/GenericArmourSelectionGui.java b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/GenericArmourSelectionGui.java index d7501f79ff..6e939abc04 100644 --- a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/GenericArmourSelectionGui.java +++ b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/GenericArmourSelectionGui.java @@ -35,6 +35,11 @@ public void addItems(ClickableInventory inventory) { inventory.setSlot(toClickable(KitItem.LEATHER_LEGGINGS), 18); inventory.setSlot(toClickable(KitItem.LEATHER_BOOTS), 27); + inventory.setSlot(toClickable(KitItem.COPPER_HELMET), 8); + inventory.setSlot(toClickable(KitItem.COPPER_CHESTPLATE), 17); + inventory.setSlot(toClickable(KitItem.COPPER_LEGGINGS), 26); + inventory.setSlot(toClickable(KitItem.COPPER_BOOTS), 35); + inventory.setSlot(toClickable(KitItem.GOLDEN_HELMET), 1); inventory.setSlot(toClickable(KitItem.GOLDEN_CHESTPLATE), 10); inventory.setSlot(toClickable(KitItem.GOLDEN_LEGGINGS), 19); diff --git a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/WeaponsAndToolsSelectionGui.java b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/WeaponsAndToolsSelectionGui.java index e2cfc640a9..00b1c64612 100644 --- a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/WeaponsAndToolsSelectionGui.java +++ b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/gui/selection/WeaponsAndToolsSelectionGui.java @@ -33,8 +33,8 @@ public void addItems(ClickableInventory inventory) { inventory.setSlot(toClickable(KitItem.WOODEN_SWORD), 0); inventory.setSlot(toClickable(KitItem.WOODEN_AXE), 9); inventory.setSlot(toClickable(KitItem.WOODEN_PICKAXE), 18); - inventory.setSlot(toClickable(KitItem.WOODEN_SHOVEL), 27); - inventory.setSlot(toClickable(KitItem.WOODEN_HOE), 36); + inventory.setSlot(toClickable(KitItem.WIND_CHARGE), 27); + inventory.setSlot(toClickable(KitItem.MACE), 36); inventory.setSlot(toClickable(KitItem.GOLDEN_SWORD), 1); inventory.setSlot(toClickable(KitItem.GOLDEN_AXE), 10); diff --git a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/kit/KitItem.java b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/kit/KitItem.java index a845f67c7f..ba80a12a2a 100644 --- a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/kit/KitItem.java +++ b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/kit/KitItem.java @@ -8,11 +8,19 @@ import org.bukkit.Material; public enum KitItem { + MACE(Material.MACE, KitCategory.TOOL, 5), + WIND_CHARGE(Material.WIND_CHARGE, KitCategory.TOOL, 0), + LEATHER_HELMET(Material.LEATHER_HELMET, KitCategory.ARMOUR, 0), LEATHER_CHESTPLATE(Material.LEATHER_CHESTPLATE, KitCategory.ARMOUR, 0), LEATHER_LEGGINGS(Material.LEATHER_LEGGINGS, KitCategory.ARMOUR, 0), LEATHER_BOOTS(Material.LEATHER_BOOTS, KitCategory.ARMOUR, 0), + COPPER_HELMET(Material.COPPER_HELMET, KitCategory.ARMOUR, 0), + COPPER_CHESTPLATE(Material.COPPER_CHESTPLATE, KitCategory.ARMOUR, 0), + COPPER_LEGGINGS(Material.COPPER_LEGGINGS, KitCategory.ARMOUR, 0), + COPPER_BOOTS(Material.COPPER_BOOTS, KitCategory.ARMOUR, 0), + GOLDEN_HELMET(Material.GOLDEN_HELMET, KitCategory.ARMOUR, 0), GOLDEN_CHESTPLATE(Material.GOLDEN_CHESTPLATE, KitCategory.ARMOUR, 0), GOLDEN_LEGGINGS(Material.GOLDEN_LEGGINGS, KitCategory.ARMOUR, 0), diff --git a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/ranked/RankedQueueManager.java b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/ranked/RankedQueueManager.java index 3702c9ece6..b39de1fd7f 100644 --- a/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/ranked/RankedQueueManager.java +++ b/plugins/kitpvp-paper/src/main/java/net/civmc/kitpvp/ranked/RankedQueueManager.java @@ -14,6 +14,7 @@ import java.util.SequencedMap; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import net.civmc.kitpvp.KitApplier; import net.civmc.kitpvp.KitPvpPlugin; @@ -28,6 +29,10 @@ import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextDecoration; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.data.TemporaryNodeMergeStrategy; +import net.luckperms.api.model.user.UserManager; +import net.luckperms.api.node.types.PermissionNode; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; @@ -114,7 +119,7 @@ public RankedQueueManager(KitPvpDao kitDao, RankedDao dao, ArenaManager arenaMan JavaPlugin.getPlugin(KitPvpPlugin.class).getLogger().log(Level.WARNING, "Ticking queued players", ex); } }, 300, 300); - /*Bukkit.getScheduler().runTaskTimer(JavaPlugin.getPlugin(KitPvpPlugin.class), () -> { + Bukkit.getScheduler().runTaskTimer(JavaPlugin.getPlugin(KitPvpPlugin.class), () -> { try { for (RankedDao.Rank rank : dao.getTop(10)) { UserManager userManager = LuckPermsProvider.get().getUserManager(); @@ -124,17 +129,17 @@ public RankedQueueManager(KitPvpDao kitDao, RankedDao dao, ArenaManager arenaMan } user.data().add( PermissionNode.builder() - .permission("ajqueue.priority.8") - .expiry(5, TimeUnit.MINUTES) + .permission("rankedpvpstar") + .expiry(15, TimeUnit.MINUTES) .build(), TemporaryNodeMergeStrategy.REPLACE_EXISTING_IF_DURATION_LONGER); userManager.saveUser(user); }); } } catch (RuntimeException ex) { - JavaPlugin.getPlugin(KitPvpPlugin.class).getLogger().log(Level.WARNING, "Ticking queue priority", ex); + JavaPlugin.getPlugin(KitPvpPlugin.class).getLogger().log(Level.WARNING, "Ticking PvP stars", ex); } - }, 20 * 60, 20 * 60);*/ + }, 20 * 60, 20 * 60); } public RankedMatch getMatch(Player player) { diff --git a/plugins/namecolors-paper/build.gradle.kts b/plugins/namecolors-paper/build.gradle.kts index 8b3cb90d4e..483c78b9bd 100644 --- a/plugins/namecolors-paper/build.gradle.kts +++ b/plugins/namecolors-paper/build.gradle.kts @@ -13,5 +13,5 @@ dependencies { compileOnly(project(":plugins:namelayer-paper")) compileOnly(project(":plugins:civchat2-paper")) - compileOnly(files("../../ansible/src/paper-plugins/TAB v5.2.5.jar")) + compileOnly(files("../../ansible/src/paper-plugins/TAB v5.5.0.jar")) } diff --git a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/command/commands/ListGroups.java b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/command/commands/ListGroups.java index f65303dbf0..9ea82818de 100644 --- a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/command/commands/ListGroups.java +++ b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/command/commands/ListGroups.java @@ -6,8 +6,11 @@ import co.aikar.commands.annotation.Syntax; import java.util.List; import java.util.UUID; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; import vg.civcraft.mc.namelayer.GroupManager; import vg.civcraft.mc.namelayer.NameLayerAPI; @@ -17,28 +20,36 @@ public class ListGroups extends BaseCommandMiddle { @CommandAlias("nllg|listgroups|groups") - @Syntax("[page]") + @Syntax("[player|page]") @Description("List groups.") - public void execute(CommandSender sender, @Optional String pageNumber) { - Player p = null; - UUID uuid = null; + public void execute(CommandSender sender, @Optional String targetOrPage) { + UUID uuid; boolean autopages = false; + Integer targetPage = null; + final boolean isAdmin = sender instanceof ConsoleCommandSender + || sender.isOp() || sender.hasPermission("namelayer.admin"); - if ((sender.isOp() || sender.hasPermission("namelayer.admin"))) { - if (pageNumber == null) { - uuid = NameLayerAPI.getUUID(sender.getName()); - } else if (pageNumber != null) { - uuid = NameLayerAPI.getUUID(sender.getName()); + if (isAdmin) { + uuid = NameLayerAPI.getUUID(sender.getName()); + if (targetOrPage != null) { + try { + targetPage = Integer.parseInt(targetOrPage); + } catch (NumberFormatException exception) { + uuid = NameLayerAPI.getUUID(targetOrPage); + } } if (uuid == null) { - sender.sendMessage(ChatColor.RED + "UUID is NULL, OP Usage is /nllg "); + sender.sendMessage(Component.text("Unknown player: " + targetOrPage, NamedTextColor.RED)); return; } autopages = true; } else { - p = (Player) sender; - uuid = NameLayerAPI.getUUID(p.getName()); + if (!(sender instanceof Player player)) { + sender.sendMessage(Component.text("Player only.", NamedTextColor.RED)); + return; + } + uuid = NameLayerAPI.getUUID(player.getName()); } List groups = gm.getAllGroupNames(uuid); @@ -53,13 +64,15 @@ public void execute(CommandSender sender, @Optional String pageNumber) { int actualPages = pages; int target = 1; - if (pageNumber != null) { + if (!autopages && targetOrPage != null) { try { - target = Integer.parseInt(pageNumber); - } catch (NumberFormatException e) { - sender.sendMessage(ChatColor.RED + pageNumber + " is not a number"); + target = Integer.parseInt(targetOrPage); + } catch (NumberFormatException exception) { + sender.sendMessage(ChatColor.RED + targetOrPage + " is not a number"); return; } + } else if (targetPage != null) { + target = targetPage; } if (target >= pages) { diff --git a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/group/Group.java b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/group/Group.java index f1051369ba..523dd1b28c 100644 --- a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/group/Group.java +++ b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/group/Group.java @@ -578,6 +578,9 @@ public UUID getOwner() { * @return true if the UUID belongs to the owner of the group, false otherwise. */ public boolean isOwner(UUID uuid) { + if (owner == null) { + return false; + } return owner.equals(uuid); } diff --git a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/gui/AdminFunctionsGUI.java b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/gui/AdminFunctionsGUI.java index 728402491e..0c46e62a5c 100644 --- a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/gui/AdminFunctionsGUI.java +++ b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/gui/AdminFunctionsGUI.java @@ -9,6 +9,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -20,7 +21,6 @@ import vg.civcraft.mc.civmodcore.inventory.gui.Clickable; import vg.civcraft.mc.civmodcore.inventory.gui.ClickableInventory; import vg.civcraft.mc.civmodcore.inventory.gui.DecorationStack; -import vg.civcraft.mc.civmodcore.inventory.gui.IClickable; import vg.civcraft.mc.civmodcore.inventory.gui.LClickable; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; import vg.civcraft.mc.namelayer.NameLayerAPI; @@ -75,12 +75,18 @@ public void showScreen() { // ci.setSlot(mergeClick, 12); ItemStack colorChangeStack = new ItemStack(Material.WHITE_DYE); ItemUtils.setComponentDisplayName(colorChangeStack, - Component.text("Change group color of ", NamedTextColor.GOLD).append(g.getGroupNameColored())); + Component.text("Change group color of ", NamedTextColor.GOLD) + .append(g.getGroupNameColored()) + .decoration(TextDecoration.ITALIC, false) + ); Clickable colorChangeClick; if (gm.hasAccess(g, p.getUniqueId(), PermissionType.getPermission("EDIT_COLOR"))) { colorChangeClick = getGroupColorChangeButton(); } else { - ItemUtils.setComponentLore(colorChangeStack, Component.text("You don't have permission to do this", NamedTextColor.RED)); + ItemUtils.setComponentLore(colorChangeStack, + Component.text("You don't have permission to do this", NamedTextColor.RED) + .decoration(TextDecoration.ITALIC, false) + ); colorChangeClick = new DecorationStack(colorChangeStack); } ci.setSlot(colorChangeClick, 11); @@ -278,7 +284,10 @@ public void clicked(Player p) { private LClickable getGroupColorChangeButton() { return new LClickable(Material.WHITE_DYE, - Component.text("Change group color of ", NamedTextColor.GOLD).append(g.getGroupNameColored()), p -> { + Component.text("Change group color of ", NamedTextColor.GOLD) + .append(g.getGroupNameColored()) + .decoration(TextDecoration.ITALIC, false) + , p -> { ClickableInventory.forceCloseInventory(p); p.sendMessage(Component.text("Enter the color you wish to change ", NamedTextColor.GREEN).append(g.getGroupNameColored()) .append(Component.text(" to or type \"cancel\" to leave this prompt", NamedTextColor.GREEN))); diff --git a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/permission/GroupPermission.java b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/permission/GroupPermission.java index b767996459..572c0c3aad 100644 --- a/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/permission/GroupPermission.java +++ b/plugins/namelayer-paper/src/main/java/vg/civcraft/mc/namelayer/permission/GroupPermission.java @@ -4,6 +4,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import org.bukkit.Bukkit; import vg.civcraft.mc.namelayer.GroupManager.PlayerType; import vg.civcraft.mc.namelayer.NameLayerPlugin; import vg.civcraft.mc.namelayer.database.GroupManagerDao; @@ -13,6 +16,7 @@ public class GroupPermission { private Map> perms; private GroupManagerDao db = NameLayerPlugin.getGroupManagerDao(); + private final Lock permissionWriteLock = new ReentrantLock(true); private Group group; @@ -74,18 +78,19 @@ public String listPermsforPlayerType(PlayerType type) { * @return Returns false if the PlayerType already has the permission. */ public boolean addPermission(PlayerType pType, PermissionType permType) { - return addPermission(pType, permType, true); - } - - public boolean addPermission(PlayerType pType, PermissionType permType, boolean savetodb) { List playerPerms = perms.get(pType); if (playerPerms == null || playerPerms.contains(permType)) { return false; } playerPerms.add(permType); - if (savetodb) { - db.addPermission(group.getName(), pType.name(), Collections.singletonList(permType)); - } + Bukkit.getScheduler().runTaskAsynchronously(NameLayerPlugin.getInstance(), () -> { + permissionWriteLock.lock(); + try { + db.addPermission(group.getName(), pType.name(), Collections.singletonList(permType)); + } finally { + permissionWriteLock.unlock(); + } + }); return true; } @@ -97,18 +102,19 @@ public boolean addPermission(PlayerType pType, PermissionType permType, boolean * @return Returns false if the PlayerType doesn't have that permission. */ public boolean removePermission(PlayerType pType, PermissionType permType) { - return removePermission(pType, permType, true); - } - - public boolean removePermission(PlayerType pType, PermissionType permType, boolean savetodb) { List playerPerms = perms.get(pType); if (playerPerms == null || !playerPerms.contains(permType)) { return false; } playerPerms.remove(permType); - if (savetodb) { - db.removePermissionAsync(group.getName(), pType, permType); - } + Bukkit.getScheduler().runTaskAsynchronously(NameLayerPlugin.getInstance(), () -> { + permissionWriteLock.lock(); + try { + db.removePermission(group.getName(), pType, permType); + } finally { + permissionWriteLock.unlock(); + } + }); return true; } diff --git a/plugins/randomspawn-paper/src/main/java/me/josvth/randomspawn/spawn/BlockingSpawnSelector.java b/plugins/randomspawn-paper/src/main/java/me/josvth/randomspawn/spawn/BlockingSpawnSelector.java index 68b750a46c..5bb9cede0d 100644 --- a/plugins/randomspawn-paper/src/main/java/me/josvth/randomspawn/spawn/BlockingSpawnSelector.java +++ b/plugins/randomspawn-paper/src/main/java/me/josvth/randomspawn/spawn/BlockingSpawnSelector.java @@ -84,7 +84,7 @@ protected CompletableFuture getRandomSpawnLocationAsync(World world, b ret = ret.thenCompose(location -> { BastionBlockManager bm = Bastion.getBastionManager(); if (bm != null) { - if (!bm.getBlockingBastions(location).isEmpty()) { + if (!bm.getBlockingBastions(location, b -> b.getType().isBlockLiquids()).isEmpty()) { return getRandomSpawnLocationAsync(world, block); } } diff --git a/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java b/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java index 02201d6749..fc266a0aad 100644 --- a/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java +++ b/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java @@ -45,7 +45,9 @@ public void on(BlockPistonExtendEvent event) { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void on(BlockPistonRetractEvent event) { - plugin.getPlantLogicManager().handleBlockDestruction(event.getBlock()); + for (Block block : event.getBlocks()) { + plugin.getPlantLogicManager().handleBlockDestruction(block); + } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) diff --git a/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/replant/AutoReplantListener.java b/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/replant/AutoReplantListener.java index c9b483c6d3..ae30423cbc 100644 --- a/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/replant/AutoReplantListener.java +++ b/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/replant/AutoReplantListener.java @@ -171,6 +171,7 @@ private void replantCropFromDrops(PlayerInteractEvent event, Material seed) { } else { drop.setAmount(amount - 1); } + break; } } } diff --git a/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java b/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java index fdf67b2a8c..fc95a8afe4 100644 --- a/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java +++ b/plugins/realisticbiomes-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.apache.commons.lang3.StringUtils; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -47,8 +49,7 @@ public void showRBOverview(Biome biome) { currentBiome = biome; } if (inventory == null) { - String biomeText = (currentBiome.toString().toLowerCase()).replace("_", " "); - biomeText = StringUtils.capitalize(biomeText); + String biomeText = PlainTextComponentSerializer.plainText().serialize(Component.translatable(currentBiome)); biomeText = StringUtils.abbreviate(biomeText, 30); inventory = new ComponableInventory(ChatColor.DARK_GRAY + biomeText, 6, player); } else { diff --git a/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java b/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java index a5292fef54..eb273699c2 100644 --- a/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java +++ b/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/listener/PlantListener.java @@ -7,6 +7,7 @@ import com.untamedears.realisticbiomes.model.Plant; import com.untamedears.realisticbiomes.model.PlantLoadState; import com.untamedears.realisticbiomes.utils.RBUtils; +import org.bukkit.ExplosionResult; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.event.Cancellable; @@ -45,7 +46,9 @@ public void on(BlockPistonExtendEvent event) { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void on(BlockPistonRetractEvent event) { - plugin.getPlantLogicManager().handleBlockDestruction(event.getBlock()); + for (Block block : event.getBlocks()) { + plugin.getPlantLogicManager().handleBlockDestruction(block); + } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -55,6 +58,9 @@ public void onBlockBreak(BlockBreakEvent event) { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onExplosion(EntityExplodeEvent event) { + if (event.getExplosionResult() == ExplosionResult.KEEP || event.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) { + return; + } for (Block block : event.blockList()) { plugin.getPlantLogicManager().handleBlockDestruction(block); } diff --git a/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java b/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java index 2caabe0e51..36d4e638fb 100644 --- a/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java +++ b/plugins/realisticbiomes2-paper/src/main/java/com/untamedears/realisticbiomes/utils/RealisticBiomesGUI.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.apache.commons.lang3.StringUtils; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -47,8 +49,7 @@ public void showRBOverview(Biome biome) { currentBiome = biome; } if (inventory == null) { - String biomeText = (currentBiome.toString().toLowerCase()).replace("_", " "); - biomeText = StringUtils.capitalize(biomeText); + String biomeText = PlainTextComponentSerializer.plainText().serialize(Component.translatable(currentBiome)); biomeText = StringUtils.abbreviate(biomeText, 30); inventory = new ComponableInventory(ChatColor.DARK_GRAY + biomeText, 6, player); } else { diff --git a/plugins/simpleadminhacks-paper/build.gradle.kts b/plugins/simpleadminhacks-paper/build.gradle.kts index dc4276170d..8db4b5e04d 100644 --- a/plugins/simpleadminhacks-paper/build.gradle.kts +++ b/plugins/simpleadminhacks-paper/build.gradle.kts @@ -16,7 +16,11 @@ dependencies { compileOnly(project(":plugins:banstick-paper")) compileOnly(project(":plugins:bastion-paper")) compileOnly(project(":plugins:exilepearl-paper")) - compileOnly("me.clip:placeholderapi:2.11.6") + compileOnly(project(":plugins:factorymod-paper")) + compileOnly(libs.placeholderapi) + compileOnly(libs.packetevents.spigot) compileOnly(libs.protocollib) + + compileOnly(files("../../ansible/src/paper-plugins/BreweryX-3.6.3.jar")) } diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java index f0c661e706..8e06c46a9d 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java @@ -256,7 +256,7 @@ public void acceptOTT( } if (Bukkit.getPluginManager().isPluginEnabled("Bastion")) { - for (final BastionBlock bastion : Bastion.getBastionManager().getBlockingBastions(sender.getLocation())) { + for (final BastionBlock bastion : Bastion.getBastionManager().getBlockingBastions(sender.getLocation(), b -> b.getType().isBlockLiquids())) { if (!bastion.canPlace(sender) || !bastion.canPlace(requestingPlayer)) { sender.sendMessage(Component.text(requestingPlayer.getName() + " could not one-time teleport to a hostile bastion!", NamedTextColor.RED)); requestingPlayer.sendMessage(Component.text(sender.getName() + " accepted your request, but they're in a hostile bastion!", NamedTextColor.RED)); diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/ReinforcedChestBreak.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/ReinforcedChestBreak.java index 2906518bb8..399320e77b 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/ReinforcedChestBreak.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/ReinforcedChestBreak.java @@ -10,6 +10,7 @@ import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -99,6 +100,7 @@ public void onBlockBreak(BlockBreakEvent eve) { || Material.BLAST_FURNACE.equals(bbe) || Material.DISPENSER.equals(bbe) || Material.DROPPER.equals(bbe) || Material.HOPPER.equals(bbe) || Material.BARREL.equals(bbe) || Material.SMOKER.equals(bbe) + || Tag.COPPER_CHESTS.isTagged(bbe) || Material.BLACK_SHULKER_BOX.equals(bbe) || Material.BLUE_SHULKER_BOX.equals(bbe) || Material.BROWN_SHULKER_BOX.equals(bbe) diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AntiDerailment.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AntiDerailment.java index 843fb38eab..019e5af1ca 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AntiDerailment.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AntiDerailment.java @@ -4,7 +4,10 @@ import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; -import net.minecraft.world.entity.vehicle.AbstractMinecart; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart; import org.bukkit.NamespacedKey; import org.bukkit.Tag; import org.bukkit.block.Block; @@ -18,10 +21,6 @@ import org.bukkit.persistence.PersistentDataType; import org.bukkit.util.Vector; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - /** * Prevents minecarts from derailing by forcibly slowing them down to 8m/s when they would otherwise derail */ diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java index 62313a2744..9461315af0 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/AttrHider.java @@ -1,24 +1,25 @@ package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.wrappers.PlayerInfoData; -import com.comphenix.protocol.wrappers.WrappedDataValue; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import com.comphenix.protocol.wrappers.WrappedWatchableObject; +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.event.PacketListener; +import com.github.retrooper.packetevents.event.PacketListenerCommon; +import com.github.retrooper.packetevents.event.PacketListenerPriority; +import com.github.retrooper.packetevents.event.PacketSendEvent; +import com.github.retrooper.packetevents.protocol.entity.data.EntityData; +import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; +import com.github.retrooper.packetevents.protocol.packettype.PacketType; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEffect; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate.Action; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate.PlayerInfo; import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; import com.programmerdan.minecraft.simpleadminhacks.framework.autoload.AutoLoad; -import com.programmerdan.minecraft.simpleadminhacks.framework.utilities.PacketManager; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -30,8 +31,7 @@ public final class AttrHider extends BasicHack { public static final String BYPASS_PERMISSION = "attrhider.bypass"; - private final PacketManager packets = new PacketManager(); - private Set customPackets = new HashSet<>(); + private final List listeners = new ArrayList<>(); @AutoLoad private boolean hideEffects; @@ -50,130 +50,140 @@ public AttrHider(final SimpleAdminHacks plugin, final BasicHackConfig config) { public void onEnable() { super.onEnable(); if (this.hideEffects) { - this.packets.addAdapter(new PacketAdapter(this.plugin, PacketType.Play.Server.ENTITY_EFFECT) { - @Override - public void onPacketSending(final PacketEvent event) { - final PacketContainer packet = event.getPacket(); - final Player player = event.getPlayer(); - if (player.hasPermission(BYPASS_PERMISSION)) { - return; - } - final PacketContainer cloned = packet.deepClone(); - final StructureModifier ints = cloned.getIntegers(); - if (player.getEntityId() == ints.read(0)) { - return; - } - // set amplifier to 0 - cloned.getBytes().write(1, (byte) 0); - // set duration to 0 - ints.write(1, 0); - // The packet data is shared between events, but the event - // instance is exclusive to THIS sending of the packet - event.setPacket(cloned); - } - }); + registerListener(new EffectHiderListener()); } if (this.hideHealth) { - this.packets.addAdapter(new PacketAdapter(this.plugin, PacketType.Play.Server.ENTITY_METADATA) { - @Override - public void onPacketSending(final PacketEvent event) { - final PacketContainer packet = event.getPacket(); - final Player player = event.getPlayer(); - if (player.hasPermission(BYPASS_PERMISSION)) { - return; - } - final Entity entity = packet.getEntityModifier(event).read(0); - if (!(entity instanceof LivingEntity) - || player.getEntityId() == entity.getEntityId() - || entity.getPassengers().contains(player) - || customPackets.remove(packet.getHandle())) { - return; - } - final PacketContainer cloned = packet.deepClone(); - for (final WrappedDataValue object : cloned.getDataValueCollectionModifier().read(0)) { - // Read the 8th field as a float as that's the living entity's health - // https://wiki.vg/Entity_metadata#Living_Entity - if (object.getIndex() == 9) { - if ((float) object.getValue() > 0) { - object.setValue(1f); // Half a heart - } - } - } - // The packet data is shared between events, but the event - // instance is exclusive to THIS sending of the packet - event.setPacket(cloned); - } - }); + registerListener(new HealthHiderListener()); } if (this.roundPlayerListPing) { - this.packets.addAdapter(new PacketAdapter(this.plugin, PacketType.Play.Server.PLAYER_INFO) { - @Override - public void onPacketSending(final PacketEvent event) { - final PacketContainer packet = event.getPacket(); - final Player player = event.getPlayer(); - if (player.hasPermission(BYPASS_PERMISSION)) { - return; - } - final PacketContainer cloned = packet.deepClone(); - List newInfos = new ArrayList<>(); - List oldInfos = cloned.getPlayerInfoDataLists().read(1); - for (PlayerInfoData oldInfo : oldInfos) { - if (oldInfo == null) continue; - int latency = oldInfo.getLatency(); - // Limit player ping in the tablist to the same 6 values vanilla clients can discern visually - // this follows 1.16.5 PlayerTabOverlay#renderPingIcon() - if (latency < 0) latency = -1; - else if (latency < 150) latency = 75; // average of 0 and 150, arbitrary - else if (latency < 300) latency = 225; - else if (latency < 600) latency = 450; - else if (latency < 1000) latency = 800; - else latency = 1000; - newInfos.add(new PlayerInfoData( - oldInfo.getProfileId(), - latency, - oldInfo.isListed(), - oldInfo.getGameMode(), - oldInfo.getProfile(), - oldInfo.getDisplayName(), - oldInfo.getRemoteChatSessionData() - )); - } - cloned.getPlayerInfoDataLists().write(1, newInfos); - // The packet data is shared between events, but the event - // instance is exclusive to THIS sending of the packet - event.setPacket(cloned); - } - }); + registerListener(new PingRounderListener()); } } @Override public void onDisable() { - this.packets.removeAllAdapters(); + for (final PacketListenerCommon listener : this.listeners) { + PacketEvents.getAPI().getEventManager().unregisterListener(listener); + } + this.listeners.clear(); super.onDisable(); } + private void registerListener(final PacketListener listener) { + final PacketListenerCommon registered = PacketEvents.getAPI().getEventManager() + .registerListener(listener, PacketListenerPriority.NORMAL); + this.listeners.add(registered); + } + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void onMountEntity(EntityMountEvent event) { - if (this.hideHealth && event.getEntity() instanceof Player player && event.getMount() instanceof LivingEntity mountedEntity) { - WrappedDataWatcher watcher = new WrappedDataWatcher(); - List wrappedDataValueList = new ArrayList<>(); + public void onMountEntity(final EntityMountEvent event) { + if (this.hideHealth + && event.getEntity() instanceof Player player + && event.getMount() instanceof LivingEntity mountedEntity) { + final List> metadata = new ArrayList<>(); + metadata.add(new EntityData<>(9, EntityDataTypes.FLOAT, (float) mountedEntity.getHealth())); + final WrapperPlayServerEntityMetadata packet = new WrapperPlayServerEntityMetadata( + mountedEntity.getEntityId(), metadata); + // Send silently so our own health-hiding listener does not intercept this packet. + // EntityMountEvent fires *before* the player is actually a passenger, + // so the listener would otherwise hide the real health. + PacketEvents.getAPI().getPlayerManager().sendPacketSilently(player, packet); + } + } + + private static final class EffectHiderListener implements PacketListener { - watcher.setEntity(mountedEntity); - watcher.setObject(9, WrappedDataWatcher.Registry.get(Float.class), (float) mountedEntity.getHealth()); - for (WrappedWatchableObject entry : watcher.getWatchableObjects()) { - if (entry == null) continue; + @Override + public void onPacketSend(final PacketSendEvent event) { + if (event.getPacketType() != PacketType.Play.Server.ENTITY_EFFECT) { + return; + } + final Player player = event.getPlayer(); + if (player == null || player.hasPermission(BYPASS_PERMISSION)) { + return; + } + final WrapperPlayServerEntityEffect packet = new WrapperPlayServerEntityEffect(event); + if (player.getEntityId() == packet.getEntityId()) { + return; + } + // Set amplifier to 0 + packet.setEffectAmplifier(0); + // Set duration to 0 + packet.setEffectDurationTicks(0); + event.markForReEncode(true); + } + } - WrappedDataWatcher.WrappedDataWatcherObject watcherObject = entry.getWatcherObject(); + private static final class HealthHiderListener implements PacketListener { - wrappedDataValueList.add(new WrappedDataValue(watcherObject.getIndex(), watcherObject.getSerializer(), entry.getRawValue())); + @Override + public void onPacketSend(final PacketSendEvent event) { + if (event.getPacketType() != PacketType.Play.Server.ENTITY_METADATA) { + return; + } + final Player player = event.getPlayer(); + if (player == null || player.hasPermission(BYPASS_PERMISSION)) { + return; + } + final WrapperPlayServerEntityMetadata packet = new WrapperPlayServerEntityMetadata(event); + final int entityId = packet.getEntityId(); + if (player.getEntityId() == entityId) { + return; + } + final Entity entity = SpigotConversionUtil.getEntityById(player.getWorld(), entityId); + if (!(entity instanceof LivingEntity) || entity.getPassengers().contains(player)) { + return; + } + for (final EntityData data : packet.getEntityMetadata()) { + // Index 9 is the LivingEntity health field + // https://wiki.vg/Entity_metadata#Living_Entity + if (data.getIndex() == 9 && data.getType() == EntityDataTypes.FLOAT) { + if ((float) data.getValue() > 0) { + @SuppressWarnings("unchecked") + final EntityData healthData = (EntityData) data; + healthData.setValue(1f); // Half a heart + } + } } + event.markForReEncode(true); + } + } - PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); - packet.getIntegers().write(0, mountedEntity.getEntityId()); - packet.getDataValueCollectionModifier().write(0, wrappedDataValueList); - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); - customPackets.add(packet.getHandle()); // Allow ignoring this packet when hiding health because EntityMountEvent fires *before* the player is actually a passenger + private static final class PingRounderListener implements PacketListener { + + @Override + public void onPacketSend(final PacketSendEvent event) { + if (event.getPacketType() != PacketType.Play.Server.PLAYER_INFO_UPDATE) { + return; + } + final Player player = event.getPlayer(); + if (player == null || player.hasPermission(BYPASS_PERMISSION)) { + return; + } + final WrapperPlayServerPlayerInfoUpdate packet = new WrapperPlayServerPlayerInfoUpdate(event); + if (!packet.getActions().contains(Action.UPDATE_LATENCY)) { + return; + } + for (final PlayerInfo entry : packet.getEntries()) { + int latency = entry.getLatency(); + // Limit player ping in the tablist to the same 6 values vanilla clients can discern visually + // this follows 1.16.5 PlayerTabOverlay#renderPingIcon() + if (latency < 0) { + latency = -1; + } else if (latency < 150) { + latency = 75; // average of 0 and 150, arbitrary + } else if (latency < 300) { + latency = 225; + } else if (latency < 600) { + latency = 450; + } else if (latency < 1000) { + latency = 800; + } else { + latency = 1000; + } + entry.setLatency(latency); + } + event.markForReEncode(true); } } } diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/BeeKeeping.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/BeeKeeping.java index a6b16d04fb..31d4d756eb 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/BeeKeeping.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/BeeKeeping.java @@ -12,7 +12,7 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.animal.Bee; +import net.minecraft.world.entity.animal.bee.Bee; import net.minecraft.world.level.block.entity.BeehiveBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import org.apache.commons.collections4.IterableUtils; @@ -107,14 +107,14 @@ public void attackedByBee(final EntityDamageByEntityEvent event) { final var lastDamageCause = bee.getLastHurtByMob(); final var angerTarget = bee.getPersistentAngerTarget(); final var goalTarget = bee.getTarget(); - final var angerLevel = bee.getRemainingPersistentAngerTime(); + final var angerLevel = bee.getPersistentAngerEndTime(); Bukkit.getScheduler().runTask(this.plugin, () -> { bee.setHasStung(false); // Reset the above values bee.setLastHurtByMob(lastDamageCause); bee.setPersistentAngerTarget(angerTarget); bee.setTarget(goalTarget, EntityTargetEvent.TargetReason.FORGOT_TARGET); // Params: target, cause, emit event - bee.setRemainingPersistentAngerTime(angerLevel); + bee.setPersistentAngerEndTime(angerLevel); }); } @@ -198,7 +198,7 @@ private static BeehiveBlockEntity getBeeHive(@NotNull final Block block) { private static List getBeesFromHive(@NotNull final BeehiveBlockEntity hive) { List bees = hive.components().get(DataComponents.BEES).bees(); - return bees == null ? null : bees.stream().map(bee -> bee.entityData().copyTag()).map(BeeData::new).collect(Collectors.toCollection(ArrayList::new)); + return bees.stream().map(bee -> bee.entityData().copyTagWithoutId()).map(BeeData::new).collect(Collectors.toCollection(ArrayList::new)); } private static final class BeeData { diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/BrewIndex.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/BrewIndex.java new file mode 100644 index 0000000000..bc240af0a7 --- /dev/null +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/BrewIndex.java @@ -0,0 +1,215 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; + +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.Description; +import com.dre.brewery.Brew; +import com.dre.brewery.api.events.brew.BrewDrinkEvent; +import com.dre.brewery.recipe.BRecipe; +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import vg.civcraft.mc.civmodcore.commands.CommandManager; +import vg.civcraft.mc.civmodcore.inventory.gui.DecorationStack; +import vg.civcraft.mc.civmodcore.inventory.gui.IClickable; +import vg.civcraft.mc.civmodcore.inventory.gui.MultiPageView; +import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; + +public final class BrewIndex extends BasicHack { + + private static final String PDC_SEPARATOR = ";"; + + private final NamespacedKey drunkBrewsKey; + private final CommandManager commands; + private boolean breweryEnabled; + + public BrewIndex(final SimpleAdminHacks plugin, final BasicHackConfig config) { + super(plugin, config); + this.drunkBrewsKey = new NamespacedKey(plugin, "drunk_brews"); + this.commands = new CommandManager(plugin()) { + @Override + public void registerCommands() { + registerCommand(new BrewIndexCommand()); + } + }; + } + + @Override + public void onEnable() { + super.onEnable(); + this.breweryEnabled = Bukkit.getPluginManager().isPluginEnabled("BreweryX"); + if (!this.breweryEnabled) { + plugin().warning("BrewIndex: BreweryX not found, /brews command will be unavailable"); + } + this.commands.init(); + } + + @Override + public void onDisable() { + this.commands.reset(); + super.onDisable(); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBrewDrink(final BrewDrinkEvent event) { + final Brew brew = event.getBrew(); + final BRecipe recipe = brew.getCurrentRecipe(); + if (recipe == null) { + return; + } + final String recipeName = recipe.getRecipeName(); + if (recipeName == null || recipeName.isEmpty()) { + return; + } + recordDrunkBrew(event.getPlayer(), recipeName, event.getQuality()); + } + + /** + * Reads the player's PDC to get a map of recipe name -> best quality drunk. + * Format stored in PDC: "name:quality;name:quality;..." + */ + private Map getDrunkBrews(final Player player) { + final PersistentDataContainer pdc = player.getPersistentDataContainer(); + final String raw = pdc.get(this.drunkBrewsKey, PersistentDataType.STRING); + final Map brews = new HashMap<>(); + if (raw != null && !raw.isEmpty()) { + for (final String entry : raw.split(PDC_SEPARATOR, -1)) { + if (entry.isEmpty()) { + continue; + } + final int colonIndex = entry.lastIndexOf(':'); + final String name = entry.substring(0, colonIndex); + try { + final int quality = Integer.parseInt(entry.substring(colonIndex + 1)); + brews.put(name, quality); + } catch (final NumberFormatException ignored) { + brews.put(entry, 0); + } + } + } + return brews; + } + + private void saveDrunkBrews(final Player player, final Map brews) { + final PersistentDataContainer pdc = player.getPersistentDataContainer(); + final StringBuilder builder = new StringBuilder(); + boolean first = true; + for (final Map.Entry entry : brews.entrySet()) { + if (!first) { + builder.append(PDC_SEPARATOR); + } + builder.append(entry.getKey()).append(':').append(entry.getValue()); + first = false; + } + pdc.set(this.drunkBrewsKey, PersistentDataType.STRING, builder.toString()); + } + + private void recordDrunkBrew(final Player player, final String recipeName, final int quality) { + final Map brews = getDrunkBrews(player); + final Integer existing = brews.get(recipeName); + if (existing == null || quality > existing) { + brews.put(recipeName, quality); + saveDrunkBrews(player, brews); + } + } + + private void openBrewGui(final Player player) { + if (!this.breweryEnabled) { + player.sendMessage(Component.text("BreweryX is not installed on this server.") + .color(NamedTextColor.RED)); + return; + } + + final List allRecipes = BRecipe.getAllRecipes(); + if (allRecipes == null || allRecipes.isEmpty()) { + player.sendMessage(Component.text("No brews are configured on this server.") + .color(NamedTextColor.RED)); + return; + } + + final Map drunkBrews = getDrunkBrews(player); + final List sortedRecipes = new ArrayList<>(allRecipes); + sortedRecipes.sort(Comparator + .comparing((BRecipe recipe) -> !drunkBrews.containsKey(recipe.getRecipeName())) + .thenComparing(BRecipe::getRecipeName, String.CASE_INSENSITIVE_ORDER)); + + final int totalBrews = sortedRecipes.size(); + final int discoveredBrews = (int) sortedRecipes.stream() + .filter(recipe -> drunkBrews.containsKey(recipe.getRecipeName())) + .count(); + + final List clickables = new ArrayList<>(); + for (final BRecipe recipe : sortedRecipes) { + final String recipeName = recipe.getRecipeName(); + final Integer bestQuality = drunkBrews.get(recipeName); + final boolean hasDrunk = bestQuality != null; + + ItemStack displayItem; + try { + final Brew brew = recipe.createBrew(10); + displayItem = brew.createItem(recipe); + brew.seal(displayItem, null); + } catch (final Exception exception) { + displayItem = new ItemStack(Material.POTION); + } + + ItemUtils.setComponentDisplayName(displayItem, Component.text(recipeName) + .color(hasDrunk ? NamedTextColor.GREEN : NamedTextColor.GRAY) + .decoration(TextDecoration.ITALIC, false)); + + final List lore = new ArrayList<>(); + final ItemMeta meta = displayItem.getItemMeta(); + if (hasDrunk) { + lore.add(Component.text("✔ Discovered") + .color(NamedTextColor.GREEN) + .decoration(TextDecoration.ITALIC, false)); + final int clamped = Math.clamp(bestQuality, 0, 10); + final int filledStars = clamped / 2; + final int unfilledStars = clamped % 2; + lore.add(Component.text("★".repeat(filledStars) + "☆".repeat(unfilledStars) + " Best quality") + .color(NamedTextColor.GOLD) + .decoration(TextDecoration.ITALIC, false)); + meta.setEnchantmentGlintOverride(true); + } else { + lore.add(Component.text("✘ Not yet discovered") + .color(NamedTextColor.RED) + .decoration(TextDecoration.ITALIC, false)); + } + meta.lore(lore); + displayItem.setItemMeta(meta); + + clickables.add(new DecorationStack(displayItem)); + } + + final String title = "Brew Log (" + discoveredBrews + "/" + totalBrews + " discovered)"; + final MultiPageView view = new MultiPageView(player, clickables, title, true); + view.showScreen(); + } + + public class BrewIndexCommand extends BaseCommand { + + @CommandAlias("brews") + @Description("Opens the brew log showing all brews and which ones you have drunk") + public void onBrews(final Player sender) { + openBrewGui(sender); + } + } +} diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/HumbugBatchOne.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/HumbugBatchOne.java index 983611d521..158213dfeb 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/HumbugBatchOne.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/HumbugBatchOne.java @@ -208,7 +208,7 @@ public void adminAccessBlockedChest(PlayerInteractEvent e) { List blocks = p.getLineOfSight(s, 8); for (Block b : blocks) { Material m = b.getType(); - if (m == Material.CHEST || m == Material.TRAPPED_CHEST) { + if (m == Material.CHEST || m == Material.TRAPPED_CHEST || Tag.COPPER_CHESTS.isTagged(m)) { if (b.getRelative(BlockFace.UP).getType().isOccluding()) { // dont show inventory twice if a normal chest is opened final Inventory chestInv = ((InventoryHolder) b.getState()).getInventory(); @@ -288,22 +288,14 @@ public void onTeleport(PlayerTeleportEvent event) { height = 0.562; } else if (Tag.FLOWER_POTS.isTagged(mat)) { height = 0.375; - } else switch (mat) { - case CHEST: - case TRAPPED_CHEST: - case ENDER_CHEST: - height = 0.875; - break; - case LILY_PAD: - height = 0.016; - break; - case ENCHANTING_TABLE: - height = 0.016; - break; - case PLAYER_WALL_HEAD: - case PLAYER_HEAD: - height = 0.5; - break; + } else if (mat == Material.CHEST || mat == Material.TRAPPED_CHEST || mat == Material.ENDER_CHEST || Tag.COPPER_CHESTS.isTagged(mat)) { + height = 0.875; + } else if (mat == Material.LILY_PAD) { + height = 0.016; + } else if (mat == Material.ENCHANTING_TABLE) { + height = 0.016; + } else if (mat == Material.PLAYER_WALL_HEAD || mat == Material.PLAYER_HEAD) { + height = 0.5; } // Check if the below block is difficult diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MobCulling.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MobCulling.java index 1181de0556..6960430245 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MobCulling.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MobCulling.java @@ -49,7 +49,7 @@ public void onEnable() { turtleCount.put(world, turtles.size()); if (turtleMaxAge >= 0) { for (Turtle turtle : turtles) { - if (turtle.getTicksLived() > turtleMaxAge && turtle.customName() != null) { + if (turtle.getTicksLived() > turtleMaxAge && turtle.customName() == null) { Location location = turtle.getLocation(); plugin.getLogger().info("Despawning turtle with " + turtle.getTicksLived() + " ticks lived at " + location.getX() + " " + location.getY() + " " + location.getZ()); turtle.remove(); @@ -61,7 +61,7 @@ public void onEnable() { striderCount.put(world, striders.size()); if (striderMaxAge >= 0) { for (Strider strider : striders) { - if (strider.getTicksLived() > striderMaxAge && strider.customName() != null && !strider.hasSaddle()) { + if (strider.getTicksLived() > striderMaxAge && strider.customName() == null && !strider.hasSaddle()) { Location location = strider.getLocation(); plugin.getLogger().info("Despawning strider with " + strider.getTicksLived() + " ticks lived at " + location.getX() + " " + location.getY() + " " + location.getZ()); strider.remove(); @@ -75,7 +75,9 @@ public void onEnable() { @Override public void onDisable() { super.onDisable(); - this.task.cancel(); + if (this.task != null) { + this.task.cancel(); + } } @EventHandler diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/NameLocker.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/NameLocker.java new file mode 100644 index 0000000000..6d390a8890 --- /dev/null +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/NameLocker.java @@ -0,0 +1,129 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; + +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; +import java.util.List; +import java.util.Objects; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.world.inventory.AnvilMenu; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.PrepareAnvilEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public class NameLocker extends BasicHack { + + private final NamespacedKey lockedKey = new NamespacedKey(plugin, "name-locked"); + + public NameLocker(SimpleAdminHacks plugin, BasicHackConfig config) { + super(plugin, config); + } + + @Override + public void onEnable() { + super.onEnable(); + if (plugin.getServer().getPluginManager().getPlugin("FactoryMod") != null) { + plugin.getServer() + .getPluginManager() + .registerEvents( + new NameLockerFMListener(lockedKey), plugin); + } + } + + @Override + public void onDisable() { + super.onDisable(); + } + + @EventHandler + public void onPrepareLock(PrepareAnvilEvent event) { + if (event.getInventory().getSecondItem() == null || !event.getInventory().getSecondItem().getType().equals(Material.HONEYCOMB)) + return; + + ItemStack itemToBeLocked = event.getInventory().getFirstItem(); + + if (itemToBeLocked == null) return; + + ItemMeta itemMeta = itemToBeLocked.getItemMeta(); + PersistentDataContainer pdc = itemMeta.getPersistentDataContainer(); + + if (pdc.has(lockedKey) && Boolean.TRUE.equals(pdc.get(lockedKey, PersistentDataType.BOOLEAN))) { // Item is locked + event.getView().setRepairCost(AnvilMenu.DEFAULT_DENIED_COST); // Cheap trick to get the X because it's nice. + event.setResult(ItemStack.empty()); + } else if (!pdc.has(lockedKey)) { + // We can't put honeycomb on anything so we have to manually do the result setup. + ItemStack result = event.getInventory().getFirstItem().clone(); + result.editMeta(meta -> { + meta.setDisplayName(event.getView().getRenameText()); + meta.getPersistentDataContainer().set(lockedKey, PersistentDataType.BOOLEAN, true); + TextComponent loreToAdd = Component.text().content("Name-locked").build(); + if (meta.hasLore()) { + List lore = meta.lore(); + lore.add(loreToAdd); // Just to make it clear. If we can change the message in the anvil this should be removed. + meta.lore(lore); + } else { + meta.lore(List.of(loreToAdd)); + } + }); + event.getView().setRepairCost(1); // We need to do this so the client will let the user withdraw the item + event.setResult(result); + } + } + + @EventHandler + public void onExecuteLock(InventoryClickEvent event) { + if (event.getInventory().getType() != InventoryType.ANVIL || event.getRawSlot() != 2) return; + ItemStack honeyComb = event.getInventory().getItem(1); + if (honeyComb == null || !honeyComb.getType().equals(Material.HONEYCOMB)) + return; + + if (honeyComb.getAmount() > 1) { + honeyComb.setAmount(honeyComb.getAmount() - 1); + ((Player) event.getWhoClicked()).give(honeyComb); // Items in the second slot of an anvil are deleted AFTER InventoryClickEvent so we can't decrement the stack size + } + } + + @EventHandler + public void onTryRename(PrepareAnvilEvent event) { + ItemStack itemToBeRenamed = event.getInventory().getFirstItem(); + ItemStack resultItem = event.getInventory().getResult(); + if (itemToBeRenamed == null + || resultItem == null) + return; + + ItemMeta itemMeta = itemToBeRenamed.getItemMeta(); + PersistentDataContainer pdc = itemMeta.getPersistentDataContainer(); + checkItem(event, itemToBeRenamed, resultItem, pdc); + + // Now check the other way. This only applies for tools where you can combine them + itemToBeRenamed = event.getInventory().getSecondItem(); + if (itemToBeRenamed == null) + return; + + itemMeta = itemToBeRenamed.getItemMeta(); + pdc = itemMeta.getPersistentDataContainer(); + checkItem(event, itemToBeRenamed, resultItem, pdc); + } + + private void checkItem(PrepareAnvilEvent event, ItemStack itemToBeRenamed, ItemStack resultItem, PersistentDataContainer pdc) { + if (pdc.has(lockedKey) && Boolean.TRUE.equals(pdc.get(lockedKey, PersistentDataType.BOOLEAN))) { // Item is locked + if (Objects.equals(itemToBeRenamed.effectiveName().compact(), resultItem.effectiveName().compact())) + return; // No name change, no enchant change (text colour white->aqua) + if (Objects.equals(itemToBeRenamed.effectiveName().compact().color(NamedTextColor.AQUA).compact(), resultItem.effectiveName().compact())) + return; // No name change, but we are adding an enchantment so the text colour changes + event.getView().setRepairCost(AnvilMenu.DEFAULT_DENIED_COST); + event.setResult(ItemStack.empty()); + // Can we change the text? Like "Too Expensive!" - > "Can't Rename!"? + } + } +} diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/NameLockerFMListener.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/NameLockerFMListener.java new file mode 100644 index 0000000000..7226ff8759 --- /dev/null +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/NameLockerFMListener.java @@ -0,0 +1,43 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; + +import com.github.igotyou.FactoryMod.events.FactoryActivateEvent; +import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.NamespacedKey; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public class NameLockerFMListener implements Listener { + + private final NamespacedKey lockedKey; + + public NameLockerFMListener(NamespacedKey lockedKey) { + this.lockedKey = lockedKey; + } + + @EventHandler + public void onTryWordbank(FactoryActivateEvent event) { + if (!(event.getFactory() instanceof FurnCraftChestFactory fac)) return; + if (!fac.getCurrentRecipe().getTypeIdentifier().equals("WORDBANK")) return; + + ItemStack itemToBeRenamed = fac.getInputInventory().getItem(0); + + if (itemToBeRenamed == null) + return; + + ItemMeta itemMeta = itemToBeRenamed.getItemMeta(); + PersistentDataContainer pdc = itemMeta.getPersistentDataContainer(); + + if (pdc.has(lockedKey) && Boolean.TRUE.equals(pdc.get(lockedKey, PersistentDataType.BOOLEAN))) { // Item is locked + event.getActivator().sendMessage(Component.text() + .color(NamedTextColor.RED) + .content("You cannot wordbank name-locked items")); + event.setCancelled(true); + } + } +} diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/ServerLinksHack.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/ServerLinksHack.java new file mode 100644 index 0000000000..f7392a1079 --- /dev/null +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/ServerLinksHack.java @@ -0,0 +1,53 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; + +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; +import com.programmerdan.minecraft.simpleadminhacks.framework.autoload.AutoLoad; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.ServerLinks; + +public final class ServerLinksHack extends BasicHack { + + @AutoLoad + private String discordUrl; + + @AutoLoad + private String patreonUrl; + + private final List links; + + public ServerLinksHack(final SimpleAdminHacks plugin, final BasicHackConfig config) { + super(plugin, config); + this.links = new ArrayList<>(); + } + + @Override + public void onEnable() { + super.onEnable(); + addLink("Discord", this.discordUrl); + addLink("Patreon", this.patreonUrl); + } + + @Override + public void onDisable() { + for (final ServerLinks.ServerLink link : this.links) { + Bukkit.getServer().getServerLinks().removeLink(link); + } + this.links.clear(); + super.onDisable(); + } + + private void addLink(final String name, final String url) { + if (url == null || url.isBlank()) { + this.plugin.warning("ServerLinksHack is missing a URL for " + name + '.'); + return; + } + this.links.add(Bukkit.getServer().getServerLinks().addLink(Component.text(name), URI.create(url))); + } + +} diff --git a/plugins/simpleadminhacks-paper/src/main/resources/config.yml b/plugins/simpleadminhacks-paper/src/main/resources/config.yml index 7b77280365..61e14e998b 100644 --- a/plugins/simpleadminhacks-paper/src/main/resources/config.yml +++ b/plugins/simpleadminhacks-paper/src/main/resources/config.yml @@ -89,6 +89,8 @@ hacks: # its stinger and thus die when successfully attacking an entity. # Default: 1.0 (100%) severStingerChance: 1.0 + BrewIndex: + enabled: true BuffSpanker: enabled: true # The list of PotionEffectType's that you do not wish players to receive. @@ -99,6 +101,10 @@ hacks: - SLOW_FALLING DebugWand: enabled: true + ServerLinksHack: + enabled: false + discordUrl: https://discord.gg/ [...] + patreonUrl: https://www.patreon.com/ [...] DogFacts: enabled: false intervalTime: 30m @@ -138,6 +144,8 @@ hacks: enabled: true MapCopyProtection: enabled: true + NameLocker: + enabled: true OldEnchanting: enabled: true # Hides what enchantment will be granted within the Enchanting Table @@ -249,6 +257,14 @@ hacks: clearOnMatch: true watchedMaterials: - CHEST + - TRAPPED_CHEST + - COPPER_CHEST + - EXPOSED_COPPER_CHEST + - OXIDIZED_COPPER_CHEST + - WEATHERED_COPPER_CHEST + - WAXED_COPPER_CHEST + - WAXED_EXPOSED_COPPER_CHEST + - WAXED_OXIDIZED_COPPER_CHEST - FURNACE - DROPPER - DISPENSER @@ -441,7 +457,7 @@ hacks: enabled: true contents: - ==: org.bukkit.inventory.ItemStack - v: 1 + v: 3839 type: COOKIE amount: 32 meta: @@ -452,7 +468,7 @@ hacks: - "Gift from the Admins as you" - "begin your journey on Devotion." - ==: org.bukkit.inventory.ItemStack - v: 1 + v: 3839 type: RED_BED amount: 1 meta: diff --git a/plugins/simpleadminhacks-paper/src/main/resources/plugin.yml b/plugins/simpleadminhacks-paper/src/main/resources/plugin.yml index b2c7fddb67..34808fd1b6 100644 --- a/plugins/simpleadminhacks-paper/src/main/resources/plugin.yml +++ b/plugins/simpleadminhacks-paper/src/main/resources/plugin.yml @@ -4,7 +4,7 @@ author: ProgrammerDan authors: [ ProgrammerDan, Maxopoly ] version: ${version} depend: [ CivModCore ] -softdepend: [ CombatTagPlus, NameLayer, Citadel, ProtocolLib, BanStick, ExilePearl, PlaceholderAPI ] +softdepend: [ CombatTagPlus, NameLayer, Citadel, ProtocolLib, packetevents, BanStick, ExilePearl, PlaceholderAPI, FactoryMod, BreweryX ] api-version: 1.21.3 commands: hacks: