mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-11-22 02:25:51 +01:00
Switch to paperweight
This commit is contained in:
parent
22be9f2d6f
commit
34106bb1fe
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
@ -6,9 +6,9 @@ on:
|
||||
- '*.md'
|
||||
- 'Jenkinsfile'
|
||||
branches:
|
||||
- ver/1.16.5
|
||||
- ver/1.17
|
||||
- dev/*
|
||||
- staging/1.16.5
|
||||
- staging/1.17
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
@ -27,7 +27,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [ '8', '11', '15', '16' ]
|
||||
java: [ '16' ]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@ -44,30 +44,21 @@ jobs:
|
||||
path: ~/.gradle
|
||||
key: ${{ runner.os }}-mavenCache-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}-openjdk-${{ matrix.java }}
|
||||
|
||||
- name: Setup Yatopia Project
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.email "ci@github.com"
|
||||
git config --global user.name "Github CI"
|
||||
git config --global gc.auto 0
|
||||
sudo chmod -R -f 777 ./gradlew
|
||||
./gradlew initGitSubmodules
|
||||
|
||||
- name: Apply Patches
|
||||
run: |
|
||||
./gradlew applyPatches
|
||||
|
||||
- name: Get MC Version
|
||||
run: echo "::set-output name=mcver::$(cat "Paper/work/BuildData/info.json" | grep minecraftVersion | cut -d '"' -f 4)"
|
||||
id: mcver
|
||||
|
||||
- name: Pull Minecraft Decompile Cache
|
||||
uses: actions/cache@v2
|
||||
id: decompile-cache
|
||||
with:
|
||||
path: Paper/work/Minecraft/${{ steps.mcver.outputs.mcver }}
|
||||
key: ${{ hashFiles('Paper/work/BuildData/mappings/bukkit-$STEPS_MCVER_OUTPUTS_MCVER-cl.csrg') }}-${{ steps.mcver.outputs.mcver }}-${{ runner.os }}-openjdk-${{ matrix.java }}-minecraft-decomp
|
||||
|
||||
- name: Apply Patches
|
||||
run: |
|
||||
./gradlew setupUpstream
|
||||
./gradlew applyPatches
|
||||
|
||||
- name: Pull Maven Cache
|
||||
uses: actions/cache@v2
|
||||
id: maven-cache
|
||||
@ -77,7 +68,7 @@ jobs:
|
||||
|
||||
- name: Build Yatopia
|
||||
run: |
|
||||
./gradlew clean build paperclip
|
||||
./gradlew generatePaperclipPatch --no-build-cache
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
|
39
.gitmodules
vendored
39
.gitmodules
vendored
@ -1,39 +0,0 @@
|
||||
[submodule "Paper"]
|
||||
path = Paper
|
||||
url = https://github.com/PaperMC/Paper.git
|
||||
|
||||
[submodule "upstream/Tuinity"]
|
||||
path = upstream/Tuinity
|
||||
url = https://github.com/Spottedleaf/Tuinity
|
||||
branch = master
|
||||
|
||||
[submodule "upstream/Purpur"]
|
||||
path = upstream/Purpur
|
||||
url = https://github.com/pl3xgaming/Purpur.git
|
||||
branch = ver/1.16.5
|
||||
|
||||
[submodule "upstream/Airplane"]
|
||||
path = upstream/Airplane
|
||||
url = https://github.com/Technove/Airplane.git
|
||||
branch = master
|
||||
|
||||
[submodule "upstream/Akarin"]
|
||||
path = upstream/Akarin
|
||||
url = https://github.com/Akarin-project/Akarin.git
|
||||
branch = ver/1.16.5
|
||||
|
||||
[submodule "upstream/Empirecraft"]
|
||||
path = upstream/Empirecraft
|
||||
url = https://github.com/starlis/empirecraft.git
|
||||
branch = master
|
||||
|
||||
[submodule "upstream/Origami"]
|
||||
path = upstream/Origami
|
||||
url = https://github.com/Minebench/Origami.git
|
||||
branch = 1.16
|
||||
|
||||
[submodule "Yatopia-API"]
|
||||
path = Yatopia-API
|
||||
|
||||
[submodule "Yatopia-Server"]
|
||||
path = Yatopia-Server
|
473
PATCHES.md
473
PATCHES.md
@ -1,473 +0,0 @@
|
||||
# Patches
|
||||
|
||||
<!---
|
||||
This file is autogenerated! Modify the .template.md to make changes!
|
||||
--->
|
||||
|
||||
This is an overview of all the patches that are currently used.
|
||||
|
||||
| Side | Patch | Author | CoAuthors |
|
||||
| ----- | ------------- |:-------------:| -----:|
|
||||
| api | AFK API | William Blake Galbreath | |
|
||||
| server | AFK API | William Blake Galbreath | |
|
||||
| api | API for any mob to burn daylight | Ben Kerllenevich | |
|
||||
| server | API for any mob to burn daylight | Ben Kerllenevich | |
|
||||
| server | Ability to re-add farmland mechanics from Alpha | Yive | |
|
||||
| server | Actually unload POI data | Spottedleaf | |
|
||||
| server | Add /ping command | William Blake Galbreath | |
|
||||
| server | Add 5 second tps average in /tps | William Blake Galbreath | |
|
||||
| api | Add EntityTeleportHinderedEvent | Mariell Hoversholm | |
|
||||
| server | Add EntityTeleportHinderedEvent | Mariell Hoversholm | |
|
||||
| api | Add GameProfileLookupEvent | tr7zw | |
|
||||
| server | Add GameProfileLookupEvent | tr7zw | |
|
||||
| server | Add IntelliJ IDEA runnable | Zoe | |
|
||||
| server | Add MC-4 fix back | BillyGalbreath | |
|
||||
| api | Add NBT API as a first-class lib | tr7zw | |
|
||||
| server | Add NBT API as a first-class lib | tr7zw | |
|
||||
| api | Add StructureGenerateEvent | Nahuel | Mariell Hoversholm |
|
||||
| server | Add StructureGenerateEvent | Nahuel | Mariell Hoversholm |
|
||||
| server | Add Velocity natives for encryption and compression | Andrew Steinborn | |
|
||||
| server | Add adjustable breeding cooldown to config | montlikadani | |
|
||||
| server | Add allow water in end world option | William Blake Galbreath | |
|
||||
| server | Add boat fall damage config | BillyGalbreath | |
|
||||
| server | Add canSaveToDisk to Entity | William Blake Galbreath | |
|
||||
| server | Add config change multiplier critical damage value | DoctaEnkoda | |
|
||||
| server | Add config for allowing Endermen to despawn even while | jmp | |
|
||||
| server | Add config for snow on blue ice | BillyGalbreath | |
|
||||
| server | Add config for villager trading | Ben Kerllenevich | |
|
||||
| server | Add configurable snowball damage | BillyGalbreath | |
|
||||
| server | Add credits command | Encode42 | |
|
||||
| api | Add critical hit check to EntityDamagedByEntityEvent | BillyGalbreath | |
|
||||
| server | Add critical hit check to EntityDamagedByEntityEvent | BillyGalbreath | |
|
||||
| server | Add demo command | BillyGalbreath | |
|
||||
| api | Add enchantment target for bows and crossbows | BillyGalbreath | |
|
||||
| server | Add enderman and creeper griefing controls | William Blake Galbreath | |
|
||||
| server | Add ghast allow-griefing option | BillyGalbreath | |
|
||||
| api | Add last tick time API | Ivan Pekov | tr7zw |
|
||||
| server | Add last tick time API | Ivan Pekov | tr7zw |
|
||||
| server | Add mobGriefing bypass to everything affected | Encode42 | |
|
||||
| server | Add no-random-tick block list | William Blake Galbreath | |
|
||||
| server | Add nspt command | Ivan Pekov | |
|
||||
| server | Add obfhelpers for plugin use | William Blake Galbreath | |
|
||||
| server | Add option for boats to eject players on land | William Blake Galbreath | |
|
||||
| server | Add option to allow loyalty on tridents to work in the void | William Blake Galbreath | |
|
||||
| server | Add option to disable dolphin treasure searching | William Blake Galbreath | |
|
||||
| server | Add option to disable mushroom and note block updates | William Blake Galbreath | |
|
||||
| server | Add option to disable observer clocks | Phoenix616 | |
|
||||
| api | Add option to disable zombie aggressiveness towards villagers | nitricspace | |
|
||||
| server | Add option to disable zombie aggressiveness towards villagers | nitricspace | |
|
||||
| server | Add option to set armorstand step height | William Blake Galbreath | |
|
||||
| server | Add option to teleport to spawn if outside world border | William Blake Galbreath | |
|
||||
| server | Add packet limiter config | Spottedleaf | |
|
||||
| server | Add permission for F3+N debug | William Blake Galbreath | |
|
||||
| server | Add phantom spawning options | William Blake Galbreath | |
|
||||
| server | Add player death exp control options | William Blake Galbreath | |
|
||||
| api | Add predicate to recipe's ExactChoice ingredient | William Blake Galbreath | |
|
||||
| server | Add predicate to recipe's ExactChoice ingredient | William Blake Galbreath | |
|
||||
| server | Add soft async catcher | Spottedleaf | |
|
||||
| server | Add tablist suffix option for afk | montlikadani | |
|
||||
| server | Add timings for Behavior | Phoenix616 | |
|
||||
| server | Add timings for Pathfinder | MrIvanPlays | |
|
||||
| server | Add twisting and weeping vines growth rates | BillyGalbreath | |
|
||||
| api | Add unsafe Entity serialization API | Mariell Hoversholm | |
|
||||
| server | Add unsafe Entity serialization API | Mariell Hoversholm | |
|
||||
| server | Add vindicator johnny spawn chance | William Blake Galbreath | |
|
||||
| server | Add wither skeleton takes wither damage option | William Blake Galbreath | |
|
||||
| api | Advancement API | William Blake Galbreath | |
|
||||
| server | Advancement API | William Blake Galbreath | |
|
||||
| server | Airplane Branding Changes | Paul Sauve | |
|
||||
| server | Airplane Configuration | Paul Sauve | |
|
||||
| server | Airplane MC Dev Fixes | Paul Sauve | |
|
||||
| server | Airplane Profiler | Paul Sauve | |
|
||||
| server | Allow Entities to be removed from a world while ticking | Spottedleaf | |
|
||||
| server | Allow anvil colors | William Blake Galbreath | |
|
||||
| server | Allow color codes in books | William Blake Galbreath | |
|
||||
| server | Allow controlled flushing for network manager | Spottedleaf | |
|
||||
| server | Allow infinite and mending enchantments together | William Blake Galbreath | |
|
||||
| server | Allow infinity on crossbows | Ben Kerllenevich | |
|
||||
| api | Allow inventory resizing | William Blake Galbreath | |
|
||||
| server | Allow leashing villagers | William Blake Galbreath | |
|
||||
| server | Allow soil to moisten from water directly under it | William Blake Galbreath | |
|
||||
| server | Allow toggling special MobSpawners per world | jmp | |
|
||||
| server | Allows change broadcast message by player | DoctaEnkoda | |
|
||||
| server | Allows you to change the thrust limit of a piston by World | DoctaEnkoda | |
|
||||
| api | Alphabetize in-game /plugins list | BillyGalbreath | |
|
||||
| server | Alternative Keepalive Handling | William Blake Galbreath | |
|
||||
| api | Anvil API | William Blake Galbreath | |
|
||||
| server | Anvil API | William Blake Galbreath | |
|
||||
| server | Apply display names from item forms of entities to entities | jmp | |
|
||||
| server | Arrows should not reset despawn counter | William Blake Galbreath | |
|
||||
| server | Attempt to recalculate regionfile header if it is corrupt | Spottedleaf | |
|
||||
| server | Avoid double I/O operation on load player file | ㄗㄠˋ ㄑㄧˊ | |
|
||||
| server | Barrels and enderchests 6 rows | William Blake Galbreath | |
|
||||
| server | Be aware of entity teleports when chunk checking entities | Spottedleaf | |
|
||||
| server | Bee can work when raining or at night | DoctaEnkoda | |
|
||||
| server | Better checking for useless move packets | Paul Sauve | |
|
||||
| server | Brand changes | Spottedleaf | |
|
||||
| server | Brandings | YatopiaMC | |
|
||||
| server | Break individual slabs when sneaking | BillyGalbreath | |
|
||||
| server | Breedable Polar Bears | William Blake Galbreath | |
|
||||
| server | Breedable parrots | BillyGalbreath | |
|
||||
| api | Bring back server name | William Blake Galbreath | |
|
||||
| server | Bring back server name | William Blake Galbreath | |
|
||||
| server | Cache climbing check for activation | Paul Sauve | |
|
||||
| server | Cache coordinate key for micro opt | Paul Sauve | |
|
||||
| server | Cache entityhuman display name | Paul Sauve | |
|
||||
| server | Cache palette array | Paul Sauve | |
|
||||
| server | Cat spawning options | William Blake Galbreath | |
|
||||
| server | Change writes to use NORMAL priority rather than LOW | Spottedleaf | |
|
||||
| server | Changeable Mob Left Handed Chance | Ben Kerllenevich | |
|
||||
| server | Charged creeper naturally spawn | William Blake Galbreath | |
|
||||
| api | ChatColor conveniences | William Blake Galbreath | |
|
||||
| server | Chickens can retaliate | William Blake Galbreath | |
|
||||
| server | Config for Enderman to aggro spawned Endermites | Encode42 | |
|
||||
| server | Config for changing the blocks that turn into paths | 12emin34 | |
|
||||
| server | Config for health to impact Creeper explosion radius | Encode42 | |
|
||||
| server | Config for powered rail activation distance | Encode42 | |
|
||||
| server | Config for skipping night | Ben Kerllenevich | |
|
||||
| server | Config for unverified username message | Ben Kerllenevich | |
|
||||
| server | Config for wither explosion radius | Ben Kerllenevich | |
|
||||
| server | Config migration: climbing should not bypass cramming | jmp | |
|
||||
| server | Config migration: disable saving projectiles to disk -> | jmp | |
|
||||
| server | Config to allow Note Block sounds when blocked | Encode42 | |
|
||||
| server | Config to allow for unsafe enchants | Encode42 | |
|
||||
| server | Config to always tame in Creative | Encode42 | |
|
||||
| server | Config to change max number of bees | DoctaEnkoda | |
|
||||
| server | Config to disable Llama caravans | Encode42 | |
|
||||
| server | Config to disable hostile mob spawn on ice | Encode42 | |
|
||||
| server | Config to disable method profiler | Paul Sauve | |
|
||||
| server | Config to ignore Dragon Head wearers and stare aggro | Encode42 | |
|
||||
| server | Config to ignore nearby mobs when sleeping | Encode42 | |
|
||||
| server | Config to make Creepers explode on death | Encode42 | |
|
||||
| server | Config to show Armor Stand arms on spawn | Encode42 | |
|
||||
| server | Config to use infinity bows without arrows | Encode42 | |
|
||||
| server | Configs for if Wither/Ender Dragon can ride vehicles | jmp | |
|
||||
| server | Configurable BlockPhysicsEvent | Mykyta Komarnytskyy | |
|
||||
| server | Configurable Ender Pearl cooldown, damage, and Endermite RNG | Encode42 | |
|
||||
| server | Configurable TPS Catchup | William Blake Galbreath | |
|
||||
| server | Configurable chance for wolves to spawn rabid | Encode42 | |
|
||||
| server | Configurable criterion triggers | Mykyta Komarnytskyy | |
|
||||
| server | Configurable damage settings for magma blocks | Ben Kerllenevich | |
|
||||
| server | Configurable daylight cycle | William Blake Galbreath | |
|
||||
| server | Configurable default wolf collar color | Encode42 | |
|
||||
| server | Configurable dungeon seed | William Blake Galbreath | |
|
||||
| server | Configurable enchanting table tick | Ivan Pekov | |
|
||||
| server | Configurable end spike seed | William Blake Galbreath | |
|
||||
| server | Configurable entity base attributes | BillyGalbreath | |
|
||||
| server | Configurable flight checks | l_MrBoom_l | |
|
||||
| server | Configurable jockey options | William Blake Galbreath | |
|
||||
| server | Configurable movement checks | l_MrBoom_l | |
|
||||
| api | Configurable permission message upgrades | William Blake Galbreath | |
|
||||
| server | Configurable powered rail boost modifier | Callum Seabrook | |
|
||||
| server | Configurable ravager griefable blocks list | BillyGalbreath | |
|
||||
| server | Configurable server mod name | William Blake Galbreath | |
|
||||
| server | Configurable sponge absorption | Encode42 | |
|
||||
| server | Configurable villager brain ticks | William Blake Galbreath | |
|
||||
| server | Configurable villager breeding | draycia | |
|
||||
| server | Configurable void damage height and damage | William Blake Galbreath | |
|
||||
| api | Conflict on change for adventure deprecations | BillyGalbreath | |
|
||||
| server | Consolidate flush calls for entity tracker packets | Spottedleaf | |
|
||||
| server | Copy passenger list in enderTeleportTo | Spottedleaf | |
|
||||
| server | Correctly handle recursion for chunkholder updates | Spottedleaf | |
|
||||
| server | Cows eat mushrooms | William Blake Galbreath | |
|
||||
| server | Crying obsidian valid for portal frames | William Blake Galbreath | |
|
||||
| server | Custom Locale Support | Zoe | |
|
||||
| server | Custom table implementation for blockstate state lookups | Spottedleaf | |
|
||||
| server | Customizable wither health and healing | jmp | |
|
||||
| api | Default permissions | William Blake Galbreath | |
|
||||
| server | Delay chunk unloads | Spottedleaf | |
|
||||
| server | Despawn rate config options per projectile type | jmp | |
|
||||
| server | Detail more information in watchdog dumps | Spottedleaf | |
|
||||
| server | Disable loot drops on death by cramming | William Blake Galbreath | |
|
||||
| server | Disable outdated build check | William Blake Galbreath | |
|
||||
| api | Disable reload command | Ivan Pekov | |
|
||||
| server | Disable the Snooper | Sotr | |
|
||||
| server | Dispenser curse of binding protection | William Blake Galbreath | |
|
||||
| server | Dispensers place anvils option | William Blake Galbreath | |
|
||||
| server | Distance manager tick timings | Spottedleaf | |
|
||||
| server | Do not allow the server to unload chunks at request of | Spottedleaf | |
|
||||
| server | Do not allow ticket level changes while unloading | Spottedleaf | |
|
||||
| server | Do not copy visible chunks | Spottedleaf | |
|
||||
| server | Do not load chunks during a crash report | Spottedleaf | |
|
||||
| server | Do not retain playerchunkmap instance in light thread factory | Spottedleaf | |
|
||||
| server | Do not run close logic for inventories on chunk unload | Spottedleaf | |
|
||||
| server | Do not run raytrace logic for AIR | Spottedleaf | |
|
||||
| server | Do not update TE's in generating chunks | Spottedleaf | |
|
||||
| server | Don't allow StructureLocateEvent to change worlds | Spottedleaf | |
|
||||
| server | Don't get entity equipment if not needed | Paul Sauve | |
|
||||
| server | Don't lookup fluid state when raytracing | Spottedleaf | |
|
||||
| server | Don't read neighbour chunk data off disk when converting | Spottedleaf | |
|
||||
| server | Don't trigger Lootable Refresh for non player interaction | Aikar | |
|
||||
| server | Don't wake up entities when damage event is cancelled | Phoenix616 | |
|
||||
| server | Dont run with scissors! | JustDoom | |
|
||||
| server | Dont send useless entity packets | William Blake Galbreath | |
|
||||
| server | Drowning Settings | Ben Kerllenevich | |
|
||||
| server | Dynamic activation range | Paul Sauve | |
|
||||
| server | EMC - Configurable disable give dropping | Aikar | |
|
||||
| api | EMC - MonsterEggSpawnEvent | Aikar | |
|
||||
| server | EMC - MonsterEggSpawnEvent | Aikar | |
|
||||
| server | Early return optimization for target finding | Paul Sauve | |
|
||||
| server | End crystal explosion options | Ben Kerllenevich | |
|
||||
| server | End gateway should check if entity can use portal | William Blake Galbreath | |
|
||||
| server | Ender dragon always drop full exp | William Blake Galbreath | |
|
||||
| server | Ensure pools create daemon threads | Ivan Pekov | |
|
||||
| server | Entities can use portals configuration | William Blake Galbreath | |
|
||||
| server | Entities pick up loot bypass mob-griefing gamerule | William Blake Galbreath | |
|
||||
| server | Entity lifespan | William Blake Galbreath | |
|
||||
| server | Execute chunk tasks mid-tick | Spottedleaf | |
|
||||
| api | ExecuteCommandEvent | William Blake Galbreath | |
|
||||
| api | Expose findClass for profiler | Paul Sauve | |
|
||||
| server | Farmland trampling changes | Mariell Hoversholm | |
|
||||
| server | Fix 'outdated server' showing in ping before server fully | William Blake Galbreath | |
|
||||
| server | Fix IndexOutOfBoundsException when sending too many changes | Ivan Pekov | |
|
||||
| server | Fix LightEngineThreaded memory leak | Ivan Pekov | |
|
||||
| server | Fix Log4j Warning | snoopdoooggyttv | |
|
||||
| server | Fix NPE in pickup logic for arrow | Spottedleaf | |
|
||||
| server | Fix SPIGOT-6278 | BillyGalbreath | |
|
||||
| server | Fix advancement triggers on entity death | BillyGalbreath | |
|
||||
| server | Fix chunks refusing to unload at low TPS | Spottedleaf | |
|
||||
| server | Fix cow rotation when shearing mooshroom | William Blake Galbreath | |
|
||||
| server | Fix exp drop of zombie pigmen (MC-56653) | Phoenix616 | |
|
||||
| server | Fix incorrect isRealPlayer init | Spottedleaf | |
|
||||
| api | Fix javadoc warnings (missing @param and @return) | BillyGalbreath | |
|
||||
| server | Fix lead fall dmg config | tr7zw | |
|
||||
| server | Fix rotating UP/DOWN CW and CCW | BillyGalbreath | |
|
||||
| server | Fix stuck in portals | BillyGalbreath | |
|
||||
| server | Fix swamp hut cat generation deadlock | Spottedleaf | |
|
||||
| server | Fix the dead lagging the server | William Blake Galbreath | |
|
||||
| server | Fix vanilla command permission handler | William Blake Galbreath | |
|
||||
| server | Flying squids! Oh my! | William Blake Galbreath | |
|
||||
| api | Full netherite armor grants fire resistance | BillyGalbreath | |
|
||||
| server | Full netherite armor grants fire resistance | BillyGalbreath | |
|
||||
| server | Gamemode extra permissions | BillyGalbreath | |
|
||||
| server | Giants AI settings | William Blake Galbreath | |
|
||||
| server | Global Eula file | tr7zw | |
|
||||
| server | Heavily optimize furnance fuel and recipe lookups | tr7zw | Mykyta Komarn |
|
||||
| server | Heavily optimize recipe lookups in CraftingManager | Mykyta Komarn | Ivan Pekov, ishland |
|
||||
| server | Hide hidden players from entity selector | BillyGalbreath | |
|
||||
| server | Highly optimise single and multi-AABB VoxelShapes and | Spottedleaf | |
|
||||
| server | Highly optimize VillagePlace filtering | Ivan Pekov | |
|
||||
| server | Illusioners AI settings | William Blake Galbreath | |
|
||||
| server | Implement Mob Blindness | Encode42 | |
|
||||
| server | Implement TPSBar | BillyGalbreath | |
|
||||
| server | Implement bed explosion options | William Blake Galbreath | |
|
||||
| server | Implement configurable search radius for villagers to spawn | William Blake Galbreath | |
|
||||
| server | Implement elytra settings | William Blake Galbreath | |
|
||||
| server | Implement infinite lava | William Blake Galbreath | |
|
||||
| server | Implement respawn anchor explosion options | William Blake Galbreath | |
|
||||
| server | Improve abnormal server shutdown process | Spottedleaf | |
|
||||
| server | Improve async tp to not load chunks when crossing worlds | Spottedleaf | |
|
||||
| server | Improve container checking with a bitset | Paul Sauve | |
|
||||
| server | Improve fluid direction caching | Paul Sauve | |
|
||||
| server | Improve paper prevent moving into unloaded chunk check | Spottedleaf | |
|
||||
| server | Infinite fuel furnace | William Blake Galbreath | |
|
||||
| server | Infinity bow settings | William Blake Galbreath | |
|
||||
| api | Iron golem poppy calms anger | BillyGalbreath | |
|
||||
| server | Iron golem poppy calms anger | BillyGalbreath | |
|
||||
| api | Item entity immunities | William Blake Galbreath | |
|
||||
| server | Item entity immunities | William Blake Galbreath | |
|
||||
| server | Item stuck sleep config | tr7zw | |
|
||||
| api | ItemFactory#getMonsterEgg | William Blake Galbreath | |
|
||||
| server | ItemFactory#getMonsterEgg | William Blake Galbreath | |
|
||||
| api | ItemStack convenience methods | William Blake Galbreath | |
|
||||
| server | Kelp weeping and twisting vines configurable max growth age | BillyGalbreath | |
|
||||
| server | Lag compensate block breaking | Spottedleaf | |
|
||||
| api | Lagging threshold | William Blake Galbreath | |
|
||||
| server | Lagging threshold | William Blake Galbreath | |
|
||||
| api | Left handed API | BillyGalbreath | |
|
||||
| server | Left handed API | BillyGalbreath | |
|
||||
| server | Lithium: CompactSineLUT | JellySquid | |
|
||||
| api | LivingEntity safeFallDistance | William Blake Galbreath | |
|
||||
| server | LivingEntity safeFallDistance | William Blake Galbreath | |
|
||||
| api | LivingEntity#broadcastItemBreak | William Blake Galbreath | |
|
||||
| server | LivingEntity#broadcastItemBreak | William Blake Galbreath | |
|
||||
| api | Llama API | William Blake Galbreath | |
|
||||
| server | Llama API | William Blake Galbreath | |
|
||||
| server | Lobotomize stuck villagers | BillyGalbreath | |
|
||||
| server | Logger settings (suppressing pointless logs) | William Blake Galbreath | |
|
||||
| server | MC-147659 - Fix non black cats spawning in swamp huts | William Blake Galbreath | |
|
||||
| server | MC-168772 Fix - Add turtle egg block options | William Blake Galbreath | |
|
||||
| server | MC-Dev fixes | Spottedleaf | |
|
||||
| server | Make CallbackExecutor strict again | Spottedleaf | |
|
||||
| server | Make Iron Golems Swim | William Blake Galbreath | |
|
||||
| server | Make VoxelShapeCollisionEntity lazier | Paul Sauve | |
|
||||
| server | Make anvil cumulative cost configurable | 12emin34 | |
|
||||
| server | Make entity breeding times configurable | jmp | |
|
||||
| server | Make entity tracker use highest range of passengers | Spottedleaf | |
|
||||
| server | Make lava flow speed configurable | William Blake Galbreath | |
|
||||
| server | Make sure inlined getChunkAt has inlined logic for loaded | Spottedleaf | |
|
||||
| server | Manually inline methods in BlockPosition | Spottedleaf | |
|
||||
| server | Mending mends most damages equipment first | William Blake Galbreath | |
|
||||
| server | Minecart settings and WASD controls | William Blake Galbreath | |
|
||||
| api | Modify POM | YatopiaMC | |
|
||||
| server | Modify POM | YatopiaMC | |
|
||||
| server | Modify default configs | tr7zw | |
|
||||
| server | More debug for plugins not shutting down tasks | Paul Sauve | |
|
||||
| server | Movement options for armor stands | Mariell Hoversholm | |
|
||||
| server | Multi-Threaded Server Ticking Vanilla | Spottedleaf | |
|
||||
| server | Multi-Threaded ticking CraftBukkit | Spottedleaf | |
|
||||
| server | Name craft scheduler threads according to the plugin using | Spottedleaf | |
|
||||
| server | New nbt cache | Hugo Planque | ishland |
|
||||
| server | Nuke streams off BlockPosition | Ivan Pekov | |
|
||||
| server | Nuke streams off SectionPosition | Ivan Pekov | |
|
||||
| server | One Punch Man! | Fourmisain | |
|
||||
| server | Oprimise map impl for tracked players | Spottedleaf | |
|
||||
| server | Optimise WorldServer#notify | Spottedleaf | |
|
||||
| server | Optimise chunk tick iteration | Spottedleaf | |
|
||||
| server | Optimise closest entity lookup | Spottedleaf | |
|
||||
| server | Optimise collision checking in player move packet handling | Spottedleaf | |
|
||||
| server | Optimise entity hard collision checking | Spottedleaf | |
|
||||
| server | Optimise general POI access | Spottedleaf | |
|
||||
| server | Optimise nearby player lookups | Spottedleaf | |
|
||||
| server | Optimise non-flush packet sending | Spottedleaf | |
|
||||
| server | Optimise snow & ice in chunk ticking | Spottedleaf | |
|
||||
| server | Optimise tab complete | Spottedleaf | |
|
||||
| server | Optimised hallowen checker | Ivan Pekov | |
|
||||
| server | Optimize BehaviorController | MrIvanPlays | |
|
||||
| server | Optimize TileEntity load/unload | tr7zw | |
|
||||
| server | Optimize Villagers | Ivan Pekov | |
|
||||
| server | Optimize advancement loading | Ivan Pekov | |
|
||||
| server | Optimize collisions | DoctaEnkoda | |
|
||||
| server | Optimize inventory API item handling | Phoenix616 | |
|
||||
| server | Optimize random calls in chunk ticking | Paul Sauve | |
|
||||
| server | Optimize redundant calls | Paul Sauve | |
|
||||
| server | Optimize some stuff in WorldServer ticking | MrIvanPlays | |
|
||||
| server | Optimize whitelist command for multiple additions / removals | Ivan Pekov | |
|
||||
| server | Option for Villager Clerics to farm Nether Wart | jmp | |
|
||||
| server | Option for chests to open even with a solid block on top | jmp | |
|
||||
| server | Option for simpler Villagers | tr7zw | |
|
||||
| server | Option to disable dragon egg teleporting | BillyGalbreath | |
|
||||
| server | Option to make doors require redstone | BillyGalbreath | |
|
||||
| server | Option to toggle milk curing bad omen | William Blake Galbreath | |
|
||||
| server | Origami - Fix ProtocolLib issues on Java 15 | Phoenix616 | |
|
||||
| server | Origami Server Config | Phoenix616 | |
|
||||
| server | PaperPR - Config option for Piglins guarding chests | jmp | |
|
||||
| server | Per World Spawn Limits | Chase Whipple | |
|
||||
| server | Per entity (type) collision settings | MrIvanPlays | tr7zw |
|
||||
| api | Per player viewdistances | Spottedleaf | |
|
||||
| server | Persistent TileEntity Lore and DisplayName | jmp | |
|
||||
| server | Phantom flames on swoop | BillyGalbreath | |
|
||||
| api | Phantoms attracted to crystals and crystals shoot phantoms | William Blake Galbreath | |
|
||||
| server | Phantoms attracted to crystals and crystals shoot phantoms | William Blake Galbreath | |
|
||||
| server | Phantoms burn in light | draycia | |
|
||||
| server | Piglin portal spawn modifier | BillyGalbreath | |
|
||||
| server | Pigs give saddle back | William Blake Galbreath | |
|
||||
| api | Player invulnerabilities | William Blake Galbreath | |
|
||||
| server | Player invulnerabilities | William Blake Galbreath | |
|
||||
| api | PlayerAttackEntityEvent | Ivan Pekov | |
|
||||
| server | PlayerAttackEntityEvent | Ivan Pekov | |
|
||||
| api | PlayerSetSpawnerTypeWithEggEvent | William Blake Galbreath | |
|
||||
| server | PlayerSetSpawnerTypeWithEggEvent | William Blake Galbreath | |
|
||||
| server | Players should not cram to death | William Blake Galbreath | |
|
||||
| server | Populator seed controls | Spottedleaf | |
|
||||
| server | Port Cadmium | Lucy-t | |
|
||||
| server | Preload ProtocolLib EnumWrappers | ishland | |
|
||||
| server | Prevent long map entry creation in light engine | Spottedleaf | |
|
||||
| server | Prevent unload() calls removing tickets for sync loads | Spottedleaf | |
|
||||
| server | Projectile offset config | YouHaveTrouble | |
|
||||
| api | Purpur config files | William Blake Galbreath | |
|
||||
| server | Purpur config files | William Blake Galbreath | |
|
||||
| server | Rabbit naturally spawn toast and killer | William Blake Galbreath | |
|
||||
| api | Rabid Wolf API | Encode42 | |
|
||||
| server | Raid cooldown setting | jmp | |
|
||||
| server | Range check flag dirty calls in PlayerChunk | Spottedleaf | |
|
||||
| server | Rebrand | William Blake Galbreath | |
|
||||
| server | Redirect Configs | tr7zw | |
|
||||
| server | Redstone deactivates spawners | draycia | |
|
||||
| server | Reduce allocation rate from crammed entities | Spottedleaf | |
|
||||
| server | Reduce allocs & improve perf of StructureManager | Paul Sauve | |
|
||||
| server | Reduce chunk loading & lookups | Paul Sauve | |
|
||||
| server | Reduce frequency of checking for entity despawn | Paul Sauve | |
|
||||
| server | Reduce iterator allocation from chunk gen | Spottedleaf | |
|
||||
| server | Reduce pathfinder branches | Spottedleaf | |
|
||||
| server | Reduce projectile chunk loading | Paul Sauve | |
|
||||
| server | Remove chunk lookup & lambda allocation from counting mobs | Spottedleaf | |
|
||||
| server | Remove iterators from inventory contains | Paul Sauve | |
|
||||
| server | Remove some streams and object allocations | Phoenix616 | |
|
||||
| server | Remove streams | Paul Sauve | |
|
||||
| server | Remove streams for villager AI | Spottedleaf | |
|
||||
| server | Replace player chunk loader system | Spottedleaf | |
|
||||
| server | Replace ticket level propagator | Spottedleaf | |
|
||||
| server | Revert MC-4 fix | Spottedleaf | |
|
||||
| server | Revert getChunkAt(Async) retaining chunks for long periods of | Spottedleaf | |
|
||||
| server | Rework PlayerChunk main thread checks | Spottedleaf | |
|
||||
| server | Rewrite the light engine | Spottedleaf | |
|
||||
| api | Ridables | William Blake Galbreath | |
|
||||
| server | Ridables | William Blake Galbreath | |
|
||||
| server | Send full pos packets for hard colliding entities | Spottedleaf | |
|
||||
| server | Separate lookup locking from state access in UserCache | Spottedleaf | |
|
||||
| server | Set name visible when using a Name Tag on an Armor Stand | jmp | |
|
||||
| server | Short enderman height | William Blake Galbreath | |
|
||||
| server | ShulkerBox allow oversized stacks | BillyGalbreath | |
|
||||
| server | Shutdown Bootstrap thread pool | foss-mc | |
|
||||
| server | Signs allow color codes | William Blake Galbreath | |
|
||||
| server | Signs editable on right click | William Blake Galbreath | |
|
||||
| server | Silk touch spawners | William Blake Galbreath | |
|
||||
| server | Simpler ShapelessRecipes comparison for Vanilla | Paul Sauve | |
|
||||
| server | Skip POI finding if stuck in vehicle | Paul Sauve | |
|
||||
| server | Skip copying unloading tile entities | Paul Sauve | |
|
||||
| server | Skip creating hashset for entity track range | Paul Sauve | |
|
||||
| server | Skip events if there's no listeners | William Blake Galbreath | |
|
||||
| server | Smarter statistics ticking | Mykyta Komarnytskyy | |
|
||||
| server | Smol entity optimisations | Ivan Pekov | |
|
||||
| server | Sneak to bulk process composter | BillyGalbreath | |
|
||||
| server | Snow Golem rate of fire config | Simon Gardling | |
|
||||
| server | Snowman drop and put back pumpkin | William Blake Galbreath | |
|
||||
| api | Spigot - Improve output of plugins command | Parker Hawke | |
|
||||
| server | Spread out and optimise player list ticks | James Lyne | |
|
||||
| server | Squid EAR immunity | William Blake Galbreath | |
|
||||
| server | Stonecutter damage | William Blake Galbreath | |
|
||||
| server | Stop large move vectors in player packet handling from | Spottedleaf | |
|
||||
| server | Stop squids floating on top of water | William Blake Galbreath | |
|
||||
| server | Stop wasting resources on JsonList#get | Ivan Pekov | |
|
||||
| server | Striders give saddle back | Ben Kerllenevich | |
|
||||
| server | Strip raytracing for EntityLiving#hasLineOfSight | Paul Sauve | |
|
||||
| api | Suspected plugins report | ishland | |
|
||||
| server | Suspected plugins report | ishland | |
|
||||
| server | Swap priority of checks in chunk ticking | Paul Sauve | |
|
||||
| server | Swaps the predicate order of collision | ㄗㄠˋ ㄑㄧˊ | |
|
||||
| server | Tick fluids config | BillyGalbreath | |
|
||||
| server | Time scoreboard search | Spottedleaf | |
|
||||
| server | Timings stuff | William Blake Galbreath | |
|
||||
| server | Toggle for Zombified Piglin death always counting as player | jmp | |
|
||||
| server | Toggle for water sensitive mob damage | YouHaveTrouble | |
|
||||
| server | Totems work in inventory | draycia | |
|
||||
| api | Tuinity POM Changes | Spottedleaf | |
|
||||
| server | Tuinity POM Changes | Spottedleaf | |
|
||||
| server | Tuinity Server Config | Spottedleaf | |
|
||||
| api | Tuinity config | Spottedleaf | |
|
||||
| server | Tulips change fox type | William Blake Galbreath | |
|
||||
| server | Update version fetcher repo | JRoy | |
|
||||
| server | Use array for gamerule storage | Paul Sauve | |
|
||||
| server | Use configured height for nether surface builders | William Blake Galbreath | |
|
||||
| server | Use hash table for maintaing changed block set | Spottedleaf | |
|
||||
| server | Use list for fast iteration over pathfinder goals | Paul Sauve | |
|
||||
| server | Use raw iterator where possible | Paul Sauve | |
|
||||
| server | Use unmodifiableMap instead of making copy | Paul Sauve | |
|
||||
| server | Util patch | Spottedleaf | |
|
||||
| server | Utilities | YatopiaMC | Mykyta Komarnytskyy, Ivan Pekov |
|
||||
| api | Villager#resetOffers | William Blake Galbreath | |
|
||||
| server | Villagers farming can bypass mob-griefing gamerule | William Blake Galbreath | |
|
||||
| server | Villagers follow emerald blocks | William Blake Galbreath | |
|
||||
| api | Yatopia Config & Redirect Config | YatopiaMC | |
|
||||
| server | Yatopia configuration | tr7zw | |
|
||||
| server | Zombie break door minimum difficulty option | BillyGalbreath | |
|
||||
| server | Zombie horse naturally spawn | William Blake Galbreath | |
|
||||
| server | add config for logging login location | Simon Gardling | |
|
||||
| server | dont load chunks for physics | Aikar | |
|
||||
| server | lithium DataTrackerMixin | JellySquid | tr7zw |
|
||||
| server | lithium HashedList | JellySquid | |
|
||||
| server | lithium MixinBox | JellySquid | |
|
||||
| server | lithium MixinDirection | JellySquid | |
|
||||
| server | lithium NoiseChunkGeneratorMixin | JellySquid | |
|
||||
| server | lithium PerlinNoiseSamplerMixin | JellySquid | Bud Gidiere |
|
||||
| server | lithium VoronoiBiomeAccessTypeMixin | JellySquid | |
|
||||
| server | lithium block | JellySquid | Hugo Planque |
|
||||
| server | lithium entity | JellySquid | Hugo Planque |
|
||||
| server | lithium enum_values | JellySquid | |
|
||||
| server | lithium reduce allocations | JellySquid | Mykyta Komarnytskyy |
|
||||
| server | lithium shape | JellySquid | Hugo Planque |
|
||||
| server | lithium: cache chunk gen sea level | SuperCoder7979 | |
|
||||
| server | lithium: optimize `BlockPos.iterateOutwards` by caching | 2No2Name | |
|
||||
| server | lithium: skip ticking block entities that are doing nothing | 2No2Name | |
|
||||
| server | tic-tacs: unblocking | Gegy | |
|
1
Paper
1
Paper
@ -1 +0,0 @@
|
||||
Subproject commit 525d0e3d3752fa78e7c136a4d4bf13c3278691d9
|
@ -1,11 +0,0 @@
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://jitpack.io/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.ishlandbukkit:jbsdiff:deff66b794")
|
||||
implementation("com.google.code.gson:gson:2.8.6")
|
||||
implementation("commons-io:commons-io:2.8.0")
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
package org.yatopiamc.yatoclip;
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.nio.file.Path;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public class YatoclipLaunch {
|
||||
|
||||
private static Instrumentation inst = null;
|
||||
|
||||
public static void premain(String args, Instrumentation inst) {
|
||||
YatoclipLaunch.inst = inst;
|
||||
}
|
||||
|
||||
public static void agentmain(final String agentArgs, final Instrumentation inst) {
|
||||
YatoclipLaunch.inst = inst;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void injectClasspath(Path setup) throws Throwable {
|
||||
if(inst == null) {
|
||||
throw new RuntimeException("Instrumentation API handle not found");
|
||||
}
|
||||
inst.appendToSystemClassLoaderSearch(new JarFile(setup.toFile()));
|
||||
inst = null;
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package org.yatopiamc.yatoclip;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class PatchesMetadata {
|
||||
|
||||
public final Set<PatchMetadata> patches;
|
||||
public final Set<Relocation> relocations;
|
||||
public final Set<String> copyExcludes;
|
||||
|
||||
public PatchesMetadata(Set<PatchMetadata> patches, Set<Relocation> relocations, Set<String> copyExcludes) {
|
||||
Objects.requireNonNull(copyExcludes);
|
||||
this.copyExcludes = Collections.unmodifiableSet(copyExcludes);
|
||||
Objects.requireNonNull(relocations);
|
||||
this.relocations = Collections.unmodifiableSet(relocations);
|
||||
Objects.requireNonNull(patches);
|
||||
this.patches = Collections.unmodifiableSet(patches);
|
||||
}
|
||||
|
||||
public static class PatchMetadata {
|
||||
public final String name;
|
||||
public final String originalHash;
|
||||
public final String targetHash;
|
||||
public final String patchHash;
|
||||
|
||||
public PatchMetadata(String name, String originalHash, String targetHash, String patchHash) {
|
||||
this.name = name;
|
||||
this.originalHash = originalHash;
|
||||
this.targetHash = targetHash;
|
||||
this.patchHash = patchHash;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Relocation implements Serializable {
|
||||
|
||||
public final String from;
|
||||
public final String to;
|
||||
public final boolean includeSubPackages;
|
||||
|
||||
public Relocation(String from, String to, boolean includeSubPackages) {
|
||||
Objects.requireNonNull(from);
|
||||
Objects.requireNonNull(to);
|
||||
this.from = from.replaceAll("\\.", "/");
|
||||
this.to = to.replaceAll("\\.", "/");
|
||||
this.includeSubPackages = includeSubPackages;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,360 +0,0 @@
|
||||
package org.yatopiamc.yatoclip;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import static java.nio.file.StandardOpenOption.CREATE;
|
||||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
||||
import static java.nio.file.StandardOpenOption.WRITE;
|
||||
|
||||
public class ServerSetup {
|
||||
|
||||
private static final String minecraftVersion;
|
||||
private static final Path cacheDirectory;
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
private static VersionInfo versionInfo = null;
|
||||
private static BuildDataInfo buildDataInfo = null;
|
||||
|
||||
static {
|
||||
Properties prop = new Properties();
|
||||
try (InputStream inputStream = ServerSetup.class.getClassLoader().getResourceAsStream("yatoclip-launch.properties")) {
|
||||
prop.load(inputStream);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
minecraftVersion = prop.getProperty("minecraftVersion");
|
||||
cacheDirectory = Paths.get("cache", minecraftVersion);
|
||||
cacheDirectory.toFile().mkdirs();
|
||||
}
|
||||
|
||||
public static Path setup() throws IOException {
|
||||
long startTime = System.nanoTime();
|
||||
checkBuildData();
|
||||
applyMappingsAndPatches();
|
||||
System.err.println(String.format("Yatoclip server setup completed in %.2fms", (System.nanoTime() - startTime) / 1_000_000.0));
|
||||
return cacheDirectory.resolve("Minecraft").resolve(minecraftVersion + "-patched.jar");
|
||||
}
|
||||
|
||||
private static void applyMappingsAndPatches() throws IOException {
|
||||
final Path minecraftDir = cacheDirectory.resolve("Minecraft");
|
||||
minecraftDir.toFile().mkdirs();
|
||||
final Path vanillaJar = minecraftDir.resolve(minecraftVersion + ".jar");
|
||||
if (!isValidZip(vanillaJar)) {
|
||||
System.err.println("Downloading vanilla jar...");
|
||||
download(new URL(buildDataInfo.serverUrl), vanillaJar);
|
||||
if (!isValidZip(vanillaJar)) throw new RuntimeException("Invalid vanilla jar");
|
||||
}
|
||||
final Path classMappedJar = minecraftDir.resolve(minecraftVersion + "-cl.jar");
|
||||
final Path memberMappedJar = minecraftDir.resolve(minecraftVersion + "-m.jar");
|
||||
final Path patchedJar = minecraftDir.resolve(minecraftVersion + "-patched.jar");
|
||||
if (!isValidZip(classMappedJar) || !isValidZip(memberMappedJar)) {
|
||||
SpecialSourceLauncher.resetSpecialSourceClassloader();
|
||||
final Path buildData = cacheDirectory.resolve("BuildData");
|
||||
SpecialSourceLauncher.setSpecialSourceJar(buildData.resolve("bin").resolve("SpecialSource-2.jar").toFile());
|
||||
System.err.println("Applying class mapping...");
|
||||
SpecialSourceLauncher.runProcess(
|
||||
"map", "--only", ".", "--only", "net/minecraft", "--auto-lvt", "BASIC", "--auto-member", "SYNTHETIC",
|
||||
"-i", vanillaJar.toAbsolutePath().toString(),
|
||||
"-m", buildData.resolve("mappings").resolve(buildDataInfo.classMappings).toAbsolutePath().toString(),
|
||||
"-o", classMappedJar.toAbsolutePath().toString()
|
||||
);
|
||||
System.err.println("Applying member mapping...");
|
||||
SpecialSourceLauncher.runProcess(
|
||||
"map", "--only", ".", "--only", "net/minecraft", "--auto-member", "LOGGER", "--auto-member", "TOKENS",
|
||||
"-i", classMappedJar.toAbsolutePath().toString(),
|
||||
"-m", buildData.resolve("mappings").resolve(buildDataInfo.memberMappings).toAbsolutePath().toString(),
|
||||
"-o", memberMappedJar.toAbsolutePath().toString()
|
||||
);
|
||||
SpecialSourceLauncher.resetSpecialSourceClassloader();
|
||||
if (!isValidZip(classMappedJar) || !isValidZip(memberMappedJar))
|
||||
throw new RuntimeException("Unable to apply mappings");
|
||||
}
|
||||
|
||||
if (!YatoclipPatcher.isJarUpToDate(patchedJar)){
|
||||
System.err.println("Applying patches...");
|
||||
YatoclipPatcher.patchJar(memberMappedJar, patchedJar);
|
||||
if(!YatoclipPatcher.isJarUpToDate(patchedJar))
|
||||
throw new RuntimeException("Unable to apply patches");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
private static boolean isValidZip(Path zipPath) {
|
||||
try {
|
||||
ZipFile zipFile = new ZipFile(zipPath.toFile());
|
||||
zipFile.close();
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void checkBuildData() throws IOException {
|
||||
final Path buildDataDir = cacheDirectory.resolve("BuildData");
|
||||
buildDataDir.toFile().mkdirs();
|
||||
final Path versionInfoFile = buildDataDir.resolve("version.json");
|
||||
if (!tryParseVersionInfo(versionInfoFile)) {
|
||||
System.err.println("Downloading version.json...");
|
||||
final URL versionInfoURI = new URL("https://hub.spigotmc.org/versions/" + minecraftVersion + ".json");
|
||||
download(versionInfoURI, versionInfoFile);
|
||||
if (!tryParseVersionInfo(versionInfoFile)) throw new RuntimeException("Unable to parse versionInfo");
|
||||
}
|
||||
final Path buildDataArchive = buildDataDir.resolve("BuildData.zip");
|
||||
if (!tryParseBuildData(buildDataArchive)) {
|
||||
System.err.println("Downloading BuildData...");
|
||||
final URL buildDataURL = new URL("https://hub.spigotmc.org/stash/rest/api/latest/projects/SPIGOT/repos/builddata/archive?at=" + ServerSetup.versionInfo.refs.buildData + "&format=zip");
|
||||
download(buildDataURL, buildDataArchive);
|
||||
if (!tryParseBuildData(buildDataArchive)) throw new RuntimeException("Unable to parse BuildData");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
private static boolean tryParseBuildData(Path buildData) {
|
||||
try {
|
||||
ZipFile zipFile = new ZipFile(buildData.toFile());
|
||||
((Iterator<ZipEntry>) zipFile.entries()).forEachRemaining(zipEntry -> {
|
||||
if (zipEntry.isDirectory()) return;
|
||||
buildData.getParent().resolve(zipEntry.getName()).getParent().toFile().mkdirs();
|
||||
try (
|
||||
final ReadableByteChannel source = Channels.newChannel(zipFile.getInputStream(zipEntry));
|
||||
final FileChannel fileChannel = FileChannel.open(buildData.getParent().resolve(zipEntry.getName()), CREATE, WRITE, TRUNCATE_EXISTING)
|
||||
) {
|
||||
fileChannel.transferFrom(source, 0, Long.MAX_VALUE);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
});
|
||||
zipFile.close();
|
||||
try (Reader reader = Files.newBufferedReader(buildData.getParent().resolve("info.json"))){
|
||||
ServerSetup.buildDataInfo = gson.fromJson(reader, BuildDataInfo.class);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
private static boolean tryParseVersionInfo(Path versionInfo) {
|
||||
try (Reader reader = Files.newBufferedReader(versionInfo)) {
|
||||
ServerSetup.versionInfo = gson.fromJson(reader, VersionInfo.class);
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void download(URL url, Path downloadTo) throws IOException {
|
||||
try (
|
||||
final ReadableByteChannel source = Channels.newChannel(url.openStream());
|
||||
final FileChannel fileChannel = FileChannel.open(downloadTo, CREATE, WRITE, TRUNCATE_EXISTING)
|
||||
) {
|
||||
downloadTo.getParent().toFile().mkdirs();
|
||||
fileChannel.transferFrom(source, 0, Long.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static String toHex(final byte[] hash) {
|
||||
final StringBuilder sb = new StringBuilder(hash.length * 2);
|
||||
for (byte aHash : hash) {
|
||||
sb.append(String.format("%02X", aHash & 0xFF));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class VersionInfo {
|
||||
|
||||
@SerializedName("refs")
|
||||
private Refs refs;
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
|
||||
@SerializedName("description")
|
||||
private String description;
|
||||
|
||||
@SerializedName("toolsVersion")
|
||||
private int toolsVersion;
|
||||
|
||||
@SerializedName("javaVersions")
|
||||
private List<Integer> javaVersions;
|
||||
|
||||
public Refs getRefs() {
|
||||
return refs;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getToolsVersion() {
|
||||
return toolsVersion;
|
||||
}
|
||||
|
||||
public List<Integer> getJavaVersions() {
|
||||
return javaVersions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return
|
||||
"VersionInfo{" +
|
||||
"refs = '" + refs + '\'' +
|
||||
",name = '" + name + '\'' +
|
||||
",description = '" + description + '\'' +
|
||||
",toolsVersion = '" + toolsVersion + '\'' +
|
||||
",javaVersions = '" + javaVersions + '\'' +
|
||||
"}";
|
||||
}
|
||||
|
||||
public static class Refs {
|
||||
|
||||
@SerializedName("BuildData")
|
||||
private String buildData;
|
||||
|
||||
@SerializedName("CraftBukkit")
|
||||
private String craftBukkit;
|
||||
|
||||
@SerializedName("Bukkit")
|
||||
private String bukkit;
|
||||
|
||||
@SerializedName("Spigot")
|
||||
private String spigot;
|
||||
|
||||
public String getBuildData() {
|
||||
return buildData;
|
||||
}
|
||||
|
||||
public String getCraftBukkit() {
|
||||
return craftBukkit;
|
||||
}
|
||||
|
||||
public String getBukkit() {
|
||||
return bukkit;
|
||||
}
|
||||
|
||||
public String getSpigot() {
|
||||
return spigot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return
|
||||
"Refs{" +
|
||||
"buildData = '" + buildData + '\'' +
|
||||
",craftBukkit = '" + craftBukkit + '\'' +
|
||||
",bukkit = '" + bukkit + '\'' +
|
||||
",spigot = '" + spigot + '\'' +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class BuildDataInfo {
|
||||
|
||||
@SerializedName("memberMapCommand")
|
||||
private String memberMapCommand;
|
||||
|
||||
@SerializedName("packageMappings")
|
||||
private String packageMappings;
|
||||
|
||||
@SerializedName("classMapCommand")
|
||||
private String classMapCommand;
|
||||
|
||||
@SerializedName("finalMapCommand")
|
||||
private String finalMapCommand;
|
||||
|
||||
@SerializedName("serverUrl")
|
||||
private String serverUrl;
|
||||
|
||||
@SerializedName("toolsVersion")
|
||||
private int toolsVersion;
|
||||
|
||||
@SerializedName("minecraftHash")
|
||||
private String minecraftHash;
|
||||
|
||||
@SerializedName("minecraftVersion")
|
||||
private String minecraftVersion;
|
||||
|
||||
@SerializedName("accessTransforms")
|
||||
private String accessTransforms;
|
||||
|
||||
@SerializedName("memberMappings")
|
||||
private String memberMappings;
|
||||
|
||||
@SerializedName("decompileCommand")
|
||||
private String decompileCommand;
|
||||
|
||||
@SerializedName("classMappings")
|
||||
private String classMappings;
|
||||
|
||||
public String getMemberMapCommand() {
|
||||
return memberMapCommand;
|
||||
}
|
||||
|
||||
public String getPackageMappings() {
|
||||
return packageMappings;
|
||||
}
|
||||
|
||||
public String getClassMapCommand() {
|
||||
return classMapCommand;
|
||||
}
|
||||
|
||||
public String getFinalMapCommand() {
|
||||
return finalMapCommand;
|
||||
}
|
||||
|
||||
public String getServerUrl() {
|
||||
return serverUrl;
|
||||
}
|
||||
|
||||
public int getToolsVersion() {
|
||||
return toolsVersion;
|
||||
}
|
||||
|
||||
public String getMinecraftHash() {
|
||||
return minecraftHash;
|
||||
}
|
||||
|
||||
public String getMinecraftVersion() {
|
||||
return minecraftVersion;
|
||||
}
|
||||
|
||||
public String getAccessTransforms() {
|
||||
return accessTransforms;
|
||||
}
|
||||
|
||||
public String getMemberMappings() {
|
||||
return memberMappings;
|
||||
}
|
||||
|
||||
public String getDecompileCommand() {
|
||||
return decompileCommand;
|
||||
}
|
||||
|
||||
public String getClassMappings() {
|
||||
return classMappings;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
package org.yatopiamc.yatoclip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class SpecialSourceLauncher {
|
||||
|
||||
private static final AtomicReference<SpecialSourceClassLoader> classLoader = new AtomicReference<>(new SpecialSourceClassLoader(new URL[0], SpecialSourceLauncher.class.getClassLoader().getParent()));
|
||||
private static final AtomicReference<String> mainClass = new AtomicReference<>("");
|
||||
|
||||
static void setSpecialSourceJar(File specialSourceJar) {
|
||||
synchronized (classLoader) {
|
||||
System.err.println("Setting up SpecialSource: " + specialSourceJar);
|
||||
try {
|
||||
classLoader.get().addURL(specialSourceJar.toURI().toURL());
|
||||
mainClass.set(Yatoclip.getMainClass(specialSourceJar.toPath()));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void resetSpecialSourceClassloader() {
|
||||
synchronized (classLoader) {
|
||||
if(!classLoader.get().isLoaded) return;
|
||||
System.err.println("Releasing SpecialSource");
|
||||
try {
|
||||
classLoader.get().close();
|
||||
classLoader.set(new SpecialSourceClassLoader(new URL[0], SpecialSourceLauncher.class.getClassLoader().getParent()));
|
||||
mainClass.set("");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void runProcess(String... command) throws IOException {
|
||||
if (!(command != null && command.length > 0)) throw new IllegalArgumentException();
|
||||
|
||||
System.err.println("Invoking SpecialSource with arguments: " + Arrays.toString(command));
|
||||
|
||||
AtomicReference<Throwable> thrown = new AtomicReference<>(null);
|
||||
final Thread thread = new Thread(() -> {
|
||||
try {
|
||||
final Class<?> mainClass = Class.forName(SpecialSourceLauncher.mainClass.get(), true, classLoader.get());
|
||||
final Method mainMethod = mainClass.getMethod("main", String[].class);
|
||||
if (!Modifier.isStatic(mainMethod.getModifiers()) || !Modifier.isPublic(mainMethod.getModifiers()))
|
||||
throw new IllegalArgumentException();
|
||||
mainMethod.invoke(null, new Object[]{command});
|
||||
} catch (Throwable t) {
|
||||
thrown.set(t);
|
||||
}
|
||||
});
|
||||
thread.setName("SpecialSource Thread");
|
||||
thread.setContextClassLoader(classLoader.get());
|
||||
thread.start();
|
||||
while (thread.isAlive())
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
if (thrown.get() != null)
|
||||
throw new RuntimeException(thrown.get());
|
||||
|
||||
}
|
||||
|
||||
private static class SpecialSourceClassLoader extends URLClassLoader {
|
||||
|
||||
private volatile boolean isLoaded = false;
|
||||
|
||||
public SpecialSourceClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void addURL(URL url) {
|
||||
if (isLoaded) throw new IllegalStateException();
|
||||
this.isLoaded = true;
|
||||
super.addURL(url);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package org.yatopiamc.yatoclip;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.jar.JarInputStream;
|
||||
|
||||
public class Yatoclip {
|
||||
|
||||
public static void main(String... args) throws Throwable {
|
||||
final Path setup = ServerSetup.setup();
|
||||
launch(setup, args);
|
||||
}
|
||||
|
||||
private static void launch(Path setup, String[] args) throws Throwable {
|
||||
YatoclipLaunch.injectClasspath(setup);
|
||||
final Class<?> mainClassInstance = Class.forName("org.bukkit.craftbukkit.Main", true, ClassLoader.getSystemClassLoader());
|
||||
final Method mainMethod = mainClassInstance.getMethod("main", String[].class);
|
||||
if(!Modifier.isPublic(mainMethod.getModifiers()) || !Modifier.isStatic(mainMethod.getModifiers())) throw new IllegalArgumentException();
|
||||
mainMethod.invoke(null, new Object[]{args});
|
||||
}
|
||||
|
||||
static String getMainClass(Path jarPath) throws IOException {
|
||||
final String mainClass;
|
||||
try (
|
||||
InputStream inputStream = Files.newInputStream(jarPath);
|
||||
JarInputStream jar = new JarInputStream(inputStream)
|
||||
) {
|
||||
mainClass = jar.getManifest().getMainAttributes().getValue("Main-Class");
|
||||
}
|
||||
return mainClass;
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package org.yatopiamc.yatoclip;
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class YatoclipLaunch {
|
||||
|
||||
public static void premain(String args, Instrumentation inst) {
|
||||
}
|
||||
|
||||
static void injectClasspath(Path setup) throws Throwable {
|
||||
final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||
if(!(systemClassLoader instanceof URLClassLoader))
|
||||
throw new ClassCastException("SystemClassLoader is not an instance of URLClassLoader");
|
||||
final URLClassLoader classLoader = (URLClassLoader) systemClassLoader;
|
||||
final Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
addURL.setAccessible(true);
|
||||
addURL.invoke(classLoader, setup.toUri().toURL());
|
||||
}
|
||||
|
||||
}
|
@ -1,236 +0,0 @@
|
||||
package org.yatopiamc.yatoclip;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.sigpipe.jbsdiff.InvalidHeaderException;
|
||||
import io.sigpipe.jbsdiff.Patch;
|
||||
import org.apache.commons.compress.compressors.CompressorException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class YatoclipPatcher {
|
||||
|
||||
private static final PatchesMetadata patchesMetadata;
|
||||
|
||||
static {
|
||||
try (
|
||||
final InputStream in = YatoclipPatcher.class.getClassLoader().getResourceAsStream("patches/metadata.json");
|
||||
final InputStreamReader reader = new InputStreamReader(in);
|
||||
) {
|
||||
patchesMetadata = new Gson().fromJson(reader, PatchesMetadata.class);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
static boolean isJarUpToDate(Path patchedJar) {
|
||||
requireNonNull(patchedJar);
|
||||
if (!patchedJar.toFile().isFile()) return false;
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
try (ZipFile patchedZip = new ZipFile(patchedJar.toFile())) {
|
||||
for (PatchesMetadata.PatchMetadata patchMetadata : patchesMetadata.patches) {
|
||||
ZipEntry zipEntry = patchedZip.getEntry(patchMetadata.name);
|
||||
if (zipEntry == null || !patchMetadata.targetHash.equals(ServerSetup.toHex(digest.digest(IOUtils.toByteArray(patchedZip.getInputStream(zipEntry))))))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Throwable t) {
|
||||
System.out.println(t.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void patchJar(Path memberMappedJar, Path patchedJar) {
|
||||
requireNonNull(memberMappedJar);
|
||||
requireNonNull(patchedJar);
|
||||
if(!memberMappedJar.toFile().isFile()) throw new IllegalArgumentException(new FileNotFoundException());
|
||||
try {
|
||||
patchedJar.toFile().getParentFile().mkdirs();
|
||||
final ThreadLocal<ZipFile> classMappedZip = ThreadLocal.withInitial(() -> {
|
||||
try {
|
||||
return new ZipFile(memberMappedJar.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
final ThreadLocal<MessageDigest> digest = ThreadLocal.withInitial(() -> {
|
||||
try {
|
||||
return MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
||||
private AtomicInteger serial = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
r.run();
|
||||
} finally {
|
||||
try {
|
||||
classMappedZip.get().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.setName("YatoClip Worker #" + serial.incrementAndGet());
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
try {
|
||||
final Set<PatchData> patchDataSet = patchesMetadata.patches.stream().map((PatchesMetadata.PatchMetadata metadata) -> new PatchData(CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return getPatchedBytes(classMappedZip.get(), digest.get(), metadata);
|
||||
} catch (IOException | CompressorException | InvalidHeaderException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, executorService), metadata)).collect(Collectors.toSet());
|
||||
try (ZipOutputStream patchedZip = new ZipOutputStream(new FileOutputStream(patchedJar.toFile()))) {
|
||||
patchedZip.setMethod(ZipOutputStream.DEFLATED);
|
||||
patchedZip.setLevel(Deflater.BEST_SPEED);
|
||||
Set<String> processed = new HashSet<>();
|
||||
for (PatchData patchData : patchDataSet) {
|
||||
putNextEntrySafe(patchedZip, patchData.metadata.name);
|
||||
final byte[] patchedBytes = patchData.patchedBytesFuture.join();
|
||||
patchedZip.write(patchedBytes);
|
||||
patchedZip.closeEntry();
|
||||
processed.add(patchData.metadata.name);
|
||||
}
|
||||
|
||||
((Iterator<ZipEntry>) classMappedZip.get().entries()).forEachRemaining(zipEntry -> {
|
||||
if (zipEntry.isDirectory() || processed.contains(applyRelocations(zipEntry.getName())) || patchesMetadata.copyExcludes.contains(zipEntry.getName()))
|
||||
return;
|
||||
try {
|
||||
InputStream in = classMappedZip.get().getInputStream(zipEntry);
|
||||
putNextEntrySafe(patchedZip, zipEntry.getName());
|
||||
patchedZip.write(IOUtils.toByteArray(in));
|
||||
patchedZip.closeEntry();
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
executorService.shutdown();
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getPatchedBytes(ZipFile classMappedZip, MessageDigest digest, PatchesMetadata.PatchMetadata patchMetadata) throws IOException, CompressorException, InvalidHeaderException {
|
||||
final byte[] originalBytes;
|
||||
final ZipEntry originalEntry = classMappedZip.getEntry(applyRelocationsReverse(patchMetadata.name));
|
||||
if (originalEntry != null)
|
||||
try (final InputStream in = classMappedZip.getInputStream(originalEntry)) {
|
||||
originalBytes = IOUtils.toByteArray(in);
|
||||
}
|
||||
else originalBytes = new byte[0];
|
||||
final byte[] patchBytes;
|
||||
try (final InputStream in = YatoclipPatcher.class.getClassLoader().getResourceAsStream("patches/" + patchMetadata.name + ".patch")) {
|
||||
if (in == null)
|
||||
throw new FileNotFoundException();
|
||||
patchBytes = IOUtils.toByteArray(in);
|
||||
}
|
||||
if (!patchMetadata.originalHash.equals(ServerSetup.toHex(digest.digest(originalBytes))) || !patchMetadata.patchHash.equals(ServerSetup.toHex(digest.digest(patchBytes))))
|
||||
throw new FileNotFoundException("Hash do not match");
|
||||
|
||||
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
||||
Patch.patch(originalBytes, patchBytes, byteOut);
|
||||
final byte[] patchedBytes = byteOut.toByteArray();
|
||||
if (!patchMetadata.targetHash.equals(ServerSetup.toHex(digest.digest(patchedBytes))))
|
||||
throw new FileNotFoundException("Hash do not match");
|
||||
return patchedBytes;
|
||||
}
|
||||
|
||||
private static void putNextEntrySafe(ZipOutputStream patchedZip, String name) throws IOException {
|
||||
String[] split = name.split("/");
|
||||
split = Arrays.copyOfRange(split, 0, split.length - 1);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String s : split) {
|
||||
sb.append(s).append("/");
|
||||
try {
|
||||
patchedZip.putNextEntry(new ZipEntry(sb.toString()));
|
||||
} catch (ZipException e) {
|
||||
if (e.getMessage().startsWith("duplicate entry"))
|
||||
continue;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
final ZipEntry entry = new ZipEntry(name);
|
||||
patchedZip.putNextEntry(entry);
|
||||
}
|
||||
|
||||
private static String applyRelocations(String name) {
|
||||
if (!name.endsWith(".class")) return name;
|
||||
if (name.indexOf('/') == -1)
|
||||
name = "/" + name;
|
||||
for (PatchesMetadata.Relocation relocation : patchesMetadata.relocations) {
|
||||
if (name.startsWith(relocation.from) && (relocation.includeSubPackages || name.split("/").length == name.split("/").length - 1)) {
|
||||
return relocation.to + name.substring(relocation.from.length());
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static String applyRelocationsReverse(String name) {
|
||||
if (!name.endsWith(".class")) return name;
|
||||
if (name.indexOf('/') == -1)
|
||||
name = "/" + name;
|
||||
for (PatchesMetadata.Relocation relocation : patchesMetadata.relocations) {
|
||||
if (name.startsWith(relocation.to) && (relocation.includeSubPackages || name.split("/").length == name.split("/").length - 1)) {
|
||||
return relocation.from + name.substring(relocation.to.length());
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static class PatchData {
|
||||
|
||||
public final CompletableFuture<byte[]> patchedBytesFuture;
|
||||
public final PatchesMetadata.PatchMetadata metadata;
|
||||
|
||||
|
||||
private PatchData(CompletableFuture<byte[]> patchedBytesFuture, PatchesMetadata.PatchMetadata metadata) {
|
||||
Objects.requireNonNull(patchedBytesFuture);
|
||||
Objects.requireNonNull(metadata);
|
||||
this.patchedBytesFuture = patchedBytesFuture.thenApply(Objects::requireNonNull);
|
||||
this.metadata = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
103
build.gradle.kts
103
build.gradle.kts
@ -1,69 +1,64 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
toothpick
|
||||
java
|
||||
id("com.github.johnrengelman.shadow") version "7.0.0" apply false
|
||||
id("io.papermc.paperweight.patcher") version "1.0.0-SNAPSHOT"
|
||||
}
|
||||
|
||||
toothpick {
|
||||
forkName = "Yatopia"
|
||||
groupId = "org.yatopiamc"
|
||||
val versionTag = System.getenv("BUILD_NUMBER")
|
||||
?: "\"${gitCmd("rev-parse", "--short", "HEAD").output}\""
|
||||
if(!System.getenv("BRANCH_NAME").isNullOrEmpty()) {
|
||||
currentBranch = System.getenv("BRANCH_NAME")
|
||||
} else if (!System.getenv("GITHUB_HEAD_REF").isNullOrEmpty()) {
|
||||
currentBranch = System.getenv("GITHUB_HEAD_REF")
|
||||
} else if (!System.getenv("GITHUB_REF").isNullOrEmpty()) {
|
||||
currentBranch = System.getenv("GITHUB_REF").substring("refs/heads/".length)
|
||||
} else {
|
||||
currentBranch = gitCmd("rev-parse", "--abbrev-ref", "HEAD").output.toString().trim()
|
||||
if(currentBranch == "HEAD") logger.warn("You are currently in \'detached HEAD\' state, branch information isn\'t available")
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://wav.jfrog.io/artifactory/repo/") {
|
||||
content {
|
||||
onlyForConfigurations("paperclip")
|
||||
}
|
||||
forkVersion = "git-$forkName-$currentBranch-$versionTag"
|
||||
forkUrl = "https://github.com/YatopiaMC/Yatopia"
|
||||
|
||||
minecraftVersion = "1.16.5"
|
||||
nmsPackage = "1_16_R3"
|
||||
nmsRevision = "R0.1-SNAPSHOT"
|
||||
|
||||
upstream = "Paper"
|
||||
upstreamBranch = "origin/master"
|
||||
|
||||
paperclipName = "yatopia-$minecraftVersion-paperclip.jar"
|
||||
|
||||
patchCreditsOutput = "PATCHES.md"
|
||||
patchCreditsTemplate = ".template.md"
|
||||
|
||||
server {
|
||||
project = project(":$forkNameLowercase-server")
|
||||
patchesDir = rootProject.projectDir.resolve("patches/server")
|
||||
}
|
||||
api {
|
||||
project = project(":$forkNameLowercase-api")
|
||||
patchesDir = rootProject.projectDir.resolve("patches/api")
|
||||
maven("https://maven.quiltmc.org/repository/release/") {
|
||||
content {
|
||||
onlyForConfigurations("remapper")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.lifecycle("Configured version string: $calcVersionString")
|
||||
dependencies {
|
||||
remapper("org.quiltmc:tiny-remapper:0.4.1")
|
||||
paperclip("io.papermc:paperclip:2.0.0-SNAPSHOT@jar")
|
||||
}
|
||||
|
||||
subprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.aikar.co/content/groups/aikar/")
|
||||
maven("https://nexus.velocitypowered.com/repository/velocity-artifacts-snapshots/")
|
||||
maven("https://libraries.minecraft.net")
|
||||
maven("https://repo.codemc.io/repository/maven-public/")
|
||||
maven("https://jitpack.io")
|
||||
mavenLocal()
|
||||
maven("${rootProjectDir}/.repository")
|
||||
}
|
||||
apply(plugin = "java")
|
||||
|
||||
java {
|
||||
if(JavaVersion.VERSION_1_8 > JavaVersion.current()){
|
||||
error("This build must be run with Java 8 or better")
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(16))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.release.set(16)
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://oss.sonatype.org/content/groups/public/")
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://ci.emc.gs/nexus/content/groups/aikar/")
|
||||
maven("https://repo.aikar.co/content/groups/aikar")
|
||||
maven("https://repo.md-5.net/content/repositories/releases/")
|
||||
maven("https://hub.spigotmc.org/nexus/content/groups/public/")
|
||||
maven("https://nexus.velocitypowered.com/repository/velocity-artifacts-snapshots/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
}
|
||||
}
|
||||
paperweight {
|
||||
serverProject.set(project(":Yatopia-Server"))
|
||||
|
||||
usePaperUpstream(providers.gradleProperty("paperCommit")) {
|
||||
withPaperPatcher {
|
||||
apiPatchDir.set(layout.projectDirectory.dir("patches/api"))
|
||||
apiOutputDir.set(layout.projectDirectory.dir("Yatopia-API"))
|
||||
|
||||
serverPatchDir.set(layout.projectDirectory.dir("patches/server"))
|
||||
serverOutputDir.set(layout.projectDirectory.dir("Yatopia-Server"))
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.current()
|
||||
withSourcesJar()
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
val kotlinxDomVersion = "0.0.10"
|
||||
val shadowVersion = "7.0.0"
|
||||
val mustacheVersion = "0.9.6"
|
||||
val javaxMailVersion = "1.4.4"
|
||||
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://plugins.gradle.org/m2/")
|
||||
maven("https://jitpack.io/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlinx:kotlinx.dom:$kotlinxDomVersion")
|
||||
implementation("com.github.johnrengelman:shadow:$shadowVersion")
|
||||
implementation("com.github.spullara.mustache.java:compiler:$mustacheVersion")
|
||||
implementation("javax.mail:mail:$javaxMailVersion")
|
||||
implementation("com.github.ishlandbukkit:jbsdiff:deff66b794")
|
||||
implementation("com.google.code.gson:gson:2.8.6")
|
||||
implementation("com.google.guava:guava:30.0-jre")
|
||||
implementation("commons-io:commons-io:2.8.0")
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
sourceCompatibility = "1.8"
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
register("Toothpick") {
|
||||
id = "toothpick"
|
||||
implementationClass = "Toothpick"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2021 Jason Penilla & Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,269 +0,0 @@
|
||||
package org.yatopiamc.yatoclip.gradle;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.gson.Gson;
|
||||
import io.sigpipe.jbsdiff.Diff;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.internal.project.ProjectInternal;
|
||||
import org.gradle.api.tasks.Copy;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.internal.logging.progress.ProgressLogger;
|
||||
import org.gradle.internal.logging.progress.ProgressLoggerFactory;
|
||||
import org.gradle.work.Incremental;
|
||||
import org.gradle.workers.WorkerExecutor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class MakePatchesTask extends DefaultTask {
|
||||
|
||||
@OutputDirectory
|
||||
private final File outputDir = ((Copy) getProject().getTasks().getByPath("processResources")).getDestinationDir().toPath().resolve("patches").toFile();
|
||||
|
||||
@InputFile
|
||||
@Incremental
|
||||
public File originalJar = null;
|
||||
@InputFile
|
||||
@Incremental
|
||||
public File targetJar = null;
|
||||
|
||||
public Set<PatchesMetadata.Relocation> getRelocations() {
|
||||
return relocations;
|
||||
}
|
||||
|
||||
public void setRelocations(Set<PatchesMetadata.Relocation> relocations) {
|
||||
this.relocations = relocations;
|
||||
}
|
||||
|
||||
@Input
|
||||
public Set<PatchesMetadata.Relocation> relocations;
|
||||
|
||||
public File getOriginalJar() {
|
||||
return originalJar;
|
||||
}
|
||||
|
||||
public void setOriginalJar(File originalJar) {
|
||||
this.originalJar = originalJar;
|
||||
}
|
||||
|
||||
public File getTargetJar() {
|
||||
return targetJar;
|
||||
}
|
||||
|
||||
public void setTargetJar(File targetJar) {
|
||||
this.targetJar = targetJar;
|
||||
}
|
||||
|
||||
public File getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
private ProgressLoggerFactory getProgressLoggerFactory() {
|
||||
return ((ProjectInternal) getProject()).getServices().get(ProgressLoggerFactory.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public WorkerExecutor getWorkerExecutor() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void genPatches() throws IOException, InterruptedException {
|
||||
Preconditions.checkNotNull(originalJar);
|
||||
Preconditions.checkNotNull(targetJar);
|
||||
getLogger().lifecycle("Generating patches for " + originalJar + " -> " + targetJar);
|
||||
|
||||
final ProgressLogger genPatches = getProgressLoggerFactory().newOperation(getClass()).setDescription("Generate patches");
|
||||
genPatches.started();
|
||||
|
||||
genPatches.progress("Cleanup");
|
||||
outputDir.mkdirs();
|
||||
FileUtils.cleanDirectory(outputDir);
|
||||
|
||||
genPatches.progress("Reading files");
|
||||
ThreadLocal<ZipFile> originalZip = ThreadLocal.withInitial(() -> {
|
||||
try {
|
||||
return new ZipFile(originalJar);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
ThreadLocal<ZipFile> targetZip = ThreadLocal.withInitial(() -> {
|
||||
try {
|
||||
return new ZipFile(targetJar);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
Set<PatchesMetadata.PatchMetadata> patchMetadata = Sets.newConcurrentHashSet();
|
||||
ThreadLocal<MessageDigest> digestThreadLocal = ThreadLocal.withInitial(() -> {
|
||||
try {
|
||||
return MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
ThreadLocal<ProgressLogger> progressLoggerThreadLocal = ThreadLocal.withInitial(() -> {
|
||||
final ProgressLogger progressLogger = getProgressLoggerFactory().newOperation(this.getClass());
|
||||
progressLogger.setDescription("Patch worker");
|
||||
progressLogger.started("Idle");
|
||||
return progressLogger;
|
||||
});
|
||||
final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(),
|
||||
new ThreadFactoryBuilder().setNameFormat("MakePatches-%d").setThreadFactory(r -> new Thread(() -> {
|
||||
boolean isExceptionOccurred = false;
|
||||
try {
|
||||
r.run();
|
||||
} catch (Throwable t) {
|
||||
isExceptionOccurred = true;
|
||||
progressLoggerThreadLocal.get().completed(t.toString(), true);
|
||||
throw t;
|
||||
} finally {
|
||||
digestThreadLocal.remove();
|
||||
if (!isExceptionOccurred)
|
||||
progressLoggerThreadLocal.get().completed();
|
||||
progressLoggerThreadLocal.remove();
|
||||
try {
|
||||
originalZip.get().close();
|
||||
targetZip.get().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
})).build());
|
||||
AtomicInteger current = new AtomicInteger(0);
|
||||
final int size = targetZip.get().size();
|
||||
((Iterator<ZipEntry>) targetZip.get().entries()).forEachRemaining(zipEntryT -> {
|
||||
genPatches.progress("Submitting tasks (" + current.incrementAndGet() + "/" + size + ")");
|
||||
if (zipEntryT.isDirectory()) return;
|
||||
executorService.execute(() -> {
|
||||
ZipEntry zipEntry = targetZip.get().getEntry(zipEntryT.getName());
|
||||
final String child = zipEntry.getName();
|
||||
progressLoggerThreadLocal.get().progress("Reading " + zipEntry.getName());
|
||||
File outputFile = new File(outputDir, child + ".patch");
|
||||
outputFile.getParentFile().mkdirs();
|
||||
final byte[] originalBytes;
|
||||
final byte[] targetBytes;
|
||||
final ZipEntry oEntry = originalZip.get().getEntry(applyRelocationsReverse(child));
|
||||
try (
|
||||
final InputStream oin = oEntry != null ? originalZip.get().getInputStream(oEntry) : null;
|
||||
final InputStream tin = targetZip.get().getInputStream(zipEntry);
|
||||
) {
|
||||
originalBytes = oin != null ? IOUtils.toByteArray(oin) : new byte[0];
|
||||
targetBytes = IOUtils.toByteArray(tin);
|
||||
} catch (Throwable e) {
|
||||
Throwables.throwIfUnchecked(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (Arrays.equals(originalBytes, targetBytes)) return;
|
||||
|
||||
progressLoggerThreadLocal.get().progress("GenPatch " + zipEntry.getName());
|
||||
try (final OutputStream out = new FileOutputStream(outputFile)) {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
Diff.diff(originalBytes, targetBytes, byteArrayOutputStream);
|
||||
patchMetadata.add(new PatchesMetadata.PatchMetadata(child, toHex(digestThreadLocal.get().digest(originalBytes)), toHex(digestThreadLocal.get().digest(targetBytes)), toHex(digestThreadLocal.get().digest(byteArrayOutputStream.toByteArray()))));
|
||||
out.write(byteArrayOutputStream.toByteArray());
|
||||
} catch (Throwable t) {
|
||||
Throwables.throwIfUnchecked(t);
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
|
||||
progressLoggerThreadLocal.get().progress("Idle");
|
||||
});
|
||||
});
|
||||
genPatches.progress("Calculating exclusions");
|
||||
Set<String> copyExcludes = new HashSet<>();
|
||||
((Iterator<ZipEntry>) originalZip.get().entries()).forEachRemaining(zipEntry -> {
|
||||
if(targetZip.get().getEntry(applyRelocations(zipEntry.getName())) == null)
|
||||
copyExcludes.add(zipEntry.getName());
|
||||
});
|
||||
originalZip.get().close();
|
||||
targetZip.get().close();
|
||||
|
||||
genPatches.progress("Waiting for patching to finish");
|
||||
executorService.shutdown();
|
||||
while (!executorService.awaitTermination(1, TimeUnit.SECONDS)) ;
|
||||
digestThreadLocal.remove();
|
||||
|
||||
genPatches.progress("Writing patches metadata");
|
||||
try (final OutputStream out = new FileOutputStream(new File(outputDir, "metadata.json"));
|
||||
final Writer writer = new OutputStreamWriter(out)) {
|
||||
new Gson().toJson(new PatchesMetadata(patchMetadata, relocations, copyExcludes), writer);
|
||||
}
|
||||
|
||||
/*
|
||||
genPatches.progress("Reading jar files into memory");
|
||||
byte[] origin = Files.readAllBytes(originalJar.toPath());
|
||||
byte[] target = Files.readAllBytes(targetJar.toPath());
|
||||
|
||||
genPatches.progress("Generating patch");
|
||||
try(final OutputStream out = new BufferedOutputStream(new FileOutputStream(output))){
|
||||
Diff.diff(origin, target, out);
|
||||
}
|
||||
*/
|
||||
|
||||
genPatches.completed();
|
||||
|
||||
}
|
||||
|
||||
private String applyRelocations(String name) {
|
||||
if(!name.endsWith(".class")) return name;
|
||||
if (name.indexOf('/') == -1)
|
||||
name = "/" + name;
|
||||
for (PatchesMetadata.Relocation relocation : relocations) {
|
||||
if (name.startsWith(relocation.from) && (relocation.includeSubPackages || name.split("/").length == name.split("/").length - 1)) {
|
||||
return relocation.to + name.substring(relocation.from.length());
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private String applyRelocationsReverse(String name) {
|
||||
if(!name.endsWith(".class")) return name;
|
||||
if (name.indexOf('/') == -1)
|
||||
name = "/" + name;
|
||||
for (PatchesMetadata.Relocation relocation : relocations) {
|
||||
if (name.startsWith(relocation.to) && (relocation.includeSubPackages || name.split("/").length == name.split("/").length - 1)) {
|
||||
return relocation.from + name.substring(relocation.to.length());
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String toHex(final byte[] hash) {
|
||||
final StringBuilder sb = new StringBuilder(hash.length * 2);
|
||||
for (byte aHash : hash) {
|
||||
sb.append(String.format("%02X", aHash & 0xFF));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package org.yatopiamc.yatoclip.gradle;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class PatchesMetadata {
|
||||
|
||||
public final Set<PatchMetadata> patches;
|
||||
public final Set<Relocation> relocations;
|
||||
public final Set<String> copyExcludes;
|
||||
|
||||
public PatchesMetadata(Set<PatchMetadata> patches, Set<Relocation> relocations, Set<String> copyExcludes) {
|
||||
Objects.requireNonNull(copyExcludes);
|
||||
this.copyExcludes = Collections.unmodifiableSet(copyExcludes);
|
||||
Objects.requireNonNull(relocations);
|
||||
this.relocations = Collections.unmodifiableSet(relocations);
|
||||
Objects.requireNonNull(patches);
|
||||
this.patches = Collections.unmodifiableSet(patches);
|
||||
}
|
||||
|
||||
public static class PatchMetadata {
|
||||
public final String name;
|
||||
public final String originalHash;
|
||||
public final String targetHash;
|
||||
public final String patchHash;
|
||||
|
||||
public PatchMetadata(String name, String originalHash, String targetHash, String patchHash) {
|
||||
this.name = name;
|
||||
this.originalHash = originalHash;
|
||||
this.targetHash = targetHash;
|
||||
this.patchHash = patchHash;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Relocation implements Serializable {
|
||||
|
||||
public final String from;
|
||||
public final String to;
|
||||
public final boolean includeSubPackages;
|
||||
|
||||
public Relocation(String from, String to, boolean includeSubPackages) {
|
||||
Objects.requireNonNull(from);
|
||||
Objects.requireNonNull(to);
|
||||
this.from = from.replaceAll("\\.", "/");
|
||||
this.to = to.replaceAll("\\.", "/");
|
||||
this.includeSubPackages = includeSubPackages;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package org.yatopiamc.yatoclip.gradle;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Properties;
|
||||
|
||||
public class PropertiesUtils {
|
||||
|
||||
public static void saveProperties(Properties prop, Path file, String comments){
|
||||
System.out.println("Saving properties file to " + file);
|
||||
file.toFile().getParentFile().mkdirs();
|
||||
file.toFile().delete();
|
||||
try(final OutputStream out = new FileOutputStream(file.toFile())) {
|
||||
prop.store(out, comments);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,253 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
// import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer
|
||||
import transformer.ModifiedLog4j2PluginsCacheFileTransformer
|
||||
import relocation.ToothpickRelocator
|
||||
import kotlinx.dom.elements
|
||||
import kotlinx.dom.search
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.UnknownDomainObjectException
|
||||
import org.gradle.api.plugins.JavaLibraryPlugin
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.yatopiamc.yatoclip.gradle.MakePatchesTask
|
||||
import org.yatopiamc.yatoclip.gradle.PatchesMetadata
|
||||
import org.yatopiamc.yatoclip.gradle.PropertiesUtils
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
internal fun Project.configureSubprojects() {
|
||||
subprojects {
|
||||
apply<JavaLibraryPlugin>()
|
||||
apply<MavenPublishPlugin>()
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = UTF_8.name()
|
||||
}
|
||||
tasks.withType<Javadoc> {
|
||||
options.encoding = UTF_8.name()
|
||||
}
|
||||
|
||||
extensions.configure<PublishingExtension> {
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
groupId = rootProject.group as String
|
||||
version = rootProject.version as String
|
||||
pom {
|
||||
name.set(project.name)
|
||||
url.set(toothpick.forkUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when {
|
||||
project.name.endsWith("server") -> configureServerProject()
|
||||
project.name.endsWith("api") -> configureApiProject()
|
||||
}
|
||||
}
|
||||
rootProject.project("Yatoclip") {
|
||||
configureYatoclipProject()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.configureYatoclipProject() {
|
||||
try {
|
||||
rootProject.toothpick.serverProject.project.extensions.getByName("relocations")
|
||||
} catch (e: UnknownDomainObjectException) {
|
||||
return
|
||||
}
|
||||
|
||||
apply<JavaLibraryPlugin>()
|
||||
apply<ShadowPlugin>()
|
||||
|
||||
tasks.register<MakePatchesTask>("genPatches") {
|
||||
originalJar = rootProject.toothpick.paperDir.resolve("work").resolve("Minecraft")
|
||||
.resolve(rootProject.toothpick.minecraftVersion).resolve("${rootProject.toothpick.minecraftVersion}-m.jar")
|
||||
targetJar = rootProject.toothpick.serverProject.project.tasks.getByName("shadowJar").outputs.files.singleFile
|
||||
setRelocations(rootProject.toothpick.serverProject.project.extensions.getByName("relocations") as HashSet<PatchesMetadata.Relocation>)
|
||||
dependsOn(rootProject.toothpick.serverProject.project.tasks.getByName("shadowJar"))
|
||||
doLast {
|
||||
val prop = Properties()
|
||||
prop.setProperty("minecraftVersion", rootProject.toothpick.minecraftVersion)
|
||||
PropertiesUtils.saveProperties(
|
||||
prop,
|
||||
outputDir.toPath().parent.resolve("yatoclip-launch.properties"),
|
||||
"Yatoclip launch values"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val sourceSets = extensions.getByName("sourceSets") as org.gradle.api.tasks.SourceSetContainer
|
||||
|
||||
sourceSets.create("java9") {
|
||||
java {
|
||||
srcDir("src/java9")
|
||||
}
|
||||
}
|
||||
|
||||
val shadowJar by tasks.getting(ShadowJar::class) {
|
||||
manifest {
|
||||
attributes(
|
||||
"Main-Class" to "org.yatopiamc.yatoclip.Yatoclip",
|
||||
"Launcher-Agent-Class" to "org.yatopiamc.yatoclip.YatoclipLaunch",
|
||||
"Premain-Class" to "org.yatopiamc.yatoclip.YatoclipLaunch",
|
||||
"Multi-Release" to "true"
|
||||
)
|
||||
}
|
||||
into("META-INF/versions/9") {
|
||||
from(sourceSets.getByName("java9").output)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<Copy>("copyJar") {
|
||||
val targetName = "yatopia-${rootProject.toothpick.minecraftVersion}-yatoclip.jar"
|
||||
from(shadowJar.outputs.files.singleFile) {
|
||||
rename { targetName }
|
||||
}
|
||||
|
||||
into(rootProject.projectDir)
|
||||
|
||||
doLast {
|
||||
logger.lifecycle(">>> $targetName saved to root project directory")
|
||||
}
|
||||
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
|
||||
tasks.getByName("processResources").dependsOn(tasks.getByName("genPatches"))
|
||||
tasks.getByName("assemble").dependsOn(tasks.getByName("copyJar"))
|
||||
tasks.getByName("jar").enabled = false
|
||||
val buildTask = tasks.getByName("build")
|
||||
val buildTaskDependencies = HashSet(buildTask.dependsOn)
|
||||
buildTask.setDependsOn(HashSet<Task>())
|
||||
buildTask.onlyIf { false }
|
||||
tasks.register("yatoclip") {
|
||||
buildTaskDependencies.forEach {
|
||||
dependsOn(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.configureServerProject() {
|
||||
apply<ShadowPlugin>()
|
||||
|
||||
val generatePomFileForMavenJavaPublication by tasks.getting(GenerateMavenPom::class) {
|
||||
destination = project.buildDir.resolve("tmp/pom.xml")
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
// didn't bother to look into why these fail. paper excludes them in paperweight as well though
|
||||
exclude("org/bukkit/craftbukkit/inventory/ItemStack*Test.class")
|
||||
}
|
||||
|
||||
val shadowJar by tasks.getting(ShadowJar::class) {
|
||||
archiveClassifier.set("") // ShadowJar is the main server artifact
|
||||
dependsOn(generatePomFileForMavenJavaPublication)
|
||||
transform(ModifiedLog4j2PluginsCacheFileTransformer::class.java)
|
||||
mergeServiceFiles()
|
||||
manifest {
|
||||
attributes(
|
||||
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||
"Implementation-Title" to "CraftBukkit",
|
||||
"Implementation-Version" to toothpick.forkVersion,
|
||||
"Implementation-Vendor" to SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(Date()),
|
||||
"Specification-Title" to "Bukkit",
|
||||
"Specification-Version" to "${project.rootProject.toothpick.minecraftVersion}-${project.rootProject.toothpick.nmsRevision}",
|
||||
"Specification-Vendor" to "Bukkit Team"
|
||||
)
|
||||
}
|
||||
from(project.buildDir.resolve("tmp/pom.xml")) {
|
||||
// dirty hack to make "java -Dpaperclip.install=true -jar paperclip.jar" work without forking paperclip
|
||||
into("META-INF/maven/io.papermc.paper/paper")
|
||||
}
|
||||
|
||||
val relocationSet = HashSet<PatchesMetadata.Relocation>()
|
||||
|
||||
// Don't like to do this but sadly have to do this for compatibility reasons
|
||||
relocate("org.bukkit.craftbukkit", "org.bukkit.craftbukkit.v${toothpick.nmsPackage}") {
|
||||
exclude("org.bukkit.craftbukkit.Main*")
|
||||
}
|
||||
relocationSet.add(PatchesMetadata.Relocation("", "net.minecraft.server.v${toothpick.nmsPackage}", false))
|
||||
|
||||
// Make sure we relocate deps the same as Paper et al.
|
||||
val dom = project.parsePom() ?: return@getting
|
||||
val buildSection = dom.search("build").first()
|
||||
val plugins = buildSection.search("plugins").first()
|
||||
plugins.elements("plugin").filter {
|
||||
val artifactId = it.search("artifactId").first().textContent
|
||||
artifactId == "maven-shade-plugin"
|
||||
}.forEach {
|
||||
it.search("executions").first()
|
||||
.search("execution").first()
|
||||
.search("configuration").first()
|
||||
.search("relocations").first()
|
||||
.elements("relocation").forEach { relocation ->
|
||||
val pattern = relocation.search("pattern").first().textContent
|
||||
val shadedPattern = relocation.search("shadedPattern").first().textContent
|
||||
val rawString = relocation.search("rawString").firstOrNull()?.textContent?.toBoolean() ?: false
|
||||
if (pattern != "org.bukkit.craftbukkit") { // We handle cb ourselves
|
||||
val excludes = if (rawString) listOf("net/minecraft/data/Main*") else emptyList()
|
||||
relocate(
|
||||
ToothpickRelocator(
|
||||
pattern,
|
||||
shadedPattern.replace("\${minecraft_version}", toothpick.nmsPackage),
|
||||
rawString,
|
||||
excludes = excludes
|
||||
)
|
||||
)
|
||||
relocationSet.add(PatchesMetadata.Relocation(pattern, shadedPattern, true))
|
||||
}
|
||||
}
|
||||
}
|
||||
project.extensions.add("relocations", relocationSet)
|
||||
}
|
||||
tasks.getByName("build") {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
|
||||
extensions.configure<PublishingExtension> {
|
||||
publications {
|
||||
create<MavenPublication>("shadow") {
|
||||
artifact(project.tasks.named("shadowJar"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
private fun Project.configureApiProject() {
|
||||
val jar by this.tasks.getting(Jar::class) {
|
||||
doFirst {
|
||||
buildDir.resolve("tmp/pom.properties")
|
||||
.writeText("version=${project.rootProject.toothpick.minecraftVersion}-${project.rootProject.toothpick.nmsRevision}")
|
||||
}
|
||||
from(buildDir.resolve("tmp/pom.properties")) {
|
||||
into("META-INF/maven/${project.group}/${project.name}")
|
||||
}
|
||||
manifest {
|
||||
attributes("Automatic-Module-Name" to "org.bukkit")
|
||||
}
|
||||
}
|
||||
|
||||
extensions.configure<PublishingExtension> {
|
||||
publications {
|
||||
getByName<MavenPublication>("mavenJava") {
|
||||
artifactId = project.name
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
const val taskGroup = "toothpick"
|
||||
const val internalTaskGroup = "toothpick_internal"
|
@ -1,72 +0,0 @@
|
||||
import kotlinx.dom.elements
|
||||
import kotlinx.dom.search
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.dsl.RepositoryHandler
|
||||
import org.gradle.kotlin.dsl.DependencyHandlerScope
|
||||
import org.gradle.kotlin.dsl.maven
|
||||
import org.gradle.kotlin.dsl.project
|
||||
import org.w3c.dom.Element
|
||||
|
||||
fun RepositoryHandler.loadRepositories(project: Project) {
|
||||
val dom = project.parsePom() ?: return
|
||||
val repositoriesBlock = dom.search("repositories").firstOrNull() ?: return
|
||||
|
||||
// Load repositories
|
||||
repositoriesBlock.elements("repository").forEach { repositoryElem ->
|
||||
val url = repositoryElem.search("url").firstOrNull()?.textContent ?: return@forEach
|
||||
maven(url)
|
||||
}
|
||||
}
|
||||
|
||||
fun DependencyHandlerScope.loadDependencies(project: Project) {
|
||||
val dom = project.parsePom() ?: return
|
||||
|
||||
// Load dependencies
|
||||
dom.search("dependencies").forEach {
|
||||
loadDependencies(project, it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun DependencyHandlerScope.loadDependencies(project: Project, dependenciesBlock: Element) {
|
||||
dependenciesBlock.elements("dependency").forEach { dependencyElem ->
|
||||
val groupId = dependencyElem.search("groupId").first().textContent
|
||||
val artifactId = dependencyElem.search("artifactId").first().textContent
|
||||
val version = dependencyElem.search("version").firstOrNull()?.textContent
|
||||
val scope = dependencyElem.search("scope").firstOrNull()?.textContent
|
||||
val classifier = dependencyElem.search("classifier").firstOrNull()?.textContent
|
||||
|
||||
val dependencyString =
|
||||
"$groupId:$artifactId${processOptionalDependencyElement(version)}${processOptionalDependencyElement(classifier)}"
|
||||
project.logger.debug("Read $scope scope dependency '$dependencyString' from '${project.name}' pom.xml")
|
||||
|
||||
// Special case API
|
||||
if (artifactId == project.toothpick.apiProject.project.name
|
||||
|| artifactId == "${project.toothpick.upstreamLowercase}-api"
|
||||
) {
|
||||
if (project == project.toothpick.serverProject.project) {
|
||||
add("api", project(":${project.toothpick.forkNameLowercase}-api"))
|
||||
}
|
||||
return@forEach
|
||||
}
|
||||
|
||||
when (scope) {
|
||||
"import" -> add("api", platform(dependencyString))
|
||||
"compile", null -> {
|
||||
add("api", dependencyString)
|
||||
if (version != null) {
|
||||
add("annotationProcessor", dependencyString)
|
||||
}
|
||||
}
|
||||
"provided" -> {
|
||||
add("compileOnly", dependencyString)
|
||||
add("testImplementation", dependencyString)
|
||||
add("annotationProcessor", dependencyString)
|
||||
}
|
||||
"runtime" -> add("runtimeOnly", dependencyString)
|
||||
"test" -> add("testImplementation", dependencyString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processOptionalDependencyElement(element: String?): String =
|
||||
element?.run { ":$this" } ?: ""
|
@ -1,74 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
import task.*
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
internal fun Project.initToothpickTasks() {
|
||||
gradle.taskGraph.whenReady {
|
||||
val fast = project.hasProperty("fast")
|
||||
tasks.withType<Test> {
|
||||
onlyIf { !fast }
|
||||
}
|
||||
tasks.withType<Javadoc> {
|
||||
onlyIf { !fast || gradle.taskGraph.allTasks.any { it.name.contains("publish", ignoreCase = true) } }
|
||||
}
|
||||
}
|
||||
|
||||
tasks.getByName("build") {
|
||||
doFirst {
|
||||
val readyToBuild =
|
||||
upstreamDir.resolve(".git").exists()
|
||||
&& toothpick.subprojects.values.all { it.projectDir.exists() && it.baseDir.exists() }
|
||||
if (!readyToBuild) {
|
||||
error("Workspace has not been setup. Try running `./gradlew applyPatches` first")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val initGitSubmodules = createInitGitSubmodulesTask()
|
||||
|
||||
val setupUpstream = createSetupUpstreamTask {
|
||||
dependsOn(initGitSubmodules)
|
||||
}
|
||||
|
||||
val importMCDev = createImportMCDevTask {
|
||||
mustRunAfter(setupUpstream)
|
||||
}
|
||||
|
||||
val paperclip = createPaperclipTask {
|
||||
val shadowJar = toothpick.serverProject.project.tasks.getByName("shadowJar")
|
||||
dependsOn(shadowJar)
|
||||
inputs.file(shadowJar.outputs.files.singleFile)
|
||||
}
|
||||
|
||||
val applyPatches = createApplyPatchesTask {
|
||||
// If Paper has not been setup yet or if we modified the submodule (i.e. upstream update), patch
|
||||
if (!lastUpstream.exists()
|
||||
|| !upstreamDir.resolve(".git").exists()
|
||||
|| lastUpstream.readText() != gitHash(upstreamDir)
|
||||
) {
|
||||
dependsOn(setupUpstream)
|
||||
}
|
||||
mustRunAfter(setupUpstream)
|
||||
dependsOn(importMCDev)
|
||||
}
|
||||
|
||||
val patchCredits = createPatchCreditsTask()
|
||||
|
||||
val fixBranch = createFixBranchesTask()
|
||||
|
||||
val rebuildPatches = createRebuildPatchesTask {
|
||||
dependsOn(fixBranch)
|
||||
finalizedBy(patchCredits)
|
||||
}
|
||||
|
||||
val updateUpstream = createUpdateUpstreamTask {
|
||||
finalizedBy(setupUpstream)
|
||||
}
|
||||
|
||||
val upstreamCommit = createUpstreamCommitTask()
|
||||
|
||||
val repackageNMS = createRepackageNMSTask()
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/**
|
||||
* This is the set of extra NMS files which will be imported as part of the patch process
|
||||
*
|
||||
* See `./Paper/work/Minecraft/$MCVER/spigot/net/minecraft/server` for a list of possible files
|
||||
*
|
||||
* The `.java` extension is always assumed and should be excluded
|
||||
*
|
||||
* NOTE: Do not commit changes to this set! Instead make changes, rebuild patches, and commit the modified patches.
|
||||
* Files already modified in existing patches will be imported automatically.
|
||||
*/
|
||||
val nmsImports = setOf<String>(
|
||||
// ex:
|
||||
//"EntityZombieVillager"
|
||||
)
|
||||
|
||||
data class LibraryImport(val group: String, val library: String, val prefix: String, val file: String)
|
||||
|
||||
/**
|
||||
* This is the set of extra files to import into the server workspace from libraries
|
||||
*
|
||||
* Changes to this set should be committed to the repo, as these won't be automatically imported.
|
||||
*/
|
||||
val libraryImports = setOf<LibraryImport>(
|
||||
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier", "CommandDispatcher"),
|
||||
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/tree", "LiteralCommandNode"),
|
||||
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/suggestion", "SuggestionsBuilder"),
|
||||
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/arguments", "BoolArgumentType"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "FieldFinder"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "DataFixUtils"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "TypeRewriteRule"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "Typed"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "TypedOptic"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "View"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "Apply"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "Comp"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "PointFree"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "PointFreeRule"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "IdAdapter"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Inj1"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Inj2"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Optics"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Proj1"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Proj2"),
|
||||
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/types", "Type")
|
||||
)
|
@ -1,77 +0,0 @@
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import java.util.*
|
||||
import java.util.function.Function
|
||||
import javax.mail.internet.MimeUtility
|
||||
|
||||
/**
|
||||
* Rudimentary parser to get Author, subject and coAuthors of a patch file
|
||||
*
|
||||
* @author tr7zw
|
||||
*/
|
||||
object PatchParser {
|
||||
fun parsePatch(file: File): PatchInfo {
|
||||
val lines: List<String> = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)
|
||||
var from: String = "Unknown"
|
||||
var subject: String = "Unknown"
|
||||
val coAuthors: MutableList<String> = ArrayList()
|
||||
for (line: String in lines) {
|
||||
when {
|
||||
line.startsWith("From: ") -> {
|
||||
from =
|
||||
decodeStringIfNeeded(line.replace("From: ", "").split("<").toTypedArray()[0].trim { it <= ' ' })
|
||||
}
|
||||
line.startsWith("Subject: ") -> {
|
||||
subject = line.replace("Subject: ", "").replace("[PATCH]", "").trim { it <= ' ' }
|
||||
}
|
||||
line.startsWith("Co-authored-by: ") -> {
|
||||
coAuthors.add(
|
||||
decodeStringIfNeeded(
|
||||
line.replace("Co-authored-by: ", "").split("<").toTypedArray()[0].trim { it <= ' ' })
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return PatchInfo(file.parentFile.name, from, subject, coAuthors)
|
||||
}
|
||||
|
||||
private fun decodeStringIfNeeded(org: String): String {
|
||||
if (org.contains("=") || org.startsWith("=?UTF-8")) {
|
||||
try {
|
||||
return MimeUtility.decodeText(org)
|
||||
} catch (ex: UnsupportedEncodingException) {
|
||||
throw IOException(ex)
|
||||
}
|
||||
}
|
||||
return org
|
||||
}
|
||||
|
||||
class PatchInfo(val parent: String, val from: String, val subject: String, val coAuthors: List<String>) {
|
||||
val coAuthorString: Function<String, String>
|
||||
get() = Function {
|
||||
java.lang.String.join(
|
||||
", ",
|
||||
coAuthors
|
||||
)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return ("PatchInfo{"
|
||||
+ "parent='"
|
||||
+ parent
|
||||
+ '\''
|
||||
+ ", from='"
|
||||
+ from
|
||||
+ '\''
|
||||
+ ", subject='"
|
||||
+ subject
|
||||
+ '\''
|
||||
+ ", coAuthors="
|
||||
+ coAuthors
|
||||
+ '}')
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* This file is part of Toothpick, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) 2020-2021 Jason Penilla & Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import kotlinx.dom.elements
|
||||
import kotlinx.dom.parseXml
|
||||
import kotlinx.dom.search
|
||||
import org.gradle.api.Project
|
||||
import org.w3c.dom.Document
|
||||
|
||||
internal fun Project.parsePom(): Document? {
|
||||
val file = file("pom.xml")
|
||||
if (!file.exists()) {
|
||||
return null
|
||||
}
|
||||
val contents = file.readText()
|
||||
val dom = parseXml(contents.byteInputStream())
|
||||
val properties = dom.search("properties").firstOrNull()?.elements() ?: emptyList()
|
||||
val propertiesMap = properties.associateBy({ it.nodeName }, { it.textContent }).toMutableMap()
|
||||
|
||||
propertiesMap["project.version"] = project.version.toString()
|
||||
propertiesMap["minecraft.version"] = toothpick.minecraftVersion
|
||||
propertiesMap["minecraft_version"] = toothpick.nmsPackage
|
||||
|
||||
return parseXml(contents.replaceProperties(propertiesMap).byteInputStream())
|
||||
}
|
||||
|
||||
private fun String.replaceProperties(
|
||||
properties: Map<String, String>
|
||||
): String {
|
||||
var result = this
|
||||
for ((key, value) in properties) {
|
||||
result = result.replace("\${$key}", value)
|
||||
}
|
||||
return result
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.create
|
||||
|
||||
class Toothpick : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.extensions.create<ToothpickExtension>("toothpick", project.objects)
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.*
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
open class ToothpickExtension(objects: ObjectFactory) {
|
||||
lateinit var project: Project
|
||||
lateinit var forkName: String
|
||||
val forkNameLowercase
|
||||
get() = forkName.toLowerCase(Locale.ENGLISH)
|
||||
lateinit var forkUrl: String
|
||||
lateinit var forkVersion: String
|
||||
lateinit var groupId: String
|
||||
lateinit var minecraftVersion: String
|
||||
lateinit var nmsRevision: String
|
||||
lateinit var nmsPackage: String
|
||||
|
||||
lateinit var upstream: String
|
||||
val upstreamLowercase
|
||||
get() = upstream.toLowerCase(Locale.ENGLISH)
|
||||
var upstreamBranch: String = "origin/master"
|
||||
|
||||
var paperclipName: String? = null
|
||||
val calcPaperclipName
|
||||
get() = paperclipName ?: "${forkNameLowercase}-paperclip.jar"
|
||||
|
||||
lateinit var serverProject: ToothpickSubproject
|
||||
|
||||
lateinit var patchCreditsOutput: String
|
||||
lateinit var patchCreditsTemplate: String
|
||||
|
||||
lateinit var currentBranch : String
|
||||
val currentBranchDisplayName
|
||||
get() = currentBranch.replace("/${minecraftVersion}", "")
|
||||
val calcVersionString
|
||||
get() = "${minecraftVersion}-${nmsRevision}"
|
||||
|
||||
fun server(receiver: ToothpickSubproject.() -> Unit) {
|
||||
serverProject = ToothpickSubproject()
|
||||
receiver(serverProject)
|
||||
}
|
||||
|
||||
lateinit var apiProject: ToothpickSubproject
|
||||
fun api(receiver: ToothpickSubproject.() -> Unit) {
|
||||
apiProject = ToothpickSubproject()
|
||||
receiver(apiProject)
|
||||
}
|
||||
|
||||
val subprojects: Map<String, ToothpickSubproject>
|
||||
get() = if (::forkName.isInitialized) mapOf(
|
||||
"$forkName-API" to apiProject,
|
||||
"$forkName-Server" to serverProject
|
||||
) else emptyMap()
|
||||
|
||||
val paperDir: File by lazy {
|
||||
if (upstream == "Paper") {
|
||||
project.upstreamDir
|
||||
} else {
|
||||
project.upstreamDir.walk().find {
|
||||
it.name == "Paper" && it.isDirectory
|
||||
&& it.resolve("work/Minecraft/${minecraftVersion}").exists()
|
||||
} ?: error("Failed to find Paper directory!")
|
||||
}
|
||||
}
|
||||
|
||||
val paperDecompDir: File
|
||||
get() = paperDir.resolve("work/Minecraft/${minecraftVersion}")
|
||||
|
||||
val paperWorkDir: File
|
||||
get() = paperDir.resolve("work")
|
||||
|
||||
fun getUpstreams(rootProjectDir: File): MutableList<Upstream>? {
|
||||
val configDir = rootProjectDir.resolve("$rootProjectDir/upstreamConfig")
|
||||
val upstreams = configDir.listFiles()
|
||||
val upstreamArray = ArrayList<Upstream>()
|
||||
val prop = Properties()
|
||||
for (upstream in upstreams) {
|
||||
prop.load(FileInputStream(upstream))
|
||||
upstreamArray.add(Upstream(prop.getProperty("name"),
|
||||
prop.getProperty("useBlackList")!!.toBoolean(),
|
||||
(prop.getProperty("list")),
|
||||
rootProjectDir,
|
||||
prop.getProperty("branch"),
|
||||
Integer.parseInt(upstream.name.substring(0,4)),
|
||||
project))
|
||||
}
|
||||
return upstreamArray.stream().sorted { upstream1, upstream2 -> upstream1.id - upstream2.id}.collect(Collectors.toList())
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.findByType
|
||||
import java.io.File
|
||||
|
||||
val Project.toothpick: ToothpickExtension
|
||||
get() = rootProject.extensions.findByType(ToothpickExtension::class)!!
|
||||
|
||||
fun Project.toothpick(receiver: ToothpickExtension.() -> Unit) {
|
||||
toothpick.project = this
|
||||
receiver(toothpick)
|
||||
allprojects {
|
||||
group = toothpick.groupId
|
||||
version = toothpick.calcVersionString
|
||||
}
|
||||
configureSubprojects()
|
||||
initToothpickTasks()
|
||||
}
|
||||
|
||||
val Project.lastUpstream: File
|
||||
get() = rootProject.projectDir.resolve("last-${toothpick.upstreamLowercase}")
|
||||
|
||||
val Project.rootProjectDir: File
|
||||
get() = rootProject.projectDir
|
||||
|
||||
val Project.upstreamDir: File
|
||||
get() = rootProject.projectDir.resolve(toothpick.upstream)
|
||||
|
||||
val Project.upstream: String
|
||||
get() = toothpick.upstream
|
||||
|
||||
val Project.upstreams: MutableList<Upstream>
|
||||
get() = toothpick.getUpstreams(rootProject.projectDir) as MutableList<Upstream>
|
||||
|
||||
val Project.forkName: String
|
||||
get() = toothpick.forkName
|
||||
|
||||
val Project.patchCreditsOutput: String
|
||||
get() = toothpick.patchCreditsOutput
|
||||
|
||||
val Project.patchCreditsTemplate: String
|
||||
get() = toothpick.patchCreditsTemplate
|
@ -1,20 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import java.io.File
|
||||
|
||||
class ToothpickSubproject {
|
||||
lateinit var project: Project
|
||||
|
||||
val baseDir: File by lazy {
|
||||
val name = project.name
|
||||
val upstream = project.toothpick.upstream
|
||||
val suffix = if (name.endsWith("server")) "Server" else "API"
|
||||
project.upstreamDir.resolve("$upstream-$suffix")
|
||||
}
|
||||
val projectDir: File
|
||||
get() = project.projectDir
|
||||
lateinit var patchesDir: File
|
||||
|
||||
operator fun component1(): File = baseDir
|
||||
operator fun component2(): File = projectDir
|
||||
operator fun component3(): File = patchesDir
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.util.stream.Collectors
|
||||
|
||||
open class Upstream(in_name: String, in_useBlackList: Boolean, in_list: String, in_rootProjectDir: File, in_branch: String, in_id: Int, in_project: Project) {
|
||||
var name: String = in_name
|
||||
var useBlackList: Boolean = in_useBlackList
|
||||
private var list: ArrayList<String> = ArrayList(in_list.split(",".toRegex()))
|
||||
private var rootProjectDir: File = in_rootProjectDir
|
||||
var branch = in_branch
|
||||
var id = in_id
|
||||
|
||||
var serverList = list.stream().filter { patch -> patch.startsWith("server/") }
|
||||
?.sorted()?.map { patch -> patch.substring(7, patch.length) }?.collect(Collectors.toList())
|
||||
var apiList = list.stream().filter { patch -> patch.startsWith("api/") }
|
||||
?.sorted()?.map { patch -> patch.substring(4, patch.length) }?.collect(Collectors.toList())
|
||||
|
||||
|
||||
var patchPath = Paths.get("$rootProjectDir/patches/$name/patches")
|
||||
var repoPath = Paths.get("$rootProjectDir/upstream/$name")
|
||||
|
||||
var project = in_project
|
||||
|
||||
var upstreamCommit = getUpstreamCommitHash()
|
||||
|
||||
private fun getUpstreamCommitHash(): String {
|
||||
val commitFileFolder = Paths.get("$rootProjectDir/upstreamCommits")
|
||||
val commitFilePath = Paths.get("$commitFileFolder/$name")
|
||||
val commitFile = commitFilePath.toFile()
|
||||
var commitHash: String
|
||||
if (commitFile.isFile) {
|
||||
commitHash = Files.readAllLines(commitFilePath).toString()
|
||||
commitHash = commitHash.substring(1, commitHash.length - 1)
|
||||
if (commitHash == "") {
|
||||
commitHash = updateHashFile(commitFile)
|
||||
}
|
||||
} else {
|
||||
Files.createFile(commitFilePath)
|
||||
commitHash = updateHashFile(commitFile)
|
||||
}
|
||||
return commitHash;
|
||||
}
|
||||
|
||||
public fun updateUpstreamCommitHash() {
|
||||
val commitFileFoler = Paths.get("$rootProjectDir/upstreamCommits")
|
||||
val commitFilePath = Paths.get("$commitFileFoler/$name")
|
||||
val commitFile = commitFilePath.toFile()
|
||||
updateHashFile(commitFile)
|
||||
upstreamCommit = getUpstreamCommitHash()
|
||||
}
|
||||
|
||||
public fun getCurrentCommitHash(): String {
|
||||
return project.getCommitHash()
|
||||
}
|
||||
|
||||
private fun updateHashFile(commitFile: File): String {
|
||||
var commitHash: String
|
||||
commitHash = project.getCommitHash()
|
||||
val fileWriter = FileWriter(commitFile)
|
||||
fileWriter.use { out -> out.write(commitHash) }
|
||||
fileWriter.close()
|
||||
return commitHash
|
||||
}
|
||||
|
||||
private fun Project.getCommitHash(): String = gitHash(repo = repoPath.toFile())
|
||||
|
||||
public fun getRepoServerPatches(): MutableList<String>? {
|
||||
return getRepoPatches(rootProjectDir.resolve("$repoPath/patches/server")).stream()
|
||||
.sorted().map {patch -> patch.substring(5, patch.length) }.collect(Collectors.toList())
|
||||
}
|
||||
|
||||
public fun getRepoAPIPatches(): MutableList<String>? {
|
||||
return getRepoPatches(rootProjectDir.resolve("$repoPath/patches/api")).stream()
|
||||
.sorted().map {patch -> patch.substring(5, patch.length) }.collect(Collectors.toList())
|
||||
}
|
||||
|
||||
private fun getRepoPatches(path: File): ArrayList<String> {
|
||||
val files = path.listFiles()
|
||||
val filesList = ArrayList<String>()
|
||||
for (patch in files) {
|
||||
filesList.add(patch.name)
|
||||
}
|
||||
return filesList
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.streams.asSequence
|
||||
|
||||
data class CmdResult(val exitCode: Int, val output: String?)
|
||||
|
||||
fun Project.cmd(
|
||||
vararg args: String,
|
||||
dir: File = rootProject.projectDir,
|
||||
printOut: Boolean = false,
|
||||
environment: Map<String, String> = emptyMap()
|
||||
): CmdResult {
|
||||
val process = ProcessBuilder().apply {
|
||||
command(*args)
|
||||
redirectErrorStream(true)
|
||||
directory(dir)
|
||||
environment().putAll(environment)
|
||||
}.start()
|
||||
val output = process.inputStream.bufferedReader().use { reader ->
|
||||
reader.lines().asSequence()
|
||||
.onEach {
|
||||
if (printOut) {
|
||||
logger.lifecycle(it)
|
||||
} else {
|
||||
logger.debug(it)
|
||||
}
|
||||
}
|
||||
.toCollection(LinkedList())
|
||||
.joinToString(separator = "\n")
|
||||
}
|
||||
val exit = process.waitFor()
|
||||
return CmdResult(exit, output)
|
||||
}
|
||||
|
||||
fun ensureSuccess(
|
||||
cmd: CmdResult,
|
||||
errorHandler: CmdResult.() -> Unit = {}
|
||||
): String? {
|
||||
val (exit, output) = cmd
|
||||
if (exit != 0) {
|
||||
errorHandler(cmd)
|
||||
error("Failed to run command, exit code is $exit")
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
fun Project.gitCmd(
|
||||
vararg args: String,
|
||||
dir: File = rootProject.projectDir,
|
||||
printOut: Boolean = false,
|
||||
environment: Map<String, String> = emptyMap()
|
||||
): CmdResult =
|
||||
cmd("git", *args, dir = dir, printOut = printOut)
|
||||
|
||||
fun Project.bashCmd(
|
||||
vararg args: String,
|
||||
dir: File = rootProject.projectDir,
|
||||
printOut: Boolean = false,
|
||||
environment: Map<String, String> = emptyMap()
|
||||
): CmdResult =
|
||||
cmd("bash", "-c", *args, dir = dir, printOut = printOut)
|
||||
|
||||
internal fun String.applyReplacements(
|
||||
vararg replacements: Pair<String, String>
|
||||
): String {
|
||||
var result = this
|
||||
for ((key, value) in replacements) {
|
||||
result = result.replace("\${$key}", value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun Project.gitSigningEnabled(repo: File): Boolean =
|
||||
gitCmd("config", "commit.gpgsign", dir = repo).output?.toBoolean() == true
|
||||
|
||||
internal fun Project.temporarilyDisableGitSigning(repo: File): Boolean {
|
||||
val isCurrentlyEnabled = gitSigningEnabled(repo)
|
||||
if (isCurrentlyEnabled) {
|
||||
gitCmd("config", "commit.gpgsign", "false", dir = repo)
|
||||
}
|
||||
return isCurrentlyEnabled
|
||||
}
|
||||
|
||||
internal fun Project.reEnableGitSigning(repo: File) {
|
||||
gitCmd("config", "commit.gpgsign", "true", dir = repo)
|
||||
}
|
||||
|
||||
fun Project.gitHash(repo: File): String =
|
||||
gitCmd("rev-parse", "HEAD", dir = repo).output ?: ""
|
||||
|
||||
val jenkins = System.getenv("JOB_NAME") != null
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* This file is part of Toothpick, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) 2020-2021 Jason Penilla & Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package relocation
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
|
||||
import com.github.jengelman.gradle.plugins.shadow.relocation.SimpleRelocator
|
||||
import java.lang.reflect.Method
|
||||
import java.util.regex.Pattern
|
||||
|
||||
internal class ToothpickRelocator(
|
||||
pattern: String,
|
||||
shadedPattern: String,
|
||||
rawString: Boolean = false,
|
||||
includes: List<String> = emptyList(),
|
||||
excludes: List<String> = emptyList(),
|
||||
private val simpleRelocator: SimpleRelocator = SimpleRelocator(pattern, shadedPattern, includes, excludes, rawString)
|
||||
) : Relocator by simpleRelocator {
|
||||
override fun canRelocatePath(path: String): Boolean {
|
||||
// Respect includes/excludes for rawString too
|
||||
if (simpleRelocator.rawString) {
|
||||
return isIncludedMethod(simpleRelocator, path) as Boolean
|
||||
&& !(isExcludedMethod(simpleRelocator, path) as Boolean)
|
||||
&& Pattern.compile(simpleRelocator.pathPattern).matcher(path).find()
|
||||
}
|
||||
return simpleRelocator.canRelocatePath(path)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val isExcludedMethod: Method = SimpleRelocator::class.java.getDeclaredMethod("isExcluded", String::class.java)
|
||||
private val isIncludedMethod: Method = SimpleRelocator::class.java.getDeclaredMethod("isIncluded", String::class.java)
|
||||
|
||||
init {
|
||||
isExcludedMethod.isAccessible = true
|
||||
isIncludedMethod.isAccessible = true
|
||||
}
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package task
|
||||
|
||||
import ensureSuccess
|
||||
import forkName
|
||||
import gitCmd
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import reEnableGitSigning
|
||||
import taskGroup
|
||||
import temporarilyDisableGitSigning
|
||||
import toothpick
|
||||
import upstreams
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
internal fun Project.createApplyPatchesTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("applyPatches") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
|
||||
fun checkCursed(project: Project): Boolean {
|
||||
return project.properties.getOrDefault("cursed", "false").toString().toBoolean()
|
||||
}
|
||||
|
||||
fun applyPatches(patchDir: Path, applyName: String, name: String, wasGitSigningEnabled: Boolean, projectDir: File): Boolean {
|
||||
if (Files.notExists(patchDir)) return true
|
||||
|
||||
val patchPaths = Files.newDirectoryStream(patchDir)
|
||||
.map { it.toFile() }
|
||||
.filter { it.name.endsWith(".patch") }
|
||||
.sorted()
|
||||
.takeIf { it.isNotEmpty() } ?: return true
|
||||
val patches = patchPaths.map { it.absolutePath }.toTypedArray()
|
||||
|
||||
logger.lifecycle(">>> Applying $applyName patches to $name")
|
||||
|
||||
gitCmd("am", "--abort")
|
||||
|
||||
//Cursed Apply Mode that makes fixing stuff a lot easier
|
||||
if (checkCursed(project)) {
|
||||
for (patch in patches) {
|
||||
val gitCommand = arrayListOf("am", "--3way", "--ignore-whitespace",
|
||||
"--rerere-autoupdate", "--whitespace=fix", "--reject", "-C0", patch)
|
||||
if (gitCmd(*gitCommand.toTypedArray(), dir = projectDir, printOut = true).exitCode != 0) {
|
||||
gitCmd("add", ".", dir = projectDir, printOut = true)
|
||||
gitCmd("am", "--continue", dir = projectDir, printOut = true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val gitCommand = arrayListOf("am", "--3way", "--ignore-whitespace",
|
||||
"--rerere-autoupdate", "--whitespace=fix", *patches)
|
||||
ensureSuccess(gitCmd(*gitCommand.toTypedArray(), dir = projectDir, printOut = true)) {
|
||||
if (wasGitSigningEnabled) reEnableGitSigning(projectDir)
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
doLast {
|
||||
for ((name, subproject) in toothpick.subprojects) {
|
||||
val (sourceRepo, projectDir, patchesDir) = subproject
|
||||
|
||||
val folder = (if (patchesDir.endsWith("server")) "server" else "api")
|
||||
|
||||
// Reset or initialize subproject
|
||||
logger.lifecycle(">>> Resetting subproject $name")
|
||||
if (projectDir.exists()) {
|
||||
ensureSuccess(gitCmd("fetch", "origin", dir = projectDir))
|
||||
ensureSuccess(gitCmd("reset", "--hard", "origin/master", dir = projectDir))
|
||||
} else {
|
||||
ensureSuccess(gitCmd("clone", sourceRepo.absolutePath, projectDir.absolutePath, printOut = true))
|
||||
}
|
||||
logger.lifecycle(">>> Done resetting subproject $name")
|
||||
|
||||
val wasGitSigningEnabled = temporarilyDisableGitSigning(projectDir)
|
||||
|
||||
for (upstream in upstreams) {
|
||||
if (((folder == "server" && upstream.serverList?.isEmpty() != false) || (folder == "api" && upstream.apiList?.isEmpty() != false)) && !upstream.useBlackList) continue
|
||||
if (((folder == "server" && upstream.getRepoServerPatches()?.isEmpty() != false) || (folder == "api" && upstream.getRepoAPIPatches()?.isEmpty() != false)) && upstream.useBlackList) continue
|
||||
project.gitCmd("branch", "-D", "${upstream.name}-$folder", dir = projectDir)
|
||||
project.gitCmd("checkout", "-b", "${upstream.name}-$folder", dir = projectDir)
|
||||
// Apply patches
|
||||
val patchDir = Paths.get("${upstream.patchPath}/$folder")
|
||||
|
||||
if (applyPatches(patchDir, upstream.name, name, wasGitSigningEnabled, projectDir)) continue
|
||||
}
|
||||
// project.gitCmd("branch", "-D", "$forkName-$folder", dir = projectDir)
|
||||
// project.gitCmd("checkout", "-b", "$forkName-$folder", dir = projectDir)
|
||||
project.gitCmd("branch", "-D", "master", dir = projectDir)
|
||||
project.gitCmd("checkout", "-b", "master", dir = projectDir)
|
||||
val patchDir = patchesDir.toPath()
|
||||
// Apply patches
|
||||
if (applyPatches(patchDir, forkName, name, wasGitSigningEnabled, projectDir)) continue
|
||||
|
||||
if (wasGitSigningEnabled) reEnableGitSigning(projectDir)
|
||||
logger.lifecycle(">>> Done applying patches to $name")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package task
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import taskGroup
|
||||
import upstreams
|
||||
import gitCmd
|
||||
import toothpick
|
||||
import java.nio.file.Paths
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import ensureSuccess
|
||||
|
||||
internal fun Project.createFixBranchesTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("fixBranches") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
val folderArray = arrayListOf("api", "server")
|
||||
doLast {
|
||||
for (folder in folderArray) {
|
||||
val subprojectWorkDir = Paths.get("${toothpick.forkName}-${if (folder == "api") {"API"} else {"Server"}}").toFile()
|
||||
// val currentBranchCommits = gitCmd("--no-pager", "log", "${toothpick.forkName}-$folder...${toothpick.upstreamBranch}", "--pretty=oneline",
|
||||
val currentBranchCommits = gitCmd("--no-pager", "log", "master...${toothpick.upstreamBranch}", "--pretty=oneline",
|
||||
dir = subprojectWorkDir).output.toString()
|
||||
val nameMap = ConcurrentHashMap<String, String>()
|
||||
for (upstream in upstreams) {
|
||||
val patchPath = Paths.get("${upstream.patchPath}/$folder").toFile()
|
||||
if (patchPath.listFiles()?.isEmpty() != false) continue
|
||||
val commitName = gitCmd("--no-pager", "log", "${upstream.name}-$folder", "-1", "--format=\"%s\"",
|
||||
dir = subprojectWorkDir).output.toString()
|
||||
val branchName = "${upstream.name}-$folder"
|
||||
val commitNameFiltered = commitName.substring(1, commitName.length-1)
|
||||
for (line in currentBranchCommits.split("\\n".toRegex()).stream().parallel()) {
|
||||
val commitNameIterator = line.substring(41, line.length)
|
||||
if (commitNameIterator == commitNameFiltered) {
|
||||
val hash = line.substring(0, 40)
|
||||
nameMap.put(branchName, hash)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
for (upstream in upstreams) {
|
||||
val patchPath = Paths.get("${upstream.patchPath}/$folder").toFile()
|
||||
if (patchPath.listFiles()?.isEmpty() != false) continue
|
||||
val branchName = "${upstream.name}-$folder"
|
||||
ensureSuccess(gitCmd("checkout", branchName, dir = subprojectWorkDir, printOut = true))
|
||||
ensureSuccess(gitCmd("reset", "--hard", nameMap.get(branchName) as String, dir = subprojectWorkDir,
|
||||
printOut = true))
|
||||
}
|
||||
// ensureSuccess(gitCmd("checkout", "${toothpick.forkName}-$folder", dir = subprojectWorkDir,
|
||||
ensureSuccess(gitCmd("checkout", "master", dir = subprojectWorkDir,
|
||||
printOut = true))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
package task
|
||||
|
||||
import LibraryImport
|
||||
import ensureSuccess
|
||||
import gitCmd
|
||||
import internalTaskGroup
|
||||
import libraryImports
|
||||
import nmsImports
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import toothpick
|
||||
import upstreams
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import kotlin.streams.toList
|
||||
|
||||
internal fun Project.createImportMCDevTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("importMCDev") {
|
||||
receiver(this)
|
||||
group = internalTaskGroup
|
||||
val upstreamServer = toothpick.serverProject.baseDir
|
||||
val importLog = arrayListOf("Extra mc-dev imports")
|
||||
|
||||
fun isDuplicateImport(target: File, className: String): Boolean {
|
||||
if (!target.exists()) return false
|
||||
val message = "Skipped import for $className, a class with that name already exists in the source tree. Is there an extra entry in mcdevimports.json?"
|
||||
project.gradle.taskGraph.allTasks.last().doLast {
|
||||
logger.warn(message)
|
||||
}
|
||||
logger.warn(message)
|
||||
return true
|
||||
}
|
||||
|
||||
fun importNMS(className: String) {
|
||||
logger.lifecycle("Importing $className")
|
||||
val classPath = "${className.replace(".", "/")}.java"
|
||||
val source = toothpick.paperDecompDir.resolve("spigot/$classPath")
|
||||
importLog.add("Importing $className")
|
||||
if (!source.exists()) error("Missing NMS: $className")
|
||||
val target = upstreamServer.resolve("src/main/java/$classPath")
|
||||
if (isDuplicateImport(target, className)) return
|
||||
target.parentFile.mkdirs()
|
||||
source.copyTo(target)
|
||||
}
|
||||
|
||||
fun importLibrary(import: LibraryImport) {
|
||||
val (group, lib, prefix, file) = import
|
||||
val className = "${prefix.replace("/", ".")}.$file"
|
||||
importLog.add("Imported $className from $group.$lib")
|
||||
logger.lifecycle("Importing $className from $group.$lib")
|
||||
val source = toothpick.paperDecompDir.resolve("libraries/$group/$lib/$prefix/$file.java")
|
||||
if (!source.exists()) error("Missing Base: $lib $prefix/$file")
|
||||
val targetDir = upstreamServer.resolve("src/main/java/$prefix")
|
||||
val target = targetDir.resolve("$file.java")
|
||||
if (isDuplicateImport(target, className)) return
|
||||
targetDir.mkdirs()
|
||||
source.copyTo(target)
|
||||
}
|
||||
|
||||
fun findNeededImports(patches: List<File>): Set<String> = patches.asSequence()
|
||||
.flatMap { it.readLines().asSequence() }
|
||||
.filter { line ->
|
||||
line.startsWith("+++ b/src/main/java/net/minecraft/")
|
||||
|| line.startsWith("+++ b/src/main/java/com/mojang/math/")
|
||||
}
|
||||
.distinct()
|
||||
.map { it.substringAfter("+++ b/src/main/java/") }
|
||||
.filter { !upstreamServer.resolve("src/main/java/$it").exists() }
|
||||
.filter {
|
||||
val sourceFile = toothpick.paperDecompDir.resolve("spigot/$it")
|
||||
val exists = sourceFile.exists()
|
||||
if (!sourceFile.exists()) logger.lifecycle("$it is either missing, or is a new file added through a patch")
|
||||
exists
|
||||
}
|
||||
.map { it.replace("/", ".").substringBefore(".java") }
|
||||
.toSet()
|
||||
|
||||
fun getAndApplyNMS(patchesDir: File) {
|
||||
findNeededImports(patchesDir.listFiles().toList()).toList().forEach(::importNMS)
|
||||
}
|
||||
|
||||
doLast {
|
||||
logger.lifecycle(">>> Importing mc-dev")
|
||||
val lastCommitIsMCDev = gitCmd(
|
||||
"log", "-1", "--oneline",
|
||||
dir = upstreamServer
|
||||
).output?.contains("Extra mc-dev imports") == true
|
||||
if (lastCommitIsMCDev) {
|
||||
ensureSuccess(
|
||||
gitCmd(
|
||||
"reset", "--hard", "HEAD~1",
|
||||
dir = upstreamServer,
|
||||
printOut = true
|
||||
)
|
||||
)
|
||||
}
|
||||
for (upstream in upstreams) {
|
||||
val patchesDir = rootProject.projectDir.resolve("${upstream.patchPath}/server")
|
||||
getAndApplyNMS(patchesDir)
|
||||
}
|
||||
|
||||
val patchesDir = toothpick.serverProject.patchesDir
|
||||
getAndApplyNMS(patchesDir)
|
||||
|
||||
|
||||
// Imports from MCDevImports.kt
|
||||
nmsImports.forEach(::importNMS)
|
||||
libraryImports.forEach(::importLibrary)
|
||||
|
||||
val add = gitCmd("add", ".", "-A", dir = upstreamServer).exitCode == 0
|
||||
val commit = gitCmd("commit", "-m", importLog.joinToString("\n"), dir = upstreamServer).exitCode == 0
|
||||
if (!add || !commit) {
|
||||
logger.lifecycle(">>> Didn't import any extra files")
|
||||
}
|
||||
logger.lifecycle(">>> Done importing mc-dev")
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package task
|
||||
|
||||
import gitCmd
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import taskGroup
|
||||
import upstreamDir
|
||||
import upstreams
|
||||
|
||||
internal fun Project.createInitGitSubmodulesTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("initGitSubmodules") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
var upstreamNotInit = false
|
||||
for (upstream in upstreams) { upstreamNotInit = upstreamNotInit || upstream.repoPath.toFile().resolve(".git").exists() }
|
||||
onlyIf { !upstreamDir.resolve(".git").exists() || upstreamNotInit }
|
||||
doLast {
|
||||
var exit = gitCmd("submodule", "update", "--init", printOut = true).exitCode
|
||||
exit += gitCmd("submodule", "update", "--init", "--recursive", dir = upstreamDir, printOut = true).exitCode
|
||||
if (exit != 0) {
|
||||
error("Failed to checkout git submodules: git exited with code $exit")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package task
|
||||
|
||||
import cmd
|
||||
import ensureSuccess
|
||||
import jenkins
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import rootProjectDir
|
||||
import taskGroup
|
||||
import toothpick
|
||||
|
||||
internal fun Project.createPaperclipTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("paperclip") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
doLast {
|
||||
val workDir = toothpick.paperDir.resolve("work")
|
||||
val paperclipDir = workDir.resolve("Paperclip")
|
||||
val vanillaJarPath =
|
||||
workDir.resolve("Minecraft/${toothpick.minecraftVersion}/${toothpick.minecraftVersion}.jar").absolutePath
|
||||
val patchedJarPath = inputs.files.singleFile.absolutePath
|
||||
logger.lifecycle(">>> Building paperclip")
|
||||
val paperclipCmd = arrayListOf(
|
||||
"mvn", "-T", "2C", "clean", "package",
|
||||
"-Dmcver=${toothpick.minecraftVersion}",
|
||||
"-Dpaperjar=$patchedJarPath",
|
||||
"-Dvanillajar=$vanillaJarPath"
|
||||
)
|
||||
if (System.getProperty("os.name").startsWith("Windows")) paperclipCmd[0] = "mvn.cmd"
|
||||
if (jenkins) paperclipCmd.add("-Dstyle.color=never")
|
||||
ensureSuccess(cmd(*paperclipCmd.toTypedArray(), dir = paperclipDir, printOut = true))
|
||||
val paperClip = paperclipDir.resolve("assembly/target/paperclip-${toothpick.minecraftVersion}.jar")
|
||||
val destination = rootProjectDir.resolve(toothpick.calcPaperclipName)
|
||||
paperClip.copyTo(destination, overwrite = true)
|
||||
logger.lifecycle(">>> ${toothpick.calcPaperclipName} saved to root project directory")
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
package task
|
||||
|
||||
import PatchParser
|
||||
import PatchParser.PatchInfo
|
||||
import com.github.mustachejava.DefaultMustacheFactory
|
||||
import com.github.mustachejava.MustacheFactory
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import taskGroup
|
||||
import java.io.*
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
import patchCreditsOutput
|
||||
import patchCreditsTemplate
|
||||
|
||||
internal fun Project.createPatchCreditsTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("patchCredits") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
|
||||
val projectDirectory: File = rootDir
|
||||
val patchDirectory: File? = Paths.get("$rootDir/patches").toFile()
|
||||
val outputFileName: String = patchCreditsOutput
|
||||
val srcFileName: String = patchCreditsTemplate
|
||||
|
||||
doLast {
|
||||
val src = File(projectDirectory, srcFileName)
|
||||
if (!src.exists()) {
|
||||
logger.warn("Unable to find src at '" + src.absolutePath + "'! Skipping!")
|
||||
return@doLast
|
||||
}
|
||||
if (!patchDirectory!!.exists()) {
|
||||
logger
|
||||
.warn(
|
||||
"Unable to find patch directory at '"
|
||||
+ patchDirectory.absolutePath
|
||||
+ "'! Skipping!"
|
||||
)
|
||||
return@doLast
|
||||
}
|
||||
logger.lifecycle("Scanning '$patchDirectory' for patches!")
|
||||
val patches: MutableList<PatchInfo> = ArrayList()
|
||||
scanFolder(patchDirectory, patches, project)
|
||||
if (patches.isEmpty()) {
|
||||
logger.warn("Unable to find any patches! Skipping!")
|
||||
return@doLast
|
||||
}
|
||||
|
||||
patches.sortWith { a: PatchInfo, b: PatchInfo -> a.subject.compareTo(b.subject) }
|
||||
val output = Output()
|
||||
output.patches = patches
|
||||
try {
|
||||
val mf: MustacheFactory = DefaultMustacheFactory()
|
||||
FileReader(src).use { srcReader ->
|
||||
val mustache = mf.compile(srcReader, "template")
|
||||
val outputFile = File(projectDirectory, outputFileName)
|
||||
if (outputFile.exists()) {
|
||||
outputFile.delete()
|
||||
}
|
||||
OutputStreamWriter(FileOutputStream(outputFile), StandardCharsets.UTF_8).use { writer ->
|
||||
mustache.execute(
|
||||
writer,
|
||||
output
|
||||
).flush()
|
||||
}
|
||||
}
|
||||
} catch (ex: IOException) {
|
||||
error("Error while writing the output file!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun scanFolder(folder: File?, patches: MutableList<PatchInfo>, project: Project) {
|
||||
val files = folder!!.listFiles { dir: File, name: String ->
|
||||
if (dir.isDirectory) {
|
||||
return@listFiles !name.equals("removed", ignoreCase = true)
|
||||
} else {
|
||||
return@listFiles true
|
||||
}
|
||||
} ?: return
|
||||
for (f: File in files) {
|
||||
if (f.isDirectory) {
|
||||
scanFolder(f, patches, project)
|
||||
} else if (f.name.endsWith(".patch")) {
|
||||
try {
|
||||
patches.add(PatchParser.parsePatch(f))
|
||||
} catch (ex: IOException) {
|
||||
project.logger.warn("Exception while parsing '" + f.absolutePath + "'!", ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Output {
|
||||
var patches: List<PatchInfo>? = null
|
||||
}
|
||||
|
@ -1,89 +0,0 @@
|
||||
package task
|
||||
|
||||
import ensureSuccess
|
||||
import forkName
|
||||
import gitCmd
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import taskGroup
|
||||
import toothpick
|
||||
import upstreams
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
import Upstream
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
internal fun Project.createRebuildPatchesTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("rebuildPatches") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
doLast {
|
||||
for ((name, subproject) in toothpick.subprojects) {
|
||||
val (sourceRepo, projectDir, patchesDir) = subproject
|
||||
var previousUpstreamName = "origin/master"
|
||||
val folder = (if (patchesDir.endsWith("server")) "server" else "api")
|
||||
|
||||
for (upstream in upstreams) {
|
||||
val patchPath = Paths.get("${upstream.patchPath}/$folder").toFile()
|
||||
|
||||
if (patchPath.listFiles()?.isEmpty() != false) continue
|
||||
|
||||
updatePatches(patchPath, upstream.name, folder, projectDir, previousUpstreamName)
|
||||
previousUpstreamName = "${upstream.name}-$folder"
|
||||
}
|
||||
// ensureSuccess(gitCmd("checkout", "$forkName-$folder", dir = projectDir,
|
||||
ensureSuccess(gitCmd("checkout", "master", dir = projectDir,
|
||||
printOut = true))
|
||||
|
||||
updatePatches(patchesDir, toothpick.forkName, folder, projectDir, previousUpstreamName)
|
||||
|
||||
logger.lifecycle(">>> Done rebuilding patches for $name")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.updatePatches(
|
||||
patchPath: File,
|
||||
name: String,
|
||||
folder: String,
|
||||
projectDir: File,
|
||||
previousUpstreamName: String
|
||||
) {
|
||||
logger.lifecycle(">>> Rebuilding patches for $name-$folder")
|
||||
if (!patchPath.exists()) {
|
||||
patchPath.mkdirs()
|
||||
}
|
||||
// Nuke old patches
|
||||
patchPath.listFiles()
|
||||
?.filter { it -> it.name.endsWith(".patch") }
|
||||
?.forEach { it -> it.delete() }
|
||||
|
||||
ensureSuccess(
|
||||
if (name != "Yatopia") {
|
||||
gitCmd(
|
||||
"checkout", "$name-$folder", dir = projectDir,
|
||||
printOut = true
|
||||
)
|
||||
} else {
|
||||
gitCmd(
|
||||
"checkout", "master", dir = projectDir,
|
||||
printOut = true
|
||||
)
|
||||
}
|
||||
)
|
||||
ensureSuccess(
|
||||
gitCmd(
|
||||
"format-patch",
|
||||
"--no-stat", "--zero-commit", "--full-index", "--no-signature", "-N",
|
||||
"-o", patchPath.absolutePath, previousUpstreamName,
|
||||
dir = projectDir,
|
||||
printOut = false
|
||||
)
|
||||
)
|
||||
gitCmd(
|
||||
"add", patchPath.canonicalPath,
|
||||
dir = patchPath,
|
||||
printOut = true
|
||||
)
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* This file is part of Toothpick, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) 2020-2021 Jason Penilla & Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package task
|
||||
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.File
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import taskGroup
|
||||
import upstreams
|
||||
import gitCmd
|
||||
import toothpick
|
||||
import java.nio.file.Paths
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import ensureSuccess
|
||||
import java.net.URL
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
internal fun Project.createRepackageNMSTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("repackageNMS") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
class Mapping(fullyQualifiedClassName: String) {
|
||||
val className = fullyQualifiedClassName.substringAfterLast(".")
|
||||
val oldFQName = "net.minecraft.server.$className"
|
||||
val oldJavaFileName = "net/minecraft/server/$className.java"
|
||||
val newFQName = fullyQualifiedClassName
|
||||
val newJavaFileName = "${fullyQualifiedClassName.replace(".", "/")}.java"
|
||||
}
|
||||
|
||||
class Remapper(private val mappings: Set<Mapping>) {
|
||||
fun remapFile(file: File): String =
|
||||
file.readLines().joinToString("\n") { remapLine(it) } + "\n"
|
||||
|
||||
private fun remapLine(line: String): String {
|
||||
if (
|
||||
line.startsWith("diff --git ")
|
||||
|| line.startsWith("+++ ")
|
||||
|| line.startsWith("--- ")
|
||||
) {
|
||||
var text = line
|
||||
mappings.forEach { text = text.replace(it.oldJavaFileName, it.newJavaFileName) }
|
||||
return text
|
||||
}
|
||||
if (line.startsWith("+")) {
|
||||
var text = line
|
||||
mappings.forEach { text = text.replace(it.oldFQName, it.newFQName) }
|
||||
return text
|
||||
}
|
||||
return line
|
||||
}
|
||||
}
|
||||
doLast {
|
||||
logger.lifecycle("Downloading class mappings from spigot...")
|
||||
val mappingsFileText = URL("https://hub.spigotmc.org/stash/projects/SPIGOT/repos/builddata/raw/mappings/bukkit-1.16.5-cl.csrg?at=80d35549ec67b87a0cdf0d897abbe826ba34ac27").readText()
|
||||
logger.lifecycle("Done downloading class mappings.")
|
||||
|
||||
logger.lifecycle(">>> Preparing patches for NMS repackage")
|
||||
val mappings = mappingsFileText
|
||||
.split("\n")
|
||||
.asSequence()
|
||||
.filter { !it.startsWith("#") && !it.contains("$") && it.trim().isNotEmpty() }
|
||||
.map { it.split(" ")[1].replace("/", ".") }
|
||||
.map { Mapping(it) }
|
||||
.filter { it.newFQName != it.oldFQName }
|
||||
.toSet()
|
||||
val remapper = Remapper(mappings)
|
||||
|
||||
toothpick.subprojects.values
|
||||
.map { it.patchesDir }
|
||||
.forEach { patchesDir ->
|
||||
val repackagedPatchesDir =
|
||||
patchesDir.parentFile.resolve("${patchesDir.name}_repackaged-${System.currentTimeMillis()}")
|
||||
repackagedPatchesDir.mkdir()
|
||||
val patchFiles = patchesDir.listFiles()?.toList() ?: error("Could not list patch files")
|
||||
patchFiles.parallelStream().forEach { patch ->
|
||||
logger.lifecycle("Processing ${patchesDir.name}/${patch.name}...")
|
||||
val newPatch = repackagedPatchesDir.resolve(patch.name)
|
||||
newPatch.writeText(remapper.remapFile(patch))
|
||||
}
|
||||
}
|
||||
|
||||
logger.lifecycle(">>> Done preparing patches")
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
package task
|
||||
|
||||
import bashCmd
|
||||
import gitHash
|
||||
import lastUpstream
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import taskGroup
|
||||
import toothpick
|
||||
import upstreamDir
|
||||
|
||||
internal fun Project.createSetupUpstreamTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("setupUpstream") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
doLast {
|
||||
val setupUpstreamCommand = if (upstreamDir.resolve(toothpick.upstreamLowercase).exists()) {
|
||||
"./${toothpick.upstreamLowercase} patch"
|
||||
} else if (
|
||||
upstreamDir.resolve("build.gradle.kts").exists()
|
||||
&& upstreamDir.resolve("subprojects/server.gradle.kts").exists()
|
||||
&& upstreamDir.resolve("subprojects/api.gradle.kts").exists()
|
||||
) {
|
||||
"./gradlew applyPatches"
|
||||
} else {
|
||||
error("Don't know how to setup upstream!")
|
||||
}
|
||||
val result = bashCmd(setupUpstreamCommand, dir = upstreamDir, printOut = true)
|
||||
if (result.exitCode != 0) {
|
||||
error("Failed to apply upstream patches: script exited with code ${result.exitCode}")
|
||||
}
|
||||
lastUpstream.writeText(gitHash(upstreamDir))
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
package task
|
||||
|
||||
import Upstream
|
||||
import ensureSuccess
|
||||
import gitCmd
|
||||
import org.apache.tools.ant.util.FileUtils
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import rootProjectDir
|
||||
import taskGroup
|
||||
import toothpick
|
||||
import upstreamDir
|
||||
import upstreams
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.util.stream.Collectors
|
||||
|
||||
|
||||
internal fun Project.createUpdateUpstreamTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("updateUpstream") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
doLast {
|
||||
ensureSuccess(gitCmd("fetch", dir = upstreamDir, printOut = true))
|
||||
ensureSuccess(gitCmd("reset", "--hard", toothpick.upstreamBranch, dir = upstreamDir, printOut = true))
|
||||
ensureSuccess(gitCmd("add", toothpick.upstream, dir = rootProjectDir, printOut = true))
|
||||
for (upstream in upstreams) {
|
||||
ensureSuccess(gitCmd("fetch", dir = upstream.repoPath.toFile(), printOut = true))
|
||||
ensureSuccess(gitCmd("reset", "--hard", upstream.branch, dir = upstream.repoPath.toFile(), printOut = true))
|
||||
ensureSuccess(gitCmd("add", "upstream/${upstream.name}", dir = rootProjectDir, printOut = true))
|
||||
}
|
||||
ensureSuccess(gitCmd("submodule", "update", "--init", "--recursive", dir = upstreamDir, printOut = true))
|
||||
val fileUtils = FileUtils.getFileUtils()
|
||||
for (upstream in upstreams) {
|
||||
val serverRepoPatches = upstream.getRepoServerPatches()
|
||||
val apiRepoPatches = upstream.getRepoAPIPatches()
|
||||
val serverPatches = upstream.serverList
|
||||
val apiPatches = upstream.apiList
|
||||
logger.lifecycle(">>> Pulling ${upstream.name} patches")
|
||||
updatePatches(serverRepoPatches, upstream, fileUtils, serverPatches, "server")
|
||||
updatePatches(apiRepoPatches, upstream, fileUtils, apiPatches, "api")
|
||||
upstream.updateUpstreamCommitHash()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePatches(
|
||||
repoPatches: MutableList<String>?,
|
||||
upstream: Upstream,
|
||||
fileUtils: FileUtils,
|
||||
patches: MutableList<String>?,
|
||||
folder: String
|
||||
) {
|
||||
if (repoPatches != null) {
|
||||
var i = 0
|
||||
val currentPatchList = Paths.get("${upstream.patchPath}/$folder").toFile().listFiles() as Array<File>?
|
||||
val tmpFolder = Paths.get("${upstream.patchPath}/tmp/$folder").toFile()
|
||||
tmpFolder.mkdirs()
|
||||
if (currentPatchList != null) {
|
||||
for (patch in currentPatchList) {
|
||||
if (patch.exists()) {
|
||||
fileUtils.copyFile(
|
||||
"${upstream.patchPath}/$folder/${patch.name}",
|
||||
"${upstream.patchPath}/tmp/$folder/${patch.name}"
|
||||
)
|
||||
patch.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
val currentPatchListFiltered = currentPatchList?.toList()
|
||||
?.stream()?.sorted()?.map { patch -> patch.name.substring(5, patch.name.length) }
|
||||
?.collect(Collectors.toList())
|
||||
for (patch in repoPatches) {
|
||||
if (patches != null) {
|
||||
if ((patches.contains(patch) && upstream.useBlackList) || (!patches.contains(patch) && !upstream.useBlackList)) {
|
||||
continue
|
||||
} else {
|
||||
i++
|
||||
updatePatch(fileUtils, upstream, repoPatches, patch, i, folder, currentPatchListFiltered)
|
||||
}
|
||||
}
|
||||
}
|
||||
val tmpFolderList = tmpFolder.listFiles()
|
||||
if (tmpFolderList != null) {
|
||||
for (patch in tmpFolderList) {
|
||||
patch.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePatch(
|
||||
fileUtils: FileUtils,
|
||||
upstream: Upstream,
|
||||
serverRepoPatches: MutableList<String>,
|
||||
patch: String,
|
||||
i: Int,
|
||||
folder: String,
|
||||
currentPatchListFiltered: MutableList<String>?
|
||||
) {
|
||||
if (currentPatchListFiltered == null || patchHasDiff(upstream, serverRepoPatches, patch, folder, currentPatchListFiltered)) {
|
||||
fileUtils.copyFile("${upstream.repoPath}/patches/$folder/" +
|
||||
"${String.format("%04d", serverRepoPatches.indexOf(patch) + 1)}-$patch",
|
||||
"${upstream.patchPath}/$folder/${String.format("%04d", i)}-$patch"
|
||||
)
|
||||
} else {
|
||||
fileUtils.copyFile("${upstream.patchPath}/tmp/$folder/" +
|
||||
"${String.format("%04d", currentPatchListFiltered.indexOf(patch) + 1)}-$patch",
|
||||
"${upstream.patchPath}/$folder/${String.format("%04d", i)}-$patch"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun patchHasDiff(
|
||||
upstream: Upstream,
|
||||
serverRepoPatches: MutableList<String>,
|
||||
patch: String,
|
||||
folder: String,
|
||||
currentPatchListFiltered: MutableList<String>
|
||||
): Boolean {
|
||||
if (!Paths.get("${upstream.patchPath}/tmp/$folder/${String.format("%04d", currentPatchListFiltered.indexOf(patch) + 1)}-$patch").toFile().isFile) return true
|
||||
if (!patchChanged(upstream, serverRepoPatches, patch, folder)) return false
|
||||
val upstreamFile = Files.readAllLines(Paths.get("${upstream.repoPath}/patches/$folder/${String.format("%04d", serverRepoPatches.indexOf(patch) + 1)}-$patch"), StandardCharsets.UTF_8)
|
||||
val repoFile = Files.readAllLines(Paths.get("${upstream.patchPath}/tmp/$folder/${String.format("%04d", currentPatchListFiltered.indexOf(patch) + 1)}-$patch"), StandardCharsets.UTF_8)
|
||||
return upstreamFile.stream().filter {line -> line.startsWith("+") || line.startsWith("-")}
|
||||
.filter {line -> if (line.startsWith("---") || line.startsWith("+++")) {
|
||||
line.substring(3, line.length).trim().isNotBlank()
|
||||
}
|
||||
else if (line.startsWith("--") || line.startsWith("++")) {
|
||||
line.substring(2, line.length).trim().isNotBlank()
|
||||
}
|
||||
else {
|
||||
line.substring(1, line.length).trim().isNotBlank()
|
||||
} }
|
||||
.filter {line -> if (repoFile.contains(line)) {
|
||||
repoFile.remove(line)
|
||||
return@filter false
|
||||
} else { return@filter true } }.collect(Collectors.toList()).isNotEmpty()
|
||||
}
|
||||
|
||||
fun patchChanged(
|
||||
upstream: Upstream,
|
||||
serverRepoPatches: MutableList<String>,
|
||||
patch: String,
|
||||
folder: String
|
||||
): Boolean {
|
||||
val diffCheckCmdResult = upstream.project.gitCmd("diff", "--name-only", upstream.upstreamCommit, upstream.getCurrentCommitHash(), dir = upstream.repoPath.toFile() )
|
||||
val diffCheckResult = diffCheckCmdResult.output.toString()
|
||||
if (diffCheckResult.isBlank()) return false
|
||||
val diffCheckChangeFiles = diffCheckResult.split("\\n".toRegex()).toTypedArray().toList()
|
||||
return diffCheckChangeFiles.contains("patches/$folder/${String.format("%04d", serverRepoPatches.indexOf(patch) + 1)}-$patch")
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package task
|
||||
|
||||
import ensureSuccess
|
||||
import gitCmd
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import taskGroup
|
||||
import toothpick
|
||||
import upstreamDir
|
||||
import upstreams
|
||||
import java.io.File
|
||||
import Upstream
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
internal fun Project.createUpstreamCommitTask(
|
||||
receiver: Task.() -> Unit = {}
|
||||
): Task = tasks.create("upstreamCommit") {
|
||||
receiver(this)
|
||||
group = taskGroup
|
||||
doLast {
|
||||
gitChangelog = getUpstreamChanges(project,this, toothpick.upstream,
|
||||
upstreamDir, toothpick.upstream)
|
||||
|
||||
for (upstream in upstreams) {
|
||||
gitChangelog = getUpstreamChanges(project,this, upstream.name,
|
||||
upstream.repoPath.toFile(), "upstream/${upstream.name}")
|
||||
}
|
||||
|
||||
var changedUpstreamsString = ""
|
||||
for (upstreamName in changedUpstreams) {
|
||||
if (changedUpstreamsString.isNotEmpty()) {
|
||||
changedUpstreamsString += "/"
|
||||
}
|
||||
changedUpstreamsString += upstreamName
|
||||
}
|
||||
if (changedUpstreamsString.isNotEmpty()) {
|
||||
val commitMessage = """
|
||||
|Updated Upstream and Sidestream(s) ($changedUpstreamsString)
|
||||
|
|
||||
|Upstream/An Sidestream has released updates that appears to apply and compile correctly
|
||||
|This update has NOT been tested by YatopiaMC and as with ANY update, please do your own testing.
|
||||
|
|
||||
|
|
||||
|$gitChangelog
|
||||
""".trimMargin()
|
||||
ensureSuccess(gitCmd("commit", "-m", commitMessage, printOut = true))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUpstreamChanges(
|
||||
project: Project,
|
||||
task: Task,
|
||||
name: String,
|
||||
dir: File,
|
||||
path: String
|
||||
): String {
|
||||
var gitChangelog1 = gitChangelog
|
||||
val oldRev = ensureSuccess(project.gitCmd("ls-tree", "HEAD", path))
|
||||
?.substringAfter("commit ")?.substringBefore("\t")
|
||||
val upstreamTmp = ensureSuccess(
|
||||
project.gitCmd(
|
||||
"log",
|
||||
"--oneline",
|
||||
"$oldRev...HEAD",
|
||||
printOut = true,
|
||||
dir = dir
|
||||
)
|
||||
) {
|
||||
task.logger.lifecycle("No $name changes to commit.")
|
||||
}
|
||||
if (!upstreamTmp.isNullOrBlank()) {
|
||||
changedUpstreams.add(name)
|
||||
gitChangelog1 += "$name Changes:\n$upstreamTmp\n\n"
|
||||
}
|
||||
return gitChangelog1
|
||||
}
|
||||
|
||||
val changedUpstreams = CopyOnWriteArrayList<String>()
|
||||
|
||||
var gitChangelog = ""
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* This file is part of Toothpick, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) 2020-2021 Jason Penilla & Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package transformer
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
|
||||
import org.gradle.api.file.FileTreeElement
|
||||
import shadow.org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor.PLUGIN_CACHE_FILE
|
||||
|
||||
internal class ModifiedLog4j2PluginsCacheFileTransformer : Transformer by Log4j2PluginsCacheFileTransformer() {
|
||||
/**
|
||||
* For some reason we have a file with name matching simply 'Log4j2Plugins.dat' and not PLUGIN_CACHE_FILE.
|
||||
* That file also needs to be merged.
|
||||
*/
|
||||
override fun canTransformResource(element: FileTreeElement): Boolean {
|
||||
return PLUGIN_CACHE_FILE == element.name || element.name == "Log4j2Plugins.dat"
|
||||
}
|
||||
}
|
@ -1,3 +1,11 @@
|
||||
# Paperweight
|
||||
|
||||
group=org.yatopiamc.yatopia
|
||||
version=1.17-R0.1-SNAPSHOT
|
||||
packageVersion=1_17_R1
|
||||
paperCommit=123a41d1325e6361e547af7c29327fa319e06fb3
|
||||
|
||||
# Gradle
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xms1G -Xmx3G
|
||||
org.gradle.parallel=true
|
||||
|
@ -1,23 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
=====================
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the “Software”), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Tue, 18 Feb 2020 20:30:03 -0600
|
||||
Subject: [PATCH] Purpur config files
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index d1a9322cf54f57f0d213145aa50c219f0eb2a90b..1a319e2842f4b99951f1cddce8b2b4be9f5373a0 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1603,6 +1603,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
}
|
||||
// Tuinity end - add config to timings report
|
||||
|
||||
+ // Purpur start
|
||||
+ @NotNull
|
||||
+ public org.bukkit.configuration.file.YamlConfiguration getPurpurConfig() {
|
||||
+ throw new UnsupportedOperationException("Not supported yet.");
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public java.util.Properties getServerProperties() {
|
||||
+ throw new UnsupportedOperationException("Not supported yet.");
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
/**
|
||||
* Sends the component to the player
|
||||
*
|
@ -1,113 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 5 Jun 2020 23:32:38 -0500
|
||||
Subject: [PATCH] Default permissions
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/util/permissions/CommandPermissions.java
|
||||
index 7763d6101ac61900db1e2310966b99584539fd0e..d5a42707d365ffd72532bbb1a59a1ca7145f9918 100644
|
||||
--- a/src/main/java/org/bukkit/util/permissions/CommandPermissions.java
|
||||
+++ b/src/main/java/org/bukkit/util/permissions/CommandPermissions.java
|
||||
@@ -18,6 +18,7 @@ public final class CommandPermissions {
|
||||
DefaultPermissions.registerPermission(PREFIX + "plugins", "Allows the user to view the list of plugins running on this server", PermissionDefault.TRUE, commands);
|
||||
DefaultPermissions.registerPermission(PREFIX + "reload", "Allows the user to reload the server settings", PermissionDefault.OP, commands);
|
||||
DefaultPermissions.registerPermission(PREFIX + "version", "Allows the user to view the version of the server", PermissionDefault.TRUE, commands);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "purpur", "Allows the user to use the purpur command", PermissionDefault.OP, commands); // Purpur
|
||||
|
||||
commands.recalculatePermissibles();
|
||||
return commands;
|
||||
diff --git a/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java b/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java
|
||||
index e1a4ddf2c07cdd242fa8054a0152522fe4039e85..8e481e3815f5645ee92f0d229e5ff25c8fc9a6c2 100644
|
||||
--- a/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java
|
||||
+++ b/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java
|
||||
@@ -89,6 +89,8 @@ public final class DefaultPermissions {
|
||||
CommandPermissions.registerPermissions(parent);
|
||||
BroadcastPermissions.registerPermissions(parent);
|
||||
|
||||
+ PurpurPermissions.registerPermissions(); // Purpur
|
||||
+
|
||||
parent.recalculatePermissibles();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/util/permissions/PurpurPermissions.java b/src/main/java/org/bukkit/util/permissions/PurpurPermissions.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..deedffb4aca00a9ff27a47a09ec7087e5566ad29
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/util/permissions/PurpurPermissions.java
|
||||
@@ -0,0 +1,76 @@
|
||||
+package org.bukkit.util.permissions;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.EntityType;
|
||||
+import org.bukkit.entity.Mob;
|
||||
+import org.bukkit.permissions.Permission;
|
||||
+import org.bukkit.permissions.PermissionDefault;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.util.HashSet;
|
||||
+import java.util.Set;
|
||||
+
|
||||
+public final class PurpurPermissions {
|
||||
+ private static final String ROOT = "purpur";
|
||||
+ private static final String PREFIX = ROOT + ".";
|
||||
+ private static final Set<String> mobs = new HashSet<>();
|
||||
+
|
||||
+ private PurpurPermissions() {
|
||||
+ for (EntityType mob : EntityType.values()) {
|
||||
+ Class<? extends Entity> clazz = mob.getEntityClass();
|
||||
+ if (clazz != null && clazz.isAssignableFrom(Mob.class)) {
|
||||
+ mobs.add(mob.getName());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static Permission registerPermissions() {
|
||||
+ Permission purpur = DefaultPermissions.registerPermission(ROOT, "Gives the user the ability to use all Purpur utilities and commands");
|
||||
+
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.six", "Gives the user six rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.five", "Gives the user five rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.four", "Gives the user four rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.three", "Gives the user three rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.two", "Gives the user two rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.one", "Gives the user one row of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE);
|
||||
+
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "debug.f3n", "Allows the user to use F3+N keybind to swap gamemodes", PermissionDefault.FALSE, purpur);
|
||||
+
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "drop.spawner", "Allows the user to drop spawner cage when broken with diamond pickaxe with silk touch", PermissionDefault.FALSE, purpur);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "place.spawner", "Allows the user to place spawner cage in the world", PermissionDefault.FALSE, purpur);
|
||||
+
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "anvil.color", "Allows the user to use color codes on anvils", PermissionDefault.FALSE, purpur);
|
||||
+
|
||||
+ Permission book = DefaultPermissions.registerPermission(PREFIX + "book", "Allows the user to use color codes on books", PermissionDefault.FALSE, purpur);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "book.color.edit", "Allows the user to use color codes on books when editing", PermissionDefault.FALSE, book);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "book.color.sign", "Allows the user to use color codes on books when signing", PermissionDefault.FALSE, book);
|
||||
+ book.recalculatePermissibles();
|
||||
+
|
||||
+ Permission sign = DefaultPermissions.registerPermission(PREFIX + "sign", "Allows the user to use all sign abilities", PermissionDefault.FALSE, purpur);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "sign.click.opens.editor", "Allows the user to click signs to open sign editor", PermissionDefault.FALSE, sign);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "sign.color", "Allows the user to use color codes on signs", PermissionDefault.FALSE, sign);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "sign.style", "Allows the user to use style codes on signs", PermissionDefault.FALSE, sign);
|
||||
+ DefaultPermissions.registerPermission(PREFIX + "sign.magic", "Allows the user to use magic/obfuscate code on signs", PermissionDefault.FALSE, sign);
|
||||
+ sign.recalculatePermissibles();
|
||||
+
|
||||
+ Permission ride = DefaultPermissions.registerPermission("allow.ride", "Allows the user to ride all mobs", PermissionDefault.FALSE);
|
||||
+ for (String mob : mobs) {
|
||||
+ DefaultPermissions.registerPermission("allow.ride." + mob, "Allows the user to ride " + mob, PermissionDefault.FALSE, ride);
|
||||
+ }
|
||||
+ ride.recalculatePermissibles();
|
||||
+
|
||||
+ Permission special = DefaultPermissions.registerPermission("allow.special", "Allows the user to use all mobs special abilities", PermissionDefault.FALSE);
|
||||
+ for (String mob : mobs) {
|
||||
+ DefaultPermissions.registerPermission("allow.special." + mob, "Allows the user to use " + mob + " special ability", PermissionDefault.FALSE, special);
|
||||
+ }
|
||||
+ special.recalculatePermissibles();
|
||||
+
|
||||
+ Permission powered = DefaultPermissions.registerPermission("allow.powered", "Allows the user to toggle all mobs powered state", PermissionDefault.FALSE);
|
||||
+ DefaultPermissions.registerPermission("allow.powered.creeper", "Allows the user to toggle creeper powered state", PermissionDefault.FALSE, powered);
|
||||
+ powered.recalculatePermissibles();
|
||||
+
|
||||
+ purpur.recalculatePermissibles();
|
||||
+ return purpur;
|
||||
+ }
|
||||
+}
|
@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 23 Jul 2019 06:50:55 -0500
|
||||
Subject: [PATCH] Allow inventory resizing
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java
|
||||
index 090d22bd30f7947103771aaaf09a2398970ac337..ca660dde2010098e8c77141d05c2d4d5470adf81 100644
|
||||
--- a/src/main/java/org/bukkit/event/inventory/InventoryType.java
|
||||
+++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java
|
||||
@@ -132,7 +132,7 @@ public enum InventoryType {
|
||||
STONECUTTER(2, "Stonecutter")
|
||||
;
|
||||
|
||||
- private final int size;
|
||||
+ private int size; // Purpur - remove final
|
||||
private final String title;
|
||||
private final boolean isCreatable;
|
||||
|
||||
@@ -159,6 +159,12 @@ public enum InventoryType {
|
||||
this.defaultTitleComponent = net.kyori.adventure.text.Component.text(defaultTitle); // Paper - Adventure
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ public void setDefaultSize(int size) {
|
||||
+ this.size = size;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
public int getDefaultSize() {
|
||||
return size;
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 31 May 2019 21:24:21 -0500
|
||||
Subject: [PATCH] Advancement API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/advancement/Advancement.java b/src/main/java/org/bukkit/advancement/Advancement.java
|
||||
index 7c5009974ac8d64d0e738e60cec45acb0d4ca89a..432caadba1b08bb94cdb4ccf552e42400e0db338 100644
|
||||
--- a/src/main/java/org/bukkit/advancement/Advancement.java
|
||||
+++ b/src/main/java/org/bukkit/advancement/Advancement.java
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.advancement;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents an advancement that may be awarded to a player. This class is not
|
||||
@@ -17,4 +18,12 @@ public interface Advancement extends Keyed {
|
||||
*/
|
||||
@NotNull
|
||||
Collection<String> getCriteria();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the display properties of this advancement
|
||||
+ *
|
||||
+ * @return The display properties
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ AdvancementDisplay getDisplay();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/advancement/AdvancementDisplay.java b/src/main/java/org/bukkit/advancement/AdvancementDisplay.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bca3d112e2397b26ba6ccb6cd41e406caae27c5c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/advancement/AdvancementDisplay.java
|
||||
@@ -0,0 +1,53 @@
|
||||
+package org.bukkit.advancement;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface AdvancementDisplay {
|
||||
+ /**
|
||||
+ * Get the title of this advancement
|
||||
+ *
|
||||
+ * @return Title text
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ String getTitle();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the description of this advancement
|
||||
+ *
|
||||
+ * @return Description text
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ String getDescription();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the frame type of this advancement
|
||||
+ *
|
||||
+ * @return Frame type
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ FrameType getFrameType();
|
||||
+
|
||||
+ /**
|
||||
+ * Get if this advancement should be announced in chat when completed
|
||||
+ *
|
||||
+ * @return True if should announce when completed
|
||||
+ */
|
||||
+ boolean shouldAnnounceToChat();
|
||||
+
|
||||
+ /**
|
||||
+ * Set if this advancement should be announced in chat when completed
|
||||
+ *
|
||||
+ * @param announce True or false
|
||||
+ *
|
||||
+ */
|
||||
+ void setShouldAnnounceToChat(boolean announce);
|
||||
+
|
||||
+ /**
|
||||
+ * Get if this advancement (and all it's children) is hidden from the advancement screen until it has been completed
|
||||
+ * <p>
|
||||
+ * This has no effect on root advancements themselves, but will alter their children
|
||||
+ *
|
||||
+ * @return True if hidden until completed
|
||||
+ */
|
||||
+ boolean isHidden();
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/advancement/FrameType.java b/src/main/java/org/bukkit/advancement/FrameType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d1757f3d456ff9efce26ce8baa1d16d896908cc2
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/advancement/FrameType.java
|
||||
@@ -0,0 +1,27 @@
|
||||
+package org.bukkit.advancement;
|
||||
+
|
||||
+import org.bukkit.ChatColor;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public enum FrameType {
|
||||
+ TASK(ChatColor.GREEN),
|
||||
+ CHALLENGE(ChatColor.DARK_PURPLE),
|
||||
+ GOAL(ChatColor.GREEN);
|
||||
+
|
||||
+ private final ChatColor color;
|
||||
+
|
||||
+ FrameType(ChatColor color) {
|
||||
+ this.color = color;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public ChatColor getColor() {
|
||||
+ return color;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "FrameType[name=" + name() + ",color=" + color + "]";
|
||||
+ }
|
||||
+}
|
@ -1,191 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 18 Oct 2019 22:50:05 -0500
|
||||
Subject: [PATCH] Llama API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/entity/LlamaJoinCaravanEvent.java b/src/main/java/net/pl3x/purpur/event/entity/LlamaJoinCaravanEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6e68c1399bf30eeef6ce0385867f0cf258698eae
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/entity/LlamaJoinCaravanEvent.java
|
||||
@@ -0,0 +1,61 @@
|
||||
+package net.pl3x.purpur.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Llama;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a Llama tries to join a caravan.
|
||||
+ * <p>
|
||||
+ * Cancelling the event will not let the Llama join. To prevent future attempts
|
||||
+ * at joining a caravan use {@link Llama#setShouldJoinCaravan(boolean)}.
|
||||
+ */
|
||||
+public class LlamaJoinCaravanEvent extends EntityEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean canceled;
|
||||
+ private final Llama head;
|
||||
+
|
||||
+ public LlamaJoinCaravanEvent(@NotNull Llama llama, @NotNull Llama head) {
|
||||
+ super(llama);
|
||||
+ this.head = head;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public Llama getEntity() {
|
||||
+ return (Llama) entity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the Llama that this Llama is about to follow
|
||||
+ *
|
||||
+ * @return Llama about to be followed
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Llama getHead() {
|
||||
+ return head;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return canceled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ canceled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/entity/LlamaLeaveCaravanEvent.java b/src/main/java/net/pl3x/purpur/event/entity/LlamaLeaveCaravanEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ec8d978c22835e2789ebaaeddf0d13588ed1122a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/entity/LlamaLeaveCaravanEvent.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package net.pl3x.purpur.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Llama;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a Llama leaves a caravan
|
||||
+ */
|
||||
+public class LlamaLeaveCaravanEvent extends EntityEvent {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ public LlamaLeaveCaravanEvent(@NotNull Llama llama) {
|
||||
+ super(llama);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public Llama getEntity() {
|
||||
+ return (Llama) entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Llama.java b/src/main/java/org/bukkit/entity/Llama.java
|
||||
index d23226ccb0f6c25028f000ce31346cd0a8898e6a..1ef9479c962b3f4f6fed46671a1209c34040d16d 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Llama.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Llama.java
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.entity;
|
||||
import com.destroystokyo.paper.entity.RangedEntity;
|
||||
import org.bukkit.inventory.LlamaInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable; // Purpur
|
||||
|
||||
/**
|
||||
* Represents a Llama.
|
||||
@@ -67,4 +68,65 @@ public interface Llama extends ChestedHorse, RangedEntity { // Paper
|
||||
@NotNull
|
||||
@Override
|
||||
LlamaInventory getInventory();
|
||||
+
|
||||
+ // Purpur start
|
||||
+
|
||||
+ /**
|
||||
+ * Check if this Llama should attempt to join a caravan
|
||||
+ *
|
||||
+ * @return True if Llama is allowed to join a caravan
|
||||
+ */
|
||||
+ boolean shouldJoinCaravan();
|
||||
+
|
||||
+ /**
|
||||
+ * Set if this Llama should attempt to join a caravan
|
||||
+ *
|
||||
+ * @param shouldJoinCaravan True to allow joining a caravan
|
||||
+ */
|
||||
+ void setShouldJoinCaravan(boolean shouldJoinCaravan);
|
||||
+
|
||||
+ /**
|
||||
+ * Check if Llama is in a caravan
|
||||
+ *
|
||||
+ * @return True if in caravan
|
||||
+ */
|
||||
+ boolean inCaravan();
|
||||
+
|
||||
+ /**
|
||||
+ * Join a caravan
|
||||
+ *
|
||||
+ * @param llama Head of caravan to join
|
||||
+ */
|
||||
+ void joinCaravan(@NotNull Llama llama);
|
||||
+
|
||||
+ /**
|
||||
+ * Leave current caravan if in one
|
||||
+ */
|
||||
+ void leaveCaravan();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if another Llama is following this Llama
|
||||
+ *
|
||||
+ * @return True if being followed in the caravan
|
||||
+ */
|
||||
+ boolean hasCaravanTail();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the Llama that this Llama is following
|
||||
+ * <p>
|
||||
+ * Does not necessarily mean the leader of the entire caravan
|
||||
+ *
|
||||
+ * @return The Llama being followed
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Llama getCaravanHead();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the Llama following this Llama, if any
|
||||
+ *
|
||||
+ * @return The Llama following this one
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Llama getCaravanTail();
|
||||
+ // Purpur end
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Sat, 10 Aug 2019 22:19:56 -0500
|
||||
Subject: [PATCH] AFK API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/PlayerAFKEvent.java b/src/main/java/net/pl3x/purpur/event/PlayerAFKEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0c8b3e5e4ba412624357ea5662a78862bd9fc4be
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/PlayerAFKEvent.java
|
||||
@@ -0,0 +1,70 @@
|
||||
+package net.pl3x.purpur.event;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public class PlayerAFKEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private final boolean setAfk;
|
||||
+ private boolean shouldKick;
|
||||
+ private String broadcast;
|
||||
+ private boolean cancel;
|
||||
+
|
||||
+ public PlayerAFKEvent(@NotNull Player player, boolean setAfk, boolean shouldKick, @Nullable String broadcast, boolean async) {
|
||||
+ super(player, async);
|
||||
+ this.setAfk = setAfk;
|
||||
+ this.shouldKick = shouldKick;
|
||||
+ this.broadcast = broadcast;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Whether player is going afk or coming back
|
||||
+ *
|
||||
+ * @return True if going afk. False is coming back
|
||||
+ */
|
||||
+ public boolean isGoingAfk() {
|
||||
+ return setAfk;
|
||||
+ }
|
||||
+
|
||||
+ public boolean shouldKick() {
|
||||
+ return shouldKick;
|
||||
+ }
|
||||
+
|
||||
+ public void setShouldKick(boolean shouldKick) {
|
||||
+ this.shouldKick = shouldKick;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public String getBroadcastMsg() {
|
||||
+ return broadcast;
|
||||
+ }
|
||||
+
|
||||
+ public void setBroadcastMsg(@Nullable String broadcast) {
|
||||
+ this.broadcast = broadcast;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 27848ad0eee667e515685a5f1cef3e9bfc7a3f53..09729abc27b6cb3458e19af24137bbbc6e5cb63e 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -2139,4 +2139,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
@Override
|
||||
Spigot spigot();
|
||||
// Spigot end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Check if player is AFK
|
||||
+ *
|
||||
+ * @return True if AFK
|
||||
+ */
|
||||
+ boolean isAfk();
|
||||
+
|
||||
+ /**
|
||||
+ * Set player as AFK
|
||||
+ *
|
||||
+ * @param setAfk Whether to set AFK or not
|
||||
+ */
|
||||
+ void setAfk(boolean setAfk);
|
||||
+
|
||||
+ /**
|
||||
+ * Reset the idle timer back to 0
|
||||
+ */
|
||||
+ void resetIdleTimer();
|
||||
+ // Purpur end
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Sun, 26 May 2019 15:18:40 -0500
|
||||
Subject: [PATCH] Bring back server name
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 33f04d57b7df3a6f9743246ba9af6d67f4fa4b54..45c64a9e4f20428a9a448194f22697a17dfb8e1f 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1951,4 +1951,15 @@ public final class Bukkit {
|
||||
public static Server.Spigot spigot() {
|
||||
return server.spigot();
|
||||
}
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Get the name of this server
|
||||
+ * @return the name of the server
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static String getServerName() {
|
||||
+ return server.getServerName();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 1a319e2842f4b99951f1cddce8b2b4be9f5373a0..91641c358b10219d4098f40b53ea56f1cfa5defc 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1725,4 +1725,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@NotNull
|
||||
io.papermc.paper.datapack.DatapackManager getDatapackManager();
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Get the name of this server
|
||||
+ * @return the name of the server
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ String getServerName();
|
||||
+ // Purpur end
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 31 May 2019 00:08:28 -0500
|
||||
Subject: [PATCH] ExecuteCommandEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/ExecuteCommandEvent.java b/src/main/java/net/pl3x/purpur/event/ExecuteCommandEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3250bd4dc29a0cf79b08833d95a3321d1a6733f6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/ExecuteCommandEvent.java
|
||||
@@ -0,0 +1,130 @@
|
||||
+package net.pl3x.purpur.event;
|
||||
+
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * This event is called whenever someone runs a command
|
||||
+ */
|
||||
+public class ExecuteCommandEvent extends Event implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancel = false;
|
||||
+ private CommandSender sender;
|
||||
+ private Command command;
|
||||
+ private String label;
|
||||
+ private String[] args;
|
||||
+
|
||||
+ public ExecuteCommandEvent(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @Nullable String[] args) {
|
||||
+ this.sender = sender;
|
||||
+ this.command = command;
|
||||
+ this.label = label;
|
||||
+ this.args = args;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the command that the player is attempting to execute.
|
||||
+ *
|
||||
+ * @return Command the player is attempting to execute
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Command getCommand() {
|
||||
+ return command;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the command that the player will execute.
|
||||
+ *
|
||||
+ * @param command New command that the player will execute
|
||||
+ * @throws IllegalArgumentException if command is null or empty
|
||||
+ */
|
||||
+ public void setCommand(@NotNull Command command) throws IllegalArgumentException {
|
||||
+ Validate.notNull(command, "Command cannot be null");
|
||||
+ this.command = command;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the sender that this command will be executed as.
|
||||
+ *
|
||||
+ * @return Sender this command will be executed as
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public CommandSender getSender() {
|
||||
+ return sender;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the sender that this command will be executed as.
|
||||
+ *
|
||||
+ * @param sender New sender which this event will execute as
|
||||
+ * @throws IllegalArgumentException if the sender provided is null
|
||||
+ */
|
||||
+ public void setSender(@NotNull final CommandSender sender) throws IllegalArgumentException {
|
||||
+ Validate.notNull(sender, "Sender cannot be null");
|
||||
+ this.sender = sender;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the label used to execute this command
|
||||
+ *
|
||||
+ * @return Label used to execute this command
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getLabel() {
|
||||
+ return label;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the label used to execute this command
|
||||
+ *
|
||||
+ * @param label Label used
|
||||
+ */
|
||||
+ public void setLabel(@NotNull String label) {
|
||||
+ this.label = label;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the args passed to the command
|
||||
+ *
|
||||
+ * @return Args passed to the command
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String[] getArgs() {
|
||||
+ return args;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the args passed to the command
|
||||
+ *
|
||||
+ * @param args Args passed to the command
|
||||
+ */
|
||||
+ public void setArgs(@NotNull String[] args) {
|
||||
+ this.args = args;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
index 460fda05a62b12db2edcfb7ea8b2a5dd8e4b110d..1e0eb099933dded131d3c4db8f3cca2b6ed8e064 100644
|
||||
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
@@ -147,6 +147,19 @@ public class SimpleCommandMap implements CommandMap {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ String[] parsedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
+ net.pl3x.purpur.event.ExecuteCommandEvent event = new net.pl3x.purpur.event.ExecuteCommandEvent(sender, target, sentCommandLabel, parsedArgs);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return true; // cancelled
|
||||
+ }
|
||||
+
|
||||
+ sender = event.getSender();
|
||||
+ target = event.getCommand();
|
||||
+ sentCommandLabel = event.getLabel();
|
||||
+ parsedArgs = event.getArgs();
|
||||
+ // Purpur end
|
||||
+
|
||||
// Paper start - Plugins do weird things to workaround normal registration
|
||||
if (target.timings == null) {
|
||||
target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target);
|
||||
@@ -156,7 +169,7 @@ public class SimpleCommandMap implements CommandMap {
|
||||
try {
|
||||
try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources
|
||||
// Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
|
||||
- target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length));
|
||||
+ target.execute(sender, sentCommandLabel, parsedArgs); // Purpur
|
||||
} // target.timings.stopTiming(); // Spigot // Paper
|
||||
} catch (CommandException ex) {
|
||||
server.getPluginManager().callEvent(new ServerExceptionEvent(new ServerCommandException(ex, target, sender, args))); // Paper
|
@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Sun, 5 May 2019 12:58:19 -0500
|
||||
Subject: [PATCH] LivingEntity safeFallDistance
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index 9f0645dc5f76ee9ef73d88f768025429e5a9edf7..4ccbb3ef3c597ef9da2c6744f410283a1dc2538c 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -850,4 +850,20 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
*/
|
||||
void setHurtDirection(float hurtDirection);
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Gets the distance (in blocks) this entity can safely fall without taking damage
|
||||
+ *
|
||||
+ * @return Safe fall distance
|
||||
+ */
|
||||
+ float getSafeFallDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Set the distance (in blocks) this entity can safely fall without taking damage
|
||||
+ *
|
||||
+ * @param safeFallDistance Safe fall distance
|
||||
+ */
|
||||
+ void setSafeFallDistance(float safeFallDistance);
|
||||
+ // Purpur end
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 23 Jul 2019 10:07:24 -0500
|
||||
Subject: [PATCH] Lagging threshold
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 45c64a9e4f20428a9a448194f22697a17dfb8e1f..b3cd3e5288bdcdd928efb8cba97f504d8e3ec58e 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1961,5 +1961,14 @@ public final class Bukkit {
|
||||
public static String getServerName() {
|
||||
return server.getServerName();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Check if server is lagging according to laggy threshold setting
|
||||
+ *
|
||||
+ * @return True if lagging
|
||||
+ */
|
||||
+ public static boolean isLagging() {
|
||||
+ return server.isLagging();
|
||||
+ }
|
||||
// Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 91641c358b10219d4098f40b53ea56f1cfa5defc..f546e3422539d91f1fcb98c94a722c4b17ef0170 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1733,5 +1733,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
*/
|
||||
@NotNull
|
||||
String getServerName();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if server is lagging according to laggy threshold setting
|
||||
+ *
|
||||
+ * @return True if lagging
|
||||
+ */
|
||||
+ boolean isLagging();
|
||||
// Purpur end
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 5 Jul 2019 16:37:04 -0500
|
||||
Subject: [PATCH] ItemFactory#getMonsterEgg
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
index ec7c07564608386c3f7d4322d0af4cbb7d92bc74..39323b3151c733392333858a2dbf1f3f8637341e 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
@@ -242,4 +242,15 @@ public interface ItemFactory {
|
||||
@Deprecated
|
||||
net.md_5.bungee.api.chat.hover.content.Content hoverContentOf(@NotNull org.bukkit.entity.Entity entity, @NotNull net.md_5.bungee.api.chat.BaseComponent[] customName);
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Get a monster egg ItemStack from an EntityType
|
||||
+ *
|
||||
+ * @param type EntityType
|
||||
+ * @return ItemStack spawner egg
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ ItemStack getMonsterEgg(@Nullable org.bukkit.entity.EntityType type);
|
||||
+ // Purpur end
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 5 Jul 2019 18:21:15 -0500
|
||||
Subject: [PATCH] PlayerSetSpawnerTypeWithEggEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/PlayerSetSpawnerTypeWithEggEvent.java b/src/main/java/net/pl3x/purpur/event/PlayerSetSpawnerTypeWithEggEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c050b75e9a11ac728868fe95e3f89e6b99de6ad2
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/PlayerSetSpawnerTypeWithEggEvent.java
|
||||
@@ -0,0 +1,85 @@
|
||||
+package net.pl3x.purpur.event;
|
||||
+
|
||||
+import org.bukkit.block.Block;
|
||||
+import org.bukkit.block.CreatureSpawner;
|
||||
+import org.bukkit.entity.EntityType;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class PlayerSetSpawnerTypeWithEggEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private final Block block;
|
||||
+ private final CreatureSpawner spawner;
|
||||
+ private EntityType type;
|
||||
+ private boolean cancel;
|
||||
+
|
||||
+ public PlayerSetSpawnerTypeWithEggEvent(@NotNull Player player, @NotNull Block block, @NotNull CreatureSpawner spawner, @NotNull EntityType type) {
|
||||
+ super(player);
|
||||
+ this.block = block;
|
||||
+ this.spawner = spawner;
|
||||
+ this.type = type;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the spawner Block in the world
|
||||
+ *
|
||||
+ * @return Spawner Block
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Block getBlock() {
|
||||
+ return block;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the spawner state
|
||||
+ *
|
||||
+ * @return Spawner state
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public CreatureSpawner getSpawner() {
|
||||
+ return spawner;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the EntityType being set on the spawner
|
||||
+ *
|
||||
+ * @return EntityType being set
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public EntityType getEntityType() {
|
||||
+ return type;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the EntityType being set on the spawner
|
||||
+ *
|
||||
+ * @param type EntityType to set
|
||||
+ */
|
||||
+ public void setEntityType(@NotNull EntityType type) {
|
||||
+ this.type = type;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
@ -1,79 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 21 Nov 2016 17:02:11 -0500
|
||||
Subject: [PATCH] EMC - MonsterEggSpawnEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/entity/MonsterEggSpawnEvent.java b/src/main/java/net/pl3x/purpur/event/entity/MonsterEggSpawnEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8f1c9c421aeeb0ddf331f076a9b646c510ea4337
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/entity/MonsterEggSpawnEvent.java
|
||||
@@ -0,0 +1,67 @@
|
||||
+package net.pl3x.purpur.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.HumanEntity;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public class MonsterEggSpawnEvent extends Event implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean canceled;
|
||||
+
|
||||
+ private final Player player;
|
||||
+ private Entity entity;
|
||||
+ private final ItemStack item;
|
||||
+
|
||||
+ public MonsterEggSpawnEvent(@Nullable HumanEntity player, @NotNull Entity entity, @NotNull ItemStack item) {
|
||||
+ this.player = (Player) player;
|
||||
+ this.entity = entity;
|
||||
+ this.item = item;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public Entity getEntity() {
|
||||
+ return entity;
|
||||
+ }
|
||||
+
|
||||
+ public void setEntity(@Nullable Entity entity) {
|
||||
+ if (entity == null) {
|
||||
+ canceled = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ this.entity = entity;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public ItemStack getItem() {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCancelled() {
|
||||
+ return canceled;
|
||||
+ }
|
||||
+
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ canceled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Mon, 7 Oct 2019 00:15:28 -0500
|
||||
Subject: [PATCH] Villager#resetOffers
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java
|
||||
index c8777a476e38ef5e72b6709761990a339eb43d2b..ed703af452cd7db5e47608b4ff6ec049f76ed03a 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Villager.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Villager.java
|
||||
@@ -113,6 +113,13 @@ public interface Villager extends AbstractVillager {
|
||||
*/
|
||||
public void wakeup();
|
||||
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Reset this villager's trade offers
|
||||
+ */
|
||||
+ public void resetOffers();
|
||||
+ // Purpur end
|
||||
+
|
||||
/**
|
||||
* Represents Villager type, usually corresponding to what biome they spawn
|
||||
* in.
|
@ -1,37 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 2 May 2020 20:55:31 -0500
|
||||
Subject: [PATCH] Player invulnerabilities
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 09729abc27b6cb3458e19af24137bbbc6e5cb63e..d6b6508fd7ab245f657be262c54ae6dfa20415e7 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -2159,5 +2159,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* Reset the idle timer back to 0
|
||||
*/
|
||||
void resetIdleTimer();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if player is invulnerable from recently spawning or accepting a resource pack
|
||||
+ *
|
||||
+ * @return True if invulnerable
|
||||
+ */
|
||||
+ boolean isSpawnInvulnerable();
|
||||
+
|
||||
+ /**
|
||||
+ * Get invulnerable ticks remaining
|
||||
+ *
|
||||
+ * @return Invulnerable ticks
|
||||
+ */
|
||||
+ int getSpawnInvulnerableTicks();
|
||||
+
|
||||
+ /**
|
||||
+ * Set invulnerable ticks remaining
|
||||
+ *
|
||||
+ * @param invulnerableTicks Invulnerable ticks remaining
|
||||
+ */
|
||||
+ void setSpawnInvulnerableTicks(int invulnerableTicks);
|
||||
// Purpur end
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 19 Apr 2020 00:25:09 -0500
|
||||
Subject: [PATCH] Anvil API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/inventory/AnvilTakeResultEvent.java b/src/main/java/net/pl3x/purpur/event/inventory/AnvilTakeResultEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..85663c0a44695f7b7f01a68693cac3d99f4b56ca
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/inventory/AnvilTakeResultEvent.java
|
||||
@@ -0,0 +1,52 @@
|
||||
+package net.pl3x.purpur.event.inventory;
|
||||
+
|
||||
+import org.bukkit.entity.HumanEntity;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.inventory.InventoryEvent;
|
||||
+import org.bukkit.inventory.AnvilInventory;
|
||||
+import org.bukkit.inventory.InventoryView;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a player takes the result item out of an anvil
|
||||
+ */
|
||||
+public class AnvilTakeResultEvent extends InventoryEvent {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private final Player player;
|
||||
+ private final ItemStack result;
|
||||
+
|
||||
+ public AnvilTakeResultEvent(@NotNull HumanEntity player, @NotNull InventoryView view, @NotNull ItemStack result) {
|
||||
+ super(view);
|
||||
+ this.player = (Player) player;
|
||||
+ this.result = result;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public ItemStack getResult() {
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public AnvilInventory getInventory() {
|
||||
+ return (AnvilInventory) super.getInventory();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/inventory/AnvilUpdateResultEvent.java b/src/main/java/net/pl3x/purpur/event/inventory/AnvilUpdateResultEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2717ad82ccc0d39c5a69b8890303c245e9a17f83
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/inventory/AnvilUpdateResultEvent.java
|
||||
@@ -0,0 +1,35 @@
|
||||
+package net.pl3x.purpur.event.inventory;
|
||||
+
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.inventory.InventoryEvent;
|
||||
+import org.bukkit.inventory.AnvilInventory;
|
||||
+import org.bukkit.inventory.InventoryView;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when anvil slots change, triggering the result slot to be updated
|
||||
+ */
|
||||
+public class AnvilUpdateResultEvent extends InventoryEvent {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ public AnvilUpdateResultEvent(@NotNull InventoryView view) {
|
||||
+ super(view);
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public AnvilInventory getInventory() {
|
||||
+ return (AnvilInventory) super.getInventory();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/AnvilInventory.java b/src/main/java/org/bukkit/inventory/AnvilInventory.java
|
||||
index b95e563b5454306a9188ae3295309ee86a756477..435026e533ea9edb8c1800d35c63543ca023a904 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/AnvilInventory.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/AnvilInventory.java
|
||||
@@ -109,4 +109,14 @@ public interface AnvilInventory extends Inventory {
|
||||
setItem(2, result);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ boolean canBypassCost();
|
||||
+
|
||||
+ void setBypassCost(boolean bypassCost);
|
||||
+
|
||||
+ boolean canDoUnsafeEnchants();
|
||||
+
|
||||
+ void setDoUnsafeEnchants(boolean canDoUnsafeEnchants);
|
||||
+ // Purpur end
|
||||
}
|
@ -1,701 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 15 Mar 2020 20:52:12 -0500
|
||||
Subject: [PATCH] ItemStack convenience methods
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
|
||||
index e2b3470e3c9a97671723f5a67f722fb86fb07fbf..560b441ef35e507236e683b04f6a774c5949a078 100644
|
||||
--- a/src/main/java/org/bukkit/Material.java
|
||||
+++ b/src/main/java/org/bukkit/Material.java
|
||||
@@ -8731,4 +8731,40 @@ public enum Material implements Keyed {
|
||||
// </editor-fold>
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Purpur start
|
||||
+ public boolean isArmor() {
|
||||
+ switch (this) {
|
||||
+ // <editor-fold defaultstate="collapsed" desc="isarmor">
|
||||
+ case LEATHER_BOOTS:
|
||||
+ case LEATHER_CHESTPLATE:
|
||||
+ case LEATHER_HELMET:
|
||||
+ case LEATHER_LEGGINGS:
|
||||
+ case CHAINMAIL_BOOTS:
|
||||
+ case CHAINMAIL_CHESTPLATE:
|
||||
+ case CHAINMAIL_HELMET:
|
||||
+ case CHAINMAIL_LEGGINGS:
|
||||
+ case IRON_BOOTS:
|
||||
+ case IRON_CHESTPLATE:
|
||||
+ case IRON_HELMET:
|
||||
+ case IRON_LEGGINGS:
|
||||
+ case GOLDEN_BOOTS:
|
||||
+ case GOLDEN_CHESTPLATE:
|
||||
+ case GOLDEN_HELMET:
|
||||
+ case GOLDEN_LEGGINGS:
|
||||
+ case DIAMOND_BOOTS:
|
||||
+ case DIAMOND_CHESTPLATE:
|
||||
+ case DIAMOND_HELMET:
|
||||
+ case DIAMOND_LEGGINGS:
|
||||
+ case NETHERITE_BOOTS:
|
||||
+ case NETHERITE_CHESTPLATE:
|
||||
+ case NETHERITE_HELMET:
|
||||
+ case NETHERITE_LEGGINGS:
|
||||
+ case TURTLE_HELMET:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
index 3e2c08641edffcf00b230ad624685aaff30af0e5..fceba6780a15c274c4689eccbeb6dfb2eee25ed9 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
@@ -17,6 +17,18 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
+// Purpur start
|
||||
+import com.google.common.collect.Multimap;
|
||||
+import java.util.Collection;
|
||||
+import org.bukkit.attribute.Attribute;
|
||||
+import org.bukkit.attribute.AttributeModifier;
|
||||
+import org.bukkit.block.data.BlockData;
|
||||
+import org.bukkit.inventory.meta.BlockDataMeta;
|
||||
+import org.bukkit.inventory.meta.Repairable;
|
||||
+import org.bukkit.persistence.PersistentDataContainer;
|
||||
+import org.bukkit.persistence.PersistentDataHolder;
|
||||
+import com.destroystokyo.paper.Namespaced;
|
||||
+// Purpur end
|
||||
|
||||
/**
|
||||
* Represents a stack of items.
|
||||
@@ -914,4 +926,626 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor
|
||||
return Bukkit.getUnsafe().isValidRepairItemStack(toBeRepaired, this);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Gets the display name that is set.
|
||||
+ * <p>
|
||||
+ * Plugins should check that hasDisplayName() returns <code>true</code>
|
||||
+ * before calling this method.
|
||||
+ *
|
||||
+ * @return the display name that is set
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getDisplayName() {
|
||||
+ return getItemMeta().getDisplayName();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the display name.
|
||||
+ *
|
||||
+ * @param name the name to set
|
||||
+ */
|
||||
+ public void setDisplayName(@Nullable String name) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ itemMeta.setDisplayName(name);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for existence of a display name.
|
||||
+ *
|
||||
+ * @return true if this has a display name
|
||||
+ */
|
||||
+ public boolean hasDisplayName() {
|
||||
+ return hasItemMeta() && getItemMeta().hasDisplayName();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the localized display name that is set.
|
||||
+ * <p>
|
||||
+ * Plugins should check that hasLocalizedName() returns <code>true</code>
|
||||
+ * before calling this method.
|
||||
+ *
|
||||
+ * @return the localized name that is set
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getLocalizedName() {
|
||||
+ return getItemMeta().getLocalizedName();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the localized name.
|
||||
+ *
|
||||
+ * @param name the name to set
|
||||
+ */
|
||||
+ public void setLocalizedName(@Nullable String name) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ itemMeta.setLocalizedName(name);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for existence of a localized name.
|
||||
+ *
|
||||
+ * @return true if this has a localized name
|
||||
+ */
|
||||
+ public boolean hasLocalizedName() {
|
||||
+ return hasItemMeta() && getItemMeta().hasLocalizedName();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for existence of lore.
|
||||
+ *
|
||||
+ * @return true if this has lore
|
||||
+ */
|
||||
+ public boolean hasLore() {
|
||||
+ return hasItemMeta() && getItemMeta().hasLore();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for existence of the specified enchantment.
|
||||
+ *
|
||||
+ * @param ench enchantment to check
|
||||
+ * @return true if this enchantment exists for this meta
|
||||
+ */
|
||||
+ public boolean hasEnchant(@NotNull Enchantment ench) {
|
||||
+ return hasItemMeta() && getItemMeta().hasEnchant(ench);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for the level of the specified enchantment.
|
||||
+ *
|
||||
+ * @param ench enchantment to check
|
||||
+ * @return The level that the specified enchantment has, or 0 if none
|
||||
+ */
|
||||
+ public int getEnchantLevel(@NotNull Enchantment ench) {
|
||||
+ return getItemMeta().getEnchantLevel(ench);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a copy the enchantments in this ItemMeta. <br>
|
||||
+ * Returns an empty map if none.
|
||||
+ *
|
||||
+ * @return An immutable copy of the enchantments
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Map<Enchantment, Integer> getEnchants() {
|
||||
+ return getItemMeta().getEnchants();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Adds the specified enchantment to this item meta.
|
||||
+ *
|
||||
+ * @param ench Enchantment to add
|
||||
+ * @param level Level for the enchantment
|
||||
+ * @param ignoreLevelRestriction this indicates the enchantment should be
|
||||
+ * applied, ignoring the level limit
|
||||
+ * @return true if the item meta changed as a result of this call, false
|
||||
+ * otherwise
|
||||
+ */
|
||||
+ public boolean addEnchant(@NotNull Enchantment ench, int level, boolean ignoreLevelRestriction) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ boolean result = itemMeta.addEnchant(ench, level, ignoreLevelRestriction);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Removes the specified enchantment from this item meta.
|
||||
+ *
|
||||
+ * @param ench Enchantment to remove
|
||||
+ * @return true if the item meta changed as a result of this call, false
|
||||
+ * otherwise
|
||||
+ */
|
||||
+ public boolean removeEnchant(@NotNull Enchantment ench) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ boolean result = itemMeta.removeEnchant(ench);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for the existence of any enchantments.
|
||||
+ *
|
||||
+ * @return true if an enchantment exists on this meta
|
||||
+ */
|
||||
+ public boolean hasEnchants() {
|
||||
+ return hasItemMeta() && getItemMeta().hasEnchants();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks if the specified enchantment conflicts with any enchantments in
|
||||
+ * this ItemMeta.
|
||||
+ *
|
||||
+ * @param ench enchantment to test
|
||||
+ * @return true if the enchantment conflicts, false otherwise
|
||||
+ */
|
||||
+ public boolean hasConflictingEnchant(@NotNull Enchantment ench) {
|
||||
+ return hasItemMeta() && getItemMeta().hasConflictingEnchant(ench);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the custom model data.
|
||||
+ * <p>
|
||||
+ * CustomModelData is an integer that may be associated client side with a
|
||||
+ * custom item model.
|
||||
+ *
|
||||
+ * @param data the data to set, or null to clear
|
||||
+ */
|
||||
+ public void setCustomModelData(@Nullable Integer data) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ itemMeta.setCustomModelData(data);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the custom model data that is set.
|
||||
+ * <p>
|
||||
+ * CustomModelData is an integer that may be associated client side with a
|
||||
+ * custom item model.
|
||||
+ * <p>
|
||||
+ * Plugins should check that hasCustomModelData() returns <code>true</code>
|
||||
+ * before calling this method.
|
||||
+ *
|
||||
+ * @return the localized name that is set
|
||||
+ */
|
||||
+ public int getCustomModelData() {
|
||||
+ return getItemMeta().getCustomModelData();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for existence of custom model data.
|
||||
+ * <p>
|
||||
+ * CustomModelData is an integer that may be associated client side with a
|
||||
+ * custom item model.
|
||||
+ *
|
||||
+ * @return true if this has custom model data
|
||||
+ */
|
||||
+ public boolean hasCustomModelData() {
|
||||
+ return hasItemMeta() && getItemMeta().hasCustomModelData();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns whether the item has block data currently attached to it.
|
||||
+ *
|
||||
+ * @return whether block data is already attached
|
||||
+ */
|
||||
+ public boolean hasBlockData() {
|
||||
+ return hasItemMeta() && ((BlockDataMeta) getItemMeta()).hasBlockData();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the currently attached block data for this item or creates a new
|
||||
+ * one if one doesn't exist.
|
||||
+ *
|
||||
+ * The state is a copy, it must be set back (or to another item) with
|
||||
+ * {@link #setBlockData(BlockData)}
|
||||
+ *
|
||||
+ * @param material the material we wish to get this data in the context of
|
||||
+ * @return the attached data or new data
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public BlockData getBlockData(@NotNull Material material) {
|
||||
+ return ((BlockDataMeta) getItemMeta()).getBlockData(material);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Attaches a copy of the passed block data to the item.
|
||||
+ *
|
||||
+ * @param blockData the block data to attach to the block.
|
||||
+ * @throws IllegalArgumentException if the blockData is null or invalid for
|
||||
+ * this item.
|
||||
+ */
|
||||
+ public void setBlockData(@NotNull BlockData blockData) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ ((BlockDataMeta) itemMeta).setBlockData(blockData);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the repair penalty
|
||||
+ *
|
||||
+ * @return the repair penalty
|
||||
+ */
|
||||
+ public int getRepairCost() {
|
||||
+ return ((Repairable) getItemMeta()).getRepairCost();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the repair penalty
|
||||
+ *
|
||||
+ * @param cost repair penalty
|
||||
+ */
|
||||
+ public void setRepairCost(int cost) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ ((Repairable) itemMeta).setRepairCost(cost);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks to see if this has a repair penalty
|
||||
+ *
|
||||
+ * @return true if this has a repair penalty
|
||||
+ */
|
||||
+ public boolean hasRepairCost() {
|
||||
+ return hasItemMeta() && ((Repairable) getItemMeta()).hasRepairCost();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Return if the unbreakable tag is true. An unbreakable item will not lose
|
||||
+ * durability.
|
||||
+ *
|
||||
+ * @return true if the unbreakable tag is true
|
||||
+ */
|
||||
+ public boolean isUnbreakable() {
|
||||
+ return hasItemMeta() && getItemMeta().isUnbreakable();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the unbreakable tag. An unbreakable item will not lose durability.
|
||||
+ *
|
||||
+ * @param unbreakable true if set unbreakable
|
||||
+ */
|
||||
+ public void setUnbreakable(boolean unbreakable) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ itemMeta.setUnbreakable(unbreakable);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for the existence of any AttributeModifiers.
|
||||
+ *
|
||||
+ * @return true if any AttributeModifiers exist
|
||||
+ */
|
||||
+ public boolean hasAttributeModifiers() {
|
||||
+ return hasItemMeta() && getItemMeta().hasAttributeModifiers();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Return an immutable copy of all Attributes and
|
||||
+ * their modifiers in this ItemMeta.<br>
|
||||
+ * Returns null if none exist.
|
||||
+ *
|
||||
+ * @return an immutable {@link Multimap} of Attributes
|
||||
+ * and their AttributeModifiers, or null if none exist
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Multimap<Attribute, AttributeModifier> getAttributeModifiers() {
|
||||
+ return getItemMeta().getAttributeModifiers();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Return an immutable copy of all {@link Attribute}s and their
|
||||
+ * {@link AttributeModifier}s for a given {@link EquipmentSlot}.<br>
|
||||
+ * Any {@link AttributeModifier} that does have have a given
|
||||
+ * {@link EquipmentSlot} will be returned. This is because
|
||||
+ * AttributeModifiers without a slot are active in any slot.<br>
|
||||
+ * If there are no attributes set for the given slot, an empty map
|
||||
+ * will be returned.
|
||||
+ *
|
||||
+ * @param slot the {@link EquipmentSlot} to check
|
||||
+ * @return the immutable {@link Multimap} with the
|
||||
+ * respective Attributes and modifiers, or an empty map
|
||||
+ * if no attributes are set.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Multimap<Attribute, AttributeModifier> getAttributeModifiers(@Nullable EquipmentSlot slot) {
|
||||
+ return getItemMeta().getAttributeModifiers(slot);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Return an immutable copy of all {@link AttributeModifier}s
|
||||
+ * for a given {@link Attribute}
|
||||
+ *
|
||||
+ * @param attribute the {@link Attribute}
|
||||
+ * @return an immutable collection of {@link AttributeModifier}s
|
||||
+ * or null if no AttributeModifiers exist for the Attribute.
|
||||
+ * @throws NullPointerException if Attribute is null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Collection<AttributeModifier> getAttributeModifiers(@NotNull Attribute attribute) {
|
||||
+ return getItemMeta().getAttributeModifiers(attribute);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Add an Attribute and it's Modifier.
|
||||
+ * AttributeModifiers can now support {@link EquipmentSlot}s.
|
||||
+ * If not set, the {@link AttributeModifier} will be active in ALL slots.
|
||||
+ * <br>
|
||||
+ * Two {@link AttributeModifier}s that have the same {@link java.util.UUID}
|
||||
+ * cannot exist on the same Attribute.
|
||||
+ *
|
||||
+ * @param attribute the {@link Attribute} to modify
|
||||
+ * @param modifier the {@link AttributeModifier} specifying the modification
|
||||
+ * @return true if the Attribute and AttributeModifier were
|
||||
+ * successfully added
|
||||
+ * @throws NullPointerException if Attribute is null
|
||||
+ * @throws NullPointerException if AttributeModifier is null
|
||||
+ * @throws IllegalArgumentException if AttributeModifier already exists
|
||||
+ */
|
||||
+ public boolean addAttributeModifier(@NotNull Attribute attribute, @NotNull AttributeModifier modifier) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ boolean result = itemMeta.addAttributeModifier(attribute, modifier);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set all {@link Attribute}s and their {@link AttributeModifier}s.
|
||||
+ * To clear all currently set Attributes and AttributeModifiers use
|
||||
+ * null or an empty Multimap.
|
||||
+ * If not null nor empty, this will filter all entries that are not-null
|
||||
+ * and add them to the ItemStack.
|
||||
+ *
|
||||
+ * @param attributeModifiers the new Multimap containing the Attributes
|
||||
+ * and their AttributeModifiers
|
||||
+ */
|
||||
+ public void setAttributeModifiers(@Nullable Multimap<Attribute, AttributeModifier> attributeModifiers) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ itemMeta.setAttributeModifiers(attributeModifiers);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Remove all {@link AttributeModifier}s associated with the given
|
||||
+ * {@link Attribute}.
|
||||
+ * This will return false if nothing was removed.
|
||||
+ *
|
||||
+ * @param attribute attribute to remove
|
||||
+ * @return true if all modifiers were removed from a given
|
||||
+ * Attribute. Returns false if no attributes were
|
||||
+ * removed.
|
||||
+ * @throws NullPointerException if Attribute is null
|
||||
+ */
|
||||
+ public boolean removeAttributeModifier(@NotNull Attribute attribute) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ boolean result = itemMeta.removeAttributeModifier(attribute);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Remove all {@link Attribute}s and {@link AttributeModifier}s for a
|
||||
+ * given {@link EquipmentSlot}.<br>
|
||||
+ * If the given {@link EquipmentSlot} is null, this will remove all
|
||||
+ * {@link AttributeModifier}s that do not have an EquipmentSlot set.
|
||||
+ *
|
||||
+ * @param slot the {@link EquipmentSlot} to clear all Attributes and
|
||||
+ * their modifiers for
|
||||
+ * @return true if all modifiers were removed that match the given
|
||||
+ * EquipmentSlot.
|
||||
+ */
|
||||
+ public boolean removeAttributeModifier(@Nullable EquipmentSlot slot) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ boolean result = itemMeta.removeAttributeModifier(slot);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Remove a specific {@link Attribute} and {@link AttributeModifier}.
|
||||
+ * AttributeModifiers are matched according to their {@link java.util.UUID}.
|
||||
+ *
|
||||
+ * @param attribute the {@link Attribute} to remove
|
||||
+ * @param modifier the {@link AttributeModifier} to remove
|
||||
+ * @return if any attribute modifiers were remove
|
||||
+ *
|
||||
+ * @throws NullPointerException if the Attribute is null
|
||||
+ * @throws NullPointerException if the AttributeModifier is null
|
||||
+ *
|
||||
+ * @see AttributeModifier#getUniqueId()
|
||||
+ */
|
||||
+ public boolean removeAttributeModifier(@NotNull Attribute attribute, @NotNull AttributeModifier modifier) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ boolean result = itemMeta.removeAttributeModifier(attribute, modifier);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a custom tag container capable of storing tags on the object.
|
||||
+ *
|
||||
+ * Note that the tags stored on this container are all stored under their
|
||||
+ * own custom namespace therefore modifying default tags using this
|
||||
+ * {@link PersistentDataHolder} is impossible.
|
||||
+ *
|
||||
+ * @return the persistent metadata container
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PersistentDataContainer getPersistentDataContainer() {
|
||||
+ return getItemMeta().getPersistentDataContainer();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks to see if this item has damage
|
||||
+ *
|
||||
+ * @return true if this has damage
|
||||
+ */
|
||||
+ public boolean hasDamage() {
|
||||
+ return hasItemMeta() && ((Damageable) getItemMeta()).hasDamage();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the damage
|
||||
+ *
|
||||
+ * @return the damage
|
||||
+ */
|
||||
+ public int getDamage() {
|
||||
+ return ((Damageable) getItemMeta()).getDamage();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the damage
|
||||
+ *
|
||||
+ * @param damage item damage
|
||||
+ */
|
||||
+ public void setDamage(int damage) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ ((Damageable) itemMeta).setDamage(damage);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
|
||||
+ *
|
||||
+ * @return Set of {@link com.destroystokyo.paper.Namespaced}
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Set<Namespaced> getDestroyableKeys() {
|
||||
+ return getItemMeta().getDestroyableKeys();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
|
||||
+ *
|
||||
+ * @param canDestroy Collection of {@link com.destroystokyo.paper.Namespaced}
|
||||
+ */
|
||||
+ public void setDestroyableKeys(@NotNull Collection<Namespaced> canDestroy) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ itemMeta.setDestroyableKeys(canDestroy);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the collection of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
|
||||
+ *
|
||||
+ * @return Set of {@link com.destroystokyo.paper.Namespaced}
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Set<Namespaced> getPlaceableKeys() {
|
||||
+ return getItemMeta().getPlaceableKeys();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the set of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
|
||||
+ *
|
||||
+ * @param canPlaceOn Collection of {@link com.destroystokyo.paper.Namespaced}
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public void setPlaceableKeys(@NotNull Collection<Namespaced> canPlaceOn) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ itemMeta.setPlaceableKeys(canPlaceOn);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for the existence of any keys that the item can be placed on
|
||||
+ *
|
||||
+ * @return true if this item has placeable keys
|
||||
+ */
|
||||
+ public boolean hasPlaceableKeys() {
|
||||
+ return hasItemMeta() && getItemMeta().hasPlaceableKeys();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks for the existence of any keys that the item can destroy
|
||||
+ *
|
||||
+ * @return true if this item has destroyable keys
|
||||
+ */
|
||||
+ public boolean hasDestroyableKeys() {
|
||||
+ return hasItemMeta() && getItemMeta().hasDestroyableKeys();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Repairs this item by 1 durability
|
||||
+ */
|
||||
+ public void repair() {
|
||||
+ repair(1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Damages this item by 1 durability
|
||||
+ *
|
||||
+ * @return True if damage broke the item
|
||||
+ */
|
||||
+ public boolean damage() {
|
||||
+ return damage(1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Repairs this item's durability by amount
|
||||
+ *
|
||||
+ * @param amount Amount of durability to repair
|
||||
+ */
|
||||
+ public void repair(int amount) {
|
||||
+ damage(-amount);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Damages this item's durability by amount
|
||||
+ *
|
||||
+ * @param amount Amount of durability to damage
|
||||
+ * @return True if damage broke the item
|
||||
+ */
|
||||
+ public boolean damage(int amount) {
|
||||
+ return damage(amount, false);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Damages this item's durability by amount
|
||||
+ *
|
||||
+ * @param amount Amount of durability to damage
|
||||
+ * @param ignoreUnbreaking Ignores unbreaking enchantment
|
||||
+ * @return True if damage broke the item
|
||||
+ */
|
||||
+ public boolean damage(int amount, boolean ignoreUnbreaking) {
|
||||
+ Damageable damageable = (Damageable) getItemMeta();
|
||||
+ if (amount > 0) {
|
||||
+ int unbreaking = getEnchantLevel(Enchantment.DURABILITY);
|
||||
+ int reduce = 0;
|
||||
+ for (int i = 0; unbreaking > 0 && i < amount; ++i) {
|
||||
+ if (reduceDamage(java.util.concurrent.ThreadLocalRandom.current(), unbreaking)) {
|
||||
+ ++reduce;
|
||||
+ }
|
||||
+ }
|
||||
+ amount -= reduce;
|
||||
+ if (amount <= 0) {
|
||||
+ return isBroke(damageable.getDamage());
|
||||
+ }
|
||||
+ }
|
||||
+ int damage = damageable.getDamage() + amount;
|
||||
+ damageable.setDamage(damage);
|
||||
+ setItemMeta((ItemMeta) damageable);
|
||||
+ return isBroke(damage);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isBroke(int damage) {
|
||||
+ if (damage > getType().getMaxDurability()) {
|
||||
+ if (getAmount() > 0) {
|
||||
+ // ensure it "breaks"
|
||||
+ setAmount(0);
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private boolean reduceDamage(java.util.Random random, int unbreaking) {
|
||||
+ if (getType().isArmor()) {
|
||||
+ return random.nextFloat() < 0.6F;
|
||||
+ }
|
||||
+ return random.nextInt(unbreaking + 1) > 0;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 28 Jun 2020 21:50:55 -0500
|
||||
Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
index b42091752981a1f309ab350e9a394092cb334824..83c51bb5e09549a8205d27a53ff0102f9439d60a 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
@@ -206,4 +206,8 @@ public interface VanillaGoal<T extends Mob> extends Goal<T> {
|
||||
GoalKey<Zombie> ZOMBIE_ATTACK = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack"));
|
||||
GoalKey<Creature> STROLL_VILLAGE_GOLEM = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_village_golem"));
|
||||
GoalKey<Mob> UNIVERSAL_ANGER_RESET = GoalKey.of(Mob.class, NamespacedKey.minecraft("universal_anger_reset"));
|
||||
+ // Purpur start
|
||||
+ GoalKey<Phantom> FIND_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal_goal"));
|
||||
+ GoalKey<Phantom> ORBIT_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal_goal"));
|
||||
+ // Purpur end
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 10 Jul 2020 12:43:25 -0500
|
||||
Subject: [PATCH] ChatColor conveniences
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/ChatColor.java b/src/main/java/org/bukkit/ChatColor.java
|
||||
index 4594701d77c5d0f744bece871b98d9f6f73eb5a7..499b222dee1f11d497a29a9a263a5596401ca1eb 100644
|
||||
--- a/src/main/java/org/bukkit/ChatColor.java
|
||||
+++ b/src/main/java/org/bukkit/ChatColor.java
|
||||
@@ -413,4 +413,30 @@ public enum ChatColor {
|
||||
BY_CHAR.put(color.code, color);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Purpur start
|
||||
+ public static final Pattern HEX_PATTERN = Pattern.compile("(#[A-Fa-f0-9]{6})");
|
||||
+
|
||||
+ @Nullable
|
||||
+ public static String replaceHex(@Nullable String str) {
|
||||
+ if (str != null) {
|
||||
+ java.util.regex.Matcher matcher = HEX_PATTERN.matcher(str);
|
||||
+ while (matcher.find()) {
|
||||
+ String group = matcher.group(1);
|
||||
+ str = str.replace(group, net.md_5.bungee.api.ChatColor.of(group).toString());
|
||||
+ }
|
||||
+ }
|
||||
+ return str;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public static String color(@Nullable String str) {
|
||||
+ return color(str, true);
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public static String color(@Nullable String str, boolean parseHex) {
|
||||
+ return str != null ? net.md_5.bungee.api.ChatColor.translateAlternateColorCodes('&', parseHex ? replaceHex(str) : str) : str;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
@ -1,210 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Sat, 4 May 2019 00:57:16 -0500
|
||||
Subject: [PATCH] Ridables
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
index 83c51bb5e09549a8205d27a53ff0102f9439d60a..177143c9764e82981423879ed35625edd25d3ebf 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
@@ -209,5 +209,7 @@ public interface VanillaGoal<T extends Mob> extends Goal<T> {
|
||||
// Purpur start
|
||||
GoalKey<Phantom> FIND_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal_goal"));
|
||||
GoalKey<Phantom> ORBIT_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal_goal"));
|
||||
+ GoalKey<Mob> HAS_RIDER = GoalKey.of(Mob.class, NamespacedKey.minecraft("has_rider"));
|
||||
+ GoalKey<AbstractHorse> HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider"));
|
||||
// Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/entity/RidableMoveEvent.java b/src/main/java/net/pl3x/purpur/event/entity/RidableMoveEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..48e7ac392fe5efac8a4ce549e31a05ed817417e4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/entity/RidableMoveEvent.java
|
||||
@@ -0,0 +1,103 @@
|
||||
+package net.pl3x.purpur.event.entity;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.Mob;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Triggered when a ridable mob moves with a rider
|
||||
+ */
|
||||
+public class RidableMoveEvent extends EntityEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean canceled;
|
||||
+ private final Player rider;
|
||||
+ private Location from;
|
||||
+ private Location to;
|
||||
+
|
||||
+ public RidableMoveEvent(@NotNull Mob entity, @NotNull Player rider, @NotNull Location from, @NotNull Location to) {
|
||||
+ super(entity);
|
||||
+ this.rider = rider;
|
||||
+ this.from = from;
|
||||
+ this.to = to;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public Mob getEntity() {
|
||||
+ return (Mob) entity;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public Player getRider() {
|
||||
+ return rider;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCancelled() {
|
||||
+ return canceled;
|
||||
+ }
|
||||
+
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ canceled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the location this entity moved from
|
||||
+ *
|
||||
+ * @return Location the entity moved from
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location getFrom() {
|
||||
+ return from;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the location to mark as where the entity moved from
|
||||
+ *
|
||||
+ * @param from New location to mark as the entity's previous location
|
||||
+ */
|
||||
+ public void setFrom(@NotNull Location from) {
|
||||
+ validateLocation(from);
|
||||
+ this.from = from;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the location this entity moved to
|
||||
+ *
|
||||
+ * @return Location the entity moved to
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location getTo() {
|
||||
+ return to;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the location that this entity will move to
|
||||
+ *
|
||||
+ * @param to New Location this entity will move to
|
||||
+ */
|
||||
+ public void setTo(@NotNull Location to) {
|
||||
+ validateLocation(to);
|
||||
+ this.to = to;
|
||||
+ }
|
||||
+
|
||||
+ private void validateLocation(@NotNull Location loc) {
|
||||
+ Preconditions.checkArgument(loc != null, "Cannot use null location!");
|
||||
+ Preconditions.checkArgument(loc.getWorld() != null, "Cannot use null location with null world!");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/entity/RidableSpacebarEvent.java b/src/main/java/net/pl3x/purpur/event/entity/RidableSpacebarEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c0ec5a130985e8da4cc9e596a6b70503d2550f77
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/entity/RidableSpacebarEvent.java
|
||||
@@ -0,0 +1,37 @@
|
||||
+package net.pl3x.purpur.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class RidableSpacebarEvent extends EntityEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+
|
||||
+ public RidableSpacebarEvent(@NotNull Entity entity) {
|
||||
+ super(entity);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
|
||||
index 46985eaea3d3b00d1dd88c2dd5a2bc53d518c64f..38c6ecba4a6090ee42180ff52db42bac8e7f95d7 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -704,4 +704,35 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
*/
|
||||
public boolean isTicking();
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Get the riding player
|
||||
+ *
|
||||
+ * @return Riding player
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Player getRider();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if entity is being ridden
|
||||
+ *
|
||||
+ * @return True if being ridden
|
||||
+ */
|
||||
+ boolean hasRider();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if entity is ridable
|
||||
+ *
|
||||
+ * @return True if ridable
|
||||
+ */
|
||||
+ boolean isRidable();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if entity is ridable in water
|
||||
+ *
|
||||
+ * @return True if ridable in water
|
||||
+ */
|
||||
+ boolean isRidableInWater();
|
||||
+ // Purpur end
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 15 Aug 2020 11:18:27 -0500
|
||||
Subject: [PATCH] Configurable permission message upgrades
|
||||
|
||||
This allows the configurable permission message in paper.yml to be blank and also support newlines
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
|
||||
index c10fc8d2386301bc2caddcdb1cd18566bcaa8689..882c565ac2be3df976e7bbeb4dc80c9ac474a8b1 100644
|
||||
--- a/src/main/java/org/bukkit/command/Command.java
|
||||
+++ b/src/main/java/org/bukkit/command/Command.java
|
||||
@@ -184,9 +184,13 @@ public abstract class Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ String permissionMessage = this.permissionMessage;
|
||||
if (permissionMessage == null) {
|
||||
- target.sendMessage(Bukkit.getPermissionMessage()); // Paper
|
||||
- } else if (permissionMessage.length() != 0) {
|
||||
+ permissionMessage = Bukkit.getPermissionMessage();
|
||||
+ }
|
||||
+ if (permissionMessage.length() != 0) {
|
||||
+ // Purpur end
|
||||
for (String line : permissionMessage.replace("<permission>", permission).split("\n")) {
|
||||
target.sendMessage(line);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 17 Aug 2020 21:50:32 -0500
|
||||
Subject: [PATCH] LivingEntity#broadcastItemBreak
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index 4ccbb3ef3c597ef9da2c6744f410283a1dc2538c..42811d18ff304082f74f45794344891208599c04 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -865,5 +865,12 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
* @param safeFallDistance Safe fall distance
|
||||
*/
|
||||
void setSafeFallDistance(float safeFallDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Play item break animation for the item in specified equipment slot
|
||||
+ *
|
||||
+ * @param slot Equipment slot to play break animation for
|
||||
+ */
|
||||
+ void broadcastItemBreak(@NotNull org.bukkit.inventory.EquipmentSlot slot);
|
||||
// Purpur end
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 22 Aug 2020 17:42:08 -0500
|
||||
Subject: [PATCH] Item entity immunities
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Item.java b/src/main/java/org/bukkit/entity/Item.java
|
||||
index 0ee072645ecf1bf5feb74de6960947ef76db366e..5b9a20e0695218f1239d2bf1d0368291e2a10c06 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Item.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Item.java
|
||||
@@ -120,4 +120,62 @@ public interface Item extends Entity {
|
||||
*/
|
||||
public void setWillAge(boolean willAge);
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Set whether or not this item is immune to cactus
|
||||
+ *
|
||||
+ * @param immuneToCactus True to make immune to cactus
|
||||
+ */
|
||||
+ void setImmuneToCactus(boolean immuneToCactus);
|
||||
+
|
||||
+ /**
|
||||
+ * Check if item is immune to cactus
|
||||
+ *
|
||||
+ * @return True if immune to cactus
|
||||
+ */
|
||||
+ boolean isImmuneToCactus();
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether or not this item is immune to explosions
|
||||
+ *
|
||||
+ * @param immuneToExplosion True to make immune to explosions
|
||||
+ */
|
||||
+ void setImmuneToExplosion(boolean immuneToExplosion);
|
||||
+
|
||||
+ /**
|
||||
+ * Check if item is immune to explosions
|
||||
+ *
|
||||
+ * @return True if immune to explosions
|
||||
+ */
|
||||
+ boolean isImmuneToExplosion();
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether or not this item is immune to fire
|
||||
+ *
|
||||
+ * @param immuneToFire True to make immune to fire
|
||||
+ */
|
||||
+ void setImmuneToFire(boolean immuneToFire);
|
||||
+
|
||||
+ /**
|
||||
+ * Check if item is immune to fire
|
||||
+ *
|
||||
+ * @return True if immune to fire
|
||||
+ */
|
||||
+ boolean isImmuneToFire();
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether or not this item is immune to lightning
|
||||
+ *
|
||||
+ * @param immuneToLightning True to make immune to lightning
|
||||
+ */
|
||||
+ void setImmuneToLightning(boolean immuneToLightning);
|
||||
+
|
||||
+ /**
|
||||
+ * Check if item is immune to lightning
|
||||
+ *
|
||||
+ * @return True if immune to lightning
|
||||
+ */
|
||||
+ boolean isImmuneToLightning();
|
||||
+ // Purpur end
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Parker Hawke <hawkeboyz2@hotmail.com>
|
||||
Date: Sat, 27 Jun 2020 18:43:37 -0400
|
||||
Subject: [PATCH] Spigot - Improve output of plugins command
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
index 1aa58c59e1e8738bbdc77752885ff3b18b29de42..4974fc518c3645e6e060ff52e71a47a86d52ec5c 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
@@ -11,6 +11,15 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
+// Spigot start
|
||||
+import net.md_5.bungee.api.chat.BaseComponent;
|
||||
+import net.md_5.bungee.api.chat.ClickEvent;
|
||||
+import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
+import net.md_5.bungee.api.chat.HoverEvent;
|
||||
+import net.md_5.bungee.api.chat.ComponentBuilder.FormatRetention;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.plugin.PluginDescriptionFile;
|
||||
+// Spigot end
|
||||
|
||||
public class PluginsCommand extends BukkitCommand {
|
||||
public PluginsCommand(@NotNull String name) {
|
||||
@@ -25,7 +34,13 @@ public class PluginsCommand extends BukkitCommand {
|
||||
public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) {
|
||||
if (!testPermission(sender)) return true;
|
||||
|
||||
- sender.sendMessage("Plugins " + getPluginList());
|
||||
+ // Spigot start
|
||||
+ if (sender instanceof Player && sender.hasPermission("bukkit.command.version")) {
|
||||
+ sender.spigot().sendMessage(getPluginListSpigot());
|
||||
+ } else {
|
||||
+ sender.sendMessage("Plugins " + getPluginList());
|
||||
+ }
|
||||
+ // Spigot end
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,4 +86,72 @@ public class PluginsCommand extends BukkitCommand {
|
||||
// Paper end
|
||||
}
|
||||
|
||||
+ // Spigot start
|
||||
+ @NotNull
|
||||
+ private BaseComponent[] getPluginListSpigot() {
|
||||
+ Plugin[] plugins = Bukkit.getPluginManager().getPlugins();
|
||||
+ ComponentBuilder pluginList = new ComponentBuilder("Plugins (" + plugins.length + "): ");
|
||||
+
|
||||
+ int index = 0;
|
||||
+ for (Plugin plugin : plugins) {
|
||||
+ if (index++ > 0) {
|
||||
+ pluginList.append(", ", FormatRetention.NONE).color(net.md_5.bungee.api.ChatColor.WHITE);
|
||||
+ }
|
||||
+
|
||||
+ // Event components
|
||||
+ PluginDescriptionFile description = plugin.getDescription();
|
||||
+ ComponentBuilder hoverEventComponents = new ComponentBuilder();
|
||||
+ hoverEventComponents.append("Version: ").color(net.md_5.bungee.api.ChatColor.WHITE).append(description.getVersion()).color(net.md_5.bungee.api.ChatColor.GREEN);
|
||||
+
|
||||
+ if (description.getDescription() != null) {
|
||||
+ hoverEventComponents.append("\nDescription: ").color(net.md_5.bungee.api.ChatColor.WHITE).append(description.getDescription()).color(net.md_5.bungee.api.ChatColor.GREEN);
|
||||
+ }
|
||||
+
|
||||
+ if (description.getWebsite() != null) {
|
||||
+ hoverEventComponents.append("\nWebsite: ").color(net.md_5.bungee.api.ChatColor.WHITE).append(description.getWebsite()).color(net.md_5.bungee.api.ChatColor.GREEN);
|
||||
+ }
|
||||
+
|
||||
+ if (!description.getAuthors().isEmpty()) {
|
||||
+ if (description.getAuthors().size() == 1) {
|
||||
+ hoverEventComponents.append("\nAuthor: ");
|
||||
+ } else {
|
||||
+ hoverEventComponents.append("\nAuthors: ");
|
||||
+ }
|
||||
+
|
||||
+ hoverEventComponents.color(net.md_5.bungee.api.ChatColor.WHITE).append(getAuthors(description));
|
||||
+ }
|
||||
+
|
||||
+ HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverEventComponents.create());
|
||||
+ ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/version " + description.getName());
|
||||
+
|
||||
+ // Plugin list entry
|
||||
+ pluginList.append(plugin.getDescription().getName());
|
||||
+ pluginList.color(plugin.isEnabled() ? net.md_5.bungee.api.ChatColor.GREEN : net.md_5.bungee.api.ChatColor.RED);
|
||||
+ pluginList.event(hoverEvent).event(clickEvent);
|
||||
+
|
||||
+ if (plugin.getDescription().getProvides().size() > 0) {
|
||||
+ pluginList.append("( ", FormatRetention.NONE).color(net.md_5.bungee.api.ChatColor.WHITE).append(String.join(", ", plugin.getDescription().getProvides())).append(")");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return pluginList.create();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ private BaseComponent[] getAuthors(@NotNull final PluginDescriptionFile description) {
|
||||
+ ComponentBuilder result = new ComponentBuilder();
|
||||
+ List<String> authors = description.getAuthors();
|
||||
+
|
||||
+ for (int i = 0; i < authors.size(); i++) {
|
||||
+ if (i > 0) {
|
||||
+ result.append(i < authors.size() - 1 ? ", " : " and ", FormatRetention.NONE);
|
||||
+ result.color(net.md_5.bungee.api.ChatColor.WHITE);
|
||||
+ }
|
||||
+
|
||||
+ result.append(authors.get(i)).color(net.md_5.bungee.api.ChatColor.GREEN);
|
||||
+ }
|
||||
+
|
||||
+ return result.create();
|
||||
+ }
|
||||
+ // Spigot end
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: nitricspace <nitricspace@users.noreply.github.com>
|
||||
Date: Wed, 23 Sep 2020 22:14:38 +0100
|
||||
Subject: [PATCH] Add option to disable zombie aggressiveness towards villagers
|
||||
when lagging
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
index 177143c9764e82981423879ed35625edd25d3ebf..da638f9745aceebe4f2ca90823308c6879c75ae7 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
@@ -211,5 +211,7 @@ public interface VanillaGoal<T extends Mob> extends Goal<T> {
|
||||
GoalKey<Phantom> ORBIT_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal_goal"));
|
||||
GoalKey<Mob> HAS_RIDER = GoalKey.of(Mob.class, NamespacedKey.minecraft("has_rider"));
|
||||
GoalKey<AbstractHorse> HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider"));
|
||||
+ GoalKey<Drowned> DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager"));
|
||||
+ GoalKey<Zombie> ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager"));
|
||||
// Purpur end
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 2 Oct 2020 17:43:24 -0500
|
||||
Subject: [PATCH] Add predicate to recipe's ExactChoice ingredient
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java
|
||||
index 90208bc96085f05a3b657b9467b1670d00b03104..c59d5e4ef9641fd73463b177239226866272745b 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/RecipeChoice.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/RecipeChoice.java
|
||||
@@ -10,6 +10,7 @@ import java.util.function.Predicate;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable; // Purpur
|
||||
|
||||
/**
|
||||
* Represents a potential item match within a recipe. All choices within a
|
||||
@@ -152,6 +153,7 @@ public interface RecipeChoice extends Predicate<ItemStack>, Cloneable {
|
||||
public static class ExactChoice implements RecipeChoice {
|
||||
|
||||
private List<ItemStack> choices;
|
||||
+ private Predicate<ItemStack> predicate; // Purpur
|
||||
|
||||
public ExactChoice(@NotNull ItemStack stack) {
|
||||
this(Arrays.asList(stack));
|
||||
@@ -196,6 +198,7 @@ public interface RecipeChoice extends Predicate<ItemStack>, Cloneable {
|
||||
|
||||
@Override
|
||||
public boolean test(@NotNull ItemStack t) {
|
||||
+ if (predicate != null) return predicate.test(t); // Purpur
|
||||
for (ItemStack match : choices) {
|
||||
if (t.isSimilar(match)) {
|
||||
return true;
|
||||
@@ -205,6 +208,17 @@ public interface RecipeChoice extends Predicate<ItemStack>, Cloneable {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ @Nullable
|
||||
+ public Predicate<ItemStack> getPredicate() {
|
||||
+ return predicate;
|
||||
+ }
|
||||
+
|
||||
+ public void setPredicate(@Nullable Predicate<ItemStack> predicate) {
|
||||
+ this.predicate = predicate;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
@ -1,56 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 24 Nov 2020 04:30:34 -0600
|
||||
Subject: [PATCH] Add critical hit check to EntityDamagedByEntityEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
|
||||
index 869bad7405ec7fa67728e90d8b9f2e11b542611f..05fde759bbdf6068f140b4428bbcb355e22d6b28 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
|
||||
@@ -10,15 +10,28 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class EntityDamageByEntityEvent extends EntityDamageEvent {
|
||||
private final Entity damager;
|
||||
+ private final boolean isCritical; // Purpur
|
||||
|
||||
public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage) {
|
||||
+ // Purpur start
|
||||
+ this(damager, damagee, cause, damage, false);
|
||||
+ }
|
||||
+ public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage, boolean isCritical) {
|
||||
+ // Purpur end
|
||||
super(damagee, cause, damage);
|
||||
this.damager = damager;
|
||||
+ this.isCritical = isCritical; // Purpur
|
||||
}
|
||||
|
||||
public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
|
||||
+ // Purpur start
|
||||
+ this(damager, damagee, cause, modifiers, modifierFunctions, false);
|
||||
+ }
|
||||
+ public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions, boolean isCritical) {
|
||||
+ // Purpur end
|
||||
super(damagee, cause, modifiers, modifierFunctions);
|
||||
this.damager = damager;
|
||||
+ this.isCritical = isCritical; // Purpur
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,4 +43,16 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent {
|
||||
public Entity getDamager() {
|
||||
return damager;
|
||||
}
|
||||
+
|
||||
+ // Purpur start
|
||||
+
|
||||
+ /**
|
||||
+ * Whether this damage was done by a critical hit
|
||||
+ *
|
||||
+ * @return True if critical hit
|
||||
+ */
|
||||
+ public boolean isCritical() {
|
||||
+ return this.isCritical;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Mon, 30 Nov 2020 06:02:54 -0600
|
||||
Subject: [PATCH] Left handed API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Mob.java b/src/main/java/org/bukkit/entity/Mob.java
|
||||
index 7d4ce660adb21e579e564796568945ee20f0ca59..4205dc5746dafd966f95103cdd2a1a55e79642f8 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Mob.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Mob.java
|
||||
@@ -146,4 +146,20 @@ public interface Mob extends LivingEntity, Lootable {
|
||||
* @return whether the mob is aware
|
||||
*/
|
||||
public boolean isAware();
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Check if Mob is left-handed
|
||||
+ *
|
||||
+ * @return True if left-handed
|
||||
+ */
|
||||
+ public boolean isLeftHanded();
|
||||
+
|
||||
+ /**
|
||||
+ * Set if Mob is left-handed
|
||||
+ *
|
||||
+ * @param leftHanded True if left-handed
|
||||
+ */
|
||||
+ public void setLeftHanded(boolean leftHanded);
|
||||
+ // Purpur end
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 8 Dec 2020 09:48:18 -0600
|
||||
Subject: [PATCH] Alphabetize in-game /plugins list
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
index 4974fc518c3645e6e060ff52e71a47a86d52ec5c..37cc5d7e9db89e4ef7ab16da1b159bd19134a4ff 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
@@ -2,6 +2,7 @@ package org.bukkit.command.defaults;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
+import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
@@ -89,7 +90,7 @@ public class PluginsCommand extends BukkitCommand {
|
||||
// Spigot start
|
||||
@NotNull
|
||||
private BaseComponent[] getPluginListSpigot() {
|
||||
- Plugin[] plugins = Bukkit.getPluginManager().getPlugins();
|
||||
+ Plugin[] plugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).sorted(Comparator.comparing(plugin -> plugin.getName().toLowerCase())).toArray(Plugin[]::new); // Purpur
|
||||
ComponentBuilder pluginList = new ComponentBuilder("Plugins (" + plugins.length + "): ");
|
||||
|
||||
int index = 0;
|
@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Encode42 <me@encode42.dev>
|
||||
Date: Tue, 8 Dec 2020 17:15:15 -0500
|
||||
Subject: [PATCH] Rabid Wolf API
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
index da638f9745aceebe4f2ca90823308c6879c75ae7..39f77041133228c4bd4cec2427ad0bae8e739d4a 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
@@ -213,5 +213,6 @@ public interface VanillaGoal<T extends Mob> extends Goal<T> {
|
||||
GoalKey<AbstractHorse> HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider"));
|
||||
GoalKey<Drowned> DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager"));
|
||||
GoalKey<Zombie> ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager"));
|
||||
+ GoalKey<Wolf> AVOID_RABID_WOLVES = GoalKey.of(Wolf.class, NamespacedKey.minecraft("avoid_rabid_wolves"));
|
||||
// Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Wolf.java b/src/main/java/org/bukkit/entity/Wolf.java
|
||||
index 0e5decadf31140d6cb121c298f935ccc12c7a7e7..c1fd30fe4cd4eec11eb8298f059d14584b7dd7ec 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Wolf.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Wolf.java
|
||||
@@ -39,4 +39,20 @@ public interface Wolf extends Tameable, Sittable {
|
||||
* @param color the color to apply
|
||||
*/
|
||||
public void setCollarColor(@NotNull DyeColor color);
|
||||
+
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * Checks if this wolf is rabid
|
||||
+ *
|
||||
+ * @return whether the wolf is rabid
|
||||
+ */
|
||||
+ public boolean isRabid();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets this wolf to be rabid or not
|
||||
+ *
|
||||
+ * @param rabid whether the wolf should be rabid
|
||||
+ */
|
||||
+ public void setRabid(boolean rabid);
|
||||
+ // Purpur end
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 24 Dec 2020 11:00:04 -0600
|
||||
Subject: [PATCH] Full netherite armor grants fire resistance
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java b/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java
|
||||
index 16b5fd279b0cb926900247618bcdb381a93f5a35..d592c62aadb3245396865c098c5979f2a162f868 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java
|
||||
@@ -213,6 +213,12 @@ public class EntityPotionEffectEvent extends EntityEvent implements Cancellable
|
||||
* When all effects are removed due to a bucket of milk.
|
||||
*/
|
||||
MILK,
|
||||
+ // Purpur start
|
||||
+ /**
|
||||
+ * When a player wears full netherite armor
|
||||
+ */
|
||||
+ NETHERITE_ARMOR,
|
||||
+ // Purpur end
|
||||
/**
|
||||
* When a player gets bad omen after killing a patrol captain.
|
||||
*/
|
@ -1,141 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Sat, 9 Jan 2021 15:26:04 +0100
|
||||
Subject: [PATCH] Add EntityTeleportHinderedEvent
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/entity/EntityTeleportHinderedEvent.java b/src/main/java/net/pl3x/purpur/event/entity/EntityTeleportHinderedEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e6fcc4027cb70061b804460b39e00cca273d35ad
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/entity/EntityTeleportHinderedEvent.java
|
||||
@@ -0,0 +1,117 @@
|
||||
+package net.pl3x.purpur.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an entity is hindered from teleporting.
|
||||
+ */
|
||||
+public class EntityTeleportHinderedEvent extends EntityEvent {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ private final Reason reason;
|
||||
+
|
||||
+ @Nullable
|
||||
+ private final TeleportCause teleportCause;
|
||||
+
|
||||
+ private boolean retry = false;
|
||||
+
|
||||
+ public EntityTeleportHinderedEvent(@NotNull Entity what, @NotNull Reason reason,
|
||||
+ @Nullable TeleportCause teleportCause) {
|
||||
+ super(what);
|
||||
+ this.reason = reason;
|
||||
+ this.teleportCause = teleportCause;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return why the teleport was hindered.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Reason getReason() {
|
||||
+ return reason;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return why the teleport occurred if cause was given, otherwise {@code null}.
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public TeleportCause getTeleportCause() {
|
||||
+ return teleportCause;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Whether the teleport should be retried.
|
||||
+ * <p>
|
||||
+ * Note that this can put the server in a never-ending loop of trying to teleport someone resulting in a stack
|
||||
+ * overflow. Do not retry more than necessary.
|
||||
+ * </p>
|
||||
+ *
|
||||
+ * @return whether the teleport should be retried.
|
||||
+ */
|
||||
+ public boolean shouldRetry() {
|
||||
+ return retry;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets whether the teleport should be retried.
|
||||
+ * <p>
|
||||
+ * Note that this can put the server in a never-ending loop of trying to teleport someone resulting in a stack
|
||||
+ * overflow. Do not retry more than necessary.
|
||||
+ * </p>
|
||||
+ *
|
||||
+ * @param retry whether the teleport should be retried.
|
||||
+ */
|
||||
+ public void setShouldRetry(boolean retry) {
|
||||
+ this.retry = retry;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Calls the event and tests if should retry.
|
||||
+ *
|
||||
+ * @return whether the teleport should be retried.
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean callEvent() {
|
||||
+ super.callEvent();
|
||||
+ return shouldRetry();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Reason for hindrance in teleports.
|
||||
+ */
|
||||
+ public enum Reason {
|
||||
+ /**
|
||||
+ * The teleported entity is a passenger of another entity.
|
||||
+ */
|
||||
+ IS_PASSENGER,
|
||||
+
|
||||
+ /**
|
||||
+ * The teleported entity has passengers.
|
||||
+ */
|
||||
+ IS_VEHICLE,
|
||||
+
|
||||
+ /**
|
||||
+ * The teleport event was cancelled.
|
||||
+ * <p>
|
||||
+ * This is only caused by players teleporting.
|
||||
+ * </p>
|
||||
+ */
|
||||
+ EVENT_CANCELLED,
|
||||
+ }
|
||||
+}
|
@ -1,112 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nahuel <nahueldolores@hotmail.com>
|
||||
Date: Sat, 9 Jan 2021 15:33:52 +0100
|
||||
Subject: [PATCH] Add StructureGenerateEvent
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Co-authored-by: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/event/world/StructureGenerateEvent.java b/src/main/java/net/pl3x/purpur/event/world/StructureGenerateEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e77f45f761368da9b230c425d975a717cf4d10fd
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/event/world/StructureGenerateEvent.java
|
||||
@@ -0,0 +1,68 @@
|
||||
+package net.pl3x.purpur.event.world;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.StructureType;
|
||||
+import org.bukkit.World;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.world.WorldEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class StructureGenerateEvent extends WorldEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ private final StructureType structureType;
|
||||
+ private final int chunkX;
|
||||
+ private final int chunkZ;
|
||||
+
|
||||
+ private boolean cancel = false;
|
||||
+
|
||||
+ public StructureGenerateEvent(@NotNull World world,
|
||||
+ @NotNull StructureType structureType, int chunkX, int chunkZ) {
|
||||
+ super(!Bukkit.isPrimaryThread(), world); // Structure generation is not necessarily on the main thread as of 1.16.
|
||||
+ this.structureType = structureType;
|
||||
+ this.chunkX = chunkX;
|
||||
+ this.chunkZ = chunkZ;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public World getWorld() {
|
||||
+ return super.getWorld();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public StructureType getStructureType() {
|
||||
+ return structureType;
|
||||
+ }
|
||||
+
|
||||
+ public int getChunkX() {
|
||||
+ return chunkX;
|
||||
+ }
|
||||
+
|
||||
+ public int getChunkZ() {
|
||||
+ return chunkZ;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/event/world/WorldEvent.java b/src/main/java/org/bukkit/event/world/WorldEvent.java
|
||||
index cffeff33f007d3b03b7c862b25be453f705da739..1fa083d53dce161ef9e9f19407f230c94b2d7d15 100644
|
||||
--- a/src/main/java/org/bukkit/event/world/WorldEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/world/WorldEvent.java
|
||||
@@ -10,6 +10,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
public abstract class WorldEvent extends Event {
|
||||
private final World world;
|
||||
|
||||
+ // Purpur start
|
||||
+ public WorldEvent(boolean isAsync, @NotNull final World world) {
|
||||
+ super(isAsync);
|
||||
+ this.world = world;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
public WorldEvent(@NotNull final World world) {
|
||||
this.world = world;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Sat, 9 Jan 2021 21:21:27 +0100
|
||||
Subject: [PATCH] Add unsafe Entity serialization API
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
index ef3011d74ce9acf02d0ee857033816854134ec0e..b2502aaab690b1414a1adffdf64e5a5456feb99c 100644
|
||||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
+++ b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@@ -194,4 +194,28 @@ public interface UnsafeValues {
|
||||
*/
|
||||
int getProtocolVersion();
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+
|
||||
+ /**
|
||||
+ * Serialize entity to byte array
|
||||
+ *
|
||||
+ * @param entity entity to serialize
|
||||
+ * @return serialized entity
|
||||
+ */
|
||||
+ byte[] serializeEntity(org.bukkit.entity.Entity entity);
|
||||
+
|
||||
+ /**
|
||||
+ * Deserialize an entity from byte array
|
||||
+ * <p>
|
||||
+ * The entity is not automatically spawned in the world. You will have to spawn
|
||||
+ * the entity yourself with {@link org.bukkit.entity.Entity#spawnAt(Location)} or
|
||||
+ * {@link org.bukkit.entity.Entity#spawnAt(Location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason)}
|
||||
+ *
|
||||
+ * @param data serialized entity
|
||||
+ * @param world world entity belongs in
|
||||
+ * @return deserialized entity
|
||||
+ */
|
||||
+ org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world);
|
||||
+ // Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
|
||||
index b47e31d2b9b41b39b46892fe10bf36d82c5d8e1b..7fa5242bd44c9b19648d79fa8fecbb7ee125288e 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -751,5 +751,24 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
* @return True if ridable in water
|
||||
*/
|
||||
boolean isRidableInWater();
|
||||
+
|
||||
+ /**
|
||||
+ * Spawn this entity in the world at the given {@link Location} with the default spawn reason.
|
||||
+ *
|
||||
+ * @param location The location at which to spawn the entity.
|
||||
+ * @return Whether the entity was successfully spawned.
|
||||
+ */
|
||||
+ default boolean spawnAt(@NotNull Location location) {
|
||||
+ return spawnAt(location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Spawn this entity in the world at the given {@link Location} with the reason given.
|
||||
+ *
|
||||
+ * @param location The location at which to spawn the entity.
|
||||
+ * @param spawnReason The reason for which the entity was spawned.
|
||||
+ * @return Whether the entity was successfully spawned.
|
||||
+ */
|
||||
+ boolean spawnAt(@NotNull Location location, @NotNull org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason);
|
||||
// Purpur end
|
||||
}
|
@ -1,867 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Wed, 17 Mar 2021 15:56:47 -0500
|
||||
Subject: [PATCH] Conflict on change for adventure deprecations
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index b3cd3e5288bdcdd928efb8cba97f504d8e3ec58e..8036c66af0bc6b11ffd0f716138901bcfea007e1 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -303,7 +303,7 @@ public final class Bukkit {
|
||||
* @return the number of players
|
||||
* @deprecated in favour of {@link Server#sendMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public static int broadcastMessage(@NotNull String message) {
|
||||
return server.broadcastMessage(message);
|
||||
}
|
||||
@@ -935,7 +935,7 @@ public final class Bukkit {
|
||||
* @return number of message recipients
|
||||
* @deprecated in favour of {@link #broadcast(net.kyori.adventure.text.Component, String)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public static int broadcast(@NotNull String message, @NotNull String permission) {
|
||||
return server.broadcast(message, permission);
|
||||
}
|
||||
@@ -1212,7 +1212,7 @@ public final class Bukkit {
|
||||
*
|
||||
* @see InventoryType#isCreatable()
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
public static Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, @NotNull String title) {
|
||||
return server.createInventory(owner, type, title);
|
||||
@@ -1262,7 +1262,7 @@ public final class Bukkit {
|
||||
* @throws IllegalArgumentException if the size is not a multiple of 9
|
||||
* @deprecated in favour of {@link #createInventory(InventoryHolder, InventoryType, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
public static Inventory createInventory(@Nullable InventoryHolder owner, int size, @NotNull String title) throws IllegalArgumentException {
|
||||
return server.createInventory(owner, size, title);
|
||||
@@ -1289,7 +1289,7 @@ public final class Bukkit {
|
||||
* @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public static Merchant createMerchant(@Nullable String title) {
|
||||
return server.createMerchant(title);
|
||||
}
|
||||
@@ -1378,7 +1378,7 @@ public final class Bukkit {
|
||||
* @deprecated in favour of {@link #motd()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public static String getMotd() {
|
||||
return server.getMotd();
|
||||
}
|
||||
@@ -1400,7 +1400,7 @@ public final class Bukkit {
|
||||
* @deprecated in favour of {@link #shutdownMessage()}
|
||||
*/
|
||||
@Nullable
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public static String getShutdownMessage() {
|
||||
return server.getShutdownMessage();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index a126581c74da8fae4c86fde2f28a850150c408cd..0f66655541dbb0dbb05a13a3612bb46cfb2b538a 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -250,7 +250,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @return the number of players
|
||||
* @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public int broadcastMessage(@NotNull String message);
|
||||
|
||||
// Paper start
|
||||
@@ -773,7 +773,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @return number of message recipients
|
||||
* @deprecated in favour of {@link #broadcast(net.kyori.adventure.text.Component, String)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public int broadcast(@NotNull String message, @NotNull String permission);
|
||||
// Paper start
|
||||
/**
|
||||
@@ -1024,7 +1024,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
*
|
||||
* @see InventoryType#isCreatable()
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, @NotNull String title);
|
||||
|
||||
@@ -1068,7 +1068,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @throws IllegalArgumentException if the size is not a multiple of 9
|
||||
* @deprecated in favour of {@link #createInventory(InventoryHolder, int, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
Inventory createInventory(@Nullable InventoryHolder owner, int size, @NotNull String title) throws IllegalArgumentException;
|
||||
|
||||
@@ -1091,7 +1091,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
Merchant createMerchant(@Nullable String title);
|
||||
|
||||
/**
|
||||
@@ -1164,7 +1164,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @deprecated in favour of {@link #motd()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
String getMotd();
|
||||
|
||||
// Paper start
|
||||
@@ -1182,7 +1182,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @deprecated in favour of {@link #shutdownMessage()}
|
||||
*/
|
||||
@Nullable
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
String getShutdownMessage();
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/block/Sign.java b/src/main/java/org/bukkit/block/Sign.java
|
||||
index 6ea9b54d95d80070c01a612c0ce2ab37f0b4ad41..fe9ec9cb7875df4a40d1c4155e13cca9b3628b30 100644
|
||||
--- a/src/main/java/org/bukkit/block/Sign.java
|
||||
+++ b/src/main/java/org/bukkit/block/Sign.java
|
||||
@@ -48,7 +48,7 @@ public interface Sign extends TileState, Colorable {
|
||||
* @deprecated in favour of {@link #lines()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String[] getLines();
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ public interface Sign extends TileState, Colorable {
|
||||
* @deprecated in favour of {@link #line(int)}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getLine(int index) throws IndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ public interface Sign extends TileState, Colorable {
|
||||
* @throws IndexOutOfBoundsException If the index is out of the range 0..3
|
||||
* @deprecated in favour of {@link #line(int, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setLine(int index, @NotNull String line) throws IndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 25252bad38ca35b81b225b57c4b6ce77ad6de166..9f289576d97c3406d506d3f4fa7287bc74e5b425 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -72,7 +72,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @return the friendly name
|
||||
* @deprecated in favour of {@link #displayName()}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
public String getDisplayName();
|
||||
|
||||
@@ -86,7 +86,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param name The new display name.
|
||||
* @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setDisplayName(@Nullable String name);
|
||||
|
||||
// Paper start
|
||||
@@ -127,7 +127,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @deprecated in favour of {@link #playerListName()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getPlayerListName();
|
||||
|
||||
/**
|
||||
@@ -138,7 +138,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param name new player list name
|
||||
* @deprecated in favour of {@link #playerListName(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setPlayerListName(@Nullable String name);
|
||||
|
||||
/**
|
||||
@@ -147,7 +147,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @return player list header or null
|
||||
* @deprecated in favour of {@link #playerListHeader()}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@Nullable
|
||||
public String getPlayerListHeader();
|
||||
|
||||
@@ -157,7 +157,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @return player list header or null
|
||||
* @deprecated in favour of {@link #playerListFooter()}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@Nullable
|
||||
public String getPlayerListFooter();
|
||||
|
||||
@@ -167,7 +167,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param header player list header, null for empty
|
||||
* @deprecated in favour of {@link #sendPlayerListHeader(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setPlayerListHeader(@Nullable String header);
|
||||
|
||||
/**
|
||||
@@ -176,7 +176,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param footer player list footer, null for empty
|
||||
* @deprecated in favour of {@link #sendPlayerListFooter(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setPlayerListFooter(@Nullable String footer);
|
||||
|
||||
/**
|
||||
@@ -187,7 +187,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param footer player list footer, null for empty
|
||||
* @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setPlayerListHeaderFooter(@Nullable String header, @Nullable String footer);
|
||||
|
||||
/**
|
||||
@@ -227,7 +227,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param message kick message
|
||||
* @deprecated in favour of {@link #kick(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void kickPlayer(@Nullable String message);
|
||||
|
||||
// Paper start
|
||||
@@ -598,7 +598,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @throws IllegalArgumentException if lines is non-null and has a length less than 4
|
||||
* @deprecated in favour of {@link #sendSignChange(org.bukkit.Location, java.util.List)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void sendSignChange(@NotNull Location loc, @Nullable String[] lines) throws IllegalArgumentException;
|
||||
|
||||
|
||||
@@ -620,7 +620,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @throws IllegalArgumentException if lines is non-null and has a length less than 4
|
||||
* @deprecated in favour of {@link #sendSignChange(org.bukkit.Location, java.util.List, org.bukkit.DyeColor)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
@@ -1769,7 +1769,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @deprecated in favour of {@link #locale()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getLocale();
|
||||
|
||||
// Paper start
|
||||
diff --git a/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java b/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java
|
||||
index 078228106b299a8e38495f7f881d38de4f87bc95..bd5b3142a88c31a676c08fa3e8175f81f4259835 100644
|
||||
--- a/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java
|
||||
+++ b/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java
|
||||
@@ -37,7 +37,7 @@ public interface CommandMinecart extends Minecart {
|
||||
* @param name New name for this CommandMinecart.
|
||||
* @deprecated in favour of {@link #customName(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setName(@Nullable String name);
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/block/SignChangeEvent.java b/src/main/java/org/bukkit/event/block/SignChangeEvent.java
|
||||
index 1f79f704abf339150df08900b8ea7da4cefef258..004106913655446774f875015cb79863d21263c8 100644
|
||||
--- a/src/main/java/org/bukkit/event/block/SignChangeEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/block/SignChangeEvent.java
|
||||
@@ -90,7 +90,7 @@ public class SignChangeEvent extends BlockEvent implements Cancellable {
|
||||
* @deprecated in favour of {@link #lines()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String[] getLines() {
|
||||
return adventure$lines.stream().map(org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer()::serialize).toArray(String[]::new); // Paper
|
||||
}
|
||||
@@ -106,7 +106,7 @@ public class SignChangeEvent extends BlockEvent implements Cancellable {
|
||||
* @deprecated in favour of {@link #line(int)}
|
||||
*/
|
||||
@Nullable
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getLine(int index) throws IndexOutOfBoundsException {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.adventure$lines.get(index)); // Paper
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class SignChangeEvent extends BlockEvent implements Cancellable {
|
||||
* or < 0}
|
||||
* @deprecated in favour of {@link #line(int, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setLine(int index, @Nullable String line) throws IndexOutOfBoundsException {
|
||||
adventure$lines.set(index, line != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(line) : null); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java b/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
|
||||
index 3d45d2e41aad6992b40a22030f2a63baeec78757..3cecfe9f7c253ab474829c612cca2dc05fd5d111 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
|
||||
@@ -151,7 +151,7 @@ public class PlayerDeathEvent extends EntityDeathEvent {
|
||||
* @param deathMessage Message to appear to other players on the server.
|
||||
* @deprecated in favour of {@link #deathMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setDeathMessage(@Nullable String deathMessage) {
|
||||
this.deathMessage = deathMessage;
|
||||
this.adventure$deathMessage = deathMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(deathMessage) : net.kyori.adventure.text.Component.empty(); // Paper
|
||||
@@ -164,7 +164,7 @@ public class PlayerDeathEvent extends EntityDeathEvent {
|
||||
* @deprecated in favour of {@link #deathMessage()}
|
||||
*/
|
||||
@Nullable
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getDeathMessage() {
|
||||
return this.deathMessage != null ? this.deathMessage : (this.adventure$deathMessage != null ? getDeathMessageString(this.adventure$deathMessage) : null); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java
|
||||
index 129eac25da4f27489038fb15ab1aeecb172b60cc..670aca11bbaa2d155cd9d2105ac94c9df71d7d8d 100644
|
||||
--- a/src/main/java/org/bukkit/event/inventory/InventoryType.java
|
||||
+++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java
|
||||
@@ -170,7 +170,7 @@ public enum InventoryType {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getDefaultTitle() {
|
||||
return title;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
index 77aefda5aac4602bf5bf71c29600e7450defdd4e..240552d61ae12fbec826f771f0f366500e72d941 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
@@ -179,7 +179,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
* @deprecated in favour of {@link #kickMessage()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getKickMessage() {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
|
||||
}
|
||||
@@ -190,7 +190,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
* @param message New kick message
|
||||
* @deprecated in favour of {@link #kickMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setKickMessage(@NotNull final String message) {
|
||||
this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
|
||||
}
|
||||
@@ -210,7 +210,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
* @param message Kick message to display to the user
|
||||
* @deprecated in favour of {@link #disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void disallow(@NotNull final Result result, @NotNull final String message) {
|
||||
this.result = result;
|
||||
this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java b/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java
|
||||
index 851a189d42e271679abc78f95049d8badf7a2b64..7057c2e95267ad32190c5666f20a0566f7fe32fa 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java
|
||||
@@ -17,7 +17,7 @@ public class PlayerJoinEvent extends PlayerEvent {
|
||||
this.joinMessage = joinMessage;
|
||||
}
|
||||
|
||||
- @Deprecated // Paper end
|
||||
+ @Deprecated // Paper end // Purpur - conflict on change
|
||||
public PlayerJoinEvent(@NotNull final Player playerJoined, @Nullable final String joinMessage) {
|
||||
super(playerJoined);
|
||||
this.joinMessage = joinMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(joinMessage) : null; // Paper end
|
||||
@@ -50,7 +50,7 @@ public class PlayerJoinEvent extends PlayerEvent {
|
||||
* @deprecated in favour of {@link #joinMessage()}
|
||||
*/
|
||||
@Nullable
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getJoinMessage() {
|
||||
return this.joinMessage == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.joinMessage); // Paper
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class PlayerJoinEvent extends PlayerEvent {
|
||||
* @param joinMessage join message. If null, no message will be sent
|
||||
* @deprecated in favour of {@link #joinMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setJoinMessage(@Nullable String joinMessage) {
|
||||
this.joinMessage = joinMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(joinMessage) : null; // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerKickEvent.java b/src/main/java/org/bukkit/event/player/PlayerKickEvent.java
|
||||
index 02914c0743852e9e4fd2c085fd4b735e74d8875b..94688093671949551992a8c80904cd6042deb83b 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerKickEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerKickEvent.java
|
||||
@@ -85,7 +85,7 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable {
|
||||
* @deprecated in favour of {@link #reason()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getReason() {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.kickReason); // Paper
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable {
|
||||
* @deprecated in favour of {@link #leaveMessage()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getLeaveMessage() {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.leaveMessage); // Paper
|
||||
}
|
||||
@@ -118,7 +118,7 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable {
|
||||
* @param kickReason kick reason
|
||||
* @deprecated in favour of {@link #reason(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setReason(@NotNull String kickReason) {
|
||||
this.kickReason = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickReason); // Paper
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable {
|
||||
* @param leaveMessage leave message
|
||||
* @deprecated in favour of {@link #leaveMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setLeaveMessage(@NotNull String leaveMessage) {
|
||||
this.leaveMessage = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(leaveMessage); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java b/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java
|
||||
index 84521186404b8e43c81a2f9513dce2be40d27840..8c65e9e1476d27fc55419290fb53e46dee9b304d 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java
|
||||
@@ -37,7 +37,7 @@ public class PlayerLocaleChangeEvent extends PlayerEvent {
|
||||
* @deprecated in favour of {@link #locale()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
|
||||
index 75cc54739ef841cd90568d74927d6002d4cfa7e0..712900c9afc3b79806d2b564c0734facf969a6fe 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
|
||||
@@ -139,7 +139,7 @@ public class PlayerLoginEvent extends PlayerEvent {
|
||||
* @deprecated in favour of {@link #kickMessage()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getKickMessage() {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
|
||||
}
|
||||
@@ -150,7 +150,7 @@ public class PlayerLoginEvent extends PlayerEvent {
|
||||
* @param message New kick message
|
||||
* @deprecated in favour of {@link #kickMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setKickMessage(@NotNull final String message) {
|
||||
this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
|
||||
}
|
||||
@@ -181,7 +181,7 @@ public class PlayerLoginEvent extends PlayerEvent {
|
||||
* @param message Kick message to display to the user
|
||||
* @deprecated in favour of {@link #disallow(Result, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper start
|
||||
+ @Deprecated // Paper start // Purpur - conflict on change
|
||||
public void disallow(@NotNull final Result result, @NotNull final String message) {
|
||||
this.result = result;
|
||||
this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message);
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java b/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
|
||||
index 123979ed64939d615b061f91c19c630e1e1db8c7..5b85579964dc6a6150f0c0be650a4bf731414838 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
|
||||
@@ -95,7 +95,7 @@ public class PlayerPreLoginEvent extends Event {
|
||||
* @return Current kick message
|
||||
* @deprecated in favour of {@link #kickMessage()}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
public String getKickMessage() {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
|
||||
@@ -107,7 +107,7 @@ public class PlayerPreLoginEvent extends Event {
|
||||
* @param message New kick message
|
||||
* @deprecated in favour of {@link #kickMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setKickMessage(@NotNull final String message) {
|
||||
this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public class PlayerPreLoginEvent extends Event {
|
||||
* @param message Kick message to display to the user
|
||||
* @deprecated in favour of {@link #disallow(org.bukkit.event.player.PlayerPreLoginEvent.Result, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void disallow(@NotNull final Result result, @NotNull final String message) {
|
||||
this.result = result;
|
||||
this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java b/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java
|
||||
index e43acfb570036adb73d195136573620378cc6a61..1826d11d8b18702ee12c669b50df7f538c324582 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java
|
||||
@@ -61,7 +61,7 @@ public class PlayerQuitEvent extends PlayerEvent {
|
||||
* @deprecated in favour of {@link #quitMessage()}
|
||||
*/
|
||||
@Nullable
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getQuitMessage() {
|
||||
return this.quitMessage == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.quitMessage); // Paper
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class PlayerQuitEvent extends PlayerEvent {
|
||||
* @param quitMessage quit message
|
||||
* @deprecated in favour of {@link #quitMessage(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setQuitMessage(@Nullable String quitMessage) {
|
||||
this.quitMessage = quitMessage != null ? org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(quitMessage) : null; // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java b/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java
|
||||
index 4f8c85222c7bd33217c7db0ff5f47bf397f8f3e5..c18d6d979bd22814ebdc52b995d2cc7ed46dd87f 100644
|
||||
--- a/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java
|
||||
@@ -73,7 +73,7 @@ public class BroadcastMessageEvent extends ServerEvent implements Cancellable {
|
||||
* @deprecated in favour of {@link #message()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getMessage() {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message); // Paper
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class BroadcastMessageEvent extends ServerEvent implements Cancellable {
|
||||
* @param message New message to broadcast
|
||||
* @deprecated in favour of {@link #message(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setMessage(@NotNull String message) {
|
||||
this.message = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/server/ServerListPingEvent.java b/src/main/java/org/bukkit/event/server/ServerListPingEvent.java
|
||||
index ede5a41bc071a9c9cea369b227b37a50222f295d..6c6501d73041a6c69e78f34d3bf2a96a7de5f690 100644
|
||||
--- a/src/main/java/org/bukkit/event/server/ServerListPingEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/server/ServerListPingEvent.java
|
||||
@@ -109,7 +109,7 @@ public class ServerListPingEvent extends ServerEvent implements Iterable<Player>
|
||||
* @deprecated in favour of {@link #motd()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getMotd() {
|
||||
return org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.motd); // Paper
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class ServerListPingEvent extends ServerEvent implements Iterable<Player>
|
||||
* @param motd the message of the day
|
||||
* @deprecated in favour of {@link #motd(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setMotd(@NotNull String motd) {
|
||||
this.motd = org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(motd); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/InventoryView.java b/src/main/java/org/bukkit/inventory/InventoryView.java
|
||||
index b06995aa57aa9cba0bb59f1d26d81015619a08e6..5e33fe46ab9bb034acc6a38a3c00c33c8f029ca6 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/InventoryView.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/InventoryView.java
|
||||
@@ -464,7 +464,7 @@ public abstract class InventoryView {
|
||||
* @return The title.
|
||||
* @deprecated in favour of {@link #title()}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
public abstract String getTitle();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/meta/BookMeta.java b/src/main/java/org/bukkit/inventory/meta/BookMeta.java
|
||||
index 7357c166115f346a1efebd0f0f2d5491de6a9a39..b90cb7aa98ea40573557a80ca5c7be7c5c494956 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/meta/BookMeta.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/meta/BookMeta.java
|
||||
@@ -242,7 +242,7 @@ public interface BookMeta extends ItemMeta, net.kyori.adventure.inventory.Book {
|
||||
* @deprecated in favour of {@link #page(int)}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
String getPage(int page);
|
||||
|
||||
/**
|
||||
@@ -258,7 +258,7 @@ public interface BookMeta extends ItemMeta, net.kyori.adventure.inventory.Book {
|
||||
* @param data the data to set for that page
|
||||
* @deprecated in favour of {@link #page(int, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setPage(int page, @NotNull String data);
|
||||
|
||||
/**
|
||||
@@ -268,7 +268,7 @@ public interface BookMeta extends ItemMeta, net.kyori.adventure.inventory.Book {
|
||||
* @deprecated in favour of {@link #pages()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
List<String> getPages();
|
||||
|
||||
/**
|
||||
@@ -278,7 +278,7 @@ public interface BookMeta extends ItemMeta, net.kyori.adventure.inventory.Book {
|
||||
* @param pages A list of pages to set the book to use
|
||||
* @deprecated in favour of {@link #pages(List)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setPages(@NotNull List<String> pages);
|
||||
|
||||
/**
|
||||
@@ -288,7 +288,7 @@ public interface BookMeta extends ItemMeta, net.kyori.adventure.inventory.Book {
|
||||
* @param pages A list of strings, each being a page
|
||||
* @deprecated in favour of {@link #pages(net.kyori.adventure.text.Component...)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setPages(@NotNull String... pages);
|
||||
|
||||
/**
|
||||
@@ -298,7 +298,7 @@ public interface BookMeta extends ItemMeta, net.kyori.adventure.inventory.Book {
|
||||
* @param pages A list of strings, each being a page
|
||||
* @deprecated in favour of {@link #addPages(net.kyori.adventure.text.Component...)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void addPage(@NotNull String... pages);
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
|
||||
index f093f991f1fedd20fcef041b093398250b7fb286..49d8b1bdad79f452c863f83557ffde7e8f4749c6 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
|
||||
@@ -59,7 +59,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
|
||||
* @return the display name that is set
|
||||
* @deprecated in favour of {@link #displayName()}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@NotNull
|
||||
String getDisplayName();
|
||||
|
||||
@@ -83,7 +83,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
|
||||
* @param name the name to set
|
||||
* @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setDisplayName(@Nullable String name);
|
||||
|
||||
// Paper start
|
||||
@@ -155,7 +155,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
|
||||
* @return a list of lore that is set
|
||||
* @deprecated in favour of {@link #lore()}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
@Nullable
|
||||
List<String> getLore();
|
||||
|
||||
@@ -179,7 +179,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
|
||||
* @param lore the lore that will be set
|
||||
* @deprecated in favour of {@link #lore(List)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setLore(@Nullable List<String> lore);
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/map/MapCursor.java b/src/main/java/org/bukkit/map/MapCursor.java
|
||||
index ed0bc2024a0bb85837e25f75ae89d1fe257b2e60..f6e831f844e1fe99a2617bd64c2290d1f2e96d81 100644
|
||||
--- a/src/main/java/org/bukkit/map/MapCursor.java
|
||||
+++ b/src/main/java/org/bukkit/map/MapCursor.java
|
||||
@@ -259,7 +259,7 @@ public final class MapCursor {
|
||||
* @deprecated in favour of {@link #caption()}
|
||||
*/
|
||||
@Nullable
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public String getCaption() {
|
||||
return this.caption == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.caption); // Paper
|
||||
}
|
||||
@@ -270,7 +270,7 @@ public final class MapCursor {
|
||||
* @param caption new caption
|
||||
* @deprecated in favour of {@link #caption(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
public void setCaption(@Nullable String caption) {
|
||||
this.caption = caption == null ? null : org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().deserialize(caption); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/scoreboard/Objective.java b/src/main/java/org/bukkit/scoreboard/Objective.java
|
||||
index 58bddb11fd534e7c33a4ffd7b72b055ba92c767a..a1b6b1123808378d58c855cacac391ce97df6f19 100644
|
||||
--- a/src/main/java/org/bukkit/scoreboard/Objective.java
|
||||
+++ b/src/main/java/org/bukkit/scoreboard/Objective.java
|
||||
@@ -47,7 +47,7 @@ public interface Objective {
|
||||
* @deprecated in favour of {@link #displayName()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
String getDisplayName() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
@@ -60,7 +60,7 @@ public interface Objective {
|
||||
* characters.
|
||||
* @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setDisplayName(@NotNull String displayName) throws IllegalStateException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/scoreboard/Scoreboard.java b/src/main/java/org/bukkit/scoreboard/Scoreboard.java
|
||||
index f09ff32cc3ffc16af379a378b1948991435393e8..e9db79d10522895e6f119c0cc87eec1cbc45ba6e 100644
|
||||
--- a/src/main/java/org/bukkit/scoreboard/Scoreboard.java
|
||||
+++ b/src/main/java/org/bukkit/scoreboard/Scoreboard.java
|
||||
@@ -89,7 +89,7 @@ public interface Scoreboard {
|
||||
* @deprecated in favour of {@link #registerNewObjective(String, String, net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
Objective registerNewObjective(@NotNull String name, @NotNull String criteria, @NotNull String displayName) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
@@ -113,7 +113,7 @@ public interface Scoreboard {
|
||||
* @deprecated in favour of {@link #registerNewObjective(String, String, net.kyori.adventure.text.Component, RenderType)}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
Objective registerNewObjective(@NotNull String name, @NotNull String criteria, @NotNull String displayName, @NotNull RenderType renderType) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/scoreboard/Team.java b/src/main/java/org/bukkit/scoreboard/Team.java
|
||||
index f0af10a5b9ad048be197ed5ec6c8ed2672eb3dd5..705b2268b1c227b34852c14601381230dc626a08 100644
|
||||
--- a/src/main/java/org/bukkit/scoreboard/Team.java
|
||||
+++ b/src/main/java/org/bukkit/scoreboard/Team.java
|
||||
@@ -110,7 +110,7 @@ public interface Team {
|
||||
* @deprecated in favour of {@link #displayName()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
String getDisplayName() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
@@ -122,7 +122,7 @@ public interface Team {
|
||||
* @throws IllegalStateException if this team has been unregistered
|
||||
* @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setDisplayName(@NotNull String displayName) throws IllegalStateException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
@@ -133,7 +133,7 @@ public interface Team {
|
||||
* @deprecated in favour of {@link #prefix()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
String getPrefix() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
@@ -146,7 +146,7 @@ public interface Team {
|
||||
* @throws IllegalStateException if this team has been unregistered
|
||||
* @deprecated in favour of {@link #prefix(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setPrefix(@NotNull String prefix) throws IllegalStateException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
@@ -157,7 +157,7 @@ public interface Team {
|
||||
* @deprecated in favour of {@link #suffix()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
String getSuffix() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
@@ -170,7 +170,7 @@ public interface Team {
|
||||
* @throws IllegalStateException if this team has been unregistered
|
||||
* @deprecated in favour of {@link #suffix(net.kyori.adventure.text.Component)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setSuffix(@NotNull String suffix) throws IllegalStateException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
@@ -184,7 +184,7 @@ public interface Team {
|
||||
* @deprecated in favour of {@link #color()}
|
||||
*/
|
||||
@NotNull
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
ChatColor getColor() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
@@ -197,7 +197,7 @@ public interface Team {
|
||||
* no color
|
||||
* @deprecated in favour of {@link #color(net.kyori.adventure.text.format.NamedTextColor)}
|
||||
*/
|
||||
- @Deprecated // Paper
|
||||
+ @Deprecated // Paper // Purpur - conflict on change
|
||||
void setColor(@NotNull ChatColor color);
|
||||
|
||||
/**
|
@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 23 Mar 2021 15:01:03 -0500
|
||||
Subject: [PATCH] Add enchantment target for bows and crossbows
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
|
||||
index 635e07a6b0e255c4fdad58ba9d281c807af4e229..93d5fad641c5afa679b59dc712f0d0faaddcfe2e 100644
|
||||
--- a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
|
||||
+++ b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
|
||||
@@ -226,6 +226,18 @@ public enum EnchantmentTarget {
|
||||
public boolean includes(@NotNull Material item) {
|
||||
return BREAKABLE.includes(item) || (WEARABLE.includes(item) && !item.equals(Material.ELYTRA)) || item.equals(Material.COMPASS);
|
||||
}
|
||||
+ // Purpur start
|
||||
+ },
|
||||
+
|
||||
+ /**
|
||||
+ * Allow the Enchantment to be placed on bows and crossbows.
|
||||
+ */
|
||||
+ BOW_AND_CROSSBOW {
|
||||
+ @Override
|
||||
+ public boolean includes(@NotNull Material item) {
|
||||
+ return item.equals(Material.BOW) || item.equals(Material.CROSSBOW);
|
||||
+ }
|
||||
+ // Purpur end
|
||||
};
|
||||
|
||||
/**
|
@ -1,17 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 13 May 2021 21:38:01 -0500
|
||||
Subject: [PATCH] Iron golem poppy calms anger
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
index 39f77041133228c4bd4cec2427ad0bae8e739d4a..29144c0e325a3efbef05670a6fb2e849bbed6bba 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
|
||||
@@ -214,5 +214,6 @@ public interface VanillaGoal<T extends Mob> extends Goal<T> {
|
||||
GoalKey<Drowned> DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager"));
|
||||
GoalKey<Zombie> ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager"));
|
||||
GoalKey<Wolf> AVOID_RABID_WOLVES = GoalKey.of(Wolf.class, NamespacedKey.minecraft("avoid_rabid_wolves"));
|
||||
+ GoalKey<IronGolem> RECEIVE_FLOWER = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("receive_flower"));
|
||||
// Purpur end
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Kerllenevich <me@notom3ga.me>
|
||||
Date: Tue, 25 May 2021 16:30:30 -0400
|
||||
Subject: [PATCH] API for any mob to burn daylight
|
||||
|
||||
Co-authored by: Encode42 <me@encode42.dev>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
|
||||
index 7fa5242bd44c9b19648d79fa8fecbb7ee125288e..62d8d7dbd4d602ca8cb00ff0cf1331583b398323 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -770,5 +770,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
* @return Whether the entity was successfully spawned.
|
||||
*/
|
||||
boolean spawnAt(@NotNull Location location, @NotNull org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason);
|
||||
+
|
||||
+ /**
|
||||
+ * Checks if the entity is in daylight
|
||||
+ *
|
||||
+ * @return True if in daylight
|
||||
+ */
|
||||
+ boolean isInDaylight();
|
||||
// Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index 42811d18ff304082f74f45794344891208599c04..ebe10b5612835d22dfcf8b30b0f028022e47216e 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -872,5 +872,19 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
* @param slot Equipment slot to play break animation for
|
||||
*/
|
||||
void broadcastItemBreak(@NotNull org.bukkit.inventory.EquipmentSlot slot);
|
||||
+
|
||||
+ /**
|
||||
+ * If this mob will burn in the sunlight
|
||||
+ *
|
||||
+ * @return True if mob will burn in sunlight
|
||||
+ */
|
||||
+ boolean shouldBurnInDay();
|
||||
+
|
||||
+ /**
|
||||
+ * Set if this mob should burn in the sunlight
|
||||
+ *
|
||||
+ * @param shouldBurnInDay True to burn in sunlight
|
||||
+ */
|
||||
+ void setShouldBurnInDay(boolean shouldBurnInDay);
|
||||
// Purpur end
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,424 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 9 May 2019 18:09:43 -0500
|
||||
Subject: [PATCH] Purpur config files
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
|
||||
index b480bd3044370b8eb733166f0c4b737344475993..4d8740678049aa749b42618470e9cc838555528d 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
|
||||
@@ -593,7 +593,7 @@ public class Metrics {
|
||||
boolean logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
// Only start Metrics, if it's enabled in the config
|
||||
if (config.getBoolean("enabled", true)) {
|
||||
- Metrics metrics = new Metrics("Airplane", serverUUID, logFailedRequests, Bukkit.getLogger()); // Tuinity - we have our own bstats page // Airplane
|
||||
+ Metrics metrics = new Metrics("Purpur", serverUUID, logFailedRequests, Bukkit.getLogger()); // Purpur
|
||||
|
||||
metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
|
||||
String minecraftVersion = Bukkit.getVersion();
|
||||
@@ -602,8 +602,8 @@ public class Metrics {
|
||||
}));
|
||||
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("players", () -> Bukkit.getOnlinePlayers().size()));
|
||||
- metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() || PaperConfig.isProxyOnlineMode() ? "online" : "offline"));
|
||||
- metrics.addCustomChart(new Metrics.SimplePie("airplane_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); // Tuinity - we have our own bstats page // Airplane
|
||||
+ metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() ? "online" : (PaperConfig.isProxyOnlineMode() ? "bungee" : "offline"))); // Purpur
|
||||
+ metrics.addCustomChart(new Metrics.SimplePie("purpur_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); // Purpur
|
||||
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
|
||||
Map<String, Map<String, Integer>> map = new HashMap<>();
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index efc1e42d606e1c9feb1a4871c0714933ae92a1b2..a0ed8ed1d6b89a4f10dff645e09eaff303fb3f8a 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -118,6 +118,11 @@ public class PaperConfig {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Purpur start - public save method for config migration
|
||||
+ saveConfig();
|
||||
+ }
|
||||
+ public static void saveConfig() {
|
||||
+ // Purpur end
|
||||
try {
|
||||
config.save(CONFIG_FILE);
|
||||
} catch (IOException ex) {
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 3e21bd029131ceeaac9cb46bef8d238617ca76ea..c2932e739a607e4ed3f94632ca45bdb2b0954ecb 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -212,6 +212,15 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
||||
return false;
|
||||
}
|
||||
com.destroystokyo.paper.PaperConfig.registerCommands();
|
||||
+ // Purpur start
|
||||
+ try {
|
||||
+ net.pl3x.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings"));
|
||||
+ } catch (Exception e) {
|
||||
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.pl3x.purpur.PurpurConfig.registerCommands();
|
||||
+ // Purpur end
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
|
||||
io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider
|
||||
// Paper end
|
||||
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
|
||||
index f8d11a1f0337acf60f2d9f94bd4bbbf6eb77c6de..0ede4766117e0bc28127baf1b14535370d8ea878 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/World.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/World.java
|
||||
@@ -158,6 +158,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
public final ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
|
||||
|
||||
public final com.tuinity.tuinity.config.TuinityConfig.WorldConfig tuinityConfig; // Tuinity - Server Config
|
||||
+ public final net.pl3x.purpur.PurpurWorldConfig purpurConfig; // Purpur
|
||||
|
||||
public final co.aikar.timings.WorldTimingsHandler timings; // Paper
|
||||
public static BlockPosition lastPhysicsProblem; // Spigot
|
||||
@@ -259,6 +260,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((net.minecraft.world.level.storage.WorldDataServer) worlddatamutable).getName(), this.spigotConfig); // Paper
|
||||
this.chunkPacketBlockController = this.paperConfig.antiXray ? new ChunkPacketBlockControllerAntiXray(this, executor) : ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
|
||||
this.tuinityConfig = new com.tuinity.tuinity.config.TuinityConfig.WorldConfig(((net.minecraft.world.level.storage.WorldDataServer)worlddatamutable).getName()); // Tuinity - Server Config
|
||||
+ this.purpurConfig = new net.pl3x.purpur.PurpurWorldConfig((((net.minecraft.world.level.storage.WorldDataServer)worlddatamutable).getName())); // Purpur
|
||||
this.generator = gen;
|
||||
this.world = new CraftWorld((WorldServer) this, gen, env);
|
||||
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..74fc4fc2216cf82e1546ef3d567f2750b1240df1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
@@ -0,0 +1,130 @@
|
||||
+package net.pl3x.purpur;
|
||||
+
|
||||
+import com.google.common.base.Throwables;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.pl3x.purpur.command.PurpurCommand;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.configuration.InvalidConfigurationException;
|
||||
+import org.bukkit.configuration.file.YamlConfiguration;
|
||||
+
|
||||
+import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.lang.reflect.InvocationTargetException;
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.List;
|
||||
+import java.util.Map;
|
||||
+import java.util.logging.Level;
|
||||
+
|
||||
+public class PurpurConfig {
|
||||
+ private static final String HEADER = "This is the main configuration file for Purpur.\n"
|
||||
+ + "As you can see, there's tons to configure. Some options may impact gameplay, so use\n"
|
||||
+ + "with caution, and make sure you know what each option does before configuring.\n"
|
||||
+ + "\n"
|
||||
+ + "If you need help with the configuration or have any questions related to Purpur,\n"
|
||||
+ + "join us in our Discord guild.\n"
|
||||
+ + "\n"
|
||||
+ + "Website: https://github.com/pl3xgaming/Purpur \n"
|
||||
+ + "Wiki: https://github.com/pl3xgaming/Purpur/wiki \n";
|
||||
+ private static File CONFIG_FILE;
|
||||
+ public static YamlConfiguration config;
|
||||
+
|
||||
+ private static Map<String, Command> commands;
|
||||
+
|
||||
+ static int version;
|
||||
+ static boolean verbose;
|
||||
+
|
||||
+ public static void init(File configFile) {
|
||||
+ CONFIG_FILE = configFile;
|
||||
+ config = new YamlConfiguration();
|
||||
+ try {
|
||||
+ config.load(CONFIG_FILE);
|
||||
+ } catch (IOException ignore) {
|
||||
+ } catch (InvalidConfigurationException ex) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Could not load purpur.yml, please correct your syntax errors", ex);
|
||||
+ throw Throwables.propagate(ex);
|
||||
+ }
|
||||
+ config.options().header(HEADER);
|
||||
+ config.options().copyDefaults(true);
|
||||
+ verbose = getBoolean("verbose", false);
|
||||
+
|
||||
+ commands = new HashMap<>();
|
||||
+ commands.put("purpur", new PurpurCommand("purpur"));
|
||||
+
|
||||
+ version = getInt("config-version", 13);
|
||||
+ set("config-version", 13);
|
||||
+
|
||||
+ readConfig(PurpurConfig.class, null);
|
||||
+ }
|
||||
+
|
||||
+ protected static void log(String s) {
|
||||
+ if (verbose) {
|
||||
+ log(Level.INFO, s);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ protected static void log(Level level, String s) {
|
||||
+ Bukkit.getLogger().log(level, s);
|
||||
+ }
|
||||
+
|
||||
+ public static void registerCommands() {
|
||||
+ for (Map.Entry<String, Command> entry : commands.entrySet()) {
|
||||
+ MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Purpur", entry.getValue());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static void readConfig(Class<?> clazz, Object instance) {
|
||||
+ for (Method method : clazz.getDeclaredMethods()) {
|
||||
+ if (Modifier.isPrivate(method.getModifiers())) {
|
||||
+ if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
|
||||
+ try {
|
||||
+ method.setAccessible(true);
|
||||
+ method.invoke(instance);
|
||||
+ } catch (InvocationTargetException ex) {
|
||||
+ throw Throwables.propagate(ex.getCause());
|
||||
+ } catch (Exception ex) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ config.save(CONFIG_FILE);
|
||||
+ } catch (IOException ex) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void set(String path, Object val) {
|
||||
+ config.addDefault(path, val);
|
||||
+ config.set(path, val);
|
||||
+ }
|
||||
+
|
||||
+ private static boolean getBoolean(String path, boolean def) {
|
||||
+ config.addDefault(path, def);
|
||||
+ return config.getBoolean(path, config.getBoolean(path));
|
||||
+ }
|
||||
+
|
||||
+ private static double getDouble(String path, double def) {
|
||||
+ config.addDefault(path, def);
|
||||
+ return config.getDouble(path, config.getDouble(path));
|
||||
+ }
|
||||
+
|
||||
+ private static int getInt(String path, int def) {
|
||||
+ config.addDefault(path, def);
|
||||
+ return config.getInt(path, config.getInt(path));
|
||||
+ }
|
||||
+
|
||||
+ private static <T> List getList(String path, T def) {
|
||||
+ config.addDefault(path, def);
|
||||
+ return config.getList(path, config.getList(path));
|
||||
+ }
|
||||
+
|
||||
+ private static String getString(String path, String def) {
|
||||
+ config.addDefault(path, def);
|
||||
+ return config.getString(path, config.getString(path));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..361f7857e461578e90cb71e15027dadaf794cb69
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+package net.pl3x.purpur;
|
||||
+
|
||||
+import org.bukkit.configuration.ConfigurationSection;
|
||||
+import java.util.List;
|
||||
+import static net.pl3x.purpur.PurpurConfig.log;
|
||||
+
|
||||
+public class PurpurWorldConfig {
|
||||
+
|
||||
+ private final String worldName;
|
||||
+
|
||||
+ public PurpurWorldConfig(String worldName) {
|
||||
+ this.worldName = worldName;
|
||||
+ init();
|
||||
+ }
|
||||
+
|
||||
+ public void init() {
|
||||
+ log("-------- World Settings For [" + worldName + "] --------");
|
||||
+ PurpurConfig.readConfig(PurpurWorldConfig.class, this);
|
||||
+ }
|
||||
+
|
||||
+ private void set(String path, Object val) {
|
||||
+ PurpurConfig.config.addDefault("world-settings.default." + path, val);
|
||||
+ PurpurConfig.config.set("world-settings.default." + path, val);
|
||||
+ if (PurpurConfig.config.get("world-settings." + worldName + "." + path) != null) {
|
||||
+ PurpurConfig.config.addDefault("world-settings." + worldName + "." + path, val);
|
||||
+ PurpurConfig.config.set("world-settings." + worldName + "." + path, val);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private ConfigurationSection getConfigurationSection(String path) {
|
||||
+ ConfigurationSection section = PurpurConfig.config.getConfigurationSection("world-settings." + worldName + "." + path);
|
||||
+ return section != null ? section : PurpurConfig.config.getConfigurationSection("world-settings.default." + path);
|
||||
+ }
|
||||
+
|
||||
+ private boolean getBoolean(String path, boolean def) {
|
||||
+ PurpurConfig.config.addDefault("world-settings.default." + path, def);
|
||||
+ return PurpurConfig.config.getBoolean("world-settings." + worldName + "." + path, PurpurConfig.config.getBoolean("world-settings.default." + path));
|
||||
+ }
|
||||
+
|
||||
+ private double getDouble(String path, double def) {
|
||||
+ PurpurConfig.config.addDefault("world-settings.default." + path, def);
|
||||
+ return PurpurConfig.config.getDouble("world-settings." + worldName + "." + path, PurpurConfig.config.getDouble("world-settings.default." + path));
|
||||
+ }
|
||||
+
|
||||
+ private int getInt(String path, int def) {
|
||||
+ PurpurConfig.config.addDefault("world-settings.default." + path, def);
|
||||
+ return PurpurConfig.config.getInt("world-settings." + worldName + "." + path, PurpurConfig.config.getInt("world-settings.default." + path));
|
||||
+ }
|
||||
+
|
||||
+ private <T> List<?> getList(String path, T def) {
|
||||
+ PurpurConfig.config.addDefault("world-settings.default." + path, def);
|
||||
+ return PurpurConfig.config.getList("world-settings." + worldName + "." + path, PurpurConfig.config.getList("world-settings.default." + path));
|
||||
+ }
|
||||
+
|
||||
+ private String getString(String path, String def) {
|
||||
+ PurpurConfig.config.addDefault("world-settings.default." + path, def);
|
||||
+ return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/pl3x/purpur/command/PurpurCommand.java b/src/main/java/net/pl3x/purpur/command/PurpurCommand.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..536955124afaec5c8a070249c7432cb99bf43d67
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/pl3x/purpur/command/PurpurCommand.java
|
||||
@@ -0,0 +1,65 @@
|
||||
+package net.pl3x.purpur.command;
|
||||
+
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.level.WorldServer;
|
||||
+import net.pl3x.purpur.PurpurConfig;
|
||||
+import org.bukkit.ChatColor;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+
|
||||
+import java.io.File;
|
||||
+import java.util.Collections;
|
||||
+import java.util.List;
|
||||
+import java.util.stream.Collectors;
|
||||
+import java.util.stream.Stream;
|
||||
+
|
||||
+public class PurpurCommand extends Command {
|
||||
+ public PurpurCommand(String name) {
|
||||
+ super(name);
|
||||
+ this.description = "Purpur related commands";
|
||||
+ this.usageMessage = "/purpur [reload | version]";
|
||||
+ this.setPermission("bukkit.command.purpur");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
|
||||
+ if (args.length == 1) {
|
||||
+ return Stream.of("reload", "version")
|
||||
+ .filter(arg -> arg.startsWith(args[0].toLowerCase()))
|
||||
+ .collect(Collectors.toList());
|
||||
+ }
|
||||
+ return Collections.emptyList();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
||||
+ if (!testPermission(sender)) return true;
|
||||
+
|
||||
+ if (args.length != 1) {
|
||||
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (args[0].equalsIgnoreCase("reload")) {
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues.");
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
|
||||
+
|
||||
+ MinecraftServer console = MinecraftServer.getServer();
|
||||
+ PurpurConfig.init((File) console.options.valueOf("purpur-settings"));
|
||||
+ for (WorldServer world : console.getWorlds()) {
|
||||
+ world.purpurConfig.init();
|
||||
+ }
|
||||
+ console.server.reloadCount++;
|
||||
+
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Purpur config reload complete.");
|
||||
+ } else if (args[0].equalsIgnoreCase("version")) {
|
||||
+ Command verCmd = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version");
|
||||
+ if (verCmd != null) {
|
||||
+ return verCmd.execute(sender, commandLabel, new String[0]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index c8e2f682746cd94c2f02a452bbeb672c36a916a1..f53389a49e62f54faa6af19226589305b597d1ae 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -882,6 +882,7 @@ public final class CraftServer implements Server {
|
||||
org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot
|
||||
com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); // Paper
|
||||
com.tuinity.tuinity.config.TuinityConfig.init((File) console.options.valueOf("tuinity-settings")); // Tuinity - Server Config
|
||||
+ net.pl3x.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur
|
||||
for (WorldServer world : console.getWorlds()) {
|
||||
world.worldDataServer.setDifficulty(config.difficulty);
|
||||
world.setSpawnFlags(config.spawnMonsters, config.spawnAnimals);
|
||||
@@ -917,6 +918,7 @@ public final class CraftServer implements Server {
|
||||
world.spigotConfig.init(); // Spigot
|
||||
world.paperConfig.init(); // Paper
|
||||
world.tuinityConfig.init(); // Tuinity - Server Config
|
||||
+ world.purpurConfig.init(); // Purpur
|
||||
}
|
||||
|
||||
Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper
|
||||
@@ -935,6 +937,7 @@ public final class CraftServer implements Server {
|
||||
reloadData();
|
||||
org.spigotmc.SpigotConfig.registerCommands(); // Spigot
|
||||
com.destroystokyo.paper.PaperConfig.registerCommands(); // Paper
|
||||
+ net.pl3x.purpur.PurpurConfig.registerCommands(); // Purpur
|
||||
overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*");
|
||||
ignoreVanillaPermissions = commandsConfiguration.getBoolean("ignore-vanilla-permissions");
|
||||
|
||||
@@ -2385,6 +2388,18 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
// Tuinity end - add config to timings report
|
||||
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public YamlConfiguration getPurpurConfig() {
|
||||
+ return net.pl3x.purpur.PurpurConfig.config;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Properties getServerProperties() {
|
||||
+ return getProperties().properties;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
@Override
|
||||
public void restart() {
|
||||
org.spigotmc.RestartCommand.restart();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 57180e164ac51b1aac070c00d820792d13d67258..09168bced10094c2058ffe7a10613b83360d998b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -154,6 +154,14 @@ public class Main {
|
||||
.describedAs("Yml file");
|
||||
/* Conctete End - Server Config */
|
||||
|
||||
+ // Purpur Start
|
||||
+ acceptsAll(asList("purpur", "purpur-settings"), "File for purpur settings")
|
||||
+ .withRequiredArg()
|
||||
+ .ofType(File.class)
|
||||
+ .defaultsTo(new File("purpur.yml"))
|
||||
+ .describedAs("Yml file");
|
||||
+ // Purpur end
|
||||
+
|
||||
// Paper start
|
||||
acceptsAll(asList("server-name"), "Name of the server")
|
||||
.withRequiredArg()
|
@ -1,73 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 5 Jun 2020 21:30:19 -0500
|
||||
Subject: [PATCH] Timings stuff
|
||||
|
||||
|
||||
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
|
||||
index 35810f42d7a0cd50a4cbe90e8d698fe57914c889..5e672a0660d0aceffcdb26d185590ca18aa4f023 100644
|
||||
--- a/src/main/java/co/aikar/timings/TimingsExport.java
|
||||
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
|
||||
@@ -227,10 +227,14 @@ public class TimingsExport extends Thread {
|
||||
// Information on the users Config
|
||||
|
||||
parent.put("config", createObject(
|
||||
- pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
|
||||
- pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
|
||||
- pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Tuinity - add config to timings report
|
||||
- pair("tuinity", mapAsJSON(Bukkit.spigot().getTuinityConfig(), null)) // Tuinity - add config to timings report
|
||||
+ // Purpur start
|
||||
+ pair("server.properties", mapAsJSON(Bukkit.spigot().getServerProperties())),
|
||||
+ pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
|
||||
+ pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
|
||||
+ pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)),
|
||||
+ pair("tuinity", mapAsJSON(Bukkit.spigot().getTuinityConfig(), null)), // Tuinity - add config to timings report
|
||||
+ pair("purpur", mapAsJSON(Bukkit.spigot().getPurpurConfig(), null))
|
||||
+ // Purpur end
|
||||
));
|
||||
|
||||
new TimingsExport(listeners, parent, history).start();
|
||||
@@ -271,6 +275,19 @@ public class TimingsExport extends Thread {
|
||||
return timingsCost;
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ private static JSONObject mapAsJSON(java.util.Properties properties) {
|
||||
+ JSONObject object = new JSONObject();
|
||||
+ for (String key : properties.stringPropertyNames()) {
|
||||
+ if (key.startsWith("rcon") || key.startsWith("query") || key.equals("level-seed") || TimingsManager.hiddenConfigs.contains(key)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ object.put(key, valAsJSON(properties.get(key), key));
|
||||
+ }
|
||||
+ return object;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
private static JSONObject mapAsJSON(ConfigurationSection config, String parentKey) {
|
||||
|
||||
JSONObject object = new JSONObject();
|
||||
@@ -307,7 +324,7 @@ public class TimingsExport extends Thread {
|
||||
String response = null;
|
||||
String timingsURL = null;
|
||||
try {
|
||||
- HttpURLConnection con = (HttpURLConnection) new URL("http://timings.aikar.co/post").openConnection();
|
||||
+ HttpURLConnection con = (HttpURLConnection) new URL(net.pl3x.purpur.PurpurConfig.timingsUrl + "/post").openConnection(); // Purpur
|
||||
con.setDoOutput(true);
|
||||
String hostName = "BrokenHost";
|
||||
try {
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
index 74fc4fc2216cf82e1546ef3d567f2750b1240df1..108be36fc37c04eece6ccb93d19e58a31326ceb0 100644
|
||||
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
@@ -127,4 +127,10 @@ public class PurpurConfig {
|
||||
config.addDefault(path, def);
|
||||
return config.getString(path, config.getString(path));
|
||||
}
|
||||
+
|
||||
+ public static String timingsUrl = "https://timings.pl3x.net";
|
||||
+ private static void timingsSettings() {
|
||||
+ timingsUrl = getString("settings.timings.url", timingsUrl);
|
||||
+ if (!TimingsManager.hiddenConfigs.contains("server-ip")) TimingsManager.hiddenConfigs.add("server-ip");
|
||||
+ }
|
||||
}
|
@ -1,189 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 23 May 2019 21:50:37 -0500
|
||||
Subject: [PATCH] Barrels and enderchests 6 rows
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/InventoryEnderChest.java b/src/main/java/net/minecraft/world/inventory/InventoryEnderChest.java
|
||||
index 85b9eba1dba3de69ab65b0e1c5ebb8740ce6e9e5..97f6ba97a4b2a35c0b8a003e1e27ad38831d859d 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/InventoryEnderChest.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/InventoryEnderChest.java
|
||||
@@ -28,11 +28,34 @@ public class InventoryEnderChest extends InventorySubcontainer {
|
||||
}
|
||||
|
||||
public InventoryEnderChest(EntityHuman owner) {
|
||||
- super(27);
|
||||
+ super(net.pl3x.purpur.PurpurConfig.enderChestSixRows ? 54 : 27); // Purpur
|
||||
this.owner = owner;
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public int getSize() {
|
||||
+ if (net.pl3x.purpur.PurpurConfig.enderChestSixRows && net.pl3x.purpur.PurpurConfig.enderChestPermissionRows && owner != null && owner.getProfile() != null) {
|
||||
+ org.bukkit.craftbukkit.entity.CraftHumanEntity bukkit = owner.getBukkitEntity();
|
||||
+ if (bukkit.hasPermission("purpur.enderchest.rows.six")) {
|
||||
+ return 54;
|
||||
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.five")) {
|
||||
+ return 45;
|
||||
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.four")) {
|
||||
+ return 36;
|
||||
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.three")) {
|
||||
+ return 27;
|
||||
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.two")) {
|
||||
+ return 18;
|
||||
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.one")) {
|
||||
+ return 9;
|
||||
+ }
|
||||
+ }
|
||||
+ return super.getSize();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
public void a(TileEntityEnderChest tileentityenderchest) {
|
||||
this.a = tileentityenderchest;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/BlockEnderChest.java b/src/main/java/net/minecraft/world/level/block/BlockEnderChest.java
|
||||
index 70d10c492b6ba893d56a463c0e71ac6aa8707f81..34ea9d2aeb9d606d487be796283c9d5ed614a6af 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BlockEnderChest.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BlockEnderChest.java
|
||||
@@ -11,6 +11,7 @@ import net.minecraft.world.TileInventory;
|
||||
import net.minecraft.world.entity.monster.piglin.PiglinAI;
|
||||
import net.minecraft.world.entity.player.EntityHuman;
|
||||
import net.minecraft.world.inventory.ContainerChest;
|
||||
+import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.inventory.InventoryEnderChest;
|
||||
import net.minecraft.world.item.context.BlockActionContext;
|
||||
import net.minecraft.world.level.GeneratorAccess;
|
||||
@@ -81,6 +82,27 @@ public class BlockEnderChest extends BlockChestAbstract<TileEntityEnderChest> im
|
||||
|
||||
inventoryenderchest.a(tileentityenderchest);
|
||||
entityhuman.openContainer(new TileInventory((i, playerinventory, entityhuman1) -> {
|
||||
+ // Purpur start
|
||||
+ if (net.pl3x.purpur.PurpurConfig.enderChestSixRows) {
|
||||
+ if (net.pl3x.purpur.PurpurConfig.enderChestPermissionRows) {
|
||||
+ org.bukkit.craftbukkit.entity.CraftHumanEntity player = entityhuman.getBukkitEntity();
|
||||
+ if (player.hasPermission("purpur.enderchest.rows.six")) {
|
||||
+ return new ContainerChest(Containers.GENERIC_9X6, i, playerinventory, inventoryenderchest, 6);
|
||||
+ } else if (player.hasPermission("purpur.enderchest.rows.five")) {
|
||||
+ return new ContainerChest(Containers.GENERIC_9X5, i, playerinventory, inventoryenderchest, 5);
|
||||
+ } else if (player.hasPermission("purpur.enderchest.rows.four")) {
|
||||
+ return new ContainerChest(Containers.GENERIC_9X4, i, playerinventory, inventoryenderchest, 4);
|
||||
+ } else if (player.hasPermission("purpur.enderchest.rows.three")) {
|
||||
+ return new ContainerChest(Containers.GENERIC_9X3, i, playerinventory, inventoryenderchest, 3);
|
||||
+ } else if (player.hasPermission("purpur.enderchest.rows.two")) {
|
||||
+ return new ContainerChest(Containers.GENERIC_9X2, i, playerinventory, inventoryenderchest, 2);
|
||||
+ } else if (player.hasPermission("purpur.enderchest.rows.one")) {
|
||||
+ return new ContainerChest(Containers.GENERIC_9X1, i, playerinventory, inventoryenderchest, 1);
|
||||
+ }
|
||||
+ }
|
||||
+ return new ContainerChest(Containers.GENERIC_9X6, i, playerinventory, inventoryenderchest, 6);
|
||||
+ }
|
||||
+ // Purpur end
|
||||
return ContainerChest.a(i, playerinventory, inventoryenderchest);
|
||||
}, BlockEnderChest.e));
|
||||
entityhuman.a(StatisticList.OPEN_ENDERCHEST);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBarrel.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBarrel.java
|
||||
index 7a6f150490bc3ef8a5ed43c401fd70bcc67f40f0..449d2c38abdd35b782a6732006eebb381815bcba 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityBarrel.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityBarrel.java
|
||||
@@ -14,6 +14,7 @@ import net.minecraft.world.entity.player.EntityHuman;
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.ContainerChest;
|
||||
+import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.BlockBarrel;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
@@ -68,7 +69,7 @@ public class TileEntityBarrel extends TileEntityLootable {
|
||||
|
||||
private TileEntityBarrel(TileEntityTypes<?> tileentitytypes) {
|
||||
super(tileentitytypes);
|
||||
- this.items = NonNullList.a(27, ItemStack.b);
|
||||
+ this.items = NonNullList.a(net.pl3x.purpur.PurpurConfig.barrelSixRows ? 54 : 27, ItemStack.b); // Purpur
|
||||
}
|
||||
|
||||
public TileEntityBarrel() {
|
||||
@@ -97,7 +98,7 @@ public class TileEntityBarrel extends TileEntityLootable {
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
- return 27;
|
||||
+ return net.pl3x.purpur.PurpurConfig.barrelSixRows ? 54 : 27; // Purpur
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,6 +118,7 @@ public class TileEntityBarrel extends TileEntityLootable {
|
||||
|
||||
@Override
|
||||
protected Container createContainer(int i, PlayerInventory playerinventory) {
|
||||
+ if (net.pl3x.purpur.PurpurConfig.barrelSixRows) return new ContainerChest(Containers.GENERIC_9X6, i, playerinventory, this, 6); // Purpur
|
||||
return ContainerChest.a(i, playerinventory, this);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
index 108be36fc37c04eece6ccb93d19e58a31326ceb0..2f329bae9f09d0ed21a4538fba6b95919ec35887 100644
|
||||
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
@@ -7,6 +7,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
+import org.bukkit.event.inventory.InventoryType;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -133,4 +134,23 @@ public class PurpurConfig {
|
||||
timingsUrl = getString("settings.timings.url", timingsUrl);
|
||||
if (!TimingsManager.hiddenConfigs.contains("server-ip")) TimingsManager.hiddenConfigs.add("server-ip");
|
||||
}
|
||||
+
|
||||
+ public static boolean barrelSixRows = false;
|
||||
+ public static boolean enderChestSixRows = false;
|
||||
+ public static boolean enderChestPermissionRows = false;
|
||||
+ private static void blockSettings() {
|
||||
+ if (version < 3) {
|
||||
+ boolean oldValue = getBoolean("settings.barrel.packed-barrels", true);
|
||||
+ set("settings.blocks.barrel.six-rows", oldValue);
|
||||
+ set("settings.packed-barrels", null);
|
||||
+ oldValue = getBoolean("settings.large-ender-chests", true);
|
||||
+ set("settings.blocks.ender_chest.six-rows", oldValue);
|
||||
+ set("settings.large-ender-chests", null);
|
||||
+ }
|
||||
+ barrelSixRows = getBoolean("settings.blocks.barrel.six-rows", barrelSixRows);
|
||||
+ InventoryType.BARREL.setDefaultSize(barrelSixRows ? 54 : 27);
|
||||
+ enderChestSixRows = getBoolean("settings.blocks.ender_chest.six-rows", enderChestSixRows);
|
||||
+ InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27);
|
||||
+ enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
index 614ab2d73db2293116f2272f6cd5c16da446132d..2885dc250f171917393c0356a005b476b23f9c5f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
@@ -212,8 +212,10 @@ public class CraftContainer extends Container {
|
||||
case PLAYER:
|
||||
case CHEST:
|
||||
case ENDER_CHEST:
|
||||
+ delegate = new ContainerChest(net.pl3x.purpur.PurpurConfig.enderChestSixRows ? Containers.GENERIC_9X6 : Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur
|
||||
+ break; // Purpur
|
||||
case BARREL:
|
||||
- delegate = new ContainerChest(Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9);
|
||||
+ delegate = new ContainerChest(net.pl3x.purpur.PurpurConfig.barrelSixRows ? Containers.GENERIC_9X6 : Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur
|
||||
break;
|
||||
case DISPENSER:
|
||||
case DROPPER:
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
index f6001047ada8308cfa1d9b26677a7a5d7774de51..922a15097bdfe64be657fdf157145d1e882b6a40 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
@@ -82,7 +82,7 @@ public class CraftInventory implements Inventory {
|
||||
|
||||
@Override
|
||||
public void setContents(ItemStack[] items) {
|
||||
- if (getSize() < items.length) {
|
||||
+ if (false && getSize() < items.length) { // Purpur
|
||||
throw new IllegalArgumentException("Invalid inventory size; expected " + getSize() + " or less");
|
||||
}
|
||||
|
@ -1,180 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 31 May 2019 21:24:33 -0500
|
||||
Subject: [PATCH] Advancement API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/advancements/Advancement.java b/src/main/java/net/minecraft/advancements/Advancement.java
|
||||
index 2f3d9e5b849093027d3c2ef434494cd600f52a31..23567430901284ab9d4d4873e53a1c8a06da6862 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/Advancement.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/Advancement.java
|
||||
@@ -78,7 +78,7 @@ public class Advancement {
|
||||
|
||||
public final @Nullable AdvancementDisplay getAdvancementDisplay() { return this.c(); } // Paper - OBFHELPER
|
||||
@Nullable
|
||||
- public AdvancementDisplay c() {
|
||||
+ public AdvancementDisplay c() { return getDisplay(); } public AdvancementDisplay getDisplay() { // Purpur
|
||||
return this.display;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/advancements/AdvancementDisplay.java b/src/main/java/net/minecraft/advancements/AdvancementDisplay.java
|
||||
index adc6779e53e7b2ee04a80e2ea714e3378b8e6f39..3335c96ec15eb8d8f0b67f51846038f728f6f9fc 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/AdvancementDisplay.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/AdvancementDisplay.java
|
||||
@@ -25,10 +25,11 @@ public class AdvancementDisplay {
|
||||
private final MinecraftKey d;
|
||||
private final AdvancementFrameType e;
|
||||
private final boolean f;
|
||||
- private final boolean g;
|
||||
- private final boolean h;
|
||||
+ private boolean g; // Purpur - un-finalize
|
||||
+ private boolean h; // Purpur - un-finalize
|
||||
private float i;
|
||||
private float j;
|
||||
+ public final org.bukkit.advancement.AdvancementDisplay bukkit = new org.bukkit.craftbukkit.advancement.CraftAdvancementDisplay(this); // Purpur
|
||||
|
||||
public AdvancementDisplay(ItemStack itemstack, IChatBaseComponent ichatbasecomponent, IChatBaseComponent ichatbasecomponent1, @Nullable MinecraftKey minecraftkey, AdvancementFrameType advancementframetype, boolean flag, boolean flag1, boolean flag2) {
|
||||
this.a = ichatbasecomponent;
|
||||
@@ -46,10 +47,12 @@ public class AdvancementDisplay {
|
||||
this.j = f1;
|
||||
}
|
||||
|
||||
+ public IChatBaseComponent getTitle() { return a(); } // Purpur - OBFHELPER
|
||||
public IChatBaseComponent a() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
+ public IChatBaseComponent getDescription() { return b(); } // Purpur - OBFHELPER
|
||||
public IChatBaseComponent b() {
|
||||
return this.b;
|
||||
}
|
||||
@@ -59,11 +62,14 @@ public class AdvancementDisplay {
|
||||
return this.e;
|
||||
}
|
||||
|
||||
+ public final void setShouldAnnounceToChat(boolean announce) { this.g = announce; } // Purpur - OBFHELPER
|
||||
public final boolean shouldAnnounceToChat() { return this.i(); } // Paper - OBFHELPER
|
||||
public boolean i() {
|
||||
return this.g;
|
||||
}
|
||||
|
||||
+ public void setHidden(boolean hidden) { this.h = hidden; } // Purpur - OBFHELPER
|
||||
+ public boolean isHidden() { return j(); } // Purpur - OBFHELPER
|
||||
public boolean j() {
|
||||
return this.h;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/advancements/AdvancementFrameType.java b/src/main/java/net/minecraft/advancements/AdvancementFrameType.java
|
||||
index 32380346555e194227423999a79f1ebcbbe38d3b..173266c81be66f85db06dd28d9c9d720e21f8bc4 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/AdvancementFrameType.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/AdvancementFrameType.java
|
||||
@@ -4,16 +4,27 @@ import net.minecraft.EnumChatFormat;
|
||||
import net.minecraft.network.chat.ChatMessage;
|
||||
import net.minecraft.network.chat.IChatBaseComponent;
|
||||
|
||||
+import org.bukkit.advancement.FrameType; // Purpur
|
||||
+
|
||||
public enum AdvancementFrameType {
|
||||
|
||||
- TASK("task", 0, EnumChatFormat.GREEN), CHALLENGE("challenge", 26, EnumChatFormat.DARK_PURPLE), GOAL("goal", 52, EnumChatFormat.GREEN);
|
||||
+ // Purpur start
|
||||
+ TASK("task", 0, EnumChatFormat.GREEN, FrameType.TASK),
|
||||
+ CHALLENGE("challenge", 26, EnumChatFormat.DARK_PURPLE, FrameType.CHALLENGE),
|
||||
+ GOAL("goal", 52, EnumChatFormat.GREEN, FrameType.GOAL);
|
||||
+ // Purpur end
|
||||
|
||||
private final String d;
|
||||
private final int e;
|
||||
private final EnumChatFormat f;
|
||||
private final IChatBaseComponent g;
|
||||
|
||||
- private AdvancementFrameType(String s, int i, EnumChatFormat enumchatformat) {
|
||||
+ // Purpur start
|
||||
+ public final FrameType bukkit;
|
||||
+
|
||||
+ AdvancementFrameType(String s, int i, EnumChatFormat enumchatformat, FrameType bukkit) {
|
||||
+ this.bukkit = bukkit;
|
||||
+ // Purpur end
|
||||
this.d = s;
|
||||
this.e = i;
|
||||
this.f = enumchatformat;
|
||||
diff --git a/src/main/java/net/minecraft/advancements/CriterionTrigger.java b/src/main/java/net/minecraft/advancements/CriterionTrigger.java
|
||||
index f2d74473caf96ca6e871311ef87afa128cd4d0bf..851e69a2f5155d9fa2e5652abdea9aee59e4b20a 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/CriterionTrigger.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/CriterionTrigger.java
|
||||
@@ -29,6 +29,7 @@ public interface CriterionTrigger<T extends CriterionInstance> {
|
||||
this.c = s;
|
||||
}
|
||||
|
||||
+ public T getInstance() { return a(); } // Purpur - OBFHELPER
|
||||
public T a() {
|
||||
return this.a;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
|
||||
index 77abcd6de43302985cdbb2085abece4f621068d4..c859fc16c263e0c50cb01fc722b6f6723d682481 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
|
||||
@@ -27,4 +27,11 @@ public class CraftAdvancement implements org.bukkit.advancement.Advancement {
|
||||
public Collection<String> getCriteria() {
|
||||
return Collections.unmodifiableCollection(handle.getCriteria().keySet());
|
||||
}
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public org.bukkit.advancement.AdvancementDisplay getDisplay() {
|
||||
+ return getHandle().getDisplay() == null ? null : getHandle().getDisplay().bukkit;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0b4ff544e04ec314e78a7a48b5bf90ee699b2ad6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
|
||||
@@ -0,0 +1,47 @@
|
||||
+package org.bukkit.craftbukkit.advancement;
|
||||
+
|
||||
+import net.minecraft.advancements.AdvancementDisplay;
|
||||
+import org.bukkit.advancement.FrameType;
|
||||
+import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
+
|
||||
+public class CraftAdvancementDisplay implements org.bukkit.advancement.AdvancementDisplay {
|
||||
+ private final AdvancementDisplay handle;
|
||||
+
|
||||
+ public CraftAdvancementDisplay(AdvancementDisplay handle) {
|
||||
+ this.handle = handle;
|
||||
+ }
|
||||
+
|
||||
+ public AdvancementDisplay getHandle() {
|
||||
+ return handle;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getTitle() {
|
||||
+ return CraftChatMessage.fromComponent(handle.getTitle());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getDescription() {
|
||||
+ return CraftChatMessage.fromComponent(handle.getDescription());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public FrameType getFrameType() {
|
||||
+ return handle.getFrameType().bukkit;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean shouldAnnounceToChat() {
|
||||
+ return handle.shouldAnnounceToChat();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShouldAnnounceToChat(boolean announce) {
|
||||
+ handle.setShouldAnnounceToChat(announce);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isHidden() {
|
||||
+ return handle.isHidden();
|
||||
+ }
|
||||
+}
|
@ -1,156 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 18 Oct 2019 22:50:12 -0500
|
||||
Subject: [PATCH] Llama API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalLlamaFollow.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalLlamaFollow.java
|
||||
index 4fd1744f13b87c79ae3f46b28a56daeaba343aa6..34a854131dd939693a6df4d52103714ebe373dc3 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalLlamaFollow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalLlamaFollow.java
|
||||
@@ -11,7 +11,7 @@ import net.minecraft.world.phys.Vec3D;
|
||||
|
||||
public class PathfinderGoalLlamaFollow extends PathfinderGoal {
|
||||
|
||||
- public final EntityLlama a;
|
||||
+ public final EntityLlama a; public EntityLlama getLlama() { return a; } // Purpur
|
||||
private double b;
|
||||
private int c;
|
||||
|
||||
@@ -23,6 +23,7 @@ public class PathfinderGoalLlamaFollow extends PathfinderGoal {
|
||||
|
||||
@Override
|
||||
public boolean a() {
|
||||
+ if (!getLlama().shouldJoinCaravan) return false; // Purpur
|
||||
if (!this.a.isLeashed() && !this.a.fC()) {
|
||||
List<Entity> list = this.a.world.getEntities(this.a, this.a.getBoundingBox().grow(9.0D, 4.0D, 9.0D), (entity) -> {
|
||||
EntityTypes<?> entitytypes = entity.getEntityType();
|
||||
@@ -82,6 +83,7 @@ public class PathfinderGoalLlamaFollow extends PathfinderGoal {
|
||||
|
||||
@Override
|
||||
public boolean b() {
|
||||
+ if (!getLlama().shouldJoinCaravan) return false; // Purpur
|
||||
if (this.a.fC() && this.a.fD().isAlive() && this.a(this.a, 0)) {
|
||||
double d0 = this.a.h((Entity) this.a.fD());
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java
|
||||
index 2005cb484ba6b5929ad81d3d120521f247f3d4cf..1c6435bf2cd870b795f87368057d8dfc1e1c938a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java
|
||||
@@ -63,7 +63,8 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
||||
@Nullable
|
||||
private EntityLlama bB;
|
||||
@Nullable
|
||||
- private EntityLlama bC;
|
||||
+ private EntityLlama bC; public EntityLlama getCaravanTail() { return bC; } // Purpur - OBFHELPER
|
||||
+ public boolean shouldJoinCaravan = true; // Purpur
|
||||
|
||||
public EntityLlama(EntityTypes<? extends EntityLlama> entitytypes, World world) {
|
||||
super(entitytypes, world);
|
||||
@@ -92,6 +93,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
||||
nbttagcompound.set("DecorItem", this.inventoryChest.getItem(1).save(new NBTTagCompound()));
|
||||
}
|
||||
|
||||
+ nbttagcompound.setBoolean("Purpur.ShouldJoinCaravan", shouldJoinCaravan); // Purpur
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,6 +105,11 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
||||
this.inventoryChest.setItem(1, ItemStack.a(nbttagcompound.getCompound("DecorItem")));
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ if (nbttagcompound.hasKey("Purpur.ShouldJoinCaravan")) {
|
||||
+ nbttagcompound.setBoolean("Purpur.ShouldJoinCaravan", shouldJoinCaravan);
|
||||
+ }
|
||||
+ // Purpur end
|
||||
this.fe();
|
||||
}
|
||||
|
||||
@@ -437,19 +444,24 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
||||
}
|
||||
}
|
||||
|
||||
+ public void leaveCaravan() { fA(); } // Purpur - OBFHELPER
|
||||
public void fA() {
|
||||
if (this.bB != null) {
|
||||
+ new net.pl3x.purpur.event.entity.LlamaLeaveCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity()).callEvent(); // Purpur
|
||||
this.bB.bC = null;
|
||||
}
|
||||
|
||||
this.bB = null;
|
||||
}
|
||||
|
||||
+ public void joinCaravan(EntityLlama entitiyllama) { a(entitiyllama); } // Purpur - OBFHELPER
|
||||
public void a(EntityLlama entityllama) {
|
||||
+ if (!shouldJoinCaravan || !new net.pl3x.purpur.event.entity.LlamaJoinCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity(), (org.bukkit.entity.Llama) entityllama.getBukkitEntity()).callEvent()) return; // Purpur
|
||||
this.bB = entityllama;
|
||||
this.bB.bC = this;
|
||||
}
|
||||
|
||||
+ public boolean hasCaravanTail() { return fB(); } // Purpur - OBFHELPER
|
||||
public boolean fB() {
|
||||
return this.bC != null;
|
||||
}
|
||||
@@ -460,7 +472,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- public EntityLlama fD() {
|
||||
+ public EntityLlama fD() { return getCaravanHead(); } public EntityLlama getCaravanHead() { // Purpur - OBFHELPER
|
||||
return this.bB;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
index 818034c62893a71808e3af0aa33393605611acdd..71536b6ae6a423e33667efcf584a0020f36fb189 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
@@ -66,4 +66,48 @@ public class CraftLlama extends CraftChestedHorse implements Llama, CraftRangedE
|
||||
public EntityType getType() {
|
||||
return EntityType.LLAMA;
|
||||
}
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public boolean shouldJoinCaravan() {
|
||||
+ return getHandle().shouldJoinCaravan;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShouldJoinCaravan(boolean shouldJoinCaravan) {
|
||||
+ getHandle().shouldJoinCaravan = shouldJoinCaravan;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean inCaravan() {
|
||||
+ return getHandle().inCaravan();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void joinCaravan(Llama llama) {
|
||||
+ if (llama != null) {
|
||||
+ getHandle().joinCaravan(((CraftLlama) llama).getHandle());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void leaveCaravan() {
|
||||
+ getHandle().leaveCaravan();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasCaravanTail() {
|
||||
+ return getHandle().hasCaravanTail();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Llama getCaravanHead() {
|
||||
+ return getHandle().getCaravanHead() == null ? null : (Llama) getHandle().getCaravanHead().getBukkitEntity();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Llama getCaravanTail() {
|
||||
+ return getHandle().getCaravanTail() == null ? null : (Llama) getHandle().getCaravanTail().getBukkitEntity();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
@ -1,302 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 8 Aug 2019 15:29:15 -0500
|
||||
Subject: [PATCH] AFK API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java
|
||||
index 32e400632ec1e61374f772c6262580f84a5b2288..aee1946f96ec6007caef63b2183c5218ffe71836 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/EntityPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java
|
||||
@@ -2102,8 +2102,54 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||
|
||||
public void resetIdleTimer() {
|
||||
this.ca = SystemUtils.getMonotonicMillis();
|
||||
+ setAfk(false); // Purpur
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ private boolean isAfk = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public void setAfk(boolean setAfk) {
|
||||
+ if (this.isAfk == setAfk) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ String msg = setAfk ? net.pl3x.purpur.PurpurConfig.afkBroadcastAway : net.pl3x.purpur.PurpurConfig.afkBroadcastBack;
|
||||
+
|
||||
+ net.pl3x.purpur.event.PlayerAFKEvent event = new net.pl3x.purpur.event.PlayerAFKEvent(getBukkitEntity(), setAfk, world.purpurConfig.idleTimeoutKick, msg, !Bukkit.isPrimaryThread());
|
||||
+ if (!event.callEvent() || event.shouldKick()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ this.isAfk = setAfk;
|
||||
+
|
||||
+ if (!setAfk) {
|
||||
+ resetIdleTimer();
|
||||
+ }
|
||||
+
|
||||
+ msg = event.getBroadcastMsg();
|
||||
+ if (msg != null && !msg.isEmpty()) {
|
||||
+ server.getPlayerList().sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromStringOrNull(String.format(msg, getProfile().getName())));
|
||||
+ }
|
||||
+
|
||||
+ if (world.purpurConfig.idleTimeoutUpdateTabList) {
|
||||
+ getBukkitEntity().setPlayerListName((setAfk ? net.pl3x.purpur.PurpurConfig.afkTabListPrefix : "") + getName());
|
||||
+ }
|
||||
+
|
||||
+ ((WorldServer) world).everyoneSleeping();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isAfk() {
|
||||
+ return isAfk;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCollidable() {
|
||||
+ return !isAfk() && super.isCollidable();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
public ServerStatisticManager getStatisticManager() {
|
||||
return this.serverStatisticManager;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
|
||||
index b11af463045bbd3bab8d269fde34071ca5f026af..6433ce5a5b951334efb3d8d7199f784f23392e0e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
|
||||
@@ -1018,7 +1018,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
// CraftBukkit end
|
||||
|
||||
if (this.everyoneSleeping && this.players.stream().noneMatch((entityplayer) -> {
|
||||
- return !entityplayer.isSpectator() && !entityplayer.isDeeplySleeping() && !entityplayer.fauxSleeping; // CraftBukkit
|
||||
+ return !entityplayer.isSpectator() && !entityplayer.isDeeplySleeping() && !entityplayer.fauxSleeping && !(purpurConfig.idleTimeoutCountAsSleeping && entityplayer.isAfk()); // CraftBukkit // Purpur
|
||||
})) {
|
||||
// CraftBukkit start
|
||||
long l = this.worldData.getDayTime() + 24000L;
|
||||
@@ -1363,7 +1363,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
while (iterator.hasNext()) {
|
||||
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
||||
|
||||
- if (entityplayer.isSpectator() || (entityplayer.fauxSleeping && !entityplayer.isSleeping())) { // CraftBukkit
|
||||
+ if (entityplayer.isSpectator() || (entityplayer.fauxSleeping && !entityplayer.isSleeping()) || (purpurConfig.idleTimeoutCountAsSleeping && entityplayer.isAfk())) { // CraftBukkit // Purpur
|
||||
++i;
|
||||
} else if (entityplayer.isSleeping()) {
|
||||
++j;
|
||||
diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java
|
||||
index 8513795943497ca80232e7d47066a6944c2f45ec..de72ebb94052efe8c63bf28f6741a4645b3ee721 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/PlayerConnection.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java
|
||||
@@ -399,6 +399,12 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
}
|
||||
|
||||
if (this.player.F() > 0L && this.minecraftServer.getIdleTimeout() > 0 && SystemUtils.getMonotonicMillis() - this.player.F() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) {
|
||||
+ // Purpur start
|
||||
+ this.player.setAfk(true);
|
||||
+ if (!this.player.world.purpurConfig.idleTimeoutKick) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854
|
||||
this.disconnect(new ChatMessage("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
|
||||
}
|
||||
@@ -682,6 +688,8 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
this.lastYaw = to.getYaw();
|
||||
this.lastPitch = to.getPitch();
|
||||
|
||||
+ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ() || to.getYaw() != from.getYaw() || to.getPitch() != from.getPitch()) this.player.resetIdleTimer(); // Purpur
|
||||
+
|
||||
// Skip the first time we do this
|
||||
if (true) { // Spigot - don't skip any move events
|
||||
Location oldTo = to.clone();
|
||||
@@ -1429,7 +1437,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
|
||||
if (!this.player.H() && d11 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.playerInteractManager.isCreative() && this.player.playerInteractManager.getGameMode() != EnumGamemode.SPECTATOR) { // Spigot
|
||||
flag1 = true; // Tuinity - diff on change, this should be moved wrongly
|
||||
- PlayerConnection.LOGGER.warn("{} moved wrongly!", this.player.getDisplayName().getString());
|
||||
+ PlayerConnection.LOGGER.warn("{} moved wrongly! ({})", this.player.getDisplayName().getString(), d11); // Purpur
|
||||
}
|
||||
|
||||
this.player.setLocation(d4, d5, d6, f, f1);
|
||||
@@ -1479,6 +1487,8 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
this.lastYaw = to.getYaw();
|
||||
this.lastPitch = to.getPitch();
|
||||
|
||||
+ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ() || to.getYaw() != from.getYaw() || to.getPitch() != from.getPitch()) this.player.resetIdleTimer(); // Purpur
|
||||
+
|
||||
// Skip the first time we do this
|
||||
if (from.getX() != Double.MAX_VALUE) {
|
||||
Location oldTo = to.clone();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/IEntitySelector.java b/src/main/java/net/minecraft/world/entity/IEntitySelector.java
|
||||
index f5e32faeb6d937cf90b1f3ea251b5cfc91f2338d..f9908fb7cc27a8947030c2100dccf1dc1a4e24f7 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/IEntitySelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/IEntitySelector.java
|
||||
@@ -15,6 +15,7 @@ import net.minecraft.world.scores.ScoreboardTeamBase;
|
||||
public final class IEntitySelector {
|
||||
|
||||
public static final Predicate<Entity> a = Entity::isAlive;
|
||||
+ public static Predicate<EntityLiving> isLivingAlive() { return b; } // Purpur - OBFHELPER
|
||||
public static final Predicate<EntityLiving> b = EntityLiving::isAlive;
|
||||
public static final Predicate<Entity> c = (entity) -> {
|
||||
return entity.isAlive() && !entity.isVehicle() && !entity.isPassenger();
|
||||
@@ -35,6 +36,7 @@ public final class IEntitySelector {
|
||||
return !entity.isSpectator();
|
||||
};
|
||||
public static Predicate<EntityHuman> isInsomniac = (player) -> MathHelper.clamp(((EntityPlayer) player).getStatisticManager().getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper
|
||||
+ public static Predicate<EntityHuman> notAfk = (player) -> !player.isAfk(); // Purpur
|
||||
|
||||
// Paper start
|
||||
public static final Predicate<Entity> affectsSpawning = (entity) -> {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
|
||||
index 5f9e64df007ebc40f7bcb50be495b10e51d5b87a..17e6f476e60a4f5dc278894a0a874ca5ae45ee22 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
|
||||
@@ -182,6 +182,15 @@ public abstract class EntityHuman extends EntityLiving {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Purpur start
|
||||
+ public void setAfk(boolean setAfk){
|
||||
+ }
|
||||
+
|
||||
+ public boolean isAfk() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
public EntityHuman(World world, BlockPosition blockposition, float f, GameProfile gameprofile) {
|
||||
super(EntityTypes.PLAYER, world);
|
||||
this.bL = ItemStack.b;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/IEntityAccess.java b/src/main/java/net/minecraft/world/level/IEntityAccess.java
|
||||
index a7f2304acf8ee0a15d6eae8c42060e003be13ae7..fd56b2f15e570f266a79c25823a3b3530a693510 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/IEntityAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/IEntityAccess.java
|
||||
@@ -183,28 +183,18 @@ public interface IEntityAccess {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
- default boolean isPlayerNearby(double d0, double d1, double d2, double d3) {
|
||||
- Iterator iterator = this.getPlayers().iterator();
|
||||
-
|
||||
- double d4;
|
||||
-
|
||||
- do {
|
||||
- EntityHuman entityhuman;
|
||||
-
|
||||
- do {
|
||||
- do {
|
||||
- if (!iterator.hasNext()) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- entityhuman = (EntityHuman) iterator.next();
|
||||
- } while (!IEntitySelector.g.test(entityhuman));
|
||||
- } while (!IEntitySelector.b.test(entityhuman));
|
||||
-
|
||||
- d4 = entityhuman.h(d0, d1, d2);
|
||||
- } while (d3 >= 0.0D && d4 >= d3 * d3);
|
||||
-
|
||||
- return true;
|
||||
+ // Purpur start
|
||||
+ default boolean isPlayerNearby(double x, double y, double z, double distance) {
|
||||
+ double distanceSq = distance * distance;
|
||||
+ for (EntityHuman player : getPlayers()) {
|
||||
+ if (IEntitySelector.notSpectator().test(player) && IEntitySelector.isLivingAlive().test(player) && IEntitySelector.notAfk.test(player)) {
|
||||
+ if (distance < 0.0D || player.getDistanceSquared(x, y, z) < distanceSq) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ // Purpur end
|
||||
}
|
||||
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
index 2f329bae9f09d0ed21a4538fba6b95919ec35887..95b55fb93049c6686e13aab78ba1ae2b2fd5785b 100644
|
||||
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.pl3x.purpur;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
+import net.minecraft.locale.LocaleLanguage;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.pl3x.purpur.command.PurpurCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -129,6 +130,15 @@ public class PurpurConfig {
|
||||
return config.getString(path, config.getString(path));
|
||||
}
|
||||
|
||||
+ public static String afkBroadcastAway = "§e§o%s is now AFK";
|
||||
+ public static String afkBroadcastBack = "§e§o%s is no longer AFK";
|
||||
+ public static String afkTabListPrefix = "[AFK] ";
|
||||
+ private static void messages() {
|
||||
+ afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
|
||||
+ afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack);
|
||||
+ afkTabListPrefix = getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix);
|
||||
+ }
|
||||
+
|
||||
public static String timingsUrl = "https://timings.pl3x.net";
|
||||
private static void timingsSettings() {
|
||||
timingsUrl = getString("settings.timings.url", timingsUrl);
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
||||
index 361f7857e461578e90cb71e15027dadaf794cb69..2578a4677d1ee060f687be531e696b7c7be89e84 100644
|
||||
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
||||
@@ -56,4 +56,15 @@ public class PurpurWorldConfig {
|
||||
PurpurConfig.config.addDefault("world-settings.default." + path, def);
|
||||
return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path));
|
||||
}
|
||||
+
|
||||
+ public boolean idleTimeoutKick = true;
|
||||
+ public boolean idleTimeoutTickNearbyEntities = true;
|
||||
+ public boolean idleTimeoutCountAsSleeping = false;
|
||||
+ public boolean idleTimeoutUpdateTabList = false;
|
||||
+ private void playerIdleTimeoutSettings() {
|
||||
+ idleTimeoutKick = getBoolean("gameplay-mechanics.player.idle-timeout.kick-if-idle", idleTimeoutKick);
|
||||
+ idleTimeoutTickNearbyEntities = getBoolean("gameplay-mechanics.player.idle-timeout.tick-nearby-entities", idleTimeoutTickNearbyEntities);
|
||||
+ idleTimeoutCountAsSleeping = getBoolean("gameplay-mechanics.player.idle-timeout.count-as-sleeping", idleTimeoutCountAsSleeping);
|
||||
+ idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index ed1bb89ae7b85bf4017315d6189d6cbf595aefe5..f3fb405c92a35796baa30cafcd96df2d8bf162e6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -2499,4 +2499,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
return spigot;
|
||||
}
|
||||
// Spigot end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public boolean isAfk() {
|
||||
+ return getHandle().isAfk();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setAfk(boolean setAfk) {
|
||||
+ getHandle().setAfk(setAfk);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetIdleTimer() {
|
||||
+ getHandle().resetIdleTimer();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
||||
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
index 94910bf0c53c79588c55b89e4a023273d6c859ef..a57473fb8815545977ff08bf46d6463d2b7a9d78 100644
|
||||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
@@ -207,6 +207,7 @@ public class ActivationRange
|
||||
{
|
||||
|
||||
player.activatedTick = MinecraftServer.currentTick;
|
||||
+ if (!player.world.purpurConfig.idleTimeoutTickNearbyEntities && player.isAfk()) continue; // Purpur
|
||||
maxBB = player.getBoundingBox().grow( maxRange, 256, maxRange );
|
||||
ActivationType.MISC.boundingBox = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange );
|
||||
ActivationType.RAIDER.boundingBox = player.getBoundingBox().grow( raiderActivationRange, 256, raiderActivationRange );
|
@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Sun, 26 May 2019 15:19:14 -0500
|
||||
Subject: [PATCH] Bring back server name
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
index 1fab9b9c7d41a0d2a551096c2c15f741a887fa2d..f33309f4c1ad92960d0634f3f5b8105c284f26a2 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -20,6 +20,7 @@ public class DedicatedServerProperties extends PropertyManager<DedicatedServerPr
|
||||
public final boolean onlineMode = this.getBoolean("online-mode", true);
|
||||
public final boolean preventProxyConnections = this.getBoolean("prevent-proxy-connections", false);
|
||||
public final String serverIp = this.getString("server-ip", "");
|
||||
+ public final String serverName = this.getString("server-name", "Unknown Server"); // Purpur
|
||||
public final boolean spawnAnimals = this.getBoolean("spawn-animals", true);
|
||||
public final boolean spawnNpcs = this.getBoolean("spawn-npcs", true);
|
||||
public final boolean pvp = this.getBoolean("pvp", true);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index f53389a49e62f54faa6af19226589305b597d1ae..3efe2a4eff95349107134b097033bf978f083d56 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2554,4 +2554,11 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public String getServerName() {
|
||||
+ return getProperties().serverName;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Mar 2020 11:47:39 -0500
|
||||
Subject: [PATCH] Configurable server mod name
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 53eca53bfcb1ea66d8cc2ecad34466f932a23866..3d42dbf9008f63cdd1458366fd87c7994cf722ca 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1650,7 +1650,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
}
|
||||
|
||||
public String getServerModName() {
|
||||
- return "Purpur"; // Purpur // Airplane // Tuinity // Paper // Spigot // CraftBukkit
|
||||
+ return net.pl3x.purpur.PurpurConfig.serverModName; // Purpur // Airplane // Tuinity // Paper // Spigot // CraftBukkit
|
||||
}
|
||||
|
||||
public CrashReport b(CrashReport crashreport) {
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
index 95b55fb93049c6686e13aab78ba1ae2b2fd5785b..2442309843bb62e08ae13c46d335c65f7d072510 100644
|
||||
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
@@ -139,6 +139,11 @@ public class PurpurConfig {
|
||||
afkTabListPrefix = getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix);
|
||||
}
|
||||
|
||||
+ public static String serverModName = "Purpur";
|
||||
+ private static void serverModName() {
|
||||
+ serverModName = getString("settings.server-mod-name", serverModName);
|
||||
+ }
|
||||
+
|
||||
public static String timingsUrl = "https://timings.pl3x.net";
|
||||
private static void timingsSettings() {
|
||||
timingsUrl = getString("settings.timings.url", timingsUrl);
|
@ -1,84 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Sun, 5 May 2019 12:58:45 -0500
|
||||
Subject: [PATCH] LivingEntity safeFallDistance
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
||||
index a49dbcffecc971f797651984cb72c455d40f9331..bb030f5b258d82a1a3e60151b42a113b8f8022f1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
||||
@@ -228,6 +228,7 @@ public abstract class EntityLiving extends Entity {
|
||||
// CraftBukkit start
|
||||
public int expToDrop;
|
||||
public int maxAirTicks = 300;
|
||||
+ public float safeFallDistance = 3.0F; // Purpur
|
||||
public boolean forceDrops;
|
||||
public ArrayList<org.bukkit.inventory.ItemStack> drops = new ArrayList<org.bukkit.inventory.ItemStack>();
|
||||
public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
|
||||
@@ -322,8 +323,8 @@ public abstract class EntityLiving extends Entity {
|
||||
this.cR();
|
||||
}
|
||||
|
||||
- if (!this.world.isClientSide && this.fallDistance > 3.0F && flag) {
|
||||
- float f = (float) MathHelper.f(this.fallDistance - 3.0F);
|
||||
+ if (!this.world.isClientSide && this.fallDistance > this.safeFallDistance && flag) { // Purpur
|
||||
+ float f = (float) MathHelper.f(this.fallDistance - this.safeFallDistance); // Purpur
|
||||
|
||||
if (!iblockdata.isAir()) {
|
||||
double d1 = Math.min((double) (0.2F + f / 15.0F), 2.5D);
|
||||
@@ -1803,7 +1804,7 @@ public abstract class EntityLiving extends Entity {
|
||||
MobEffect mobeffect = this.getEffect(MobEffects.JUMP);
|
||||
float f2 = mobeffect == null ? 0.0F : (float) (mobeffect.getAmplifier() + 1);
|
||||
|
||||
- return MathHelper.f((f - 3.0F - f2) * f1);
|
||||
+ return MathHelper.f((f - this.safeFallDistance - f2) * f1); // Purpur
|
||||
}
|
||||
|
||||
protected void playBlockStepSound() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java
|
||||
index 1e41c45af6dbcf097d7d6104e63db637f199301a..cb6e2053d1315b65812e7bff8a17988b5b8ab0e4 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java
|
||||
@@ -272,7 +272,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven
|
||||
|
||||
@Override
|
||||
protected int e(float f, float f1) {
|
||||
- return MathHelper.f((f * 0.5F - 3.0F) * f1);
|
||||
+ return MathHelper.f((f * 0.5F - this.safeFallDistance) * f1); // Purpur
|
||||
}
|
||||
|
||||
protected int getChestSlots() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java b/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java
|
||||
index 3b004160da9a2aed440a3ccda538d78f91c61e87..5e6a92dcdbca686d5a8cfc4aaff72b70b81b111f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java
|
||||
@@ -13,6 +13,7 @@ public class EntityGiantZombie extends EntityMonster {
|
||||
|
||||
public EntityGiantZombie(EntityTypes<? extends EntityGiantZombie> entitytypes, World world) {
|
||||
super(entitytypes, world);
|
||||
+ this.safeFallDistance = 10.0F; // Purpur
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 4545bac9309f5a3aad617f48f7808d8ae829602d..d99ab01298c7e35eae806af8fc60d5beba89c826 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -859,4 +859,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
throw new IllegalArgumentException(entityCategory + " is an unrecognized entity category");
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public float getSafeFallDistance() {
|
||||
+ return getHandle().safeFallDistance;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSafeFallDistance(float safeFallDistance) {
|
||||
+ getHandle().safeFallDistance = safeFallDistance;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Tue, 23 Jul 2019 10:07:16 -0500
|
||||
Subject: [PATCH] Lagging threshold
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 3d42dbf9008f63cdd1458366fd87c7994cf722ca..4a5290a4d9bf8cf0ad48af135231cbef2d8d36f8 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -280,6 +280,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
public static final int TICK_TIME = 1000000000 / TPS;
|
||||
private static final int SAMPLE_INTERVAL = 20; // Paper
|
||||
public final double[] recentTps = new double[ 3 ];
|
||||
+ public boolean lagging = false; // Purpur
|
||||
public final SlackActivityAccountant slackActivityAccountant = new SlackActivityAccountant();
|
||||
// Spigot end
|
||||
|
||||
@@ -1118,6 +1119,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
recentTps[1] = tps5.getAverage();
|
||||
recentTps[2] = tps15.getAverage();
|
||||
// Paper end
|
||||
+ lagging = recentTps[0] < net.pl3x.purpur.PurpurConfig.laggingThreshold; // Purpur
|
||||
tickSection = curTime;
|
||||
}
|
||||
// Tuinity - replace logic
|
||||
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
index 2442309843bb62e08ae13c46d335c65f7d072510..089ae62c2189fe774796ecc6caf9961d3edb5ea3 100644
|
||||
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
|
||||
@@ -150,6 +150,11 @@ public class PurpurConfig {
|
||||
if (!TimingsManager.hiddenConfigs.contains("server-ip")) TimingsManager.hiddenConfigs.add("server-ip");
|
||||
}
|
||||
|
||||
+ public static double laggingThreshold = 19.0D;
|
||||
+ private static void tickLoopSettings() {
|
||||
+ laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold);
|
||||
+ }
|
||||
+
|
||||
public static boolean barrelSixRows = false;
|
||||
public static boolean enderChestSixRows = false;
|
||||
public static boolean enderChestPermissionRows = false;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 3efe2a4eff95349107134b097033bf978f083d56..d46e5819bd0bc6ac16b536ee3abe5a0142995bf3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2560,5 +2560,10 @@ public final class CraftServer implements Server {
|
||||
public String getServerName() {
|
||||
return getProperties().serverName;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isLagging() {
|
||||
+ return getServer().lagging;
|
||||
+ }
|
||||
// Purpur end
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 5 Jul 2019 16:36:55 -0500
|
||||
Subject: [PATCH] ItemFactory#getMonsterEgg
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java b/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java
|
||||
index 4d965e504a40eb52777575df839856c825a0900a..addddb64956c63563fc072b35cc511d31c9afd45 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java
|
||||
@@ -35,7 +35,7 @@ import net.minecraft.world.phys.Vec3D;
|
||||
|
||||
public class ItemMonsterEgg extends Item {
|
||||
|
||||
- private static final Map<EntityTypes<?>, ItemMonsterEgg> a = Maps.newIdentityHashMap();
|
||||
+ public static final Map<EntityTypes<?>, ItemMonsterEgg> a = Maps.newIdentityHashMap(); // Purpur - private -> public
|
||||
private final int b;
|
||||
private final int c;
|
||||
private final EntityTypes<?> d;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index 347c23d4b7d47198f214c3f95354e8abb660b191..4ec0e93d93936080d876ffa017ebe181d2896b22 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -401,4 +401,18 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
new net.md_5.bungee.api.chat.TextComponent(customName));
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public ItemStack getMonsterEgg(org.bukkit.entity.EntityType type) {
|
||||
+ if (type == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ String name = type.getKey().toString();
|
||||
+ net.minecraft.resources.MinecraftKey key = new net.minecraft.resources.MinecraftKey(name);
|
||||
+ net.minecraft.world.entity.EntityTypes types = net.minecraft.world.entity.EntityTypes.getFromKey(key);
|
||||
+ net.minecraft.world.item.ItemMonsterEgg egg = net.minecraft.world.item.ItemMonsterEgg.a.get(types);
|
||||
+ return new net.minecraft.world.item.ItemStack(egg).asBukkitMirror();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Fri, 5 Jul 2019 18:21:00 -0500
|
||||
Subject: [PATCH] PlayerSetSpawnerTypeWithEggEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityTypes.java b/src/main/java/net/minecraft/world/entity/EntityTypes.java
|
||||
index 80c229c1852199fda85c03453d64cae33e413e89..6335e9046a6288f7bcf945ad8c381e080744653d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityTypes.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityTypes.java
|
||||
@@ -274,6 +274,16 @@ public class EntityTypes<T extends Entity> {
|
||||
return (EntityTypes) IRegistry.a((IRegistry) IRegistry.ENTITY_TYPE, s, (Object) entitytypes_builder.a(s));
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ public static EntityTypes getFromBukkitType(org.bukkit.entity.EntityType bukkitType) {
|
||||
+ return getFromKey(new MinecraftKey(bukkitType.getKey().toString()));
|
||||
+ }
|
||||
+
|
||||
+ public static EntityTypes getFromKey(MinecraftKey key) {
|
||||
+ return IRegistry.ENTITY_TYPE.get(key);
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
public static MinecraftKey getName(EntityTypes<?> entitytypes) {
|
||||
return IRegistry.ENTITY_TYPE.getKey(entitytypes);
|
||||
}
|
||||
@@ -439,6 +449,16 @@ public class EntityTypes<T extends Entity> {
|
||||
return this.bg;
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ public String getName() {
|
||||
+ return IRegistry.ENTITY_TYPE.getKey(this).getKey();
|
||||
+ }
|
||||
+
|
||||
+ public String getTranslatedName() {
|
||||
+ return getNameComponent().getString();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
public String getDescriptionId() { return f(); } // Paper - OBFHELPER
|
||||
public String f() {
|
||||
if (this.bo == null) {
|
||||
@@ -448,6 +468,7 @@ public class EntityTypes<T extends Entity> {
|
||||
return this.bo;
|
||||
}
|
||||
|
||||
+ public IChatBaseComponent getNameComponent() { return g(); } // Purpur - OBFHELPER
|
||||
public IChatBaseComponent g() {
|
||||
if (this.bp == null) {
|
||||
this.bp = new ChatMessage(this.f());
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java b/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java
|
||||
index addddb64956c63563fc072b35cc511d31c9afd45..5e2d0246146af8bf1de1038f6a1953451b99f0f5 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemMonsterEgg.java
|
||||
@@ -33,6 +33,13 @@ import net.minecraft.world.phys.MovingObjectPosition;
|
||||
import net.minecraft.world.phys.MovingObjectPositionBlock;
|
||||
import net.minecraft.world.phys.Vec3D;
|
||||
|
||||
+// Purpur start
|
||||
+import net.pl3x.purpur.event.PlayerSetSpawnerTypeWithEggEvent;
|
||||
+import org.bukkit.block.CreatureSpawner;
|
||||
+import org.bukkit.entity.EntityType;
|
||||
+import org.bukkit.entity.Player;
|
||||
+// Purpur end
|
||||
+
|
||||
public class ItemMonsterEgg extends Item {
|
||||
|
||||
public static final Map<EntityTypes<?>, ItemMonsterEgg> a = Maps.newIdentityHashMap(); // Purpur - private -> public
|
||||
@@ -67,6 +74,15 @@ public class ItemMonsterEgg extends Item {
|
||||
MobSpawnerAbstract mobspawnerabstract = ((TileEntityMobSpawner) tileentity).getSpawner();
|
||||
EntityTypes<?> entitytypes = this.a(itemstack.getTag());
|
||||
|
||||
+ // Purpur start
|
||||
+ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ PlayerSetSpawnerTypeWithEggEvent event = new PlayerSetSpawnerTypeWithEggEvent((Player) itemactioncontext.getEntity().getBukkitEntity(), bukkitBlock, (CreatureSpawner) bukkitBlock.getState(), EntityType.fromName(entitytypes.getName()));
|
||||
+ if (!event.callEvent()) {
|
||||
+ return EnumInteractionResult.FAIL;
|
||||
+ }
|
||||
+ entitytypes = EntityTypes.getFromBukkitType(event.getEntityType());
|
||||
+ // Purpur end
|
||||
+
|
||||
mobspawnerabstract.setMobName(entitytypes);
|
||||
tileentity.update();
|
||||
world.notify(blockposition, iblockdata, iblockdata, 3);
|
@ -1,63 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 20 Jul 2013 22:40:56 -0400
|
||||
Subject: [PATCH] EMC - MonsterEggSpawnEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityTypes.java b/src/main/java/net/minecraft/world/entity/EntityTypes.java
|
||||
index 6335e9046a6288f7bcf945ad8c381e080744653d..1bfde4cfc0f27705238abf7852ad9bb7997e23e6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityTypes.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityTypes.java
|
||||
@@ -318,13 +318,20 @@ public class EntityTypes<T extends Entity> {
|
||||
|
||||
@Nullable
|
||||
public Entity spawnCreature(WorldServer worldserver, @Nullable ItemStack itemstack, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1) {
|
||||
- return this.spawnCreature(worldserver, itemstack == null ? null : itemstack.getTag(), itemstack != null && itemstack.hasName() ? itemstack.getName() : null, entityhuman, blockposition, enummobspawn, flag, flag1);
|
||||
+ return this.spawnCreature(worldserver, itemstack, itemstack == null ? null : itemstack.getTag(), itemstack != null && itemstack.hasName() ? itemstack.getName() : null, entityhuman, blockposition, enummobspawn, flag, flag1); // Purpur
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T spawnCreature(WorldServer worldserver, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1) {
|
||||
+ // Purpur start
|
||||
+ return spawnCreature(worldserver, null, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1);
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public T spawnCreature(WorldServer worldserver, @Nullable ItemStack itemstack, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1) {
|
||||
+ // Purpur end
|
||||
// CraftBukkit start
|
||||
- return this.spawnCreature(worldserver, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG);
|
||||
+ return this.spawnCreature(worldserver, itemstack, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG, null); // Purpur
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -349,9 +356,29 @@ public class EntityTypes<T extends Entity> {
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
+ // Purpur start
|
||||
+ return spawnCreature(worldserver, null, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1, spawnReason, op);
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public T spawnCreature(WorldServer worldserver, @Nullable ItemStack itemstack, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason, @Nullable java.util.function.Consumer<T> op) {
|
||||
+ // Purpur end
|
||||
T t0 = this.createCreature(worldserver, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1);
|
||||
if (t0 != null && op != null) op.accept(t0); // Paper
|
||||
|
||||
+ // Purpur start
|
||||
+ if (spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG && itemstack != null && t0 != null) {
|
||||
+ final net.pl3x.purpur.event.entity.MonsterEggSpawnEvent event = new net.pl3x.purpur.event.entity.MonsterEggSpawnEvent(entityhuman != null ? entityhuman.getBukkitEntity() : null, t0.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack));
|
||||
+ if (!event.callEvent()) {
|
||||
+ worldserver.removeEntity(t0);
|
||||
+ return null;
|
||||
+ }
|
||||
+ if (event.getEntity().getEntityId() != t0.getId()) {
|
||||
+ return (T) ((org.bukkit.craftbukkit.entity.CraftEntity) event.getEntity()).getHandle();
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
if (t0 != null) {
|
||||
worldserver.addAllEntities(t0, spawnReason);
|
||||
return !t0.dead ? t0 : null; // Don't return an entity when CreatureSpawnEvent is canceled
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user