Compare commits
311 Commits
Author | SHA1 | Date |
---|---|---|
Joo200 | aa254c80e0 | |
Joo200 | 2f93b26be0 | |
wizjany | 6bbf49314d | |
Madeline Miller | f6a0a0b415 | |
Joo200 | 4ad11151fe | |
Joo200 | c29edf7467 | |
Joo200 | da3c81a88d | |
Joo200 | c65dd83a7e | |
Joo200 | 694195435d | |
Madeline Miller | 0d824d375b | |
aromaa | c7319f10dc | |
Joo200 | c2b95f59a8 | |
Joo200 | 5fa6f2a858 | |
Joo200 | 0a9eb447d6 | |
Joo200 | 02a8fd4c17 | |
wizjany | 3201cee1b7 | |
wizjany | 16a3c85005 | |
Joo200 | 5934e49489 | |
Joo200 | 58fbb6f008 | |
Joo200 | fba8333de3 | |
Joo200 | 8cbce96a2c | |
Madeline Miller | fffb0c1f98 | |
Madeline Miller | 223b80c590 | |
Joo200 | 853631139d | |
Joo200 | c61e9f1fe0 | |
Joo200 | 64ccda4615 | |
Joo200 | 16887c8540 | |
Joo200 | 2c448f1ba2 | |
wizjany | c0cbe27efc | |
Joo200 | bb3fdcc880 | |
JOO200 | 8d5953a550 | |
Joo200 | 4a26e306b6 | |
wizjany | 129ae6c971 | |
wizjany | 44d0735412 | |
wizjany | 33cdb4a6a8 | |
wizjany | feb548aa84 | |
wizjany | 961461c23c | |
wizjany | ad6d5af592 | |
wizjany | 7ae7a04721 | |
wizjany | 40adfe9cef | |
Joo200 | 78498491dd | |
stonar96 | ca636d20af | |
Joo200 | b67fd01ebd | |
Joo200 | bddfbdd353 | |
JOO200 | ece376a69e | |
wizjany | 1e81a91d4d | |
JOO200 | 216f95f87c | |
JOO200 | ca6e228f61 | |
Joo200 | fd1cb1e4bd | |
Joo200 | 8c8a8092b5 | |
Maddy Miller | 1729e5e3d6 | |
Madeline Miller | 46dfb69fb1 | |
Joo200 | 9ceecf5d3a | |
Maddy Miller | 20044a72d3 | |
JOO200 | 8bc7ff49ab | |
Joo200 | 6f749b058b | |
Joo200 | 91380a8316 | |
Joo200 | ba55cc79c2 | |
Joo200 | 62be386626 | |
aromaa | cb100bb797 | |
Joo200 | 741f9e231b | |
Joni Aromaa | bd1d772faa | |
wizjany | f1f1e8aa7d | |
wizjany | 598c441718 | |
wizjany | cbb2ba7216 | |
dordsor21 | e756d127c5 | |
Joo200 | 0d2ed8205f | |
JOO200 | 6efdb1089e | |
wizjany | 4a21bf43e7 | |
JOO200 | 3a181a230f | |
JOO200 | 857f7468d8 | |
JOO200 | f8e8d0f01e | |
JOO200 | 23521858fd | |
JOO200 | 0fddd2a573 | |
JOO200 | 85dd012b85 | |
wizjany | dc23af7947 | |
JOO200 | b698941378 | |
wizjany | 271b32aa1d | |
wizjany | 938f0c3b66 | |
wizjany | bc63119373 | |
wizjany | 3549f04a33 | |
wizjany | 216b061172 | |
wizjany | 27dca2b506 | |
wizjany | 79a3b70d8d | |
wizjany | cf69425153 | |
wizjany | e2fe770e6f | |
wizjany | 7e06088c1a | |
wizjany | f9d1c2d4e0 | |
wizjany | f883899cfe | |
wizjany | de386fb4d8 | |
wizjany | 660f9ffa0d | |
wizjany | e05d42371f | |
JOO200 | dca0515104 | |
wizjany | 4abf971cf6 | |
wizjany | 875a6fc827 | |
JOO200 | 3cb4abdbf7 | |
JOO200 | 4caf0afb38 | |
JOO200 | 054a73416b | |
Cristobal Lopez | b59da5992f | |
wizjany | 46251f5ffa | |
wizjany | 98bef4e0ab | |
JOO200 | f1c8649f9a | |
JOO200 | aad698af84 | |
JOO200 | ad7ecbaefe | |
wizjany | 81750e191d | |
wizjany | 703146bc18 | |
JOO200 | 2541483ebc | |
JOO200 | 0a601dbc28 | |
stonar96 | f55802c176 | |
wizjany | a0922cb467 | |
wizjany | fb9705e4f0 | |
JOO200 | 9b665136d0 | |
wizjany | efac79fd38 | |
wizjany | 1cff55f355 | |
wizjany | f4fb78c7f5 | |
wizjany | 56086b0878 | |
wizjany | 51fa25dd03 | |
wizjany | 5b0fdb6801 | |
stonar96 | cb69ab73a7 | |
stonar96 | 5a6b6eb81b | |
stonar96 | 75774dbbb0 | |
wizjany | fe0fd17d37 | |
stonar96 | 5e702f80a6 | |
Wyatt Childers | 0165175a2e | |
wizjany | 821c3e689e | |
stonar96 | 4644268214 | |
wizjany | c81f5892eb | |
LoaiDev | 88854592ce | |
wizjany | 8efc2e6539 | |
stonar96 | b1cd1303d1 | |
wizjany | c98f9eda7e | |
JOO200 | 682942b965 | |
JOO200 | 7e817c3330 | |
wizjany | 5302bcb132 | |
stonar96 | bcac63dcaa | |
JOO200 | 37906c0fc4 | |
wizjany | 6879f10de6 | |
JOO200 | 7155ef5833 | |
JOO200 | e2f775c952 | |
JOO200 | c5dad7476d | |
JOO200 | 4dfb9bea38 | |
JOO200 | 7436d5064e | |
JOO200 | 621c1289b3 | |
JOO200 | 093e282e13 | |
JOO200 | 2958c2526c | |
wizjany | d21ee98624 | |
wizjany | dd90fa21c7 | |
JOO200 | 34ed6175e5 | |
JOO200 | 0818b3c262 | |
JOO200 | 04541ed5a6 | |
JOO200 | f17f1fc8c8 | |
JOO200 | 9defab65d1 | |
JOO200 | a225d1b2d3 | |
JOO200 | bcab33c12c | |
JOO200 | 3cb83465d1 | |
wizjany | 32d16a7eaa | |
wizjany | 3827266eb3 | |
wizjany | c3dbfdd699 | |
wizjany | f19ebab0e1 | |
stonar96 | f8f95a44f0 | |
stonar96 | 0a74d02fc9 | |
stonar96 | 46a662e1a7 | |
stonar96 | 149d1f84e8 | |
stonar96 | c4e76af5f4 | |
stonar96 | c1c26360e3 | |
stonar96 | 65c894cfe9 | |
TheBusyBiscuit | 7dcec2b3b4 | |
stonar96 | 09ce3b6373 | |
wizjany | de22a5cd25 | |
JOO200 | d2c2bfbab2 | |
wizjany | 528ba32a93 | |
JOO200 | f37fbb1ae8 | |
wizjany | f1f8b625a8 | |
wizjany | e933050436 | |
wizjany | 59d4c7b96d | |
Shane Freeder | 0c7f4bb8f7 | |
wizjany | 3c9b21d01f | |
wizjany | aeea455560 | |
wizjany | 129d27351a | |
wizjany | 310ce9a662 | |
kikelkik | e04c654cde | |
JOO200 | b1674e5cb7 | |
JOO200 | 89c6a33b90 | |
JOO200 | 88c91ce3fc | |
JOO200 | b70f5a73ce | |
JOO200 | b6fc9ddd93 | |
wizjany | cbb3212082 | |
Intelli | 04d5a3b437 | |
Matthew Miller | 282425f3cf | |
wizjany | 15a08097ae | |
wizjany | 035a645de0 | |
wizjany | 59c146f59a | |
wizjany | d313f2caad | |
wizjany | 8350267b10 | |
JOO200 | e98196af40 | |
wizjany | 3879772103 | |
wizjany | 48233c3327 | |
wizjany | 664ab18f00 | |
Matthew Miller | 07bf1871ab | |
JOO200 | 5921be432c | |
wizjany | 60b16fc4c7 | |
wizjany | 746b630d01 | |
wizjany | 0b362088f4 | |
wizjany | 014277fb2f | |
wizjany | f7ff984c34 | |
Pisich | d4b2060766 | |
JOO200 | 0e73b50d6f | |
JOO200 | 136ec31f38 | |
JOO200 | ad000ab051 | |
JOO200 | af67f1dd6a | |
wizjany | 8dee2ad3b8 | |
wizjany | c860fce299 | |
wizjany | 0cb84927a3 | |
wizjany | 2ed60eba02 | |
wizjany | 91a1494634 | |
Matthew Miller | 5b8c3e7f70 | |
Matthew Miller | c1ff4fc3d3 | |
JOO200 | 691325c8f0 | |
JOO200 | 3da19a7ff0 | |
wizjany | f677af566f | |
wizjany | 58eaf31879 | |
wizjany | 6708b21016 | |
wizjany | ed4287ace7 | |
wizjany | 03f05d3a4e | |
JOO200 | c8bde17994 | |
JOO200 | 449145ba1f | |
JOO200 | 85c5f53d29 | |
JOO200 | 5162ce3dbd | |
wizjany | efe1e48bd4 | |
wizjany | 1710c07623 | |
JOO200 | 6f9ed5d10f | |
JOO200 | f0ec54af49 | |
JOO200 | e9e1885f2e | |
wizjany | f8e2d8d6b7 | |
wizjany | 2c0b592b19 | |
wizjany | 46e230e625 | |
wizjany | fe24668c6a | |
wizjany | 23efd5fec2 | |
JOO200 | e54235a65e | |
JOO200 | 5ec3ed6092 | |
TheMolkaPL | 1652c9bfc0 | |
TheMolkaPL | a97db0ede9 | |
wizjany | 36e42eefd0 | |
wizjany | 5b8eef92b8 | |
wizjany | d73dc6d719 | |
wizjany | 74d8a4f0e7 | |
JOO200 | 613406aab4 | |
wizjany | 66fd84ba2f | |
wizjany | 53abb6c4ad | |
wizjany | 923369e28c | |
wizjany | bc551da903 | |
wizjany | bffe5e76f2 | |
JOO200 | 8722322cd8 | |
JOO200 | 0fa92d4836 | |
JOO200 | e52875bd0b | |
JOO200 | dbad328d0d | |
wizjany | 5407315799 | |
wizjany | b769469f5b | |
wizjany | 3a9b1b1525 | |
wizjany | ff5f933879 | |
wizjany | 0492fafe30 | |
wizjany | 36d95ad090 | |
wizjany | c1ec708050 | |
wizjany | f4a3e8a936 | |
wizjany | 6c5380ba0b | |
wizjany | 868089b44f | |
wizjany | 9905d22ddf | |
UltraFaceguy | 4eaa376e2c | |
JOO200 | 37ae70f35d | |
wizjany | 1a69250d9b | |
wizjany | b2d2d0815b | |
wizjany | 47cd96a3af | |
wizjany | 0a735e0146 | |
stonar96 | 60590acfe3 | |
stonar96 | 6030bea13e | |
stonar96 | 20f89ea2ae | |
wizjany | 4c351fb0e3 | |
wizjany | 5e7829c3fe | |
wizjany | 37e66dae7d | |
wizjany | 662ae2bc84 | |
wizjany | fa60582afe | |
wizjany | 17c1647163 | |
wizjany | 1fcda13469 | |
wizjany | 570b7f7b77 | |
wizjany | aca0d843f6 | |
wizjany | 1172ebd419 | |
wizjany | a09ccc5b45 | |
wizjany | e6bdf8abb5 | |
wizjany | df2ae6a666 | |
wizjany | e4481f9337 | |
wizjany | 2169aa218e | |
wizjany | 523e45188d | |
wizjany | d95c6af1be | |
wizjany | 0d860bfca7 | |
wizjany | 6f6125fe00 | |
wizjany | 0332929531 | |
Wyatt Childers | 637665f52d | |
wizjany | db3838ccfe | |
wizjany | 789405d116 | |
wizjany | d37f015f0c | |
wizjany | 239eda3f96 | |
wizjany | 0715cbe216 | |
wizjany | 738b24bfc1 | |
wizjany | b835ee39d5 | |
Pieter12345 | 4a7552e6be | |
Joo200 | c6c0fc9d74 | |
wizjany | f43a4eaad8 | |
JOO200 | abfa5cb6a5 | |
JOO200 | 05f7d68705 | |
wizjany | 9adac4f239 | |
wizjany | c5355adb4b |
|
@ -1,2 +1,34 @@
|
|||
*.java diff=java
|
||||
* text=auto eol=lf
|
||||
# Force Batch files to CRLF
|
||||
*.bat eol=crlf -text
|
||||
|
||||
# Java sources
|
||||
*.java text diff=java
|
||||
*.kt text diff=java
|
||||
*.gradle text diff=java
|
||||
*.gradle.kts text diff=java
|
||||
|
||||
# These files are text and should be normalized (Convert crlf => lf)
|
||||
*.css text diff=css
|
||||
*.df text
|
||||
*.htm text diff=html
|
||||
*.html text diff=html
|
||||
*.js text
|
||||
*.jsp text
|
||||
*.jspf text
|
||||
*.jspx text
|
||||
*.properties text
|
||||
*.tld text
|
||||
*.tag text
|
||||
*.tagx text
|
||||
*.xml text
|
||||
|
||||
# These files are binary and should be left untouched
|
||||
# (binary is a macro for -text -diff)
|
||||
*.class binary
|
||||
*.dll binary
|
||||
*.ear binary
|
||||
*.jar binary
|
||||
*.so binary
|
||||
*.war binary
|
||||
*.jks binary
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
github: enginehub
|
|
@ -0,0 +1,93 @@
|
|||
name: Bug report
|
||||
description: Report a way in which WorldGuard is not working as intended
|
||||
labels: ['type:bug', 'status:pending']
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please note that this is only for bugs, help with installation or other types of support should
|
||||
be taken to the Discord Guild instead.
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: WorldEdit Version
|
||||
description: The full version of WorldEdit, can be found by using `/we version`.
|
||||
placeholder: e.g. 7.2.3 or 7.3.0-SNAPSHOT
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: WorldGuard Version
|
||||
description: The full version of WorldGuard, can be found by using `/wg version`.
|
||||
placeholder: e.g. 7.0.5 or 7.0.6-SNAPSHOT
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Platform Version
|
||||
description: |
|
||||
The version of the platform you are on, i.e. Spigot or Paper.
|
||||
Please ensure you are running up-to-date software before making a bug report.
|
||||
Old versions, paper forks or hybrids will receive little to no support.
|
||||
placeholder: e.g. git-Spigot-21fe707-e1ebe52, git-Paper-463
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: confirmations
|
||||
attributes:
|
||||
label: Confirmations
|
||||
description: Please confirm the following before submitting the bug. Your report will be closed if you are running hybrids or old software.
|
||||
options:
|
||||
- label: I am using the most recent Minecraft release.
|
||||
required: true
|
||||
- label: I am using a version of WorldEdit compatible with my Minecraft version.
|
||||
required: true
|
||||
- label: I am using a version of WorldGuard compatible with my Minecraft version.
|
||||
required: true
|
||||
- label: I am using the latest or recommended version of my platform software.
|
||||
required: true
|
||||
- label: I am NOT using a hybrid server, e.g. a server that combines Bukkit and Forge. Examples include Arclight, Mohist, and Cardboard.
|
||||
required: true
|
||||
- label: I am NOT using a fork of WorldEdit, such as FastAsyncWorldEdit (FAWE) or AsyncWorldEdit (AWE)
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Bug Description
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: The behavior that you expected, instead of the bugged behavior that occurs.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: Steps to reproduce the behavior.
|
||||
value: |
|
||||
1. ...
|
||||
2. ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Optional WorldGuard-Report
|
||||
description: Link to WorldGuard Region report for bugs with regions, received with `/wg report -p`
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything Else?
|
||||
description: Add any additional context you can provide below.
|
|
@ -0,0 +1,5 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: EngineHub Discord
|
||||
url: https://discord.gg/EngineHub
|
||||
about: Please ask and answer questions here.
|
|
@ -0,0 +1,35 @@
|
|||
name: Feature request
|
||||
description: Suggest an idea for WorldGuard
|
||||
labels: ['type:feature-request', 'status:pending']
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: The Problem
|
||||
description: >
|
||||
What is making your WorldGuard experience sub-optimal? This should be something that
|
||||
cannot be easily solved by existing WorldGuard features.
|
||||
placeholder: It's hard to ... ; I'm unable to ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: A Solution
|
||||
description: What is your proposed solution to the above problem?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Alternatives
|
||||
description: |
|
||||
Alternative solutions or workarounds to the problem.
|
||||
You should also describe why these are not preferable to the given solution.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything Else?
|
||||
description: Add any additional context you can provide below.
|
|
@ -15,3 +15,5 @@ dependency-reduced-pom.xml
|
|||
.gradle/
|
||||
**/build/
|
||||
out/
|
||||
|
||||
scripts/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
language: java
|
||||
dist: trusty
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk11
|
||||
notifications:
|
||||
email: false
|
||||
before_install: chmod +x gradlew
|
||||
|
|
125
CHANGELOG.md
125
CHANGELOG.md
|
@ -1,5 +1,130 @@
|
|||
# Changelog
|
||||
|
||||
## 7.0.10
|
||||
|
||||
* Add support for MC 1.20.5 and 1.20.6, drop support for other 1.20 versions
|
||||
|
||||
## 7.0.9
|
||||
* Add support for MC 1.20, drop support for MC 1.19
|
||||
* Made entities spawned via the `/summon` command get treated as plugin-spawned entities
|
||||
* Add sniffer egg trample protection options
|
||||
|
||||
## 7.0.8
|
||||
* Add support for MC 1.19
|
||||
* Add skulk-growth flag and config option
|
||||
* Add copper-fade flag
|
||||
* Add data packs to report output
|
||||
* Add protection for allay inventory slot
|
||||
* Categorize allay item pickups under item-pickup flag
|
||||
* Categorize dragon egg interaction (teleporting) as building
|
||||
* Ignore most NPC-based actions for Player events
|
||||
* Optimize handling of tamed animals where the owner was offline (Paper only)
|
||||
* Optimize additional InventoryHolder accesses (Paper only)
|
||||
* Fix an exception that occurred when plugins created portals with non-player entities
|
||||
* Fix possible error when using Paper's entity origin API
|
||||
* Update bstats and squirrelid libs
|
||||
|
||||
## 7.0.7
|
||||
* Add rock-growth flag for budding amethyst and pointed dripstone.
|
||||
* Add /rg migrateheights command. See https://worldguard.enginehub.org/en/latest/regions/commands/#migrate-region-heights
|
||||
* Add regions.set-parent-on-claim config (set to a region id for /rg claim to automatically assign the parent region).
|
||||
* Add `-i search` and `-s` flags to /rg list, -c to /rg teleport.
|
||||
* Fix an error in blacklist logging caused by non-player actions (eg on-dispense)
|
||||
* Treat unknown causes as known if using paper-entity-origin config option.
|
||||
* Improve lightning strike handling from channeling tridents (PaperMC only).
|
||||
* Ignore an error caused by lingering player references of offline players.
|
||||
* Add red sand to no-physics-sand.
|
||||
* Fix potion splash events being cancelled if no entities were affected.
|
||||
|
||||
## 7.0.6
|
||||
|
||||
* Add support for 1.17 blocks/items, drop support for 1.16.
|
||||
* Add use-dripleaf flag for "toggling" big dripleaf blocks.
|
||||
* Fix support for fully negative-height regions.
|
||||
* Fix crop-growth config option.
|
||||
* Be more rigorous with protecting blocks against dispenser behaviors.
|
||||
* Fix handling of lingering splash potion effects.
|
||||
* Handle other-explosion flag consistently for block-like entities (armor frames etc.)
|
||||
* Allow inheriting values for all flags (previously wasn't used for things like teleport.)
|
||||
* Region commands that defaulted to the region the player was standing in no longer check parents.
|
||||
* Fix child regions being unlinked when redefining a parent region.
|
||||
|
||||
## 7.0.5
|
||||
|
||||
* Add a use-anvil flag and exclude it from the use flag (since they can break on use.)
|
||||
* Add nonplayer-protection-domains flag which allows merging region borders from the perspective of pistons, saplings, etc.
|
||||
* Expand crop-related options (crop-growth, etc) to sweet berry bushes, nether wart, and bamboo.
|
||||
* Add a config option (`mobs.block-vehicle-entry`) to prevent non-players from entering vehicles.
|
||||
* Add a UUID flag (for developers/API usage).
|
||||
* Add map query methods with fallback flag (for developers/API usage).
|
||||
* Add `on` and `off` optional arguments for `/rg toggle-bypass` command.
|
||||
* Add additional timings info for session handlers.
|
||||
* Fix sponge-simulation clearing NBT from blocks. Note that if you are using sponge simulation you should switch to something like CraftBook as the feature will be removed from WorldGuard in a future (major) version.
|
||||
* Fix the `/rg` command showing up as unknown client-side to players without bypass perms.
|
||||
* Fix error propagation from third-party flag loading causing WG to error.
|
||||
* Fix a (harmless) exception that occurred when swapping armor slots to the offhand slot.
|
||||
* Fix empty lines being sent on enderpearl/chorus-fruit teleport if the deny messages were empty.
|
||||
* Fix an issue with falling blocks when using max-priority-association.
|
||||
* Fix performance issues with third-party plugins querying protection for offline players.
|
||||
* Fix dispensing shulkers over region boundaries.
|
||||
* Fix iron door interaction being denied as if it were a regular door.
|
||||
* Fix being able to enter/exit regions with the flag denied by using entity mounting functions in other plugins.
|
||||
|
||||
## 7.0.4 (including beta1)
|
||||
|
||||
* Add support for MC 1.16. Dropped support for previous versions.
|
||||
* Add respawn-anchors flag mirroring the sleep flag (e.g. to prevent using respawn anchors to cause explosions in the overworld)
|
||||
* Add nether vines to vine-growth flag.
|
||||
* Add config option to disable the bypass permission cache.
|
||||
* Fix water-flow flags not checking waterlogged blocks.
|
||||
* Add config option to consider non-player causes (e.g. pistons, flowing water) to only be members of the highest priority region. This should be enabled for plots-within-city-like setups to prevent things in plots from modifying the city.
|
||||
* Fix items dropping from falling blocks that were suppressed by other plugins.
|
||||
* Add config option to block turtle egg trampling.
|
||||
* Fix ride flag being checked on striders that didn't have saddles.
|
||||
* Add config option to have /rg bypass toggled off on login.
|
||||
* Developer changes: Methods taking names in Domains are now explicitly deprecated (was previously just a javadoc comment.); These will eventually be removed: there is no reason to use names over UUIDs. Offline players and NPCs alike have stable UUIDs.
|
||||
* Also for developers; The new `com.sk89q.worldguard.protection.util.WorldEditRegionConverter` class has some useful static methods to convert to and from WorldEdit's Region and WorldGuard's ProtectedRegion classes.
|
||||
|
||||
|
||||
## 7.0.3
|
||||
|
||||
* This is the last release supporting MC 1.14 and 1.15.
|
||||
* Decouple chest-access flag from interact flag. IMPORTANT: If you relied on allowing players to access chests via setting
|
||||
the interact flag to allow, you will now need to set the chest-access flag to allow instead (or as well). This does not
|
||||
affect any setups where users were *not* supposed to be able to access chests and other inventories.
|
||||
* Add natural-health-regen and natural-hunger-drain flags. Unlike the heal/feed flags, these can not restore or deplete health/hunger.
|
||||
* Fix the interact flag allowing breaking of turtle eggs (now tied directly to block-trampling flag).
|
||||
* Fix a memory leak that could occur with many many explosives.
|
||||
* Add regions.titles-always-use-default-times config option. Set this to true if you use greeting/farewell titles and another plugin
|
||||
makes the titles disappear too quickly.
|
||||
* Add protection for cauldrons water level changing.
|
||||
* Improve diagnostic hints and information, such as spawn protection warnings, flag colors in region info, etc.
|
||||
* Fix waterlogged blocks bypassing water-flow flag.
|
||||
* Workaround for a CraftBukkit change that made no-physics-sand/gravel non-functional.
|
||||
* Workaround for CraftBukkit throttling move events.
|
||||
* Track projectiles shot by dispensers.
|
||||
* Allowed setting passthrough allow on global to unprotect it if members/owners are added.
|
||||
* Add support for newer forge clients (FML2) in host keys.
|
||||
* Allow using WorldEdit's `//world <worldname>` command to select a world for region commands. This removes the need to
|
||||
use `-w <worldname>` in every command when running commands from console.
|
||||
* Add a teleport-message flag, shown when using `/rg tp`.
|
||||
* Add coral-fade flag, which prevents corals from drying when out of water.
|
||||
* Fix spammy deny-message when walking over redstone ore with certain flag setups.
|
||||
* Improve handling of interacting with various tools in hand that didn't modify blocks. (eg opening a chest with an axe in hand)
|
||||
* Fix allow-all-interact option not being read from per-world configs.
|
||||
* Fix misattribution of pets (eg wolves) in PvP.
|
||||
* Improve performance of hopper checks when on recent builds of Paper.
|
||||
* Add event-handling.break-hoppers-on-denied-move config option to prevent hoppers from being broken (but items still won't be moved).
|
||||
* Note to developers using the WorldGuard API: If you specifically relied on flags such as greeting/farewell, deny-message, etc being
|
||||
StringFlags, be warned that this will change in a future version to support JSON text components. Please plan accordingly.
|
||||
|
||||
|
||||
## 7.0.2
|
||||
* Update to MC 1.15. Still compatible with 1.14, and incompatible with 1.13, as before.
|
||||
* Add an informational message when defining a region that overlaps vanilla spawn protection.
|
||||
* Protect against pushing a piston with another piston on a region border.
|
||||
* Protect against buckets in dispensers on region borders.
|
||||
|
||||
## 7.0.1
|
||||
* Add `/rg toggle-bypass` command which temporarily turns off region bypassing until used again.
|
||||
* More improvements to `/rg flag` and `/rg flags` commands.
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
Compiling
|
||||
=========
|
||||
|
||||
You can compile WorldGuard as long as you have some version of Java greater than or equal to 21 installed.
|
||||
Gradle will download JDK 21 specifically if needed, but it needs some version of Java to bootstrap from.
|
||||
|
||||
The build process uses Gradle, which you do *not* need to download. WorldGuard is a multi-module project with three modules:
|
||||
|
||||
* `worldguard-core` contains the WorldGuard API
|
||||
* `worldguard-bukkit` is the Bukkit plugin
|
||||
* `worldguard-libs` contains library relocations
|
||||
|
||||
## To compile...
|
||||
|
||||
### On Windows
|
||||
|
||||
1. **Shift** + **right click** the folder with WorldGuard's files and click "Open PowerShell window here".
|
||||
2. `gradlew build`
|
||||
|
||||
### On Linux, BSD, or Mac OS X
|
||||
|
||||
1. In your terminal, navigate to the folder with WorldGuard's files (`cd /folder/of/worldguard/files`)
|
||||
2. `./gradlew build`
|
||||
|
||||
## Then you will find...
|
||||
|
||||
You will find:
|
||||
|
||||
* The core WorldGuard API in **worldguard-core/build/libs**
|
||||
* WorldGuard for Bukkit in **worldguard-bukkit/build/libs**
|
||||
|
||||
If you want to use WorldGuard, use the `-dist` version.
|
||||
|
||||
(The -dist version includes WorldGuard + necessary libraries.)
|
||||
|
||||
## Other commands
|
||||
|
||||
* `gradlew idea` will generate an [IntelliJ IDEA](http://www.jetbrains.com/idea/) module for each folder.
|
||||
* `gradlew eclipse` will generate an [Eclipse](https://www.eclipse.org/downloads/) project for each folder.
|
|
@ -7,9 +7,7 @@ ask that you make note of the following guidelines.
|
|||
* **Follow the [Oracle coding conventions](https://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).**
|
||||
We can't stress this enough; if your code has notable issues, it may delay
|
||||
the process significantly.
|
||||
* **Target Java 6 for source and compilation.** Make sure to mark methods with
|
||||
` @Override` that override methods of parent classes, or that implement
|
||||
methods of interfaces (Java 6+).
|
||||
* **Target Java 16 for source and compilation.**
|
||||
* **Use only spaces for indentation.** Our indents are 4-spaces long, and tabs
|
||||
are unacceptable.
|
||||
* **Wrap code to a 89 column limit.** We do this to make side by side diffs
|
||||
|
|
35
README.md
35
README.md
|
@ -1,27 +1,29 @@
|
|||
# ![WorldGuard](worldguard-logo.png)
|
||||
<h1>
|
||||
<img src="worldguard-logo.svg" alt="WorldGuard" width="400" />
|
||||
</h1>
|
||||
|
||||
WorldGuard lets you and players guard areas of land against griefers and undesirables, as well as tweak and disable various gameplay features of Minecraft.
|
||||
|
||||
* Block creeper and wither block damage, falling damage, etc.;
|
||||
* Disable fire spread, lava fire spread, ice formation, Endermen picking up blocks, etc.;
|
||||
* Blacklist certain items and blocks so they can't be used;
|
||||
* Warn moderators when certain items and blocks are used;
|
||||
* Protect areas of your world so only certain people can build in them;
|
||||
* Set areas where PVP, TNT, mob damage, and other features are disabled;
|
||||
* Protect your server from various 'exploits' like magical obsidian creation machines;
|
||||
* Disable, or enable, various Minecraft features, like sponges from classic;
|
||||
* Add useful commands like an immediate "STOP ALL FIRE SPREAD" command.
|
||||
* Enable only features you want! Everything is off by default.
|
||||
* Block creeper and wither block damage, falling damage, etc.
|
||||
* Disable fire spread, lava fire spread, ice formation, Endermen picking up blocks, etc.
|
||||
* Blacklist certain items and blocks so they can't be used
|
||||
* Warn moderators when certain items and blocks are used
|
||||
* Protect areas of your world so only certain people can build in them
|
||||
* Set areas where PVP, TNT, mob damage, and other features are disabled
|
||||
* Protect your server from various 'exploits' like magical obsidian creation machines
|
||||
* Disable, or enable, various Minecraft features, like sponges from classic
|
||||
* Add useful commands like an immediate "STOP ALL FIRE SPREAD" command
|
||||
* Enable only features you want! Everything is off by default
|
||||
|
||||
WorldGuard is open source and is available under the GNU Lesser
|
||||
General Public License v3.
|
||||
|
||||
Currently, Bukkit is required to use WorldGuard. You can get a release copy of WorldGuard from the [BukkitDev site](http://dev.bukkit.org/bukkit-plugins/worldguard/).
|
||||
A Bukkit server implementation (such as [Paper](https://papermc.io)) and the [WorldEdit plugin](https://dev.bukkit.org/projects/worldedit) are required to use WorldGuard. You can get a release copy of WorldGuard from the [BukkitDev site](https://dev.bukkit.org/projects/worldguard).
|
||||
|
||||
Compiling
|
||||
---------
|
||||
|
||||
The project is written for Java 8 and our build process makes use of
|
||||
The project is written for Java 17 and our build process makes use of
|
||||
[Gradle](http://gradle.org).
|
||||
|
||||
Dependencies are automatically handled by Gradle.
|
||||
|
@ -38,9 +40,8 @@ Submissions must be licensed under the GNU Lesser General Public License v3.
|
|||
Links
|
||||
-----
|
||||
|
||||
* [Homepage](http://enginehub.org/worldguard)
|
||||
* [Homepage](https://enginehub.org/worldguard)
|
||||
* [Discord](https://discord.gg/enginehub)
|
||||
* [IRC channel](https://webchat.esper.net/?join=sk89q) (#sk89q on irc.esper.net)
|
||||
* [Issue tracker](https://dev.enginehub.org/issues/WORLDGUARD)
|
||||
* [Continuous integration](http://builds.enginehub.org) [![Build Status](https://ci.enginehub.org/app/rest/builds/buildType:bt11,branch:master/statusIcon.svg)](http://ci.enginehub.org/viewType.html?buildTypeId=bt11&guest=1)
|
||||
* [Issue tracker](https://github.com/EngineHub/WorldGuard/issues)
|
||||
* [Continuous integration](https://builds.enginehub.org) [![Build Status](https://ci.enginehub.org/app/rest/builds/buildType:bt11,branch:master/statusIcon.svg)](http://ci.enginehub.org/viewType.html?buildTypeId=bt11&guest=1)
|
||||
* [End-user documentation](https://worldguard.enginehub.org/en/latest/)
|
||||
|
|
|
@ -17,10 +17,10 @@ applyRootArtifactoryConfig()
|
|||
if (!project.hasProperty("gitCommitHash")) {
|
||||
apply(plugin = "org.ajoberstar.grgit")
|
||||
ext["gitCommitHash"] = try {
|
||||
(ext["grgit"] as Grgit?)?.head()?.abbreviatedId
|
||||
Grgit.open(mapOf("currentDir" to project.rootDir))?.head()?.abbreviatedId
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Error getting commit hash", e)
|
||||
|
||||
"no_git_id"
|
||||
"no.git.id"
|
||||
}
|
||||
}
|
|
@ -4,16 +4,26 @@ plugins {
|
|||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(gradleApi())
|
||||
implementation("gradle.plugin.net.minecrell:licenser:0.4.1")
|
||||
implementation("org.ajoberstar.grgit:grgit-gradle:3.1.1")
|
||||
implementation("com.github.jengelman.gradle.plugins:shadow:5.1.0")
|
||||
implementation("net.ltgt.apt-eclipse:net.ltgt.apt-eclipse.gradle.plugin:0.21")
|
||||
implementation("net.ltgt.apt-idea:net.ltgt.apt-idea.gradle.plugin:0.21")
|
||||
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.7")
|
||||
}
|
||||
implementation("gradle.plugin.org.cadixdev.gradle:licenser:0.6.1")
|
||||
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2")
|
||||
implementation("com.github.johnrengelman:shadow:8.1.1")
|
||||
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:5.2.0")
|
||||
constraints {
|
||||
val asmVersion = "[9.7,)"
|
||||
implementation("org.ow2.asm:asm:$asmVersion") {
|
||||
because("Need Java 21 support in shadow")
|
||||
}
|
||||
implementation("org.ow2.asm:asm-commons:$asmVersion") {
|
||||
because("Need Java 21 support in shadow")
|
||||
}
|
||||
implementation("org.vafer:jdependency:[2.10,)") {
|
||||
because("Need Java 21 support in shadow")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ fun Project.applyRootArtifactoryConfig() {
|
|||
}
|
||||
|
||||
fun Project.applyCommonArtifactoryConfig() {
|
||||
val named = tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
publishConfigs("archives")
|
||||
tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
publications("maven")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import org.cadixdev.gradle.licenser.LicenseExtension
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.repositories
|
||||
import org.gradle.kotlin.dsl.the
|
||||
|
||||
fun Project.applyCommonConfiguration() {
|
||||
group = rootProject.group
|
||||
|
@ -7,12 +13,26 @@ fun Project.applyCommonConfiguration() {
|
|||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("https://maven.sk89q.com/repo/") }
|
||||
maven { url = uri("https://maven.enginehub.org/repo/") }
|
||||
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") }
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
cacheChangingModulesFor(5, "minutes")
|
||||
cacheChangingModulesFor(5, "MINUTES")
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withId("java") {
|
||||
the<JavaPluginExtension>().toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
apply(plugin = "org.cadixdev.licenser")
|
||||
configure<LicenseExtension> {
|
||||
header(rootProject.file("HEADER.txt"))
|
||||
include("**/*.java")
|
||||
include("**/*.kt")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.plugins.quality.CheckstyleExtension
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.external.javadoc.StandardJavadocDocletOptions
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
|
||||
fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, javaRelease: Int = 8, banSlf4j: Boolean = true) {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "eclipse")
|
||||
apply(plugin = "idea")
|
||||
apply(plugin = "checkstyle")
|
||||
|
||||
tasks
|
||||
.withType<JavaCompile>()
|
||||
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
|
||||
.configureEach {
|
||||
val disabledLint = listOf(
|
||||
"processing", "path", "fallthrough", "serial"
|
||||
)
|
||||
options.release.set(javaRelease)
|
||||
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
||||
options.isDeprecation = true
|
||||
options.encoding = "UTF-8"
|
||||
options.compilerArgs.add("-parameters")
|
||||
}
|
||||
|
||||
configure<CheckstyleExtension> {
|
||||
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
|
||||
toolVersion = "9.1"
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"compileOnly"("com.google.code.findbugs:jsr305:${Versions.FINDBUGS}")
|
||||
"testImplementation"("org.junit.jupiter:junit-jupiter-api:${Versions.JUNIT}")
|
||||
"testImplementation"("org.junit.jupiter:junit-jupiter-params:${Versions.JUNIT}")
|
||||
"testImplementation"("org.mockito:mockito-core:${Versions.MOCKITO}")
|
||||
"testImplementation"("org.mockito:mockito-junit-jupiter:${Versions.MOCKITO}")
|
||||
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:${Versions.JUNIT}")
|
||||
}
|
||||
|
||||
// Java 8 turns on doclint which we fail
|
||||
tasks.withType<Javadoc>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
(options as StandardJavadocDocletOptions).apply {
|
||||
addStringOption("Xdoclint:none", "-quiet")
|
||||
tags(
|
||||
"apiNote:a:API Note:",
|
||||
"implSpec:a:Implementation Requirements:",
|
||||
"implNote:a:Implementation Note:"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
disableAutoTargetJvm()
|
||||
withJavadocJar()
|
||||
if (sourcesJar) {
|
||||
withSourcesJar()
|
||||
}
|
||||
}
|
||||
|
||||
if (banSlf4j) {
|
||||
configurations["compileClasspath"].apply {
|
||||
resolutionStrategy.componentSelection {
|
||||
withModule("org.slf4j:slf4j-api") {
|
||||
reject("No SLF4J allowed on compile classpath")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("check").configure {
|
||||
dependsOn("checkstyleMain", "checkstyleTest")
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.tasks.SourceSetContainer
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.kotlin.dsl.the
|
||||
|
@ -9,4 +9,4 @@ val Project.ext: ExtraPropertiesExtension
|
|||
get() = extensions.getByType()
|
||||
|
||||
val Project.sourceSets: SourceSetContainer
|
||||
get() = the<JavaPluginConvention>().sourceSets
|
||||
get() = the<JavaPluginExtension>().sourceSets
|
||||
|
|
|
@ -1,70 +1,88 @@
|
|||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.internal.HasConvention
|
||||
import org.gradle.api.plugins.MavenRepositoryHandlerConvention
|
||||
import org.gradle.api.tasks.Upload
|
||||
import org.gradle.api.attributes.Bundling
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.DocsType
|
||||
import org.gradle.api.attributes.LibraryElements
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.attributes.java.TargetJvmVersion
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.component.SoftwareComponentFactory
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getPlugin
|
||||
import org.gradle.kotlin.dsl.invoke
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import javax.inject.Inject
|
||||
|
||||
fun Project.applyLibrariesConfiguration() {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java-base")
|
||||
apply(plugin = "maven")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
|
||||
configurations {
|
||||
create("shade")
|
||||
getByName("archives").extendsFrom(getByName("default"))
|
||||
}
|
||||
|
||||
group = "${rootProject.group}.worldguard-libs"
|
||||
|
||||
val relocations = mapOf(
|
||||
"org.enginehub.squirrelid" to "com.sk89q.worldguard.util.profile"
|
||||
)
|
||||
|
||||
tasks.register<ShadowJar>("jar") {
|
||||
configurations = listOf(project.configurations["shade"])
|
||||
archiveClassifier.set("")
|
||||
|
||||
dependencies {
|
||||
exclude(dependency("com.google.code.findbugs:jsr305:1.3.9"))
|
||||
exclude(dependency("com.google.code.findbugs:jsr305"))
|
||||
}
|
||||
|
||||
relocate("com.sk89q.squirrelid", "com.sk89q.worldguard.util.profile")
|
||||
relocations.forEach { (from, to) ->
|
||||
relocate(from, to)
|
||||
}
|
||||
}
|
||||
val altConfigFiles = { artifactType: String ->
|
||||
val deps = configurations["shade"].incoming.dependencies
|
||||
.filterIsInstance<ModuleDependency>()
|
||||
.map { it.copy() }
|
||||
.map { dependency ->
|
||||
dependency.artifact {
|
||||
name = dependency.name
|
||||
type = artifactType
|
||||
extension = "jar"
|
||||
classifier = artifactType
|
||||
}
|
||||
dependency
|
||||
.filterIsInstance<ModuleDependency>()
|
||||
.map { it.copy() }
|
||||
.map { dependency ->
|
||||
dependency.artifact {
|
||||
name = dependency.name
|
||||
type = artifactType
|
||||
extension = "jar"
|
||||
classifier = artifactType
|
||||
}
|
||||
dependency
|
||||
}
|
||||
|
||||
files(configurations.detachedConfiguration(*deps.toTypedArray())
|
||||
.resolvedConfiguration.lenientConfiguration.artifacts
|
||||
.filter { it.classifier == artifactType }
|
||||
.map { zipTree(it.file) })
|
||||
.resolvedConfiguration.lenientConfiguration.artifacts
|
||||
.filter { it.classifier == artifactType }
|
||||
.map { zipTree(it.file) })
|
||||
}
|
||||
tasks.register<Jar>("sourcesJar") {
|
||||
from({
|
||||
altConfigFiles("sources")
|
||||
})
|
||||
val filePattern = Regex("(.*)com/sk89q/squirrelid((?:/|$).*)")
|
||||
val textPattern = Regex("com\\.sk89q\\.squirrelid")
|
||||
eachFile {
|
||||
filter {
|
||||
it.replaceFirst(textPattern, "com.sk89q.worldguard.util.profile")
|
||||
relocations.forEach { (from, to) ->
|
||||
val filePattern = Regex("(.*)${from.replace('.', '/')}((?:/|$).*)")
|
||||
val textPattern = Regex.fromLiteral(from)
|
||||
eachFile {
|
||||
filter {
|
||||
it.replaceFirst(textPattern, to)
|
||||
}
|
||||
path = path.replaceFirst(filePattern, "$1${to.replace('.', '/')}$2")
|
||||
}
|
||||
path = path.replaceFirst(filePattern, "$1com/sk89q/worldguard/util/profile$2")
|
||||
}
|
||||
archiveClassifier.set("sources")
|
||||
}
|
||||
|
@ -73,24 +91,97 @@ fun Project.applyLibrariesConfiguration() {
|
|||
dependsOn("jar", "sourcesJar")
|
||||
}
|
||||
|
||||
artifacts {
|
||||
val jar = tasks.named("jar")
|
||||
add("default", jar) {
|
||||
builtBy(jar)
|
||||
}
|
||||
val sourcesJar = tasks.named("sourcesJar")
|
||||
add("archives", sourcesJar) {
|
||||
builtBy(sourcesJar)
|
||||
project.apply<LibsConfigPluginHack>()
|
||||
|
||||
val libsComponent = project.components["libs"] as AdhocComponentWithVariants
|
||||
|
||||
val apiElements = project.configurations.register("apiElements") {
|
||||
isVisible = false
|
||||
description = "API elements for libs"
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API))
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 8)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
|
||||
tasks.register<Upload>("install") {
|
||||
configuration = configurations["archives"]
|
||||
(repositories as HasConvention).convention.getPlugin<MavenRepositoryHandlerConvention>().mavenInstaller {
|
||||
pom.version = project.version.toString()
|
||||
pom.artifactId = project.name
|
||||
val runtimeElements = project.configurations.register("runtimeElements") {
|
||||
isVisible = false
|
||||
description = "Runtime elements for libs"
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 8)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
|
||||
val sourcesElements = project.configurations.register("sourcesElements") {
|
||||
isVisible = false
|
||||
description = "Source elements for libs"
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.DOCUMENTATION))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.objects.named(DocsType.SOURCES))
|
||||
}
|
||||
outgoing.artifact(tasks.named("sourcesJar"))
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(apiElements.get()) {
|
||||
mapToMavenScope("compile")
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(runtimeElements.get()) {
|
||||
mapToMavenScope("runtime")
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(sourcesElements.get()) {
|
||||
mapToMavenScope("runtime")
|
||||
}
|
||||
|
||||
configure<PublishingExtension> {
|
||||
publications {
|
||||
register<MavenPublication>("maven") {
|
||||
from(libsComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyCommonArtifactoryConfig()
|
||||
}
|
||||
}
|
||||
|
||||
// A horrible hack because `softwareComponentFactory` has to be gotten via plugin
|
||||
// gradle why
|
||||
internal open class LibsConfigPluginHack @Inject constructor(
|
||||
private val softwareComponentFactory: SoftwareComponentFactory
|
||||
) : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
val libsComponents = softwareComponentFactory.adhoc("libs")
|
||||
project.components.add(libsComponents)
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.constrainDependenciesToLibsCore() {
|
||||
evaluationDependsOn(":worldguard-libs:core")
|
||||
val coreDeps = project(":worldguard-libs:core").configurations["shade"].dependencies
|
||||
.filterIsInstance<ExternalModuleDependency>()
|
||||
dependencies.constraints {
|
||||
for (coreDep in coreDeps) {
|
||||
add("shade", "${coreDep.group}:${coreDep.name}:${coreDep.version}") {
|
||||
because("libs should align with libs:core")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,105 +1,48 @@
|
|||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import net.minecrell.gradle.licenser.LicenseExtension
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.plugins.quality.CheckstyleExtension
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.external.javadoc.CoreJavadocOptions
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getByName
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
|
||||
fun Project.applyPlatformAndCoreConfiguration() {
|
||||
fun Project.applyPlatformAndCoreConfiguration(javaRelease: Int = 17) {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "eclipse")
|
||||
apply(plugin = "idea")
|
||||
apply(plugin = "maven")
|
||||
apply(plugin = "checkstyle")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
apply(plugin = "net.minecrell.licenser")
|
||||
applyCommonJavaConfiguration(
|
||||
sourcesJar = true,
|
||||
javaRelease = javaRelease,
|
||||
banSlf4j = false
|
||||
)
|
||||
|
||||
ext["internalVersion"] = "$version;${rootProject.ext["gitCommitHash"]}"
|
||||
ext["internalVersion"] = "$version+${rootProject.ext["gitCommitHash"]}"
|
||||
|
||||
configure<JavaPluginConvention> {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
configure<CheckstyleExtension> {
|
||||
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
|
||||
toolVersion = "7.6.1"
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnit()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"testCompile"("junit:junit:${Versions.JUNIT}")
|
||||
// TODO switch to jupiter - doesn't support abstract test classes so tests need rewriting
|
||||
//"testImplementation"("org.junit.jupiter:junit-jupiter-api:${Versions.JUNIT}")
|
||||
//"testRuntime"("org.junit.jupiter:junit-jupiter-engine:${Versions.JUNIT}")
|
||||
}
|
||||
|
||||
// Java 8 turns on doclint which we fail
|
||||
tasks.withType<Javadoc>().configureEach {
|
||||
(options as CoreJavadocOptions).addStringOption("Xdoclint:none", "-quiet")
|
||||
}
|
||||
|
||||
tasks.register<Jar>("javadocJar") {
|
||||
dependsOn("javadoc")
|
||||
archiveClassifier.set("javadoc")
|
||||
from(tasks.getByName<Javadoc>("javadoc").destinationDir)
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("javadocJar")
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("archives", tasks.named("jar"))
|
||||
add("archives", tasks.named("javadocJar"))
|
||||
}
|
||||
|
||||
if (name == "worldguard-core" || name == "worldguard-bukkit") {
|
||||
tasks.register<Jar>("sourcesJar") {
|
||||
dependsOn("classes")
|
||||
archiveClassifier.set("sources")
|
||||
from(sourceSets["main"].allSource)
|
||||
configure<PublishingExtension> {
|
||||
publications {
|
||||
register<MavenPublication>("maven") {
|
||||
from(components["java"])
|
||||
versionMapping {
|
||||
usage("java-api") {
|
||||
fromResolutionOf("runtimeClasspath")
|
||||
}
|
||||
usage("java-runtime") {
|
||||
fromResolutionResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("archives", tasks.named("sourcesJar"))
|
||||
}
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("sourcesJar")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("check").configure {
|
||||
dependsOn("checkstyleMain", "checkstyleTest")
|
||||
}
|
||||
|
||||
applyCommonArtifactoryConfig()
|
||||
|
||||
configure<LicenseExtension> {
|
||||
header = rootProject.file("HEADER.txt")
|
||||
include("**/*.java")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun Project.applyShadowConfiguration() {
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("dist")
|
||||
dependencies {
|
||||
|
@ -110,10 +53,16 @@ fun Project.applyShadowConfiguration() {
|
|||
relocate("org.flywaydb", "com.sk89q.worldguard.internal.flywaydb") {
|
||||
include(dependency("org.flywaydb:flyway-core:3.0"))
|
||||
}
|
||||
relocate("com.sk89q.squirrelid", "com.sk89q.worldguard.util.profile")
|
||||
exclude("com.google.code.findbugs:jsr305")
|
||||
}
|
||||
exclude("GradleStart**")
|
||||
exclude(".cache")
|
||||
exclude("LICENSE*")
|
||||
exclude("META-INF/maven/**")
|
||||
}
|
||||
val javaComponent = components["java"] as AdhocComponentWithVariants
|
||||
// I don't think we want this published (it's the shadow jar)
|
||||
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
|
||||
skip()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
object Versions {
|
||||
// const val PISTON = "0.4.3"
|
||||
// const val AUTO_VALUE = "1.6.5"
|
||||
const val JUNIT = "4.11"
|
||||
const val SQUIRRELID = "0.2.0"
|
||||
// const val PISTON = "0.4.3"
|
||||
// const val AUTO_VALUE = "1.6.5"
|
||||
const val WORLDEDIT = "7.3.0"
|
||||
const val JUNIT = "5.9.1"
|
||||
const val MOCKITO = "4.9.0"
|
||||
const val SQUIRRELID = "0.3.2"
|
||||
const val GUAVA = "31.1-jre"
|
||||
const val FINDBUGS = "3.0.2"
|
||||
}
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
<module name="FileTabCharacter"/>
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${basedir}/config/checkstyle/suppressions.xml"/>
|
||||
<property name="file" value="${config_loc}/suppressions.xml"/>
|
||||
</module>
|
||||
|
||||
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!-- Important basics -->
|
||||
<!-- <module name="PackageDeclaration"/> Unlikely that we would miss this in a PR -->
|
||||
|
@ -20,7 +22,7 @@
|
|||
It is a bit draconian, so update as necessary!
|
||||
-->
|
||||
<module name="ImportControl">
|
||||
<property name="file" value="${basedir}/config/checkstyle/import-control.xml"/>
|
||||
<property name="file" value="${config_loc}/import-control.xml"/>
|
||||
</module>
|
||||
|
||||
<!-- Code -->
|
||||
|
|
|
@ -27,8 +27,11 @@
|
|||
<subpackage name="bukkit">
|
||||
<allow pkg="org.bukkit"/>
|
||||
<allow pkg="org.bstats.bukkit"/>
|
||||
<allow pkg="org.bstats.charts"/>
|
||||
<allow pkg="io.papermc.lib"/>
|
||||
<allow pkg="com.destroystokyo.paper"/>
|
||||
<allow pkg="io.papermc.paper"/>
|
||||
<allow pkg="org.spigotmc" />
|
||||
</subpackage>
|
||||
|
||||
</subpackage>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
group=com.sk89q.worldguard
|
||||
version=7.0.1
|
||||
version=7.1.0-SNAPSHOT
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,7 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -1,78 +1,127 @@
|
|||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
@ -81,92 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
|
@ -9,25 +25,29 @@
|
|||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m"
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
@ -35,48 +55,36 @@ goto fail
|
|||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.internal.HasConvention
|
||||
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("net.ltgt.apt-eclipse")
|
||||
id("net.ltgt.apt-idea")
|
||||
`java-library`
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
|
@ -13,62 +10,65 @@ applyShadowConfiguration()
|
|||
repositories {
|
||||
maven {
|
||||
name = "paper"
|
||||
url = uri("https://papermc.io/repo/repository/maven-public/")
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
maven {
|
||||
name = "bstats"
|
||||
url = uri("https://repo.codemc.org/repository/maven-public")
|
||||
// TODO: Remove this once paper updated to adventure release
|
||||
name = "adventure-snapshots"
|
||||
url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
compileClasspath.get().extendsFrom(create("shadeOnly"))
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"compile"(project(":worldguard-core"))
|
||||
//"compile"(project(":worldguard-libs:bukkit"))
|
||||
"api"("com.destroystokyo.paper:paper-api:1.14.4-R0.1-SNAPSHOT")
|
||||
"implementation"("io.papermc:paperlib:1.0.2")
|
||||
"api"("com.sk89q.worldedit:worldedit-bukkit:7.0.1-SNAPSHOT") { isTransitive = false }
|
||||
"implementation"("com.sk89q:commandbook:2.3") { isTransitive = false }
|
||||
"implementation"("org.bstats:bstats-bukkit:1.5")
|
||||
}
|
||||
|
||||
tasks.named<Upload>("install") {
|
||||
(repositories as HasConvention).convention.getPlugin<MavenRepositoryHandlerConvention>().mavenInstaller {
|
||||
pom.whenConfigured {
|
||||
dependencies.firstOrNull { dep ->
|
||||
dep!!.withGroovyBuilder {
|
||||
getProperty("groupId") == "com.destroystokyo.paper" && getProperty("artifactId") == "paper-api"
|
||||
}
|
||||
}?.withGroovyBuilder {
|
||||
setProperty("groupId", "org.bukkit")
|
||||
setProperty("artifactId", "bukkit")
|
||||
}
|
||||
}
|
||||
"api"(project(":worldguard-core"))
|
||||
"compileOnly"("io.papermc.paper:paper-api:1.20.6-R0.1-SNAPSHOT")
|
||||
"runtimeOnly"("org.spigotmc:spigot-api:1.20.6-R0.1-SNAPSHOT") {
|
||||
exclude("junit", "junit")
|
||||
}
|
||||
"api"("com.sk89q.worldedit:worldedit-bukkit:${Versions.WORLDEDIT}") { isTransitive = false }
|
||||
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
|
||||
"compileOnly"("com.sk89q:commandbook:2.3") { isTransitive = false }
|
||||
"shadeOnly"("io.papermc:paperlib:1.0.8")
|
||||
"shadeOnly"("org.bstats:bstats-bukkit:3.0.1")
|
||||
}
|
||||
|
||||
tasks.named<Copy>("processResources") {
|
||||
val internalVersion = project.ext["internalVersion"]
|
||||
inputs.property("internalVersion", internalVersion)
|
||||
filesMatching("plugin.yml") {
|
||||
expand("internalVersion" to project.ext["internalVersion"])
|
||||
expand("internalVersion" to internalVersion)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<Jar>("jar") {
|
||||
val projectVersion = project.version
|
||||
inputs.property("projectVersion", projectVersion)
|
||||
manifest {
|
||||
attributes("Implementation-Version" to project.version)
|
||||
attributes("Implementation-Version" to projectVersion)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
configurations = listOf(project.configurations["shadeOnly"], project.configurations["runtimeClasspath"])
|
||||
|
||||
dependencies {
|
||||
include(dependency(":worldguard-core"))
|
||||
relocate("org.bstats", "com.sk89q.worldguard.bukkit.bstats") {
|
||||
include(dependency("org.bstats:bstats-bukkit:1.5"))
|
||||
include(dependency("org.bstats:"))
|
||||
}
|
||||
relocate ("io.papermc.lib", "com.sk89q.worldguard.bukkit.paperlib") {
|
||||
include(dependency("io.papermc:paperlib:1.0.2"))
|
||||
include(dependency("io.papermc:paperlib"))
|
||||
}
|
||||
relocate ("co.aikar.timings.lib", "com.sk89q.worldguard.bukkit.timingslib") {
|
||||
include(dependency("co.aikar:minecraft-timings"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("shadowJar")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,10 @@ public class BukkitConfigurationManager extends YamlConfigurationManager {
|
|||
@Override
|
||||
public BukkitWorldConfiguration get(World world) {
|
||||
String worldName = world.getName();
|
||||
return get(worldName);
|
||||
}
|
||||
|
||||
public BukkitWorldConfiguration get(String worldName) {
|
||||
BukkitWorldConfiguration config = worlds.get(worldName);
|
||||
BukkitWorldConfiguration newConfig = null;
|
||||
|
||||
|
@ -99,8 +103,8 @@ public class BukkitConfigurationManager extends YamlConfigurationManager {
|
|||
if (newConfig == null) {
|
||||
newConfig = new BukkitWorldConfiguration(plugin, worldName, this.getConfig());
|
||||
}
|
||||
worlds.putIfAbsent(world.getName(), newConfig);
|
||||
config = worlds.get(world.getName());
|
||||
worlds.putIfAbsent(worldName, newConfig);
|
||||
config = worlds.get(worldName);
|
||||
}
|
||||
|
||||
return config;
|
||||
|
|
|
@ -24,6 +24,8 @@ import com.sk89q.worldedit.util.Location;
|
|||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.util.MessagingUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.BanList.Type;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -172,7 +174,11 @@ public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implem
|
|||
|
||||
@Override
|
||||
public void sendTitle(String title, String subtitle) {
|
||||
getPlayer().sendTitle(title, subtitle, -1, -1, -1);
|
||||
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(getWorld()).forceDefaultTitleTimes) {
|
||||
getPlayer().sendTitle(title, subtitle, 10, 70, 20);
|
||||
} else {
|
||||
getPlayer().sendTitle(title, subtitle, -1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -185,7 +191,10 @@ public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implem
|
|||
PaperLib.teleportAsync(getPlayer(), BukkitAdapter.adapt(location))
|
||||
.thenApply(success -> {
|
||||
if (success) {
|
||||
print(successMessage);
|
||||
// The success message can be cleared via flag
|
||||
if (!successMessage.isEmpty()) {
|
||||
MessagingUtil.sendStringToChat(this, successMessage);
|
||||
}
|
||||
} else {
|
||||
printError(failMessage);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import com.sk89q.worldguard.chest.ChestProtection;
|
|||
import com.sk89q.worldguard.commands.CommandUtils;
|
||||
import com.sk89q.worldguard.config.YamlWorldConfiguration;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -105,6 +105,13 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
|
||||
if (inputs == null || inputs.isEmpty()) {
|
||||
parentConfig.setProperty(node, new ArrayList<String>());
|
||||
}
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
inputs = config.getStringList(node, null);
|
||||
}
|
||||
|
||||
if (inputs == null || inputs.isEmpty()) {
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -128,11 +135,13 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
config.load();
|
||||
} catch (IOException e) {
|
||||
log.log(Level.SEVERE, "Error reading configuration for world " + worldName + ": ", e);
|
||||
} catch (ParserException e) {
|
||||
} catch (YAMLException e) {
|
||||
log.severe("Error parsing configuration for world " + worldName + ". ");
|
||||
throw e;
|
||||
}
|
||||
|
||||
boolean needParentSave = false;
|
||||
|
||||
summaryOnStart = getBoolean("summary-on-start", true);
|
||||
opPermissions = getBoolean("op-permissions", true);
|
||||
|
||||
|
@ -144,13 +153,17 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
allowAllInteract = getTargetMatchers("event-handling.interaction-whitelist");
|
||||
blockUseAtFeet = getTargetMatchers("event-handling.emit-block-use-at-feet");
|
||||
ignoreHopperMoveEvents = getBoolean("event-handling.ignore-hopper-item-move-events", false);
|
||||
breakDeniedHoppers = getBoolean("event-handling.break-hoppers-on-denied-move", true);
|
||||
|
||||
usePaperEntityOrigin = getBoolean("regions.use-paper-entity-origin", false);
|
||||
|
||||
itemDurability = getBoolean("protection.item-durability", true);
|
||||
removeInfiniteStacks = getBoolean("protection.remove-infinite-stacks", false);
|
||||
disableExpDrops = getBoolean("protection.disable-xp-orb-drops", false);
|
||||
disableObsidianGenerators = getBoolean("protection.disable-obsidian-generators", false);
|
||||
|
||||
needParentSave |= removeProperty("protection.disable-obsidian-generators");
|
||||
|
||||
useMaxPriorityAssociation = getBoolean("protection.use-max-priority-association", false);
|
||||
|
||||
blockPotions = new HashSet<>();
|
||||
for (String potionName : getStringList("gameplay.block-potions", null)) {
|
||||
|
@ -168,6 +181,11 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
simulateSponge = getBoolean("simulation.sponge.enable", false);
|
||||
spongeRadius = Math.max(1, getInt("simulation.sponge.radius", 3)) - 1;
|
||||
redstoneSponges = getBoolean("simulation.sponge.redstone", false);
|
||||
if (simulateSponge) {
|
||||
log.warning("Sponge simulation is deprecated for removal in a future version. We recommend using CraftBook's sponge simulation instead.");
|
||||
} else {
|
||||
needParentSave |= removeProperty("simulation");
|
||||
}
|
||||
|
||||
pumpkinScuba = getBoolean("default.pumpkin-scuba", false);
|
||||
disableHealthRegain = getBoolean("default.disable-health-regain", false);
|
||||
|
@ -208,6 +226,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
blockGroundSlimes = getBoolean("mobs.block-above-ground-slimes", false);
|
||||
blockOtherExplosions = getBoolean("mobs.block-other-explosions", false);
|
||||
blockZombieDoorDestruction = getBoolean("mobs.block-zombie-door-destruction", false);
|
||||
blockEntityVehicleEntry = getBoolean("mobs.block-vehicle-entry", false);
|
||||
|
||||
disableFallDamage = getBoolean("player-damage.disable-fall-damage", false);
|
||||
disableLavaDamage = getBoolean("player-damage.disable-lava-damage", false);
|
||||
|
@ -225,11 +244,21 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
disableDeathMessages = getBoolean("player-damage.disable-death-messages", false);
|
||||
|
||||
signChestProtection = getBoolean("chest-protection.enable", false);
|
||||
disableSignChestProtectionCheck = getBoolean("chest-protection.disable-off-check", false);
|
||||
disableSignChestProtectionCheck = getBoolean("chest-protection.disable-off-check", true);
|
||||
if (signChestProtection) {
|
||||
log.warning("Sign-based chest protection is deprecated for removal in a future version. See https://worldguard.enginehub.org/en/latest/chest-protection/ for details.");
|
||||
} else {
|
||||
needParentSave |= removeProperty("chest-protection");
|
||||
}
|
||||
|
||||
disableCreatureCropTrampling = getBoolean("crops.disable-creature-trampling", false);
|
||||
disablePlayerCropTrampling = getBoolean("crops.disable-player-trampling", false);
|
||||
|
||||
disableCreatureTurtleEggTrampling = getBoolean("turtle-egg.disable-creature-trampling", false);
|
||||
disablePlayerTurtleEggTrampling = getBoolean("turtle-egg.disable-player-trampling", false);
|
||||
disableCreatureSnifferEggTrampling = getBoolean("sniffer-egg.disable-creature-trampling", false);
|
||||
disablePlayerSnifferEggTrampling = getBoolean("sniffer-egg.disable-player-trampling", false);
|
||||
|
||||
disallowedLightningBlocks = new HashSet<>(convertLegacyBlocks(getStringList("weather.prevent-lightning-strike-blocks", null)));
|
||||
preventLightningFire = getBoolean("weather.disable-lightning-strike-fire", false);
|
||||
disableThunder = getBoolean("weather.disable-thunderstorm", false);
|
||||
|
@ -249,14 +278,19 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
disableGrassGrowth = getBoolean("dynamics.disable-grass-growth", false);
|
||||
disableMyceliumSpread = getBoolean("dynamics.disable-mycelium-spread", false);
|
||||
disableVineGrowth = getBoolean("dynamics.disable-vine-growth", false);
|
||||
disableRockGrowth = getBoolean("dynamics.disable-rock-growth", false);
|
||||
disableSculkGrowth = getBoolean("dynamics.disable-sculk-growth", false);
|
||||
disableCropGrowth = getBoolean("dynamics.disable-crop-growth", false);
|
||||
disableSoilDehydration = getBoolean("dynamics.disable-soil-dehydration", false);
|
||||
disableCoralBlockFade = getBoolean("dynamics.disable-coral-block-fade", false);
|
||||
disableCopperBlockFade = getBoolean("dynamics.disable-copper-block-fade", false);
|
||||
allowedSnowFallOver = new HashSet<>(convertLegacyBlocks(getStringList("dynamics.snow-fall-blocks", null)));
|
||||
|
||||
useRegions = getBoolean("regions.enable", true);
|
||||
regionInvinciblityRemovesMobs = getBoolean("regions.invincibility-removes-mobs", false);
|
||||
regionCancelEmptyChatEvents = getBoolean("regions.cancel-chat-without-recipients", true);
|
||||
regionNetherPortalProtection = getBoolean("regions.nether-portal-protection", false);
|
||||
regionNetherPortalProtection = getBoolean("regions.nether-portal-protection", true);
|
||||
forceDefaultTitleTimes = config.getBoolean("regions.titles-always-use-default-times", true); // note: technically not region-specific, but we only use it for the title flags
|
||||
fakePlayerBuildOverride = getBoolean("regions.fake-player-build-override", true);
|
||||
explosionFlagCancellation = getBoolean("regions.explosion-flags-block-entity-damage", true);
|
||||
highFreqFlags = getBoolean("regions.high-frequency-flags", false);
|
||||
|
@ -264,6 +298,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
regionWand = convertLegacyItem(getString("regions.wand", ItemTypes.LEATHER.getId()));
|
||||
maxClaimVolume = getInt("regions.max-claim-volume", 30000);
|
||||
claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false);
|
||||
setParentOnClaim = getString("regions.set-parent-on-claim", "");
|
||||
boundedLocationFlags = getBoolean("regions.location-flags-only-inside-regions", false);
|
||||
|
||||
maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7);
|
||||
|
@ -385,6 +420,20 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
|||
config.setHeader(CONFIG_HEADER);
|
||||
|
||||
config.save();
|
||||
if (needParentSave) {
|
||||
parentConfig.save();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean removeProperty(String prop) {
|
||||
if (config.getProperty(prop) != null) {
|
||||
config.removeProperty(prop);
|
||||
}
|
||||
if (parentConfig.getProperty(prop) != null) {
|
||||
parentConfig.removeProperty(prop);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isChestProtected(Location block, LocalPlayer player) {
|
||||
|
|
|
@ -19,15 +19,22 @@
|
|||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.report.ReportList;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.util.profile.resolver.PaperProfileService;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.util.profile.resolver.PaperPlayerService;
|
||||
import com.sk89q.worldguard.bukkit.protection.events.flags.FlagContextCreateEvent;
|
||||
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
|
||||
import com.sk89q.worldguard.bukkit.util.report.DatapackReport;
|
||||
import com.sk89q.worldguard.bukkit.util.report.PerformanceReport;
|
||||
import com.sk89q.worldguard.bukkit.util.report.PluginReport;
|
||||
import com.sk89q.worldguard.bukkit.util.report.SchedulerReport;
|
||||
|
@ -52,6 +59,7 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -60,7 +68,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
||||
|
||||
private SessionManager sessionManager;
|
||||
private BukkitSessionManager sessionManager;
|
||||
private BukkitConfigurationManager configuration;
|
||||
private BukkitRegionContainer regionContainer;
|
||||
private BukkitDebugHandler debugHandler;
|
||||
|
@ -138,6 +146,7 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
|||
|
||||
@Override
|
||||
public void unload() {
|
||||
sessionManager.shutdown();
|
||||
configuration.unload();
|
||||
regionContainer.shutdown();
|
||||
}
|
||||
|
@ -165,7 +174,6 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
|||
@Override
|
||||
public void stackPlayerInventory(LocalPlayer localPlayer) {
|
||||
boolean ignoreMax = localPlayer.hasPermission("worldguard.stack.illegitimate");
|
||||
boolean ignoreDamaged = localPlayer.hasPermission("worldguard.stack.damaged");
|
||||
|
||||
Player player = ((BukkitPlayer) localPlayer).getPlayer();
|
||||
|
||||
|
@ -199,12 +207,7 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
|||
}
|
||||
|
||||
// Same type?
|
||||
// Blocks store their color in the damage value
|
||||
if (item2.getType() == item.getType() &&
|
||||
(ignoreDamaged || item.getDurability() == item2.getDurability()) &&
|
||||
((item.getItemMeta() == null && item2.getItemMeta() == null)
|
||||
|| (item.getItemMeta() != null &&
|
||||
item.getItemMeta().equals(item2.getItemMeta())))) {
|
||||
if (item2.isSimilar(item)) {
|
||||
// This stack won't fit in the parent stack
|
||||
if (item2.getAmount() > needed) {
|
||||
item.setAmount(max);
|
||||
|
@ -236,6 +239,7 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
|||
report.add(new ServicesReport());
|
||||
report.add(new WorldReport());
|
||||
report.add(new PerformanceReport());
|
||||
if (PaperLib.isPaper()) report.add(new DatapackReport());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -243,7 +247,7 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
|||
List<ProfileService> services = new ArrayList<>();
|
||||
if (PaperLib.isPaper()) {
|
||||
// Paper has a shared cache
|
||||
services.add(PaperProfileService.getInstance());
|
||||
services.add(PaperPlayerService.getInstance());
|
||||
} else {
|
||||
services.add(BukkitPlayerService.getInstance());
|
||||
}
|
||||
|
@ -251,4 +255,22 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
|||
return new CacheForwardingService(new CombinedProfileService(services),
|
||||
profileCache);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProtectedRegion getSpawnProtection(World world) {
|
||||
if (world instanceof BukkitWorld) {
|
||||
org.bukkit.World bWorld = ((BukkitWorld) world).getWorld();
|
||||
if (bWorld.getUID().equals(Bukkit.getServer().getWorlds().get(0).getUID())) {
|
||||
int radius = Bukkit.getServer().getSpawnRadius();
|
||||
if (radius > 0) {
|
||||
BlockVector3 spawnLoc = BukkitAdapter.asBlockVector(bWorld.getSpawnLocation());
|
||||
return new ProtectedCuboidRegion("__spawn_protection__",
|
||||
spawnLoc.subtract(radius, 0, radius).withY(world.getMinimumPoint().y()),
|
||||
spawnLoc.add(radius, 0, radius).withY(world.getMaxY()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.sk89q.bukkit.util.CommandsManagerRegistration;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||
|
@ -60,11 +59,13 @@ import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener;
|
|||
import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldRulesListener;
|
||||
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
|
||||
import com.sk89q.worldguard.bukkit.util.ClassSourceValidator;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.bukkit.util.Events;
|
||||
import com.sk89q.worldguard.bukkit.util.logging.ClassSourceValidator;
|
||||
import com.sk89q.worldguard.commands.GeneralCommands;
|
||||
import com.sk89q.worldguard.commands.ProtectionCommands;
|
||||
import com.sk89q.worldguard.commands.ToggleCommands;
|
||||
import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
|
||||
|
@ -72,10 +73,12 @@ import com.sk89q.worldguard.protection.managers.RegionManager;
|
|||
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
|
||||
import com.sk89q.worldguard.protection.managers.storage.file.DirectoryYamlDriver;
|
||||
import com.sk89q.worldguard.protection.managers.storage.sql.SQLDriver;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.util.logging.RecordMessagePrefixer;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.DrilldownPie;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bstats.charts.SingleLineChart;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
@ -93,9 +96,8 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
/**
|
||||
* The main class for WorldGuard as a Bukkit plugin.
|
||||
|
@ -107,6 +109,8 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
private final CommandsManager<Actor> commands;
|
||||
private PlayerMoveListener playerMoveListener;
|
||||
|
||||
private static final int BSTATS_PLUGIN_ID = 3283;
|
||||
|
||||
/**
|
||||
* Construct objects. Actual loading occurs when the plugin is enabled, so
|
||||
* this merely instantiates the objects.
|
||||
|
@ -134,6 +138,10 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
*/
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Catch bad things being done by naughty plugins that include WorldGuard's classes
|
||||
ClassSourceValidator verifier = new ClassSourceValidator(this);
|
||||
verifier.reportMismatches(ImmutableList.of(WorldGuard.class, ProtectedRegion.class, Flag.class));
|
||||
|
||||
configureLogger();
|
||||
|
||||
getDataFolder().mkdirs(); // Need to create the plugins/WorldGuard folder
|
||||
|
@ -147,21 +155,14 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
// Set the proper command injector
|
||||
commands.setInjector(new SimpleInjector(WorldGuard.getInstance()));
|
||||
|
||||
// Catch bad things being done by naughty plugins that include
|
||||
// WorldGuard's classes
|
||||
ClassSourceValidator verifier = new ClassSourceValidator(this);
|
||||
verifier.reportMismatches(ImmutableList.of(ProtectedRegion.class, ProtectedCuboidRegion.class, Flag.class));
|
||||
|
||||
// Register command classes
|
||||
final CommandsManagerRegistration reg = new CommandsManagerRegistration(this, commands);
|
||||
reg.register(ToggleCommands.class);
|
||||
reg.register(ProtectionCommands.class);
|
||||
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
|
||||
if (!platform.getGlobalStateManager().hasCommandBookGodMode()) {
|
||||
reg.register(GeneralCommands.class);
|
||||
}
|
||||
}, 0L);
|
||||
if (!platform.getGlobalStateManager().hasCommandBookGodMode()) {
|
||||
reg.register(GeneralCommands.class);
|
||||
}
|
||||
|
||||
getServer().getScheduler().scheduleSyncRepeatingTask(this, sessionManager, BukkitSessionManager.RUN_DELAY, BukkitSessionManager.RUN_DELAY);
|
||||
|
||||
|
@ -212,22 +213,23 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
});
|
||||
|
||||
((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).setInitialized(true);
|
||||
((SimpleDomainRegistry) WorldGuard.getInstance().getDomainRegistry()).setInitialized(true);
|
||||
|
||||
// Enable metrics
|
||||
final Metrics metrics = new Metrics(this);
|
||||
if (metrics.isEnabled() && platform.getGlobalStateManager().extraStats) {
|
||||
final Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID); // bStats plugin id
|
||||
if (platform.getGlobalStateManager().extraStats) {
|
||||
setupCustomCharts(metrics);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupCustomCharts(Metrics metrics) {
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("region_count", () ->
|
||||
metrics.addCustomChart(new SingleLineChart("region_count", () ->
|
||||
platform.getRegionContainer().getLoaded().stream().mapToInt(RegionManager::size).sum()));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("region_driver", () -> {
|
||||
metrics.addCustomChart(new SimplePie("region_driver", () -> {
|
||||
RegionDriver driver = platform.getGlobalStateManager().selectedRegionStoreDriver;
|
||||
return driver instanceof DirectoryYamlDriver ? "yaml" : driver instanceof SQLDriver ? "sql" : "unknown";
|
||||
}));
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("blacklist", () -> {
|
||||
metrics.addCustomChart(new DrilldownPie("blacklist", () -> {
|
||||
int empty = 0;
|
||||
Map<String, Integer> blacklistMap = new HashMap<>();
|
||||
Map<String, Integer> whitelistMap = new HashMap<>();
|
||||
|
@ -250,14 +252,14 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
blacklistCounts.put("whitelist", whitelistMap);
|
||||
return blacklistCounts;
|
||||
}));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("chest_protection", () ->
|
||||
metrics.addCustomChart(new SimplePie("chest_protection", () ->
|
||||
"" + platform.getGlobalStateManager().getWorldConfigs().stream().anyMatch(cfg -> cfg.signChestProtection)));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("build_permissions", () ->
|
||||
metrics.addCustomChart(new SimplePie("build_permissions", () ->
|
||||
"" + platform.getGlobalStateManager().getWorldConfigs().stream().anyMatch(cfg -> cfg.buildPermissions)));
|
||||
|
||||
metrics.addCustomChart(new Metrics.SimplePie("custom_flags", () ->
|
||||
metrics.addCustomChart(new SimplePie("custom_flags", () ->
|
||||
"" + (WorldGuard.getInstance().getFlagRegistry().size() > Flags.INBUILT_FLAGS.size())));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("custom_handlers", () ->
|
||||
metrics.addCustomChart(new SimplePie("custom_handlers", () ->
|
||||
"" + (WorldGuard.getInstance().getPlatform().getSessionManager().customHandlersRegistered())));
|
||||
}
|
||||
|
||||
|
@ -387,6 +389,8 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
Plugin worldEdit = getServer().getPluginManager().getPlugin("WorldEdit");
|
||||
if (worldEdit == null) {
|
||||
throw new CommandException("WorldEdit does not appear to be installed.");
|
||||
} else if (!worldEdit.isEnabled()) {
|
||||
throw new CommandException("WorldEdit does not appear to be enabled.");
|
||||
}
|
||||
|
||||
if (worldEdit instanceof WorldEditPlugin) {
|
||||
|
@ -418,8 +422,9 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
}
|
||||
|
||||
public Actor wrapCommandSender(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
return wrapPlayer((Player) sender);
|
||||
if (sender instanceof Player player) {
|
||||
if (Entities.isNPC(player)) return null;
|
||||
return wrapPlayer(player);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -452,6 +457,13 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
return new BukkitOfflinePlayer(this, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method. Do not use as API.
|
||||
*/
|
||||
public BukkitConfigurationManager getConfigManager() {
|
||||
return platform.getGlobalStateManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a protection query helper object that can be used by another
|
||||
* plugin to test whether WorldGuard permits an action at a particular
|
||||
|
@ -488,44 +500,25 @@ public class WorldGuardPlugin extends JavaPlugin {
|
|||
return;
|
||||
}
|
||||
|
||||
InputStream input = null;
|
||||
try {
|
||||
JarFile file = new JarFile(getFile());
|
||||
ZipEntry copy = file.getEntry("defaults/" + defaultName);
|
||||
if (copy == null) throw new FileNotFoundException();
|
||||
input = file.getInputStream(copy);
|
||||
try (InputStream stream = getResource("defaults/" + defaultName)){
|
||||
if (stream == null) throw new FileNotFoundException();
|
||||
copyDefaultConfig(stream, actual, defaultName);
|
||||
} catch (IOException e) {
|
||||
WorldGuard.logger.severe("Unable to read default configuration: " + defaultName);
|
||||
getLogger().severe("Unable to read default configuration: " + defaultName);
|
||||
}
|
||||
|
||||
if (input != null) {
|
||||
FileOutputStream output = null;
|
||||
}
|
||||
|
||||
try {
|
||||
output = new FileOutputStream(actual);
|
||||
byte[] buf = new byte[8192];
|
||||
int length = 0;
|
||||
while ((length = input.read(buf)) > 0) {
|
||||
output.write(buf, 0, length);
|
||||
}
|
||||
|
||||
WorldGuard.logger.info("Default configuration file written: "
|
||||
+ actual.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
if (output != null) {
|
||||
output.close();
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
private void copyDefaultConfig(InputStream input, File actual, String name) {
|
||||
try (FileOutputStream output = new FileOutputStream(actual)) {
|
||||
byte[] buf = new byte[8192];
|
||||
int length;
|
||||
while ((length = input.read(buf)) > 0) {
|
||||
output.write(buf, 0, length);
|
||||
}
|
||||
getLogger().info("Default configuration file written: " + name);
|
||||
} catch (IOException e) {
|
||||
getLogger().log(Level.WARNING, "Failed to write default config file", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,21 +21,29 @@ package com.sk89q.worldguard.bukkit.cause;
|
|||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.internal.WGMetadata;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.AnimalTamer;
|
||||
import org.bukkit.entity.AreaEffectCloud;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.metadata.Metadatable;
|
||||
import org.bukkit.projectiles.BlockProjectileSource;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
@ -88,26 +96,39 @@ public final class Cause {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return whether a cause is known. This method will return true if
|
||||
* the list of causes is empty or the list of causes only contains
|
||||
* objects that really are not root causes (i.e primed TNT).
|
||||
* Return whether a cause is known. This method will return false if
|
||||
* the list of causes is empty or the root cause is really not known
|
||||
* (e.g. primed TNT).
|
||||
*
|
||||
* @return true if known
|
||||
*/
|
||||
public boolean isKnown() {
|
||||
if (causes.isEmpty()) {
|
||||
Object object = getRootCause();
|
||||
|
||||
if (object == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (Object object : causes) {
|
||||
if (!(object instanceof TNTPrimed) && !(object instanceof Vehicle)) {
|
||||
found = true;
|
||||
break;
|
||||
if (object instanceof Tameable tameable && tameable.isTamed()) {
|
||||
// if they're tamed but also the root cause, the owner is offline
|
||||
// otherwise the owner will be the root cause (and known)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object instanceof TNTPrimed || object instanceof Vehicle) {
|
||||
if (!PaperLib.isPaper()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Entity entity = (Entity) object;
|
||||
BukkitWorldConfiguration config = WorldGuardPlugin.inst().getConfigManager().get(entity.getWorld().getName());
|
||||
|
||||
if (!config.usePaperEntityOrigin || entity.getOrigin() == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -122,8 +143,8 @@ public final class Cause {
|
|||
@Nullable
|
||||
public Player getFirstPlayer() {
|
||||
for (Object object : causes) {
|
||||
if (object instanceof Player) {
|
||||
return (Player) object;
|
||||
if (object instanceof Player p && !Entities.isNPC(p)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,8 +154,8 @@ public final class Cause {
|
|||
@Nullable
|
||||
public Entity getFirstEntity() {
|
||||
for (Object object : causes) {
|
||||
if (object instanceof Entity) {
|
||||
return (Entity) object;
|
||||
if (object instanceof Entity e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,8 +165,8 @@ public final class Cause {
|
|||
@Nullable
|
||||
public Entity getFirstNonPlayerEntity() {
|
||||
for (Object object : causes) {
|
||||
if (object instanceof Entity && !(object instanceof Player)) {
|
||||
return (Entity) object;
|
||||
if (object instanceof Entity e && (!(object instanceof Player) || Entities.isNPC(e))) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,8 +176,8 @@ public final class Cause {
|
|||
@Nullable
|
||||
public Block getFirstBlock() {
|
||||
for (Object object : causes) {
|
||||
if (object instanceof Block) {
|
||||
return (Block) object;
|
||||
if (object instanceof Block b) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,6 +257,15 @@ public final class Cause {
|
|||
WGMetadata.put(target, CAUSE_KEY, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a parent cause from a {@code Metadatable} object.
|
||||
*
|
||||
* @param target the target
|
||||
*/
|
||||
public static void untrackParentCause(Metadatable target) {
|
||||
WGMetadata.remove(target, CAUSE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds causes.
|
||||
*/
|
||||
|
@ -249,19 +279,22 @@ public final class Cause {
|
|||
}
|
||||
|
||||
private void addAll(@Nullable Object... element) {
|
||||
if (element != null) {
|
||||
for (Object o : element) {
|
||||
if (o == null || seen.contains(o)) {
|
||||
continue;
|
||||
}
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
for (Object o : element) {
|
||||
if (o == null || seen.contains(o)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
seen.add(o);
|
||||
seen.add(o);
|
||||
|
||||
if (o instanceof TNTPrimed) {
|
||||
addAll(((TNTPrimed) o).getSource());
|
||||
} else if (o instanceof Projectile) {
|
||||
addAll(((Projectile) o).getShooter());
|
||||
} else if (o instanceof Firework && PaperLib.isPaper()) {
|
||||
if (o instanceof TNTPrimed) {
|
||||
addAll(((TNTPrimed) o).getSource());
|
||||
} else if (o instanceof Projectile) {
|
||||
ProjectileSource shooter = ((Projectile) o).getShooter();
|
||||
addAll(shooter);
|
||||
if (shooter == null && o instanceof Firework && PaperLib.isPaper()) {
|
||||
UUID spawningUUID = ((Firework) o).getSpawningEntity();
|
||||
if (spawningUUID != null) {
|
||||
Entity spawningEntity = Bukkit.getEntity(spawningUUID);
|
||||
|
@ -269,32 +302,53 @@ public final class Cause {
|
|||
addAll(spawningEntity);
|
||||
}
|
||||
}
|
||||
} else if (o instanceof Vehicle) {
|
||||
((Vehicle) o).getPassengers().forEach(this::addAll);
|
||||
} else if (o instanceof AreaEffectCloud) {
|
||||
indirect = true;
|
||||
addAll(((AreaEffectCloud) o).getSource());
|
||||
} else if (o instanceof Creature && ((Creature) o).getTarget() != null) {
|
||||
indirect = true;
|
||||
addAll(((Creature) o).getTarget());
|
||||
} else if (o instanceof Tameable) {
|
||||
indirect = true;
|
||||
addAll(((Tameable) o).getOwner());
|
||||
}
|
||||
|
||||
// Add manually tracked parent causes
|
||||
Object source = o;
|
||||
int index = causes.size();
|
||||
while (source instanceof Metadatable && !(source instanceof Block)) {
|
||||
source = WGMetadata.getIfPresent((Metadatable) source, CAUSE_KEY, Object.class);
|
||||
if (source != null) {
|
||||
causes.add(index, source);
|
||||
seen.add(source);
|
||||
} else if (o instanceof Vehicle) {
|
||||
((Vehicle) o).getPassengers().forEach(this::addAll);
|
||||
} else if (o instanceof AreaEffectCloud) {
|
||||
indirect = true;
|
||||
addAll(((AreaEffectCloud) o).getSource());
|
||||
} else if (o instanceof Tameable tameable) {
|
||||
indirect = true;
|
||||
if (PaperLib.isPaper()) {
|
||||
UUID ownerId = tameable.getOwnerUniqueId();
|
||||
if (ownerId != null) {
|
||||
Player owner = Bukkit.getPlayer(ownerId);
|
||||
if (owner != null) {
|
||||
addAll(owner);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// this will cause offline player loads if the player is offline
|
||||
// too bad for spigot users
|
||||
AnimalTamer owner = tameable.getOwner();
|
||||
if (owner instanceof OfflinePlayer player) {
|
||||
addAll(player.getPlayer()); // player object if online, else null
|
||||
}
|
||||
}
|
||||
|
||||
causes.add(o);
|
||||
} else if (o instanceof Creature && ((Creature) o).getTarget() != null) {
|
||||
indirect = true;
|
||||
addAll(((Creature) o).getTarget());
|
||||
} else if (o instanceof BlockProjectileSource) {
|
||||
addAll(((BlockProjectileSource) o).getBlock());
|
||||
} else if (o instanceof LightningStrike && PaperLib.isPaper() &&
|
||||
((LightningStrike) o).getCausingEntity() != null) {
|
||||
indirect = true;
|
||||
addAll(((LightningStrike) o).getCausingEntity());
|
||||
}
|
||||
|
||||
// Add manually tracked parent causes
|
||||
Object source = o;
|
||||
int index = causes.size();
|
||||
while (source instanceof Metadatable && !(source instanceof Block)) {
|
||||
source = WGMetadata.getIfPresent((Metadatable) source, CAUSE_KEY, Object.class);
|
||||
if (source != null) {
|
||||
causes.add(index, source);
|
||||
seen.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
causes.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,4 +75,13 @@ public final class WGMetadata {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes metadata from the target.
|
||||
*
|
||||
* @param target the target
|
||||
* @param key the key
|
||||
*/
|
||||
public static void remove(Metadatable target, String key) {
|
||||
target.removeMetadata(key, WorldGuardPlugin.inst());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,16 +22,17 @@ package com.sk89q.worldguard.bukkit.listener;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.BukkitPlayer;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.cause.Cause;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.domains.Association;
|
||||
import com.sk89q.worldguard.protection.DelayedRegionOverlapAssociation;
|
||||
import com.sk89q.worldguard.protection.association.DelayedRegionOverlapAssociation;
|
||||
import com.sk89q.worldguard.protection.association.Associables;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
|
@ -72,8 +73,8 @@ class AbstractListener implements Listener {
|
|||
*
|
||||
* @return the plugin
|
||||
*/
|
||||
protected WorldGuardPlugin getPlugin() {
|
||||
return plugin;
|
||||
protected static WorldGuardPlugin getPlugin() {
|
||||
return WorldGuardPlugin.inst();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,8 +82,8 @@ class AbstractListener implements Listener {
|
|||
*
|
||||
* @return the configuration
|
||||
*/
|
||||
protected static ConfigurationManager getConfig() {
|
||||
return WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
protected static BukkitConfigurationManager getConfig() {
|
||||
return getPlugin().getConfigManager();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,18 +92,22 @@ class AbstractListener implements Listener {
|
|||
* @param world The world to get the configuration for.
|
||||
* @return The configuration for {@code world}
|
||||
*/
|
||||
protected static WorldConfiguration getWorldConfig(World world) {
|
||||
protected static BukkitWorldConfiguration getWorldConfig(String world) {
|
||||
return getConfig().get(world);
|
||||
}
|
||||
|
||||
protected static BukkitWorldConfiguration getWorldConfig(org.bukkit.World world) {
|
||||
return getWorldConfig(world.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world configuration given a player.
|
||||
*
|
||||
* @param player The player to get the wold from
|
||||
* @return The {@link WorldConfiguration} for the player's world
|
||||
*/
|
||||
protected static WorldConfiguration getWorldConfig(LocalPlayer player) {
|
||||
return getWorldConfig((World) player.getExtent());
|
||||
protected static BukkitWorldConfiguration getWorldConfig(LocalPlayer player) {
|
||||
return getWorldConfig(((BukkitPlayer) player).getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,7 +116,7 @@ class AbstractListener implements Listener {
|
|||
* @param world the world
|
||||
* @return true if region support is enabled
|
||||
*/
|
||||
protected static boolean isRegionSupportEnabled(World world) {
|
||||
protected static boolean isRegionSupportEnabled(org.bukkit.World world) {
|
||||
return getWorldConfig(world).useRegions;
|
||||
}
|
||||
|
||||
|
@ -120,27 +125,30 @@ class AbstractListener implements Listener {
|
|||
|
||||
if (!cause.isKnown()) {
|
||||
return Associables.constant(Association.NON_MEMBER);
|
||||
} else if (rootCause instanceof Player) {
|
||||
return getPlugin().wrapPlayer((Player) rootCause);
|
||||
} else if (rootCause instanceof OfflinePlayer) {
|
||||
return getPlugin().wrapOfflinePlayer((OfflinePlayer) rootCause);
|
||||
} else if (rootCause instanceof Entity) {
|
||||
} else if (rootCause instanceof Player player && !Entities.isNPC(player)) {
|
||||
return getPlugin().wrapPlayer(player);
|
||||
} else if (rootCause instanceof OfflinePlayer offlinePlayer) {
|
||||
return getPlugin().wrapOfflinePlayer(offlinePlayer);
|
||||
} else if (rootCause instanceof Entity entity) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
final Entity entity = (Entity) rootCause;
|
||||
BukkitWorldConfiguration config = getWorldConfig(entity.getWorld());
|
||||
Location loc;
|
||||
if (PaperLib.isPaper()
|
||||
&& ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(entity.getWorld()))).usePaperEntityOrigin) {
|
||||
if (PaperLib.isPaper() && config.usePaperEntityOrigin) {
|
||||
loc = entity.getOrigin();
|
||||
if (loc == null) {
|
||||
// Origin world may be null, and thus a Location with a null world created, which cannot be adapted to a WorldEdit location
|
||||
if (loc == null || loc.getWorld() == null) {
|
||||
loc = entity.getLocation();
|
||||
}
|
||||
} else {
|
||||
loc = entity.getLocation();
|
||||
}
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(loc));
|
||||
} else if (rootCause instanceof Block) {
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(loc),
|
||||
config.useMaxPriorityAssociation);
|
||||
} else if (rootCause instanceof Block block) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(((Block) rootCause).getLocation()));
|
||||
Location loc = block.getLocation();
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(loc),
|
||||
getWorldConfig(loc.getWorld()).useMaxPriorityAssociation);
|
||||
} else {
|
||||
return Associables.constant(Association.NON_MEMBER);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import com.sk89q.worldguard.blacklist.event.ItemDestroyWithBlacklistEvent;
|
|||
import com.sk89q.worldguard.blacklist.event.ItemDropBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.event.ItemEquipBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.event.ItemUseBlacklistEvent;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
|
||||
|
@ -49,6 +50,7 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.BlockDispenseArmorEvent;
|
||||
import org.bukkit.event.block.BlockDispenseEvent;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCreativeEvent;
|
||||
|
@ -58,6 +60,7 @@ import org.bukkit.event.player.PlayerDropItemEvent;
|
|||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
|
||||
|
||||
|
@ -77,20 +80,19 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBreakBlock(final BreakBlockEvent event) {
|
||||
final Player player = event.getCause().getFirstPlayer();
|
||||
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
final WorldConfiguration wcfg = getWorldConfig(localPlayer);
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.filter(target -> {
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new BlockBreakBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target),
|
||||
|
@ -108,6 +110,12 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlaceBlock(final PlaceBlockEvent event) {
|
||||
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player == null) {
|
||||
|
@ -115,19 +123,18 @@ public class BlacklistListener extends AbstractListener {
|
|||
}
|
||||
|
||||
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
final WorldConfiguration wcfg = getWorldConfig(localPlayer);
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.filter(target -> wcfg.getBlacklist().check(new BlockPlaceBlacklistEvent(
|
||||
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock(), event.getEffectiveMaterial())), false, false));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseBlock(final UseBlockEvent event) {
|
||||
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player == null) {
|
||||
|
@ -135,33 +142,25 @@ public class BlacklistListener extends AbstractListener {
|
|||
}
|
||||
|
||||
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
final WorldConfiguration wcfg = getWorldConfig(localPlayer);
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.filter(target -> wcfg.getBlacklist().check(new BlockInteractBlacklistEvent(
|
||||
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock(), event.getEffectiveMaterial())), false, false));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSpawnEntity(SpawnEntityEvent event) {
|
||||
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
WorldConfiguration wcfg = getWorldConfig(localPlayer);
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
Material material = Materials.getRelatedMaterial(event.getEffectiveType());
|
||||
if (material != null) {
|
||||
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(
|
||||
|
@ -173,21 +172,20 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDestroyEntity(DestroyEntityEvent event) {
|
||||
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
Entity target = event.getEntity();
|
||||
WorldConfiguration wcfg = getWorldConfig(localPlayer);
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target instanceof Item) {
|
||||
Item item = (Item) target;
|
||||
if (!wcfg.getBlacklist().check(
|
||||
|
@ -210,21 +208,20 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseItem(UseItemEvent event) {
|
||||
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
ItemStack target = event.getItemStack();
|
||||
WorldConfiguration wcfg = getWorldConfig(localPlayer);
|
||||
|
||||
// Blacklist guard
|
||||
if (wcfg.getBlacklist() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(
|
||||
localPlayer, BukkitAdapter.asBlockVector(player.getLocation()), createTarget(target)), false, false)) {
|
||||
event.setCancelled(true);
|
||||
|
@ -239,8 +236,7 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getPlayer().getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getPlayer().getWorld());
|
||||
|
||||
if (wcfg.getBlacklist() != null) {
|
||||
Item ci = event.getItemDrop();
|
||||
|
@ -255,8 +251,7 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockDispense(BlockDispenseEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getBlock().getWorld()));
|
||||
BukkitWorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
|
||||
if (wcfg.getBlacklist() != null) {
|
||||
if (!wcfg.getBlacklist().check(new BlockDispenseBlacklistEvent(null, BukkitAdapter.asBlockVector(event.getBlock().getLocation()),
|
||||
|
@ -275,8 +270,7 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
if (item != null && inventory.getHolder() != null) {
|
||||
Player player = (Player) entity;
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
|
||||
|
@ -330,12 +324,16 @@ public class BlacklistListener extends AbstractListener {
|
|||
return cursor;
|
||||
}
|
||||
case HOTBAR_SWAP:
|
||||
if (event.getClick() == ClickType.SWAP_OFFHAND) {
|
||||
return clickedInventory == null ? null : ((PlayerInventory) clickedInventory).getItemInOffHand();
|
||||
}
|
||||
return clickedInventory == null ? null : clickedInventory.getItem(event.getHotbarButton());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER
|
||||
&& event.getView().getTopInventory().getType() == InventoryType.PLAYER
|
||||
&& (event.getView().getTopInventory().getType() == InventoryType.PLAYER
|
||||
|| event.getView().getTopInventory().getType() == InventoryType.CRAFTING)
|
||||
&& event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
|
||||
return event.getCurrentItem();
|
||||
}
|
||||
|
@ -349,8 +347,7 @@ public class BlacklistListener extends AbstractListener {
|
|||
|
||||
if (item.getType() != Material.AIR && entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
|
||||
|
@ -367,8 +364,7 @@ public class BlacklistListener extends AbstractListener {
|
|||
ItemStack item = inventory.getItem(event.getNewSlot());
|
||||
|
||||
if (item != null) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(player.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
|
||||
|
@ -384,8 +380,7 @@ public class BlacklistListener extends AbstractListener {
|
|||
Player player = ((Player) event.getTargetEntity());
|
||||
ItemStack stack = event.getItem();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(player.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
|
||||
new ItemEquipBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(player.getLocation()), createTarget(stack)), false, true)) {
|
||||
|
|
|
@ -19,14 +19,11 @@
|
|||
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.entity.DamageEntityEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Arrow;
|
||||
|
@ -38,6 +35,10 @@ import org.bukkit.inventory.ItemStack;
|
|||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles blocked potions.
|
||||
|
@ -53,51 +54,56 @@ public class BlockedPotionsListener extends AbstractListener {
|
|||
super(plugin);
|
||||
}
|
||||
|
||||
private PotionEffectType getBlockedEffectByArrow(Arrow arrow, BukkitWorldConfiguration wcfg) {
|
||||
List<PotionEffect> effects = new ArrayList<>();
|
||||
PotionType potionType = arrow.getBasePotionType();
|
||||
if (potionType != null) {
|
||||
effects.addAll(potionType.getPotionEffects());
|
||||
}
|
||||
effects.addAll(arrow.getCustomEffects());
|
||||
for (PotionEffect potionEffect : effects) {
|
||||
if (wcfg.blockPotions.contains(potionEffect.getType())) {
|
||||
return potionEffect.getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onProjectile(DamageEntityEvent event) {
|
||||
if (event.getOriginalEvent() instanceof EntityDamageByEntityEvent) {
|
||||
EntityDamageByEntityEvent originalEvent = (EntityDamageByEntityEvent) event.getOriginalEvent();
|
||||
if (Entities.isPotionArrow(originalEvent.getDamager())) { // should take care of backcompat
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
PotionEffectType blockedEffect = null;
|
||||
if (originalEvent.getDamager() instanceof SpectralArrow) {
|
||||
if (wcfg.blockPotions.contains(PotionEffectType.GLOWING)) {
|
||||
blockedEffect = PotionEffectType.GLOWING;
|
||||
}
|
||||
} else if (originalEvent.getDamager() instanceof Arrow) {
|
||||
Arrow tippedArrow = (Arrow) originalEvent.getDamager();
|
||||
PotionEffectType baseEffect = tippedArrow.getBasePotionData().getType().getEffectType();
|
||||
if (wcfg.blockPotions.contains(baseEffect)) {
|
||||
blockedEffect = baseEffect;
|
||||
} else {
|
||||
for (PotionEffect potionEffect : tippedArrow.getCustomEffects()) {
|
||||
if (wcfg.blockPotions.contains(potionEffect.getType())) {
|
||||
blockedEffect = potionEffect.getType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (blockedEffect != null) {
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
if (player != null) {
|
||||
if (getPlugin().hasPermission(player, "worldguard.override.potions")) {
|
||||
return;
|
||||
}
|
||||
player.sendMessage(ChatColor.RED + "Sorry, arrows with "
|
||||
+ blockedEffect.getName() + " are presently disabled.");
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (!(event.getOriginalEvent() instanceof EntityDamageByEntityEvent originalEvent)) {
|
||||
return;
|
||||
}
|
||||
if (!Entities.isPotionArrow(originalEvent.getDamager())) {
|
||||
return;
|
||||
}
|
||||
|
||||
BukkitWorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
PotionEffectType blockedEffect = null;
|
||||
if (originalEvent.getDamager() instanceof SpectralArrow) {
|
||||
if (wcfg.blockPotions.contains(PotionEffectType.GLOWING)) {
|
||||
blockedEffect = PotionEffectType.GLOWING;
|
||||
}
|
||||
} else if (originalEvent.getDamager() instanceof Arrow arrow) {
|
||||
blockedEffect = getBlockedEffectByArrow(arrow, wcfg);
|
||||
}
|
||||
if (blockedEffect != null) {
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
if (player != null) {
|
||||
if (getPlugin().hasPermission(player, "worldguard.override.potions")) {
|
||||
return;
|
||||
}
|
||||
player.sendMessage(ChatColor.RED + "Sorry, arrows with "
|
||||
+ blockedEffect.getName() + " are presently disabled.");
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onItemInteract(UseItemEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
BukkitWorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
ItemStack item = event.getItemStack();
|
||||
|
||||
if (item.getType() != Material.POTION
|
||||
|
@ -109,25 +115,20 @@ public class BlockedPotionsListener extends AbstractListener {
|
|||
if (!wcfg.blockPotions.isEmpty()) {
|
||||
PotionEffectType blockedEffect = null;
|
||||
|
||||
PotionMeta meta;
|
||||
if (item.getItemMeta() instanceof PotionMeta) {
|
||||
meta = ((PotionMeta) item.getItemMeta());
|
||||
} else {
|
||||
return; // ok...?
|
||||
if (!(item.getItemMeta() instanceof PotionMeta meta)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the first blocked effect
|
||||
PotionEffectType baseEffect = meta.getBasePotionData().getType().getEffectType();
|
||||
if (wcfg.blockPotions.contains(baseEffect)) {
|
||||
blockedEffect = baseEffect;
|
||||
List<PotionEffect> effects = new ArrayList<>();
|
||||
if (meta.getBasePotionType() != null) {
|
||||
effects.addAll(meta.getBasePotionType().getPotionEffects());
|
||||
}
|
||||
|
||||
if (blockedEffect == null && meta.hasCustomEffects()) {
|
||||
for (PotionEffect effect : meta.getCustomEffects()) {
|
||||
if (wcfg.blockPotions.contains(effect.getType())) {
|
||||
blockedEffect = effect.getType();
|
||||
break;
|
||||
}
|
||||
effects.addAll(meta.getCustomEffects());
|
||||
for (PotionEffect potionEffect : effects) {
|
||||
if (wcfg.blockPotions.contains(potionEffect.getType())) {
|
||||
blockedEffect = potionEffect.getType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
|
||||
|
@ -52,7 +51,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
}
|
||||
|
||||
private void tellErrorMessage(CommandSender sender, World world) {
|
||||
String message = getWorldConfig(BukkitAdapter.adapt(world)).buildPermissionDenyMessage;
|
||||
String message = getWorldConfig(world).buildPermissionDenyMessage;
|
||||
if (!message.isEmpty()) {
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
@ -60,7 +59,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlaceBlock(final PlaceBlockEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
@ -78,7 +77,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBreakBlock(final BreakBlockEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
@ -96,7 +95,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseBlock(final UseBlockEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
@ -114,7 +113,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSpawnEntity(SpawnEntityEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
@ -132,7 +131,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDestroyEntity(DestroyEntityEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
@ -150,7 +149,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseEntity(UseEntityEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
@ -168,7 +167,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDamageEntity(DamageEntityEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
@ -186,7 +185,7 @@ public class BuildPermissionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseItem(UseItemEvent event) {
|
||||
if (!getWorldConfig(BukkitAdapter.adapt(event.getWorld())).buildPermissions) return;
|
||||
if (!getWorldConfig(event.getWorld()).buildPermissions) return;
|
||||
|
||||
Object rootCause = event.getCause().getRootCause();
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public class ChestProtectionListener extends AbstractListener {
|
|||
final Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player != null) {
|
||||
final BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) getWorldConfig(WorldGuardPlugin.inst().wrapPlayer(player));
|
||||
final BukkitWorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Early guard
|
||||
if (!wcfg.signChestProtection) {
|
||||
|
@ -82,7 +82,7 @@ public class ChestProtectionListener extends AbstractListener {
|
|||
public void onBreakBlock(final BreakBlockEvent event) {
|
||||
final Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
final BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(event.getWorld()));
|
||||
final BukkitWorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Early guard
|
||||
if (!wcfg.signChestProtection) {
|
||||
|
@ -108,7 +108,7 @@ public class ChestProtectionListener extends AbstractListener {
|
|||
public void onUseBlock(final UseBlockEvent event) {
|
||||
final Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
final BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(event.getWorld()));
|
||||
final BukkitWorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
// Early guard
|
||||
if (!wcfg.signChestProtection) {
|
||||
|
@ -133,7 +133,7 @@ public class ChestProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) getWorldConfig(WorldGuardPlugin.inst().wrapPlayer(player));
|
||||
final BukkitWorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
|
||||
if (wcfg.signChestProtection) {
|
||||
if ("[Lock]".equalsIgnoreCase(event.getLine(0))) {
|
||||
|
|
|
@ -21,9 +21,7 @@ package com.sk89q.worldguard.bukkit.listener;
|
|||
|
||||
import static com.sk89q.worldguard.bukkit.cause.Cause.create;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
import com.destroystokyo.paper.event.entity.EntityZapEvent;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.cause.Cause;
|
||||
import com.sk89q.worldguard.bukkit.event.DelegateEvent;
|
||||
|
@ -48,11 +46,14 @@ import com.sk89q.worldguard.bukkit.util.Events;
|
|||
import com.sk89q.worldguard.bukkit.util.Materials;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import io.papermc.paper.event.player.PlayerOpenSignEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
@ -61,6 +62,7 @@ import org.bukkit.block.Chest;
|
|||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.block.PistonMoveReaction;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.Dispenser;
|
||||
import org.bukkit.entity.AreaEffectCloud;
|
||||
|
@ -72,14 +74,17 @@ import org.bukkit.entity.Firework;
|
|||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.entity.Painting;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.ThrownPotion;
|
||||
import org.bukkit.entity.minecart.HopperMinecart;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
|
@ -94,6 +99,7 @@ import org.bukkit.event.block.BlockMultiPlaceEvent;
|
|||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.CauldronLevelChangeEvent;
|
||||
import org.bukkit.event.block.EntityBlockFormEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
|
||||
|
@ -108,6 +114,7 @@ import org.bukkit.event.entity.EntityDamageEvent;
|
|||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityInteractEvent;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.entity.EntityTameEvent;
|
||||
import org.bukkit.event.entity.EntityUnleashEvent;
|
||||
import org.bukkit.event.entity.ExpBottleEvent;
|
||||
|
@ -137,6 +144,8 @@ import org.bukkit.event.world.StructureGrowEvent;
|
|||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
|
@ -163,6 +172,17 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvents() {
|
||||
super.registerEvents();
|
||||
|
||||
if (PaperLib.isPaper()) {
|
||||
PluginManager pm = getPlugin().getServer().getPluginManager();
|
||||
pm.registerEvents(new EventAbstractionListener.PaperListener(), getPlugin());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Block break / place
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -228,7 +248,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
boolean allowed = false;
|
||||
|
||||
for (Block source : adjacent) {
|
||||
if (source.getType() == Material.FIRE) {
|
||||
if (Materials.isFire(source.getType())) {
|
||||
found++;
|
||||
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(source), target))) {
|
||||
source.setType(Material.AIR);
|
||||
|
@ -257,6 +277,42 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
}
|
||||
}
|
||||
|
||||
private void handleFallingBlock(EntityChangeBlockEvent event, boolean dropItem) {
|
||||
Entity entity = event.getEntity();
|
||||
Block block = event.getBlock();
|
||||
|
||||
if (entity instanceof FallingBlock) {
|
||||
try {
|
||||
if (dropItem) {
|
||||
FallingBlock fallingBlock = (FallingBlock) entity;
|
||||
if (!fallingBlock.getDropItem()) return;
|
||||
final Material material = fallingBlock.getBlockData().getMaterial();
|
||||
if (!material.isItem()) return;
|
||||
ItemStack itemStack = new ItemStack(material, 1);
|
||||
Item item = block.getWorld().dropItem(fallingBlock.getLocation(), itemStack);
|
||||
item.setVelocity(new Vector());
|
||||
if (Events.fireAndTestCancel(new SpawnEntityEvent(event, create(block, entity), item))) {
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Cause.untrackParentCause(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setDelegateEventMaterialOptions(DelegateEvent event, Material fromType, Material toType) {
|
||||
if (fromType == Material.FARMLAND && toType == Material.DIRT) {
|
||||
event.setSilent(true);
|
||||
event.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
} else if (Tag.REDSTONE_ORES.isTagged(fromType)) {
|
||||
event.setSilent(true);
|
||||
} else if (fromType == Material.BIG_DRIPLEAF && toType == Material.BIG_DRIPLEAF) {
|
||||
event.setSilent(true);
|
||||
event.getRelevantFlags().add(Flags.USE_DRIPLEAF);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
||||
Block block = event.getBlock();
|
||||
|
@ -267,54 +323,44 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
// Fire two events: one as BREAK and one as PLACE
|
||||
if (toType != Material.AIR && fromType != Material.AIR) {
|
||||
boolean trample = fromType == Material.FARMLAND && toType == Material.DIRT;
|
||||
BreakBlockEvent breakDelagate = new BreakBlockEvent(event, cause, block);
|
||||
if (trample) {
|
||||
breakDelagate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
}
|
||||
if (!Events.fireToCancel(event, breakDelagate)) {
|
||||
setDelegateEventMaterialOptions(breakDelagate, fromType, toType);
|
||||
boolean denied;
|
||||
if (!(denied = Events.fireToCancel(event, breakDelagate))) {
|
||||
PlaceBlockEvent placeDelegate = new PlaceBlockEvent(event, cause, block.getLocation(), toType);
|
||||
if (trample) {
|
||||
placeDelegate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
}
|
||||
Events.fireToCancel(event, placeDelegate);
|
||||
setDelegateEventMaterialOptions(placeDelegate, fromType, toType);
|
||||
denied = Events.fireToCancel(event, placeDelegate);
|
||||
}
|
||||
if (denied && entity instanceof Player) {
|
||||
playDenyEffect((Player) entity, block.getLocation());
|
||||
}
|
||||
} else {
|
||||
if (toType == Material.AIR) {
|
||||
// Track the source so later we can create a proper chain of causes
|
||||
if (entity instanceof FallingBlock) {
|
||||
Cause.trackParentCause(entity, block);
|
||||
|
||||
// Switch around the event
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, create(block), entity));
|
||||
} else {
|
||||
entityBreakBlockDebounce.debounce(
|
||||
block, event.getEntity(), event, new BreakBlockEvent(event, cause, block));
|
||||
}
|
||||
handleFallingBlock(event, denied);
|
||||
} else if (toType == Material.AIR) {
|
||||
// Track the source so later we can create a proper chain of causes
|
||||
if (entity instanceof FallingBlock) {
|
||||
Cause.trackParentCause(entity, block);
|
||||
|
||||
// Switch around the event
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, create(block), entity));
|
||||
} else {
|
||||
boolean wasCancelled = event.isCancelled();
|
||||
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, block.getLocation(), toType));
|
||||
|
||||
if (event.isCancelled() && !wasCancelled && entity instanceof FallingBlock) {
|
||||
FallingBlock fallingBlock = (FallingBlock) entity;
|
||||
final Material material = fallingBlock.getBlockData().getMaterial();
|
||||
if (!material.isItem()) return;
|
||||
ItemStack itemStack = new ItemStack(material, 1);
|
||||
Item item = block.getWorld().dropItem(fallingBlock.getLocation(), itemStack);
|
||||
item.setVelocity(new Vector());
|
||||
if (Events.fireAndTestCancel(new SpawnEntityEvent(event, create(block, entity), item))) {
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
entityBreakBlockDebounce.debounce(
|
||||
block, event.getEntity(), event, new BreakBlockEvent(event, cause, block));
|
||||
}
|
||||
} else { // toType != Material.AIR && fromType == Material.AIR
|
||||
boolean denied = Events.fireToCancel(event, new PlaceBlockEvent(event, cause, block.getLocation(), toType));
|
||||
handleFallingBlock(event, denied);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, create(entity), event.getLocation().getWorld(), event.blockList(), Material.AIR));
|
||||
if (entity instanceof Creeper) {
|
||||
Cause.untrackParentCause(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
|
@ -332,6 +378,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, cause, event.getBlock().getWorld(), blocks, Material.AIR));
|
||||
if (originalSize != blocks.size()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
for (Block b : blocks) {
|
||||
Location loc = b.getRelative(direction).getLocation();
|
||||
|
@ -351,17 +398,24 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
|
||||
EventDebounce.Entry entry = pistonExtendDebounce.getIfNotPresent(new BlockPistonExtendKey(event), event);
|
||||
if (entry != null) {
|
||||
Cause cause = create(event.getBlock());
|
||||
List<Block> blocks = new ArrayList<>(event.getBlocks());
|
||||
int originalLength = blocks.size();
|
||||
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, cause, event.getBlock().getWorld(), blocks, Material.AIR));
|
||||
if (originalLength != blocks.size()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
BlockFace dir = event.getDirection();
|
||||
for (int i = 0; i < blocks.size(); i++) {
|
||||
Block existing = blocks.get(i);
|
||||
if (existing.getPistonMoveReaction() == PistonMoveReaction.MOVE
|
||||
|| existing.getPistonMoveReaction() == PistonMoveReaction.PUSH_ONLY) {
|
||||
|| existing.getPistonMoveReaction() == PistonMoveReaction.PUSH_ONLY
|
||||
|| existing.getType() == Material.PISTON || existing.getType() == Material.STICKY_PISTON) {
|
||||
blocks.set(i, existing.getRelative(dir));
|
||||
}
|
||||
}
|
||||
Events.fireBulkEventToCancel(event, new PlaceBlockEvent(event, create(event.getBlock()), event.getBlock().getWorld(), blocks, Material.STONE));
|
||||
Events.fireBulkEventToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getWorld(), blocks, Material.STONE));
|
||||
if (blocks.size() != originalLength) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
@ -394,23 +448,43 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
@Nullable ItemStack item = event.getItem();
|
||||
Block clicked = event.getClickedBlock();
|
||||
Block placed;
|
||||
boolean silent = false;
|
||||
boolean modifiesWorld;
|
||||
Cause cause = create(player);
|
||||
|
||||
switch (event.getAction()) {
|
||||
case PHYSICAL:
|
||||
if (event.useInteractedBlock() != Result.DENY) {
|
||||
if (clicked.getType() == Material.FARMLAND ||
|
||||
clicked.getType() == Material.TURTLE_EGG ||
|
||||
clicked.getType() == Material.SNIFFER_EGG) {
|
||||
BreakBlockEvent breakDelagate = new BreakBlockEvent(event, cause, clicked);
|
||||
breakDelagate.setSilent(true);
|
||||
breakDelagate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
boolean denied;
|
||||
if (!(denied = Events.fireToCancel(event, breakDelagate))) {
|
||||
PlaceBlockEvent placeDelegate = new PlaceBlockEvent(event, cause, clicked.getLocation(),
|
||||
clicked.getType() == Material.FARMLAND ? Material.DIRT : clicked.getType());
|
||||
placeDelegate.setSilent(true);
|
||||
placeDelegate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
denied = Events.fireToCancel(event, placeDelegate);
|
||||
}
|
||||
if (denied) {
|
||||
playDenyEffect(player, clicked.getLocation());
|
||||
}
|
||||
return;
|
||||
}
|
||||
DelegateEvent firedEvent = new UseBlockEvent(event, cause, clicked).setAllowed(hasInteractBypass(clicked));
|
||||
if (clicked.getType() == Material.REDSTONE_ORE) {
|
||||
silent = true;
|
||||
if (Tag.REDSTONE_ORES.isTagged(clicked.getType())) {
|
||||
firedEvent.setSilent(true);
|
||||
}
|
||||
if (clicked.getType() == Material.FARMLAND || clicked.getType() == Material.TURTLE_EGG) {
|
||||
silent = true;
|
||||
firedEvent.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
if (clicked.getType() == Material.BIG_DRIPLEAF) {
|
||||
firedEvent.getRelevantFlags().add(Flags.USE_DRIPLEAF);
|
||||
firedEvent.setSilent(true);
|
||||
}
|
||||
firedEvent.setSilent(silent);
|
||||
interactDebounce.debounce(clicked, event.getPlayer(), event, firedEvent);
|
||||
if (event.useInteractedBlock() == Result.DENY && !firedEvent.isSilent()) {
|
||||
playDenyEffect(player, clicked.getLocation().add(0, 1, 0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -452,7 +526,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
}
|
||||
|
||||
// Special handling of putting out fires
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK && placed.getType() == Material.FIRE) {
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK && Materials.isFire(placed.getType())) {
|
||||
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(event.getPlayer()), placed))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
break;
|
||||
|
@ -476,7 +550,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
// emit a "use block here" event where the player is
|
||||
// standing, which is a hack to protect items that don't
|
||||
// throw events
|
||||
if (item != null && ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(player.getWorld()))).blockUseAtFeet.test(item)) {
|
||||
if (item != null && getWorldConfig(player.getWorld()).blockUseAtFeet.test(item)) {
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, cause, player.getLocation().getBlock()))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
}
|
||||
|
@ -502,6 +576,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockFertilize(BlockFertilizeEvent event) {
|
||||
if (event.getBlocks().isEmpty()) return;
|
||||
Cause cause = create(event.getPlayer(), event.getBlock());
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getWorld(), event.getBlocks()));
|
||||
}
|
||||
|
@ -527,9 +602,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), event.getBlock()));
|
||||
|
||||
if (event.isCancelled()) {
|
||||
if (Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getPlayer()), event.getBlock()))) {
|
||||
playDenyEffect(event.getPlayer(), event.getBlock().getLocation().add(0.5, 0.5, 0.5));
|
||||
}
|
||||
}
|
||||
|
@ -596,7 +669,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockFromTo(BlockFromToEvent event) {
|
||||
WorldConfiguration config = getWorldConfig(BukkitAdapter.adapt(event.getBlock().getWorld()));
|
||||
WorldConfiguration config = getWorldConfig(event.getBlock().getWorld());
|
||||
|
||||
// This only applies to regions but nothing else cares about high
|
||||
// frequency events at the moment
|
||||
|
@ -642,7 +715,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
case DISPENSE_EGG:
|
||||
case EGG:
|
||||
case SPAWNER_EGG:
|
||||
if (getWorldConfig(BukkitAdapter.adapt(event.getEntity().getWorld())).strictEntitySpawn) {
|
||||
if (getWorldConfig(event.getEntity().getWorld()).strictEntitySpawn) {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, Cause.unknown(), event.getEntity()));
|
||||
}
|
||||
break;
|
||||
|
@ -703,7 +776,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
event.setCancelled(true);
|
||||
}
|
||||
} else if (event.getState() == PlayerFishEvent.State.CAUGHT_FISH) {
|
||||
if (Events.fireAndTestCancel(new SpawnEntityEvent(event, create(event.getPlayer(), event.getHook()), event.getHook().getLocation(), EntityType.EXPERIENCE_ORB))) {
|
||||
if (event.getExpToDrop() > 0 && Events.fireAndTestCancel(new SpawnEntityEvent(event, create(event.getPlayer(), event.getHook()), event.getHook().getLocation(), EntityType.EXPERIENCE_ORB))) {
|
||||
event.setExpToDrop(0);
|
||||
}
|
||||
} else if (event.getState() == PlayerFishEvent.State.CAUGHT_ENTITY) {
|
||||
|
@ -792,7 +865,11 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
} else if (damager instanceof Creeper) {
|
||||
eventToFire.getRelevantFlags().add(Flags.CREEPER_EXPLOSION);
|
||||
}
|
||||
Events.fireToCancel(event, eventToFire);
|
||||
if (Events.fireToCancel(event, eventToFire)) {
|
||||
if (damager instanceof Tameable && damager instanceof Mob) {
|
||||
((Mob) damager).setTarget(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Item use event with the item in hand
|
||||
// Older blacklist handler code used this, although it suffers from
|
||||
|
@ -843,6 +920,12 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
pickupDebounce.debounce(event.getPlayer(), item, event, new DestroyEntityEvent(event, create(event.getPlayer()), event.getItem()));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityPickupItem(EntityPickupItemEvent event) {
|
||||
Item item = event.getItem();
|
||||
pickupDebounce.debounce(event.getEntity(), item, event, new DestroyEntityEvent(event, create(event.getEntity()), event.getItem()));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, create(event.getPlayer()), event.getItemDrop()));
|
||||
|
@ -873,21 +956,23 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryMoveItem(InventoryMoveItemEvent event) {
|
||||
final InventoryHolder causeHolder = event.getInitiator().getHolder();
|
||||
InventoryHolder causeHolder = PaperLib.getHolder(event.getInitiator(), false).getHolder();
|
||||
|
||||
WorldConfiguration wcfg = null;
|
||||
if (causeHolder instanceof Hopper
|
||||
&& getWorldConfig(BukkitAdapter.adapt((((Hopper) causeHolder).getWorld()))).ignoreHopperMoveEvents) {
|
||||
&& (wcfg = getWorldConfig((((Hopper) causeHolder).getWorld()))).ignoreHopperMoveEvents) {
|
||||
return;
|
||||
} else if (causeHolder instanceof HopperMinecart
|
||||
&& getWorldConfig(BukkitAdapter.adapt((((HopperMinecart) causeHolder).getWorld()))).ignoreHopperMoveEvents) {
|
||||
&& (wcfg = getWorldConfig((((HopperMinecart) causeHolder).getWorld()))).ignoreHopperMoveEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entry entry;
|
||||
|
||||
if ((entry = moveItemDebounce.tryDebounce(event)) != null) {
|
||||
InventoryHolder sourceHolder = event.getSource().getHolder();
|
||||
InventoryHolder targetHolder = event.getDestination().getHolder();
|
||||
InventoryHolder sourceHolder = PaperLib.getHolder(event.getSource(), false).getHolder();
|
||||
InventoryHolder targetHolder = PaperLib.getHolder(event.getDestination(), false).getHolder();
|
||||
|
||||
Cause cause;
|
||||
|
||||
if (causeHolder instanceof Entity) {
|
||||
|
@ -904,7 +989,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
handleInventoryHolderUse(event, cause, targetHolder);
|
||||
|
||||
if (event.isCancelled() && causeHolder instanceof Hopper) {
|
||||
if (event.isCancelled() && causeHolder instanceof Hopper && wcfg.breakDeniedHoppers) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(),
|
||||
() -> ((Hopper) causeHolder).getBlock().breakNaturally());
|
||||
} else {
|
||||
|
@ -943,7 +1028,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
}
|
||||
}
|
||||
|
||||
if (blocked == affectedSize) { // server does weird things with this if the event is modified, so use cached number
|
||||
if (affectedSize > 0 && blocked == affectedSize) { // server does weird things with this if the event is modified, so use cached number
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -951,18 +1036,32 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockDispense(BlockDispenseEvent event) {
|
||||
Cause cause = create(event.getBlock());
|
||||
Block dispenserBlock = event.getBlock();
|
||||
ItemStack item = event.getItem();
|
||||
|
||||
Events.fireToCancel(event, new UseItemEvent(event, cause, dispenserBlock.getWorld(), item));
|
||||
|
||||
// Simulate right click event as players have it
|
||||
if (dispenserBlock.getBlockData() instanceof Dispenser) {
|
||||
Dispenser dispenser = (Dispenser) dispenserBlock.getBlockData();
|
||||
if (dispenserBlock.getType() == Material.DISPENSER) {
|
||||
Cause cause = create(event.getBlock());
|
||||
ItemStack item = event.getItem();
|
||||
if (Events.fireToCancel(event, new UseItemEvent(event, cause, dispenserBlock.getWorld(), item))) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockData blockData = dispenserBlock.getBlockData();
|
||||
Dispenser dispenser = (Dispenser) blockData; // if this ClassCastExceptions it's a bukkit bug
|
||||
Block placed = dispenserBlock.getRelative(dispenser.getFacing());
|
||||
Block clicked = placed.getRelative(dispenser.getFacing());
|
||||
handleBlockRightClick(event, cause, item, clicked, placed);
|
||||
|
||||
// handle special dispenser behavior
|
||||
if (Materials.isShulkerBox(item.getType())) {
|
||||
if (Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(), item.getType()))) {
|
||||
playDenyEffect(placed.getLocation());
|
||||
}
|
||||
} else if (isItemAppliedToBlock(item, placed)) {
|
||||
if (Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(), placed.getType()))) {
|
||||
playDenyEffect(placed.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -985,7 +1084,16 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onLingeringApply(AreaEffectCloudApplyEvent event) {
|
||||
if (!Materials.hasDamageEffect(event.getEntity().getCustomEffects())) {
|
||||
AreaEffectCloud entity = event.getEntity();
|
||||
List<PotionEffect> effects = new ArrayList<>();
|
||||
List<PotionEffect> baseEffectTypes = entity.getBasePotionType() == null ? null : entity.getBasePotionType().getPotionEffects();
|
||||
if (baseEffectTypes != null) {
|
||||
effects.addAll(baseEffectTypes);
|
||||
}
|
||||
if (entity.hasCustomEffects()) {
|
||||
effects.addAll(entity.getCustomEffects());
|
||||
}
|
||||
if (!Materials.hasDamageEffect(effects)) {
|
||||
return;
|
||||
}
|
||||
Cause cause = create(event.getEntity());
|
||||
|
@ -1009,10 +1117,17 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onTakeLecternBook(PlayerTakeLecternBookEvent event) {
|
||||
final UseBlockEvent useEvent = new UseBlockEvent(event, create(event.getPlayer()), event.getLectern().getBlock());
|
||||
useEvent.getRelevantFlags().add(Flags.CHEST_ACCESS);
|
||||
Events.fireToCancel(event, useEvent);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onCauldronLevelChange(CauldronLevelChangeEvent event) {
|
||||
if (event.getEntity() == null) return;
|
||||
interactDebounce.debounce(event.getBlock(), event.getEntity(), event,
|
||||
new UseBlockEvent(event, create(event.getEntity()),
|
||||
event.getBlock()).setAllowed(hasInteractBypass(event.getBlock())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the right click of a block while an item is held.
|
||||
*
|
||||
|
@ -1058,13 +1173,23 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
if (item != null && item.getType() == Material.END_CRYSTAL) { /*&& placed.getType() == Material.BEDROCK) {*/ // in vanilla you can only place them on bedrock but who knows what plugins will add
|
||||
// may be overprotective as a result, but better than being underprotective
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.ENDER_CRYSTAL));
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.END_CRYSTAL));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle created spawn eggs
|
||||
if (item != null && Materials.isSpawnEgg(item.getType())) {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), Materials.getEntitySpawnEgg(item.getType())));
|
||||
if (item != null) {
|
||||
EntityType possibleEntityType = Materials.getEntitySpawnEgg(item.getType());
|
||||
if (possibleEntityType != null) {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), possibleEntityType));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// handle water/lava placement
|
||||
if (item != null && (item.getType() == Material.WATER_BUCKET || item.getType() == Material.LAVA_BUCKET)) {
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, placed.getLocation(),
|
||||
item.getType() == Material.WATER_BUCKET ? Material.WATER : Material.LAVA));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1074,8 +1199,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (holder instanceof Entity) {
|
||||
Entity entity = (Entity) holder;
|
||||
if (holder instanceof Entity entity) {
|
||||
Material mat = Materials.getRelatedMaterial((entity).getType());
|
||||
UseEntityEvent useEntityEvent = new UseEntityEvent(originalEvent, cause, entity);
|
||||
if (mat != null && hasInteractBypass((entity).getWorld(), mat)) {
|
||||
|
@ -1083,8 +1207,7 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
}
|
||||
Events.fireToCancel(originalEvent, useEntityEvent);
|
||||
} else {
|
||||
if (holder instanceof BlockState) {
|
||||
final BlockState block = (BlockState) holder;
|
||||
if (holder instanceof BlockState block && block.isPlaced()) {
|
||||
final UseBlockEvent useBlockEvent = new UseBlockEvent(originalEvent, cause, block.getBlock());
|
||||
if (hasInteractBypass(block.getWorld(), block.getType())) {
|
||||
useBlockEvent.setAllowed(true);
|
||||
|
@ -1104,15 +1227,15 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
}
|
||||
|
||||
private static boolean hasInteractBypass(Block block) {
|
||||
return ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(block.getWorld()))).allowAllInteract.test(block);
|
||||
return getWorldConfig(block.getWorld()).allowAllInteract.test(block);
|
||||
}
|
||||
|
||||
private static boolean hasInteractBypass(World world, Material material) {
|
||||
return ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(world))).allowAllInteract.test(material);
|
||||
return getWorldConfig(world).allowAllInteract.test(material);
|
||||
}
|
||||
|
||||
private static boolean hasInteractBypass(World world, ItemStack item) {
|
||||
return ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(world))).allowAllInteract.test(item);
|
||||
return getWorldConfig(world).allowAllInteract.test(item);
|
||||
}
|
||||
|
||||
private static boolean isBlockModifiedOnClick(Block block, boolean rightClick) {
|
||||
|
@ -1127,15 +1250,29 @@ public class EventAbstractionListener extends AbstractListener {
|
|||
|
||||
private static void playDenyEffect(Player player, Location location) {
|
||||
//player.playSound(location, Sound.SUCCESSFUL_HIT, 0.2f, 0.4f);
|
||||
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().particleEffects) {
|
||||
if (getConfig().particleEffects) {
|
||||
player.playEffect(location, Effect.SMOKE, BlockFace.UP);
|
||||
}
|
||||
}
|
||||
|
||||
private static void playDenyEffect(Location location) {
|
||||
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().particleEffects) {
|
||||
if (getConfig().particleEffects) {
|
||||
location.getWorld().playEffect(location, Effect.SMOKE, BlockFace.UP);
|
||||
}
|
||||
}
|
||||
|
||||
private class PaperListener implements Listener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityTransform(EntityZapEvent event) {
|
||||
Events.fireToCancel(event, new DamageEntityEvent(event, create(event.getBolt()), event.getEntity()));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSignOpen(PlayerOpenSignEvent event) {
|
||||
if (event.getCause() == PlayerOpenSignEvent.Cause.INTERACT) {
|
||||
// other cases are handled by other events
|
||||
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), event.getSign().getBlock()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -59,14 +58,11 @@ public class InvincibilityListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
Entity victim = event.getEntity();
|
||||
if (Entities.isNPC(victim)) return;
|
||||
|
||||
if (victim instanceof Player) {
|
||||
Player player = (Player) victim;
|
||||
if (victim instanceof Player player) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
|
||||
BukkitWorldConfiguration worldConfig =
|
||||
(BukkitWorldConfiguration) WorldGuard.getInstance().getPlatform().getGlobalStateManager().get((World) localPlayer.getExtent());
|
||||
|
||||
if (isInvincible(localPlayer)) {
|
||||
player.setFireTicks(0);
|
||||
event.setCancelled(true);
|
||||
|
@ -79,7 +75,7 @@ public class InvincibilityListener extends AbstractListener {
|
|||
attacker = (Entity) ((Projectile) attacker).getShooter();
|
||||
}
|
||||
|
||||
if (worldConfig.regionInvinciblityRemovesMobs
|
||||
if (getWorldConfig(player.getWorld()).regionInvinciblityRemovesMobs
|
||||
&& attacker instanceof LivingEntity && !(attacker instanceof Player)
|
||||
&& !(attacker instanceof Tameable && ((Tameable) attacker).isTamed())) {
|
||||
attacker.remove();
|
||||
|
@ -92,9 +88,9 @@ public class InvincibilityListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityCombust(EntityCombustEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (Entities.isNPC(entity)) return;
|
||||
|
||||
if (entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
if (entity instanceof Player player) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
|
||||
if (isInvincible(localPlayer)) {
|
||||
|
@ -105,8 +101,9 @@ public class InvincibilityListener extends AbstractListener {
|
|||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
||||
if (event.getEntity() instanceof Player) {
|
||||
Player player = (Player) event.getEntity();
|
||||
if (Entities.isNPC(event.getEntity())) return;
|
||||
|
||||
if (event.getEntity() instanceof Player player) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
|
||||
if (event.getFoodLevel() < player.getFoodLevel() && isInvincible(localPlayer)) {
|
||||
|
|
|
@ -27,37 +27,37 @@ import com.sk89q.worldguard.session.MoveType;
|
|||
import com.sk89q.worldguard.session.Session;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityMountEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.vehicle.VehicleEnterEvent;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class PlayerMoveListener implements Listener {
|
||||
|
||||
private final WorldGuardPlugin plugin;
|
||||
public class PlayerMoveListener extends AbstractListener {
|
||||
|
||||
public PlayerMoveListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvents() {
|
||||
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().usePlayerMove) {
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvents(this, plugin);
|
||||
PluginManager pm = getPlugin().getServer().getPluginManager();
|
||||
pm.registerEvents(this, getPlugin());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerRespawn(PlayerRespawnEvent event) {
|
||||
LocalPlayer player = plugin.wrapPlayer(event.getPlayer());
|
||||
LocalPlayer player = getPlugin().wrapPlayer(event.getPlayer());
|
||||
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
|
||||
session.testMoveTo(player, BukkitAdapter.adapt(event.getRespawnLocation()), MoveType.RESPAWN, true);
|
||||
|
@ -67,7 +67,7 @@ public class PlayerMoveListener implements Listener {
|
|||
public void onVehicleEnter(VehicleEnterEvent event) {
|
||||
Entity entity = event.getEntered();
|
||||
if (entity instanceof Player) {
|
||||
LocalPlayer player = plugin.wrapPlayer((Player) entity);
|
||||
LocalPlayer player = getPlugin().wrapPlayer((Player) entity);
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
|
||||
if (null != session.testMoveTo(player, BukkitAdapter.adapt(event.getVehicle().getLocation()), MoveType.EMBARK, true)) {
|
||||
event.setCancelled(true);
|
||||
|
@ -77,8 +77,16 @@ public class PlayerMoveListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
Location from = event.getFrom();
|
||||
Location to = event.getTo();
|
||||
if (from.getBlockX() == to.getBlockX()
|
||||
&& from.getBlockY() == to.getBlockY()
|
||||
&& from.getBlockZ() == to.getBlockZ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer);
|
||||
MoveType moveType = MoveType.MOVE;
|
||||
|
@ -86,18 +94,18 @@ public class PlayerMoveListener implements Listener {
|
|||
moveType = MoveType.GLIDE;
|
||||
} else if (event.getPlayer().isSwimming()) {
|
||||
moveType = MoveType.SWIM;
|
||||
} else if (event.getPlayer().getVehicle() != null && event.getPlayer().getVehicle() instanceof Horse) {
|
||||
} else if (event.getPlayer().getVehicle() != null && event.getPlayer().getVehicle() instanceof AbstractHorse) {
|
||||
moveType = MoveType.RIDE;
|
||||
}
|
||||
com.sk89q.worldedit.util.Location weLocation = session.testMoveTo(localPlayer, BukkitAdapter.adapt(event.getTo()), moveType);
|
||||
com.sk89q.worldedit.util.Location weLocation = session.testMoveTo(localPlayer, BukkitAdapter.adapt(to), moveType);
|
||||
|
||||
if (weLocation != null) {
|
||||
final Location override = BukkitAdapter.adapt(weLocation);
|
||||
override.setX(override.getBlockX() + 0.5);
|
||||
override.setY(override.getBlockY());
|
||||
override.setZ(override.getBlockZ() + 0.5);
|
||||
override.setPitch(event.getTo().getPitch());
|
||||
override.setYaw(event.getTo().getYaw());
|
||||
override.setPitch(to.getPitch());
|
||||
override.setYaw(to.getYaw());
|
||||
|
||||
event.setTo(override.clone());
|
||||
|
||||
|
@ -119,9 +127,35 @@ public class PlayerMoveListener implements Listener {
|
|||
|
||||
player.teleport(override.clone().add(0, 1, 0));
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> player.teleport(override.clone().add(0, 1, 0)), 1);
|
||||
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> player.teleport(override.clone().add(0, 1, 0)), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer);
|
||||
com.sk89q.worldedit.util.Location loc = session.testMoveTo(localPlayer,
|
||||
BukkitAdapter.adapt(event.getPlayer().getLocation()), MoveType.OTHER_CANCELLABLE); // white lie
|
||||
if (loc != null) {
|
||||
player.teleport(BukkitAdapter.adapt(loc));
|
||||
}
|
||||
|
||||
session.uninitialize(localPlayer);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityMount(EntityMountEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity instanceof Player) {
|
||||
LocalPlayer player = getPlugin().wrapPlayer((Player) entity);
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
|
||||
if (null != session.testMoveTo(player, BukkitAdapter.adapt(event.getMount().getLocation()), MoveType.EMBARK, true)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.sk89q.worldguard.WorldGuard;
|
|||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.bukkit.util.Materials;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
|
@ -57,8 +58,7 @@ public class RegionFlagsListener extends AbstractListener {
|
|||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlaceBlock(final PlaceBlockEvent event) {
|
||||
com.sk89q.worldedit.world.World weWorld = BukkitAdapter.adapt(event.getWorld());
|
||||
if (!isRegionSupportEnabled(weWorld)) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class RegionFlagsListener extends AbstractListener {
|
|||
}
|
||||
}
|
||||
|
||||
if (event.getCause().find(EntityType.SNOWMAN) != null) {
|
||||
if (event.getCause().find(EntityType.SNOW_GOLEM) != null) {
|
||||
event.filter(testState(query, Flags.SNOWMAN_TRAILS), false);
|
||||
}
|
||||
|
||||
|
@ -80,10 +80,9 @@ public class RegionFlagsListener extends AbstractListener {
|
|||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onBreakBlock(final BreakBlockEvent event) {
|
||||
com.sk89q.worldedit.world.World weWorld = BukkitAdapter.adapt(event.getWorld());
|
||||
if (!isRegionSupportEnabled(weWorld)) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
|
||||
WorldConfiguration config = getWorldConfig(weWorld);
|
||||
WorldConfiguration config = getWorldConfig(event.getWorld());
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
|
||||
Block block;
|
||||
|
@ -101,7 +100,7 @@ public class RegionFlagsListener extends AbstractListener {
|
|||
event.filter(testState(query, Flags.ENDERDRAGON_BLOCK_DAMAGE), config.explosionFlagCancellation);
|
||||
}
|
||||
|
||||
if (event.getCause().find(EntityType.ENDER_CRYSTAL) != null) { // EnderCrystal
|
||||
if (event.getCause().find(EntityType.END_CRYSTAL) != null) { // EnderCrystal
|
||||
event.filter(testState(query, Flags.OTHER_EXPLOSION), config.explosionFlagCancellation);
|
||||
}
|
||||
|
||||
|
@ -118,26 +117,26 @@ public class RegionFlagsListener extends AbstractListener {
|
|||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
World world = entity.getWorld();
|
||||
if (!isRegionSupportEnabled(world)) return; // Region support disabled
|
||||
|
||||
if (Entities.isNPC(entity)) return;
|
||||
if (!(entity instanceof Player player)) return;
|
||||
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(world))) return; // Region support disabled
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
|
||||
if (entity instanceof Player && event.getCause() == DamageCause.FALL) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer((Player) entity);
|
||||
if (event.getCause() == DamageCause.FALL) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
if (!query.testState(BukkitAdapter.adapt(entity.getLocation()), localPlayer, Flags.FALL_DAMAGE)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (entity instanceof Player && event.getCause() == DamageCause.FLY_INTO_WALL) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer((Player) entity);
|
||||
if (!query.testState(BukkitAdapter.adapt(entity.getLocation()), localPlayer, Flags.FALL_DAMAGE)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (event.getCause() == DamageCause.FLY_INTO_WALL) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
if (!query.testState(BukkitAdapter.adapt(entity.getLocation()), localPlayer, Flags.FALL_DAMAGE)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,7 +41,6 @@ import com.sk89q.worldguard.bukkit.util.InteropUtils;
|
|||
import com.sk89q.worldguard.bukkit.util.Materials;
|
||||
import com.sk89q.worldguard.commands.CommandUtils;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
|
@ -59,8 +58,10 @@ import org.bukkit.entity.Item;
|
|||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerTakeLecternBookEvent;
|
||||
import org.bukkit.event.vehicle.VehicleExitEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -135,15 +136,14 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
|
||||
if (rootCause instanceof Player) {
|
||||
Player player = (Player) rootCause;
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
com.sk89q.worldedit.world.World localWorld = BukkitAdapter.adapt(world);
|
||||
WorldConfiguration config = getWorldConfig(localWorld);
|
||||
WorldConfiguration config = getWorldConfig(world);
|
||||
|
||||
if (config.fakePlayerBuildOverride && InteropUtils.isFakePlayer(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !pvp && WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, localWorld);
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
return !pvp && WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, localPlayer.getWorld());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlaceBlock(final PlaceBlockEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(event.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
final Material type = event.getEffectiveMaterial();
|
||||
|
@ -162,7 +162,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
// Don't check liquid flow unless it's enabled
|
||||
if (event.getCause().getRootCause() instanceof Block
|
||||
&& Materials.isLiquid(type)
|
||||
&& !getWorldConfig(BukkitAdapter.adapt(event.getWorld())).checkLiquidFlow) {
|
||||
&& !getWorldConfig(event.getWorld()).checkLiquidFlow) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -171,9 +171,9 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
String what;
|
||||
|
||||
/* Flint and steel, fire charge, etc. */
|
||||
if (type == Material.FIRE) {
|
||||
if (Materials.isFire(type)) {
|
||||
Block block = event.getCause().getFirstBlock();
|
||||
boolean fire = block != null && block.getType() == Material.FIRE;
|
||||
boolean fire = block != null && Materials.isFire(type);
|
||||
boolean lava = block != null && Materials.isLava(block.getType());
|
||||
List<StateFlag> flags = new ArrayList<>();
|
||||
flags.add(Flags.BLOCK_PLACE);
|
||||
|
@ -205,7 +205,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBreakBlock(final BreakBlockEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(event.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
final RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
|
@ -218,7 +218,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
String what;
|
||||
|
||||
/* TNT */
|
||||
if (event.getCause().find(EntityType.PRIMED_TNT, EntityType.MINECART_TNT) != null) {
|
||||
if (event.getCause().find(EntityType.TNT, EntityType.TNT_MINECART) != null) {
|
||||
canBreak = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.BLOCK_BREAK, Flags.TNT));
|
||||
what = "use dynamite";
|
||||
|
||||
|
@ -241,7 +241,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseBlock(final UseBlockEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(event.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
final Material type = event.getEffectiveMaterial();
|
||||
|
@ -259,14 +259,29 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
|
||||
/* Inventory */
|
||||
} else if (Materials.isInventoryBlock(type)) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.INTERACT, Flags.CHEST_ACCESS));
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.CHEST_ACCESS));
|
||||
what = "open that";
|
||||
|
||||
/* Inventory for blocks with the possibility to be only use, e.g. lectern */
|
||||
} else if (handleAsInventoryUsage(event.getOriginalEvent())) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.CHEST_ACCESS));
|
||||
what = "take that";
|
||||
|
||||
/* Anvils */
|
||||
} else if (Materials.isAnvil(type)) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.USE_ANVIL));
|
||||
what = "use that";
|
||||
|
||||
/* Beds */
|
||||
} else if (Materials.isBed(type)) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.INTERACT, Flags.SLEEP));
|
||||
what = "sleep";
|
||||
|
||||
/* Respawn Anchors */
|
||||
} else if(type == Material.RESPAWN_ANCHOR) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.INTERACT, Flags.RESPAWN_ANCHORS));
|
||||
what = "use anchors";
|
||||
|
||||
/* TNT */
|
||||
} else if (type == Material.TNT) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.INTERACT, Flags.TNT));
|
||||
|
@ -295,7 +310,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSpawnEntity(SpawnEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(event.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
Location target = event.getTarget();
|
||||
|
@ -329,12 +344,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
/* Everything else */
|
||||
} else {
|
||||
canSpawn = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event));
|
||||
|
||||
if (event.getEntity() instanceof Item) {
|
||||
what = "drop items";
|
||||
} else {
|
||||
what = "place things";
|
||||
}
|
||||
what = "place things";
|
||||
}
|
||||
|
||||
if (!canSpawn) {
|
||||
|
@ -346,7 +356,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDestroyEntity(DestroyEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(event.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
Location target = event.getTarget();
|
||||
|
@ -382,7 +392,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseEntity(UseEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(event.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
|
||||
|
||||
Location target = event.getTarget();
|
||||
|
@ -401,7 +411,8 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
what = "use that";
|
||||
/* Paintings, item frames, etc. */
|
||||
} else if (Entities.isConsideredBuildingIfUsed(entity)) {
|
||||
if (type == EntityType.ITEM_FRAME && event.getCause().getFirstPlayer() != null
|
||||
if ((type == EntityType.ITEM_FRAME || type == EntityType.GLOW_ITEM_FRAME)
|
||||
&& event.getCause().getFirstPlayer() != null
|
||||
&& ((ItemFrame) entity).getItem().getType() != Material.AIR) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.ITEM_FRAME_ROTATE));
|
||||
what = "change that";
|
||||
|
@ -432,7 +443,7 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDamageEntity(DamageEntityEvent event) {
|
||||
if (event.getResult() == Result.ALLOW) return; // Don't care about events that have been pre-allowed
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(event.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
|
||||
// Whitelist check is below
|
||||
|
||||
com.sk89q.worldedit.util.Location target = BukkitAdapter.adapt(event.getTarget());
|
||||
|
@ -508,11 +519,10 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onVehicleExit(VehicleExitEvent event) {
|
||||
Entity vehicle = event.getVehicle();
|
||||
if (!isRegionSupportEnabled(BukkitAdapter.adapt(vehicle.getWorld()))) return; // Region support disabled
|
||||
if (!isRegionSupportEnabled(vehicle.getWorld())) return; // Region support disabled
|
||||
Entity exited = event.getExited();
|
||||
|
||||
if (vehicle instanceof Tameable && exited instanceof Player) {
|
||||
Player player = (Player) exited;
|
||||
if (vehicle instanceof Tameable && exited instanceof Player player && !Entities.isNPC(player)) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
if (!isWhitelisted(Cause.create(player), vehicle.getWorld(), false)) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
|
@ -531,10 +541,6 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isWhitelistedEntity(Entity entity) {
|
||||
return Entities.isNonPlayerCreature(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the flags from a delegate event with an array of flags.
|
||||
*
|
||||
|
@ -553,4 +559,14 @@ public class RegionProtectionListener extends AbstractListener {
|
|||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if that event should be handled as inventory usage, e.g. if a player takes a book from a lectern
|
||||
*
|
||||
* @param event the event to handle
|
||||
* @return whether it should be handled as inventory usage
|
||||
*/
|
||||
private static boolean handleAsInventoryUsage(Event event) {
|
||||
return event instanceof PlayerTakeLecternBookEvent;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,14 +31,16 @@ import com.sk89q.worldguard.protection.association.RegionAssociable;
|
|||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.util.SpongeUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Snowman;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
|
@ -60,12 +62,9 @@ import org.bukkit.inventory.meta.ItemMeta;
|
|||
|
||||
/**
|
||||
* The listener for block events.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldGuardBlockListener implements Listener {
|
||||
public class WorldGuardBlockListener extends AbstractListener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
|
@ -73,34 +72,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
* @param plugin The plugin instance
|
||||
*/
|
||||
public WorldGuardBlockListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world configuration given a world.
|
||||
*
|
||||
* @param world The world to get the configuration for.
|
||||
* @return The configuration for {@code world}
|
||||
*/
|
||||
private WorldConfiguration getWorldConfig(World world) {
|
||||
return WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(BukkitAdapter.adapt(world));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world configuration given a player.
|
||||
*
|
||||
* @param player The player to get the wold from
|
||||
* @return The {@link BukkitWorldConfiguration} for the player's world
|
||||
*/
|
||||
private WorldConfiguration getWorldConfig(Player player) {
|
||||
return getWorldConfig(player.getWorld());
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -109,7 +81,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
WorldConfiguration wcfg = getWorldConfig(player);
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
|
||||
if (!wcfg.itemDurability) {
|
||||
ItemStack held = player.getInventory().getItemInMainHand();
|
||||
|
@ -131,18 +103,20 @@ public class WorldGuardBlockListener implements Listener {
|
|||
Block blockFrom = event.getBlock();
|
||||
Block blockTo = event.getToBlock();
|
||||
|
||||
boolean isWater = blockFrom.getType() == Material.WATER;
|
||||
boolean isLava = blockFrom.getType() == Material.LAVA;
|
||||
boolean isAir = blockFrom.getType() == Material.AIR;
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Material fromType = blockFrom.getType();
|
||||
boolean isWater = Materials.isWater(fromType);
|
||||
boolean isLava = fromType == Material.LAVA;
|
||||
boolean isAir = fromType == Material.AIR;
|
||||
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
|
||||
if (wcfg.simulateSponge && isWater) {
|
||||
int ox = blockTo.getX();
|
||||
int oy = blockTo.getY();
|
||||
|
@ -194,7 +168,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
}
|
||||
}
|
||||
|
||||
if (wcfg.highFreqFlags && isWater
|
||||
if (wcfg.highFreqFlags && (isWater || blockFrom.getBlockData() instanceof Waterlogged)
|
||||
&& WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().queryState(BukkitAdapter.adapt(blockFrom.getLocation()), (RegionAssociable) null, Flags.WATER_FLOW) == StateFlag.State.DENY) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -205,13 +179,6 @@ public class WorldGuardBlockListener implements Listener {
|
|||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableObsidianGenerators && (isAir || isLava)
|
||||
&& (blockTo.getType() == Material.REDSTONE_WIRE
|
||||
|| blockTo.getType() == Material.TRIPWIRE)) {
|
||||
blockTo.setType(Material.AIR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -223,13 +190,14 @@ public class WorldGuardBlockListener implements Listener {
|
|||
Block block = event.getBlock();
|
||||
World world = block.getWorld();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
boolean isFireSpread = cause == IgniteCause.SPREAD;
|
||||
|
||||
if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) {
|
||||
|
@ -249,7 +217,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
|
||||
if (wcfg.blockLighter && (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL)
|
||||
&& event.getPlayer() != null
|
||||
&& !plugin.hasPermission(event.getPlayer(), "worldguard.override.lighter")) {
|
||||
&& !getPlugin().hasPermission(event.getPlayer(), "worldguard.override.lighter")) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
@ -310,14 +278,15 @@ public class WorldGuardBlockListener implements Listener {
|
|||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockBurn(BlockBurnEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) getWorldConfig(event.getBlock().getWorld());
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
BukkitWorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
|
||||
if (wcfg.disableFireSpread) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -326,7 +295,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
if (wcfg.fireSpreadDisableToggle) {
|
||||
Block block = event.getBlock();
|
||||
event.setCancelled(true);
|
||||
checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), Material.FIRE);
|
||||
checkAndDestroyFireAround(block.getWorld(), block.getX(), block.getY(), block.getZ());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -335,7 +304,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
|
||||
if (wcfg.disableFireSpreadBlocks.contains(BukkitAdapter.asBlockType(block.getType()).getId())) {
|
||||
event.setCancelled(true);
|
||||
checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), Material.FIRE);
|
||||
checkAndDestroyFireAround(block.getWorld(), block.getX(), block.getY(), block.getZ());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -354,24 +323,24 @@ public class WorldGuardBlockListener implements Listener {
|
|||
WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(block.getLocation()));
|
||||
|
||||
if (!set.testState(null, Flags.FIRE_SPREAD)) {
|
||||
checkAndDestroyAround(block.getWorld(), x, y, z, Material.FIRE);
|
||||
checkAndDestroyFireAround(block.getWorld(), x, y, z);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndDestroyAround(World world, int x, int y, int z, Material required) {
|
||||
checkAndDestroy(world, x, y, z + 1, required);
|
||||
checkAndDestroy(world, x, y, z - 1, required);
|
||||
checkAndDestroy(world, x, y + 1, z, required);
|
||||
checkAndDestroy(world, x, y - 1, z, required);
|
||||
checkAndDestroy(world, x + 1, y, z, required);
|
||||
checkAndDestroy(world, x - 1, y, z, required);
|
||||
private void checkAndDestroyFireAround(World world, int x, int y, int z) {
|
||||
checkAndDestroyFire(world, x, y, z + 1);
|
||||
checkAndDestroyFire(world, x, y, z - 1);
|
||||
checkAndDestroyFire(world, x, y + 1, z);
|
||||
checkAndDestroyFire(world, x, y - 1, z);
|
||||
checkAndDestroyFire(world, x + 1, y, z);
|
||||
checkAndDestroyFire(world, x - 1, y, z);
|
||||
}
|
||||
|
||||
private void checkAndDestroy(World world, int x, int y, int z, Material required) {
|
||||
if (world.getBlockAt(x, y, z).getType() == required) {
|
||||
private void checkAndDestroyFire(World world, int x, int y, int z) {
|
||||
if (Materials.isFire(world.getBlockAt(x, y, z).getType())) {
|
||||
world.getBlockAt(x, y, z).setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
@ -381,22 +350,22 @@ public class WorldGuardBlockListener implements Listener {
|
|||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Material id = event.getBlock().getType();
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
final Material id = event.getBlock().getType();
|
||||
|
||||
if (id == Material.GRAVEL && wcfg.noPhysicsGravel) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == Material.SAND && wcfg.noPhysicsSand) {
|
||||
if ((id == Material.SAND || id == Material.RED_SAND) && wcfg.noPhysicsSand) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
@ -406,7 +375,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (wcfg.ropeLadders && event.getBlock().getType() == Material.LADDER) {
|
||||
if (id == Material.LADDER && wcfg.ropeLadders) {
|
||||
if (event.getBlock().getRelative(0, 1, 0).getType() == Material.LADDER) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -473,14 +442,15 @@ public class WorldGuardBlockListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onLeavesDecay(LeavesDecayEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
|
||||
if (wcfg.disableLeafDecay) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -498,14 +468,15 @@ public class WorldGuardBlockListener implements Listener {
|
|||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockForm(BlockFormEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
|
||||
Material type = event.getNewState().getType();
|
||||
|
||||
if (event instanceof EntityBlockFormEvent) {
|
||||
|
@ -549,6 +520,18 @@ public class WorldGuardBlockListener implements Listener {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Materials.isUnwaxedCopper(event.getBlock().getType())) {
|
||||
if (wcfg.disableCopperBlockFade) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
|
||||
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.COPPER_FADE))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -556,14 +539,14 @@ public class WorldGuardBlockListener implements Listener {
|
|||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockSpread(BlockSpreadEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
Material newType = event.getNewState().getType(); // craftbukkit randomly gives AIR as event.getSource even if that block is not air
|
||||
|
||||
if (Materials.isMushroom(newType)) {
|
||||
|
@ -603,7 +586,7 @@ public class WorldGuardBlockListener implements Listener {
|
|||
}
|
||||
}
|
||||
|
||||
if (newType == Material.VINE || newType == Material.KELP) {
|
||||
if (Materials.isVine(newType)) {
|
||||
if (wcfg.disableVineGrowth) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -615,21 +598,54 @@ public class WorldGuardBlockListener implements Listener {
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockGrow(BlockGrowEvent event) {
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
final Material type = event.getNewState().getType();
|
||||
|
||||
if (Materials.isCrop(type)) {
|
||||
if (wcfg.disableCropGrowth) {
|
||||
event.setCancelled(false);
|
||||
if (Materials.isAmethystGrowth(newType) || newType == Material.POINTED_DRIPSTONE) {
|
||||
if (wcfg.disableRockGrowth) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
|
||||
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.CROP_GROWTH))) {
|
||||
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.ROCK_GROWTH))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Materials.isSculkGrowth(newType)) {
|
||||
if (wcfg.disableSculkGrowth) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
|
||||
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.SCULK_GROWTH))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
handleGrow(event, event.getBlock().getLocation(), newType);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockGrow(BlockGrowEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
final Material type = event.getNewState().getType();
|
||||
|
||||
handleGrow(event, loc, type);
|
||||
}
|
||||
|
||||
private void handleGrow(Cancellable event, Location loc, Material type) {
|
||||
WorldConfiguration wcfg = getWorldConfig(loc.getWorld());
|
||||
if (Materials.isCrop(type)) {
|
||||
if (wcfg.disableCropGrowth) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
|
||||
.queryState(BukkitAdapter.adapt(loc), (RegionAssociable) null, Flags.CROP_GROWTH))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
@ -682,12 +698,22 @@ public class WorldGuardBlockListener implements Listener {
|
|||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (Materials.isCoral(event.getBlock().getType())) {
|
||||
if (wcfg.disableCoralBlockFade) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
|
||||
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.CORAL_FADE))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockExplode(BlockExplodeEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
|
|
|
@ -25,13 +25,17 @@ import com.sk89q.worldguard.LocalPlayer;
|
|||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.cause.Cause;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.bukkit.util.InteropUtils;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.FailedLoadRegionSet;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
|
@ -47,7 +51,9 @@ import org.bukkit.entity.EnderDragon;
|
|||
import org.bukkit.entity.Enderman;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Fireball;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -60,7 +66,6 @@ import org.bukkit.entity.Wolf;
|
|||
import org.bukkit.entity.minecart.ExplosiveMinecart;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.event.entity.CreeperPowerEvent;
|
||||
|
@ -74,10 +79,13 @@ import org.bukkit.event.entity.EntityDeathEvent;
|
|||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityInteractEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.event.entity.EntityTransformEvent;
|
||||
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.entity.PigZapEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.vehicle.VehicleEnterEvent;
|
||||
import org.bukkit.event.world.PortalCreateEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
@ -86,12 +94,8 @@ import java.util.Set;
|
|||
|
||||
/**
|
||||
* Listener for entity related events.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldGuardEntityListener implements Listener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
public class WorldGuardEntityListener extends AbstractListener {
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
|
@ -99,36 +103,32 @@ public class WorldGuardEntityListener implements Listener {
|
|||
* @param plugin The plugin instance
|
||||
*/
|
||||
public WorldGuardEntityListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onEntityInteract(EntityInteractEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
Block block = event.getBlock();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(block.getWorld());
|
||||
|
||||
if (block.getType() == Material.FARMLAND) {
|
||||
if (/* entity instanceof Creature && // catch for any entity (not thrown for players) */
|
||||
wcfg.disableCreatureCropTrampling) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (block.getType() == Material.FARMLAND && wcfg.disableCreatureCropTrampling) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (block.getType() == Material.TURTLE_EGG && wcfg.disableCreatureTurtleEggTrampling) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (block.getType() == Material.SNIFFER_EGG && wcfg.disableCreatureSnifferEggTrampling) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
WorldConfiguration wcfg =
|
||||
WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(BukkitAdapter.adapt(event.getEntity().getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getEntity().getWorld());
|
||||
|
||||
if (event instanceof PlayerDeathEvent && wcfg.disableDeathMessages) {
|
||||
((PlayerDeathEvent) event).setDeathMessage("");
|
||||
|
@ -139,16 +139,14 @@ public class WorldGuardEntityListener implements Listener {
|
|||
Entity defender = event.getEntity();
|
||||
DamageCause type = event.getCause();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(defender.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(defender.getWorld());
|
||||
|
||||
if (defender instanceof Wolf && ((Wolf) defender).isTamed()) {
|
||||
if (wcfg.antiWolfDumbness && !(type == DamageCause.VOID)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
} else if (defender instanceof Player player && !Entities.isNPC(defender)) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
|
||||
if (wcfg.disableLavaDamage && type == DamageCause.LAVA) {
|
||||
|
@ -190,7 +188,7 @@ public class WorldGuardEntityListener implements Listener {
|
|||
// handled anywhere else
|
||||
if (type == DamageCause.BLOCK_EXPLOSION
|
||||
&& (wcfg.blockOtherExplosions
|
||||
|| (wcfg.explosionFlagCancellation
|
||||
|| ((wcfg.explosionFlagCancellation || Entities.isConsideredBuildingIfUsed(defender))
|
||||
&& !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
|
||||
.queryState(BukkitAdapter.adapt(defender.getLocation()), (RegionAssociable) null, Flags.OTHER_EXPLOSION))))) {
|
||||
event.setCancelled(true);
|
||||
|
@ -210,8 +208,7 @@ public class WorldGuardEntityListener implements Listener {
|
|||
Entity attacker = event.getDamager();
|
||||
Entity defender = event.getEntity();
|
||||
|
||||
WorldConfiguration wcfg =
|
||||
WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(BukkitAdapter.adapt(defender.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(defender.getWorld());
|
||||
|
||||
if (defender instanceof ItemFrame) {
|
||||
if (checkItemFrameProtection(attacker, (ItemFrame) defender)) {
|
||||
|
@ -237,9 +234,8 @@ public class WorldGuardEntityListener implements Listener {
|
|||
}
|
||||
}
|
||||
|
||||
if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
if (defender instanceof Player player && !Entities.isNPC(defender)) {
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
if (wcfg.disableLightningDamage && event.getCause() == DamageCause.LIGHTNING) {
|
||||
event.setCancelled(true);
|
||||
|
@ -298,11 +294,9 @@ public class WorldGuardEntityListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(defender.getWorld()));
|
||||
if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
WorldConfiguration wcfg = getWorldConfig(defender.getWorld());
|
||||
if (defender instanceof Player player && !Entities.isNPC(defender)) {
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
|
||||
// Check Mob
|
||||
|
@ -367,16 +361,14 @@ public class WorldGuardEntityListener implements Listener {
|
|||
Entity defender = event.getEntity();
|
||||
DamageCause type = event.getCause();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(defender.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(defender.getWorld());
|
||||
|
||||
if (defender instanceof Wolf && ((Wolf) defender).isTamed()) {
|
||||
if (wcfg.antiWolfDumbness) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
} else if (defender instanceof Player player && !Entities.isNPC(defender)) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
|
||||
if (type == DamageCause.WITHER) {
|
||||
|
@ -389,14 +381,14 @@ public class WorldGuardEntityListener implements Listener {
|
|||
if (wcfg.useRegions) {
|
||||
ApplicableRegionSet set = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(localPlayer.getLocation());
|
||||
|
||||
if (!set.testState(plugin.wrapPlayer(player), Flags.MOB_DAMAGE)) {
|
||||
if (!set.testState(getPlugin().wrapPlayer(player), Flags.MOB_DAMAGE)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == DamageCause.DROWNING && cfg.hasAmphibiousMode(localPlayer)) {
|
||||
if (type == DamageCause.DROWNING && getConfig().hasAmphibiousMode(localPlayer)) {
|
||||
player.setRemainingAir(player.getMaximumAir());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -448,10 +440,7 @@ public class WorldGuardEntityListener implements Listener {
|
|||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
Location l = event.getLocation();
|
||||
World world = l.getWorld();
|
||||
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) cfg.get(BukkitAdapter.adapt(world));
|
||||
ConfigurationManager cfg = getConfig();
|
||||
Entity ent = event.getEntity();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
|
@ -460,6 +449,7 @@ public class WorldGuardEntityListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
BukkitWorldConfiguration wcfg = getWorldConfig(event.getLocation().getWorld());
|
||||
if (ent instanceof Creeper) {
|
||||
if (wcfg.blockCreeperExplosions) {
|
||||
event.setCancelled(true);
|
||||
|
@ -566,8 +556,7 @@ public class WorldGuardEntityListener implements Listener {
|
|||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onExplosionPrime(ExplosionPrimeEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getEntity().getWorld()));
|
||||
ConfigurationManager cfg = getConfig();
|
||||
Entity ent = event.getEntity();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
|
@ -576,6 +565,7 @@ public class WorldGuardEntityListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
BukkitWorldConfiguration wcfg = getWorldConfig(ent.getWorld());
|
||||
if (event.getEntityType() == EntityType.WITHER) {
|
||||
if (wcfg.blockWitherExplosions) {
|
||||
event.setCancelled(true);
|
||||
|
@ -596,8 +586,8 @@ public class WorldGuardEntityListener implements Listener {
|
|||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (event.getEntityType() == EntityType.PRIMED_TNT
|
||||
|| event.getEntityType() == EntityType.MINECART_TNT) {
|
||||
} else if (event.getEntityType() == EntityType.TNT
|
||||
|| event.getEntityType() == EntityType.TNT_MINECART) {
|
||||
if (wcfg.blockTNTExplosions) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -607,17 +597,17 @@ public class WorldGuardEntityListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onCreatureSpawn(CreatureSpawnEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getEntity().getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getEntity().getWorld());
|
||||
|
||||
// allow spawning of creatures from plugins
|
||||
if (!wcfg.blockPluginSpawning && event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.CUSTOM) {
|
||||
if (!wcfg.blockPluginSpawning && Entities.isPluginSpawning(event.getSpawnReason())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -669,37 +659,48 @@ public class WorldGuardEntityListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onCreatePortal(PortalCreateEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
final com.sk89q.worldedit.world.World world = BukkitAdapter.adapt(event.getWorld());
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
if (wcfg.regionNetherPortalProtection
|
||||
if (wcfg.useRegions && wcfg.regionNetherPortalProtection
|
||||
&& event.getReason() == PortalCreateEvent.CreateReason.NETHER_PAIR
|
||||
&& !event.getBlocks().isEmpty()) {
|
||||
final RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer()
|
||||
.get(world);
|
||||
if (regionManager == null) return;
|
||||
LocalPlayer associable = null;
|
||||
if (event.getEntity() instanceof Player) {
|
||||
associable = plugin.wrapPlayer(((Player) event.getEntity()));
|
||||
if (WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(associable, world)) {
|
||||
final com.sk89q.worldedit.world.World world = BukkitAdapter.adapt(event.getWorld());
|
||||
final Cause cause = Cause.create(event.getEntity());
|
||||
LocalPlayer localPlayer = null;
|
||||
if (cause.getRootCause() instanceof Player player) {
|
||||
if (wcfg.fakePlayerBuildOverride && InteropUtils.isFakePlayer(player)) {
|
||||
return;
|
||||
}
|
||||
localPlayer = getPlugin().wrapPlayer(player);
|
||||
if (WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, world)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
BlockVector3 min = null;
|
||||
BlockVector3 max = null;
|
||||
for (BlockState block : event.getBlocks()) {
|
||||
BlockVector3 loc = BlockVector3.at(block.getX(), block.getY(), block.getZ());
|
||||
min = min == null ? loc : loc.getMinimum(min);
|
||||
max = max == null ? loc : loc.getMaximum(max);
|
||||
final RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer()
|
||||
.get(world);
|
||||
ApplicableRegionSet regions;
|
||||
if (regionManager == null) {
|
||||
regions = FailedLoadRegionSet.getInstance();
|
||||
} else {
|
||||
BlockVector3 min = null;
|
||||
BlockVector3 max = null;
|
||||
for (BlockState block : event.getBlocks()) {
|
||||
BlockVector3 loc = BlockVector3.at(block.getX(), block.getY(), block.getZ());
|
||||
min = min == null ? loc : loc.getMinimum(min);
|
||||
max = max == null ? loc : loc.getMaximum(max);
|
||||
}
|
||||
ProtectedCuboidRegion target = new ProtectedCuboidRegion("__portal_check", true, min, max);
|
||||
regions = regionManager.getApplicableRegions(target);
|
||||
}
|
||||
ProtectedCuboidRegion target = new ProtectedCuboidRegion("__portal_check", true, min, max);
|
||||
final ApplicableRegionSet regions = regionManager.getApplicableRegions(target);
|
||||
if (!regions.testState(associable, Flags.BUILD, Flags.BLOCK_PLACE)) {
|
||||
if (associable != null) {
|
||||
final RegionAssociable associable = createRegionAssociable(cause);
|
||||
final State buildState = StateFlag.denyToNone(regions.queryState(associable, Flags.BUILD));
|
||||
if (!StateFlag.test(buildState, regions.queryState(associable, Flags.BLOCK_BREAK))
|
||||
|| !StateFlag.test(buildState, regions.queryState(associable, Flags.BLOCK_PLACE))) {
|
||||
if (localPlayer != null && !cause.isIndirect()) {
|
||||
// NB there is no way to cancel the teleport without PTA (since PlayerPortal doesn't have block info)
|
||||
// removing PTA was a mistake
|
||||
associable.print("Destination is an a protected area.");
|
||||
String message = regions.queryValue(localPlayer, Flags.DENY_MESSAGE);
|
||||
RegionProtectionListener.formatAndSendDenyMessage("create portals", localPlayer, message);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
@ -714,9 +715,8 @@ public class WorldGuardEntityListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onEntityTransform(EntityTransformEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
final Entity entity = event.getEntity();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(entity.getWorld());
|
||||
|
||||
final EntityType type = entity.getType();
|
||||
if (wcfg.disableVillagerZap && type == EntityType.VILLAGER
|
||||
|
@ -727,9 +727,8 @@ public class WorldGuardEntityListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onPigZap(PigZapEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
final Entity entity = event.getEntity();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(entity.getWorld());
|
||||
|
||||
if (wcfg.disablePigZap) {
|
||||
event.setCancelled(true);
|
||||
|
@ -738,8 +737,8 @@ public class WorldGuardEntityListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onCreeperPower(CreeperPowerEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getEntity().getWorld()));
|
||||
final Entity entity = event.getEntity();
|
||||
WorldConfiguration wcfg = getWorldConfig(entity.getWorld());
|
||||
|
||||
if (wcfg.disableCreeperPower) {
|
||||
event.setCancelled(true);
|
||||
|
@ -748,17 +747,44 @@ public class WorldGuardEntityListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onEntityRegainHealth(EntityRegainHealthEvent event) {
|
||||
RegainReason regainReason = event.getRegainReason();
|
||||
if (regainReason != RegainReason.REGEN && regainReason != RegainReason.SATIATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity ent = event.getEntity();
|
||||
World world = ent.getWorld();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
WorldConfiguration wcfg = getWorldConfig(ent.getWorld());
|
||||
|
||||
if (wcfg.disableHealthRegain) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && ent instanceof Player player && !Entities.isNPC(ent)
|
||||
&& !WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().testState(
|
||||
BukkitAdapter.adapt(ent.getLocation()),
|
||||
WorldGuardPlugin.inst().wrapPlayer(player),
|
||||
Flags.HEALTH_REGEN)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onFoodChange(FoodLevelChangeEvent event) {
|
||||
if (event.getItem() != null) return;
|
||||
HumanEntity ent = event.getEntity();
|
||||
if (Entities.isNPC(ent)) return;
|
||||
if (!(ent instanceof Player bukkitPlayer)) return;
|
||||
if (event.getFoodLevel() > ent.getFoodLevel()) return;
|
||||
|
||||
LocalPlayer player = WorldGuardPlugin.inst().wrapPlayer(bukkitPlayer);
|
||||
WorldConfiguration wcfg = getWorldConfig(ent.getWorld());
|
||||
|
||||
if (wcfg.useRegions
|
||||
&& !WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().testState(
|
||||
player.getLocation(), player, Flags.HUNGER_DRAIN)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -769,12 +795,21 @@ public class WorldGuardEntityListener implements Listener {
|
|||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
||||
Entity ent = event.getEntity();
|
||||
Block block = event.getBlock();
|
||||
Location location = block.getLocation();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(ent.getWorld()));
|
||||
if (ent instanceof Enderman) {
|
||||
WorldConfiguration wcfg = getWorldConfig(ent.getWorld());
|
||||
if (ent instanceof FallingBlock) {
|
||||
Material id = event.getBlock().getType();
|
||||
|
||||
if (id == Material.GRAVEL && wcfg.noPhysicsGravel) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((id == Material.SAND || id == Material.RED_SAND) && wcfg.noPhysicsSand) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (ent instanceof Enderman) {
|
||||
if (wcfg.disableEndermanGriefing) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -785,6 +820,7 @@ public class WorldGuardEntityListener implements Listener {
|
|||
return;
|
||||
}
|
||||
if (wcfg.useRegions) {
|
||||
Location location = event.getBlock().getLocation();
|
||||
if (!StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().queryState(BukkitAdapter.adapt(location), (RegionAssociable) null, Flags.WITHER_DAMAGE))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
@ -798,6 +834,15 @@ public class WorldGuardEntityListener implements Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onVehicleEnter(VehicleEnterEvent event) {
|
||||
BukkitWorldConfiguration wcfg = getWorldConfig(event.getEntered().getWorld());
|
||||
|
||||
if (wcfg.blockEntityVehicleEntry && !(event.getEntered() instanceof Player)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks regions and config settings to protect items from being knocked
|
||||
* out of item frames.
|
||||
|
@ -806,9 +851,8 @@ public class WorldGuardEntityListener implements Listener {
|
|||
* @return true if the event should be cancelled
|
||||
*/
|
||||
private boolean checkItemFrameProtection(Entity attacker, ItemFrame defender) {
|
||||
World world = attacker.getWorld();
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
World world = defender.getWorld();
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
if (wcfg.useRegions) {
|
||||
// bukkit throws this event when a player attempts to remove an item from a frame
|
||||
if (!(attacker instanceof Player)) {
|
||||
|
|
|
@ -22,7 +22,6 @@ package com.sk89q.worldguard.bukkit.listener;
|
|||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
|
@ -38,7 +37,6 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause;
|
||||
|
@ -46,35 +44,18 @@ import org.bukkit.projectiles.ProjectileSource;
|
|||
|
||||
/**
|
||||
* Listener for painting related events.
|
||||
*
|
||||
* @author BangL <henno.rickowski@gmail.com>
|
||||
*/
|
||||
public class WorldGuardHangingListener implements Listener {
|
||||
public class WorldGuardHangingListener extends AbstractListener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin The plugin instance
|
||||
*/
|
||||
public WorldGuardHangingListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onHangingBreak(HangingBreakEvent event) {
|
||||
Hanging hanging = event.getEntity();
|
||||
World world = hanging.getWorld();
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
|
||||
if (event instanceof HangingBreakByEntityEvent) {
|
||||
HangingBreakByEntityEvent entityEvent = (HangingBreakByEntityEvent) event;
|
||||
|
|
|
@ -38,6 +38,7 @@ import com.sk89q.worldguard.session.Session;
|
|||
import com.sk89q.worldguard.session.handler.GameModeFlag;
|
||||
import com.sk89q.worldguard.util.Entities;
|
||||
import com.sk89q.worldguard.util.command.CommandFilter;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
@ -47,7 +48,6 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
@ -60,45 +60,31 @@ import org.bukkit.event.player.PlayerRespawnEvent;
|
|||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles all events thrown in relation to a player.
|
||||
*/
|
||||
public class WorldGuardPlayerListener implements Listener {
|
||||
public class WorldGuardPlayerListener extends AbstractListener {
|
||||
|
||||
private static final Logger log = Logger.getLogger(WorldGuardPlayerListener.class.getCanonicalName());
|
||||
private static final Pattern opPattern = Pattern.compile("^/(?:minecraft:)?(?:bukkit:)?(?:de)?op(?:\\s.*)?$", Pattern.CASE_INSENSITIVE);
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardPlayerListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
WorldConfiguration wcfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(localPlayer.getWorld());
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().getIfPresent(localPlayer);
|
||||
if (session != null) {
|
||||
GameModeFlag handler = session.getHandler(GameModeFlag.class);
|
||||
|
@ -116,11 +102,10 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
World world = player.getWorld();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(localPlayer.getWorld());
|
||||
ConfigurationManager cfg = getConfig();
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
player.sendMessage(ChatColor.YELLOW
|
||||
|
@ -147,14 +132,15 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
}
|
||||
|
||||
Events.fire(new ProcessPlayerEvent(player));
|
||||
WorldGuard.getInstance().getExecutorService().submit(() ->
|
||||
WorldGuard.getInstance().getProfileCache().put(new Profile(player.getUniqueId(), player.getName())));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
WorldConfiguration wcfg =
|
||||
WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(localPlayer.getWorld());
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
if (wcfg.useRegions) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
ApplicableRegionSet chatFrom = query.getApplicableRegions(localPlayer.getLocation());
|
||||
|
@ -169,7 +155,7 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
boolean anyRemoved = false;
|
||||
for (Iterator<Player> i = event.getRecipients().iterator(); i.hasNext();) {
|
||||
Player rPlayer = i.next();
|
||||
LocalPlayer rLocal = plugin.wrapPlayer(rPlayer);
|
||||
LocalPlayer rLocal = getPlugin().wrapPlayer(rPlayer);
|
||||
if (!query.testState(rLocal.getLocation(), rLocal, Flags.RECEIVE_CHAT)) {
|
||||
i.remove();
|
||||
anyRemoved = true;
|
||||
|
@ -184,7 +170,7 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
String hostKey = cfg.hostKeys.get(player.getUniqueId().toString());
|
||||
if (hostKey == null) {
|
||||
|
@ -199,7 +185,8 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
}
|
||||
|
||||
if (!hostname.equals(hostKey)
|
||||
&& !(cfg.hostKeysAllowFMLClients && hostname.equals(hostKey + "\u0000FML\u0000"))) {
|
||||
&& !(cfg.hostKeysAllowFMLClients &&
|
||||
(hostname.equals(hostKey + "\u0000FML\u0000") || hostname.equals(hostKey + "\u0000FML2\u0000")))) {
|
||||
event.disallow(PlayerLoginEvent.Result.KICK_OTHER,
|
||||
"You did not join with the valid host key!");
|
||||
log.warning("WorldGuard host key check: " +
|
||||
|
@ -225,11 +212,11 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
handlePhysicalInteract(event);
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
ConfigurationManager cfg = getConfig();
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
|
||||
if (wcfg.removeInfiniteStacks
|
||||
&& !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
|
||||
&& !getPlugin().hasPermission(player, "worldguard.override.infinite-stack")) {
|
||||
int slot = player.getInventory().getHeldItemSlot();
|
||||
ItemStack heldItem = player.getInventory().getItem(slot);
|
||||
if (heldItem != null && heldItem.getAmount() < 0) {
|
||||
|
@ -255,13 +242,12 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
Player player = event.getPlayer();
|
||||
@Nullable ItemStack item = event.getItem();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
|
||||
// Infinite stack removal
|
||||
if (Materials.isInventoryBlock(type)
|
||||
&& wcfg.removeInfiniteStacks
|
||||
&& !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
|
||||
&& !getPlugin().hasPermission(player, "worldguard.override.infinite-stack")) {
|
||||
for (int slot = 0; slot < 40; slot++) {
|
||||
ItemStack heldItem = player.getInventory().getItem(slot);
|
||||
if (heldItem != null && heldItem.getAmount() < 0) {
|
||||
|
@ -272,13 +258,11 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
//Block placedIn = block.getRelative(event.getBlockFace());
|
||||
ApplicableRegionSet set =
|
||||
WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(block.getLocation()));
|
||||
//ApplicableRegionSet placedInSet = plugin.getRegionContainer().createQuery().getApplicableRegions(placedIn.getLocation());
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
|
||||
if (item != null && item.getType().getKey().toString().equals(wcfg.regionWand) && plugin.hasPermission(player, "worldguard.region.wand")) {
|
||||
if (item != null && item.getType().getKey().toString().equals(wcfg.regionWand) && getPlugin().hasPermission(player, "worldguard.region.wand")) {
|
||||
ApplicableRegionSet set = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
|
||||
.getApplicableRegions(BukkitAdapter.adapt(block.getLocation()), RegionQuery.QueryOption.SORT);
|
||||
if (set.size() > 0) {
|
||||
player.sendMessage(ChatColor.YELLOW + "Can you build? " + (set.testState(localPlayer, Flags.BUILD) ? "Yes" : "No"));
|
||||
|
||||
|
@ -310,13 +294,20 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
|
||||
Player player = event.getPlayer();
|
||||
Block block = event.getClickedBlock(); //not actually clicked but whatever
|
||||
//int type = block.getTypeId();
|
||||
Material type = block.getType();
|
||||
World world = player.getWorld();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
|
||||
if (block.getType() == Material.FARMLAND && wcfg.disablePlayerCropTrampling) {
|
||||
if (type == Material.FARMLAND && wcfg.disablePlayerCropTrampling) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (type == Material.TURTLE_EGG && wcfg.disablePlayerTurtleEggTrampling) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (type == Material.SNIFFER_EGG && wcfg.disablePlayerSnifferEggTrampling) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
@ -325,12 +316,11 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerRespawn(PlayerRespawnEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(localPlayer.getWorld());
|
||||
if (com.sk89q.worldguard.bukkit.util.Entities.isNPC(player)) return;
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
ApplicableRegionSet set =
|
||||
WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(localPlayer.getLocation());
|
||||
|
||||
|
@ -345,12 +335,10 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onItemHeldChange(PlayerItemHeldEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(player.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
|
||||
if (wcfg.removeInfiniteStacks
|
||||
&& !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
|
||||
&& !getPlugin().hasPermission(player, "worldguard.override.infinite-stack")) {
|
||||
int newSlot = event.getNewSlot();
|
||||
ItemStack heldItem = player.getInventory().getItem(newSlot);
|
||||
if (heldItem != null && heldItem.getAmount() < 0) {
|
||||
|
@ -363,15 +351,15 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(localPlayer.getWorld());
|
||||
if (com.sk89q.worldguard.bukkit.util.Entities.isNPC(player)) return;
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
ConfigurationManager cfg = getConfig();
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
|
||||
if (wcfg.useRegions && cfg.usePlayerTeleports) {
|
||||
ApplicableRegionSet set =
|
||||
WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(event.getTo()));
|
||||
ApplicableRegionSet setFrom =
|
||||
WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(event.getFrom()));
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
ApplicableRegionSet set = query.getApplicableRegions(BukkitAdapter.adapt(event.getTo()));
|
||||
ApplicableRegionSet setFrom = query.getApplicableRegions(BukkitAdapter.adapt(event.getFrom()));
|
||||
|
||||
if (event.getCause() == TeleportCause.ENDER_PEARL) {
|
||||
if (!WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, localPlayer.getWorld())) {
|
||||
|
@ -385,7 +373,7 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
message = set.queryValue(localPlayer, Flags.ENTRY_DENY_MESSAGE);
|
||||
}
|
||||
if (cancel) {
|
||||
if (message != null) {
|
||||
if (message != null && !message.isEmpty()) {
|
||||
player.sendMessage(message);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
|
@ -404,7 +392,7 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
message = set.queryValue(localPlayer, Flags.ENTRY_DENY_MESSAGE);
|
||||
}
|
||||
if (cancel) {
|
||||
if (message != null) {
|
||||
if (message != null && !message.isEmpty()) {
|
||||
player.sendMessage(message);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
|
@ -423,9 +411,9 @@ public class WorldGuardPlayerListener implements Listener {
|
|||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(localPlayer.getWorld());
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
ConfigurationManager cfg = getConfig();
|
||||
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
|
||||
|
||||
if (wcfg.useRegions && !WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, localPlayer.getWorld())) {
|
||||
ApplicableRegionSet set =
|
||||
|
|
|
@ -19,42 +19,28 @@
|
|||
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
/**
|
||||
* @author zml2008
|
||||
*/
|
||||
public class WorldGuardServerListener implements Listener {
|
||||
|
||||
private final WorldGuardPlugin plugin;
|
||||
public class WorldGuardServerListener extends AbstractListener {
|
||||
|
||||
public WorldGuardServerListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvents(this, plugin);
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent event) {
|
||||
if (event.getPlugin().getDescription().getName().equalsIgnoreCase("CommandBook")) {
|
||||
((BukkitConfigurationManager) WorldGuard.getInstance().getPlatform().getGlobalStateManager()).updateCommandBookGodMode();
|
||||
getConfig().updateCommandBookGodMode();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
if (event.getPlugin().getDescription().getName().equalsIgnoreCase("CommandBook")) {
|
||||
((BukkitConfigurationManager) WorldGuard.getInstance().getPlatform().getGlobalStateManager()).updateCommandBookGodMode();
|
||||
getConfig().updateCommandBookGodMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import com.sk89q.worldedit.util.Location;
|
|||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.session.MoveType;
|
||||
import com.sk89q.worldguard.util.Locations;
|
||||
|
@ -32,31 +32,16 @@ import org.bukkit.World;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.vehicle.VehicleMoveEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WorldGuardVehicleListener implements Listener {
|
||||
public class WorldGuardVehicleListener extends AbstractListener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardVehicleListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -69,14 +54,14 @@ public class WorldGuardVehicleListener implements Listener {
|
|||
return;
|
||||
}
|
||||
World world = vehicle.getWorld();
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
// Did we move a block?
|
||||
if (Locations.isDifferentBlock(BukkitAdapter.adapt(event.getFrom()), BukkitAdapter.adapt(event.getTo()))) {
|
||||
for (Player player : playerPassengers) {
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
if (Entities.isNPC(player)) continue;
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
Location lastValid;
|
||||
if ((lastValid = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer)
|
||||
.testMoveTo(localPlayer, BukkitAdapter.adapt(event.getTo()), MoveType.RIDE)) != null) {
|
||||
|
|
|
@ -22,7 +22,6 @@ package com.sk89q.worldguard.bukkit.listener;
|
|||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
|
@ -33,35 +32,19 @@ import org.bukkit.block.Block;
|
|||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.weather.LightningStrikeEvent;
|
||||
import org.bukkit.event.weather.ThunderChangeEvent;
|
||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
|
||||
public class WorldGuardWeatherListener implements Listener {
|
||||
public class WorldGuardWeatherListener extends AbstractListener {
|
||||
|
||||
/**
|
||||
* Plugin.
|
||||
*/
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin The plugin instance
|
||||
*/
|
||||
public WorldGuardWeatherListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onWeatherChange(WeatherChangeEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
if (event.toWeatherState()) {
|
||||
if (wcfg.disableWeather) {
|
||||
|
@ -76,8 +59,7 @@ public class WorldGuardWeatherListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onThunderChange(ThunderChangeEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
if (event.toThunderState()) {
|
||||
if (wcfg.disableThunder) {
|
||||
|
@ -92,8 +74,7 @@ public class WorldGuardWeatherListener implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onLightningStrike(LightningStrikeEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getWorld());
|
||||
|
||||
if (!wcfg.disallowedLightningBlocks.isEmpty()) {
|
||||
final Block target = event.getLightning().getLocation().getBlock();
|
||||
|
|
|
@ -34,30 +34,17 @@ import org.bukkit.event.world.WorldLoadEvent;
|
|||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class WorldGuardWorldListener implements Listener {
|
||||
public class WorldGuardWorldListener extends AbstractListener {
|
||||
|
||||
private static final Logger log = Logger.getLogger(WorldGuardWorldListener.class.getCanonicalName());
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin The plugin instance
|
||||
*/
|
||||
public WorldGuardWorldListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
ConfigurationManager cfg = getConfig();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
int removed = 0;
|
||||
|
@ -89,8 +76,7 @@ public class WorldGuardWorldListener implements Listener {
|
|||
* @param world The specified world
|
||||
*/
|
||||
public void initWorld(World world) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
|
||||
WorldConfiguration wcfg = getWorldConfig(world);
|
||||
if (wcfg.alwaysRaining && !wcfg.disableWeather) {
|
||||
world.setStorm(true);
|
||||
} else if (wcfg.disableWeather && !wcfg.alwaysRaining) {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
|
@ -42,7 +41,7 @@ public class WorldRulesListener extends AbstractListener {
|
|||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onSpawnEntity(final SpawnEntityEvent event) {
|
||||
if (event.getEffectiveType() == EntityType.EXPERIENCE_ORB) {
|
||||
WorldConfiguration config = getWorldConfig(BukkitAdapter.adapt(event.getWorld()));
|
||||
WorldConfiguration config = getWorldConfig(event.getWorld());
|
||||
|
||||
if (config.disableExpDrops) {
|
||||
event.setCancelled(true);
|
||||
|
@ -53,7 +52,7 @@ public class WorldRulesListener extends AbstractListener {
|
|||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onPotionEffect(EntityPotionEffectEvent event) {
|
||||
if (event.getCause() == EntityPotionEffectEvent.Cause.CONDUIT) {
|
||||
WorldConfiguration config = getWorldConfig(BukkitAdapter.adapt(event.getEntity().getWorld()));
|
||||
WorldConfiguration config = getWorldConfig(event.getEntity().getWorld());
|
||||
|
||||
if (config.disableConduitEffects) {
|
||||
event.setCancelled(true);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package com.sk89q.worldguard.bukkit.listener.debounce.legacy;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.listener.debounce.legacy.InventoryMoveItemEventDebounce.Key;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
@ -44,18 +45,18 @@ public class InventoryMoveItemEventDebounce extends AbstractEventDebounce<Key> {
|
|||
private final Object target;
|
||||
|
||||
public Key(InventoryMoveItemEvent event) {
|
||||
cause = transform(event.getInitiator().getHolder());
|
||||
source = transform(event.getSource().getHolder());
|
||||
target = transform(event.getDestination().getHolder());
|
||||
cause = transform(PaperLib.getHolder(event.getInitiator(), false).getHolder());
|
||||
source = transform(PaperLib.getHolder(event.getSource(), false).getHolder());
|
||||
target = transform(PaperLib.getHolder(event.getDestination(), false).getHolder());
|
||||
}
|
||||
|
||||
private Object transform(InventoryHolder holder) {
|
||||
if (holder instanceof BlockState) {
|
||||
return new BlockMaterialKey(((BlockState) holder).getBlock());
|
||||
} else if (holder instanceof DoubleChest) {
|
||||
InventoryHolder left = ((DoubleChest) holder).getLeftSide();
|
||||
if (left instanceof Chest) {
|
||||
return new BlockMaterialKey(((Chest) left).getBlock());
|
||||
if (holder instanceof BlockState blockState) {
|
||||
return new BlockMaterialKey(blockState);
|
||||
} else if (holder instanceof DoubleChest doubleChest) {
|
||||
InventoryHolder left = PaperLib.isPaper() ? doubleChest.getLeftSide(false) : doubleChest.getLeftSide();
|
||||
if (left instanceof Chest chest) {
|
||||
return new BlockMaterialKey(chest);
|
||||
} else {
|
||||
return holder;
|
||||
}
|
||||
|
@ -94,8 +95,8 @@ public class InventoryMoveItemEventDebounce extends AbstractEventDebounce<Key> {
|
|||
private final Block block;
|
||||
private final Material material;
|
||||
|
||||
private BlockMaterialKey(Block block) {
|
||||
this.block = block;
|
||||
private BlockMaterialKey(BlockState block) {
|
||||
this.block = block.getBlock();
|
||||
material = block.getType();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,14 @@ import com.sk89q.worldguard.LocalPlayer;
|
|||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitPlayer;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
|
||||
import com.sk89q.worldguard.bukkit.util.Entities;
|
||||
import com.sk89q.worldguard.session.AbstractSessionManager;
|
||||
import com.sk89q.worldguard.session.Session;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
@ -57,7 +58,7 @@ public class BukkitSessionManager extends AbstractSessionManager implements Runn
|
|||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
public void onPlayerProcess(ProcessPlayerEvent event) {
|
||||
// Pre-load a session
|
||||
LocalPlayer player = WorldGuardPlugin.inst().wrapPlayer(event.getPlayer());
|
||||
get(player).initialize(player);
|
||||
|
@ -73,11 +74,22 @@ public class BukkitSessionManager extends AbstractSessionManager implements Runn
|
|||
|
||||
@Override
|
||||
public boolean hasBypass(LocalPlayer player, World world) {
|
||||
if (player instanceof BukkitPlayer) {
|
||||
if (((BukkitPlayer) player).getPlayer().hasMetadata("NPC")
|
||||
&& WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).fakePlayerBuildOverride)
|
||||
if (player instanceof BukkitPlayer bukkitPlayer) {
|
||||
if (Entities.isNPC(bukkitPlayer.getPlayer())
|
||||
&& WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).fakePlayerBuildOverride) {
|
||||
return true;
|
||||
}
|
||||
if (!((BukkitPlayer) player).getPlayer().isOnline()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return super.hasBypass(player, world);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
get(localPlayer).uninitialize(localPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.util;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.PluginClassLoader;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Validates that certain specified classes came from the same source as
|
||||
* a plugin.
|
||||
* This is copied from the same class in WorldEdit because unfortunately
|
||||
* trying to use WorldEdit's means we're susceptible to getting a bad version
|
||||
* of this class if another plugin shades it....which is exactly what we're
|
||||
* trying to detect and report.
|
||||
*/
|
||||
public class ClassSourceValidator {
|
||||
|
||||
private static final String SEPARATOR_LINE = Strings.repeat("*", 46);
|
||||
private static final Method loadClass;
|
||||
private static Class<?> pluginClassLoaderClass;
|
||||
|
||||
static {
|
||||
Method tmp;
|
||||
try {
|
||||
pluginClassLoaderClass = Class.forName("org.bukkit.plugin.java.PluginClassLoader", false,
|
||||
Bukkit.class.getClassLoader());
|
||||
tmp = pluginClassLoaderClass.getDeclaredMethod("loadClass0",
|
||||
String.class, boolean.class, boolean.class, boolean.class);
|
||||
tmp.setAccessible(true);
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
tmp = null;
|
||||
}
|
||||
loadClass = tmp;
|
||||
}
|
||||
|
||||
private final Plugin plugin;
|
||||
@Nullable
|
||||
private final ClassLoader expectedClassLoader;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param plugin The plugin
|
||||
*/
|
||||
public ClassSourceValidator(Plugin plugin) {
|
||||
checkNotNull(plugin, "plugin");
|
||||
this.plugin = plugin;
|
||||
this.expectedClassLoader = plugin.getClass().getClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a map of classes that been loaded from a different source.
|
||||
*
|
||||
* @param classes A list of classes to check
|
||||
* @return The results
|
||||
*/
|
||||
public Map<Class<?>, Plugin> findMismatches(List<Class<?>> classes) {
|
||||
checkNotNull(classes, "classes");
|
||||
|
||||
if (expectedClassLoader == null || loadClass == null) {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
Map<Class<?>, Plugin> mismatches = new HashMap<>();
|
||||
|
||||
for (Plugin target : Bukkit.getPluginManager().getPlugins()) {
|
||||
if (target == plugin) {
|
||||
continue;
|
||||
}
|
||||
ClassLoader targetLoader = target.getClass().getClassLoader();
|
||||
if (!(pluginClassLoaderClass.isAssignableFrom(targetLoader.getClass()))) {
|
||||
continue;
|
||||
}
|
||||
for (Class<?> testClass : classes) {
|
||||
Class<?> targetClass;
|
||||
try {
|
||||
targetClass = (Class<?>) loadClass.invoke(targetLoader, testClass.getName(), false, false, false);
|
||||
} catch (IllegalAccessException | InvocationTargetException ignored) {
|
||||
continue;
|
||||
}
|
||||
if (targetClass.getClassLoader() != expectedClassLoader) {
|
||||
mismatches.putIfAbsent(testClass, targetClass.getClassLoader() == targetLoader ? target : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mismatches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports classes that have come from a different source.
|
||||
*
|
||||
* <p>The warning is emitted to the log.</p>
|
||||
*
|
||||
* @param classes The list of classes to check
|
||||
*/
|
||||
public void reportMismatches(List<Class<?>> classes) {
|
||||
if (Boolean.getBoolean("enginehub.disable.class.source.validation")) {
|
||||
return;
|
||||
}
|
||||
Map<Class<?>, Plugin> mismatches = findMismatches(classes);
|
||||
|
||||
if (mismatches.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder("\n");
|
||||
|
||||
builder.append(SEPARATOR_LINE).append("\n");
|
||||
builder.append("** /!\\ SEVERE WARNING /!\\\n");
|
||||
builder.append("** \n");
|
||||
builder.append("** A plugin developer has included a portion of \n");
|
||||
builder.append("** ").append(plugin.getName()).append(" into their own plugin, so rather than using\n");
|
||||
builder.append("** the version of ").append(plugin.getName()).append(" that you downloaded, you\n");
|
||||
builder.append("** will be using a broken mix of old ").append(plugin.getName()).append(" (that came\n");
|
||||
builder.append("** with the plugin) and your downloaded version. THIS MAY\n");
|
||||
builder.append("** SEVERELY BREAK ").append(plugin.getName().toUpperCase(Locale.ROOT)).append(" AND ALL OF ITS FEATURES.\n");
|
||||
builder.append("**\n");
|
||||
builder.append("** This may have happened because the developer is using\n");
|
||||
builder.append("** the ").append(plugin.getName()).append(" API and thinks that including\n");
|
||||
builder.append("** ").append(plugin.getName()).append(" is necessary. However, it is not!\n");
|
||||
builder.append("**\n");
|
||||
builder.append("** Here are some files that have been overridden:\n");
|
||||
builder.append("** \n");
|
||||
for (Map.Entry<Class<?>, Plugin> entry : mismatches.entrySet()) {
|
||||
Plugin badPlugin = entry.getValue();
|
||||
String url = badPlugin == null
|
||||
? "(unknown)"
|
||||
: badPlugin.getName() + " (" + badPlugin.getClass().getProtectionDomain().getCodeSource().getLocation() + ")";
|
||||
builder.append("** '").append(entry.getKey().getSimpleName()).append("' came from '").append(url).append("'\n");
|
||||
}
|
||||
builder.append("**\n");
|
||||
builder.append("** Please report this to the plugins' developers.\n");
|
||||
builder.append(SEPARATOR_LINE).append("\n");
|
||||
|
||||
plugin.getLogger().severe(builder.toString());
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package com.sk89q.worldguard.bukkit.util;
|
||||
|
||||
import org.bukkit.entity.Allay;
|
||||
import org.bukkit.entity.Ambient;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Arrow;
|
||||
|
@ -33,16 +34,17 @@ import org.bukkit.entity.LivingEntity;
|
|||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.NPC;
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.Shulker;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.entity.SpectralArrow;
|
||||
import org.bukkit.entity.Steerable;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.entity.minecart.ExplosiveMinecart;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
|
@ -91,7 +93,7 @@ public final class Entities {
|
|||
* @return true if the entity can be ridden
|
||||
*/
|
||||
public static boolean isRiddenOnUse(Entity entity) {
|
||||
return entity instanceof Pig ? ((Pig) entity).hasSaddle() : entity instanceof Vehicle;
|
||||
return entity instanceof Steerable ? ((Steerable) entity).hasSaddle() : entity instanceof Vehicle;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,8 +103,20 @@ public final class Entities {
|
|||
* @return true if the type is a vehicle type
|
||||
*/
|
||||
public static boolean isVehicle(EntityType type) {
|
||||
return type == EntityType.BOAT
|
||||
|| isMinecart(type);
|
||||
return isBoat(type) || isMinecart(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given entity type is a Boat type.
|
||||
*
|
||||
* @param type the type
|
||||
* @return true if the type is a Boat type
|
||||
*/
|
||||
public static boolean isBoat(EntityType type) {
|
||||
return switch(type) {
|
||||
case BOAT, CHEST_BOAT -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,13 +126,11 @@ public final class Entities {
|
|||
* @return true if the type is a Minecart type
|
||||
*/
|
||||
public static boolean isMinecart(EntityType type) {
|
||||
return type == EntityType.MINECART
|
||||
|| type == EntityType.MINECART_CHEST
|
||||
|| type == EntityType.MINECART_COMMAND
|
||||
|| type == EntityType.MINECART_FURNACE
|
||||
|| type == EntityType.MINECART_HOPPER
|
||||
|| type == EntityType.MINECART_MOB_SPAWNER
|
||||
|| type == EntityType.MINECART_TNT;
|
||||
return switch(type) {
|
||||
case MINECART, CHEST_MINECART, COMMAND_BLOCK_MINECART, FURNACE_MINECART,
|
||||
HOPPER_MINECART, SPAWNER_MINECART, TNT_MINECART -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,6 +220,7 @@ public final class Entities {
|
|||
return entity instanceof Hanging
|
||||
|| entity instanceof ArmorStand
|
||||
|| entity instanceof EnderCrystal
|
||||
|| entity instanceof Allay
|
||||
|| entity instanceof Minecart && entity instanceof InventoryHolder;
|
||||
}
|
||||
|
||||
|
@ -218,4 +231,18 @@ public final class Entities {
|
|||
public static boolean isAoECloud(EntityType type) {
|
||||
return type == EntityType.AREA_EFFECT_CLOUD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the spawn reason should be considered as a "plugin spawning".
|
||||
* This is true for custom creations or the summon command.
|
||||
*
|
||||
* @param spawnReason the reason
|
||||
* @return true if considerd plugin spawning
|
||||
*/
|
||||
public static boolean isPluginSpawning(CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
return switch (spawnReason) {
|
||||
case CUSTOM, COMMAND -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public final class InteropUtils {
|
|||
UUID uuid = player.getUniqueId();
|
||||
String name = player.getName();
|
||||
|
||||
if (player.hasMetadata("NPC")) {
|
||||
if (Entities.isNPC(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.util.logging;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.security.CodeSource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Validates that certain specified classes came from the same source as
|
||||
* a plugin.
|
||||
*/
|
||||
public class ClassSourceValidator {
|
||||
|
||||
private static final Logger log = Logger.getLogger(ClassSourceValidator.class.getCanonicalName());
|
||||
private static final String separatorLine = Strings.repeat("*", 46);
|
||||
|
||||
private final Plugin plugin;
|
||||
@Nullable
|
||||
private final CodeSource expectedCodeSource;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param plugin The plugin
|
||||
*/
|
||||
public ClassSourceValidator(Plugin plugin) {
|
||||
checkNotNull(plugin, "plugin");
|
||||
this.plugin = plugin;
|
||||
this.expectedCodeSource = plugin.getClass().getProtectionDomain().getCodeSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a map of classes that been loaded from a different source.
|
||||
*
|
||||
* @param classes A list of classes to check
|
||||
* @return The results
|
||||
*/
|
||||
public Map<Class<?>, CodeSource> findMismatches(List<Class<?>> classes) {
|
||||
checkNotNull(classes, "classes");
|
||||
|
||||
Map<Class<?>, CodeSource> mismatches = Maps.newHashMap();
|
||||
|
||||
if (expectedCodeSource != null) {
|
||||
for (Class<?> testClass : classes) {
|
||||
CodeSource testSource = testClass.getProtectionDomain().getCodeSource();
|
||||
if (!expectedCodeSource.equals(testSource)) {
|
||||
mismatches.put(testClass, testSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mismatches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports classes that have come from a different source.
|
||||
*
|
||||
* <p>The warning is emitted to the log.</p>
|
||||
*
|
||||
* @param classes The list of classes to check
|
||||
*/
|
||||
public void reportMismatches(List<Class<?>> classes) {
|
||||
if (Boolean.getBoolean("worldguard.disable.class.validation")) {
|
||||
return;
|
||||
}
|
||||
Map<Class<?>, CodeSource> mismatches = findMismatches(classes);
|
||||
|
||||
if (!mismatches.isEmpty()) {
|
||||
StringBuilder builder = new StringBuilder("\n");
|
||||
|
||||
builder.append(separatorLine).append("\n");
|
||||
builder.append("** /!\\ SEVERE WARNING /!\\\n");
|
||||
builder.append("** \n");
|
||||
builder.append("** A plugin developer has copied and pasted a portion of \n");
|
||||
builder.append("** ").append(plugin.getName()).append(" into their own plugin, so rather than using\n");
|
||||
builder.append("** the version of ").append(plugin.getName()).append(" that you downloaded, you\n");
|
||||
builder.append("** will be using a broken mix of old ").append(plugin.getName()).append(" (that came\n");
|
||||
builder.append("** with the plugin) and your downloaded version. THIS MAY\n");
|
||||
builder.append("** SEVERELY BREAK ").append(plugin.getName().toUpperCase()).append(" AND ALL OF ITS FEATURES.\n");
|
||||
builder.append("**\n");
|
||||
builder.append("** This may have happened because the developer is using\n");
|
||||
builder.append("** the ").append(plugin.getName()).append(" API and thinks that including\n");
|
||||
builder.append("** ").append(plugin.getName()).append(" is necessary. However, it is not!\n");
|
||||
builder.append("**\n");
|
||||
builder.append("** Here are some files that have been overridden:\n");
|
||||
builder.append("** \n");
|
||||
for (Map.Entry<Class<?>, CodeSource> entry : mismatches.entrySet()) {
|
||||
CodeSource codeSource = entry.getValue();
|
||||
String url = codeSource != null ? codeSource.getLocation().toExternalForm() : "(unknown)";
|
||||
builder.append("** '").append(entry.getKey().getSimpleName()).append("' came from '").append(url).append("'\n");
|
||||
}
|
||||
builder.append("**\n");
|
||||
builder.append("** Please report this to the plugins' developers.\n");
|
||||
builder.append(separatorLine).append("\n");
|
||||
|
||||
log.log(Level.SEVERE, builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.util.report;
|
||||
|
||||
import com.sk89q.worldedit.util.report.DataReport;
|
||||
import io.papermc.paper.datapack.Datapack;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A report for current datapacks with some information. Only available on Paper
|
||||
*/
|
||||
public class DatapackReport extends DataReport {
|
||||
public DatapackReport() {
|
||||
super("DataPacks");
|
||||
|
||||
Collection<Datapack> packs = Bukkit.getDatapackManager().getPacks();
|
||||
|
||||
append("Datapack Count", packs.size());
|
||||
append("Datapack Enabled Count", Bukkit.getDatapackManager().getEnabledPacks().size());
|
||||
|
||||
for (Datapack pack : packs) {
|
||||
DataReport report = new DataReport("DataPack: " + pack.getName());
|
||||
report.append("Enabled?", pack.isEnabled());
|
||||
report.append("Name", pack.getName());
|
||||
report.append("Compatibility", pack.getCompatibility().name());
|
||||
append(report.getTitle(), report);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
package com.sk89q.worldguard.bukkit.util.report;
|
||||
|
||||
import com.sk89q.worldedit.util.report.DataReport;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
||||
|
@ -33,9 +34,18 @@ public class ServerReport extends DataReport {
|
|||
append("Bukkit Version", server.getBukkitVersion());
|
||||
append("Implementation", server.getName() + " " + server.getVersion());
|
||||
append("Player Count", "%d/%d", Bukkit.getOnlinePlayers().size(), server.getMaxPlayers());
|
||||
|
||||
append("Server Class Source", server.getClass().getProtectionDomain().getCodeSource().getLocation());
|
||||
|
||||
DataReport onlineMode = new DataReport("Online Mode");
|
||||
onlineMode.append("enabled?", server.getOnlineMode());
|
||||
if (PaperLib.isSpigot()) {
|
||||
onlineMode.append("BungeeCord support?", Bukkit.spigot().getConfig().getBoolean("settings.bungeecord", false));
|
||||
}
|
||||
if (PaperLib.isPaper()) {
|
||||
onlineMode.append("Velocity support?", Bukkit.spigot().getPaperConfig().getBoolean("proxies.velocity.enabled", false));
|
||||
}
|
||||
append(onlineMode.getTitle(), onlineMode);
|
||||
|
||||
DataReport spawning = new DataReport("Spawning");
|
||||
spawning.append("Ambient Spawn Limit", server.getAmbientSpawnLimit());
|
||||
spawning.append("Animal Spawn Limit", server.getAnimalSpawnLimit());
|
||||
|
|
|
@ -19,14 +19,19 @@
|
|||
|
||||
package com.sk89q.worldguard.util.profile.resolver;
|
||||
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link com.sk89q.worldguard.util.profile.resolver.PaperPlayerService} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final class PaperProfileService extends SingleRequestService {
|
||||
private static final PaperPlayerService SUPER = PaperPlayerService.getInstance();
|
||||
private static final PaperProfileService INSTANCE = new PaperProfileService();
|
||||
|
||||
private PaperProfileService() {
|
||||
|
@ -37,18 +42,19 @@ public final class PaperProfileService extends SingleRequestService {
|
|||
|
||||
@Override
|
||||
public int getIdealRequestLimit() {
|
||||
return Integer.MAX_VALUE;
|
||||
return SUPER.getIdealRequestLimit();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Profile findByName(String name) {
|
||||
PlayerProfile profile = Bukkit.createProfile(name);
|
||||
if (profile.completeFromCache()) {
|
||||
//noinspection ConstantConditions - completeFromCache guarantees non-null on success
|
||||
return new Profile(profile.getId(), profile.getName());
|
||||
}
|
||||
return null;
|
||||
public Profile findByName(String name) throws IOException, InterruptedException {
|
||||
return SUPER.findByName(name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Profile findByUuid(UUID uuid) throws IOException, InterruptedException {
|
||||
return SUPER.findByUuid(uuid);
|
||||
}
|
||||
|
||||
public static PaperProfileService getInstance() {
|
||||
|
|
|
@ -3,4 +3,4 @@ main: com.sk89q.worldguard.bukkit.WorldGuardPlugin
|
|||
version: "${internalVersion}"
|
||||
depend: [WorldEdit]
|
||||
softdepend: [CommandBook]
|
||||
api-version: 1.13
|
||||
api-version: "1.20"
|
||||
|
|
|
@ -1,31 +1,20 @@
|
|||
plugins {
|
||||
id("java-library")
|
||||
id("net.ltgt.apt-eclipse")
|
||||
id("net.ltgt.apt-idea")
|
||||
`java-library`
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
|
||||
dependencies {
|
||||
"compile"(project(":worldguard-libs:core"))
|
||||
"compile"("com.sk89q.worldedit:worldedit-core:7.0.1-SNAPSHOT")
|
||||
"api"(project(":worldguard-libs:core"))
|
||||
"api"("com.sk89q.worldedit:worldedit-core:${Versions.WORLDEDIT}")
|
||||
"implementation"("org.flywaydb:flyway-core:3.0")
|
||||
"implementation"("org.yaml:snakeyaml:2.0")
|
||||
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
|
||||
|
||||
"compileOnly"("com.google.code.findbugs:jsr305:1.3.9")
|
||||
"testImplementation"("org.hamcrest:hamcrest-library:1.2.1")
|
||||
"compileOnly"("com.google.code.findbugs:jsr305:${Versions.FINDBUGS}")
|
||||
"testImplementation"("org.hamcrest:hamcrest-library:2.2")
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
dependsOn(":worldguard-libs:build")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir("src/main/java")
|
||||
}
|
||||
resources {
|
||||
srcDir("src/main/resources")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldguard.domains.registry.DomainRegistry;
|
||||
import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
|
||||
import com.sk89q.worldguard.util.profile.cache.HashMapCache;
|
||||
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
|
||||
import com.sk89q.worldguard.util.profile.cache.SQLiteCache;
|
||||
|
@ -55,6 +57,7 @@ public final class WorldGuard {
|
|||
|
||||
private WorldGuardPlatform platform;
|
||||
private final SimpleFlagRegistry flagRegistry = new SimpleFlagRegistry();
|
||||
private final SimpleDomainRegistry domainRegistry = new SimpleDomainRegistry();
|
||||
private final Supervisor supervisor = new SimpleSupervisor();
|
||||
private ProfileCache profileCache;
|
||||
private ProfileService profileService;
|
||||
|
@ -93,11 +96,12 @@ public final class WorldGuard {
|
|||
|
||||
/**
|
||||
* The WorldGuard Platform.
|
||||
* The Platform is only available after WorldGuard is enabled.
|
||||
*
|
||||
* @return The platform
|
||||
*/
|
||||
public WorldGuardPlatform getPlatform() {
|
||||
checkNotNull(platform);
|
||||
checkNotNull(platform, "WorldGuard is not enabled, unable to access the platform.");
|
||||
return platform;
|
||||
}
|
||||
|
||||
|
@ -115,6 +119,16 @@ public final class WorldGuard {
|
|||
return this.flagRegistry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the domain registry.
|
||||
*
|
||||
* @return the domain registry
|
||||
*/
|
||||
public DomainRegistry getDomainRegistry() {
|
||||
return this.domainRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the supervisor.
|
||||
*
|
||||
|
|
|
@ -95,9 +95,9 @@ public class DatabaseHandler implements LoggerHandler {
|
|||
stmt.setString(1, eventType.name());
|
||||
stmt.setString(2, worldName);
|
||||
stmt.setString(3, player != null ? player.getName() : "");
|
||||
stmt.setInt(4, pos.getBlockX());
|
||||
stmt.setInt(5, pos.getBlockY());
|
||||
stmt.setInt(6, pos.getBlockZ());
|
||||
stmt.setInt(4, pos.x());
|
||||
stmt.setInt(5, pos.y());
|
||||
stmt.setInt(6, pos.z());
|
||||
stmt.setString(7, item);
|
||||
stmt.setInt(8, (int)(System.currentTimeMillis() / 1000));
|
||||
stmt.setString(9, comment);
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.sk89q.worldguard.LocalPlayer;
|
|||
import com.sk89q.worldguard.blacklist.event.BlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.target.Target;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
|
@ -87,13 +88,13 @@ public class FileHandler implements LoggerHandler {
|
|||
* Build the path.
|
||||
*
|
||||
* @param playerName The name of the player
|
||||
* @return The path for the logfile
|
||||
* @return The path for the logfile, null when no applicable path could be found
|
||||
*/
|
||||
private String buildPath(String playerName) {
|
||||
private @Nullable String buildPath(@Nullable String playerName) {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
|
||||
Matcher m = pattern.matcher(pathPattern);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
// Pattern replacements
|
||||
while (m.find()) {
|
||||
|
@ -103,12 +104,13 @@ public class FileHandler implements LoggerHandler {
|
|||
if (group.matches("%%")) {
|
||||
rep = "%";
|
||||
} else if (group.matches("%u")) {
|
||||
if (playerName == null) return null; // Unable to create a path for non player logging events
|
||||
rep = playerName.toLowerCase().replaceAll("[^A-Za-z0-9_]", "_");
|
||||
if (rep.length() > 32) { // Actual max length is 16
|
||||
rep = rep.substring(0, 32);
|
||||
}
|
||||
|
||||
}else if (group.matches("%w")) {
|
||||
} else if (group.matches("%w")) {
|
||||
rep = worldName.toLowerCase().replaceAll("[^A-Za-z0-9_]", "_");
|
||||
if (rep.length() > 32) { // Actual max length is 16
|
||||
rep = rep.substring(0, 32);
|
||||
|
@ -148,11 +150,12 @@ public class FileHandler implements LoggerHandler {
|
|||
* @param message The message to log
|
||||
* @param comment The comment associated with the logged event
|
||||
*/
|
||||
private void log(LocalPlayer player, String message, String comment) {
|
||||
String path = buildPath(player.getName());
|
||||
private void log(@Nullable LocalPlayer player, String message, String comment) {
|
||||
String path = buildPath(player != null ? player.getName() : null);
|
||||
if (path == null) return;
|
||||
try {
|
||||
String date = dateFormat.format(new Date());
|
||||
String line = "[" + date + "] " + player.getName() + ": " + message
|
||||
String line = "[" + date + "] " + (player != null ? player.getName() : "Unknown Source") + ": " + message
|
||||
+ (comment != null ? " (" + comment + ")" : "") + "\r\n";
|
||||
|
||||
LogFileWriter writer = writers.get(path);
|
||||
|
@ -190,7 +193,7 @@ public class FileHandler implements LoggerHandler {
|
|||
writers.entrySet().iterator();
|
||||
|
||||
// Remove some entries
|
||||
for (; it.hasNext(); ) {
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String,LogFileWriter> entry = it.next();
|
||||
try {
|
||||
entry.getValue().getWriter().close();
|
||||
|
@ -218,7 +221,7 @@ public class FileHandler implements LoggerHandler {
|
|||
* @return The position's coordinates in human-readable form
|
||||
*/
|
||||
private String getCoordinates(BlockVector3 pos) {
|
||||
return "@" + pos.getBlockX() + "," + pos.getBlockY() + "," + pos.getBlockZ();
|
||||
return "@" + pos.x() + "," + pos.y() + "," + pos.z();
|
||||
}
|
||||
|
||||
private void logEvent(BlacklistEvent event, String text, Target target, BlockVector3 pos, String comment) {
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.commands;
|
||||
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class CommandInputContext<T extends Exception> {
|
||||
protected final Actor sender;
|
||||
protected final String input;
|
||||
|
||||
protected Map<String, Object> context;
|
||||
|
||||
protected CommandInputContext(Actor sender, String input, Map<String, Object> values) {
|
||||
this.sender = sender;
|
||||
this.input = input;
|
||||
this.context = values;
|
||||
}
|
||||
|
||||
public void put(String name, Object value) {
|
||||
context.put(name, value);
|
||||
}
|
||||
|
||||
public Actor getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public String getUserInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CommandSender as a player.
|
||||
*
|
||||
* @return Player
|
||||
* @throws T if the sender is not a player
|
||||
*/
|
||||
public LocalPlayer getPlayerSender() throws T {
|
||||
if (sender.isPlayer() && sender instanceof LocalPlayer) {
|
||||
return (LocalPlayer) sender;
|
||||
} else {
|
||||
throw createException("Not a player");
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getUserInputAsInt() throws T {
|
||||
try {
|
||||
return Integer.parseInt(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw createException("Not a number: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
public Double getUserInputAsDouble() throws T {
|
||||
try {
|
||||
return Double.parseDouble(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw createException("Not a number: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T createException(String str);
|
||||
|
||||
/**
|
||||
* Get an object from the context by key name.
|
||||
* May return null if the object does not exist in the context.
|
||||
*
|
||||
* @param name key name of the object
|
||||
* @return the object matching the key, or null
|
||||
*/
|
||||
@Nullable
|
||||
public Object get(String name) {
|
||||
return get(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the context by key name.
|
||||
* Will only return null if
|
||||
* a) you provide null as the default
|
||||
* b) the key has explicity been set to null
|
||||
*
|
||||
* @param name key name of the object
|
||||
* @return the object matching the key
|
||||
*/
|
||||
@Nullable
|
||||
public Object get(String name, Object defaultValue) {
|
||||
Object obj;
|
||||
return (((obj = context.get(name)) != null) || context.containsKey(name)
|
||||
? obj : defaultValue);
|
||||
}
|
||||
}
|
|
@ -226,7 +226,7 @@ public class WorldGuardCommands {
|
|||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
|
||||
Futures.addCallback(sampler.getFuture(), new FutureCallback<Sampler>() {
|
||||
Futures.addCallback(sampler.getFuture(), new FutureCallback<>() {
|
||||
@Override
|
||||
public void onSuccess(Sampler result) {
|
||||
String output = result.toString();
|
||||
|
@ -247,7 +247,7 @@ public class WorldGuardCommands {
|
|||
@Override
|
||||
public void onFailure(Throwable throwable) {
|
||||
}
|
||||
});
|
||||
}, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
@Command(aliases = {"stopprofile"}, usage = "",desc = "Stop a running profile", min = 0, max = 0)
|
||||
|
|
|
@ -46,6 +46,7 @@ import com.sk89q.worldguard.protection.flags.RegistryFlag;
|
|||
import com.sk89q.worldguard.protection.flags.SetFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StringFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.UnknownFlag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -75,7 +76,7 @@ class FlagHelperBox extends PaginationBox {
|
|||
.collect(Collectors.toList());
|
||||
private static final int SIZE = FLAGS.size() == Flags.INBUILT_FLAGS.size() ? FLAGS.size() : FLAGS.size() + 1;
|
||||
private static final int PAD_PX_SIZE = 180;
|
||||
private static final Set<Flag<?>> DANGER_ZONE = ImmutableSet.of(Flags.BUILD, Flags.PASSTHROUGH, Flags.BLOCK_PLACE, Flags.BLOCK_BREAK);
|
||||
static final Set<Flag<?>> DANGER_ZONE = ImmutableSet.of(Flags.BUILD, Flags.PASSTHROUGH, Flags.BLOCK_PLACE, Flags.BLOCK_BREAK);
|
||||
|
||||
private final World world;
|
||||
private final ProtectedRegion region;
|
||||
|
@ -108,7 +109,7 @@ class FlagHelperBox extends PaginationBox {
|
|||
private Component createLine(Flag<?> flag, boolean thirdParty) {
|
||||
final TextComponent.Builder builder = TextComponent.builder("");
|
||||
|
||||
appendFlagName(builder, flag, thirdParty ? TextColor.LIGHT_PURPLE : TextColor.GOLD);
|
||||
appendFlagName(builder, flag, flag instanceof UnknownFlag ? TextColor.GRAY : thirdParty ? TextColor.LIGHT_PURPLE : TextColor.GOLD);
|
||||
appendFlagValue(builder, flag);
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -199,7 +200,7 @@ class FlagHelperBox extends PaginationBox {
|
|||
if (maySet) {
|
||||
if (isExplicitSet) {
|
||||
hoverTexts.add(TextComponent.of("Click to unset", TextColor.GOLD));
|
||||
} else if (DANGER_ZONE.contains(flag)) {
|
||||
} else if (DANGER_ZONE.contains(flag) && !(ProtectedRegion.GLOBAL_REGION.equals(region.getId()) && flag == Flags.PASSTHROUGH)) {
|
||||
hoverTexts.add(TextComponent.of("Setting this flag may have unintended consequences.", TextColor.RED)
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("Please read the documentation and set this flag manually if you really intend to.")
|
||||
|
@ -255,7 +256,7 @@ class FlagHelperBox extends PaginationBox {
|
|||
|
||||
boolean isExplicitSet = currVal != null && !inherited;
|
||||
|
||||
boolean maySet = perms.maySetFlag(region, flag);
|
||||
boolean maySet = !(flag instanceof UnknownFlag) && perms.maySetFlag(region, flag);
|
||||
|
||||
TextColor col = isExplicitSet ? TextColor.WHITE : inherited ? TextColor.GRAY : TextColor.DARK_GRAY;
|
||||
Set<TextDecoration> styles = currVal == defVal ? ImmutableSet.of(TextDecoration.UNDERLINED) : Collections.emptySet();
|
||||
|
@ -359,11 +360,9 @@ class FlagHelperBox extends PaginationBox {
|
|||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
List<V> values = currVal == null ? Collections.emptyList() : (List<V>) flag.marshal(currVal);
|
||||
String display = (currVal == null ? "" : currVal.size() + "x ") + subName;
|
||||
final String stringValue = currVal == null ? ""
|
||||
: values.stream().map(String::valueOf).collect(Collectors.joining(","));
|
||||
: currVal.stream().map(String::valueOf).collect(Collectors.joining(","));
|
||||
TextComponent hoverComp = TextComponent.of("");
|
||||
if (currVal != null) {
|
||||
hoverComp = hoverComp.append(TextComponent.of("Current values:"))
|
||||
|
@ -379,7 +378,7 @@ class FlagHelperBox extends PaginationBox {
|
|||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
String display = currVal == null ? regName : currVal.getId();
|
||||
String display = currVal == null ? regName : currVal.id();
|
||||
appendValueText(builder, flag, display, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,16 +25,27 @@ import com.sk89q.minecraft.util.commands.CommandException;
|
|||
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.domains.registry.DomainFactory;
|
||||
import com.sk89q.worldguard.domains.registry.DomainRegistry;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.util.DomainInputResolver;
|
||||
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class MemberCommands extends RegionCommandsBase {
|
||||
|
@ -67,6 +78,8 @@ public class MemberCommands extends RegionCommandsBase {
|
|||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
|
||||
resolver.setActor(sender);
|
||||
resolver.setRegion(region);
|
||||
|
||||
|
||||
final String description = String.format("Adding members to the region '%s' on '%s'", region.getId(), world.getName());
|
||||
|
@ -101,7 +114,8 @@ public class MemberCommands extends RegionCommandsBase {
|
|||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
|
||||
|
||||
resolver.setActor(sender);
|
||||
resolver.setRegion(region);
|
||||
|
||||
final String description = String.format("Adding owners to the region '%s' on '%s'", region.getId(), world.getName());
|
||||
AsyncCommandBuilder.wrap(checkedAddOwners(sender, manager, region, world, resolver), sender)
|
||||
|
@ -174,6 +188,8 @@ public class MemberCommands extends RegionCommandsBase {
|
|||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
|
||||
resolver.setActor(sender);
|
||||
resolver.setRegion(region);
|
||||
|
||||
callable = resolver;
|
||||
}
|
||||
|
@ -217,6 +233,8 @@ public class MemberCommands extends RegionCommandsBase {
|
|||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
|
||||
resolver.setActor(sender);
|
||||
resolver.setRegion(region);
|
||||
|
||||
callable = resolver;
|
||||
}
|
||||
|
|
|
@ -21,16 +21,17 @@ package com.sk89q.worldguard.commands.region;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||
import com.sk89q.worldedit.util.formatting.component.LabelFormat;
|
||||
|
@ -42,9 +43,9 @@ import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
|||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.commands.CommandUtils;
|
||||
import com.sk89q.worldguard.commands.task.RegionAdder;
|
||||
import com.sk89q.worldguard.commands.task.RegionLister;
|
||||
import com.sk89q.worldguard.commands.task.RegionManagerLoader;
|
||||
|
@ -54,10 +55,11 @@ import com.sk89q.worldguard.config.ConfigurationManager;
|
|||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.FlagValueCalculator;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.FlagContext;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormatException;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
|
@ -66,6 +68,7 @@ import com.sk89q.worldguard.protection.managers.RemovalStrategy;
|
|||
import com.sk89q.worldguard.protection.managers.migration.DriverMigration;
|
||||
import com.sk89q.worldguard.protection.managers.migration.MigrationException;
|
||||
import com.sk89q.worldguard.protection.managers.migration.UUIDMigration;
|
||||
import com.sk89q.worldguard.protection.managers.migration.WorldHeightMigration;
|
||||
import com.sk89q.worldguard.protection.managers.storage.DriverType;
|
||||
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
|
@ -74,6 +77,7 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
|||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
|
||||
import com.sk89q.worldguard.protection.util.WorldEditRegionConverter;
|
||||
import com.sk89q.worldguard.session.Session;
|
||||
import com.sk89q.worldguard.util.Enums;
|
||||
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
|
||||
|
@ -129,22 +133,22 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
* @throws CommandException any error
|
||||
*/
|
||||
@Command(aliases = {"define", "def", "d", "create"},
|
||||
usage = "<id> [<owner1> [<owner2> [<owners...>]]]",
|
||||
flags = "ng",
|
||||
usage = "[-w <world>] <id> [<owner1> [<owner2> [<owners...>]]]",
|
||||
flags = "ngw:",
|
||||
desc = "Defines a region",
|
||||
min = 1)
|
||||
public void define(CommandContext args, Actor sender) throws CommandException {
|
||||
warnAboutSaveFailures(sender);
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(player).mayDefine()) {
|
||||
if (!getPermissionModel(sender).mayDefine()) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
String id = checkRegionId(args.getString(0), false);
|
||||
|
||||
RegionManager manager = checkRegionManager(player.getWorld());
|
||||
World world = checkWorld(args, sender, 'w');
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
|
||||
checkRegionDoesNotExist(manager, id, true);
|
||||
|
||||
|
@ -153,10 +157,10 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
if (args.hasFlag('g')) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
region = checkRegionFromSelection(player, id);
|
||||
region = checkRegionFromSelection(sender, id);
|
||||
}
|
||||
|
||||
RegionAdder task = new RegionAdder(manager, region);
|
||||
RegionAdder task = new RegionAdder(manager, region, sender);
|
||||
task.addOwnersFromCommand(args, 2);
|
||||
|
||||
final String description = String.format("Adding region '%s'", region.getId());
|
||||
|
@ -167,6 +171,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
sender.print(String.format("A new region has been made named '%s'.", region.getId()));
|
||||
warnAboutDimensions(sender, region);
|
||||
informNewUser(sender, manager, region);
|
||||
checkSpawnOverlap(sender, world, region);
|
||||
})
|
||||
.onFailure(String.format("Failed to add the region '%s'", region.getId()), worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
|
@ -180,23 +185,22 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
* @throws CommandException any error
|
||||
*/
|
||||
@Command(aliases = {"redefine", "update", "move"},
|
||||
usage = "<id>",
|
||||
usage = "[-w <world>] <id>",
|
||||
desc = "Re-defines the shape of a region",
|
||||
flags = "g",
|
||||
flags = "gw:",
|
||||
min = 1, max = 1)
|
||||
public void redefine(CommandContext args, Actor sender) throws CommandException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
|
||||
String id = checkRegionId(args.getString(0), false);
|
||||
|
||||
RegionManager manager = checkRegionManager(player.getWorld());
|
||||
World world = checkWorld(args, sender, 'w');
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
|
||||
ProtectedRegion existing = checkExistingRegion(manager, id, false);
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(player).mayRedefine(existing)) {
|
||||
if (!getPermissionModel(sender).mayRedefine(existing)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
|
@ -205,12 +209,12 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
if (args.hasFlag('g')) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
region = checkRegionFromSelection(player, id);
|
||||
region = checkRegionFromSelection(sender, id);
|
||||
}
|
||||
|
||||
region.copyFrom(existing);
|
||||
|
||||
RegionAdder task = new RegionAdder(manager, region);
|
||||
RegionAdder task = new RegionAdder(manager, region, sender);
|
||||
|
||||
final String description = String.format("Updating region '%s'", region.getId());
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
|
@ -218,9 +222,10 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
.sendMessageAfterDelay("(Please wait... " + description + ")")
|
||||
.onSuccess((Component) null,
|
||||
t -> {
|
||||
player.print(String.format("Region '%s' has been updated with a new area.", region.getId()));
|
||||
warnAboutDimensions(player, region);
|
||||
informNewUser(player, manager, region);
|
||||
sender.print(String.format("Region '%s' has been updated with a new area.", region.getId()));
|
||||
warnAboutDimensions(sender, region);
|
||||
informNewUser(sender, manager, region);
|
||||
checkSpawnOverlap(sender, world, region);
|
||||
})
|
||||
.onFailure(String.format("Failed to update the region '%s'", region.getId()), worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
|
@ -280,7 +285,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
}
|
||||
}
|
||||
|
||||
// We have to check whether this region violates the space of any other reion
|
||||
// We have to check whether this region violates the space of any other region
|
||||
ApplicableRegionSet regions = manager.getApplicableRegions(region);
|
||||
|
||||
// Check if this region overlaps any other region
|
||||
|
@ -313,17 +318,21 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
}
|
||||
}
|
||||
|
||||
RegionAdder task = new RegionAdder(manager, region);
|
||||
task.setLocatorPolicy(UserLocatorPolicy.UUID_ONLY);
|
||||
task.setOwnersInput(new String[]{player.getName()});
|
||||
// Inherit from a template region
|
||||
if (!Strings.isNullOrEmpty(wcfg.setParentOnClaim)) {
|
||||
ProtectedRegion templateRegion = manager.getRegion(wcfg.setParentOnClaim);
|
||||
if (templateRegion != null) {
|
||||
try {
|
||||
region.setParent(templateRegion);
|
||||
} catch (CircularInheritanceException e) {
|
||||
throw new CommandException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final String description = String.format("Claiming region '%s'", id);
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), description)
|
||||
.sendMessageAfterDelay("(Please wait... " + description + ")")
|
||||
.onSuccess(TextComponent.of(String.format("A new region has been claimed named '%s'.", id)), null)
|
||||
.onFailure("Failed to claim region", WorldGuard.getInstance().getExceptionConverter())
|
||||
.buildAndExec(WorldGuard.getInstance().getExecutorService());
|
||||
region.getOwners().addPlayer(player);
|
||||
manager.addRegion(region);
|
||||
player.print(TextComponent.of(String.format("A new region has been claimed named '%s'.", id)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -334,28 +343,34 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
* @throws CommandException any error
|
||||
*/
|
||||
@Command(aliases = {"select", "sel", "s"},
|
||||
usage = "[id]",
|
||||
usage = "[-w <world>] [id]",
|
||||
desc = "Load a region as a WorldEdit selection",
|
||||
min = 0, max = 1)
|
||||
min = 0, max = 1,
|
||||
flags = "w:")
|
||||
public void select(CommandContext args, Actor sender) throws CommandException {
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
RegionManager manager = checkRegionManager(player.getWorld());
|
||||
World world = checkWorld(args, sender, 'w');
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion existing;
|
||||
|
||||
// If no arguments were given, get the region that the player is inside
|
||||
if (args.argsLength() == 0) {
|
||||
existing = checkRegionStandingIn(manager, player, "/rg select %id%");
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
if (!player.getWorld().equals(world)) { // confusing to get current location regions in another world
|
||||
throw new CommandException("Please specify a region name."); // just don't allow that
|
||||
}
|
||||
world = player.getWorld();
|
||||
existing = checkRegionStandingIn(manager, player, "/rg select -w \"" + world.getName() + "\" %id%");
|
||||
} else {
|
||||
existing = checkExistingRegion(manager, args.getString(0), false);
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
if (!getPermissionModel(player).maySelect(existing)) {
|
||||
if (!getPermissionModel(sender).maySelect(existing)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
// Select
|
||||
setPlayerSelection(player, existing);
|
||||
setPlayerSelection(sender, existing, world);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -403,7 +418,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
setPlayerSelection(worldGuard.checkPlayer(sender), existing);
|
||||
setPlayerSelection(worldGuard.checkPlayer(sender), existing, world);
|
||||
}
|
||||
|
||||
// Print region information
|
||||
|
@ -413,7 +428,10 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
AsyncCommandBuilder.wrap(printout, sender)
|
||||
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Fetching region info")
|
||||
.sendMessageAfterDelay("(Please wait... fetching region information...)")
|
||||
.onSuccess((Component) null, sender::print)
|
||||
.onSuccess((Component) null, component -> {
|
||||
sender.print(component);
|
||||
checkSpawnOverlap(sender, world, existing);
|
||||
})
|
||||
.onFailure("Failed to fetch region information", WorldGuard.getInstance().getExceptionConverter())
|
||||
.buildAndExec(WorldGuard.getInstance().getExecutorService());
|
||||
}
|
||||
|
@ -426,9 +444,9 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
* @throws CommandException any error
|
||||
*/
|
||||
@Command(aliases = {"list"},
|
||||
usage = "[page]",
|
||||
usage = "[-w world] [-p owner [-n]] [-s] [-i filter] [page]",
|
||||
desc = "Get a list of regions",
|
||||
flags = "np:w:",
|
||||
flags = "np:w:i:s",
|
||||
max = 1)
|
||||
public void list(CommandContext args, Actor sender) throws CommandException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
@ -465,6 +483,16 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
task.filterOwnedByName(ownedBy, args.hasFlag('n'));
|
||||
}
|
||||
|
||||
if (args.hasFlag('s')) {
|
||||
ProtectedRegion existing = checkRegionFromSelection(sender, "tmp");
|
||||
task.filterByIntersecting(existing);
|
||||
}
|
||||
|
||||
// -i string is in region id
|
||||
if (args.hasFlag('i')) {
|
||||
task.filterIdByMatch(args.getFlag('i'));
|
||||
}
|
||||
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Getting region list")
|
||||
.sendMessageAfterDelay("(Please wait... fetching region list...)")
|
||||
|
@ -559,7 +587,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
// the [value] part throws an error.
|
||||
try {
|
||||
groupValue = groupFlag.parseInput(FlagContext.create().setSender(sender).setInput(group).setObject("region", existing).build());
|
||||
} catch (InvalidFlagFormat e) {
|
||||
} catch (InvalidFlagFormatException e) {
|
||||
throw new CommandException(e.getMessage());
|
||||
}
|
||||
|
||||
|
@ -570,7 +598,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
// Set the flag if [value] was given even if [-g group] was given as well
|
||||
try {
|
||||
value = setFlag(existing, foundFlag, sender, value).toString();
|
||||
} catch (InvalidFlagFormat e) {
|
||||
} catch (InvalidFlagFormatException e) {
|
||||
throw new CommandException(e.getMessage());
|
||||
}
|
||||
|
||||
|
@ -618,6 +646,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
printout.appendFlagsList(false);
|
||||
printout.append(SubtleFormat.wrap(")"));
|
||||
printout.send(sender);
|
||||
checkSpawnOverlap(sender, world, existing);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,7 +663,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
ProtectedRegion region;
|
||||
if (args.argsLength() == 0) { // Get region from where the player is
|
||||
if (!(sender instanceof LocalPlayer)) {
|
||||
throw new CommandException("Please specify the region with /region info -w world_name region_name.");
|
||||
throw new CommandException("Please specify the region with /region flags -w world_name region_name.");
|
||||
}
|
||||
|
||||
region = checkRegionStandingIn(manager, (LocalPlayer) sender, true,
|
||||
|
@ -658,7 +687,12 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
if (!sender.isPlayer()) {
|
||||
flagHelperBox.tryMonoSpacing();
|
||||
}
|
||||
AsyncCommandBuilder.wrap(() -> flagHelperBox.create(page), sender)
|
||||
AsyncCommandBuilder.wrap(() -> {
|
||||
if (checkSpawnOverlap(sender, world, region)) {
|
||||
flagHelperBox.setComponentsPerPage(15);
|
||||
}
|
||||
return flagHelperBox.create(page);
|
||||
}, sender)
|
||||
.onSuccess((Component) null, sender::print)
|
||||
.onFailure("Failed to get region flags", WorldGuard.getInstance().getExceptionConverter())
|
||||
.buildAndExec(WorldGuard.getInstance().getExecutorService());
|
||||
|
@ -694,6 +728,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
existing.setPriority(priority);
|
||||
|
||||
sender.print("Priority of '" + existing.getId() + "' set to " + priority + " (higher numbers override).");
|
||||
checkSpawnOverlap(sender, world, existing);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1052,6 +1087,62 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Migrate regions that went from 0-255 to new world heights.
|
||||
*
|
||||
* @param args the arguments
|
||||
* @param sender the sender
|
||||
* @throws CommandException any error
|
||||
*/
|
||||
@Command(aliases = {"migrateheights"},
|
||||
usage = "[world]", max = 1,
|
||||
flags = "yw:",
|
||||
desc = "Migrate regions from old height limits to new height limits")
|
||||
public void migrateHeights(CommandContext args, Actor sender) throws CommandException {
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayMigrateRegionHeights()) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
if (!args.hasFlag('y')) {
|
||||
throw new CommandException("This command is potentially dangerous.\n" +
|
||||
"Please ensure you have made a backup of your data, and then re-enter the command with -y tacked on at the end to proceed.");
|
||||
}
|
||||
|
||||
World world = null;
|
||||
try {
|
||||
world = checkWorld(args, sender, 'w');
|
||||
} catch (CommandException ignored) {
|
||||
}
|
||||
|
||||
LoggerToChatHandler handler = null;
|
||||
Logger minecraftLogger = null;
|
||||
|
||||
if (sender instanceof LocalPlayer) {
|
||||
handler = new LoggerToChatHandler(sender);
|
||||
handler.setLevel(Level.ALL);
|
||||
minecraftLogger = Logger.getLogger("com.sk89q.worldguard");
|
||||
minecraftLogger.addHandler(handler);
|
||||
}
|
||||
|
||||
try {
|
||||
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||
RegionDriver driver = container.getDriver();
|
||||
WorldHeightMigration migration = new WorldHeightMigration(driver, WorldGuard.getInstance().getFlagRegistry(), world);
|
||||
container.migrate(migration);
|
||||
sender.print("Migration complete!");
|
||||
} catch (MigrationException e) {
|
||||
log.log(Level.WARNING, "Failed to migrate", e);
|
||||
throw new CommandException("Error encountered while migrating: " + e.getMessage());
|
||||
} finally {
|
||||
if (minecraftLogger != null) {
|
||||
minecraftLogger.removeHandler(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Teleport to a region
|
||||
*
|
||||
|
@ -1060,8 +1151,8 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
* @throws CommandException any error
|
||||
*/
|
||||
@Command(aliases = {"teleport", "tp"},
|
||||
usage = "<id>",
|
||||
flags = "sw:",
|
||||
usage = "[-w world] [-c|s] <id>",
|
||||
flags = "csw:",
|
||||
desc = "Teleports you to the location associated with the region.",
|
||||
min = 1, max = 1)
|
||||
public void teleport(CommandContext args, Actor sender) throws CommandException {
|
||||
|
@ -1080,32 +1171,70 @@ public final class RegionCommands extends RegionCommandsBase {
|
|||
|
||||
// -s for spawn location
|
||||
if (args.hasFlag('s')) {
|
||||
teleportLocation = existing.getFlag(Flags.SPAWN_LOC);
|
||||
teleportLocation = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.SPAWN_LOC, player);
|
||||
|
||||
if (teleportLocation == null) {
|
||||
throw new CommandException(
|
||||
"The region has no spawn point associated.");
|
||||
}
|
||||
} else if (args.hasFlag('c')) {
|
||||
// Check permissions
|
||||
if (!getPermissionModel(player).mayTeleportToCenter(existing)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
Region region = WorldEditRegionConverter.convertToRegion(existing);
|
||||
if (region == null || region.getCenter() == null) {
|
||||
throw new CommandException("The region has no center point.");
|
||||
}
|
||||
if (player.getGameMode() == GameModes.SPECTATOR) {
|
||||
teleportLocation = new Location(world, region.getCenter(), 0, 0);
|
||||
} else {
|
||||
// TODO: Add some method to create a safe teleport location.
|
||||
// The method AbstractPlayerActor$findFreePoisition(Location loc) is no good way for this.
|
||||
// It doesn't return the found location and it can't be checked if the location is inside the region.
|
||||
throw new CommandException("Center teleport is only available in Spectator gamemode.");
|
||||
}
|
||||
} else {
|
||||
teleportLocation = existing.getFlag(Flags.TELE_LOC);
|
||||
teleportLocation = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.TELE_LOC, player);
|
||||
|
||||
if (teleportLocation == null) {
|
||||
throw new CommandException("The region has no teleport point associated.");
|
||||
}
|
||||
}
|
||||
|
||||
String message = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.TELE_MESSAGE, player);
|
||||
|
||||
// If the flag isn't set, use the default message
|
||||
// If message.isEmpty(), no message is sent by LocalPlayer#teleport(...)
|
||||
if (message == null) {
|
||||
message = Flags.TELE_MESSAGE.getDefault();
|
||||
}
|
||||
|
||||
player.teleport(teleportLocation,
|
||||
"Teleported you to the region '" + existing.getId() + "'.",
|
||||
message.replace("%id%", existing.getId()),
|
||||
"Unable to teleport to region '" + existing.getId() + "'.");
|
||||
}
|
||||
|
||||
@Command(aliases = {"toggle-bypass", "bypass"},
|
||||
usage = "[on|off]",
|
||||
desc = "Toggle region bypassing, effectively ignoring bypass permissions.")
|
||||
@CommandPermissions({"worldguard.region.toggle-bypass"})
|
||||
public void toggleBypass(CommandContext args, Actor sender) throws CommandException {
|
||||
LocalPlayer player = worldGuard.checkPlayer(sender);
|
||||
if (!player.hasPermission("worldguard.region.toggle-bypass")) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
|
||||
if (session.hasBypassDisabled()) {
|
||||
boolean shouldEnableBypass;
|
||||
if (args.argsLength() > 0) {
|
||||
String arg1 = args.getString(0);
|
||||
if (!arg1.equalsIgnoreCase("on") && !arg1.equalsIgnoreCase("off")) {
|
||||
throw new CommandException("Allowed optional arguments are: on, off");
|
||||
}
|
||||
shouldEnableBypass = arg1.equalsIgnoreCase("on");
|
||||
} else {
|
||||
shouldEnableBypass = session.hasBypassDisabled();
|
||||
}
|
||||
if (shouldEnableBypass) {
|
||||
session.setBypassDisabled(false);
|
||||
player.print("You are now bypassing region protection (as long as you have permission).");
|
||||
} else {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package com.sk89q.worldguard.commands.region;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
|
@ -30,8 +31,8 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Polygonal2DRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
|
@ -44,13 +45,15 @@ import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
|||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.FlagContext;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormatException;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery.QueryOption;
|
||||
import com.sk89q.worldguard.protection.util.WorldEditRegionConverter;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -81,9 +84,25 @@ class RegionCommandsBase {
|
|||
* @throws CommandException on error
|
||||
*/
|
||||
protected static World checkWorld(CommandContext args, Actor sender, char flag) throws CommandException {
|
||||
return checkWorld(args, sender, flag, true);
|
||||
}
|
||||
|
||||
protected static World checkWorld(CommandContext args, Actor sender, char flag, boolean allowWorldEditOverride) throws CommandException {
|
||||
if (args.hasFlag(flag)) {
|
||||
return WorldGuard.getInstance().getPlatform().getMatcher().matchWorld(sender, args.getFlag(flag));
|
||||
} else {
|
||||
if (allowWorldEditOverride) {
|
||||
try {
|
||||
World override = WorldEdit.getInstance().getSessionManager().get(sender).getWorldOverride();
|
||||
if (override != null) {
|
||||
if (sender instanceof LocalPlayer && !override.equals(((LocalPlayer) sender).getWorld())) {
|
||||
sender.printDebug(TextComponent.of("Using //world override for region command: " + override.getName()));
|
||||
}
|
||||
return override;
|
||||
}
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
}
|
||||
}
|
||||
if (sender instanceof LocalPlayer) {
|
||||
return ((LocalPlayer) sender).getWorld();
|
||||
} else {
|
||||
|
@ -179,7 +198,7 @@ class RegionCommandsBase {
|
|||
* @throws CommandException thrown if no region was found
|
||||
*/
|
||||
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, LocalPlayer player, boolean allowGlobal, String rgCmd) throws CommandException {
|
||||
ApplicableRegionSet set = regionManager.getApplicableRegions(player.getLocation().toVector().toBlockPoint());
|
||||
ApplicableRegionSet set = regionManager.getApplicableRegions(player.getLocation().toVector().toBlockPoint(), QueryOption.SORT);
|
||||
|
||||
if (set.size() == 0) {
|
||||
if (allowGlobal) {
|
||||
|
@ -189,7 +208,7 @@ class RegionCommandsBase {
|
|||
return global;
|
||||
}
|
||||
throw new CommandException(
|
||||
"You're not standing in a region." +
|
||||
"You're not standing in a region. " +
|
||||
"Specify an ID if you want to select a specific region.");
|
||||
} else if (set.size() > 1) {
|
||||
boolean first = true;
|
||||
|
@ -209,28 +228,31 @@ class RegionCommandsBase {
|
|||
builder.append(regionComp);
|
||||
}
|
||||
player.print(builder.build());
|
||||
throw new CommandException("Several regions affect your current location (please pick one).");
|
||||
throw new CommandException("You're standing in several regions (please pick one).");
|
||||
}
|
||||
|
||||
return set.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a WorldEdit selection for a player, or emit an exception if there is none
|
||||
* Get a WorldEdit selection for an actor, or emit an exception if there is none
|
||||
* available.
|
||||
*
|
||||
* @param player the player
|
||||
* @param actor the actor
|
||||
* @return the selection
|
||||
* @throws CommandException thrown on an error
|
||||
*/
|
||||
protected static Region checkSelection(LocalPlayer player) throws CommandException {
|
||||
protected static Region checkSelection(Actor actor) throws CommandException {
|
||||
LocalSession localSession = WorldEdit.getInstance().getSessionManager().get(actor);
|
||||
try {
|
||||
return WorldEdit.getInstance().getSessionManager().get(player).getRegionSelector(player.getWorld()).getRegion();
|
||||
if (localSession == null || localSession.getSelectionWorld() == null) {
|
||||
throw new IncompleteRegionException();
|
||||
}
|
||||
return localSession.getRegionSelector(localSession.getSelectionWorld()).getRegion();
|
||||
} catch (IncompleteRegionException e) {
|
||||
throw new CommandException(
|
||||
"Please select an area first. " +
|
||||
"Use WorldEdit to make a selection! " +
|
||||
"(see: https://worldedit.enginehub.org/en/latest/usage/regions/selections/).");
|
||||
throw new CommandException("Please select an area first. " +
|
||||
"Use WorldEdit to make a selection! " +
|
||||
"(see: https://worldedit.enginehub.org/en/latest/usage/regions/selections/).");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,21 +292,21 @@ class RegionCommandsBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a {@link ProtectedRegion} from the player's selection.
|
||||
* Create a {@link ProtectedRegion} from the actor's selection.
|
||||
*
|
||||
* @param player the player
|
||||
* @param actor the actor
|
||||
* @param id the ID of the new region
|
||||
* @return a new region
|
||||
* @throws CommandException thrown on an error
|
||||
*/
|
||||
protected static ProtectedRegion checkRegionFromSelection(LocalPlayer player, String id) throws CommandException {
|
||||
Region selection = checkSelection(player);
|
||||
protected static ProtectedRegion checkRegionFromSelection(Actor actor, String id) throws CommandException {
|
||||
Region selection = checkSelection(actor);
|
||||
|
||||
// Detect the type of region from WorldEdit
|
||||
if (selection instanceof Polygonal2DRegion) {
|
||||
Polygonal2DRegion polySel = (Polygonal2DRegion) selection;
|
||||
int minY = polySel.getMinimumPoint().getBlockY();
|
||||
int maxY = polySel.getMaximumPoint().getBlockY();
|
||||
int minY = polySel.getMinimumPoint().y();
|
||||
int maxY = polySel.getMaximumPoint().y();
|
||||
return new ProtectedPolygonalRegion(id, polySel.getPoints(), minY, maxY);
|
||||
} else if (selection instanceof CuboidRegion) {
|
||||
BlockVector3 min = selection.getMinimumPoint();
|
||||
|
@ -320,7 +342,10 @@ class RegionCommandsBase {
|
|||
* @param region the region
|
||||
*/
|
||||
protected static void warnAboutDimensions(Actor sender, ProtectedRegion region) {
|
||||
int height = region.getMaximumPoint().getBlockY() - region.getMinimumPoint().getBlockY();
|
||||
if (region instanceof GlobalProtectedRegion) {
|
||||
return;
|
||||
}
|
||||
int height = region.getMaximumPoint().y() - region.getMinimumPoint().y();
|
||||
if (height <= 2) {
|
||||
sender.printDebug("(Warning: The height of the region was " + (height + 1) + " block(s).)");
|
||||
}
|
||||
|
@ -342,44 +367,44 @@ class RegionCommandsBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set a player's selection to a given region.
|
||||
* Inform a user if the region overlaps spawn protection.
|
||||
*
|
||||
* @param player the player
|
||||
* @param sender the sender to send the message to
|
||||
* @param world the world the region is in
|
||||
* @param region the region
|
||||
*/
|
||||
protected static boolean checkSpawnOverlap(Actor sender, World world, ProtectedRegion region) {
|
||||
ProtectedRegion spawn = WorldGuard.getInstance().getPlatform().getSpawnProtection(world);
|
||||
if (spawn != null) {
|
||||
if (!spawn.getIntersectingRegions(ImmutableList.of(region)).isEmpty()) {
|
||||
sender.print(ErrorFormat.wrap("Warning!")
|
||||
.append(TextComponent.of(" This region overlaps vanilla's spawn protection. WorldGuard cannot " +
|
||||
"override this, and only server operators will be able to interact with this area.", TextColor.WHITE)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an actor's selection to a given region.
|
||||
*
|
||||
* @param actor the actor
|
||||
* @param region the region
|
||||
* @throws CommandException thrown on a command error
|
||||
*/
|
||||
protected static void setPlayerSelection(LocalPlayer player, ProtectedRegion region) throws CommandException {
|
||||
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
|
||||
|
||||
// Set selection
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
|
||||
BlockVector3 pt1 = cuboid.getMinimumPoint();
|
||||
BlockVector3 pt2 = cuboid.getMaximumPoint();
|
||||
|
||||
CuboidRegionSelector selector = new CuboidRegionSelector(player.getWorld(), pt1, pt2);
|
||||
session.setRegionSelector(player.getWorld(), selector);
|
||||
selector.explainRegionAdjust(player, session);
|
||||
player.print("Region selected as a cuboid.");
|
||||
|
||||
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||
ProtectedPolygonalRegion poly2d = (ProtectedPolygonalRegion) region;
|
||||
Polygonal2DRegionSelector selector = new Polygonal2DRegionSelector(
|
||||
player.getWorld(), poly2d.getPoints(),
|
||||
poly2d.getMinimumPoint().getBlockY(),
|
||||
poly2d.getMaximumPoint().getBlockY());
|
||||
session.setRegionSelector(player.getWorld(), selector);
|
||||
selector.explainRegionAdjust(player, session);
|
||||
player.print("Region selected as a polygon.");
|
||||
|
||||
} else if (region instanceof GlobalProtectedRegion) {
|
||||
throw new CommandException(
|
||||
"Can't select global regions! " +
|
||||
"That would cover the entire world.");
|
||||
protected static void setPlayerSelection(Actor actor, ProtectedRegion region, World world) throws CommandException {
|
||||
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
|
||||
|
||||
RegionSelector selector = WorldEditRegionConverter.convertToSelector(region);
|
||||
if (selector != null) {
|
||||
selector.setWorld(world);
|
||||
session.setRegionSelector(world, selector);
|
||||
selector.explainRegionAdjust(actor, session);
|
||||
actor.print("Region selected as " + region.getType().getName());
|
||||
} else {
|
||||
throw new CommandException("Unknown region type: " +
|
||||
region.getClass().getCanonicalName());
|
||||
throw new CommandException("Can't select that region! " +
|
||||
"The region type '" + region.getType().getName() + "' can't be selected.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,9 +415,9 @@ class RegionCommandsBase {
|
|||
* @param flag the flag
|
||||
* @param sender the sender
|
||||
* @param value the value
|
||||
* @throws InvalidFlagFormat thrown if the value is invalid
|
||||
* @throws InvalidFlagFormatException thrown if the value is invalid
|
||||
*/
|
||||
protected static <V> V setFlag(ProtectedRegion region, Flag<V> flag, Actor sender, String value) throws InvalidFlagFormat {
|
||||
protected static <V> V setFlag(ProtectedRegion region, Flag<V> flag, Actor sender, String value) throws InvalidFlagFormatException {
|
||||
V val = flag.parseInput(FlagContext.create().setSender(sender).setInput(value).setObject("region", region).build());
|
||||
region.setFlag(flag, val);
|
||||
return val;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package com.sk89q.worldguard.commands.region;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.registry.UnknownFlag;
|
||||
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
|
@ -35,6 +36,8 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
|||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.FlagValueCalculator;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
|
@ -143,8 +146,22 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
|||
flagString = flag.getName() + " -g " + group + ": ";
|
||||
}
|
||||
|
||||
TextComponent flagText = TextComponent.of(flagString, useColors ? TextColor.GOLD : TextColor.WHITE)
|
||||
.append(TextComponent.of(String.valueOf(val), useColors? TextColor.YELLOW : TextColor.WHITE));
|
||||
TextColor flagColor = TextColor.WHITE;
|
||||
if (useColors) {
|
||||
// passthrough is ok on global
|
||||
if (FlagHelperBox.DANGER_ZONE.contains(flag)
|
||||
&& !(region.getId().equals(ProtectedRegion.GLOBAL_REGION) && flag == Flags.PASSTHROUGH)) {
|
||||
flagColor = TextColor.DARK_RED;
|
||||
} else if (Flags.INBUILT_FLAGS.contains(flag.getName())) {
|
||||
flagColor = TextColor.GOLD;
|
||||
} else if (flag instanceof UnknownFlag) {
|
||||
flagColor = TextColor.GRAY;
|
||||
} else {
|
||||
flagColor = TextColor.LIGHT_PURPLE;
|
||||
}
|
||||
}
|
||||
TextComponent flagText = TextComponent.of(flagString, flagColor)
|
||||
.append(TextComponent.of(String.valueOf(val), useColors ? TextColor.YELLOW : TextColor.WHITE));
|
||||
if (perms != null && perms.maySetFlag(region, flag)) {
|
||||
flagText = flagText.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set flag")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
|
@ -300,16 +317,22 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
|||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg select " + region.getId()));
|
||||
}
|
||||
builder.append(bound);
|
||||
final Location teleFlag = region.getFlag(Flags.TELE_LOC);
|
||||
final Location teleFlag = FlagValueCalculator.getEffectiveFlagOf(region, Flags.TELE_LOC, perms != null && perms.getSender() instanceof RegionAssociable ? (RegionAssociable) perms.getSender() : null);
|
||||
if (teleFlag != null && perms != null && perms.mayTeleportTo(region)) {
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[Teleport]", TextColor.GRAY)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("Click to teleport").append(TextComponent.newline()).append(
|
||||
TextComponent.of(teleFlag.getBlockY() + ", "
|
||||
TextComponent.of(teleFlag.getBlockX() + ", "
|
||||
+ teleFlag.getBlockY() + ", "
|
||||
+ teleFlag.getBlockZ()))))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg tp -w \"" + world + "\" " + region.getId()))));
|
||||
} else if (perms != null && perms.mayTeleportToCenter(region) && region.isPhysicalArea()) {
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[Center Teleport]", TextColor.GRAY)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("Click to teleport to the center of the region")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg tp -c -w \"" + world + "\" " + region.getId()))));
|
||||
}
|
||||
|
||||
newline();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package com.sk89q.worldguard.commands.task;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
@ -39,6 +40,7 @@ public class RegionAdder implements Callable<ProtectedRegion> {
|
|||
|
||||
private final RegionManager manager;
|
||||
private final ProtectedRegion region;
|
||||
private final Actor actor;
|
||||
@Nullable
|
||||
private String[] ownersInput;
|
||||
private UserLocatorPolicy locatorPolicy = UserLocatorPolicy.UUID_ONLY;
|
||||
|
@ -46,15 +48,26 @@ public class RegionAdder implements Callable<ProtectedRegion> {
|
|||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param manager the manage
|
||||
* @param manager the manager
|
||||
* @param region the region
|
||||
*/
|
||||
public RegionAdder(RegionManager manager, ProtectedRegion region) {
|
||||
this(manager, region, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
* @param manager the manager
|
||||
* @param region the region
|
||||
* @param actor the actor
|
||||
*/
|
||||
public RegionAdder(RegionManager manager, ProtectedRegion region, Actor actor) {
|
||||
checkNotNull(manager);
|
||||
checkNotNull(region);
|
||||
|
||||
this.manager = manager;
|
||||
this.region = region;
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,6 +88,9 @@ public class RegionAdder implements Callable<ProtectedRegion> {
|
|||
if (ownersInput != null) {
|
||||
DomainInputResolver resolver = new DomainInputResolver(WorldGuard.getInstance().getProfileService(), ownersInput);
|
||||
resolver.setLocatorPolicy(locatorPolicy);
|
||||
resolver.setActor(actor);
|
||||
resolver.setRegion(region);
|
||||
|
||||
DefaultDomain domain = resolver.call();
|
||||
region.getOwners().addAll(domain);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
|
@ -33,12 +34,15 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
|||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.FlagValueCalculator;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -55,6 +59,8 @@ public class RegionLister implements Callable<Integer> {
|
|||
private final RegionManager manager;
|
||||
private final String world;
|
||||
private OwnerMatcher ownerMatcher;
|
||||
private String idFilter;
|
||||
private ProtectedRegion filterByIntersecting;
|
||||
private int page;
|
||||
private String playerName;
|
||||
private boolean nameOnly;
|
||||
|
@ -77,6 +83,10 @@ public class RegionLister implements Callable<Integer> {
|
|||
this.page = page;
|
||||
}
|
||||
|
||||
public void filterByIntersecting(ProtectedRegion region) {
|
||||
this.filterByIntersecting = region;
|
||||
}
|
||||
|
||||
public void filterOwnedByName(String name, boolean nameOnly) {
|
||||
this.playerName = name;
|
||||
this.nameOnly = nameOnly;
|
||||
|
@ -141,20 +151,29 @@ public class RegionLister implements Callable<Integer> {
|
|||
};
|
||||
}
|
||||
|
||||
public void filterIdByMatch(String idFilter) {
|
||||
this.idFilter = idFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
Map<String, ProtectedRegion> regions = manager.getRegions();
|
||||
Collection<ProtectedRegion> iterableRegions = regions.values();
|
||||
|
||||
if (filterByIntersecting != null) {
|
||||
iterableRegions = filterByIntersecting.getIntersectingRegions(iterableRegions);
|
||||
}
|
||||
|
||||
// Build a list of regions to show
|
||||
List<RegionListEntry> entries = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, ProtectedRegion> rg : regions.entrySet()) {
|
||||
if (rg.getKey().equals("__global__")) {
|
||||
for (ProtectedRegion rg : iterableRegions) {
|
||||
if (rg.getId().equals("__global__")) {
|
||||
continue;
|
||||
}
|
||||
final ProtectedRegion region = rg.getValue();
|
||||
final RegionListEntry entry = new RegionListEntry(region);
|
||||
if (entry.matches(ownerMatcher)) {
|
||||
final RegionListEntry entry = new RegionListEntry(rg);
|
||||
|
||||
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +184,7 @@ public class RegionLister implements Callable<Integer> {
|
|||
// insert global on top
|
||||
if (regions.containsKey("__global__")) {
|
||||
final RegionListEntry entry = new RegionListEntry(regions.get("__global__"));
|
||||
if (entry.matches(ownerMatcher)) {
|
||||
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
|
||||
entries.add(0, entry);
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +198,8 @@ public class RegionLister implements Callable<Integer> {
|
|||
String cmd = "/rg list -w \"" + world + "\""
|
||||
+ (playerName != null ? " -p " + playerName : "")
|
||||
+ (nameOnly ? " -n" : "")
|
||||
+ (filterByIntersecting != null ? " -s" : "")
|
||||
+ (idFilter != null ? " -i " + idFilter : "")
|
||||
+ " %page%";
|
||||
PaginationBox box = new RegionListBox(title, cmd, perms, entries, world);
|
||||
sender.print(box.create(page));
|
||||
|
@ -207,6 +228,10 @@ public class RegionLister implements Callable<Integer> {
|
|||
|| (isMember = matcher.isContainedWithin(region.getMembers()));
|
||||
}
|
||||
|
||||
public boolean matches(String idMatcher) {
|
||||
return idMatcher == null || region.getId().contains(idMatcher);
|
||||
}
|
||||
|
||||
public ProtectedRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
@ -261,11 +286,18 @@ public class RegionLister implements Callable<Integer> {
|
|||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg info -w \"" + world + "\" " + entry.region.getId()))));
|
||||
}
|
||||
if (perms != null && entry.region.getFlag(Flags.TELE_LOC) != null && perms.mayTeleportTo(entry.region)) {
|
||||
final Location teleFlag = FlagValueCalculator.getEffectiveFlagOf(entry.region, Flags.TELE_LOC, perms != null && perms.getSender() instanceof RegionAssociable ? (RegionAssociable) perms.getSender() : null);
|
||||
if (perms != null && teleFlag != null && perms.mayTeleportTo(entry.region)) {
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[TP]", TextColor.GRAY)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to teleport")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg tp -w \"" + world + "\" " + entry.region.getId()))));
|
||||
} else if (perms != null && perms.mayTeleportToCenter(entry.getRegion()) && entry.getRegion().isPhysicalArea()) {
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[TP-Center]", TextColor.GRAY)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("Click to teleport to the center")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg tp -c -w \"" + world + "\" " + entry.region.getId()))));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
|
|
@ -76,6 +76,9 @@ public abstract class ConfigurationManager {
|
|||
public boolean migrateRegionsToUuid;
|
||||
public boolean keepUnresolvedNames;
|
||||
public boolean particleEffects;
|
||||
public boolean disablePermissionCache;
|
||||
public boolean disableDefaultBypass;
|
||||
public boolean announceBypassStatus;
|
||||
|
||||
@Unreported public Map<String, String> hostKeys = new HashMap<>();
|
||||
public boolean hostKeysAllowFMLClients;
|
||||
|
|
|
@ -105,6 +105,7 @@ public abstract class WorldConfiguration {
|
|||
public boolean blockEntityPaintingDestroy;
|
||||
public boolean blockEntityItemFrameDestroy;
|
||||
public boolean blockEntityArmorStandDestroy;
|
||||
public boolean blockEntityVehicleEntry;
|
||||
public boolean blockPluginSpawning;
|
||||
public boolean blockGroundSlimes;
|
||||
public boolean blockZombieDoorDestruction;
|
||||
|
@ -128,6 +129,7 @@ public abstract class WorldConfiguration {
|
|||
public boolean allowTamedSpawns;
|
||||
public int maxClaimVolume;
|
||||
public boolean claimOnlyInsideExistingRegions;
|
||||
public String setParentOnClaim;
|
||||
public int maxRegionCountPerPlayer;
|
||||
public boolean antiWolfDumbness;
|
||||
public boolean signChestProtection;
|
||||
|
@ -135,6 +137,10 @@ public abstract class WorldConfiguration {
|
|||
public boolean removeInfiniteStacks;
|
||||
public boolean disableCreatureCropTrampling;
|
||||
public boolean disablePlayerCropTrampling;
|
||||
public boolean disableCreatureTurtleEggTrampling;
|
||||
public boolean disablePlayerTurtleEggTrampling;
|
||||
public boolean disableCreatureSnifferEggTrampling;
|
||||
public boolean disablePlayerSnifferEggTrampling;
|
||||
public boolean preventLightningFire;
|
||||
public Set<String> disallowedLightningBlocks;
|
||||
public boolean disableThunder;
|
||||
|
@ -154,20 +160,26 @@ public abstract class WorldConfiguration {
|
|||
public boolean disableGrassGrowth;
|
||||
public boolean disableMyceliumSpread;
|
||||
public boolean disableVineGrowth;
|
||||
public boolean disableRockGrowth;
|
||||
public boolean disableSculkGrowth;
|
||||
public boolean disableCropGrowth;
|
||||
public boolean disableEndermanGriefing;
|
||||
public boolean disableSnowmanTrails;
|
||||
public boolean disableSoilDehydration;
|
||||
public boolean disableCoralBlockFade;
|
||||
public boolean disableCopperBlockFade;
|
||||
public Set<String> allowedSnowFallOver;
|
||||
public boolean regionInvinciblityRemovesMobs;
|
||||
public boolean regionCancelEmptyChatEvents;
|
||||
public boolean regionNetherPortalProtection;
|
||||
public boolean forceDefaultTitleTimes;
|
||||
public boolean fakePlayerBuildOverride;
|
||||
public boolean explosionFlagCancellation;
|
||||
public boolean disableDeathMessages;
|
||||
public boolean disableObsidianGenerators;
|
||||
public boolean strictEntitySpawn;
|
||||
public boolean ignoreHopperMoveEvents;
|
||||
public boolean breakDeniedHoppers;
|
||||
public boolean useMaxPriorityAssociation;
|
||||
protected Map<String, Integer> maxRegionCounts;
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,9 @@ public abstract class YamlConfigurationManager extends ConfigurationManager {
|
|||
migrateRegionsToUuid = config.getBoolean("regions.uuid-migration.perform-on-next-start", true);
|
||||
keepUnresolvedNames = config.getBoolean("regions.uuid-migration.keep-names-that-lack-uuids", true);
|
||||
useRegionsCreatureSpawnEvent = config.getBoolean("regions.use-creature-spawn-event", true);
|
||||
disableDefaultBypass = config.getBoolean("regions.disable-bypass-by-default", false);
|
||||
announceBypassStatus = config.getBoolean("regions.announce-bypass-status", false);
|
||||
|
||||
useGodPermission = config.getBoolean("auto-invincible", config.getBoolean("auto-invincible-permission", false));
|
||||
useGodGroup = config.getBoolean("auto-invincible-group", false);
|
||||
useAmphibiousGroup = config.getBoolean("auto-no-drowning-group", false);
|
||||
|
@ -63,6 +66,7 @@ public abstract class YamlConfigurationManager extends ConfigurationManager {
|
|||
usePlayerMove = config.getBoolean("use-player-move-event", true);
|
||||
usePlayerTeleports = config.getBoolean("use-player-teleports", true);
|
||||
particleEffects = config.getBoolean("use-particle-effects", true);
|
||||
disablePermissionCache = config.getBoolean("disable-permission-cache", false);
|
||||
|
||||
deopOnJoin = config.getBoolean("security.deop-everyone-on-join", false);
|
||||
blockInGameOp = config.getBoolean("security.block-in-game-op-command", false);
|
||||
|
@ -89,6 +93,12 @@ public abstract class YamlConfigurationManager extends ConfigurationManager {
|
|||
String sqlUsername = config.getString("regions.sql.username", "worldguard");
|
||||
String sqlPassword = config.getString("regions.sql.password", "worldguard");
|
||||
String sqlTablePrefix = config.getString("regions.sql.table-prefix", "");
|
||||
if (!useSqlDatabase) {
|
||||
config.removeProperty("regions.sql");
|
||||
} else {
|
||||
log.warning("SQL support for WorldGuard region storage is deprecated for removal in a future version. Please migrate to YAML storage.");
|
||||
log.warning("For details, see https://worldguard.enginehub.org/en/latest/regions/storage/");
|
||||
}
|
||||
|
||||
DataSourceConfig dataSourceConfig = new DataSourceConfig(sqlDsn, sqlUsername, sqlPassword, sqlTablePrefix);
|
||||
SQLDriver sqlDriver = new SQLDriver(dataSourceConfig);
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.domains.registry.CustomDomainContext;
|
||||
import com.sk89q.worldguard.domains.registry.InvalidDomainFormatException;
|
||||
import com.sk89q.worldguard.util.ChangeTracked;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public abstract class CustomDomain implements Domain, ChangeTracked {
|
||||
private static final Pattern VALID_NAME = Pattern.compile("^[a-z0-9\\-]{1,40}$");
|
||||
|
||||
private final String name;
|
||||
private boolean dirty;
|
||||
|
||||
public CustomDomain(String name) {
|
||||
if (name == null ||!isValidName(name)) {
|
||||
throw new IllegalArgumentException("Invalid Domain name used.");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the domain resolver.
|
||||
*
|
||||
* @return The name of the domain
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given input to fill the context of the CustomDomain.
|
||||
*
|
||||
* @param context the {@link CustomDomainContext}
|
||||
* @throws InvalidDomainFormatException Raised if the input is invalid
|
||||
*/
|
||||
public abstract void parseInput(CustomDomainContext context) throws InvalidDomainFormatException;
|
||||
|
||||
/**
|
||||
* Convert a raw type that was loaded (from a YAML file, for example)
|
||||
* into the custom domain.
|
||||
*
|
||||
* @param o The object
|
||||
*/
|
||||
public abstract void unmarshal(Object o);
|
||||
|
||||
/**
|
||||
* Convert the current Domain to a storable foramt
|
||||
*
|
||||
* @return The marshalled type
|
||||
*/
|
||||
public abstract Object marshal();
|
||||
|
||||
/**
|
||||
* Test whether a flag name is valid.
|
||||
*
|
||||
* @param name The flag name
|
||||
* @return Whether the name is valid
|
||||
*/
|
||||
public static boolean isValidName(String name) {
|
||||
checkNotNull(name, "name");
|
||||
// g is already reserved by the group domain
|
||||
return VALID_NAME.matcher(name).matches() && !name.equalsIgnoreCase("g");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean contains(LocalPlayer player) {
|
||||
return contains(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
return dirty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty(boolean dirty) {
|
||||
this.dirty = dirty;
|
||||
}
|
||||
}
|
|
@ -22,8 +22,6 @@ package com.sk89q.worldguard.domains;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
|
@ -31,14 +29,19 @@ import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
|||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.util.ChangeTracked;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -50,6 +53,9 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
private PlayerDomain playerDomain = new PlayerDomain();
|
||||
private GroupDomain groupDomain = new GroupDomain();
|
||||
|
||||
private final Map<String, CustomDomain> customDomains = new ConcurrentHashMap<>();
|
||||
private boolean customDomainsChanged = false;
|
||||
|
||||
/**
|
||||
* Create a new domain.
|
||||
*/
|
||||
|
@ -64,6 +70,7 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
public DefaultDomain(DefaultDomain existing) {
|
||||
setPlayerDomain(existing.getPlayerDomain());
|
||||
setGroupDomain(existing.getGroupDomain());
|
||||
setCustomDomains(existing.customDomains);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,6 +111,72 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
this.groupDomain = new GroupDomain(groupDomain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new custom domains
|
||||
*
|
||||
* @param customDomain a domain
|
||||
*/
|
||||
public void addCustomDomain(CustomDomain customDomain) {
|
||||
checkNotNull(customDomain);
|
||||
this.customDomains.put(customDomain.getName(), customDomain);
|
||||
this.customDomainsChanged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a custom domain matched by the name
|
||||
*
|
||||
* @param name the name
|
||||
*/
|
||||
public void removeCustomDomain(String name) {
|
||||
checkNotNull(name);
|
||||
if (this.customDomains.remove(name) != null) {
|
||||
this.customDomainsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a custom domain
|
||||
*
|
||||
* @param customDomain a domain
|
||||
*/
|
||||
public void removeCustomDomain(CustomDomain customDomain) {
|
||||
checkNotNull(customDomain);
|
||||
if (this.customDomains.remove(customDomain.getName()) != null) {
|
||||
this.customDomainsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the api domains to a specified value
|
||||
*
|
||||
* @param customDomains the domains
|
||||
*/
|
||||
public void setCustomDomains(Map<String, CustomDomain> customDomains) {
|
||||
checkNotNull(customDomains);
|
||||
this.customDomains.clear();
|
||||
this.customDomains.putAll(customDomains);
|
||||
this.customDomainsChanged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all api domains
|
||||
*
|
||||
* @return a unmodifiable copy of the domains
|
||||
*/
|
||||
public Collection<CustomDomain> getCustomDomains() {
|
||||
return Collections.unmodifiableCollection(this.customDomains.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the api domain specified by its name
|
||||
*
|
||||
* @param name the name of the domain
|
||||
* @return the custom domain
|
||||
*/
|
||||
public @Nullable CustomDomain getCustomDomain(String name) {
|
||||
return this.customDomains.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given player to the domain, identified by the player's name.
|
||||
*
|
||||
|
@ -175,6 +248,9 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
for (String group : other.getGroups()) {
|
||||
addGroup(group);
|
||||
}
|
||||
for (CustomDomain domain : other.getCustomDomains()) {
|
||||
addCustomDomain(domain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,6 +269,9 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
for (String group : other.getGroups()) {
|
||||
removeGroup(group);
|
||||
}
|
||||
for (CustomDomain domain : other.getCustomDomains()) {
|
||||
removeCustomDomain(domain.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,12 +321,12 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
|
||||
@Override
|
||||
public boolean contains(LocalPlayer player) {
|
||||
return playerDomain.contains(player) || groupDomain.contains(player);
|
||||
return playerDomain.contains(player) || groupDomain.contains(player) || customDomains.values().stream().anyMatch(d -> d.contains(player));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(UUID uniqueId) {
|
||||
return playerDomain.contains(uniqueId);
|
||||
return playerDomain.contains(uniqueId) || customDomains.values().stream().anyMatch(d -> d.contains(uniqueId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -257,7 +336,7 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
|
||||
@Override
|
||||
public int size() {
|
||||
return groupDomain.size() + playerDomain.size();
|
||||
return groupDomain.size() + playerDomain.size() + customDomains.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -275,7 +354,6 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
}
|
||||
|
||||
public String toPlayersString(@Nullable ProfileCache cache) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
List<String> output = new ArrayList<>();
|
||||
|
||||
for (String name : playerDomain.getPlayers()) {
|
||||
|
@ -299,19 +377,13 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
}
|
||||
|
||||
output.sort(String.CASE_INSENSITIVE_ORDER);
|
||||
for (Iterator<String> it = output.iterator(); it.hasNext();) {
|
||||
str.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
str.append(", ");
|
||||
}
|
||||
}
|
||||
return str.toString();
|
||||
return String.join(", ", output);
|
||||
}
|
||||
|
||||
public String toGroupsString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (Iterator<String> it = groupDomain.getGroups().iterator(); it.hasNext(); ) {
|
||||
str.append("*");
|
||||
str.append("g:");
|
||||
str.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
str.append(", ");
|
||||
|
@ -320,25 +392,20 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
return str.toString();
|
||||
}
|
||||
|
||||
public String toUserFriendlyString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
if (playerDomain.size() > 0) {
|
||||
str.append(toPlayersString());
|
||||
public String toCustomDomainsString() {
|
||||
List<String> output = new ArrayList<>();
|
||||
for (CustomDomain customDomain : customDomains.values()) {
|
||||
output.add(customDomain.getName() + ":" + customDomain.toString());
|
||||
}
|
||||
|
||||
if (groupDomain.size() > 0) {
|
||||
if (str.length() > 0) {
|
||||
str.append("; ");
|
||||
}
|
||||
|
||||
str.append(toGroupsString());
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
output.sort(String.CASE_INSENSITIVE_ORDER);
|
||||
return String.join(", ", output);
|
||||
}
|
||||
|
||||
public String toUserFriendlyString(ProfileCache cache) {
|
||||
public String toUserFriendlyString() {
|
||||
return toUserFriendlyString(null);
|
||||
}
|
||||
|
||||
public String toUserFriendlyString(@Nullable ProfileCache cache) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
if (playerDomain.size() > 0) {
|
||||
|
@ -352,6 +419,12 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
|
||||
str.append(toGroupsString());
|
||||
}
|
||||
if (!customDomains.isEmpty()) {
|
||||
if (str.length() > 0) {
|
||||
str.append("; ");
|
||||
}
|
||||
str.append(toCustomDomainsString());
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
@ -367,13 +440,20 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
}
|
||||
builder.append(toGroupsComponent());
|
||||
}
|
||||
if (!customDomains.isEmpty()) {
|
||||
if (playerDomain.size() > 0 || groupDomain.size() > 0) {
|
||||
builder.append(TextComponent.of("; "));
|
||||
}
|
||||
builder.append(toCustomDomainsComponent());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Component toGroupsComponent() {
|
||||
final TextComponent.Builder builder = TextComponent.builder("");
|
||||
for (Iterator<String> it = groupDomain.getGroups().iterator(); it.hasNext(); ) {
|
||||
builder.append(TextComponent.of(it.next(), TextColor.GOLD));
|
||||
builder.append(TextComponent.of("g:", TextColor.GRAY))
|
||||
.append(TextComponent.of(it.next(), TextColor.GOLD));
|
||||
if (it.hasNext()) {
|
||||
builder.append(TextComponent.of(", "));
|
||||
}
|
||||
|
@ -408,15 +488,18 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
final TextComponent.Builder builder = TextComponent.builder("");
|
||||
final Iterator<TextComponent> profiles = profileMap.keySet().stream().sorted().map(name -> {
|
||||
final UUID uuid = profileMap.get(name);
|
||||
final TextComponent component = TextComponent.of(name, TextColor.YELLOW)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, uuid == null
|
||||
? TextComponent.of("Name only", TextColor.GRAY)
|
||||
: TextComponent.of("Last known name of uuid: ", TextColor.GRAY)
|
||||
.append(TextComponent.of(uuid.toString(), TextColor.WHITE))));
|
||||
if (uuid == null) {
|
||||
return component;
|
||||
return TextComponent.of(name, TextColor.YELLOW)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Name only", TextColor.GRAY)
|
||||
.append(TextComponent.newline()).append(TextComponent.of("Click to copy"))))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.COPY_TO_CLIPBOARD, name));
|
||||
} else {
|
||||
return TextComponent.of(name, TextColor.YELLOW)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Last known name of uuid: ", TextColor.GRAY)
|
||||
.append(TextComponent.of(uuid.toString(), TextColor.WHITE))
|
||||
.append(TextComponent.newline()).append(TextComponent.of("Click to copy"))))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.COPY_TO_CLIPBOARD, uuid.toString()));
|
||||
}
|
||||
return component.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, uuid.toString()));
|
||||
}).iterator();
|
||||
while (profiles.hasNext()) {
|
||||
builder.append(profiles.next());
|
||||
|
@ -427,30 +510,50 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
|||
|
||||
if (!uuids.isEmpty()) {
|
||||
builder.append(TextComponent.of(uuids.size() + " unknown uuid" + (uuids.size() == 1 ? "" : "s"), TextColor.GRAY)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of(String.join("\n", uuids))
|
||||
.append(TextComponent.newline().append(TextComponent.of("Click to select")))))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, String.join(",", uuids))));
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Unable to resolve the name for:", TextColor.GRAY)
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of(String.join("\n", uuids), TextColor.WHITE))
|
||||
.append(TextComponent.newline().append(TextComponent.of("Click to copy")))))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.COPY_TO_CLIPBOARD, String.join(",", uuids))));
|
||||
}
|
||||
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Component toCustomDomainsComponent() {
|
||||
final TextComponent.Builder builder = TextComponent.builder("");
|
||||
for (Iterator<CustomDomain> it = customDomains.values().iterator(); it.hasNext(); ) {
|
||||
CustomDomain domain = it.next();
|
||||
builder.append(TextComponent.of(domain.getName() + ":", TextColor.LIGHT_PURPLE))
|
||||
.append(TextComponent.of(domain.toString(), TextColor.GOLD));
|
||||
if (it.hasNext()) {
|
||||
builder.append(TextComponent.of(", "));
|
||||
}
|
||||
}
|
||||
return builder.build().hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("CustomDomain")));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
return playerDomain.isDirty() || groupDomain.isDirty();
|
||||
return playerDomain.isDirty() || groupDomain.isDirty() ||
|
||||
customDomainsChanged || customDomains.values().stream().anyMatch(ChangeTracked::isDirty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty(boolean dirty) {
|
||||
playerDomain.setDirty(dirty);
|
||||
groupDomain.setDirty(dirty);
|
||||
customDomainsChanged = dirty;
|
||||
customDomains.values().forEach(d -> d.setDirty(dirty));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{players=" + playerDomain +
|
||||
", groups=" + groupDomain +
|
||||
", custom=" + customDomains +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,9 @@ public class PlayerDomain implements Domain, ChangeTracked {
|
|||
* Add the given player to the domain, identified by the player's name.
|
||||
*
|
||||
* @param name the name of the player
|
||||
* @deprecated names are deprecated in favor of UUIDs in MC 1.7+
|
||||
*/
|
||||
@Deprecated
|
||||
public void addPlayer(String name) {
|
||||
checkNotNull(name);
|
||||
if (!name.trim().isEmpty()) {
|
||||
|
@ -111,7 +113,9 @@ public class PlayerDomain implements Domain, ChangeTracked {
|
|||
* Remove the given player from the domain, identified by the player's name.
|
||||
*
|
||||
* @param name the name of the player
|
||||
* @deprecated names are deprecated in favor of UUIDs in MC 1.7+
|
||||
*/
|
||||
@Deprecated
|
||||
public void removePlayer(String name) {
|
||||
checkNotNull(name);
|
||||
setDirty(true);
|
||||
|
@ -145,14 +149,16 @@ public class PlayerDomain implements Domain, ChangeTracked {
|
|||
@Override
|
||||
public boolean contains(LocalPlayer player) {
|
||||
checkNotNull(player);
|
||||
return contains(player.getName().trim().toLowerCase()) || contains(player.getUniqueId());
|
||||
return contains(player.getUniqueId()) || (!names.isEmpty() && contains(player.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of player names.
|
||||
*
|
||||
* @return the set of player names
|
||||
* @deprecated names are deprecated in favor of UUIDs in MC 1.7+
|
||||
*/
|
||||
@Deprecated
|
||||
public Set<String> getPlayers() {
|
||||
return Collections.unmodifiableSet(names);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains.registry;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldguard.commands.CommandInputContext;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
|
||||
public final class CustomDomainContext extends CommandInputContext<InvalidDomainFormatException> {
|
||||
|
||||
private CustomDomainContext(Actor sender, String input, Map<String, Object> values) {
|
||||
super(sender, input, values);
|
||||
}
|
||||
|
||||
|
||||
public static CustomDomainContext.CustomDomainContextBuilder create() {
|
||||
return new CustomDomainContext.CustomDomainContextBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of this CustomDomainContext, with optional substitutions for values
|
||||
*
|
||||
* <p>If any supplied variable is null, it will be ignored.
|
||||
* If a map is supplied, it will override this CustomDomainContext's values of the same key,
|
||||
* but unprovided keys will not be overriden and will be returned as shallow copies.</p>
|
||||
*
|
||||
* @param commandSender CommandSender for the new CustomDomainContext to run under
|
||||
* @param s String of the user input for the new CustomDomainContext
|
||||
* @param values map of values to override from the current CustomDomainContext
|
||||
* @return a copy of this CustomDomainContext
|
||||
*/
|
||||
public CustomDomainContext copyWith(@Nullable Actor commandSender, @Nullable String s, @Nullable Map<String, Object> values) {
|
||||
Map<String, Object> map = Maps.newHashMap();
|
||||
map.putAll(context);
|
||||
if (values != null) {
|
||||
map.putAll(values);
|
||||
}
|
||||
return new CustomDomainContext(commandSender == null ? this.sender : commandSender, s == null ? this.input : s, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvalidDomainFormatException createException(String str) {
|
||||
return new InvalidDomainFormatException(str);
|
||||
}
|
||||
|
||||
public static class CustomDomainContextBuilder {
|
||||
private Actor sender;
|
||||
private String input;
|
||||
private Map<String, Object> map = Maps.newHashMap();
|
||||
|
||||
public CustomDomainContextBuilder setSender(Actor sender) {
|
||||
this.sender = sender;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomDomainContextBuilder setInput(String input) {
|
||||
this.input = input;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomDomainContextBuilder setObject(String key, Object value) {
|
||||
this.map.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean tryAddToMap(String key, Object value) {
|
||||
if (map.containsKey(key)) return false;
|
||||
this.map.put(key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public CustomDomainContext build() {
|
||||
return new CustomDomainContext(sender, input, map);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains.registry;
|
||||
|
||||
public class DomainConflictException extends RuntimeException {
|
||||
public DomainConflictException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
package com.sk89q.worldguard.domains.registry;
|
||||
|
||||
import com.sk89q.worldguard.domains.CustomDomain;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DomainFactory<T extends CustomDomain> {
|
||||
T create(String name);
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains.registry;
|
||||
|
||||
import com.sk89q.worldguard.domains.CustomDomain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DomainRegistry extends Iterable<DomainFactory<?>> {
|
||||
|
||||
/**
|
||||
* Register a new Domain
|
||||
*
|
||||
* <p>There may be an appropiate time to register domains. if domains are
|
||||
* registered outside this time, then an exception may be thrown.</p>
|
||||
*
|
||||
* @param domain The domain
|
||||
* @throws DomainConflictException Thrown when already an existing domain exists with the same name
|
||||
* @throws IllegalStateException If it is not the right time to register new domains
|
||||
*/
|
||||
void register(String name, DomainFactory<?> domain) throws DomainConflictException;
|
||||
|
||||
/**
|
||||
* Register a collection of domains.
|
||||
*
|
||||
* <p>There may be an appropriate time to register domains. If domains are
|
||||
* registered outside this time, then an exception may be thrown.</p>
|
||||
*
|
||||
* <p>If there is a domain conflict, then an error will be logged but
|
||||
* no exception will be thrown.</p>
|
||||
*
|
||||
* @param domains a collection of domain factories
|
||||
* @throws IllegalStateException If it is not the right time to register new domains
|
||||
*/
|
||||
void registerAll(Map<String, DomainFactory<?>> domains);
|
||||
|
||||
/**
|
||||
* Get the domain by its name.
|
||||
*
|
||||
* @param name The name
|
||||
* @return The domain, if it has been registered
|
||||
*/
|
||||
@Nullable
|
||||
DomainFactory<?> get(String name);
|
||||
|
||||
/**
|
||||
* Try to get a domain by its name
|
||||
*/
|
||||
@Nullable
|
||||
CustomDomain createDomain(String name);
|
||||
|
||||
/**
|
||||
* Get all domains keyed by the registered name
|
||||
*
|
||||
* @return All domains
|
||||
*/
|
||||
Map<String, DomainFactory<?>> getAll();
|
||||
|
||||
/**
|
||||
* Unmarshal a raw map of values into a list of domains with their
|
||||
* unmarshalled values.
|
||||
*
|
||||
* @param rawValues The raw values map
|
||||
* @param createUnknown Whether "just in time" domains should be created for unknown domains
|
||||
* @return The unmarshalled domain list
|
||||
*/
|
||||
Map<String, CustomDomain> unmarshal(Map<String, Object> rawValues, boolean createUnknown);
|
||||
|
||||
/**
|
||||
* Get the number of registered domains.
|
||||
*
|
||||
* @return The number of registered domains
|
||||
*/
|
||||
int size();
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains.registry;
|
||||
|
||||
public class InvalidDomainFormatException extends Exception {
|
||||
private static final long serialVersionUID = 8101615074524004172L;
|
||||
|
||||
public InvalidDomainFormatException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains.registry;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldguard.domains.CustomDomain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SimpleDomainRegistry implements DomainRegistry {
|
||||
private static final Logger log = Logger.getLogger(SimpleDomainRegistry.class.getCanonicalName());
|
||||
|
||||
private final Object lock = new Object();
|
||||
private final ConcurrentMap<String, DomainFactory<?>> domains = Maps.newConcurrentMap();
|
||||
private boolean initialized = false;
|
||||
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public void setInitialized(boolean initialized) {
|
||||
this.initialized = initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(String name, DomainFactory<?> domain) throws DomainConflictException {
|
||||
synchronized (lock) {
|
||||
if (initialized) {
|
||||
throw new IllegalStateException("New domains cannot be registered at this time");
|
||||
}
|
||||
|
||||
forceRegister(name, domain);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAll(Map<String, DomainFactory<?>> domains) {
|
||||
synchronized (lock) {
|
||||
for (Map.Entry<String, DomainFactory<?>> entry : domains.entrySet()) {
|
||||
try {
|
||||
register(entry.getKey(), entry.getValue());
|
||||
} catch (DomainConflictException e) {
|
||||
log.log(Level.WARNING, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends DomainFactory<?>> T forceRegister(String name, T domain) throws DomainConflictException {
|
||||
checkNotNull(domain, "domain");
|
||||
checkNotNull(name, "name");
|
||||
|
||||
if (!CustomDomain.isValidName(name)) {
|
||||
throw new IllegalArgumentException("Invalid Domain name used.");
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
if (domains.containsKey(name)) {
|
||||
throw new DomainConflictException("A domain already exists by the name " + name);
|
||||
}
|
||||
|
||||
domains.put(name, domain);
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DomainFactory<?> get(String name) {
|
||||
checkNotNull(name, "name");
|
||||
return domains.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CustomDomain createDomain(String name) {
|
||||
DomainFactory<?> factory = get(name);
|
||||
if (factory == null) return null;
|
||||
return factory.create(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, DomainFactory<?>> getAll() {
|
||||
return ImmutableMap.copyOf(domains);
|
||||
}
|
||||
|
||||
private CustomDomain getOrCreate(String name, Object value, boolean createUnknown) {
|
||||
CustomDomain customDomain = createDomain(name);
|
||||
|
||||
if (customDomain != null) {
|
||||
customDomain.unmarshal(value);
|
||||
return customDomain;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
customDomain = createDomain(name); // Load again because the previous load was not synchronized
|
||||
if (customDomain != null) {
|
||||
customDomain.unmarshal(value);
|
||||
return customDomain;
|
||||
}
|
||||
if (createUnknown) {
|
||||
DomainFactory<UnknownDomain> unknownFactory = forceRegister(name, UnknownDomain.FACTORY);
|
||||
if (unknownFactory != null) {
|
||||
customDomain = unknownFactory.create(name);
|
||||
if (customDomain != null) customDomain.unmarshal(value);
|
||||
return customDomain;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, CustomDomain> unmarshal(Map<String, Object> rawValues, boolean createUnknown) {
|
||||
checkNotNull(rawValues, "rawValues");
|
||||
|
||||
Map<String, CustomDomain> domains = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, Object> entry : rawValues.entrySet()) {
|
||||
try {
|
||||
CustomDomain domain = getOrCreate(entry.getKey(), entry.getValue(), createUnknown);
|
||||
domains.put(domain.getName(), domain);
|
||||
} catch (Throwable e) {
|
||||
log.log(Level.WARNING, "Failed to unmarshal domain for " + entry.getKey(), e);
|
||||
}
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return domains.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<DomainFactory<?>> iterator() {
|
||||
return Iterators.unmodifiableIterator(domains.values().iterator());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains.registry;
|
||||
|
||||
import com.sk89q.worldguard.domains.CustomDomain;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UnknownDomain extends CustomDomain {
|
||||
public static DomainFactory<UnknownDomain> FACTORY = UnknownDomain::new;
|
||||
|
||||
private boolean isDirty = false;
|
||||
private Object o;
|
||||
|
||||
public UnknownDomain(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseInput(CustomDomainContext context) throws InvalidDomainFormatException {
|
||||
throw new InvalidDomainFormatException("The plugin that registered this domain is not currently installed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmarshal(Object o) {
|
||||
this.o = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal() {
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(UUID uniqueId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String playerName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
isDirty = true;
|
||||
o = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty(boolean dirty) {
|
||||
isDirty = dirty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UnknownDomain{" +
|
||||
"o=" + o +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -63,7 +63,11 @@ public class RegionPermissionModel extends AbstractPermissionModel {
|
|||
public boolean mayMigrateRegionNames() {
|
||||
return hasPluginPermission("region.migrateuuid");
|
||||
}
|
||||
|
||||
|
||||
public boolean mayMigrateRegionHeights() {
|
||||
return hasPluginPermission("region.migrateheights");
|
||||
}
|
||||
|
||||
public boolean mayDefine() {
|
||||
return hasPluginPermission("region.define");
|
||||
}
|
||||
|
@ -106,6 +110,10 @@ public class RegionPermissionModel extends AbstractPermissionModel {
|
|||
return hasPatternPermission("teleport", region);
|
||||
}
|
||||
|
||||
public boolean mayTeleportToCenter(ProtectedRegion region) {
|
||||
return hasPatternPermission("teleportcenter", region);
|
||||
}
|
||||
|
||||
public boolean mayOverrideLocationFlagBounds(ProtectedRegion region) {
|
||||
return hasPatternPermission("locationoverride", region);
|
||||
}
|
||||
|
@ -125,7 +133,7 @@ public class RegionPermissionModel extends AbstractPermissionModel {
|
|||
return mayList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean maySetFlag(ProtectedRegion region) {
|
||||
return hasPatternPermission("flag.regions", region);
|
||||
}
|
||||
|
@ -168,13 +176,14 @@ public class RegionPermissionModel extends AbstractPermissionModel {
|
|||
public boolean mayRemoveOwners(ProtectedRegion region) {
|
||||
return hasPatternPermission("removeowner", region);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if the given sender has permission to modify the given region
|
||||
* using the region permission pattern.
|
||||
*
|
||||
* @param perm the name of the node
|
||||
* @param region the region
|
||||
* @return whether the actor has the permission
|
||||
*/
|
||||
private boolean hasPatternPermission(String perm, ProtectedRegion region) {
|
||||
if (!(getSender() instanceof Player)) {
|
||||
|
@ -195,5 +204,4 @@ public class RegionPermissionModel extends AbstractPermissionModel {
|
|||
|
||||
return hasPluginPermission(effectivePerm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,15 +21,18 @@ package com.sk89q.worldguard.internal.platform;
|
|||
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.report.ReportList;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.protection.flags.FlagContext;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.session.SessionManager;
|
||||
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
|
||||
import com.sk89q.worldguard.util.profile.resolver.ProfileService;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
|
@ -155,4 +158,15 @@ public interface WorldGuardPlatform {
|
|||
* Internal use.
|
||||
*/
|
||||
ProfileService createProfileService(ProfileCache profileCache);
|
||||
|
||||
/**
|
||||
* Get a region that encompasses the Vanilla spawn protection for the given world, if applicable.
|
||||
*
|
||||
* @param world world to check spawn protection of
|
||||
* @return a region, or null if not applicable
|
||||
*/
|
||||
@Nullable
|
||||
default ProtectedRegion getSpawnProtection(World world) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ import com.sk89q.worldguard.LocalPlayer;
|
|||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.MapFlag;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
@ -119,6 +121,50 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
|
|||
@Nullable
|
||||
<V> V queryValue(@Nullable RegionAssociable subject, Flag<V> flag);
|
||||
|
||||
/**
|
||||
* Get the effective value for a key in a {@link MapFlag}. If there are multiple values
|
||||
* (for example, if there are multiple regions with the same priority
|
||||
* but with different farewell messages set, there would be multiple
|
||||
* completing values), then the selected (or "winning") value will be undefined.
|
||||
*
|
||||
* <p>A subject can be provided that is used to determine whether the value
|
||||
* of a flag on a particular region should be used. For example, if a
|
||||
* flag's region group is set to {@link RegionGroup#MEMBERS} and the given
|
||||
* subject is not a member, then the region would be skipped when
|
||||
* querying that flag. If {@code null} is provided for the subject, then
|
||||
* only flags that use {@link RegionGroup#ALL},
|
||||
* {@link RegionGroup#NON_MEMBERS}, etc. will apply.</p>
|
||||
*
|
||||
* @param subject an optional subject, which would be used to determine the region group to apply
|
||||
* @param flag the flag of type {@link MapFlag}
|
||||
* @param key the key for the map flag
|
||||
* @return a value, which could be {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
<V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key);
|
||||
|
||||
/**
|
||||
* Get the effective value for a key in a {@link MapFlag}. If there are multiple values
|
||||
* (for example, if there are multiple regions with the same priority
|
||||
* but with different farewell messages set, there would be multiple
|
||||
* completing values), then the selected (or "winning") value will be undefined.
|
||||
*
|
||||
* <p>A subject can be provided that is used to determine whether the value
|
||||
* of a flag on a particular region should be used. For example, if a
|
||||
* flag's region group is set to {@link RegionGroup#MEMBERS} and the given
|
||||
* subject is not a member, then the region would be skipped when
|
||||
* querying that flag. If {@code null} is provided for the subject, then
|
||||
* only flags that use {@link RegionGroup#ALL},
|
||||
* {@link RegionGroup#NON_MEMBERS}, etc. will apply.</p>
|
||||
*
|
||||
* @param subject an optional subject, which would be used to determine the region group to apply
|
||||
* @param flag the flag of type {@link MapFlag}
|
||||
* @param key the key for the map flag
|
||||
* @return a value, which could be {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
<V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback);
|
||||
|
||||
/**
|
||||
* Get the effective values for a flag, returning a collection of all
|
||||
* values. It is up to the caller to determine which value, if any,
|
||||
|
|
|
@ -21,16 +21,8 @@ package com.sk89q.worldguard.protection;
|
|||
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import com.sk89q.worldguard.domains.Association;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Determines that the association to a region is {@code OWNER} if the input
|
||||
|
@ -38,41 +30,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
*
|
||||
* <p>This class only performs a spatial query if its
|
||||
* {@link #getAssociation(List)} method is called.</p>
|
||||
*
|
||||
* @deprecated Use {@link com.sk89q.worldguard.protection.association.DelayedRegionOverlapAssociation} instead. This class is mis-packaged.
|
||||
*/
|
||||
public class DelayedRegionOverlapAssociation implements RegionAssociable {
|
||||
|
||||
private final RegionQuery query;
|
||||
private final Location location;
|
||||
@Nullable
|
||||
private Set<ProtectedRegion> source;
|
||||
|
||||
@Deprecated
|
||||
public class DelayedRegionOverlapAssociation extends com.sk89q.worldguard.protection.association.DelayedRegionOverlapAssociation {
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param query the query
|
||||
* @param location the location
|
||||
*/
|
||||
public DelayedRegionOverlapAssociation(RegionQuery query, Location location) {
|
||||
checkNotNull(query);
|
||||
checkNotNull(location);
|
||||
this.query = query;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Association getAssociation(List<ProtectedRegion> regions) {
|
||||
if (source == null) {
|
||||
ApplicableRegionSet result = query.getApplicableRegions(location);
|
||||
source = result.getRegions();
|
||||
}
|
||||
|
||||
for (ProtectedRegion region : regions) {
|
||||
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty()) || source.contains(region)) {
|
||||
return Association.OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
return Association.NON_MEMBER;
|
||||
super(query, location, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.sk89q.worldguard.LocalPlayer;
|
|||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.MapFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
|
@ -31,6 +32,7 @@ import javax.annotation.Nullable;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -65,6 +67,19 @@ public class FailedLoadRegionSet extends AbstractRegionSet {
|
|||
return flag.getDefault();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
|
||||
return queryMapValue(subject, flag, key, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback) {
|
||||
Map<K, V> defaultVal = flag.getDefault();
|
||||
return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.sk89q.worldguard.domains.Association;
|
|||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.MapFlag;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
|
@ -89,13 +90,14 @@ public class FlagValueCalculator {
|
|||
/**
|
||||
* Return the membership status of the given subject, indicating
|
||||
* whether there are no (counted) regions in the list of regions,
|
||||
* whether the subject is a member of all regions, or whether
|
||||
* the region is not a member of all regions.
|
||||
* whether the subject is a member of all (counted) regions, or
|
||||
* whether the subject is not a member of all (counted) regions.
|
||||
*
|
||||
* <p>A region is "counted" if it doesn't have the
|
||||
* {@link Flags#PASSTHROUGH} flag set to {@code ALLOW}. (The
|
||||
* explicit purpose of the PASSTHROUGH flag is to have the region
|
||||
* be skipped over in this check.)</p>
|
||||
* {@link Flags#PASSTHROUGH} flag set to {@code ALLOW} and if
|
||||
* there isn't another "counted" region with a higher priority.
|
||||
* (The explicit purpose of the PASSTHROUGH flag is to have the
|
||||
* region be skipped over in this check.)</p>
|
||||
*
|
||||
* <p>This method is mostly for internal use. It's not particularly
|
||||
* useful.</p>
|
||||
|
@ -112,11 +114,13 @@ public class FlagValueCalculator {
|
|||
Set<ProtectedRegion> ignoredRegions = Sets.newHashSet();
|
||||
|
||||
for (ProtectedRegion region : getApplicable()) {
|
||||
int priority = getPriority(region);
|
||||
|
||||
// Don't consider lower priorities below minimumPriority
|
||||
// (which starts at Integer.MIN_VALUE). A region that "counts"
|
||||
// (has the flag set OR has members) will raise minimumPriority
|
||||
// to its own priority.
|
||||
if (getPriority(region) < minimumPriority) {
|
||||
if (priority < minimumPriority) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -129,7 +133,7 @@ public class FlagValueCalculator {
|
|||
continue;
|
||||
}
|
||||
|
||||
minimumPriority = getPriority(region);
|
||||
minimumPriority = priority;
|
||||
|
||||
boolean member = RegionGroup.MEMBERS.contains(subject.getAssociation(Collections.singletonList(region)));
|
||||
|
||||
|
@ -224,6 +228,117 @@ public class FlagValueCalculator {
|
|||
return flag.chooseValue(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effective value for a key in a {@link MapFlag}. If there are multiple values
|
||||
* (for example, if there are multiple regions with the same priority
|
||||
* but with different farewell messages set, there would be multiple
|
||||
* completing values), then the selected (or "winning") value will be undefined.
|
||||
*
|
||||
* <p>A subject can be provided that is used to determine whether the value
|
||||
* of a flag on a particular region should be used. For example, if a
|
||||
* flag's region group is set to {@link RegionGroup#MEMBERS} and the given
|
||||
* subject is not a member, then the region would be skipped when
|
||||
* querying that flag. If {@code null} is provided for the subject, then
|
||||
* only flags that use {@link RegionGroup#ALL},
|
||||
* {@link RegionGroup#NON_MEMBERS}, etc. will apply.</p>
|
||||
*
|
||||
* @param subject an optional subject, which would be used to determine the region group to apply
|
||||
* @param flag the flag of type {@link MapFlag}
|
||||
* @param key the key for the map flag
|
||||
* @return a value, which could be {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, Flag<V> fallback) {
|
||||
checkNotNull(flag);
|
||||
checkNotNull(key);
|
||||
|
||||
Map<ProtectedRegion, V> consideredValues = new HashMap<>();
|
||||
Map<ProtectedRegion, V> fallbackValues = new HashMap<>();
|
||||
int minimumPriority = Integer.MIN_VALUE;
|
||||
Set<ProtectedRegion> ignoredParents = new HashSet<>();
|
||||
|
||||
for(ProtectedRegion region : getApplicable()) {
|
||||
int priority = getPriority(region);
|
||||
|
||||
if (priority < minimumPriority) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ignoredParents.contains(region)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
V effectiveValue = getEffectiveMapValue(region, flag, key, subject);
|
||||
|
||||
if (effectiveValue != null) {
|
||||
minimumPriority = priority;
|
||||
consideredValues.put(region, effectiveValue);
|
||||
} else if (fallback != null) {
|
||||
effectiveValue = getEffectiveFlag(region, fallback, subject);
|
||||
if (effectiveValue != null) {
|
||||
minimumPriority = priority;
|
||||
fallbackValues.put(region, effectiveValue);
|
||||
}
|
||||
}
|
||||
|
||||
addParents(ignoredParents, region);
|
||||
}
|
||||
|
||||
|
||||
if (consideredValues.isEmpty()) {
|
||||
if (fallback != null && !fallbackValues.isEmpty()) {
|
||||
return fallback.chooseValue(fallbackValues.values());
|
||||
}
|
||||
V defaultValue = flag.getValueFlag().getDefault();
|
||||
return defaultValue != null ? defaultValue : fallback != null ? fallback.getDefault() : null;
|
||||
}
|
||||
|
||||
return flag.getValueFlag().chooseValue(consideredValues.values());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <V, K> V getEffectiveMapValue(ProtectedRegion region, MapFlag<K, V> mapFlag, K key, RegionAssociable subject) {
|
||||
return getEffectiveMapValueOf(region, mapFlag, key, subject);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <V, K> V getEffectiveMapValueOf(ProtectedRegion region, MapFlag<K, V> mapFlag, K key, RegionAssociable subject) {
|
||||
List<ProtectedRegion> seen = new ArrayList<>();
|
||||
ProtectedRegion current = region;
|
||||
|
||||
while (current != null) {
|
||||
seen.add(current);
|
||||
|
||||
Map<K, V> mapValue = current.getFlag(mapFlag);
|
||||
|
||||
if (mapValue != null && mapValue.containsKey(key)) {
|
||||
boolean use = true;
|
||||
|
||||
if (mapFlag.getRegionGroupFlag() != null) {
|
||||
RegionGroup group = current.getFlag(mapFlag.getRegionGroupFlag());
|
||||
if (group == null) {
|
||||
group = mapFlag.getRegionGroupFlag().getDefault();
|
||||
}
|
||||
|
||||
if (group == null) {
|
||||
use = false;
|
||||
} else if (subject == null) {
|
||||
use = group.contains(Association.NON_MEMBER);
|
||||
} else if (!group.contains(subject.getAssociation(seen))) {
|
||||
use = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (use) {
|
||||
return mapValue.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
current = current.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effective values for a flag, returning a collection of all
|
||||
* values. It is up to the caller to determine which value, if any,
|
||||
|
@ -283,7 +398,9 @@ public class FlagValueCalculator {
|
|||
Set<ProtectedRegion> ignoredParents = new HashSet<>();
|
||||
|
||||
for (ProtectedRegion region : getApplicable()) {
|
||||
if (getPriority(region) < minimumPriority) {
|
||||
int priority = getPriority(region);
|
||||
|
||||
if (priority < minimumPriority) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -292,7 +409,6 @@ public class FlagValueCalculator {
|
|||
}
|
||||
|
||||
V value = getEffectiveFlag(region, flag, subject);
|
||||
int priority = getPriority(region);
|
||||
|
||||
if (value != null) {
|
||||
minimumPriority = priority;
|
||||
|
@ -310,7 +426,7 @@ public class FlagValueCalculator {
|
|||
// PASSTHROUGH is not set to ALLOW
|
||||
if (priority != minimumPriority && flag.implicitlySetWithMembership()
|
||||
&& getEffectiveFlag(region, Flags.PASSTHROUGH, subject) != State.ALLOW) {
|
||||
minimumPriority = getPriority(region);
|
||||
minimumPriority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,7 +455,11 @@ public class FlagValueCalculator {
|
|||
* @return the priority
|
||||
*/
|
||||
public int getPriority(final ProtectedRegion region) {
|
||||
if (region == globalRegion) {
|
||||
return getPriorityOf(region);
|
||||
}
|
||||
|
||||
public static int getPriorityOf(final ProtectedRegion region) {
|
||||
if (region.getId().equals(ProtectedRegion.GLOBAL_REGION)) {
|
||||
return Integer.MIN_VALUE;
|
||||
} else {
|
||||
return region.getPriority();
|
||||
|
@ -355,13 +475,20 @@ public class FlagValueCalculator {
|
|||
* @param subject an subject object
|
||||
* @return the value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public <V> V getEffectiveFlag(final ProtectedRegion region, Flag<V> flag, @Nullable RegionAssociable subject) {
|
||||
if (region == globalRegion) {
|
||||
return getEffectiveFlagOf(region, flag, subject);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public static <V> V getEffectiveFlagOf(final ProtectedRegion region, Flag<V> flag, @Nullable RegionAssociable subject) {
|
||||
if (region.getId().equals(ProtectedRegion.GLOBAL_REGION)) {
|
||||
if (flag == Flags.PASSTHROUGH) {
|
||||
// Has members/owners -> the global region acts like
|
||||
// a regular region without PASSTHROUGH
|
||||
if (region.hasMembersOrOwners() || region.getFlag(Flags.PASSTHROUGH) == State.DENY) {
|
||||
State passthrough = region.getFlag(Flags.PASSTHROUGH);
|
||||
if (passthrough == State.DENY || passthrough != State.ALLOW && region.hasMembersOrOwners()) {
|
||||
return null;
|
||||
} else {
|
||||
return (V) State.ALLOW;
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.sk89q.worldguard.LocalPlayer;
|
|||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.MapFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
|
@ -31,6 +32,7 @@ import javax.annotation.Nullable;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -59,6 +61,19 @@ public class PermissiveRegionSet extends AbstractRegionSet {
|
|||
return flag.getDefault();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
|
||||
return queryMapValue(subject, flag, key, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback) {
|
||||
Map<K, V> defaultVal = flag.getDefault();
|
||||
return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag<V> flag) {
|
||||
|
|
|
@ -19,16 +19,22 @@
|
|||
|
||||
package com.sk89q.worldguard.protection;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.MapFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.util.NormativeOrders;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -63,7 +69,7 @@ public class RegionResultSet extends AbstractRegionSet {
|
|||
*/
|
||||
public RegionResultSet(Set<ProtectedRegion> applicable, @Nullable ProtectedRegion globalRegion) {
|
||||
this(NormativeOrders.fromSet(applicable), globalRegion, true);
|
||||
this.regionSet = applicable;
|
||||
this.regionSet = ImmutableSet.copyOf(applicable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,7 +88,7 @@ public class RegionResultSet extends AbstractRegionSet {
|
|||
if (!sorted) {
|
||||
NormativeOrders.sort(applicable);
|
||||
}
|
||||
this.applicable = applicable;
|
||||
this.applicable = Collections.unmodifiableList(applicable);
|
||||
this.flagValueCalculator = new FlagValueCalculator(applicable, globalRegion);
|
||||
}
|
||||
|
||||
|
@ -108,6 +114,18 @@ public class RegionResultSet extends AbstractRegionSet {
|
|||
return flagValueCalculator.queryAllValues(subject, flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
|
||||
return flagValueCalculator.queryMapValue(subject, flag, key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, Flag<V> fallback) {
|
||||
return flagValueCalculator.queryMapValue(subject, flag, key, fallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOwnerOfAll(LocalPlayer player) {
|
||||
checkNotNull(player);
|
||||
|
@ -144,7 +162,7 @@ public class RegionResultSet extends AbstractRegionSet {
|
|||
if (regionSet != null) {
|
||||
return regionSet;
|
||||
}
|
||||
regionSet = Collections.unmodifiableSet(new HashSet<>(applicable));
|
||||
regionSet = ImmutableSet.copyOf(applicable);
|
||||
return regionSet;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.association;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldguard.domains.Association;
|
||||
import com.sk89q.worldguard.protection.FlagValueCalculator;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class AbstractRegionOverlapAssociation implements RegionAssociable {
|
||||
|
||||
@Nullable
|
||||
protected Set<ProtectedRegion> source;
|
||||
private boolean useMaxPriorityAssociation;
|
||||
private int maxPriority;
|
||||
private Set<ProtectedRegion> maxPriorityRegions;
|
||||
|
||||
protected AbstractRegionOverlapAssociation(@Nullable Set<ProtectedRegion> source, boolean useMaxPriorityAssociation) {
|
||||
this.source = source;
|
||||
this.useMaxPriorityAssociation = useMaxPriorityAssociation;
|
||||
}
|
||||
|
||||
protected void calcMaxPriority() {
|
||||
checkNotNull(source);
|
||||
int best = 0;
|
||||
Set<ProtectedRegion> bestRegions = new HashSet<>();
|
||||
for (ProtectedRegion region : source) {
|
||||
int priority = region.getPriority();
|
||||
if (priority > best) {
|
||||
best = priority;
|
||||
bestRegions.clear();
|
||||
bestRegions.add(region);
|
||||
} else if (priority == best) {
|
||||
bestRegions.add(region);
|
||||
}
|
||||
}
|
||||
this.maxPriority = best;
|
||||
this.maxPriorityRegions = bestRegions;
|
||||
}
|
||||
|
||||
private boolean checkNonplayerProtectionDomains(Iterable<? extends ProtectedRegion> source, Collection<?> domains) {
|
||||
if (source == null || domains == null || domains.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ProtectedRegion region : source) {
|
||||
// Potential endless recurrence? No, because there is no region group flag.
|
||||
Set<String> regionDomains = FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, this);
|
||||
|
||||
if (regionDomains == null || regionDomains.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Collections.disjoint(regionDomains, domains)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Association getAssociation(List<ProtectedRegion> regions) {
|
||||
checkNotNull(source);
|
||||
for (ProtectedRegion region : regions) {
|
||||
while (region != null) {
|
||||
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty())) {
|
||||
return Association.OWNER;
|
||||
}
|
||||
|
||||
if (source.contains(region)) {
|
||||
if (useMaxPriorityAssociation) {
|
||||
int priority = region.getPriority();
|
||||
if (priority == maxPriority) {
|
||||
return Association.OWNER;
|
||||
}
|
||||
} else {
|
||||
return Association.OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
Set<ProtectedRegion> source;
|
||||
|
||||
if (useMaxPriorityAssociation) {
|
||||
source = maxPriorityRegions;
|
||||
} else {
|
||||
source = this.source;
|
||||
}
|
||||
|
||||
// Potential endless recurrence? No, because there is no region group flag.
|
||||
if (checkNonplayerProtectionDomains(source, FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, this))) {
|
||||
return Association.OWNER;
|
||||
}
|
||||
|
||||
region = region.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
return Association.NON_MEMBER;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue