Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
014277fb2f | ||
|
|
f7ff984c34 | ||
|
|
d4b2060766 | ||
|
|
0e73b50d6f | ||
|
|
136ec31f38 | ||
|
|
ad000ab051 | ||
|
|
af67f1dd6a | ||
|
|
8dee2ad3b8 | ||
|
|
c860fce299 | ||
|
|
0cb84927a3 | ||
|
|
2ed60eba02 | ||
|
|
91a1494634 | ||
|
|
5b8c3e7f70 | ||
|
|
c1ff4fc3d3 | ||
|
|
691325c8f0 | ||
|
|
3da19a7ff0 | ||
|
|
f677af566f | ||
|
|
58eaf31879 | ||
|
|
6708b21016 | ||
|
|
ed4287ace7 | ||
|
|
03f05d3a4e | ||
|
|
c8bde17994 | ||
|
|
449145ba1f | ||
|
|
85c5f53d29 | ||
|
|
5162ce3dbd | ||
|
|
efe1e48bd4 | ||
|
|
1710c07623 | ||
|
|
6f9ed5d10f | ||
|
|
f0ec54af49 | ||
|
|
e9e1885f2e | ||
|
|
f8e2d8d6b7 | ||
|
|
2c0b592b19 | ||
|
|
46e230e625 | ||
|
|
fe24668c6a | ||
|
|
23efd5fec2 | ||
|
|
e54235a65e | ||
|
|
5ec3ed6092 | ||
|
|
1652c9bfc0 | ||
|
|
a97db0ede9 | ||
|
|
36e42eefd0 | ||
|
|
5b8eef92b8 | ||
|
|
d73dc6d719 | ||
|
|
74d8a4f0e7 | ||
|
|
613406aab4 | ||
|
|
66fd84ba2f | ||
|
|
53abb6c4ad | ||
|
|
923369e28c | ||
|
|
bc551da903 | ||
|
|
bffe5e76f2 | ||
|
|
8722322cd8 | ||
|
|
0fa92d4836 | ||
|
|
e52875bd0b | ||
|
|
dbad328d0d | ||
|
|
5407315799 | ||
|
|
b769469f5b | ||
|
|
3a9b1b1525 | ||
|
|
ff5f933879 | ||
|
|
0492fafe30 | ||
|
|
36d95ad090 | ||
|
|
c1ec708050 | ||
|
|
f4a3e8a936 | ||
|
|
6c5380ba0b | ||
|
|
868089b44f | ||
|
|
9905d22ddf | ||
|
|
4eaa376e2c | ||
|
|
37ae70f35d | ||
|
|
1a69250d9b | ||
|
|
b2d2d0815b | ||
|
|
47cd96a3af | ||
|
|
0a735e0146 | ||
|
|
60590acfe3 | ||
|
|
6030bea13e | ||
|
|
20f89ea2ae | ||
|
|
4c351fb0e3 | ||
|
|
5e7829c3fe | ||
|
|
37e66dae7d | ||
|
|
662ae2bc84 | ||
|
|
fa60582afe | ||
|
|
17c1647163 | ||
|
|
1fcda13469 | ||
|
|
570b7f7b77 | ||
|
|
aca0d843f6 | ||
|
|
1172ebd419 | ||
|
|
a09ccc5b45 | ||
|
|
e6bdf8abb5 | ||
|
|
df2ae6a666 | ||
|
|
e4481f9337 | ||
|
|
2169aa218e | ||
|
|
523e45188d | ||
|
|
d95c6af1be | ||
|
|
0d860bfca7 | ||
|
|
6f6125fe00 | ||
|
|
0332929531 | ||
|
|
637665f52d | ||
|
|
db3838ccfe | ||
|
|
789405d116 | ||
|
|
d37f015f0c | ||
|
|
239eda3f96 | ||
|
|
0715cbe216 | ||
|
|
738b24bfc1 | ||
|
|
b835ee39d5 | ||
|
|
4a7552e6be | ||
|
|
c6c0fc9d74 | ||
|
|
f43a4eaad8 | ||
|
|
abfa5cb6a5 | ||
|
|
05f7d68705 | ||
|
|
9adac4f239 | ||
|
|
c5355adb4b | ||
|
|
fb37342b3c | ||
|
|
1fd94a3655 | ||
|
|
c413cf4123 | ||
|
|
87162acf11 | ||
|
|
2c14acc28c | ||
|
|
26477406f1 | ||
|
|
121b34ecb9 | ||
|
|
3ebaaf9c8b | ||
|
|
4c9812db04 | ||
|
|
e792dd6f98 | ||
|
|
d410e1f84e | ||
|
|
d07f95952d | ||
|
|
cb9ab3a7b2 | ||
|
|
1c3cf02ebd | ||
|
|
fc0f7acab5 | ||
|
|
20db92541b | ||
|
|
5fca3b3c3d | ||
|
|
c633a2d070 | ||
|
|
effbd62e68 | ||
|
|
056eaa6587 | ||
|
|
cb2c0870ec | ||
|
|
179c324c80 | ||
|
|
96d15d6dbf | ||
|
|
120d2e223d | ||
|
|
70ea6bad6e | ||
|
|
e59d61e1cf | ||
|
|
bbed280f62 | ||
|
|
f165ae3d95 | ||
|
|
124898ec91 | ||
|
|
ba32d24363 | ||
|
|
0bba822295 | ||
|
|
7538af2686 | ||
|
|
48922118b1 | ||
|
|
14fe2d0e79 | ||
|
|
11a1ac6742 | ||
|
|
c5bfdcb0e6 | ||
|
|
93dae282b2 | ||
|
|
3468e3d47e | ||
|
|
b7ad0257b7 | ||
|
|
070f6e005f | ||
|
|
cc3f4d4d44 | ||
|
|
21e65be110 | ||
|
|
61494fd76e | ||
|
|
556b638d04 | ||
|
|
825b3a3f36 | ||
|
|
afe042ef4d | ||
|
|
4044e2b122 | ||
|
|
aa4137822f | ||
|
|
f37acd3de6 | ||
|
|
b0e4cf148b | ||
|
|
248ffd0ba8 | ||
|
|
3272759f25 | ||
|
|
456a16591b | ||
|
|
79f6635b8a | ||
|
|
1f362bef59 | ||
|
|
63209d1174 | ||
|
|
f546700189 | ||
|
|
35e0db36d3 | ||
|
|
ab7751e046 | ||
|
|
a9cd23c6ef | ||
|
|
8ca01b37a4 | ||
|
|
aa8997aeca | ||
|
|
b757fcc88b | ||
|
|
7593e1a01c | ||
|
|
af3eb85962 | ||
|
|
aabb0b2345 | ||
|
|
6d25513739 | ||
|
|
96b61743b9 | ||
|
|
ff7209a58b | ||
|
|
fe4f0cfc49 | ||
|
|
9cf1e02506 |
No files matched your search
@@ -0,0 +1 @@
|
||||
github: enginehub
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a way in which WorldGuard is not working as intended
|
||||
title: ''
|
||||
labels: type:bug, status:pending
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Versions**
|
||||
<!-- Please include the full version of WorldEdit, WorldGuard and the platform (Bukkit/Spigot/Paper) you are running, e.g. output from `/we version`, `/wg version` `/version` commands. Please ensure you are running up to date software before making a bug report. Old versions will receive little to no support. -->
|
||||
WorldEdit version:
|
||||
|
||||
WorldGuard version:
|
||||
|
||||
Platform version:
|
||||
|
||||
|
||||
**Describe the bug**
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**To Reproduce**
|
||||
<!-- Steps to reproduce the behavior: -->
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
**Expected behavior**
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- If applicable, add screenshots to help explain your problem. Screenshots of `/rg info` for any applicable regions (or simply the link from `/wg report -p`) are good to include. -->
|
||||
|
||||
**Additional context**
|
||||
<!-- Add any other context about the problem here. -->
|
||||
@@ -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,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for WorldGuard
|
||||
title: ''
|
||||
labels: type:feature-request, status:pending
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
||||
|
||||
**Describe the solution you'd like**
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
**Additional context**
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
@@ -15,3 +15,5 @@ dependency-reduced-pom.xml
|
||||
.gradle/
|
||||
**/build/
|
||||
out/
|
||||
|
||||
scripts/
|
||||
@@ -1,4 +1,5 @@
|
||||
language: java
|
||||
dist: trusty
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
notifications:
|
||||
|
||||
@@ -1,5 +1,102 @@
|
||||
# Changelog
|
||||
|
||||
## 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.
|
||||
|
||||
|
||||
## 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.
|
||||
* Fix some checks for adding owners to unclaimed regions.
|
||||
* Fix an issue with time-/weather-lock flags when logging in to a region with the flag set.
|
||||
* Fix cause tracking in vehicles (incl. breaking lilypads in a boat)
|
||||
* Use async teleports on Paper.
|
||||
* Include hopper minecarts in the ignore hoppers config setting.
|
||||
* Add sugar cane and cacti to the crop-growth flag. Bamboo is also included pending Spigot throwing an event for it.
|
||||
* Specifically track when players ignite creepers with flint and steel.
|
||||
* Fix fuzziness when using bonemeal near a protected region.
|
||||
* Fix color codes not applying in greeting, etc flags when placed after a newline (\n).
|
||||
* Add applicable region information to `/wg report`.
|
||||
* Fix pistons flag not applying to sticky pistons pulling blocks.
|
||||
* Add some custom metrics for bStats.
|
||||
* Everything in the RC/beta changelog below.
|
||||
|
||||
## 7.0.1 RC 2 (inc. beta 1)
|
||||
* Due to breaking changes in important Bukkit API, this is not compatible with MC 1.13!
|
||||
* Update to MC 1.14. Adds protection for new blocks, etc.
|
||||
* To allow players to read from lecterns, but not take the book, flag interact allow, and then flag chest-access -g nonmembers deny.
|
||||
* Add ravager-grief flag.
|
||||
* Fix overprotection of unsaddled pigs with the ride flag.
|
||||
* Fix lava fire defaulting to off (won't change existing configs).
|
||||
* Fix damaged/chipped anvils not respecting use flag like regular anvils.
|
||||
* Add on-equip blacklist event. Note that it is overprotective due to deficiencies in Bukkit API.
|
||||
* Update WorldEdit CUI when using /rg select.
|
||||
* Add config option to disable villagers getting zapped into witches. ("weather.disable-villager-witchification")
|
||||
* Add entity support to interact-whitelist config option (use the Material of the corresponding item).
|
||||
* Fix vehicle-place protecting the rails at the very top of region boundaries incorrectly.
|
||||
* Fix for emptying buckets on waterloggable blocks.
|
||||
* Whitelist all player -> player interactions (previously was spammy in pvp).
|
||||
* Fix sleep flag not protecting against explosions in nether/end.
|
||||
* Add config for the teleport-on-void to reset fall distance.
|
||||
* Fix config options taking material lists requiring "minecraft:" namespace.
|
||||
* Fix disallowed-lightning-blocks situationally not working.
|
||||
* Fix errors that occurred when plugins used falling block entities with non-item materials.
|
||||
* Add special support for Paper servers (papermc.io): Paper's API allows us to track who launched fireworks.
|
||||
* Fireworks are now protected by default. On Paper servers, members can use them by default (to deal damage),
|
||||
on non-Paper servers, flag firework-damage allow to revert to old behavior (everyone can deal damage with fireworks by default).
|
||||
* Misc performance enhancements for Paper servers.
|
||||
* Add 'regions.use-paper-entity-origin' as an experimental setting (default off) for Paper servers. Enabling it will make non-player entities be treated as members of the place they spawned, instead of their current location when flags are checked.
|
||||
|
||||
## 7.0.0
|
||||
* Added support for MC 1.13, dropped support for previous versions.
|
||||
* Added lots of interactive text in e.g. `/rg info` command.
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
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/>.
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
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.
|
||||
@@ -22,8 +22,7 @@ Compiling
|
||||
---------
|
||||
|
||||
The project is written for Java 8 and our build process makes use of
|
||||
[Gradle](http://gradle.org). Detailed compilation information
|
||||
[can be found on the wiki](http://wiki.sk89q.com/wiki/WorldGuard/Development#Compiling).
|
||||
[Gradle](http://gradle.org).
|
||||
|
||||
Dependencies are automatically handled by Gradle.
|
||||
|
||||
@@ -43,5 +42,5 @@ Links
|
||||
* [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) [](https://travis-ci.org/EngineHub/WorldGuard)
|
||||
* [End-user documentation](https://worldguard.readthedocs.io/en/latest/) / [Older Wiki](http://wiki.sk89q.com/wiki/WorldGuard)
|
||||
* [Continuous integration](http://builds.enginehub.org) [](http://ci.enginehub.org/viewType.html?buildTypeId=bt11&guest=1)
|
||||
* [End-user documentation](https://worldguard.enginehub.org/en/latest/)
|
||||
-136
@@ -1,136 +0,0 @@
|
||||
println """
|
||||
*******************************************
|
||||
You are building WorldGuard!
|
||||
|
||||
If you encounter trouble:
|
||||
1) Read COMPILING.md if you haven't yet
|
||||
2) Try running 'build' in a separate Gradle run
|
||||
3) Use gradlew and not gradle
|
||||
4) If you still need help, ask on IRC! irc.esper.net #sk89q
|
||||
|
||||
Output files will be in [subproject]/build/libs
|
||||
*******************************************
|
||||
"""
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
jcenter()
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
force 'com.google.guava:guava:21.0'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "com.github.jengelman.gradle.plugins:shadow:4.0.3"
|
||||
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.5'
|
||||
classpath 'org.ajoberstar:gradle-git:1.7.2'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
group = 'com.sk89q.worldguard'
|
||||
version = '7.0.0'
|
||||
}
|
||||
|
||||
if (!project.hasProperty("artifactory_contextUrl")) ext.artifactory_contextUrl = "http://localhost"
|
||||
if (!project.hasProperty("artifactory_user")) ext.artifactory_user = "guest"
|
||||
if (!project.hasProperty("artifactory_password")) ext.artifactory_password = ""
|
||||
|
||||
if (!project.hasProperty("gitCommitHash")) {
|
||||
try {
|
||||
def repo = org.ajoberstar.grgit.Grgit.open(project.file('.'))
|
||||
ext.gitCommitHash = repo.head().abbreviatedId
|
||||
} catch (Exception e) {
|
||||
ext.gitCommitHash = "no_git_id"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.jfrog.artifactory'
|
||||
artifactory {
|
||||
contextUrl = "${artifactory_contextUrl}"
|
||||
publish {
|
||||
repository {
|
||||
repoKey = project.version.contains("SNAPSHOT") ? 'libs-snapshot-local' : 'libs-release-local'
|
||||
username = "${artifactory_user}"
|
||||
password = "${artifactory_password}"
|
||||
maven = true
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
artifactoryPublish.skip = true
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'checkstyle'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply plugin: 'com.jfrog.artifactory'
|
||||
|
||||
ext.internalVersion = version + ";" + gitCommitHash
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
|
||||
checkstyle.configFile = new File(rootProject.projectDir, "config/checkstyle/checkstyle.xml")
|
||||
checkstyle.toolVersion = '7.6.1'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url "https://repo.spongepowered.org/maven/" }
|
||||
maven { url "https://hub.spigotmc.org/nexus/content/groups/public" }
|
||||
maven { url "https://maven.sk89q.com/repo/" }
|
||||
maven { url "https://repo.maven.apache.org/maven2" }
|
||||
}
|
||||
|
||||
if (JavaVersion.current().isJava8Compatible()) {
|
||||
// Java 8 turns on doclint which we fail
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives jar
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
|
||||
build.dependsOn(checkstyleMain)
|
||||
build.dependsOn(checkstyleTest)
|
||||
build.dependsOn(sourcesJar)
|
||||
build.dependsOn(javadocJar)
|
||||
|
||||
shadowJar {
|
||||
classifier 'dist'
|
||||
dependencies {
|
||||
include(dependency('org.khelekore:prtree:1.5.0'))
|
||||
include(dependency('com.sk89q:squirrelid:0.2.0'))
|
||||
include(dependency('org.flywaydb:flyway-core:3.0'))
|
||||
}
|
||||
exclude 'GradleStart**'
|
||||
exclude '.cache'
|
||||
exclude 'LICENSE*'
|
||||
}
|
||||
|
||||
artifactoryPublish {
|
||||
publishConfigs('archives')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
|
||||
logger.lifecycle("""
|
||||
*******************************************
|
||||
You are building WorldGuard!
|
||||
If you encounter trouble:
|
||||
1) Try running 'build' in a separate Gradle run
|
||||
2) Use gradlew and not gradle
|
||||
3) If you still need help, ask on Discord! https://discord.gg/enginehub
|
||||
|
||||
Output files will be in [subproject]/build/libs
|
||||
*******************************************
|
||||
""")
|
||||
|
||||
applyRootArtifactoryConfig()
|
||||
|
||||
if (!project.hasProperty("gitCommitHash")) {
|
||||
apply(plugin = "org.ajoberstar.grgit")
|
||||
ext["gitCommitHash"] = try {
|
||||
(ext["grgit"] as Grgit?)?.head()?.abbreviatedId
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Error getting commit hash", e)
|
||||
|
||||
"no.git.id"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
kotlin("jvm") version embeddedKotlinVersion
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
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")
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention
|
||||
import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask
|
||||
|
||||
private const val ARTIFACTORY_CONTEXT_URL = "artifactory_contextUrl"
|
||||
private const val ARTIFACTORY_USER = "artifactory_user"
|
||||
private const val ARTIFACTORY_PASSWORD = "artifactory_password"
|
||||
|
||||
fun Project.applyRootArtifactoryConfig() {
|
||||
if (!project.hasProperty(ARTIFACTORY_CONTEXT_URL)) ext[ARTIFACTORY_CONTEXT_URL] = "http://localhost"
|
||||
if (!project.hasProperty(ARTIFACTORY_USER)) ext[ARTIFACTORY_USER] = "guest"
|
||||
if (!project.hasProperty(ARTIFACTORY_PASSWORD)) ext[ARTIFACTORY_PASSWORD] = ""
|
||||
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
configure<ArtifactoryPluginConvention> {
|
||||
setContextUrl("${project.property(ARTIFACTORY_CONTEXT_URL)}")
|
||||
clientConfig.publisher.run {
|
||||
repoKey = when {
|
||||
"${project.version}".contains("SNAPSHOT") -> "libs-snapshot-local"
|
||||
else -> "libs-release-local"
|
||||
}
|
||||
username = "${project.property(ARTIFACTORY_USER)}"
|
||||
password = "${project.property(ARTIFACTORY_PASSWORD)}"
|
||||
isMaven = true
|
||||
isIvy = false
|
||||
}
|
||||
}
|
||||
tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
isSkip = true
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.applyCommonArtifactoryConfig() {
|
||||
tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
publishConfigs("archives")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.repositories
|
||||
|
||||
fun Project.applyCommonConfiguration() {
|
||||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("https://maven.enginehub.org/repo/") }
|
||||
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") }
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
cacheChangingModulesFor(5, "MINUTES")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.tasks.SourceSetContainer
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.kotlin.dsl.the
|
||||
|
||||
val Project.ext: ExtraPropertiesExtension
|
||||
get() = extensions.getByType()
|
||||
|
||||
val Project.sourceSets: SourceSetContainer
|
||||
get() = the<JavaPluginConvention>().sourceSets
|
||||
@@ -0,0 +1,96 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.Project
|
||||
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.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getPlugin
|
||||
import org.gradle.kotlin.dsl.invoke
|
||||
import org.gradle.kotlin.dsl.register
|
||||
|
||||
fun Project.applyLibrariesConfiguration() {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java-base")
|
||||
apply(plugin = "maven")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
|
||||
configurations {
|
||||
create("shade")
|
||||
getByName("archives").extendsFrom(getByName("default"))
|
||||
}
|
||||
|
||||
group = "${rootProject.group}.worldguard-libs"
|
||||
|
||||
tasks.register<ShadowJar>("jar") {
|
||||
configurations = listOf(project.configurations["shade"])
|
||||
archiveClassifier.set("")
|
||||
|
||||
dependencies {
|
||||
exclude(dependency("com.google.code.findbugs:jsr305:1.3.9"))
|
||||
}
|
||||
|
||||
relocate("com.sk89q.squirrelid", "com.sk89q.worldguard.util.profile")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
files(configurations.detachedConfiguration(*deps.toTypedArray())
|
||||
.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")
|
||||
}
|
||||
path = path.replaceFirst(filePattern, "$1com/sk89q/worldguard/util/profile$2")
|
||||
}
|
||||
archiveClassifier.set("sources")
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("jar", "sourcesJar")
|
||||
}
|
||||
|
||||
artifacts {
|
||||
val jar = tasks.named("jar")
|
||||
add("default", jar) {
|
||||
builtBy(jar)
|
||||
}
|
||||
val sourcesJar = tasks.named("sourcesJar")
|
||||
add("archives", sourcesJar) {
|
||||
builtBy(sourcesJar)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<Upload>("install") {
|
||||
configuration = configurations["archives"]
|
||||
(repositories as HasConvention).convention.getPlugin<MavenRepositoryHandlerConvention>().mavenInstaller {
|
||||
pom.version = project.version.toString()
|
||||
pom.artifactId = project.name
|
||||
}
|
||||
}
|
||||
|
||||
applyCommonArtifactoryConfig()
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
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.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() {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "eclipse")
|
||||
apply(plugin = "idea")
|
||||
apply(plugin = "maven")
|
||||
apply(plugin = "checkstyle")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
apply(plugin = "net.minecrell.licenser")
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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() {
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("dist")
|
||||
dependencies {
|
||||
include(project(":worldguard-libs:core"))
|
||||
//include(project(":worldguard-libs:${project.name.replace("worldguard-", "")}"))
|
||||
include(project(":worldguard-core"))
|
||||
|
||||
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("GradleStart**")
|
||||
exclude(".cache")
|
||||
exclude("LICENSE*")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
object Versions {
|
||||
// const val PISTON = "0.4.3"
|
||||
// const val AUTO_VALUE = "1.6.5"
|
||||
const val WORLDEDIT = "7.2.0-SNAPSHOT"
|
||||
const val JUNIT = "4.11"
|
||||
const val SQUIRRELID = "0.2.0"
|
||||
const val GUAVA = "21.0"
|
||||
}
|
||||
@@ -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 -->
|
||||
@@ -58,10 +60,4 @@
|
||||
<!-- <module name="TypeName"/> Unlikely that we would miss this in a PR -->
|
||||
</module>
|
||||
|
||||
<!-- Require the header, something that many people forget and we hate to fix -->
|
||||
<!-- You should configure the header in your IDE -->
|
||||
<module name="Header">
|
||||
<property name="headerFile" value="${basedir}/config/checkstyle/header.txt"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
</module>
|
||||
</module>
|
||||
@@ -1,18 +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/>.
|
||||
*/
|
||||
@@ -16,24 +16,21 @@
|
||||
<allow pkg="org.khelekore"/>
|
||||
<allow pkg="org.flywaydb"/>
|
||||
<allow pkg="org.yaml"/>
|
||||
<allow pkg="org.json"/>
|
||||
<allow pkg="org.enginehub.piston"/>
|
||||
|
||||
<subpackage name="util.profile.resolver">
|
||||
<allow pkg="org.bukkit"/>
|
||||
<allow pkg="io.papermc.lib"/>
|
||||
<allow pkg="com.destroystokyo.paper"/>
|
||||
</subpackage>
|
||||
|
||||
<subpackage name="bukkit">
|
||||
<allow pkg="org.bukkit"/>
|
||||
<allow pkg="org.bstats.bukkit"/>
|
||||
<allow pkg="io.papermc.lib"/>
|
||||
<allow pkg="com.destroystokyo.paper"/>
|
||||
</subpackage>
|
||||
|
||||
<subpackage name="sponge">
|
||||
<allow pkg="org.spongepowered"/>
|
||||
<allow pkg="org.bstats.sponge"/>
|
||||
<allow pkg="com.flowpowered"/>
|
||||
</subpackage>
|
||||
|
||||
<subpackage name="forge">
|
||||
<allow pkg="net.minecraft"/>
|
||||
<allow pkg="net.minecraftforge"/>
|
||||
</subpackage>
|
||||
</subpackage>
|
||||
|
||||
</import-control>
|
||||
@@ -0,0 +1,2 @@
|
||||
group=com.sk89q.worldguard
|
||||
version=7.0.4
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,5 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or 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
|
||||
@@ -28,7 +44,7 @@ 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"'
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
Vendored
+17
-1
@@ -1,3 +1,19 @@
|
||||
@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
|
||||
@@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@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
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
rootProject.name = 'worldguard'
|
||||
|
||||
include 'worldguard-core', 'worldguard-bukkit'
|
||||
@@ -0,0 +1,7 @@
|
||||
rootProject.name = "worldguard"
|
||||
|
||||
include("worldguard-libs")
|
||||
include("worldguard-libs:core")
|
||||
include("worldguard-core")
|
||||
//include("worldguard-libs:bukkit")
|
||||
include("worldguard-bukkit")
|
||||
@@ -1,55 +0,0 @@
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'idea'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'bstats repo'
|
||||
url = 'https://repo.codemc.org/repository/maven-public'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':worldguard-core', configuration: 'shadow')
|
||||
api 'org.bukkit:bukkit:1.13-R0.1-SNAPSHOT'
|
||||
api ('com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT') {
|
||||
exclude group: 'io.papermc', module: 'paperlib'
|
||||
}
|
||||
implementation ('com.sk89q:commandbook:2.3') {
|
||||
exclude group: 'com.sk89q', module: 'worldedit'
|
||||
exclude group: 'com.zachsthings.libcomponents'
|
||||
exclude group: 'org.bukkit'
|
||||
exclude group: 'net.sf.opencsv'
|
||||
}
|
||||
implementation 'org.bstats:bstats-bukkit:1.4'
|
||||
}
|
||||
|
||||
processResources {
|
||||
from (sourceSets.main.resources.srcDirs) {
|
||||
expand project.properties
|
||||
include 'plugin.yml'
|
||||
}
|
||||
|
||||
from (sourceSets.main.resources.srcDirs) {
|
||||
exclude 'plugin.yml'
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes("Implementation-Version": version)
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency(':worldguard-core'))
|
||||
relocate ("org.bstats", "com.sk89q.worldguard.bukkit.bstats") {
|
||||
include(dependency("org.bstats:bstats-bukkit:1.4"))
|
||||
}
|
||||
}
|
||||
|
||||
relocate('org.flywaydb', 'com.sk89q.worldguard.internal.flywaydb')
|
||||
|
||||
}
|
||||
|
||||
build.dependsOn(shadowJar)
|
||||
@@ -0,0 +1,75 @@
|
||||
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")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
applyShadowConfiguration()
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "paper"
|
||||
url = uri("https://papermc.io/repo/repository/maven-public/")
|
||||
}
|
||||
maven {
|
||||
name = "bstats"
|
||||
url = uri("https://repo.codemc.org/repository/maven-public")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"compile"(project(":worldguard-core"))
|
||||
//"compile"(project(":worldguard-libs:bukkit"))
|
||||
"api"("com.destroystokyo.paper:paper-api:1.16.2-R0.1-SNAPSHOT")
|
||||
"implementation"("io.papermc:paperlib:1.0.4")
|
||||
"api"("com.sk89q.worldedit:worldedit-bukkit:${Versions.WORLDEDIT}") { isTransitive = false }
|
||||
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
|
||||
"implementation"("com.sk89q:commandbook:2.3") { isTransitive = false }
|
||||
"implementation"("org.bstats:bstats-bukkit:1.7")
|
||||
}
|
||||
|
||||
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.spigotmc")
|
||||
setProperty("artifactId", "spigot-api")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<Copy>("processResources") {
|
||||
filesMatching("plugin.yml") {
|
||||
expand("internalVersion" to project.ext["internalVersion"])
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<Jar>("jar") {
|
||||
manifest {
|
||||
attributes("Implementation-Version" to project.version)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
dependencies {
|
||||
relocate("org.bstats", "com.sk89q.worldguard.bukkit.bstats") {
|
||||
include(dependency("org.bstats:bstats-bukkit:1.7"))
|
||||
}
|
||||
relocate ("io.papermc.lib", "com.sk89q.worldguard.bukkit.paperlib") {
|
||||
include(dependency("io.papermc:paperlib:1.0.4"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("shadowJar")
|
||||
}
|
||||
+13
@@ -26,6 +26,7 @@ import com.sk89q.worldguard.config.YamlConfigurationManager;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
@@ -35,6 +36,7 @@ public class BukkitConfigurationManager extends YamlConfigurationManager {
|
||||
@Unreported private ConcurrentMap<String, BukkitWorldConfiguration> worlds = new ConcurrentHashMap<>();
|
||||
|
||||
private boolean hasCommandBookGodMode;
|
||||
boolean extraStats;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
@@ -46,6 +48,16 @@ public class BukkitConfigurationManager extends YamlConfigurationManager {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public Collection<BukkitWorldConfiguration> getWorldConfigs() {
|
||||
return worlds.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
this.extraStats = getConfig().getBoolean("custom-metrics-charts", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDataFolder() {
|
||||
return plugin.getDataFolder();
|
||||
@@ -68,6 +80,7 @@ public class BukkitConfigurationManager extends YamlConfigurationManager {
|
||||
for (World world : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
|
||||
get(world);
|
||||
}
|
||||
getConfig().save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,9 @@ 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;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -120,7 +123,8 @@ public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implem
|
||||
|
||||
@Override
|
||||
public WeatherType getPlayerWeather() {
|
||||
return null;
|
||||
org.bukkit.WeatherType playerWeather = getPlayer().getPlayerWeather();
|
||||
return playerWeather == null ? null : playerWeather == org.bukkit.WeatherType.CLEAR ? WeatherTypes.CLEAR : WeatherTypes.RAIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +174,32 @@ 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
|
||||
public void resetFallDistance() {
|
||||
getPlayer().setFallDistance(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Location location, String successMessage, String failMessage) {
|
||||
PaperLib.teleportAsync(getPlayer(), BukkitAdapter.adapt(location))
|
||||
.thenApply(success -> {
|
||||
if (success) {
|
||||
// The success message can be cleared via flag
|
||||
if (!successMessage.isEmpty()) {
|
||||
MessagingUtil.sendStringToChat(this, successMessage);
|
||||
}
|
||||
} else {
|
||||
printError(failMessage);
|
||||
}
|
||||
return success;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -97,6 +97,10 @@ public class BukkitRegionContainer extends RegionContainer {
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, cache::invalidateAll, CACHE_INVALIDATION_INTERVAL, CACHE_INVALIDATION_INTERVAL);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
container.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected RegionManager load(World world) {
|
||||
|
||||
+24
-4
@@ -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;
|
||||
@@ -70,6 +70,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
||||
public Set<PotionEffectType> blockPotions;
|
||||
public TargetMatcherSet allowAllInteract;
|
||||
public TargetMatcherSet blockUseAtFeet;
|
||||
public boolean usePaperEntityOrigin;
|
||||
/* Configuration data end */
|
||||
|
||||
/**
|
||||
@@ -104,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;
|
||||
}
|
||||
|
||||
@@ -127,7 +135,7 @@ 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;
|
||||
}
|
||||
@@ -143,12 +151,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);
|
||||
|
||||
useMaxPriorityAssociation = getBoolean("protection.use-max-priority-association", false);
|
||||
|
||||
blockPotions = new HashSet<>();
|
||||
for (String potionName : getStringList("gameplay.block-potions", null)) {
|
||||
PotionEffectType effect = PotionEffectType.getByName(potionName);
|
||||
@@ -179,7 +192,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
||||
blockTNTBlockDamage = getBoolean("ignition.block-tnt-block-damage", false);
|
||||
blockLighter = getBoolean("ignition.block-lighter", false);
|
||||
|
||||
preventLavaFire = getBoolean("fire.disable-lava-fire-spread", true);
|
||||
preventLavaFire = getBoolean("fire.disable-lava-fire-spread", false);
|
||||
disableFireSpread = getBoolean("fire.disable-all-fire-spread", false);
|
||||
disableFireSpreadBlocks = new HashSet<>(convertLegacyBlocks(getStringList("fire.disable-fire-spread-blocks", null)));
|
||||
allowedLavaSpreadOver = new HashSet<>(convertLegacyBlocks(getStringList("fire.lava-spread-blocks", null)));
|
||||
@@ -216,6 +229,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
||||
teleportOnSuffocation = getBoolean("player-damage.teleport-on-suffocation", false);
|
||||
disableVoidDamage = getBoolean("player-damage.disable-void-damage", false);
|
||||
teleportOnVoid = getBoolean("player-damage.teleport-on-void-falling", false);
|
||||
safeFallOnVoid = getBoolean("player-damage.reset-fall-on-void-teleport", false);
|
||||
disableExplosionDamage = getBoolean("player-damage.disable-explosion-damage", false);
|
||||
disableMobDamage = getBoolean("player-damage.disable-mob-damage", false);
|
||||
disableDeathMessages = getBoolean("player-damage.disable-death-messages", false);
|
||||
@@ -226,11 +240,15 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
||||
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);
|
||||
|
||||
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);
|
||||
disableWeather = getBoolean("weather.disable-weather", false);
|
||||
disablePigZap = getBoolean("weather.disable-pig-zombification", false);
|
||||
disableVillagerZap = getBoolean("weather.disable-villager-witchification", false);
|
||||
disableCreeperPower = getBoolean("weather.disable-powered-creepers", false);
|
||||
alwaysRaining = getBoolean("weather.always-raining", false);
|
||||
alwaysThundering = getBoolean("weather.always-thundering", false);
|
||||
@@ -246,12 +264,14 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
|
||||
disableVineGrowth = getBoolean("dynamics.disable-vine-growth", false);
|
||||
disableCropGrowth = getBoolean("dynamics.disable-crop-growth", false);
|
||||
disableSoilDehydration = getBoolean("dynamics.disable-soil-dehydration", false);
|
||||
disableCoralBlockFade = getBoolean("dynamics.disable-coral-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);
|
||||
|
||||
+49
-1
@@ -19,12 +19,19 @@
|
||||
|
||||
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.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.util.profile.resolver.PaperProfileService;
|
||||
import com.sk89q.worldguard.bukkit.protection.events.flags.FlagContextCreateEvent;
|
||||
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
|
||||
import com.sk89q.worldguard.bukkit.util.report.PerformanceReport;
|
||||
@@ -39,12 +46,21 @@ import com.sk89q.worldguard.internal.platform.WorldGuardPlatform;
|
||||
import com.sk89q.worldguard.protection.flags.FlagContext;
|
||||
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.BukkitPlayerService;
|
||||
import com.sk89q.worldguard.util.profile.resolver.CacheForwardingService;
|
||||
import com.sk89q.worldguard.util.profile.resolver.CombinedProfileService;
|
||||
import com.sk89q.worldguard.util.profile.resolver.HttpRepositoryService;
|
||||
import com.sk89q.worldguard.util.profile.resolver.ProfileService;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
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;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -130,7 +146,7 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
||||
@Override
|
||||
public void unload() {
|
||||
configuration.unload();
|
||||
regionContainer.unload();
|
||||
regionContainer.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,4 +244,36 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
|
||||
report.add(new WorldReport());
|
||||
report.add(new PerformanceReport());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileService createProfileService(ProfileCache profileCache) {
|
||||
List<ProfileService> services = new ArrayList<>();
|
||||
if (PaperLib.isPaper()) {
|
||||
// Paper has a shared cache
|
||||
services.add(PaperProfileService.getInstance());
|
||||
} else {
|
||||
services.add(BukkitPlayerService.getInstance());
|
||||
}
|
||||
services.add(HttpRepositoryService.forMinecraft());
|
||||
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().getY()),
|
||||
spawnLoc.add(radius, 0, radius).withY(world.getMaxY()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -35,9 +35,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.commands.GeneralCommands;
|
||||
import com.sk89q.worldguard.commands.ProtectionCommands;
|
||||
import com.sk89q.worldguard.commands.ToggleCommands;
|
||||
import com.sk89q.worldguard.blacklist.Blacklist;
|
||||
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlacklistListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener;
|
||||
@@ -63,8 +61,16 @@ import com.sk89q.worldguard.bukkit.listener.WorldRulesListener;
|
||||
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
|
||||
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.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
|
||||
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;
|
||||
@@ -84,9 +90,10 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
/**
|
||||
* The main class for WorldGuard as a Bukkit plugin.
|
||||
@@ -205,7 +212,51 @@ public class WorldGuardPlugin extends JavaPlugin {
|
||||
((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).setInitialized(true);
|
||||
|
||||
// Enable metrics
|
||||
new Metrics(this);
|
||||
final Metrics metrics = new Metrics(this, 3283); // bStats plugin id
|
||||
if (metrics.isEnabled() && platform.getGlobalStateManager().extraStats) {
|
||||
setupCustomCharts(metrics);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupCustomCharts(Metrics metrics) {
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("region_count", () ->
|
||||
platform.getRegionContainer().getLoaded().stream().mapToInt(RegionManager::size).sum()));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("region_driver", () -> {
|
||||
RegionDriver driver = platform.getGlobalStateManager().selectedRegionStoreDriver;
|
||||
return driver instanceof DirectoryYamlDriver ? "yaml" : driver instanceof SQLDriver ? "sql" : "unknown";
|
||||
}));
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("blacklist", () -> {
|
||||
int empty = 0;
|
||||
Map<String, Integer> blacklistMap = new HashMap<>();
|
||||
Map<String, Integer> whitelistMap = new HashMap<>();
|
||||
for (BukkitWorldConfiguration worldConfig : platform.getGlobalStateManager().getWorldConfigs()) {
|
||||
Blacklist blacklist = worldConfig.getBlacklist();
|
||||
if (blacklist != null && !blacklist.isEmpty()) {
|
||||
Map<String, Integer> target = blacklist.isWhitelist() ? whitelistMap : blacklistMap;
|
||||
int floor = ((blacklist.getItemCount() - 1) / 10) * 10;
|
||||
String range = floor >= 100 ? "101+" : (floor + 1) + " - " + (floor + 10);
|
||||
target.merge(range, 1, Integer::sum);
|
||||
} else {
|
||||
empty++;
|
||||
}
|
||||
}
|
||||
Map<String, Map<String, Integer>> blacklistCounts = new HashMap<>();
|
||||
Map<String, Integer> emptyMap = new HashMap<>();
|
||||
emptyMap.put("empty", empty);
|
||||
blacklistCounts.put("empty", emptyMap);
|
||||
blacklistCounts.put("blacklist", blacklistMap);
|
||||
blacklistCounts.put("whitelist", whitelistMap);
|
||||
return blacklistCounts;
|
||||
}));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("chest_protection", () ->
|
||||
"" + platform.getGlobalStateManager().getWorldConfigs().stream().anyMatch(cfg -> cfg.signChestProtection)));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("build_permissions", () ->
|
||||
"" + platform.getGlobalStateManager().getWorldConfigs().stream().anyMatch(cfg -> cfg.buildPermissions)));
|
||||
|
||||
metrics.addCustomChart(new Metrics.SimplePie("custom_flags", () ->
|
||||
"" + (WorldGuard.getInstance().getFlagRegistry().size() > Flags.INBUILT_FLAGS.size())));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("custom_handlers", () ->
|
||||
"" + (WorldGuard.getInstance().getPlatform().getSessionManager().customHandlersRegistered())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -435,44 +486,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,15 +22,29 @@ package com.sk89q.worldguard.bukkit.cause;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldguard.bukkit.internal.WGMetadata;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.*;
|
||||
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.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;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@@ -224,6 +238,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.
|
||||
*/
|
||||
@@ -248,18 +271,30 @@ public final class Cause {
|
||||
if (o instanceof TNTPrimed) {
|
||||
addAll(((TNTPrimed) o).getSource());
|
||||
} else if (o instanceof Projectile) {
|
||||
addAll(((Projectile) o).getShooter());
|
||||
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);
|
||||
if (spawningEntity != null) {
|
||||
addAll(spawningEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (o instanceof Vehicle) {
|
||||
addAll(((Vehicle) o).getPassengers());
|
||||
((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());
|
||||
} else if (o instanceof Creature && ((Creature) o).getTarget() != null) {
|
||||
indirect = true;
|
||||
addAll(((Creature) o).getTarget());
|
||||
} else if (o instanceof BlockProjectileSource) {
|
||||
addAll(((BlockProjectileSource) o).getBlock());
|
||||
}
|
||||
|
||||
// Add manually tracked parent causes
|
||||
|
||||
+32
-7
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.event.block;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.cause.Cause;
|
||||
@@ -28,12 +29,15 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -44,7 +48,8 @@ import javax.annotation.Nullable;
|
||||
abstract class AbstractBlockEvent extends DelegateEvent implements BulkEvent {
|
||||
|
||||
private final World world;
|
||||
private final List<Block> blocks;
|
||||
private List<Block> blocks;
|
||||
private final List<BlockState> blockStates;
|
||||
private final Material effectiveMaterial;
|
||||
|
||||
protected AbstractBlockEvent(@Nullable Event originalEvent, Cause cause, World world, List<Block> blocks, Material effectiveMaterial) {
|
||||
@@ -55,6 +60,18 @@ abstract class AbstractBlockEvent extends DelegateEvent implements BulkEvent {
|
||||
this.world = world;
|
||||
this.blocks = blocks;
|
||||
this.effectiveMaterial = effectiveMaterial;
|
||||
this.blockStates = null;
|
||||
}
|
||||
|
||||
protected AbstractBlockEvent(@Nullable Event originalEvent, Cause cause, World world, List<BlockState> blocks) {
|
||||
super(originalEvent, cause);
|
||||
checkNotNull(world);
|
||||
checkNotNull(blocks);
|
||||
checkArgument(!blocks.isEmpty());
|
||||
this.world = world;
|
||||
this.blockStates = blocks;
|
||||
this.blocks = null;
|
||||
this.effectiveMaterial = blocks.get(0).getType();
|
||||
}
|
||||
|
||||
protected AbstractBlockEvent(@Nullable Event originalEvent, Cause cause, Block block) {
|
||||
@@ -86,6 +103,9 @@ abstract class AbstractBlockEvent extends DelegateEvent implements BulkEvent {
|
||||
* @return a list of affected block
|
||||
*/
|
||||
public List<Block> getBlocks() {
|
||||
if (blocks == null) { // be lazy here because we often don't call getBlocks internally, just filter
|
||||
blocks = blockStates.stream().map(BlockState::getBlock).collect(Collectors.toList());
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@@ -99,15 +119,21 @@ abstract class AbstractBlockEvent extends DelegateEvent implements BulkEvent {
|
||||
* @return true if one or more blocks were filtered out
|
||||
*/
|
||||
public boolean filter(Predicate<Location> predicate, boolean cancelEventOnFalse) {
|
||||
boolean hasRemoval = false;
|
||||
return blocks == null
|
||||
? filterInternal(blockStates, BlockState::getLocation, predicate, cancelEventOnFalse)
|
||||
: filterInternal(blocks, Block::getLocation, predicate, cancelEventOnFalse);
|
||||
}
|
||||
|
||||
Iterator<Block> it = blocks.iterator();
|
||||
private <B> boolean filterInternal(List<B> blockList, Function<B, Location> locFunc,
|
||||
Predicate<Location> predicate, boolean cancelEventOnFalse) {
|
||||
boolean hasRemoval = false;
|
||||
Iterator<B> it = blockList.iterator();
|
||||
while (it.hasNext()) {
|
||||
if (!predicate.test(it.next().getLocation())) {
|
||||
if (!predicate.test(locFunc.apply(it.next()))) {
|
||||
hasRemoval = true;
|
||||
|
||||
if (cancelEventOnFalse) {
|
||||
getBlocks().clear();
|
||||
blockList.clear();
|
||||
setCancelled(true);
|
||||
break;
|
||||
} else {
|
||||
@@ -115,7 +141,6 @@ abstract class AbstractBlockEvent extends DelegateEvent implements BulkEvent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasRemoval;
|
||||
}
|
||||
|
||||
@@ -147,7 +172,7 @@ abstract class AbstractBlockEvent extends DelegateEvent implements BulkEvent {
|
||||
|
||||
@Override
|
||||
public Result getResult() {
|
||||
if (blocks.isEmpty()) {
|
||||
if (blocks == null ? blockStates.isEmpty() : blocks.isEmpty()) {
|
||||
return Result.DENY;
|
||||
}
|
||||
return super.getResult();
|
||||
|
||||
+5
@@ -24,6 +24,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@@ -40,6 +41,10 @@ public class PlaceBlockEvent extends AbstractBlockEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public PlaceBlockEvent(@Nullable Event originalEvent, Cause cause, World world, List<BlockState> blocks) {
|
||||
super(originalEvent, cause, world, blocks);
|
||||
}
|
||||
|
||||
public PlaceBlockEvent(@Nullable Event originalEvent, Cause cause, World world, List<Block> blocks, Material effectiveMaterial) {
|
||||
super(originalEvent, cause, world, blocks, effectiveMaterial);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
+52
-4
@@ -21,12 +21,26 @@ 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.BukkitWorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.cause.Cause;
|
||||
import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.domains.Association;
|
||||
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;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
/**
|
||||
@@ -67,7 +81,7 @@ class AbstractListener implements Listener {
|
||||
*
|
||||
* @return the configuration
|
||||
*/
|
||||
protected ConfigurationManager getConfig() {
|
||||
protected static ConfigurationManager getConfig() {
|
||||
return WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
}
|
||||
|
||||
@@ -77,7 +91,7 @@ class AbstractListener implements Listener {
|
||||
* @param world The world to get the configuration for.
|
||||
* @return The configuration for {@code world}
|
||||
*/
|
||||
protected WorldConfiguration getWorldConfig(World world) {
|
||||
protected static WorldConfiguration getWorldConfig(World world) {
|
||||
return getConfig().get(world);
|
||||
}
|
||||
|
||||
@@ -87,7 +101,7 @@ class AbstractListener implements Listener {
|
||||
* @param player The player to get the wold from
|
||||
* @return The {@link WorldConfiguration} for the player's world
|
||||
*/
|
||||
protected WorldConfiguration getWorldConfig(LocalPlayer player) {
|
||||
protected static WorldConfiguration getWorldConfig(LocalPlayer player) {
|
||||
return getWorldConfig((World) player.getExtent());
|
||||
}
|
||||
|
||||
@@ -97,8 +111,42 @@ class AbstractListener implements Listener {
|
||||
* @param world the world
|
||||
* @return true if region support is enabled
|
||||
*/
|
||||
protected boolean isRegionSupportEnabled(World world) {
|
||||
protected static boolean isRegionSupportEnabled(World world) {
|
||||
return getWorldConfig(world).useRegions;
|
||||
}
|
||||
|
||||
protected RegionAssociable createRegionAssociable(Cause cause) {
|
||||
Object rootCause = cause.getRootCause();
|
||||
|
||||
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) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
final Entity entity = (Entity) rootCause;
|
||||
BukkitWorldConfiguration config =
|
||||
(BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(entity.getWorld()));
|
||||
Location loc;
|
||||
if (PaperLib.isPaper() && config.usePaperEntityOrigin) {
|
||||
loc = entity.getOrigin();
|
||||
if (loc == null) {
|
||||
loc = entity.getLocation();
|
||||
}
|
||||
} else {
|
||||
loc = entity.getLocation();
|
||||
}
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(loc),
|
||||
config.useMaxPriorityAssociation);
|
||||
} else if (rootCause instanceof Block) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
Location loc = ((Block) rootCause).getLocation();
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(loc),
|
||||
getWorldConfig(BukkitAdapter.adapt(loc.getWorld())).useMaxPriorityAssociation);
|
||||
} else {
|
||||
return Associables.constant(Association.NON_MEMBER);
|
||||
}
|
||||
}
|
||||
}
|
||||
+92
-14
@@ -19,8 +19,6 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
@@ -31,6 +29,7 @@ import com.sk89q.worldguard.blacklist.event.BlockPlaceBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.event.ItemAcquireBlacklistEvent;
|
||||
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.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
|
||||
@@ -47,16 +46,21 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.BlockDispenseArmorEvent;
|
||||
import org.bukkit.event.block.BlockDispenseEvent;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCreativeEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
|
||||
|
||||
/**
|
||||
* Handle events that need to be processed by the blacklist.
|
||||
*/
|
||||
@@ -89,10 +93,12 @@ public class BlacklistListener extends AbstractListener {
|
||||
|
||||
event.filter(target -> {
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new BlockBreakBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock(), event.getEffectiveMaterial())), false, false)) {
|
||||
new BlockBreakBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target),
|
||||
createTarget(target.getBlock(), event.getEffectiveMaterial())), false, false)) {
|
||||
return false;
|
||||
} else if (!wcfg.getBlacklist().check(
|
||||
new ItemDestroyWithBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target), createTarget(player.getItemInHand())), false, false)) {
|
||||
new ItemDestroyWithBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target),
|
||||
createTarget(player.getInventory().getItemInMainHand())), false, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -122,9 +128,6 @@ public class BlacklistListener extends AbstractListener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onUseBlock(final UseBlockEvent event) {
|
||||
if (event.getResult() == Event.Result.ALLOW) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getCause().getFirstPlayer();
|
||||
|
||||
if (player == null) {
|
||||
@@ -161,7 +164,8 @@ public class BlacklistListener extends AbstractListener {
|
||||
|
||||
Material material = Materials.getRelatedMaterial(event.getEffectiveType());
|
||||
if (material != null) {
|
||||
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(event.getTarget()), createTarget(material)), false, false)) {
|
||||
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(
|
||||
localPlayer, BukkitAdapter.asBlockVector(event.getTarget()), createTarget(material)), false, false)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -197,7 +201,8 @@ public class BlacklistListener extends AbstractListener {
|
||||
Material material = Materials.getRelatedMaterial(target.getType());
|
||||
if (material != null) {
|
||||
// Not really a block but we only have one on-break blacklist event
|
||||
if (!wcfg.getBlacklist().check(new BlockBreakBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(event.getTarget()), createTarget(material)), false, false)) {
|
||||
if (!wcfg.getBlacklist().check(new BlockBreakBlacklistEvent(
|
||||
localPlayer, BukkitAdapter.asBlockVector(event.getTarget()), createTarget(material)), false, false)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -220,7 +225,14 @@ public class BlacklistListener extends AbstractListener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(player.getLocation()), createTarget(target)), false, false)) {
|
||||
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(
|
||||
localPlayer, BukkitAdapter.asBlockVector(player.getLocation()), createTarget(target)), false, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Materials.isArmor(target.getType()) && !wcfg.getBlacklist().check(new ItemEquipBlacklistEvent(
|
||||
localPlayer, BukkitAdapter.asBlockVector(player.getLocation()), createTarget(target)), false, false)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -257,10 +269,11 @@ public class BlacklistListener extends AbstractListener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
HumanEntity entity = event.getWhoClicked();
|
||||
if (!(entity instanceof Player)) return;
|
||||
Inventory inventory = event.getInventory();
|
||||
ItemStack item = event.getCurrentItem();
|
||||
|
||||
if (item != null && inventory != null && inventory.getHolder() != null && entity instanceof Player) {
|
||||
if (item != null && inventory.getHolder() != null) {
|
||||
Player player = (Player) entity;
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
@@ -274,15 +287,67 @@ public class BlacklistListener extends AbstractListener {
|
||||
event.setCurrentItem(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ItemStack equipped = checkEquipped(event);
|
||||
if (equipped != null) {
|
||||
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(new ItemEquipBlacklistEvent(localPlayer,
|
||||
BukkitAdapter.asBlockVector(player.getLocation()), createTarget(equipped)), false, false)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
HumanEntity entity = event.getWhoClicked();
|
||||
if (!(entity instanceof Player)) return;
|
||||
if (event.getInventory().getType() != InventoryType.PLAYER
|
||||
&& event.getInventory().getType() != InventoryType.CRAFTING) return;
|
||||
if (event.getRawSlots().stream().anyMatch(i -> i >= 5 && i <= 8)) { // dropped on armor slots
|
||||
Player player = (Player) entity;
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
|
||||
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(new ItemEquipBlacklistEvent(localPlayer,
|
||||
BukkitAdapter.asBlockVector(player.getLocation()), createTarget(event.getOldCursor())), false, false)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack checkEquipped(InventoryClickEvent event) {
|
||||
final Inventory clickedInventory = event.getClickedInventory();
|
||||
if (event.getSlotType() == InventoryType.SlotType.ARMOR) {
|
||||
switch (event.getAction()) {
|
||||
case PLACE_ONE:
|
||||
case PLACE_SOME:
|
||||
case PLACE_ALL:
|
||||
case SWAP_WITH_CURSOR:
|
||||
final ItemStack cursor = event.getCursor();
|
||||
if (cursor != null) {
|
||||
return cursor;
|
||||
}
|
||||
case HOTBAR_SWAP:
|
||||
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.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
|
||||
return event.getCurrentItem();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryCreative(InventoryCreativeEvent event) {
|
||||
HumanEntity entity = event.getWhoClicked();
|
||||
ItemStack item = event.getCursor();
|
||||
|
||||
if (item != null && entity instanceof Player) {
|
||||
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()));
|
||||
@@ -291,7 +356,6 @@ public class BlacklistListener extends AbstractListener {
|
||||
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
|
||||
new ItemAcquireBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(entity.getLocation()), createTarget(item)), false, false)) {
|
||||
event.setCancelled(true);
|
||||
event.setCursor(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,4 +378,18 @@ public class BlacklistListener extends AbstractListener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockDispenseArmor(BlockDispenseArmorEvent event) {
|
||||
if (!(event.getTargetEntity() instanceof Player)) return;
|
||||
Player player = ((Player) event.getTargetEntity());
|
||||
ItemStack stack = event.getItem();
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(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)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-28
@@ -22,21 +22,20 @@ 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.config.ConfigurationManager;
|
||||
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;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.SpectralArrow;
|
||||
import org.bukkit.entity.TippedArrow;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
@@ -66,8 +65,8 @@ public class BlockedPotionsListener extends AbstractListener {
|
||||
if (wcfg.blockPotions.contains(PotionEffectType.GLOWING)) {
|
||||
blockedEffect = PotionEffectType.GLOWING;
|
||||
}
|
||||
} else if (originalEvent.getDamager() instanceof TippedArrow) {
|
||||
TippedArrow tippedArrow = (TippedArrow) originalEvent.getDamager();
|
||||
} else if (originalEvent.getDamager() instanceof Arrow) {
|
||||
Arrow tippedArrow = (Arrow) originalEvent.getDamager();
|
||||
PotionEffectType baseEffect = tippedArrow.getBasePotionData().getType().getEffectType();
|
||||
if (wcfg.blockPotions.contains(baseEffect)) {
|
||||
blockedEffect = baseEffect;
|
||||
@@ -101,24 +100,12 @@ public class BlockedPotionsListener extends AbstractListener {
|
||||
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
ItemStack item = event.getItemStack();
|
||||
|
||||
// We only care about potions
|
||||
boolean oldPotions = false;
|
||||
try {
|
||||
if (item.getType() != Material.POTION
|
||||
&& item.getType() != Material.SPLASH_POTION
|
||||
&& item.getType() != Material.LINGERING_POTION) {
|
||||
return;
|
||||
}
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
// PotionMeta technically has been around since 1.7, so the code below
|
||||
// *should* work still. we just have different materials now.
|
||||
if (item.getType() != Material.POTION) {
|
||||
return;
|
||||
}
|
||||
oldPotions = true;
|
||||
if (item.getType() != Material.POTION
|
||||
&& item.getType() != Material.SPLASH_POTION
|
||||
&& item.getType() != Material.LINGERING_POTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!wcfg.blockPotions.isEmpty()) {
|
||||
PotionEffectType blockedEffect = null;
|
||||
|
||||
@@ -149,13 +136,8 @@ public class BlockedPotionsListener extends AbstractListener {
|
||||
|
||||
if (player != null) {
|
||||
if (getPlugin().hasPermission(player, "worldguard.override.potions")) {
|
||||
boolean isSplash = false;
|
||||
try {
|
||||
isSplash = (!oldPotions && (item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION));
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
isSplash |= (oldPotions && (Potion.fromItemStack(item).isSplash()));
|
||||
if (isSplash && wcfg.blockPotionsAlways) {
|
||||
if (wcfg.blockPotionsAlways && (item.getType() == Material.SPLASH_POTION
|
||||
|| item.getType() == Material.LINGERING_POTION)) {
|
||||
player.sendMessage(ChatColor.RED + "Sorry, potions with " +
|
||||
blockedEffect.getName() + " can't be thrown, " +
|
||||
"even if you have a permission to bypass it, " +
|
||||
|
||||
+6
-5
@@ -29,6 +29,7 @@ import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
@@ -135,7 +136,7 @@ public class ChestProtectionListener extends AbstractListener {
|
||||
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) getWorldConfig(WorldGuardPlugin.inst().wrapPlayer(player));
|
||||
|
||||
if (wcfg.signChestProtection) {
|
||||
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
|
||||
if ("[Lock]".equalsIgnoreCase(event.getLine(0))) {
|
||||
if (wcfg.isChestProtectedPlacement(BukkitAdapter.adapt(event.getBlock().getLocation()), WorldGuardPlugin.inst().wrapPlayer(player))) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You do not own the adjacent chest.");
|
||||
event.getBlock().breakNaturally();
|
||||
@@ -143,7 +144,7 @@ public class ChestProtectionListener extends AbstractListener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getBlock().getType() != Material.SIGN) {
|
||||
if (!Tag.STANDING_SIGNS.isTagged(event.getBlock().getType())) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "The [Lock] sign must be a sign post, not a wall sign.");
|
||||
|
||||
@@ -152,7 +153,7 @@ public class ChestProtectionListener extends AbstractListener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event.getLine(1).equalsIgnoreCase(player.getName())) {
|
||||
if (!player.getName().equalsIgnoreCase(event.getLine(1))) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "The first owner line must be your name.");
|
||||
|
||||
@@ -164,7 +165,7 @@ public class ChestProtectionListener extends AbstractListener {
|
||||
Material below = event.getBlock().getRelative(0, -1, 0).getType();
|
||||
|
||||
if (below == Material.TNT || below == Material.SAND
|
||||
|| below == Material.GRAVEL || below == Material.SIGN) {
|
||||
|| below == Material.GRAVEL || Tag.STANDING_SIGNS.isTagged(below)) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "That is not a safe block that you're putting this sign on.");
|
||||
|
||||
@@ -178,7 +179,7 @@ public class ChestProtectionListener extends AbstractListener {
|
||||
+ "A chest or double chest above is now protected.");
|
||||
}
|
||||
} else if (!wcfg.disableSignChestProtectionCheck) {
|
||||
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
|
||||
if ("[Lock]".equalsIgnoreCase(event.getLine(0))) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "WorldGuard's sign chest protection is disabled.");
|
||||
|
||||
|
||||
+268
-125
@@ -21,7 +21,6 @@ package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.cause.Cause.create;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
@@ -59,21 +58,27 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.block.Dropper;
|
||||
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;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LingeringPotion;
|
||||
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;
|
||||
@@ -85,12 +90,14 @@ import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockDispenseEvent;
|
||||
import org.bukkit.event.block.BlockExpEvent;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.BlockFertilizeEvent;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
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;
|
||||
@@ -126,20 +133,22 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemConsumeEvent;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerShearEntityEvent;
|
||||
import org.bukkit.event.player.PlayerTakeLecternBookEvent;
|
||||
import org.bukkit.event.player.PlayerUnleashEntityEvent;
|
||||
import org.bukkit.event.vehicle.VehicleDamageEvent;
|
||||
import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EventAbstractionListener extends AbstractListener {
|
||||
|
||||
@@ -150,6 +159,17 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
private final EventDebounce<BlockPistonRetractKey> pistonRetractDebounce = EventDebounce.create(5000);
|
||||
private final EventDebounce<BlockPistonExtendKey> pistonExtendDebounce = EventDebounce.create(5000);
|
||||
|
||||
private static final boolean HAS_SNAPSHOT_INVHOLDER;
|
||||
static {
|
||||
boolean temp;
|
||||
try {
|
||||
Inventory.class.getMethod("getHolder", boolean.class);
|
||||
temp = true;
|
||||
} catch (NoSuchMethodException e) {
|
||||
temp = false;
|
||||
}
|
||||
HAS_SNAPSHOT_INVHOLDER = temp;
|
||||
}
|
||||
/**
|
||||
* Construct the listener.
|
||||
*
|
||||
@@ -174,12 +194,14 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockMultiPlace(BlockMultiPlaceEvent event) {
|
||||
List<Block> blocks = new ArrayList<>();
|
||||
for (BlockState bs : event.getReplacedBlockStates()) {
|
||||
blocks.add(bs.getBlock());
|
||||
List<Block> placed = event.getReplacedBlockStates().stream().map(BlockState::getBlock).collect(Collectors.toList());
|
||||
int origAmt = placed.size();
|
||||
PlaceBlockEvent delegateEvent = new PlaceBlockEvent(event, create(event.getPlayer()), event.getBlock().getWorld(),
|
||||
placed, event.getBlockPlaced().getType());
|
||||
Events.fireToCancel(event, delegateEvent);
|
||||
if (origAmt != placed.size()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getPlayer()),
|
||||
event.getBlock().getWorld(), blocks, event.getBlock().getType()));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
@@ -188,7 +210,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
BlockState previousState = event.getBlockReplacedState();
|
||||
|
||||
// Some blocks, like tall grass and fire, get replaced
|
||||
if (previousState.getType() != Material.AIR) {
|
||||
if (previousState.getType() != Material.AIR && previousState.getType() != event.getBlockReplacedState().getType()) {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(event.getPlayer()), previousState.getLocation(), previousState.getType()));
|
||||
}
|
||||
|
||||
@@ -222,7 +244,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);
|
||||
@@ -240,39 +262,51 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onStructureGrowEvent(StructureGrowEvent event) {
|
||||
int originalCount = event.getBlocks().size();
|
||||
List<Block> blockList = Lists.transform(event.getBlocks(), new BlockStateAsBlockFunction());
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player != null) {
|
||||
Events.fireBulkEventToCancel(event, new PlaceBlockEvent(event, create(player), event.getLocation().getWorld(), blockList, Material.AIR));
|
||||
} else {
|
||||
Events.fireBulkEventToCancel(event, new PlaceBlockEvent(event, create(event.getLocation().getBlock()), event.getLocation().getWorld(), blockList, Material.AIR));
|
||||
}
|
||||
Events.fireBulkEventToCancel(event, new PlaceBlockEvent(event,
|
||||
create(player == null ? event.getLocation().getBlock() : player),
|
||||
event.getLocation().getWorld(), event.getBlocks()));
|
||||
|
||||
if (!event.isCancelled() && event.getBlocks().size() != originalCount) {
|
||||
event.getLocation().getBlock().setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Handle EntityCreatePortalEvent?
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
||||
Block block = event.getBlock();
|
||||
Entity entity = event.getEntity();
|
||||
Material to = event.getTo();
|
||||
|
||||
// Forget about Redstone ore, especially since we handle it in INTERACT
|
||||
if (block.getType() == Material.REDSTONE_ORE && to == Material.REDSTONE_ORE) {
|
||||
return;
|
||||
}
|
||||
Material toType = event.getTo();
|
||||
Material fromType = block.getType();
|
||||
Cause cause = create(entity);
|
||||
|
||||
// Fire two events: one as BREAK and one as PLACE
|
||||
if (event.getTo() != Material.AIR && event.getBlock().getType() != Material.AIR) {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(entity), block));
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(entity), block.getLocation(), to));
|
||||
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.setSilent(true);
|
||||
breakDelagate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
} else if (fromType == Material.REDSTONE_ORE) {
|
||||
breakDelagate.setSilent(true);
|
||||
}
|
||||
boolean denied;
|
||||
if (!(denied = Events.fireToCancel(event, breakDelagate))) {
|
||||
PlaceBlockEvent placeDelegate = new PlaceBlockEvent(event, cause, block.getLocation(), toType);
|
||||
if (trample) {
|
||||
placeDelegate.setSilent(true);
|
||||
placeDelegate.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
} else if (fromType == Material.REDSTONE_ORE) {
|
||||
placeDelegate.setSilent(true);
|
||||
}
|
||||
denied = Events.fireToCancel(event, placeDelegate);
|
||||
}
|
||||
if (denied && entity instanceof Player) {
|
||||
playDenyEffect((Player) entity, block.getLocation());
|
||||
}
|
||||
} else {
|
||||
if (event.getTo() == Material.AIR) {
|
||||
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);
|
||||
@@ -281,21 +315,29 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, create(block), entity));
|
||||
} else {
|
||||
entityBreakBlockDebounce.debounce(
|
||||
event.getBlock(), event.getEntity(), event, new BreakBlockEvent(event, create(entity), event.getBlock()));
|
||||
block, event.getEntity(), event, new BreakBlockEvent(event, cause, block));
|
||||
}
|
||||
} else {
|
||||
boolean wasCancelled = event.isCancelled();
|
||||
Cause cause = create(entity);
|
||||
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getLocation(), to));
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, block.getLocation(), toType));
|
||||
|
||||
if (event.isCancelled() && !wasCancelled && entity instanceof FallingBlock) {
|
||||
FallingBlock fallingBlock = (FallingBlock) entity;
|
||||
ItemStack itemStack = new ItemStack(fallingBlock.getBlockData().getMaterial(), 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();
|
||||
if (entity instanceof FallingBlock) {
|
||||
try {
|
||||
if (event.isCancelled() && !wasCancelled) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,12 +347,10 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (event.getYield() == 0 && event.blockList().isEmpty()) {
|
||||
// avoids ender dragon spam
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -328,6 +368,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();
|
||||
@@ -347,17 +388,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);
|
||||
}
|
||||
@@ -390,23 +438,37 @@ 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) {
|
||||
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;
|
||||
firedEvent.setSilent(true);
|
||||
}
|
||||
if (clicked.getType() == Material.FARMLAND || clicked.getType() == Material.TURTLE_EGG) {
|
||||
silent = true;
|
||||
firedEvent.getRelevantFlags().add(Flags.TRAMPLE_BLOCKS);
|
||||
}
|
||||
firedEvent.setSilent(silent);
|
||||
interactDebounce.debounce(clicked, event.getPlayer(), event, firedEvent);
|
||||
if (event.useInteractedBlock() == Result.DENY) {
|
||||
playDenyEffect(player, clicked.getLocation().add(0, 1, 0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -425,8 +487,8 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
// Only fire events for blocks that are modified when right clicked
|
||||
final boolean hasItemInteraction = item != null && isItemAppliedToBlock(item, clicked)
|
||||
&& event.getAction() == Action.RIGHT_CLICK_BLOCK;
|
||||
modifiesWorld = isBlockModifiedOnClick(clicked, event.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
|| hasItemInteraction;
|
||||
modifiesWorld = hasItemInteraction
|
||||
|| isBlockModifiedOnClick(clicked, event.getAction() == Action.RIGHT_CLICK_BLOCK);
|
||||
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, cause, clicked).setAllowed(!modifiesWorld))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
@@ -443,11 +505,12 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
if (hasItemInteraction) {
|
||||
if (Events.fireAndTestCancel(new PlaceBlockEvent(event, cause, clicked.getLocation(), clicked.getType()))) {
|
||||
event.setUseItemInHand(Result.DENY);
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -495,6 +558,12 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
event.getBlock()).setAllowed(hasInteractBypass(event.getBlock())));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockFertilize(BlockFertilizeEvent event) {
|
||||
Cause cause = create(event.getPlayer(), event.getBlock());
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, event.getBlock().getWorld(), event.getBlocks()));
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockIgnite(BlockIgniteEvent event) {
|
||||
Block block = event.getBlock();
|
||||
@@ -531,7 +600,15 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Block blockAffected = event.getBlockClicked().getRelative(event.getBlockFace());
|
||||
Block blockClicked = event.getBlockClicked();
|
||||
Block blockAffected;
|
||||
|
||||
if (blockClicked.getBlockData() instanceof Waterlogged) {
|
||||
blockAffected = blockClicked;
|
||||
} else {
|
||||
blockAffected = blockClicked.getRelative(event.getBlockFace());
|
||||
}
|
||||
|
||||
boolean allowed = false;
|
||||
|
||||
// Milk buckets can't be emptied as of writing
|
||||
@@ -591,7 +668,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
Material toType = to.getType();
|
||||
|
||||
// Liquids pass this event when flowing to solid blocks
|
||||
if (toType.isSolid() && Materials.isLiquid(fromType)) {
|
||||
if (Materials.isLiquid(fromType) && toType.isSolid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -627,27 +704,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, Cause.unknown(), event.getEntity()));
|
||||
}
|
||||
break;
|
||||
case NATURAL:
|
||||
case JOCKEY:
|
||||
case CHUNK_GEN:
|
||||
case SPAWNER:
|
||||
case LIGHTNING:
|
||||
case BUILD_SNOWMAN:
|
||||
case BUILD_IRONGOLEM:
|
||||
case BUILD_WITHER:
|
||||
case VILLAGE_DEFENSE:
|
||||
case VILLAGE_INVASION:
|
||||
case BREEDING:
|
||||
case SLIME_SPLIT:
|
||||
case REINFORCEMENTS:
|
||||
case NETHER_PORTAL:
|
||||
case INFECTION:
|
||||
case CURED:
|
||||
case OCELOT_BABY:
|
||||
case SILVERFISH_BLOCK:
|
||||
case MOUNT:
|
||||
case CUSTOM:
|
||||
case DEFAULT:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -670,6 +727,15 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
if (event.isCancelled() && remover instanceof Player) {
|
||||
playDenyEffect((Player) remover, event.getEntity().getLocation());
|
||||
}
|
||||
} else if (event.getCause() == HangingBreakEvent.RemoveCause.EXPLOSION){
|
||||
DestroyEntityEvent destroyEntityEvent = new DestroyEntityEvent(event, Cause.unknown(), event.getEntity());
|
||||
destroyEntityEvent.getRelevantFlags().add(Flags.OTHER_EXPLOSION);
|
||||
if (event.getEntity() instanceof ItemFrame) {
|
||||
destroyEntityEvent.getRelevantFlags().add(Flags.ENTITY_ITEM_FRAME_DESTROY);
|
||||
} else if (event.getEntity() instanceof Painting) {
|
||||
destroyEntityEvent.getRelevantFlags().add(Flags.ENTITY_PAINTING_DESTROY);
|
||||
}
|
||||
Events.fireToCancel(event, destroyEntityEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,7 +761,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) {
|
||||
@@ -748,8 +814,20 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
? player.getInventory().getItemInOffHand() : player.getInventory().getItemInMainHand();
|
||||
Entity entity = event.getRightClicked();
|
||||
|
||||
Events.fireToCancel(event, new UseItemEvent(event, create(player), world, item));
|
||||
Events.fireToCancel(event, new UseEntityEvent(event, create(player), entity));
|
||||
if (Events.fireToCancel(event, new UseItemEvent(event, create(player), world, item))) {
|
||||
return;
|
||||
}
|
||||
final UseEntityEvent useEntityEvent = new UseEntityEvent(event, create(player), entity);
|
||||
Material matchingItem = Materials.getRelatedMaterial(entity.getType());
|
||||
if (matchingItem != null && hasInteractBypass(world, matchingItem)) {
|
||||
useEntityEvent.setAllowed(true);
|
||||
}
|
||||
if (!Events.fireToCancel(event, useEntityEvent)) {
|
||||
// so this is a hack but CreeperIgniteEvent doesn't actually tell us who, so we need to do it here
|
||||
if (item.getType() == Material.FLINT_AND_STEEL && entity.getType() == EntityType.CREEPER) {
|
||||
Cause.trackParentCause(entity, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
@@ -766,7 +844,17 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
} else if (event instanceof EntityDamageByEntityEvent) {
|
||||
EntityDamageByEntityEvent entityEvent = (EntityDamageByEntityEvent) event;
|
||||
Entity damager = entityEvent.getDamager();
|
||||
Events.fireToCancel(event, new DamageEntityEvent(event, create(damager), event.getEntity()));
|
||||
final DamageEntityEvent eventToFire = new DamageEntityEvent(event, create(damager), event.getEntity());
|
||||
if (damager instanceof Firework) {
|
||||
eventToFire.getRelevantFlags().add(Flags.FIREWORK_DAMAGE);
|
||||
} else if (damager instanceof Creeper) {
|
||||
eventToFire.getRelevantFlags().add(Flags.CREEPER_EXPLOSION);
|
||||
}
|
||||
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
|
||||
@@ -798,7 +886,7 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
if (event instanceof PlayerUnleashEntityEvent) {
|
||||
PlayerUnleashEntityEvent playerEvent = (PlayerUnleashEntityEvent) event;
|
||||
Events.fireToCancel(playerEvent, new UseEntityEvent(playerEvent, create(playerEvent.getPlayer()), event.getEntity()));
|
||||
} // TODO: Raise anyway?
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
@@ -840,30 +928,42 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryOpen(InventoryOpenEvent event) {
|
||||
InventoryHolder holder = event.getInventory().getHolder();
|
||||
if (holder instanceof BlockState) {
|
||||
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), ((BlockState) holder).getBlock()));
|
||||
} else if (holder instanceof Entity) {
|
||||
if (!(holder instanceof Player)) {
|
||||
Events.fireToCancel(event, new UseEntityEvent(event, create(event.getPlayer()), (Entity) holder));
|
||||
}
|
||||
}
|
||||
if (holder instanceof Entity && holder == event.getPlayer()) return;
|
||||
|
||||
handleInventoryHolderUse(event, create(event.getPlayer()), holder);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryMoveItem(InventoryMoveItemEvent event) {
|
||||
final InventoryHolder causeHolder = event.getInitiator().getHolder();
|
||||
InventoryHolder sourceHolder = event.getSource().getHolder();
|
||||
InventoryHolder targetHolder = event.getDestination().getHolder();
|
||||
InventoryHolder causeHolder;
|
||||
if (HAS_SNAPSHOT_INVHOLDER) {
|
||||
causeHolder = event.getInitiator().getHolder(false);
|
||||
} else {
|
||||
causeHolder = event.getInitiator().getHolder();
|
||||
}
|
||||
|
||||
if ((causeHolder instanceof Hopper || causeHolder instanceof Dropper)
|
||||
&& ((BukkitWorldConfiguration) WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(
|
||||
BukkitAdapter.adapt(((Container) causeHolder).getWorld()))).ignoreHopperMoveEvents) {
|
||||
WorldConfiguration wcfg = null;
|
||||
if (causeHolder instanceof Hopper
|
||||
&& (wcfg = getWorldConfig(BukkitAdapter.adapt((((Hopper) causeHolder).getWorld())))).ignoreHopperMoveEvents) {
|
||||
return;
|
||||
} else if (causeHolder instanceof HopperMinecart
|
||||
&& (wcfg = getWorldConfig(BukkitAdapter.adapt((((HopperMinecart) causeHolder).getWorld())))).ignoreHopperMoveEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entry entry;
|
||||
|
||||
if ((entry = moveItemDebounce.tryDebounce(event)) != null) {
|
||||
InventoryHolder sourceHolder;
|
||||
InventoryHolder targetHolder;
|
||||
if (HAS_SNAPSHOT_INVHOLDER) {
|
||||
sourceHolder = event.getSource().getHolder(false);
|
||||
targetHolder = event.getDestination().getHolder(false);
|
||||
} else {
|
||||
sourceHolder = event.getSource().getHolder();
|
||||
targetHolder = event.getDestination().getHolder();
|
||||
}
|
||||
|
||||
Cause cause;
|
||||
|
||||
if (causeHolder instanceof Entity) {
|
||||
@@ -880,7 +980,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 {
|
||||
@@ -927,15 +1027,18 @@ 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);
|
||||
@@ -982,6 +1085,20 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
Events.fireBulkEventToCancel(event, eventToFire);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onTakeLecternBook(PlayerTakeLecternBookEvent event) {
|
||||
final UseBlockEvent useEvent = new UseBlockEvent(event, create(event.getPlayer()), event.getLectern().getBlock());
|
||||
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.
|
||||
*
|
||||
@@ -1005,14 +1122,16 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
|
||||
// Handle created Minecarts
|
||||
if (item != null && Materials.isMinecart(item.getType())) {
|
||||
// TODO: Give a more specific Minecart type
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.MINECART));
|
||||
EntityType entityType = Materials.getRelatedEntity(item.getType());
|
||||
if (entityType == null) {
|
||||
entityType = EntityType.MINECART;
|
||||
}
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, clicked.getLocation().add(0.5, 0, 0.5), entityType));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle created boats
|
||||
if (item != null && Materials.isBoat(item.getType())) {
|
||||
// TODO as above
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), EntityType.BOAT));
|
||||
return;
|
||||
}
|
||||
@@ -1034,6 +1153,13 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, cause, placed.getLocation().add(0.5, 0, 0.5), Materials.getEntitySpawnEgg(item.getType())));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends Event & Cancellable> void handleInventoryHolderUse(T originalEvent, Cause cause, InventoryHolder holder) {
|
||||
@@ -1042,47 +1168,64 @@ public class EventAbstractionListener extends AbstractListener {
|
||||
}
|
||||
|
||||
if (holder instanceof Entity) {
|
||||
Events.fireToCancel(originalEvent, new UseEntityEvent(originalEvent, cause, (Entity) holder));
|
||||
} else if (holder instanceof BlockState) {
|
||||
Events.fireToCancel(originalEvent, new UseBlockEvent(originalEvent, cause, ((BlockState) holder).getBlock()));
|
||||
} else if (holder instanceof DoubleChest) {
|
||||
InventoryHolder left = ((DoubleChest) holder).getLeftSide();
|
||||
InventoryHolder right = ((DoubleChest) holder).getRightSide();
|
||||
if (left instanceof Chest) {
|
||||
Events.fireToCancel(originalEvent, new UseBlockEvent(originalEvent, cause, ((Chest) left).getBlock()));
|
||||
Entity entity = (Entity) holder;
|
||||
Material mat = Materials.getRelatedMaterial((entity).getType());
|
||||
UseEntityEvent useEntityEvent = new UseEntityEvent(originalEvent, cause, entity);
|
||||
if (mat != null && hasInteractBypass((entity).getWorld(), mat)) {
|
||||
useEntityEvent.setAllowed(true);
|
||||
}
|
||||
if (right instanceof Chest) {
|
||||
Events.fireToCancel(originalEvent, new UseBlockEvent(originalEvent, cause, ((Chest) right).getBlock()));
|
||||
Events.fireToCancel(originalEvent, useEntityEvent);
|
||||
} else {
|
||||
if (holder instanceof BlockState) {
|
||||
final BlockState block = (BlockState) holder;
|
||||
final UseBlockEvent useBlockEvent = new UseBlockEvent(originalEvent, cause, block.getBlock());
|
||||
if (hasInteractBypass(block.getWorld(), block.getType())) {
|
||||
useBlockEvent.setAllowed(true);
|
||||
}
|
||||
Events.fireToCancel(originalEvent, useBlockEvent);
|
||||
} else if (holder instanceof DoubleChest) {
|
||||
InventoryHolder left = ((DoubleChest) holder).getLeftSide();
|
||||
InventoryHolder right = ((DoubleChest) holder).getRightSide();
|
||||
if (left instanceof Chest) {
|
||||
Events.fireToCancel(originalEvent, new UseBlockEvent(originalEvent, cause, ((Chest) left).getBlock()));
|
||||
}
|
||||
if (right instanceof Chest) {
|
||||
Events.fireToCancel(originalEvent, new UseBlockEvent(originalEvent, cause, ((Chest) right).getBlock()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasInteractBypass(Block block) {
|
||||
private static boolean hasInteractBypass(Block block) {
|
||||
return ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(block.getWorld()))).allowAllInteract.test(block);
|
||||
}
|
||||
|
||||
private boolean hasInteractBypass(World world, ItemStack item) {
|
||||
private static boolean hasInteractBypass(World world, Material material) {
|
||||
return ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(world))).allowAllInteract.test(material);
|
||||
}
|
||||
|
||||
private static boolean hasInteractBypass(World world, ItemStack item) {
|
||||
return ((BukkitWorldConfiguration) getWorldConfig(BukkitAdapter.adapt(world))).allowAllInteract.test(item);
|
||||
}
|
||||
|
||||
private boolean isBlockModifiedOnClick(Block block, boolean rightClick) {
|
||||
private static boolean isBlockModifiedOnClick(Block block, boolean rightClick) {
|
||||
return Materials.isBlockModifiedOnClick(block.getType(), rightClick) && !hasInteractBypass(block);
|
||||
}
|
||||
|
||||
private boolean isItemAppliedToBlock(ItemStack item, Block clicked) {
|
||||
private static boolean isItemAppliedToBlock(ItemStack item, Block clicked) {
|
||||
return Materials.isItemAppliedToBlock(item.getType(), clicked.getType())
|
||||
&& !hasInteractBypass(clicked)
|
||||
&& !hasInteractBypass(clicked.getWorld(), item);
|
||||
}
|
||||
|
||||
private void playDenyEffect(Player player, Location location) {
|
||||
private static void playDenyEffect(Player player, Location location) {
|
||||
//player.playSound(location, Sound.SUCCESSFUL_HIT, 0.2f, 0.4f);
|
||||
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().particleEffects) {
|
||||
player.playEffect(location, Effect.SMOKE, BlockFace.UP);
|
||||
}
|
||||
}
|
||||
|
||||
private void playDenyEffect(Location location) {
|
||||
private static void playDenyEffect(Location location) {
|
||||
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().particleEffects) {
|
||||
location.getWorld().playEffect(location, Effect.SMOKE, BlockFace.UP);
|
||||
}
|
||||
|
||||
+24
-3
@@ -35,6 +35,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
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;
|
||||
@@ -77,6 +78,14 @@ 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);
|
||||
|
||||
@@ -89,15 +98,15 @@ public class PlayerMoveListener implements Listener {
|
||||
} else if (event.getPlayer().getVehicle() != null && event.getPlayer().getVehicle() instanceof Horse) {
|
||||
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());
|
||||
|
||||
@@ -124,4 +133,16 @@ public class PlayerMoveListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-17
@@ -39,7 +39,6 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
|
||||
@@ -109,6 +108,10 @@ public class RegionFlagsListener extends AbstractListener {
|
||||
if (event.getCause().find(EntityType.ENDERMAN) != null) {
|
||||
event.filter(testState(query, Flags.ENDER_BUILD), false);
|
||||
}
|
||||
|
||||
if (event.getCause().find(EntityType.RAVAGER) != null) {
|
||||
event.filter(testState(query, Flags.RAVAGER_RAVAGE), false);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
@@ -126,27 +129,15 @@ public class RegionFlagsListener extends AbstractListener {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
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;
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (event instanceof EntityDamageByEntityEvent) {
|
||||
Entity damager = (((EntityDamageByEntityEvent) event)).getDamager();
|
||||
if (damager != null && damager.getType() == EntityType.FIREWORK) {
|
||||
if (!query.testState(BukkitAdapter.adapt(entity.getLocation()), (RegionAssociable) null, Flags.FIREWORK_DAMAGE)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+36
-42
@@ -41,10 +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.domains.Association;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.DelayedRegionOverlapAssociation;
|
||||
import com.sk89q.worldguard.protection.association.Associables;
|
||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
@@ -53,7 +49,6 @@ import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -63,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;
|
||||
@@ -140,38 +137,19 @@ public class RegionProtectionListener extends AbstractListener {
|
||||
if (rootCause instanceof Player) {
|
||||
Player player = (Player) rootCause;
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
WorldConfiguration config = getWorldConfig(BukkitAdapter.adapt(world));
|
||||
com.sk89q.worldedit.world.World localWorld = BukkitAdapter.adapt(world);
|
||||
WorldConfiguration config = getWorldConfig(localWorld);
|
||||
|
||||
if (config.fakePlayerBuildOverride && InteropUtils.isFakePlayer(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !pvp && new RegionPermissionModel(localPlayer).mayIgnoreRegionProtection(BukkitAdapter.adapt(world));
|
||||
return !pvp && WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, localWorld);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private RegionAssociable createRegionAssociable(Cause cause) {
|
||||
Object rootCause = cause.getRootCause();
|
||||
|
||||
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) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(((Entity) rootCause).getLocation()));
|
||||
} else if (rootCause instanceof Block) {
|
||||
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
|
||||
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(((Block) rootCause).getLocation()));
|
||||
} else {
|
||||
return Associables.constant(Association.NON_MEMBER);
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
@@ -194,9 +172,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);
|
||||
@@ -282,14 +260,24 @@ 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";
|
||||
|
||||
/* 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));
|
||||
@@ -352,12 +340,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) {
|
||||
@@ -416,15 +399,16 @@ public class RegionProtectionListener extends AbstractListener {
|
||||
String what;
|
||||
|
||||
/* Hostile / ambient mob override */
|
||||
final EntityType type = event.getEntity().getType();
|
||||
if (Entities.isHostile(event.getEntity()) || Entities.isAmbient(event.getEntity())
|
||||
|| Entities.isNPC(event.getEntity())) {
|
||||
final Entity entity = event.getEntity();
|
||||
final EntityType type = entity.getType();
|
||||
if (Entities.isHostile(entity) || Entities.isAmbient(entity)
|
||||
|| Entities.isNPC(entity) || entity instanceof Player) {
|
||||
canUse = event.getRelevantFlags().isEmpty() || query.queryState(BukkitAdapter.adapt(target), associable, combine(event)) != State.DENY;
|
||||
what = "use that";
|
||||
/* Paintings, item frames, etc. */
|
||||
} else if (Entities.isConsideredBuildingIfUsed(event.getEntity())) {
|
||||
} else if (Entities.isConsideredBuildingIfUsed(entity)) {
|
||||
if (type == EntityType.ITEM_FRAME && event.getCause().getFirstPlayer() != null
|
||||
&& ((ItemFrame) event.getEntity()).getItem().getType() != Material.AIR) {
|
||||
&& ((ItemFrame) entity).getItem().getType() != Material.AIR) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.ITEM_FRAME_ROTATE));
|
||||
what = "change that";
|
||||
} else if (Entities.isMinecart(type)) {
|
||||
@@ -435,7 +419,7 @@ public class RegionProtectionListener extends AbstractListener {
|
||||
what = "change that";
|
||||
}
|
||||
/* Ridden on use */
|
||||
} else if (Entities.isRiddenOnUse(event.getEntity())) {
|
||||
} else if (Entities.isRiddenOnUse(entity)) {
|
||||
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.RIDE, Flags.INTERACT));
|
||||
what = "ride that";
|
||||
|
||||
@@ -575,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;
|
||||
}
|
||||
|
||||
}
|
||||
+30
-25
@@ -34,6 +34,7 @@ import com.sk89q.worldguard.util.SpongeUtil;
|
||||
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.EventHandler;
|
||||
@@ -131,9 +132,10 @@ 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;
|
||||
Material fromType = blockFrom.getType();
|
||||
boolean isWater = Materials.isWater(fromType);
|
||||
boolean isLava = fromType == Material.LAVA;
|
||||
boolean isAir = fromType == Material.AIR;
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
@@ -194,7 +196,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 +207,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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -326,7 +321,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 +330,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 +349,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);
|
||||
}
|
||||
}
|
||||
@@ -603,7 +598,7 @@ public class WorldGuardBlockListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
if (newType == Material.VINE || newType == Material.KELP) {
|
||||
if (Materials.isVine(newType)) {
|
||||
if (wcfg.disableVineGrowth) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
@@ -620,7 +615,7 @@ public class WorldGuardBlockListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockGrow(BlockGrowEvent event) {
|
||||
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
final Material type = event.getBlock().getType();
|
||||
final Material type = event.getNewState().getType();
|
||||
|
||||
if (Materials.isCrop(type)) {
|
||||
if (wcfg.disableCropGrowth) {
|
||||
@@ -682,6 +677,16 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+117
-27
@@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
|
||||
@@ -31,11 +32,14 @@ import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
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.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.EnderCrystal;
|
||||
@@ -43,7 +47,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;
|
||||
@@ -62,7 +68,6 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.event.entity.CreeperPowerEvent;
|
||||
import org.bukkit.event.entity.EntityBreakDoorEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityCreatePortalEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
@@ -71,9 +76,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.world.PortalCreateEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
@@ -102,9 +111,6 @@ public class WorldGuardEntityListener implements Listener {
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
if (!EntityCreatePortalEvent.class.isAnnotationPresent(Deprecated.class)) {
|
||||
plugin.getServer().getPluginManager().registerEvents(new UselessIn114Listener(), plugin);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
@@ -115,11 +121,13 @@ public class WorldGuardEntityListener implements Listener {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +170,9 @@ public class WorldGuardEntityListener implements Listener {
|
||||
|
||||
if (wcfg.teleportOnVoid && type == DamageCause.VOID) {
|
||||
localPlayer.findFreePosition();
|
||||
if (wcfg.safeFallOnVoid) {
|
||||
localPlayer.resetFallDistance();
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
@@ -277,13 +288,6 @@ public class WorldGuardEntityListener implements Listener {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attacker instanceof Creeper) {
|
||||
if (!set.testState(localPlayer, Flags.CREEPER_EXPLOSION) && wcfg.explosionFlagCancellation) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -669,24 +673,69 @@ public class WorldGuardEntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private static class UselessIn114Listener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onCreatePortal(EntityCreatePortalEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getEntity().getWorld()));
|
||||
@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);
|
||||
|
||||
switch (event.getEntityType()) {
|
||||
case ENDER_DRAGON:
|
||||
if (wcfg.blockEnderDragonPortalCreation) event.setCancelled(true);
|
||||
break;
|
||||
if (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)) {
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
// 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.");
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: as of right now, bukkit doesn't fire this event for this (despite deprecating EntityCreatePortalEvent for it)
|
||||
// maybe one day this code will be useful
|
||||
if (event.getEntity() instanceof EnderDragon && wcfg.blockEnderDragonPortalCreation) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@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()));
|
||||
|
||||
final EntityType type = entity.getType();
|
||||
if (wcfg.disableVillagerZap && type == EntityType.VILLAGER
|
||||
&& event.getTransformReason() == EntityTransformEvent.TransformReason.LIGHTNING) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onPigZap(PigZapEvent event) {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getEntity().getWorld()));
|
||||
final Entity entity = event.getEntity();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(entity.getWorld()));
|
||||
|
||||
if (wcfg.disablePigZap) {
|
||||
event.setCancelled(true);
|
||||
@@ -705,6 +754,10 @@ 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();
|
||||
@@ -716,6 +769,31 @@ public class WorldGuardEntityListener implements Listener {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && ent instanceof Player
|
||||
&& !WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().testState(
|
||||
BukkitAdapter.adapt(ent.getLocation()),
|
||||
WorldGuardPlugin.inst().wrapPlayer((Player) ent),
|
||||
Flags.HEALTH_REGEN)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onFoodChange(FoodLevelChangeEvent event) {
|
||||
if (event.getItem() != null) return;
|
||||
HumanEntity ent = event.getEntity();
|
||||
if (!(ent instanceof Player)) return;
|
||||
LocalPlayer player = WorldGuardPlugin.inst().wrapPlayer((Player) ent);
|
||||
if (event.getFoodLevel() > player.getFoodLevel()) return;
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(player.getWorld());
|
||||
|
||||
if (wcfg.useRegions
|
||||
&& !WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().testState(
|
||||
player.getLocation(), player, Flags.HUNGER_DRAIN)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -731,7 +809,19 @@ public class WorldGuardEntityListener implements Listener {
|
||||
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(ent.getWorld()));
|
||||
if (ent instanceof Enderman) {
|
||||
if (ent instanceof FallingBlock) {
|
||||
Material id = event.getBlock().getType();
|
||||
|
||||
if (id == Material.GRAVEL && wcfg.noPhysicsGravel) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == Material.SAND && wcfg.noPhysicsSand) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (ent instanceof Enderman) {
|
||||
if (wcfg.disableEndermanGriefing) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
||||
+25
-72
@@ -31,8 +31,6 @@ import com.sk89q.worldguard.config.ConfigurationManager;
|
||||
import com.sk89q.worldguard.config.WorldConfiguration;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import com.sk89q.worldguard.session.MoveType;
|
||||
@@ -40,10 +38,9 @@ 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.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TravelAgent;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -60,20 +57,18 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
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.
|
||||
*/
|
||||
@@ -143,7 +138,7 @@ public class WorldGuardPlayerListener implements Listener {
|
||||
|
||||
if (removed > 10) {
|
||||
log.info("Halt-Act: " + removed + " entities (>10) auto-removed from "
|
||||
+ player.getWorld().toString());
|
||||
+ player.getWorld());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +148,8 @@ 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)
|
||||
@@ -181,7 +178,7 @@ public class WorldGuardPlayerListener implements Listener {
|
||||
anyRemoved = true;
|
||||
}
|
||||
}
|
||||
if (anyRemoved && event.getRecipients().size() == 0 && wcfg.regionCancelEmptyChatEvents) {
|
||||
if (anyRemoved && event.getRecipients().isEmpty() && wcfg.regionCancelEmptyChatEvents) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -205,7 +202,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: " +
|
||||
@@ -316,13 +314,17 @@ 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));
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -368,7 +370,6 @@ public class WorldGuardPlayerListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
World world = event.getFrom().getWorld();
|
||||
Player player = event.getPlayer();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
@@ -386,89 +387,41 @@ public class WorldGuardPlayerListener implements Listener {
|
||||
String message = null;
|
||||
if (!setFrom.testState(localPlayer, Flags.ENDERPEARL)) {
|
||||
cancel = true;
|
||||
message = set.queryValue(localPlayer, Flags.EXIT_DENY_MESSAGE);
|
||||
message = setFrom.queryValue(localPlayer, Flags.EXIT_DENY_MESSAGE);
|
||||
} else if (!set.testState(localPlayer, Flags.ENDERPEARL)) {
|
||||
cancel = true;
|
||||
message = set.queryValue(localPlayer, Flags.ENTRY_DENY_MESSAGE);
|
||||
}
|
||||
if (cancel) {
|
||||
player.sendMessage(message);
|
||||
if (message != null) {
|
||||
player.sendMessage(message);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (event.getCause() == TeleportCause.CHORUS_FRUIT) {
|
||||
} else if (event.getCause() == TeleportCause.CHORUS_FRUIT) {
|
||||
if (!WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, localPlayer.getWorld())) {
|
||||
boolean cancel = false;
|
||||
String message = null;
|
||||
if (!setFrom.testState(localPlayer, Flags.CHORUS_TELEPORT)) {
|
||||
cancel = true;
|
||||
message = set.queryValue(localPlayer, Flags.EXIT_DENY_MESSAGE);
|
||||
message = setFrom.queryValue(localPlayer, Flags.EXIT_DENY_MESSAGE);
|
||||
} else if (!set.testState(localPlayer, Flags.CHORUS_TELEPORT)) {
|
||||
cancel = true;
|
||||
message = set.queryValue(localPlayer, Flags.ENTRY_DENY_MESSAGE);
|
||||
}
|
||||
if (cancel) {
|
||||
player.sendMessage(message);
|
||||
if (message != null) {
|
||||
player.sendMessage(message);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (null != WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer).testMoveTo(localPlayer,
|
||||
BukkitAdapter.adapt(event.getTo()),
|
||||
MoveType.TELEPORT)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
||||
public void onPlayerPortal(PlayerPortalEvent event) {
|
||||
if (event.getTo() == null) { // apparently this counts as a cancelled event, implementation specific though
|
||||
return;
|
||||
}
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(event.getPlayer());
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getTo().getWorld()));
|
||||
if (!wcfg.regionNetherPortalProtection) return;
|
||||
if (event.getCause() != TeleportCause.NETHER_PORTAL) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (!event.useTravelAgent()) { // either end travel (even though we checked cause) or another plugin is fucking with us, shouldn't create a portal though
|
||||
return;
|
||||
}
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
return;
|
||||
}
|
||||
TravelAgent pta = event.getPortalTravelAgent();
|
||||
if (pta == null) { // possible, but shouldn't create a portal
|
||||
return;
|
||||
}
|
||||
if (pta.findPortal(event.getTo()) != null) {
|
||||
return; // portal exists...it shouldn't make a new one
|
||||
}
|
||||
// HOPEFULLY covered everything the server can throw at us...proceed protection checking
|
||||
// a lot of that is implementation specific though
|
||||
|
||||
// hackily estimate the area that could be effected by this event, since the server refuses to tell us
|
||||
int radius = pta.getCreationRadius();
|
||||
Location min = event.getTo().clone().subtract(radius, radius, radius);
|
||||
Location max = event.getTo().clone().add(radius, radius, radius);
|
||||
com.sk89q.worldedit.world.World world = BukkitAdapter.adapt(event.getTo().getWorld());
|
||||
|
||||
ProtectedRegion check = new ProtectedCuboidRegion("__portalcheck__", BukkitAdapter.adapt(min.getBlock().getLocation()).toVector().toBlockPoint(),
|
||||
BukkitAdapter.adapt(max.getBlock().getLocation()).toVector().toBlockPoint());
|
||||
|
||||
if (wcfg.useRegions && !WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, world)) {
|
||||
RegionManager mgr = WorldGuard.getInstance().getPlatform().getRegionContainer().get(world);
|
||||
if (mgr == null) return;
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(check);
|
||||
if (!set.testState(plugin.wrapPlayer(event.getPlayer()), Flags.BUILD)) {
|
||||
event.getPlayer().sendMessage(ChatColor.RED + "Destination is in a protected area.");
|
||||
if (null != WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer)
|
||||
.testMoveTo(localPlayer, BukkitAdapter.adapt(event.getTo()), MoveType.TELEPORT)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
+8
-2
@@ -29,6 +29,8 @@ import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
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;
|
||||
@@ -93,8 +95,12 @@ public class WorldGuardWeatherListener implements Listener {
|
||||
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(event.getWorld()));
|
||||
|
||||
if (wcfg.disallowedLightningBlocks.size() > 0) {
|
||||
Material targetId = event.getLightning().getLocation().getBlock().getType();
|
||||
if (!wcfg.disallowedLightningBlocks.isEmpty()) {
|
||||
final Block target = event.getLightning().getLocation().getBlock();
|
||||
Material targetId = target.getType();
|
||||
if (targetId == Material.AIR) {
|
||||
targetId = target.getRelative(BlockFace.DOWN).getType();
|
||||
}
|
||||
if (wcfg.disallowedLightningBlocks.contains(BukkitAdapter.asBlockType(targetId).getId())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
+3
-3
@@ -24,13 +24,13 @@ 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.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 +57,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);
|
||||
@@ -75,7 +75,7 @@ public class BukkitSessionManager extends AbstractSessionManager implements Runn
|
||||
public boolean hasBypass(LocalPlayer player, World world) {
|
||||
if (player instanceof BukkitPlayer) {
|
||||
if (((BukkitPlayer) player).getPlayer().hasMetadata("NPC")
|
||||
&& WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).fakePlayerBuildOverride)
|
||||
&& WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).fakePlayerBuildOverride)
|
||||
return true;
|
||||
}
|
||||
return super.hasBypass(player, world);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.util;
|
||||
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -45,7 +46,7 @@ public final class Blocks {
|
||||
* @return a list of connected blocks, not including the given block
|
||||
*/
|
||||
public static List<Block> getConnected(Block block) {
|
||||
BlockState state = block.getState();
|
||||
BlockState state = PaperLib.getBlockState(block, false).getState();
|
||||
BlockData data = state.getBlockData();
|
||||
|
||||
if (data instanceof Bed) {
|
||||
|
||||
@@ -21,6 +21,7 @@ package com.sk89q.worldguard.bukkit.util;
|
||||
|
||||
import org.bukkit.entity.Ambient;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.EnderCrystal;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
@@ -37,11 +38,10 @@ 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.TippedArrow;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.entity.WaterMob;
|
||||
import org.bukkit.entity.minecart.ExplosiveMinecart;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
@@ -91,7 +91,7 @@ public final class Entities {
|
||||
* @return true if the entity can be ridden
|
||||
*/
|
||||
public static boolean isRiddenOnUse(Entity entity) {
|
||||
return entity instanceof Vehicle;
|
||||
return entity instanceof Steerable ? ((Steerable) entity).hasSaddle() : entity instanceof Vehicle;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,8 +163,7 @@ public final class Entities {
|
||||
* @return true if non-hostile
|
||||
*/
|
||||
public static boolean isNonHostile(Entity entity) {
|
||||
return !isHostile(entity)
|
||||
&& (entity instanceof Creature || entity instanceof WaterMob);
|
||||
return !isHostile(entity) && entity instanceof Creature;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +212,7 @@ public final class Entities {
|
||||
}
|
||||
|
||||
public static boolean isPotionArrow(Entity entity) {
|
||||
return entity instanceof TippedArrow || entity instanceof SpectralArrow;
|
||||
return entity instanceof Arrow || entity instanceof SpectralArrow;
|
||||
}
|
||||
|
||||
public static boolean isAoECloud(EntityType type) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
@@ -36,8 +37,6 @@ import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Material utility class.
|
||||
*/
|
||||
@@ -53,7 +52,6 @@ public final class Materials {
|
||||
private static final Map<Material, Integer> MATERIAL_FLAGS = new EnumMap<>(Material.class);
|
||||
private static final Set<PotionEffectType> DAMAGE_EFFECTS = new HashSet<>();
|
||||
|
||||
|
||||
private static Set<Material> shulkerBoxes = new HashSet<>();
|
||||
|
||||
static {
|
||||
@@ -94,6 +92,7 @@ public final class Materials {
|
||||
ENTITY_ITEMS.put(EntityType.SPLASH_POTION, Material.POTION);
|
||||
ENTITY_ITEMS.put(EntityType.EGG, Material.EGG);
|
||||
ENTITY_ITEMS.put(EntityType.ARMOR_STAND, Material.ARMOR_STAND);
|
||||
ENTITY_ITEMS.put(EntityType.ENDER_CRYSTAL, Material.END_CRYSTAL);
|
||||
|
||||
MATERIAL_FLAGS.put(Material.AIR, 0);
|
||||
MATERIAL_FLAGS.put(Material.STONE, 0);
|
||||
@@ -124,20 +123,10 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.PISTON, 0);
|
||||
MATERIAL_FLAGS.put(Material.PISTON_HEAD, 0);
|
||||
MATERIAL_FLAGS.put(Material.MOVING_PISTON, 0);
|
||||
MATERIAL_FLAGS.put(Material.DANDELION, 0);
|
||||
MATERIAL_FLAGS.put(Material.BLUE_ORCHID, 0);
|
||||
MATERIAL_FLAGS.put(Material.ALLIUM, 0);
|
||||
MATERIAL_FLAGS.put(Material.AZURE_BLUET, 0);
|
||||
MATERIAL_FLAGS.put(Material.ORANGE_TULIP, 0);
|
||||
MATERIAL_FLAGS.put(Material.PINK_TULIP, 0);
|
||||
MATERIAL_FLAGS.put(Material.RED_TULIP, 0);
|
||||
MATERIAL_FLAGS.put(Material.WHITE_TULIP, 0);
|
||||
MATERIAL_FLAGS.put(Material.OXEYE_DAISY, 0);
|
||||
MATERIAL_FLAGS.put(Material.SUNFLOWER, 0);
|
||||
MATERIAL_FLAGS.put(Material.LILAC, 0);
|
||||
MATERIAL_FLAGS.put(Material.PEONY, 0);
|
||||
MATERIAL_FLAGS.put(Material.ROSE_BUSH, 0);
|
||||
MATERIAL_FLAGS.put(Material.POPPY, 0);
|
||||
MATERIAL_FLAGS.put(Material.BROWN_MUSHROOM, 0);
|
||||
MATERIAL_FLAGS.put(Material.RED_MUSHROOM, 0);
|
||||
MATERIAL_FLAGS.put(Material.GOLD_BLOCK, 0);
|
||||
@@ -151,7 +140,7 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.FIRE, 0);
|
||||
MATERIAL_FLAGS.put(Material.SPAWNER, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.CHEST, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_WIRE, 0);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_WIRE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_ORE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.CRAFTING_TABLE, 0);
|
||||
@@ -172,7 +161,6 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.CACTUS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CLAY, 0);
|
||||
MATERIAL_FLAGS.put(Material.JUKEBOX, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.OAK_FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.PUMPKIN, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERRACK, 0);
|
||||
MATERIAL_FLAGS.put(Material.SOUL_SAND, 0);
|
||||
@@ -206,17 +194,10 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.PUMPKIN_STEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.MELON_STEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.VINE, 0);
|
||||
MATERIAL_FLAGS.put(Material.SPRUCE_FENCE_GATE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.ACACIA_FENCE_GATE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BIRCH_FENCE_GATE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.DARK_OAK_FENCE_GATE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.JUNGLE_FENCE_GATE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.OAK_FENCE_GATE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BRICK_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.MYCELIUM, 0);
|
||||
MATERIAL_FLAGS.put(Material.LILY_PAD, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHER_BRICK, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHER_BRICK_FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHER_BRICK_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.ENCHANTING_TABLE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BREWING_STAND, MODIFIED_ON_RIGHT);
|
||||
@@ -235,7 +216,6 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.EMERALD_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.COMMAND_BLOCK, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BEACON, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.COBBLESTONE_WALL, 0);
|
||||
MATERIAL_FLAGS.put(Material.ANVIL, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.CHIPPED_ANVIL, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.DAMAGED_ANVIL, MODIFIED_ON_RIGHT);
|
||||
@@ -269,11 +249,6 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.IRON_TRAPDOOR, 0);
|
||||
MATERIAL_FLAGS.put(Material.RED_SANDSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.RED_SANDSTONE_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.SPRUCE_FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.BIRCH_FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.JUNGLE_FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DARK_OAK_FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.ACACIA_FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.SPRUCE_DOOR, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BIRCH_DOOR, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.JUNGLE_DOOR, MODIFIED_ON_RIGHT);
|
||||
@@ -406,7 +381,6 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.MAGENTA_STAINED_GLASS, 0);
|
||||
MATERIAL_FLAGS.put(Material.MAGENTA_STAINED_GLASS_PANE, 0);
|
||||
MATERIAL_FLAGS.put(Material.MAGENTA_TERRACOTTA, 0);
|
||||
MATERIAL_FLAGS.put(Material.MOSSY_COBBLESTONE_WALL, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSHROOM_STEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.OBSERVER, 0);
|
||||
MATERIAL_FLAGS.put(Material.ORANGE_STAINED_GLASS, 0);
|
||||
@@ -447,9 +421,29 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.YELLOW_STAINED_GLASS_PANE, 0);
|
||||
MATERIAL_FLAGS.put(Material.YELLOW_TERRACOTTA, 0);
|
||||
|
||||
MATERIAL_FLAGS.put(Material.IRON_SHOVEL, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.BAMBOO, 0);
|
||||
MATERIAL_FLAGS.put(Material.BAMBOO_SAPLING, 0);
|
||||
MATERIAL_FLAGS.put(Material.BARREL, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BELL, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BLAST_FURNACE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.CAMPFIRE, MODIFIED_ON_RIGHT | MODIFIED_ON_LEFT);
|
||||
MATERIAL_FLAGS.put(Material.CARTOGRAPHY_TABLE, 0);
|
||||
MATERIAL_FLAGS.put(Material.COMPOSTER, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.FLETCHING_TABLE, 0);
|
||||
MATERIAL_FLAGS.put(Material.GRINDSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.JIGSAW, MODIFIED_ON_RIGHT | MODIFIED_ON_LEFT);
|
||||
MATERIAL_FLAGS.put(Material.LANTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.LECTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.LOOM, 0);
|
||||
MATERIAL_FLAGS.put(Material.SCAFFOLDING, 0);
|
||||
MATERIAL_FLAGS.put(Material.SMITHING_TABLE, 0);
|
||||
MATERIAL_FLAGS.put(Material.SMOKER, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.STONECUTTER, 0);
|
||||
MATERIAL_FLAGS.put(Material.SWEET_BERRY_BUSH, MODIFIED_ON_RIGHT);
|
||||
|
||||
MATERIAL_FLAGS.put(Material.IRON_SHOVEL, 0);
|
||||
MATERIAL_FLAGS.put(Material.IRON_PICKAXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.IRON_AXE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.IRON_AXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.FLINT_AND_STEEL, 0);
|
||||
MATERIAL_FLAGS.put(Material.APPLE, 0);
|
||||
MATERIAL_FLAGS.put(Material.BOW, 0);
|
||||
@@ -460,32 +454,32 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.GOLD_INGOT, 0);
|
||||
MATERIAL_FLAGS.put(Material.IRON_SWORD, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_SWORD, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_SHOVEL, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_SHOVEL, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_PICKAXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_AXE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_AXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.STONE_SWORD, 0);
|
||||
MATERIAL_FLAGS.put(Material.STONE_SHOVEL, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.STONE_SHOVEL, 0);
|
||||
MATERIAL_FLAGS.put(Material.STONE_PICKAXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.STONE_AXE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.STONE_AXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_SWORD, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_SHOVEL, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_SHOVEL, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_PICKAXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_AXE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_AXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.STICK, 0);
|
||||
MATERIAL_FLAGS.put(Material.BOWL, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSHROOM_STEW, 0);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_SWORD, 0);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_SHOVEL, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_SHOVEL, 0);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_PICKAXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_AXE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_AXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.STRING, 0);
|
||||
MATERIAL_FLAGS.put(Material.FEATHER, 0);
|
||||
MATERIAL_FLAGS.put(Material.GUNPOWDER, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_HOE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.STONE_HOE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.IRON_HOE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_HOE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_HOE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_HOE, 0);
|
||||
MATERIAL_FLAGS.put(Material.STONE_HOE, 0);
|
||||
MATERIAL_FLAGS.put(Material.IRON_HOE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_HOE, 0);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_HOE, 0);
|
||||
MATERIAL_FLAGS.put(Material.WHEAT_SEEDS, 0);
|
||||
MATERIAL_FLAGS.put(Material.BREAD, 0);
|
||||
MATERIAL_FLAGS.put(Material.LEATHER_HELMET, 0);
|
||||
@@ -539,23 +533,30 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.GLOWSTONE_DUST, 0);
|
||||
MATERIAL_FLAGS.put(Material.COD, 0);
|
||||
MATERIAL_FLAGS.put(Material.COOKED_COD, 0);
|
||||
MATERIAL_FLAGS.put(Material.INK_SAC, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.CYAN_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.GRAY_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.LIGHT_BLUE_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.LIGHT_GRAY_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.LIME_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.MAGENTA_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.ORANGE_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.PINK_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.PURPLE_DYE, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.COCOA_BEANS, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.INK_SAC, 0);
|
||||
MATERIAL_FLAGS.put(Material.BLACK_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.BLUE_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.BROWN_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.CYAN_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.GRAY_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.GREEN_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.LIGHT_BLUE_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.LIGHT_GRAY_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.LIME_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.MAGENTA_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.ORANGE_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.PINK_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.PURPLE_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.RED_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.WHITE_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.YELLOW_DYE, 0);
|
||||
MATERIAL_FLAGS.put(Material.COCOA_BEANS, 0);
|
||||
MATERIAL_FLAGS.put(Material.BONE_MEAL, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.BONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.SUGAR, 0);
|
||||
MATERIAL_FLAGS.put(Material.COOKIE, 0);
|
||||
MATERIAL_FLAGS.put(Material.MAP, 0);
|
||||
MATERIAL_FLAGS.put(Material.SHEARS, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.SHEARS, 0);
|
||||
MATERIAL_FLAGS.put(Material.MELON_SLICE, 0);
|
||||
MATERIAL_FLAGS.put(Material.PUMPKIN_SEEDS, 0);
|
||||
MATERIAL_FLAGS.put(Material.MELON_SEEDS, 0);
|
||||
@@ -623,6 +624,7 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.RABBIT_FOOT, 0);
|
||||
MATERIAL_FLAGS.put(Material.RABBIT_HIDE, 0);
|
||||
MATERIAL_FLAGS.put(Material.ARMOR_STAND, 0);
|
||||
MATERIAL_FLAGS.put(Material.LEATHER_HORSE_ARMOR, 0);
|
||||
MATERIAL_FLAGS.put(Material.IRON_HORSE_ARMOR, 0);
|
||||
MATERIAL_FLAGS.put(Material.GOLDEN_HORSE_ARMOR, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_HORSE_ARMOR, 0);
|
||||
@@ -668,18 +670,82 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.TROPICAL_FISH, 0);
|
||||
MATERIAL_FLAGS.put(Material.TROPICAL_FISH_BUCKET, 0);
|
||||
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_11, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_13, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_BLOCKS, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_CAT, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_CHIRP, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_FAR, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_MALL, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_MELLOHI, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_STAL, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_STRAD, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_WAIT, 0);
|
||||
MATERIAL_FLAGS.put(Material.MUSIC_DISC_WARD, 0);
|
||||
MATERIAL_FLAGS.put(Material.CREEPER_BANNER_PATTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.FLOWER_BANNER_PATTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.GLOBE_BANNER_PATTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.MOJANG_BANNER_PATTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.SKULL_BANNER_PATTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.CROSSBOW, 0);
|
||||
MATERIAL_FLAGS.put(Material.SUSPICIOUS_STEW, 0);
|
||||
MATERIAL_FLAGS.put(Material.SWEET_BERRIES, 0);
|
||||
|
||||
// 1.15
|
||||
MATERIAL_FLAGS.put(Material.BEEHIVE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.BEE_NEST, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.HONEY_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.HONEYCOMB_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.HONEY_BOTTLE, 0);
|
||||
MATERIAL_FLAGS.put(Material.HONEYCOMB, 0);
|
||||
|
||||
// 1.16
|
||||
MATERIAL_FLAGS.put(Material.ANCIENT_DEBRIS, 0);
|
||||
MATERIAL_FLAGS.put(Material.BASALT, 0);
|
||||
MATERIAL_FLAGS.put(Material.BLACKSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.CHAIN, 0);
|
||||
MATERIAL_FLAGS.put(Material.CHISELED_NETHER_BRICKS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CHISELED_POLISHED_BLACKSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.CRACKED_NETHER_BRICKS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CRACKED_POLISHED_BLACKSTONE_BRICKS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CRIMSON_FUNGUS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CRIMSON_NYLIUM, 0);
|
||||
MATERIAL_FLAGS.put(Material.CRIMSON_ROOTS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CRIMSON_TRAPDOOR, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.CRYING_OBSIDIAN, 0);
|
||||
MATERIAL_FLAGS.put(Material.GILDED_BLACKSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.LODESTONE, 0);
|
||||
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_AXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_BOOTS, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_CHESTPLATE, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_HELMET, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_HOE, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_INGOT, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_LEGGINGS, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_PICKAXE, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_SCRAP, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_SHOVEL, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERITE_SWORD, 0);
|
||||
|
||||
MATERIAL_FLAGS.put(Material.NETHER_GOLD_ORE, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHER_SPROUTS, 0);
|
||||
MATERIAL_FLAGS.put(Material.PIGLIN_BANNER_PATTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.POLISHED_BASALT, 0);
|
||||
MATERIAL_FLAGS.put(Material.POLISHED_BLACKSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.POLISHED_BLACKSTONE_BRICKS, 0);
|
||||
MATERIAL_FLAGS.put(Material.POLISHED_BLACKSTONE_PRESSURE_PLATE, 0);
|
||||
MATERIAL_FLAGS.put(Material.QUARTZ_BRICKS, 0);
|
||||
MATERIAL_FLAGS.put(Material.RESPAWN_ANCHOR, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.SHROOMLIGHT, 0);
|
||||
MATERIAL_FLAGS.put(Material.SOUL_CAMPFIRE, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.SOUL_FIRE, 0);
|
||||
MATERIAL_FLAGS.put(Material.SOUL_LANTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.SOUL_SOIL, 0);
|
||||
MATERIAL_FLAGS.put(Material.SOUL_TORCH, 0);
|
||||
MATERIAL_FLAGS.put(Material.SOUL_WALL_TORCH, 0);
|
||||
MATERIAL_FLAGS.put(Material.TARGET, 0);
|
||||
MATERIAL_FLAGS.put(Material.TWISTING_VINES, 0);
|
||||
MATERIAL_FLAGS.put(Material.TWISTING_VINES_PLANT, 0);
|
||||
|
||||
MATERIAL_FLAGS.put(Material.WARPED_FUNGUS, 0);
|
||||
MATERIAL_FLAGS.put(Material.WARPED_FUNGUS_ON_A_STICK, 0);
|
||||
MATERIAL_FLAGS.put(Material.WARPED_NYLIUM, 0);
|
||||
MATERIAL_FLAGS.put(Material.WARPED_ROOTS, 0);
|
||||
MATERIAL_FLAGS.put(Material.WARPED_TRAPDOOR, MODIFIED_ON_RIGHT);
|
||||
MATERIAL_FLAGS.put(Material.WARPED_WART_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.WEEPING_VINES, 0);
|
||||
MATERIAL_FLAGS.put(Material.WEEPING_VINES_PLANT, 0);
|
||||
|
||||
|
||||
// Fake tags
|
||||
for (Material m : shulkerBoxes) {
|
||||
@@ -729,6 +795,30 @@ public final class Materials {
|
||||
for (Material pot : Tag.FLOWER_POTS.getValues()) {
|
||||
MATERIAL_FLAGS.put(pot, MODIFIED_ON_RIGHT);
|
||||
}
|
||||
for (Material wall : Tag.WALLS.getValues()) {
|
||||
MATERIAL_FLAGS.put(wall, 0);
|
||||
}
|
||||
for (Material sign : Tag.SIGNS.getValues()) {
|
||||
MATERIAL_FLAGS.put(sign, 0);
|
||||
}
|
||||
for (Material flower : Tag.SMALL_FLOWERS.getValues()) {
|
||||
MATERIAL_FLAGS.put(flower, 0);
|
||||
}
|
||||
for (Material bed : Tag.BEDS.getValues()) {
|
||||
MATERIAL_FLAGS.put(bed, MODIFIED_ON_RIGHT);
|
||||
}
|
||||
for (Material musicDisc : Tag.ITEMS_MUSIC_DISCS.getValues()) {
|
||||
MATERIAL_FLAGS.put(musicDisc, 0);
|
||||
}
|
||||
for (Material bannerPat : Tag.ITEMS_BANNERS.getValues()) {
|
||||
MATERIAL_FLAGS.put(bannerPat, 0);
|
||||
}
|
||||
for (Material fenceGate : Tag.FENCE_GATES.getValues()) {
|
||||
MATERIAL_FLAGS.put(fenceGate, MODIFIED_ON_RIGHT);
|
||||
}
|
||||
for (Material fence : Tag.FENCES.getValues()) {
|
||||
MATERIAL_FLAGS.put(fence, 0);
|
||||
}
|
||||
Stream.concat(Stream.concat(
|
||||
Tag.CORAL_BLOCKS.getValues().stream(),
|
||||
Tag.CORALS.getValues().stream()),
|
||||
@@ -740,57 +830,51 @@ public final class Materials {
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
MATERIAL_FLAGS.put(Material.SIGN, 0);
|
||||
MATERIAL_FLAGS.put(Material.WALL_SIGN, 0);
|
||||
MATERIAL_FLAGS.put(Material.DANDELION_YELLOW, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.ROSE_RED, MODIFIES_BLOCKS);
|
||||
MATERIAL_FLAGS.put(Material.CACTUS_GREEN, MODIFIES_BLOCKS);
|
||||
} catch (NoSuchFieldError ignored) { // missing fields in 1.14
|
||||
}
|
||||
|
||||
// Check for missing items/blocks
|
||||
for (Material material : Material.values()) {
|
||||
//noinspection deprecation
|
||||
if (material.isLegacy()) continue;
|
||||
// Add spawn eggs
|
||||
if (isSpawnEgg(material)) {
|
||||
MATERIAL_FLAGS.put(material, 0);
|
||||
} else if (isBed(material)) {
|
||||
MATERIAL_FLAGS.put(material, MODIFIED_ON_RIGHT);
|
||||
}
|
||||
if (!MATERIAL_FLAGS.containsKey(material)) {
|
||||
logger.fine("Missing material definition for " + (material.isBlock() ? "block " : "item ") + material.name());
|
||||
MATERIAL_FLAGS.put(material, MODIFIED_ON_LEFT | MODIFIED_ON_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.ABSORPTION);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.BLINDNESS);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.CONFUSION);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.DAMAGE_RESISTANCE);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.FAST_DIGGING);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.FIRE_RESISTANCE);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.HARM);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.HEAL);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.HEALTH_BOOST);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.HUNGER);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.INCREASE_DAMAGE);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.INVISIBILITY);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.JUMP);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.NIGHT_VISION);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.POISON);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.REGENERATION);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.SATURATION);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.SPEED);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.SLOW);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.FAST_DIGGING);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.SLOW_DIGGING);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.SPEED);
|
||||
//DAMAGE_EFFECTS.add(PotionEffectType.WATER_BREATHING);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.INCREASE_DAMAGE);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.HEAL);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.HARM);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.JUMP);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.CONFUSION);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.REGENERATION);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.DAMAGE_RESISTANCE);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.FIRE_RESISTANCE);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.WATER_BREATHING);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.INVISIBILITY);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.BLINDNESS);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.NIGHT_VISION);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.HUNGER);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.WEAKNESS);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.POISON);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.WITHER);
|
||||
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.LEVITATION); // considered by game so I guess
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.HEALTH_BOOST);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.ABSORPTION);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.SATURATION);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.GLOWING);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.LEVITATION);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.LUCK);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.UNLUCK);
|
||||
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.SLOW_FALLING);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.CONDUIT_POWER);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.DOLPHINS_GRACE);
|
||||
DAMAGE_EFFECTS.add(PotionEffectType.BAD_OMEN);
|
||||
// DAMAGE_EFFECTS.add(PotionEffectType.HERO_OF_THE_VILLAGE);
|
||||
}
|
||||
|
||||
private Materials() {
|
||||
@@ -807,6 +891,17 @@ public final class Materials {
|
||||
return ENTITY_ITEMS.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the related entity type for a material.
|
||||
*
|
||||
* @param material the material
|
||||
* @return the related entity type or {@code null} if one is not known or exists
|
||||
*/
|
||||
@Nullable
|
||||
public static EntityType getRelatedEntity(Material material) {
|
||||
return ENTITY_ITEMS.inverse().get(material);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the material of the block placed by the given bucket, defaulting
|
||||
* to water if the bucket type is not known.
|
||||
@@ -825,7 +920,6 @@ public final class Materials {
|
||||
case LAVA_BUCKET:
|
||||
return Material.LAVA;
|
||||
case WATER_BUCKET:
|
||||
return Material.WATER;
|
||||
default:
|
||||
return Material.WATER;
|
||||
}
|
||||
@@ -868,7 +962,8 @@ public final class Materials {
|
||||
* @return true if a water block
|
||||
*/
|
||||
public static boolean isWater(Material material) {
|
||||
return material == Material.WATER;
|
||||
return material == Material.WATER || material == Material.BUBBLE_COLUMN
|
||||
|| material == Material.KELP_PLANT || material == Material.SEAGRASS || material == Material.TALL_SEAGRASS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -910,7 +1005,8 @@ public final class Materials {
|
||||
*/
|
||||
public static boolean isPistonBlock(Material material) {
|
||||
return material == Material.PISTON
|
||||
|| material == Material.STICKY_PISTON;
|
||||
|| material == Material.STICKY_PISTON
|
||||
|| material == Material.MOVING_PISTON;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -927,6 +1023,7 @@ public final class Materials {
|
||||
|| material == Material.FURNACE_MINECART
|
||||
|| material == Material.CHEST_MINECART;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given material is a Boat.
|
||||
*
|
||||
@@ -952,14 +1049,19 @@ public final class Materials {
|
||||
|| material == Material.TRAPPED_CHEST
|
||||
|| material == Material.HOPPER
|
||||
|| material == Material.DROPPER
|
||||
|| material == Material.BARREL
|
||||
|| material == Material.BLAST_FURNACE
|
||||
|| material == Material.SMOKER
|
||||
|| shulkerBoxes.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isSpawnEgg(Material material) {
|
||||
switch(material) {
|
||||
switch (material) {
|
||||
case SPIDER_SPAWN_EGG:
|
||||
case BAT_SPAWN_EGG:
|
||||
case BEE_SPAWN_EGG:
|
||||
case BLAZE_SPAWN_EGG:
|
||||
case CAT_SPAWN_EGG:
|
||||
case CAVE_SPIDER_SPAWN_EGG:
|
||||
case CHICKEN_SPAWN_EGG:
|
||||
case COD_SPAWN_EGG:
|
||||
@@ -972,8 +1074,10 @@ public final class Materials {
|
||||
case ENDERMAN_SPAWN_EGG:
|
||||
case ENDERMITE_SPAWN_EGG:
|
||||
case EVOKER_SPAWN_EGG:
|
||||
case FOX_SPAWN_EGG:
|
||||
case GHAST_SPAWN_EGG:
|
||||
case GUARDIAN_SPAWN_EGG:
|
||||
case HOGLIN_SPAWN_EGG:
|
||||
case HORSE_SPAWN_EGG:
|
||||
case HUSK_SPAWN_EGG:
|
||||
case LLAMA_SPAWN_EGG:
|
||||
@@ -981,12 +1085,17 @@ public final class Materials {
|
||||
case MOOSHROOM_SPAWN_EGG:
|
||||
case MULE_SPAWN_EGG:
|
||||
case OCELOT_SPAWN_EGG:
|
||||
case PANDA_SPAWN_EGG:
|
||||
case PARROT_SPAWN_EGG:
|
||||
case PHANTOM_SPAWN_EGG:
|
||||
case PIGLIN_BRUTE_SPAWN_EGG:
|
||||
case PIGLIN_SPAWN_EGG:
|
||||
case PIG_SPAWN_EGG:
|
||||
case PILLAGER_SPAWN_EGG:
|
||||
case POLAR_BEAR_SPAWN_EGG:
|
||||
case PUFFERFISH_SPAWN_EGG:
|
||||
case RABBIT_SPAWN_EGG:
|
||||
case RAVAGER_SPAWN_EGG:
|
||||
case SALMON_SPAWN_EGG:
|
||||
case SHEEP_SPAWN_EGG:
|
||||
case SHULKER_SPAWN_EGG:
|
||||
@@ -996,16 +1105,20 @@ public final class Materials {
|
||||
case SLIME_SPAWN_EGG:
|
||||
case SQUID_SPAWN_EGG:
|
||||
case STRAY_SPAWN_EGG:
|
||||
case STRIDER_SPAWN_EGG:
|
||||
case TRADER_LLAMA_SPAWN_EGG:
|
||||
case TROPICAL_FISH_SPAWN_EGG:
|
||||
case TURTLE_SPAWN_EGG:
|
||||
case VEX_SPAWN_EGG:
|
||||
case VILLAGER_SPAWN_EGG:
|
||||
case VINDICATOR_SPAWN_EGG:
|
||||
case WANDERING_TRADER_SPAWN_EGG:
|
||||
case WITCH_SPAWN_EGG:
|
||||
case WITHER_SKELETON_SPAWN_EGG:
|
||||
case WOLF_SPAWN_EGG:
|
||||
case ZOGLIN_SPAWN_EGG:
|
||||
case ZOMBIE_HORSE_SPAWN_EGG:
|
||||
case ZOMBIE_PIGMAN_SPAWN_EGG:
|
||||
case ZOMBIFIED_PIGLIN_SPAWN_EGG:
|
||||
case ZOMBIE_SPAWN_EGG:
|
||||
case ZOMBIE_VILLAGER_SPAWN_EGG:
|
||||
return true;
|
||||
@@ -1020,8 +1133,12 @@ public final class Materials {
|
||||
return EntityType.SPIDER;
|
||||
case BAT_SPAWN_EGG:
|
||||
return EntityType.BAT;
|
||||
case BEE_SPAWN_EGG:
|
||||
return EntityType.BEE;
|
||||
case BLAZE_SPAWN_EGG:
|
||||
return EntityType.BLAZE;
|
||||
case CAT_SPAWN_EGG:
|
||||
return EntityType.CAT;
|
||||
case CAVE_SPIDER_SPAWN_EGG:
|
||||
return EntityType.CAVE_SPIDER;
|
||||
case CHICKEN_SPAWN_EGG:
|
||||
@@ -1046,10 +1163,14 @@ public final class Materials {
|
||||
return EntityType.ENDERMITE;
|
||||
case EVOKER_SPAWN_EGG:
|
||||
return EntityType.EVOKER;
|
||||
case FOX_SPAWN_EGG:
|
||||
return EntityType.FOX;
|
||||
case GHAST_SPAWN_EGG:
|
||||
return EntityType.GHAST;
|
||||
case GUARDIAN_SPAWN_EGG:
|
||||
return EntityType.GUARDIAN;
|
||||
case HOGLIN_SPAWN_EGG:
|
||||
return EntityType.HOGLIN;
|
||||
case HORSE_SPAWN_EGG:
|
||||
return EntityType.HORSE;
|
||||
case HUSK_SPAWN_EGG:
|
||||
@@ -1064,18 +1185,26 @@ public final class Materials {
|
||||
return EntityType.MULE;
|
||||
case OCELOT_SPAWN_EGG:
|
||||
return EntityType.OCELOT;
|
||||
case PANDA_SPAWN_EGG:
|
||||
return EntityType.PANDA;
|
||||
case PARROT_SPAWN_EGG:
|
||||
return EntityType.PARROT;
|
||||
case PHANTOM_SPAWN_EGG:
|
||||
return EntityType.PHANTOM;
|
||||
case PIG_SPAWN_EGG:
|
||||
return EntityType.PIG;
|
||||
case PIGLIN_BRUTE_SPAWN_EGG:
|
||||
return EntityType.PIGLIN_BRUTE;
|
||||
case PIGLIN_SPAWN_EGG:
|
||||
return EntityType.PIGLIN;
|
||||
case PILLAGER_SPAWN_EGG:
|
||||
return EntityType.PILLAGER;
|
||||
case POLAR_BEAR_SPAWN_EGG:
|
||||
return EntityType.POLAR_BEAR;
|
||||
case PUFFERFISH_SPAWN_EGG:
|
||||
return EntityType.PUFFERFISH;
|
||||
case RABBIT_SPAWN_EGG:
|
||||
return EntityType.RABBIT;
|
||||
case RAVAGER_SPAWN_EGG:
|
||||
return EntityType.RAVAGER;
|
||||
case SALMON_SPAWN_EGG:
|
||||
return EntityType.SALMON;
|
||||
case SHEEP_SPAWN_EGG:
|
||||
@@ -1094,6 +1223,10 @@ public final class Materials {
|
||||
return EntityType.SQUID;
|
||||
case STRAY_SPAWN_EGG:
|
||||
return EntityType.STRAY;
|
||||
case STRIDER_SPAWN_EGG:
|
||||
return EntityType.STRIDER;
|
||||
case TRADER_LLAMA_SPAWN_EGG:
|
||||
return EntityType.TRADER_LLAMA;
|
||||
case TROPICAL_FISH_SPAWN_EGG:
|
||||
return EntityType.TROPICAL_FISH;
|
||||
case TURTLE_SPAWN_EGG:
|
||||
@@ -1104,6 +1237,8 @@ public final class Materials {
|
||||
return EntityType.VILLAGER;
|
||||
case VINDICATOR_SPAWN_EGG:
|
||||
return EntityType.VINDICATOR;
|
||||
case WANDERING_TRADER_SPAWN_EGG:
|
||||
return EntityType.WANDERING_TRADER;
|
||||
case WITCH_SPAWN_EGG:
|
||||
return EntityType.WITCH;
|
||||
case WITHER_SKELETON_SPAWN_EGG:
|
||||
@@ -1112,39 +1247,27 @@ public final class Materials {
|
||||
return EntityType.WOLF;
|
||||
case ZOMBIE_HORSE_SPAWN_EGG:
|
||||
return EntityType.ZOMBIE_HORSE;
|
||||
case ZOMBIE_PIGMAN_SPAWN_EGG:
|
||||
return EntityType.PIG_ZOMBIE;
|
||||
case ZOMBIFIED_PIGLIN_SPAWN_EGG:
|
||||
return EntityType.ZOMBIFIED_PIGLIN;
|
||||
case ZOMBIE_SPAWN_EGG:
|
||||
return EntityType.ZOMBIE;
|
||||
case ZOMBIE_VILLAGER_SPAWN_EGG:
|
||||
return EntityType.ZOMBIE_VILLAGER;
|
||||
default:
|
||||
return EntityType.PIG; // Uhhh
|
||||
case PIG_SPAWN_EGG:
|
||||
default: // Uhh
|
||||
return EntityType.PIG;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBed(Material material) {
|
||||
switch (material) {
|
||||
case BLACK_BED:
|
||||
case BLUE_BED:
|
||||
case BROWN_BED:
|
||||
case CYAN_BED:
|
||||
case GRAY_BED:
|
||||
case GREEN_BED:
|
||||
case LIGHT_BLUE_BED:
|
||||
case LIGHT_GRAY_BED:
|
||||
case LIME_BED:
|
||||
case MAGENTA_BED:
|
||||
case ORANGE_BED:
|
||||
case PINK_BED:
|
||||
case PURPLE_BED:
|
||||
case RED_BED:
|
||||
case WHITE_BED:
|
||||
case YELLOW_BED:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return Tag.BEDS.isTagged(material);
|
||||
}
|
||||
|
||||
public static boolean isCoral(Material material) {
|
||||
return Tag.CORAL_BLOCKS.isTagged(material) ||
|
||||
Tag.CORAL_PLANTS.isTagged(material) ||
|
||||
Tag.CORALS.isTagged(material) ||
|
||||
Tag.WALL_CORALS.isTagged(material);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1160,7 +1283,24 @@ public final class Materials {
|
||||
|| type == Material.MELON_STEM
|
||||
|| type == Material.PUMPKIN_STEM
|
||||
|| type == Material.PUMPKIN
|
||||
|| type == Material.MELON;
|
||||
|| type == Material.MELON
|
||||
|| type == Material.CACTUS
|
||||
|| type == Material.SUGAR_CANE
|
||||
|| type == Material.BAMBOO
|
||||
|| type == Material.BAMBOO_SAPLING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the material should be handled as vine. Used by the vine-growth flag
|
||||
* @param newType the material
|
||||
* @return true if the material should be handled as vine
|
||||
*/
|
||||
public static boolean isVine(Material newType) {
|
||||
return newType == Material.VINE ||
|
||||
newType == Material.KELP ||
|
||||
newType == Material.TWISTING_VINES ||
|
||||
newType == Material.WEEPING_VINES;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1175,26 +1315,23 @@ public final class Materials {
|
||||
*/
|
||||
public static boolean isUseFlagApplicable(Material material) {
|
||||
if (Tag.BUTTONS.isTagged(material)
|
||||
|| Tag.DOORS.isTagged(material)
|
||||
|| Tag.WOODEN_PRESSURE_PLATES.isTagged(material)
|
||||
|| Tag.WOODEN_TRAPDOORS.isTagged(material)) {
|
||||
|| Tag.DOORS.isTagged(material)
|
||||
|| Tag.WOODEN_TRAPDOORS.isTagged(material)
|
||||
|| Tag.FENCE_GATES.isTagged(material)
|
||||
|| Tag.PRESSURE_PLATES.isTagged(material)
|
||||
|| Tag.ANVIL.isTagged(material)) {
|
||||
return true;
|
||||
}
|
||||
switch (material) {
|
||||
case LEVER: return true;
|
||||
case TRIPWIRE: return true;
|
||||
case ENCHANTING_TABLE: return true;
|
||||
case BEACON: return true;
|
||||
case ANVIL: return true;
|
||||
case STONE_PRESSURE_PLATE: return true;
|
||||
case HEAVY_WEIGHTED_PRESSURE_PLATE: return true;
|
||||
case LIGHT_WEIGHTED_PRESSURE_PLATE: return true;
|
||||
case OAK_FENCE_GATE: return true;
|
||||
case SPRUCE_FENCE_GATE: return true;
|
||||
case BIRCH_FENCE_GATE: return true;
|
||||
case JUNGLE_FENCE_GATE: return true;
|
||||
case DARK_OAK_FENCE_GATE: return true;
|
||||
case ACACIA_FENCE_GATE: return true;
|
||||
case LEVER:
|
||||
case LECTERN:
|
||||
case ENCHANTING_TABLE:
|
||||
case BELL:
|
||||
case LOOM:
|
||||
case CARTOGRAPHY_TABLE:
|
||||
case STONECUTTER:
|
||||
case GRINDSTONE:
|
||||
return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
@@ -1229,7 +1366,7 @@ public final class Materials {
|
||||
*/
|
||||
public static boolean isItemAppliedToBlock(Material item, Material block) {
|
||||
Integer flags = MATERIAL_FLAGS.get(item);
|
||||
return flags == null || (flags & MODIFIES_BLOCKS) == MODIFIES_BLOCKS;
|
||||
return flags == null || (flags & MODIFIES_BLOCKS) == MODIFIES_BLOCKS || isToolApplicable(item, block);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1262,4 +1399,145 @@ public final class Materials {
|
||||
return false;
|
||||
}
|
||||
|
||||
// should match instances of ItemArmor
|
||||
|
||||
/**
|
||||
* Check if the material is equippable armor (i.e. that it is equipped on right-click
|
||||
* not necessarily that it can be put in the armor slots)
|
||||
*
|
||||
* @param type material to check
|
||||
* @return true if equippable armor
|
||||
*/
|
||||
public static boolean isArmor(Material type) {
|
||||
switch (type) {
|
||||
case LEATHER_HELMET:
|
||||
case LEATHER_CHESTPLATE:
|
||||
case LEATHER_LEGGINGS:
|
||||
case LEATHER_BOOTS:
|
||||
case CHAINMAIL_HELMET:
|
||||
case CHAINMAIL_CHESTPLATE:
|
||||
case CHAINMAIL_LEGGINGS:
|
||||
case CHAINMAIL_BOOTS:
|
||||
case IRON_HELMET:
|
||||
case IRON_CHESTPLATE:
|
||||
case IRON_LEGGINGS:
|
||||
case IRON_BOOTS:
|
||||
case DIAMOND_HELMET:
|
||||
case DIAMOND_CHESTPLATE:
|
||||
case DIAMOND_LEGGINGS:
|
||||
case DIAMOND_BOOTS:
|
||||
case GOLDEN_HELMET:
|
||||
case GOLDEN_CHESTPLATE:
|
||||
case GOLDEN_LEGGINGS:
|
||||
case GOLDEN_BOOTS:
|
||||
case NETHERITE_HELMET:
|
||||
case NETHERITE_CHESTPLATE:
|
||||
case NETHERITE_LEGGINGS:
|
||||
case NETHERITE_BOOTS:
|
||||
case TURTLE_HELMET:
|
||||
case ELYTRA:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the material is usable via right-click on the target
|
||||
* material. Returns false if the target material cannot be modified
|
||||
* by the provided tool, or of the provided tool material isn't
|
||||
* a tool material.
|
||||
*
|
||||
* @param toolMaterial the tool material being used
|
||||
* @param targetMaterial the target material to check
|
||||
* @return true if tool has an interact function with this material
|
||||
*/
|
||||
public static boolean isToolApplicable(Material toolMaterial, Material targetMaterial) {
|
||||
switch (toolMaterial) {
|
||||
case WOODEN_HOE:
|
||||
case STONE_HOE:
|
||||
case IRON_HOE:
|
||||
case GOLDEN_HOE:
|
||||
case DIAMOND_HOE:
|
||||
case NETHERITE_HOE:
|
||||
switch (targetMaterial) {
|
||||
case GRASS_BLOCK:
|
||||
case DIRT:
|
||||
case GRASS_PATH:
|
||||
// case COARSE_DIRT: // already handled by the server...
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case WOODEN_AXE:
|
||||
case STONE_AXE:
|
||||
case IRON_AXE:
|
||||
case GOLDEN_AXE:
|
||||
case DIAMOND_AXE:
|
||||
case NETHERITE_AXE:
|
||||
switch (targetMaterial) {
|
||||
case OAK_LOG:
|
||||
case DARK_OAK_LOG:
|
||||
case ACACIA_LOG:
|
||||
case BIRCH_LOG:
|
||||
case SPRUCE_LOG:
|
||||
case JUNGLE_LOG:
|
||||
case OAK_WOOD:
|
||||
case DARK_OAK_WOOD:
|
||||
case ACACIA_WOOD:
|
||||
case BIRCH_WOOD:
|
||||
case SPRUCE_WOOD:
|
||||
case JUNGLE_WOOD:
|
||||
case CRIMSON_STEM:
|
||||
case WARPED_STEM:
|
||||
case CRIMSON_HYPHAE:
|
||||
case WARPED_HYPHAE:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case WOODEN_SHOVEL:
|
||||
case STONE_SHOVEL:
|
||||
case IRON_SHOVEL:
|
||||
case GOLDEN_SHOVEL:
|
||||
case DIAMOND_SHOVEL:
|
||||
case NETHERITE_SHOVEL:
|
||||
switch (targetMaterial) {
|
||||
case GRASS_BLOCK:
|
||||
case CAMPFIRE:
|
||||
case SOUL_CAMPFIRE:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case SHEARS:
|
||||
switch (targetMaterial) {
|
||||
case PUMPKIN:
|
||||
case BEE_NEST:
|
||||
case BEEHIVE:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case BLACK_DYE:
|
||||
case BLUE_DYE:
|
||||
case BROWN_DYE:
|
||||
case CYAN_DYE:
|
||||
case GRAY_DYE:
|
||||
case GREEN_DYE:
|
||||
case LIGHT_BLUE_DYE:
|
||||
case LIGHT_GRAY_DYE:
|
||||
case LIME_DYE:
|
||||
case MAGENTA_DYE:
|
||||
case ORANGE_DYE:
|
||||
case PINK_DYE:
|
||||
case PURPLE_DYE:
|
||||
case RED_DYE:
|
||||
case WHITE_DYE:
|
||||
case YELLOW_DYE:
|
||||
return Tag.SIGNS.isTagged(targetMaterial);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFire(Material type) {
|
||||
return type == Material.FIRE || type == Material.SOUL_FIRE;
|
||||
}
|
||||
}
|
||||
+3
@@ -87,6 +87,9 @@ public class ClassSourceValidator {
|
||||
* @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()) {
|
||||
|
||||
+1
-6
@@ -30,13 +30,8 @@ public class ServerReport extends DataReport {
|
||||
|
||||
Server server = Bukkit.getServer();
|
||||
|
||||
try {
|
||||
append("Server ID", server.getServerId());
|
||||
append("Server Name", server.getServerName());
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
}
|
||||
append("Bukkit Version", server.getBukkitVersion());
|
||||
append("Implementation", server.getVersion());
|
||||
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());
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.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;
|
||||
|
||||
public final class PaperProfileService extends SingleRequestService {
|
||||
private static final PaperProfileService INSTANCE = new PaperProfileService();
|
||||
|
||||
private PaperProfileService() {
|
||||
if (!PaperLib.isPaper()) {
|
||||
throw new IllegalStateException("Attempt to access PaperProfileService on non-Paper server.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIdealRequestLimit() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@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 static PaperProfileService getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Example to block some ore mining and placement:
|
||||
# [coalore,goldore,ironore]
|
||||
# [coal_ore,gold_ore,iron_ore]
|
||||
# on-break=deny,log,kick
|
||||
# on-place=deny,tell
|
||||
#
|
||||
@@ -19,6 +19,8 @@
|
||||
# - on-interact (when a block in used (doors, chests, etc.))
|
||||
# - on-drop (an item is being dropped from the player's inventory)
|
||||
# - on-acquire (an item enters a player's inventory via some method)
|
||||
# - on-equip (an item is equipped to the player's armor slots)
|
||||
# NOTE: on-equip is overprotective due to deficiencies in Bukkit API
|
||||
# - on-dispense (a dispenser is about to dispense an item)
|
||||
#
|
||||
# Actions (for events):
|
||||
@@ -40,7 +42,7 @@
|
||||
###############################################################################
|
||||
#
|
||||
# For more information, see:
|
||||
# http://wiki.sk89q.com/wiki/WorldGuard/Blacklist
|
||||
# https://worldguard.enginehub.org/en/latest/blacklist/
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
@@ -49,17 +51,12 @@
|
||||
#
|
||||
|
||||
# Deny lava buckets
|
||||
#[lavabucket]
|
||||
#[lava_bucket]
|
||||
#ignore-perms=my.own.madeup.permission
|
||||
#ignore-groups=admins,mods
|
||||
#on-use=deny,tell
|
||||
|
||||
# Deny some ore
|
||||
#[coalore,goldore,ironore]
|
||||
#[coal_ore,gold_ore,iron_ore]
|
||||
#ignore-groups=admins,mods
|
||||
#on-break=notify,deny,log
|
||||
|
||||
# Some funky data value tests
|
||||
#[wood:0;>=2]
|
||||
#ignore-groups=admins,mods
|
||||
#on-break=notify,deny,log
|
||||
@@ -1,6 +1,6 @@
|
||||
name: WorldGuard
|
||||
main: com.sk89q.worldguard.bukkit.WorldGuardPlugin
|
||||
version: "${project.internalVersion}"
|
||||
version: "${internalVersion}"
|
||||
depend: [WorldEdit]
|
||||
softdepend: [CommandBook]
|
||||
api-version: 1.13
|
||||
api-version: 1.16
|
||||
@@ -1,31 +0,0 @@
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'idea'
|
||||
|
||||
dependencies {
|
||||
api 'com.sk89q.worldedit:worldedit-core:7.0.0-SNAPSHOT'
|
||||
implementation 'com.sk89q.intake:intake:4.2-SNAPSHOT'
|
||||
implementation 'com.sk89q:squirrelid:0.2.0'
|
||||
implementation 'org.flywaydb:flyway-core:3.0'
|
||||
implementation 'org.khelekore:prtree:1.5.0'
|
||||
|
||||
api 'com.google.code.findbugs:jsr305:1.3.9'
|
||||
testImplementation 'junit:junit:4.11'
|
||||
testImplementation 'org.hamcrest:hamcrest-library:1.2.1'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir 'src/main/java'
|
||||
}
|
||||
resources {
|
||||
srcDir 'src/main/resources'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
relocate('com.sk89q.squirrelid', 'com.sk89q.worldguard.util.profile')
|
||||
}
|
||||
|
||||
build.dependsOn(shadowJar { classifier = null })
|
||||
@@ -0,0 +1,33 @@
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("net.ltgt.apt-eclipse")
|
||||
id("net.ltgt.apt-idea")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
|
||||
dependencies {
|
||||
"api"(project(":worldguard-libs:core"))
|
||||
"api"("com.sk89q.worldedit:worldedit-core:${Versions.WORLDEDIT}")
|
||||
"implementation"("org.flywaydb:flyway-core:3.0")
|
||||
"implementation"("org.yaml:snakeyaml:1.9")
|
||||
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
|
||||
|
||||
"compileOnly"("com.google.code.findbugs:jsr305:1.3.9")
|
||||
"testImplementation"("org.hamcrest:hamcrest-library:1.2.1")
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
dependsOn(":worldguard-libs:build")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir("src/main/java")
|
||||
}
|
||||
resources {
|
||||
srcDir("src/main/resources")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,4 +207,17 @@ public interface LocalPlayer extends Player, RegionAssociable {
|
||||
*/
|
||||
@Beta
|
||||
void sendTitle(String title, String subtitle);
|
||||
|
||||
/**
|
||||
* Clears fall distance.
|
||||
*/
|
||||
void resetFallDistance();
|
||||
|
||||
/**
|
||||
* Teleport the player, potentially async, displaying the message on a success.
|
||||
* @param location location to teleport to
|
||||
* @param successMessage message to display on success
|
||||
* @param failMessage message to display on failure
|
||||
*/
|
||||
void teleport(Location location, String successMessage, String failMessage);
|
||||
}
|
||||
@@ -24,14 +24,10 @@ 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.squirrelid.cache.HashMapCache;
|
||||
import com.sk89q.squirrelid.cache.ProfileCache;
|
||||
import com.sk89q.squirrelid.cache.SQLiteCache;
|
||||
import com.sk89q.squirrelid.resolver.BukkitPlayerService;
|
||||
import com.sk89q.squirrelid.resolver.CacheForwardingService;
|
||||
import com.sk89q.squirrelid.resolver.CombinedProfileService;
|
||||
import com.sk89q.squirrelid.resolver.HttpRepositoryService;
|
||||
import com.sk89q.squirrelid.resolver.ProfileService;
|
||||
import com.sk89q.worldguard.util.profile.cache.HashMapCache;
|
||||
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
|
||||
import com.sk89q.worldguard.util.profile.cache.SQLiteCache;
|
||||
import com.sk89q.worldguard.util.profile.resolver.ProfileService;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.util.task.SimpleSupervisor;
|
||||
import com.sk89q.worldedit.util.task.Supervisor;
|
||||
@@ -77,23 +73,20 @@ public final class WorldGuard {
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20));
|
||||
executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20,
|
||||
"WorldGuard Task Executor - %s"));
|
||||
|
||||
File cacheDir = new File(getPlatform().getConfigDir().toFile(), "cache");
|
||||
cacheDir.mkdirs();
|
||||
|
||||
try {
|
||||
profileCache = new SQLiteCache(new File(cacheDir, "profiles.sqlite"));
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Failed to initialize SQLite profile cache");
|
||||
} catch (IOException | UnsatisfiedLinkError ignored) {
|
||||
logger.log(Level.WARNING, "Failed to initialize SQLite profile cache. Cache is memory-only.");
|
||||
profileCache = new HashMapCache();
|
||||
}
|
||||
|
||||
profileService = new CacheForwardingService(
|
||||
new CombinedProfileService(
|
||||
BukkitPlayerService.getInstance(),
|
||||
HttpRepositoryService.forMinecraft()),
|
||||
profileCache);
|
||||
profileService = getPlatform().createProfileService(profileCache);
|
||||
|
||||
getPlatform().load();
|
||||
}
|
||||
|
||||
@@ -27,13 +27,14 @@ public enum EventType {
|
||||
DISPENSE(BlockDispenseBlacklistEvent.class, "on-dispense"),
|
||||
DESTROY_WITH(ItemDestroyWithBlacklistEvent.class, "on-destroy-with"),
|
||||
ACQUIRE(ItemAcquireBlacklistEvent.class, "on-acquire"),
|
||||
EQUIP(ItemEquipBlacklistEvent.class, "on-equip"),
|
||||
DROP(ItemDropBlacklistEvent.class, "on-drop"),
|
||||
USE(ItemUseBlacklistEvent.class, "on-use");
|
||||
|
||||
private final Class<? extends BlacklistEvent> eventClass;
|
||||
private final String ruleName;
|
||||
|
||||
private EventType(Class<? extends BlacklistEvent> eventClass, String ruleName) {
|
||||
EventType(Class<? extends BlacklistEvent> eventClass, String ruleName) {
|
||||
this.eventClass = eventClass;
|
||||
this.ruleName = ruleName;
|
||||
}
|
||||
|
||||
+23
-7
@@ -17,19 +17,35 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
package com.sk89q.worldguard.blacklist.event;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.target.Target;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
class BlockStateAsBlockFunction implements Function<BlockState, Block> {
|
||||
public final class ItemEquipBlacklistEvent extends ItemBlacklistEvent {
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param player The player associated with this event
|
||||
* @param position The position the event occurred at
|
||||
* @param target The target of the event
|
||||
*/
|
||||
public ItemEquipBlacklistEvent(@Nullable LocalPlayer player, BlockVector3 position, Target target) {
|
||||
super(player, position, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block apply(@Nullable BlockState blockState) {
|
||||
return blockState != null ? blockState.getBlock() : null;
|
||||
public String getDescription() {
|
||||
return "equip";
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventType getEventType() {
|
||||
return EventType.EQUIP;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,9 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Command-related utility methods.
|
||||
@@ -76,7 +78,12 @@ public final class CommandUtils {
|
||||
str = str.replace("`x", "&r");
|
||||
|
||||
// MC classic
|
||||
str = LegacyComponentSerializer.INSTANCE.serialize(LegacyComponentSerializer.INSTANCE.deserialize(str, '&'));
|
||||
// FIXME: workaround for https://github.com/KyoriPowered/text/issues/50
|
||||
// remove when fixed upstream and updated in WorldEdit
|
||||
str = Arrays.stream(str.split("\n")).map(line -> {
|
||||
TextComponent comp = LegacyComponentSerializer.INSTANCE.deserialize(line, '&');
|
||||
return LegacyComponentSerializer.INSTANCE.serialize(comp);
|
||||
}).collect(Collectors.joining("\n"));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
+14
-8
@@ -52,12 +52,13 @@ import com.sk89q.worldguard.util.profiler.SamplerBuilder;
|
||||
import com.sk89q.worldguard.util.profiler.SamplerBuilder.Sampler;
|
||||
import com.sk89q.worldguard.util.profiler.ThreadIdFilter;
|
||||
import com.sk89q.worldguard.util.profiler.ThreadNameFilter;
|
||||
import com.sk89q.worldguard.util.report.ApplicableRegionsReport;
|
||||
import com.sk89q.worldguard.util.report.ConfigReport;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
@@ -130,11 +131,14 @@ public class WorldGuardCommands {
|
||||
worldGuard.getPlatform().addPlatformReports(report);
|
||||
report.add(new SystemInfoReport());
|
||||
report.add(new ConfigReport());
|
||||
if (sender instanceof LocalPlayer) {
|
||||
report.add(new ApplicableRegionsReport((LocalPlayer) sender));
|
||||
}
|
||||
String result = report.toString();
|
||||
|
||||
try {
|
||||
File dest = new File(worldGuard.getPlatform().getConfigDir().toFile(), "report.txt");
|
||||
Files.write(result, dest, Charset.forName("UTF-8"));
|
||||
Files.write(result, dest, StandardCharsets.UTF_8);
|
||||
sender.print("WorldGuard report written to " + dest.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("Failed to write report: " + e.getMessage());
|
||||
@@ -196,7 +200,7 @@ public class WorldGuardCommands {
|
||||
|
||||
synchronized (this) {
|
||||
if (activeSampler != null) {
|
||||
throw new CommandException("A profile is currently in progress! Please use /wg stopprofile to stop the current profile.");
|
||||
throw new CommandException("A profile is currently in progress! Please use /wg stopprofile to cancel the current profile.");
|
||||
}
|
||||
|
||||
SamplerBuilder builder = new SamplerBuilder();
|
||||
@@ -206,10 +210,12 @@ public class WorldGuardCommands {
|
||||
sampler = activeSampler = builder.start();
|
||||
}
|
||||
|
||||
sender.print(TextComponent.of("Starting CPU profiling. Use ", TextColor.LIGHT_PURPLE)
|
||||
sender.print(TextComponent.of("Starting CPU profiling. Results will be available in " + minutes + " minutes.", TextColor.LIGHT_PURPLE)
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("Use ", TextColor.GRAY))
|
||||
.append(TextComponent.of("/wg stopprofile", TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/wg stopprofile")))
|
||||
.append(TextComponent.of(" to stop profiling.", TextColor.LIGHT_PURPLE)));
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/wg stopprofile")))
|
||||
.append(TextComponent.of(" at any time to cancel CPU profiling.", TextColor.GRAY)));
|
||||
|
||||
worldGuard.getSupervisor().monitor(FutureForwardingTask.create(
|
||||
sampler.getFuture(), "CPU profiling for " + minutes + " minutes", sender));
|
||||
@@ -227,7 +233,7 @@ public class WorldGuardCommands {
|
||||
|
||||
try {
|
||||
File dest = new File(worldGuard.getPlatform().getConfigDir().toFile(), "profile.txt");
|
||||
Files.write(output, dest, Charset.forName("UTF-8"));
|
||||
Files.write(output, dest, StandardCharsets.UTF_8);
|
||||
sender.print("CPU profiling data written to " + dest.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
sender.printError("Failed to write CPU profiling data: " + e.getMessage());
|
||||
@@ -256,7 +262,7 @@ public class WorldGuardCommands {
|
||||
activeSampler = null;
|
||||
}
|
||||
|
||||
sender.print("The running CPU profile has been stopped.");
|
||||
sender.print("The running CPU profile has been cancelled.");
|
||||
}
|
||||
|
||||
@Command(aliases = {"flushstates", "clearstates"},
|
||||
|
||||
+25
-29
@@ -38,11 +38,10 @@ import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
|
||||
import com.sk89q.worldguard.protection.flags.BooleanFlag;
|
||||
import com.sk89q.worldguard.protection.flags.DoubleFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.IntegerFlag;
|
||||
import com.sk89q.worldguard.protection.flags.LocationFlag;
|
||||
import com.sk89q.worldguard.protection.flags.NumberFlag;
|
||||
import com.sk89q.worldguard.protection.flags.RegistryFlag;
|
||||
import com.sk89q.worldguard.protection.flags.SetFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
@@ -76,13 +75,15 @@ 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;
|
||||
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;
|
||||
private final RegionPermissionModel perms;
|
||||
private boolean monoSpace;
|
||||
|
||||
FlagHelperBox(World world, ProtectedRegion region, RegionPermissionModel perms) {
|
||||
super("Flags for " + region.getId(), "/rg flags -w " + world.getName() + " -p %page% " + region.getId());
|
||||
super("Flags for " + region.getId(), "/rg flags -w \"" + world.getName() + "\" -p %page% " + region.getId());
|
||||
this.world = world;
|
||||
this.region = region;
|
||||
this.perms = perms;
|
||||
@@ -114,25 +115,25 @@ class FlagHelperBox extends PaginationBox {
|
||||
|
||||
private void appendFlagName(TextComponent.Builder builder, Flag<?> flag, TextColor color) {
|
||||
final String name = flag.getName();
|
||||
int length = FlagFontInfo.getPxLength(name);
|
||||
int length = monoSpace ? name.length() : FlagFontInfo.getPxLength(name);
|
||||
builder.append(TextComponent.of(name, color));
|
||||
if (flag.usesMembershipAsDefault()) {
|
||||
builder.append(TextComponent.empty().append(TextComponent.of("*", TextColor.AQUA))
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("This is a special flag which defaults to allow for members, and deny for non-members"))));
|
||||
length += FlagFontInfo.getPxLength('*');
|
||||
length += monoSpace ? 1 : FlagFontInfo.getPxLength('*');
|
||||
}
|
||||
if (flag == Flags.PASSTHROUGH) {
|
||||
builder.append(TextComponent.empty().append(TextComponent.of("*", TextColor.AQUA))
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
|
||||
TextComponent.of("This is a special flag which overrides build checks. (Not movement related!)"))));
|
||||
length += FlagFontInfo.getPxLength('*');
|
||||
length += monoSpace ? 1 : FlagFontInfo.getPxLength('*');
|
||||
}
|
||||
int leftover = PAD_PX_SIZE - length;
|
||||
int leftover = (monoSpace ? PAD_PX_SIZE / 3 : PAD_PX_SIZE) - length;
|
||||
builder.append(TextComponent.space());
|
||||
leftover -= 4;
|
||||
if (leftover > 0) {
|
||||
builder.append(TextComponent.of(Strings.repeat(".", leftover / 2), TextColor.DARK_GRAY));
|
||||
builder.append(TextComponent.of(Strings.repeat(".", monoSpace ? leftover : leftover / 2), TextColor.DARK_GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,10 +150,8 @@ class FlagHelperBox extends PaginationBox {
|
||||
appendStringFlagValue(builder, ((StringFlag) flag));
|
||||
} else if (flag instanceof LocationFlag) {
|
||||
appendLocationFlagValue(builder, ((LocationFlag) flag));
|
||||
} else if (flag instanceof IntegerFlag) {
|
||||
appendNumericFlagValue(builder, (IntegerFlag) flag);
|
||||
} else if (flag instanceof DoubleFlag) {
|
||||
appendNumericFlagValue(builder, (DoubleFlag) flag);
|
||||
} else if (flag instanceof NumberFlag) {
|
||||
appendNumericFlagValue(builder, (NumberFlag<? extends Number>) flag);
|
||||
} else {
|
||||
String display = String.valueOf(region.getFlag(flag));
|
||||
if (display.length() > 23) {
|
||||
@@ -200,6 +199,12 @@ class FlagHelperBox extends PaginationBox {
|
||||
if (maySet) {
|
||||
if (isExplicitSet) {
|
||||
hoverTexts.add(TextComponent.of("Click to unset", TextColor.GOLD));
|
||||
} 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.")
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("(Hint: You do not need to set this to protect the region!)"))));
|
||||
} else {
|
||||
hoverTexts.add(TextComponent.of("Click to set", TextColor.GOLD));
|
||||
}
|
||||
@@ -221,7 +226,7 @@ class FlagHelperBox extends PaginationBox {
|
||||
HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hoverBuilder.build()));
|
||||
}
|
||||
|
||||
if (maySet) {
|
||||
if (maySet && (isExplicitSet || !DANGER_ZONE.contains(flag))) {
|
||||
builder.append(choiceComponent.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
makeCommand(flag, isExplicitSet ? "" : choice))));
|
||||
} else {
|
||||
@@ -296,7 +301,7 @@ class FlagHelperBox extends PaginationBox {
|
||||
}
|
||||
|
||||
private String makeCommand(Flag<?> flag, Object choice) {
|
||||
return "/rg flag -w " + world.getName() + " -h " + getCurrentPage()
|
||||
return "/rg flag -w \"" + world.getName() + "\" -h " + getCurrentPage()
|
||||
+ " " + region.getId() + " " + flag.getName() + " " + choice;
|
||||
}
|
||||
|
||||
@@ -397,13 +402,13 @@ class FlagHelperBox extends PaginationBox {
|
||||
}
|
||||
}
|
||||
|
||||
private <V extends Number> void appendNumericFlagValue(TextComponent.Builder builder, Flag<V> flag) {
|
||||
private <V extends Number> void appendNumericFlagValue(TextComponent.Builder builder, NumberFlag<V> flag) {
|
||||
Number currVal = region.getFlag(flag);
|
||||
if (currVal == null) {
|
||||
currVal = getInheritedValue(region, flag);
|
||||
}
|
||||
Number defVal = flag.getDefault();
|
||||
Number[] suggested = getSuggestedNumbers(flag);
|
||||
Number[] suggested = flag.getSuggestedValues();
|
||||
SortedSet<Number> choices = new TreeSet<>(Comparator.comparing(Number::doubleValue));
|
||||
if (currVal != null) {
|
||||
choices.add(currVal);
|
||||
@@ -418,19 +423,6 @@ class FlagHelperBox extends PaginationBox {
|
||||
appendValueChoices(builder, flag, (Iterator<V>) choices.iterator(), choices.isEmpty() ? "unset number" : "[custom]");
|
||||
}
|
||||
|
||||
private Number[] getSuggestedNumbers(Flag<? extends Number> flag) {
|
||||
if (flag == Flags.HEAL_AMOUNT || flag == Flags.FEED_AMOUNT) {
|
||||
return new Number[]{0, 5, 10, 20};
|
||||
} else if (flag == Flags.MIN_FOOD || flag == Flags.MIN_HEAL) {
|
||||
return new Number[]{0, 10};
|
||||
} else if (flag == Flags.MAX_FOOD || flag == Flags.MAX_HEAL) {
|
||||
return new Number[]{10, 20};
|
||||
} else if (flag == Flags.HEAL_DELAY || flag == Flags.FEED_DELAY) {
|
||||
return new Number[]{0, 1, 5};
|
||||
}
|
||||
return new Number[0];
|
||||
}
|
||||
|
||||
private void appendStringFlagValue(TextComponent.Builder builder, StringFlag flag) {
|
||||
String currVal = region.getFlag(flag);
|
||||
if (currVal == null) {
|
||||
@@ -479,6 +471,10 @@ class FlagHelperBox extends PaginationBox {
|
||||
}
|
||||
}
|
||||
|
||||
void tryMonoSpacing() {
|
||||
this.monoSpace = true;
|
||||
}
|
||||
|
||||
private static final class FlagFontInfo {
|
||||
static int getPxLength(char c) {
|
||||
switch (c) {
|
||||
|
||||
+38
-27
@@ -82,41 +82,19 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
flags = "nw:",
|
||||
desc = "Add an owner to a region",
|
||||
min = 2)
|
||||
public void addOwner(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
|
||||
public void addOwner(CommandContext args, Actor sender) throws CommandException {
|
||||
warnAboutSaveFailures(sender);
|
||||
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
|
||||
LocalPlayer player = null;
|
||||
if (sender instanceof LocalPlayer) {
|
||||
player = (LocalPlayer) sender;
|
||||
}
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion region = checkExistingRegion(manager, id, true);
|
||||
|
||||
id = region.getId();
|
||||
|
||||
DefaultDomain owners = region.getOwners();
|
||||
|
||||
if (player != null) {
|
||||
if (owners != null && owners.size() == 0) {
|
||||
if (!sender.hasPermission("worldguard.region.unlimited")) {
|
||||
int maxRegionCount = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).getMaxRegionCount(player);
|
||||
if (maxRegionCount >= 0 && manager.getRegionCountOfPlayer(player)
|
||||
>= maxRegionCount) {
|
||||
throw new CommandException("You already own the maximum allowed amount of regions.");
|
||||
}
|
||||
}
|
||||
sender.checkPermission("worldguard.region.addowner.unclaimed." + id.toLowerCase());
|
||||
} else {
|
||||
// Check permissions
|
||||
if (!getPermissionModel(player).mayAddOwners(region)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
}
|
||||
// Check permissions
|
||||
if (!getPermissionModel(sender).mayAddOwners(region)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
// Resolve owners asynchronously
|
||||
@@ -126,13 +104,46 @@ public class MemberCommands extends RegionCommandsBase {
|
||||
|
||||
|
||||
final String description = String.format("Adding owners to the region '%s' on '%s'", region.getId(), world.getName());
|
||||
AsyncCommandBuilder.wrap(resolver, sender)
|
||||
AsyncCommandBuilder.wrap(checkedAddOwners(sender, manager, region, world, resolver), sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.onSuccess(String.format("Region '%s' updated with new owners.", region.getId()), region.getOwners()::addAll)
|
||||
.onFailure("Failed to add new owners", worldGuard.getExceptionConverter())
|
||||
.buildAndExec(worldGuard.getExecutorService());
|
||||
}
|
||||
|
||||
private static Callable<DefaultDomain> checkedAddOwners(Actor sender, RegionManager manager, ProtectedRegion region,
|
||||
World world, DomainInputResolver resolver) {
|
||||
return () -> {
|
||||
DefaultDomain owners = resolver.call();
|
||||
// TODO this was always broken and never checked other players
|
||||
if (sender instanceof LocalPlayer) {
|
||||
LocalPlayer player = (LocalPlayer) sender;
|
||||
if (owners.contains(player) && !sender.hasPermission("worldguard.region.unlimited")) {
|
||||
int maxRegionCount = WorldGuard.getInstance().getPlatform().getGlobalStateManager()
|
||||
.get(world).getMaxRegionCount(player);
|
||||
if (maxRegionCount >= 0 && manager.getRegionCountOfPlayer(player)
|
||||
>= maxRegionCount) {
|
||||
throw new CommandException("You already own the maximum allowed amount of regions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (region.getOwners().size() == 0) {
|
||||
boolean anyOwners = false;
|
||||
ProtectedRegion parent = region;
|
||||
while ((parent = parent.getParent()) != null) {
|
||||
if (parent.getOwners().size() > 0) {
|
||||
anyOwners = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!anyOwners) {
|
||||
sender.checkPermission("worldguard.region.addowner.unclaimed." + region.getId().toLowerCase());
|
||||
}
|
||||
}
|
||||
return owners;
|
||||
};
|
||||
}
|
||||
|
||||
@Command(aliases = {"removemember", "remmember", "removemem", "remmem", "rm"},
|
||||
usage = "<id> <owners...>",
|
||||
flags = "naw:",
|
||||
|
||||
+189
-104
@@ -25,6 +25,7 @@ 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;
|
||||
@@ -43,7 +44,6 @@ import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
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;
|
||||
@@ -73,12 +73,14 @@ 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.session.Session;
|
||||
import com.sk89q.worldguard.util.Enums;
|
||||
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -95,7 +97,29 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
checkNotNull(worldGuard);
|
||||
this.worldGuard = worldGuard;
|
||||
}
|
||||
|
||||
|
||||
private static TextComponent passthroughFlagWarning = TextComponent.empty()
|
||||
.append(TextComponent.of("WARNING:", TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(ErrorFormat.wrap(" This flag is unrelated to moving through regions."))
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("It overrides build checks. If you're unsure what this means, see ")
|
||||
.append(TextComponent.of("[this documentation page]", TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.OPEN_URL,
|
||||
"https://worldguard.enginehub.org/en/latest/regions/flags/#overrides")))
|
||||
.append(TextComponent.of(" for more info.")));
|
||||
private static TextComponent buildFlagWarning = TextComponent.empty()
|
||||
.append(TextComponent.of("WARNING:", TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(ErrorFormat.wrap(" Setting this flag is not required for protection."))
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("Setting this flag will completely override default protection, and apply" +
|
||||
" to members, non-members, pistons, sand physics, and everything else that can modify blocks."))
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("Only set this flag if you are sure you know what you are doing. See ")
|
||||
.append(TextComponent.of("[this documentation page]", TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.OPEN_URL,
|
||||
"https://worldguard.enginehub.org/en/latest/regions/flags/#protection-related")))
|
||||
.append(TextComponent.of(" for more info.")));
|
||||
|
||||
/**
|
||||
* Defines a new region.
|
||||
*
|
||||
@@ -104,22 +128,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);
|
||||
|
||||
@@ -128,9 +152,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
if (args.hasFlag('g')) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
region = checkRegionFromSelection(player, id);
|
||||
warnAboutDimensions(player, region);
|
||||
informNewUser(player, manager, region);
|
||||
region = checkRegionFromSelection(sender, id);
|
||||
}
|
||||
|
||||
RegionAdder task = new RegionAdder(manager, region);
|
||||
@@ -139,8 +161,14 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
final String description = String.format("Adding region '%s'", region.getId());
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.onSuccess(String.format("A new region has been made named '%s'.", region.getId()), null)
|
||||
.onFailure("Failed to add the region '%s'", worldGuard.getExceptionConverter())
|
||||
.onSuccess((Component) null,
|
||||
t -> {
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -152,23 +180,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();
|
||||
}
|
||||
|
||||
@@ -177,9 +204,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
if (args.hasFlag('g')) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
region = checkRegionFromSelection(player, id);
|
||||
warnAboutDimensions(player, region);
|
||||
informNewUser(player, manager, region);
|
||||
region = checkRegionFromSelection(sender, id);
|
||||
}
|
||||
|
||||
region.copyFrom(existing);
|
||||
@@ -190,7 +215,13 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(worldGuard.getSupervisor(), description)
|
||||
.sendMessageAfterDelay("(Please wait... " + description + ")")
|
||||
.onSuccess(String.format("Region '%s' has been updated with a new area.", region.getId()), null)
|
||||
.onSuccess((Component) null,
|
||||
t -> {
|
||||
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());
|
||||
}
|
||||
@@ -303,28 +334,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,7 +392,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
}
|
||||
|
||||
existing = checkRegionStandingIn(manager, (LocalPlayer) sender, true,
|
||||
"/rg info -w " + world.getName() + " %id%" + (args.hasFlag('u') ? " -u" : "") + (args.hasFlag('s') ? " -s" : ""));
|
||||
"/rg info -w \"" + world.getName() + "\" %id%" + (args.hasFlag('u') ? " -u" : "") + (args.hasFlag('s') ? " -s" : ""));
|
||||
} else { // Get region from the ID
|
||||
existing = checkExistingRegion(manager, args.getString(0), true);
|
||||
}
|
||||
@@ -372,7 +409,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
|
||||
setPlayerSelection(worldGuard.checkPlayer(sender), existing);
|
||||
setPlayerSelection(worldGuard.checkPlayer(sender), existing, world);
|
||||
}
|
||||
|
||||
// Print region information
|
||||
@@ -382,7 +419,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());
|
||||
}
|
||||
@@ -471,11 +511,6 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
value = "";
|
||||
}
|
||||
|
||||
// Add color codes
|
||||
if (value != null) {
|
||||
value = CommandUtils.replaceColorMacros(value);
|
||||
}
|
||||
|
||||
// Lookup the existing region
|
||||
RegionManager manager = checkRegionManager(world);
|
||||
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
|
||||
@@ -484,77 +519,30 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
if (!permModel.maySetFlag(existing)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
String regionId = existing.getId();
|
||||
|
||||
Flag<?> foundFlag = Flags.fuzzyMatchFlag(flagRegistry, flagName);
|
||||
|
||||
// We didn't find the flag, so let's print a list of flags that the user
|
||||
// can use, and do nothing afterwards
|
||||
if (foundFlag == null) {
|
||||
ArrayList<String> flagList = new ArrayList<>();
|
||||
|
||||
// Need to build a list
|
||||
for (Flag<?> flag : flagRegistry) {
|
||||
// Can the user set this flag?
|
||||
if (!permModel.maySetFlag(existing, flag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
flagList.add(flag.getName());
|
||||
}
|
||||
|
||||
Collections.sort(flagList);
|
||||
|
||||
final TextComponent.Builder builder = TextComponent.builder("Available flags: ");
|
||||
|
||||
final HoverEvent clickToSet = HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set"));
|
||||
for (int i = 0; i < flagList.size(); i++) {
|
||||
String flag = flagList.get(i);
|
||||
|
||||
builder.append(TextComponent.of(flag, i % 2 == 0 ? TextColor.GRAY : TextColor.WHITE)
|
||||
.hoverEvent(clickToSet).clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
"/rg flag -w " + world.getName() + " " + existing.getId() + " " + flag + " ")));
|
||||
if (i < flagList.size() + 1) {
|
||||
builder.append(TextComponent.of(", "));
|
||||
}
|
||||
}
|
||||
|
||||
sender.printError("Unknown flag specified: " + flagName);
|
||||
sender.print(builder.build());
|
||||
if (sender.isPlayer()) {
|
||||
sender.print(TextComponent.of("Or use the command ", TextColor.LIGHT_PURPLE)
|
||||
.append(TextComponent.of("/rg flags " + existing.getId(), TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg flags -w " + world.getName() + " " + existing.getId()))));
|
||||
}
|
||||
|
||||
AsyncCommandBuilder.wrap(new FlagListBuilder(flagRegistry, permModel, existing, world,
|
||||
regionId, sender, flagName), sender)
|
||||
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Flag list for invalid flag command.")
|
||||
.onSuccess((Component) null, sender::print)
|
||||
.onFailure((Component) null, WorldGuard.getInstance().getExceptionConverter())
|
||||
.buildAndExec(WorldGuard.getInstance().getExecutorService());
|
||||
return;
|
||||
} else if (value != null) {
|
||||
if (foundFlag == Flags.BUILD || foundFlag == Flags.BLOCK_BREAK || foundFlag == Flags.BLOCK_PLACE) {
|
||||
sender.print(TextComponent.empty().append(TextComponent.of("WARNING:", TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(ErrorFormat.wrap(" Setting the " + foundFlag.getName() + " flag is not required for protection."))
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("Setting this flag will completely override default protection, and apply" +
|
||||
" to members, non-members, pistons, and everything else that can modify blocks."))
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("Only set this flag if you are sure you know what you are doing. See ")
|
||||
.append(TextComponent.of("[this documentation page]", TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.OPEN_URL,
|
||||
"https://worldguard.readthedocs.io/en/latest/regions/flags/#protection-related")))
|
||||
.append(TextComponent.of(" for more info."))));
|
||||
sender.print(buildFlagWarning);
|
||||
if (!sender.isPlayer()) {
|
||||
sender.printRaw("https://worldguard.readthedocs.io/en/latest/regions/flags/#protection-related");
|
||||
sender.printRaw("https://worldguard.enginehub.org/en/latest/regions/flags/#protection-related");
|
||||
}
|
||||
} else if (foundFlag == Flags.PASSTHROUGH) {
|
||||
sender.print(TextComponent.empty().append(TextComponent.of("WARNING:", TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(ErrorFormat.wrap(" This flag is unrelated to moving through regions."))
|
||||
.append(TextComponent.newline())
|
||||
.append(TextComponent.of("It overrides build checks. If you're unsure what this means, see ")
|
||||
.append(TextComponent.of("[this documentation page]", TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.OPEN_URL,
|
||||
"https://worldguard.readthedocs.io/en/latest/regions/flags/#overrides")))
|
||||
.append(TextComponent.of(" for more info."))));
|
||||
sender.print(passthroughFlagWarning);
|
||||
if (!sender.isPlayer()) {
|
||||
sender.printRaw("https://worldguard.readthedocs.io/en/latest/regions/flags/#overrides");
|
||||
sender.printRaw("https://worldguard.enginehub.org/en/latest/regions/flags/#overrides");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,13 +578,13 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
if (value != null) {
|
||||
// Set the flag if [value] was given even if [-g group] was given as well
|
||||
try {
|
||||
setFlag(existing, foundFlag, sender, value);
|
||||
value = setFlag(existing, foundFlag, sender, value).toString();
|
||||
} catch (InvalidFlagFormat e) {
|
||||
throw new CommandException(e.getMessage());
|
||||
}
|
||||
|
||||
if (!args.hasFlag('h')) {
|
||||
sender.print("Region flag " + foundFlag.getName() + " set on '" + existing.getId() + "' to '" + value + "'.");
|
||||
sender.print("Region flag " + foundFlag.getName() + " set on '" + regionId + "' to '" + value + "'.");
|
||||
}
|
||||
|
||||
// No value? Clear the flag, if -g isn't specified
|
||||
@@ -611,7 +599,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
}
|
||||
|
||||
if (!args.hasFlag('h')) {
|
||||
sender.print("Region flag " + foundFlag.getName() + " removed from '" + existing.getId() + "'. (Any -g(roups) were also removed.)");
|
||||
sender.print("Region flag " + foundFlag.getName() + " removed from '" + regionId + "'. (Any -g(roups) were also removed.)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,6 +627,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
printout.appendFlagsList(false);
|
||||
printout.append(SubtleFormat.wrap(")"));
|
||||
printout.send(sender);
|
||||
checkSpawnOverlap(sender, world, existing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,11 +644,11 @@ 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,
|
||||
"/rg flags -w " + world.getName() + " %id%");
|
||||
"/rg flags -w \"" + world.getName() + "\" %id%");
|
||||
} else { // Get region from the ID
|
||||
region = checkExistingRegion(manager, args.getString(0), true);
|
||||
}
|
||||
@@ -676,7 +665,15 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
private static void sendFlagHelper(Actor sender, World world, ProtectedRegion region, RegionPermissionModel perms, int page) {
|
||||
final FlagHelperBox flagHelperBox = new FlagHelperBox(world, region, perms);
|
||||
flagHelperBox.setComponentsPerPage(18);
|
||||
AsyncCommandBuilder.wrap(() -> flagHelperBox.create(page), sender)
|
||||
if (!sender.isPlayer()) {
|
||||
flagHelperBox.tryMonoSpacing();
|
||||
}
|
||||
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());
|
||||
@@ -712,6 +709,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -766,7 +764,7 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
|
||||
// Tell the user the current inheritance
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), child, null, sender);
|
||||
printout.append(LabelFormat.wrap("Inheritance set for region '", child.getId(), "'."));
|
||||
printout.append(TextComponent.of("Inheritance set for region '" + child.getId() + "'.", TextColor.LIGHT_PURPLE));
|
||||
if (parent != null) {
|
||||
printout.newline();
|
||||
printout.append(SubtleFormat.wrap("(Current inheritance:")).newline();
|
||||
@@ -1112,7 +1110,94 @@ public final class RegionCommands extends RegionCommandsBase {
|
||||
}
|
||||
}
|
||||
|
||||
player.setLocation(teleportLocation);
|
||||
sender.print("Teleported you to the region '" + existing.getId() + "'.");
|
||||
String message = existing.getFlag(Flags.TELE_MESSAGE);
|
||||
|
||||
// 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,
|
||||
message.replace("%id%", existing.getId()),
|
||||
"Unable to teleport to region '" + existing.getId() + "'.");
|
||||
}
|
||||
|
||||
@Command(aliases = {"toggle-bypass", "bypass"},
|
||||
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);
|
||||
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
|
||||
if (session.hasBypassDisabled()) {
|
||||
session.setBypassDisabled(false);
|
||||
player.print("You are now bypassing region protection (as long as you have permission).");
|
||||
} else {
|
||||
session.setBypassDisabled(true);
|
||||
player.print("You are no longer bypassing region protection.");
|
||||
}
|
||||
}
|
||||
|
||||
private static class FlagListBuilder implements Callable<Component> {
|
||||
private final FlagRegistry flagRegistry;
|
||||
private final RegionPermissionModel permModel;
|
||||
private final ProtectedRegion existing;
|
||||
private final World world;
|
||||
private final String regionId;
|
||||
private final Actor sender;
|
||||
private final String flagName;
|
||||
|
||||
FlagListBuilder(FlagRegistry flagRegistry, RegionPermissionModel permModel, ProtectedRegion existing,
|
||||
World world, String regionId, Actor sender, String flagName) {
|
||||
this.flagRegistry = flagRegistry;
|
||||
this.permModel = permModel;
|
||||
this.existing = existing;
|
||||
this.world = world;
|
||||
this.regionId = regionId;
|
||||
this.sender = sender;
|
||||
this.flagName = flagName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component call() {
|
||||
ArrayList<String> flagList = new ArrayList<>();
|
||||
|
||||
// Need to build a list
|
||||
for (Flag<?> flag : flagRegistry) {
|
||||
// Can the user set this flag?
|
||||
if (!permModel.maySetFlag(existing, flag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
flagList.add(flag.getName());
|
||||
}
|
||||
|
||||
Collections.sort(flagList);
|
||||
|
||||
final TextComponent.Builder builder = TextComponent.builder("Available flags: ");
|
||||
|
||||
final HoverEvent clickToSet = HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set"));
|
||||
for (int i = 0; i < flagList.size(); i++) {
|
||||
String flag = flagList.get(i);
|
||||
|
||||
builder.append(TextComponent.of(flag, i % 2 == 0 ? TextColor.GRAY : TextColor.WHITE)
|
||||
.hoverEvent(clickToSet).clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
"/rg flag -w \"" + world.getName() + "\" " + regionId + " " + flag + " ")));
|
||||
if (i < flagList.size() + 1) {
|
||||
builder.append(TextComponent.of(", "));
|
||||
}
|
||||
}
|
||||
|
||||
Component ret = ErrorFormat.wrap("Unknown flag specified: " + flagName)
|
||||
.append(TextComponent.newline())
|
||||
.append(builder.build());
|
||||
if (sender.isPlayer()) {
|
||||
return ret.append(TextComponent.of("Or use the command ", TextColor.LIGHT_PURPLE)
|
||||
.append(TextComponent.of("/rg flags " + regionId, TextColor.AQUA)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg flags -w \"" + world.getName() + "\" " + regionId))));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
-45
@@ -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,13 +31,16 @@ 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.RegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
|
||||
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;
|
||||
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.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
@@ -51,6 +55,7 @@ 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.util.WorldEditRegionConverter;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -81,9 +86,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 {
|
||||
@@ -216,21 +237,24 @@ class RegionCommandsBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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! " +
|
||||
"(wiki: http://wiki.sk89q.com/wiki/WorldEdit).");
|
||||
throw new CommandException("Please select an area first. " +
|
||||
"Use WorldEdit to make a selection! " +
|
||||
"(see: https://worldedit.enginehub.org/en/latest/usage/regions/selections/).");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +278,7 @@ class RegionCommandsBase {
|
||||
* @param world the world
|
||||
* @throws CommandException thrown if the manager is null
|
||||
*/
|
||||
protected static RegionManager checkRegionManager(com.sk89q.worldedit.world.World world) throws CommandException {
|
||||
protected static RegionManager checkRegionManager(World world) throws CommandException {
|
||||
if (!WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).useRegions) {
|
||||
throw new CommandException("Region support is disabled in the target world. " +
|
||||
"It can be enabled per-world in WorldGuard's configuration files. " +
|
||||
@@ -270,15 +294,15 @@ 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) {
|
||||
@@ -320,6 +344,9 @@ class RegionCommandsBase {
|
||||
* @param region the region
|
||||
*/
|
||||
protected static void warnAboutDimensions(Actor sender, ProtectedRegion region) {
|
||||
if (region instanceof GlobalProtectedRegion) {
|
||||
return;
|
||||
}
|
||||
int height = region.getMaximumPoint().getBlockY() - region.getMinimumPoint().getBlockY();
|
||||
if (height <= 2) {
|
||||
sender.printDebug("(Warning: The height of the region was " + (height + 1) + " block(s).)");
|
||||
@@ -334,7 +361,7 @@ class RegionCommandsBase {
|
||||
* @param region the region
|
||||
*/
|
||||
protected static void informNewUser(Actor sender, RegionManager manager, ProtectedRegion region) {
|
||||
if (manager.getRegions().size() <= 2) {
|
||||
if (manager.size() <= 2) {
|
||||
sender.print(SubtleFormat.wrap("(This region is NOW PROTECTED from modification from others. Don't want that? Use ")
|
||||
.append(TextComponent.of("/rg flag " + region.getId() + " passthrough allow", TextColor.AQUA))
|
||||
.append(TextComponent.of(")", TextColor.GRAY)));
|
||||
@@ -342,41 +369,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();
|
||||
|
||||
session.setRegionSelector(player.getWorld(), new CuboidRegionSelector(player.getWorld(), pt1, pt2));
|
||||
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);
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,8 +419,10 @@ class RegionCommandsBase {
|
||||
* @param value the value
|
||||
* @throws InvalidFlagFormat thrown if the value is invalid
|
||||
*/
|
||||
protected static <V> void setFlag(ProtectedRegion region, Flag<V> flag, Actor sender, String value) throws InvalidFlagFormat {
|
||||
region.setFlag(flag, flag.parseInput(FlagContext.create().setSender(sender).setInput(value).setObject("region", region).build()));
|
||||
protected static <V> V setFlag(ProtectedRegion region, Flag<V> flag, Actor sender, String value) throws InvalidFlagFormat {
|
||||
V val = flag.parseInput(FlagContext.create().setSender(sender).setInput(value).setObject("region", region).build());
|
||||
region.setFlag(flag, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
}
|
||||
+31
-17
@@ -19,7 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.commands.region;
|
||||
|
||||
import com.sk89q.squirrelid.cache.ProfileCache;
|
||||
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;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
@@ -86,7 +87,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
public void appendBasics() {
|
||||
builder.append(TextComponent.of("Region: ", TextColor.BLUE));
|
||||
builder.append(TextComponent.of(region.getId(), TextColor.YELLOW)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg info -w " + world + " " + region.getId())));
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg info -w \"" + world + "\" " + region.getId())));
|
||||
|
||||
builder.append(TextComponent.of(" (type=", TextColor.GRAY));
|
||||
builder.append(TextComponent.of(region.getType().getName()));
|
||||
@@ -143,12 +144,26 @@ 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,
|
||||
"/rg flag -w " + world + " " + region.getId() + " " + flag.getName() + " "));
|
||||
"/rg flag -w \"" + world + "\" " + region.getId() + " " + flag.getName() + " "));
|
||||
}
|
||||
builder.append(flagText);
|
||||
|
||||
@@ -164,7 +179,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
builder.append(TextComponent.space())
|
||||
.append(TextComponent.of("[Flags]", useColors ? TextColor.GREEN : TextColor.GRAY)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set a flag")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg flags -w " + world + " " + region.getId())));
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg flags -w \"" + world + "\" " + region.getId())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +232,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
if (perms != null && perms.mayLookup(cur)) {
|
||||
builder.append(TextComponent.of(cur.getId(), useColors ? TextColor.GREEN : TextColor.WHITE)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click for info")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg info -w " + world + " " + cur.getId())));
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg info -w \"" + world + "\" " + cur.getId())));
|
||||
} else {
|
||||
builder.append(TextComponent.of(cur.getId(), useColors ? TextColor.GREEN : TextColor.WHITE));
|
||||
}
|
||||
@@ -232,7 +247,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
builder.append(TextComponent.space());
|
||||
builder.append(TextComponent.of("[X]", TextColor.RED)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to unlink parent")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/rg setparent -w " + world + " " + cur.getId())));
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/rg setparent -w \"" + world + "\" " + cur.getId())));
|
||||
}
|
||||
|
||||
last = cur;
|
||||
@@ -272,17 +287,17 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[Add]", TextColor.GREEN)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to add a player or group")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
"/rg " + addCommand + " -w " + world + " " + region.getId() + " "))));
|
||||
"/rg " + addCommand + " -w \"" + world + "\" " + region.getId() + " "))));
|
||||
}
|
||||
if (removeCommand != null && domain.size() > 0) {
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[Rem]", TextColor.RED)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to remove a player or group")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
"/rg " + removeCommand + " -w " + world + " " + region.getId() + " "))));
|
||||
"/rg " + removeCommand + " -w \"" + world + "\" " + region.getId() + " "))));
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[Clr]", TextColor.RED)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to clear")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
|
||||
"/rg " + removeCommand + " -w " + world + " -a " + region.getId()))));
|
||||
"/rg " + removeCommand + " -w \"" + world + "\" -a " + region.getId()))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,8 +308,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
BlockVector3 min = region.getMinimumPoint();
|
||||
BlockVector3 max = region.getMaximumPoint();
|
||||
builder.append(TextComponent.of("Bounds:", TextColor.BLUE));
|
||||
TextComponent bound = TextComponent.of(" (" + min.getBlockX() + "," + min.getBlockY() + "," + min.getBlockZ() + ")"
|
||||
+ " -> (" + max.getBlockX() + "," + max.getBlockY() + "," + max.getBlockZ() + ")", TextColor.YELLOW);
|
||||
TextComponent bound = TextComponent.of(" " + min + " -> " + max, TextColor.YELLOW);
|
||||
if (perms != null && perms.maySelect(region)) {
|
||||
bound = bound
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to select")))
|
||||
@@ -302,15 +316,15 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
}
|
||||
builder.append(bound);
|
||||
final Location teleFlag = region.getFlag(Flags.TELE_LOC);
|
||||
if (perms != null && perms.mayTeleportTo(region) && teleFlag != 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()))));
|
||||
"/rg tp -w \"" + world + "\" " + region.getId()))));
|
||||
}
|
||||
|
||||
newline();
|
||||
@@ -321,7 +335,7 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
|
||||
if (perms != null && perms.maySetPriority(rg)) {
|
||||
builder.append(TextComponent.of(content, TextColor.GOLD)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to change")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/rg setpriority -w " + world + " " + rg.getId() + " ")));
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/rg setpriority -w \"" + world + "\" " + rg.getId() + " ")));
|
||||
} else {
|
||||
builder.append(TextComponent.of(content, TextColor.WHITE));
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ package com.sk89q.worldguard.commands.task;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.squirrelid.Profile;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
@@ -33,6 +33,7 @@ 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.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
@@ -175,7 +176,7 @@ public class RegionLister implements Callable<Integer> {
|
||||
|
||||
RegionPermissionModel perms = sender.isPlayer() ? new RegionPermissionModel(sender) : null;
|
||||
String title = ownerMatcher == null ? "Regions" : "Regions for " + ownerMatcher.getName();
|
||||
String cmd = "/rg list -w " + world
|
||||
String cmd = "/rg list -w \"" + world + "\""
|
||||
+ (playerName != null ? " -p " + playerName : "")
|
||||
+ (nameOnly ? " -n" : "")
|
||||
+ " %page%";
|
||||
@@ -258,7 +259,13 @@ public class RegionLister implements Callable<Integer> {
|
||||
builder.append(TextComponent.space().append(TextComponent.of("[Info]", TextColor.GRAY)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click for info")))
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
|
||||
"/rg info -w " + world + " " + entry.region.getId()))));
|
||||
"/rg info -w \"" + world + "\" " + entry.region.getId()))));
|
||||
}
|
||||
if (perms != null && entry.region.getFlag(Flags.TELE_LOC) != 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()))));
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -19,15 +19,21 @@
|
||||
|
||||
package com.sk89q.worldguard.config;
|
||||
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.Blacklist;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -55,7 +61,8 @@ public abstract class WorldConfiguration {
|
||||
|
||||
protected File blacklistFile;
|
||||
|
||||
@Unreported protected Blacklist blacklist;
|
||||
@Unreported
|
||||
protected Blacklist blacklist;
|
||||
|
||||
public boolean boundedLocationFlags;
|
||||
public boolean useRegions;
|
||||
@@ -111,6 +118,7 @@ public abstract class WorldConfiguration {
|
||||
public boolean teleportOnSuffocation;
|
||||
public boolean disableVoidDamage;
|
||||
public boolean teleportOnVoid;
|
||||
public boolean safeFallOnVoid;
|
||||
public boolean disableExplosionDamage;
|
||||
public boolean disableMobDamage;
|
||||
public boolean highFreqFlags;
|
||||
@@ -127,6 +135,8 @@ public abstract class WorldConfiguration {
|
||||
public boolean removeInfiniteStacks;
|
||||
public boolean disableCreatureCropTrampling;
|
||||
public boolean disablePlayerCropTrampling;
|
||||
public boolean disableCreatureTurtleEggTrampling;
|
||||
public boolean disablePlayerTurtleEggTrampling;
|
||||
public boolean preventLightningFire;
|
||||
public Set<String> disallowedLightningBlocks;
|
||||
public boolean disableThunder;
|
||||
@@ -134,6 +144,7 @@ public abstract class WorldConfiguration {
|
||||
public boolean alwaysRaining;
|
||||
public boolean alwaysThundering;
|
||||
public boolean disablePigZap;
|
||||
public boolean disableVillagerZap;
|
||||
public boolean disableCreeperPower;
|
||||
public boolean disableHealthRegain;
|
||||
public boolean disableMushroomSpread;
|
||||
@@ -149,16 +160,20 @@ public abstract class WorldConfiguration {
|
||||
public boolean disableEndermanGriefing;
|
||||
public boolean disableSnowmanTrails;
|
||||
public boolean disableSoilDehydration;
|
||||
public boolean disableCoralBlockFade;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -171,49 +186,63 @@ public abstract class WorldConfiguration {
|
||||
}
|
||||
|
||||
public List<String> convertLegacyItems(List<String> legacyItems) {
|
||||
return legacyItems.stream().map(this::convertLegacyItem).collect(Collectors.toList());
|
||||
return legacyItems.stream().map(this::convertLegacyItem).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String convertLegacyItem(String legacy) {
|
||||
String item = legacy;
|
||||
String[] splitter = legacy.split(":", 2);
|
||||
try {
|
||||
String[] splitter = item.split(":", 2);
|
||||
int id = 0;
|
||||
byte data = 0;
|
||||
int id;
|
||||
byte data;
|
||||
if (splitter.length == 1) {
|
||||
id = Integer.parseInt(item);
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = 0;
|
||||
} else {
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = Byte.parseByte(splitter[1]);
|
||||
}
|
||||
item = LegacyMapper.getInstance().getItemFromLegacy(id, data).getId();
|
||||
} catch (Throwable e) {
|
||||
ItemType legacyItem = LegacyMapper.getInstance().getItemFromLegacy(id, data);
|
||||
if (legacyItem != null) {
|
||||
return legacyItem.getId();
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
final ItemType itemType = ItemTypes.get(legacy);
|
||||
if (itemType != null) {
|
||||
return itemType.getId();
|
||||
}
|
||||
|
||||
return item;
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> convertLegacyBlocks(List<String> legacyBlocks) {
|
||||
return legacyBlocks.stream().map(this::convertLegacyBlock).collect(Collectors.toList());
|
||||
return legacyBlocks.stream().map(this::convertLegacyBlock).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String convertLegacyBlock(String legacy) {
|
||||
String block = legacy;
|
||||
String[] splitter = legacy.split(":", 2);
|
||||
try {
|
||||
String[] splitter = block.split(":", 2);
|
||||
int id = 0;
|
||||
byte data = 0;
|
||||
int id;
|
||||
byte data;
|
||||
if (splitter.length == 1) {
|
||||
id = Integer.parseInt(block);
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = 0;
|
||||
} else {
|
||||
id = Integer.parseInt(splitter[0]);
|
||||
data = Byte.parseByte(splitter[1]);
|
||||
}
|
||||
block = LegacyMapper.getInstance().getBlockFromLegacy(id, data).getBlockType().getId();
|
||||
} catch (Throwable e) {
|
||||
BlockState legacyBlock = LegacyMapper.getInstance().getBlockFromLegacy(id, data);
|
||||
if (legacyBlock != null) {
|
||||
return legacyBlock.getBlockType().getId();
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
final BlockType blockType = BlockTypes.get(legacy);
|
||||
if (blockType != null) {
|
||||
return blockType.getId();
|
||||
}
|
||||
|
||||
return block;
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getMaxRegionCount(LocalPlayer player) {
|
||||
|
||||
+4
@@ -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);
|
||||
|
||||
@@ -22,8 +22,8 @@ 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.squirrelid.Profile;
|
||||
import com.sk89q.squirrelid.cache.ProfileCache;
|
||||
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;
|
||||
@@ -311,7 +311,7 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
||||
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(", ");
|
||||
@@ -373,7 +373,8 @@ public class DefaultDomain implements Domain, ChangeTracked {
|
||||
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(", "));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -152,7 +156,9 @@ public class PlayerDomain implements Domain, ChangeTracked {
|
||||
* 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);
|
||||
}
|
||||
|
||||
+7
@@ -23,6 +23,7 @@ import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
@@ -37,7 +38,13 @@ public class RegionPermissionModel extends AbstractPermissionModel {
|
||||
super(sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Check {@code WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(..)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean mayIgnoreRegionProtection(World world) {
|
||||
if (getSender() instanceof LocalPlayer)
|
||||
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass((LocalPlayer) getSender(), world);
|
||||
return hasPluginPermission("region.bypass." + world.getName());
|
||||
}
|
||||
|
||||
|
||||
+21
@@ -21,13 +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;
|
||||
|
||||
/**
|
||||
@@ -148,4 +153,20 @@ public interface WorldGuardPlatform {
|
||||
* @param report The reportlist
|
||||
*/
|
||||
void addPlatformReports(ReportList report);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -65,7 +65,7 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
|
||||
*
|
||||
* <p>{@code subject} can be non-null to satisfy region group requirements,
|
||||
* otherwise it will be assumed that the caller that is not a member of any
|
||||
* regions. (FlagUtil on a region can be changed so that they only apply
|
||||
* regions. (Flags on a region can be changed so that they only apply
|
||||
* to certain users.) The subject argument is required if the
|
||||
* {@link Flags#BUILD} flag is in the list of flags.</p>
|
||||
*
|
||||
@@ -83,7 +83,7 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
|
||||
*
|
||||
* <p>{@code subject} can be non-null to satisfy region group requirements,
|
||||
* otherwise it will be assumed that the caller that is not a member of any
|
||||
* regions. (FlagUtil on a region can be changed so that they only apply
|
||||
* regions. (Flags on a region can be changed so that they only apply
|
||||
* to certain users.) The subject argument is required if the
|
||||
* {@link Flags#BUILD} flag is in the list of flags.</p>
|
||||
*
|
||||
@@ -108,7 +108,7 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
|
||||
*
|
||||
* <p>{@code subject} can be non-null to satisfy region group requirements,
|
||||
* otherwise it will be assumed that the caller that is not a member of any
|
||||
* regions. (FlagUtil on a region can be changed so that they only apply
|
||||
* regions. (Flags on a region can be changed so that they only apply
|
||||
* to certain users.) The subject argument is required if the
|
||||
* {@link Flags#BUILD} flag is the flag being queried.</p>
|
||||
*
|
||||
@@ -126,7 +126,7 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
|
||||
*
|
||||
* <p>{@code subject} can be non-null to satisfy region group requirements,
|
||||
* otherwise it will be assumed that the caller that is not a member of any
|
||||
* regions. (FlagUtil on a region can be changed so that they only apply
|
||||
* regions. (Flags on a region can be changed so that they only apply
|
||||
* to certain users.) The subject argument is required if the
|
||||
* {@link Flags#BUILD} flag is the flag being queried.</p>
|
||||
*
|
||||
|
||||
+5
-36
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -361,7 +361,8 @@ public class FlagValueCalculator {
|
||||
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;
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.regions.ProtectedRegion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
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;
|
||||
|
||||
protected AbstractRegionOverlapAssociation(@Nullable Set<ProtectedRegion> source, boolean useMaxPriorityAssociation) {
|
||||
this.source = source;
|
||||
this.useMaxPriorityAssociation = useMaxPriorityAssociation;
|
||||
}
|
||||
|
||||
protected void calcMaxPriority() {
|
||||
checkNotNull(source);
|
||||
int best = 0;
|
||||
for (ProtectedRegion region : source) {
|
||||
int priority = region.getPriority();
|
||||
if (priority > best) {
|
||||
best = priority;
|
||||
}
|
||||
}
|
||||
this.maxPriority = best;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Association getAssociation(List<ProtectedRegion> regions) {
|
||||
checkNotNull(source);
|
||||
for (ProtectedRegion region : regions) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Association.NON_MEMBER;
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.worldedit.util.Location;
|
||||
import com.sk89q.worldguard.domains.Association;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Determines that the association to a region is {@code OWNER} if the input
|
||||
* region is in a set of source regions.
|
||||
*
|
||||
* <p>This class only performs a spatial query if its
|
||||
* {@link #getAssociation(List)} method is called.</p>
|
||||
*/
|
||||
public class DelayedRegionOverlapAssociation extends AbstractRegionOverlapAssociation {
|
||||
|
||||
private final RegionQuery query;
|
||||
private final Location location;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
* @param query the query
|
||||
* @param location the location
|
||||
*/
|
||||
public DelayedRegionOverlapAssociation(RegionQuery query, Location location) {
|
||||
this(query, location, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
* @param query the query
|
||||
* @param location the location
|
||||
* @param useMaxPriorityAssociation whether to use the max priority from regions to determine association
|
||||
*/
|
||||
public DelayedRegionOverlapAssociation(RegionQuery query, Location location, boolean useMaxPriorityAssociation) {
|
||||
super(null, useMaxPriorityAssociation);
|
||||
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();
|
||||
calcMaxPriority();
|
||||
}
|
||||
|
||||
return super.getAssociation(regions);
|
||||
}
|
||||
|
||||
}
|
||||
+13
-19
@@ -19,41 +19,35 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.association;
|
||||
|
||||
import com.sk89q.worldguard.domains.Association;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
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
|
||||
* region is in a set of source regions.
|
||||
*/
|
||||
public class RegionOverlapAssociation implements RegionAssociable {
|
||||
|
||||
private final Set<ProtectedRegion> source;
|
||||
public class RegionOverlapAssociation extends AbstractRegionOverlapAssociation {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param source set of regions that input regions must be contained within
|
||||
*/
|
||||
public RegionOverlapAssociation(Set<ProtectedRegion> source) {
|
||||
checkNotNull(source);
|
||||
this.source = source;
|
||||
public RegionOverlapAssociation(@Nonnull Set<ProtectedRegion> source) {
|
||||
this(source, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Association getAssociation(List<ProtectedRegion> regions) {
|
||||
for (ProtectedRegion region : regions) {
|
||||
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty()) || source.contains(region)) {
|
||||
return Association.OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
return Association.NON_MEMBER;
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param source set of regions that input regions must be contained within
|
||||
* @param useMaxPriorityAssociation whether to use the max priority from regions to determine association
|
||||
*/
|
||||
public RegionOverlapAssociation(@Nonnull Set<ProtectedRegion> source, boolean useMaxPriorityAssociation) {
|
||||
super(source, useMaxPriorityAssociation);
|
||||
calcMaxPriority();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ package com.sk89q.worldguard.protection.flags;
|
||||
/**
|
||||
* Stores doubles.
|
||||
*/
|
||||
public class DoubleFlag extends Flag<Double> {
|
||||
public class DoubleFlag extends NumberFlag<Double> {
|
||||
|
||||
public DoubleFlag(String name, RegionGroup defaultGroup) {
|
||||
super(name, defaultGroup);
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* The flags that are used in WorldGuard.
|
||||
@@ -59,6 +60,7 @@ public final class Flags {
|
||||
public static final StateFlag DAMAGE_ANIMALS = register(new StateFlag("damage-animals", false));
|
||||
public static final StateFlag PVP = register(new StateFlag("pvp", false));
|
||||
public static final StateFlag SLEEP = register(new StateFlag("sleep", false));
|
||||
public static final StateFlag RESPAWN_ANCHORS = register(new StateFlag("respawn-anchors", false));
|
||||
public static final StateFlag TNT = register(new StateFlag("tnt", false));
|
||||
public static final StateFlag CHEST_ACCESS = register(new StateFlag("chest-access", false));
|
||||
public static final StateFlag PLACE_VEHICLE = register(new StateFlag("vehicle-place", false));
|
||||
@@ -68,6 +70,7 @@ public final class Flags {
|
||||
public static final StateFlag POTION_SPLASH = register(new StateFlag("potion-splash", false));
|
||||
public static final StateFlag ITEM_FRAME_ROTATE = register(new StateFlag("item-frame-rotation", false));
|
||||
public static final StateFlag TRAMPLE_BLOCKS = register(new StateFlag("block-trampling", false));
|
||||
public static final StateFlag FIREWORK_DAMAGE = register(new StateFlag("firework-damage", false));
|
||||
|
||||
// These flags are similar to the ones above (used in tandem with BUILD),
|
||||
// but their defaults are set to TRUE because it is more user friendly.
|
||||
@@ -86,11 +89,11 @@ public final class Flags {
|
||||
public static final StateFlag CREEPER_EXPLOSION = register(new StateFlag("creeper-explosion", true));
|
||||
public static final StateFlag ENDERDRAGON_BLOCK_DAMAGE = register(new StateFlag("enderdragon-block-damage", true));
|
||||
public static final StateFlag GHAST_FIREBALL = register(new StateFlag("ghast-fireball", true));
|
||||
public static final StateFlag FIREWORK_DAMAGE = register(new StateFlag("firework-damage", true));
|
||||
public static final StateFlag OTHER_EXPLOSION = register(new StateFlag("other-explosion", true));
|
||||
public static final StateFlag WITHER_DAMAGE = register(new StateFlag("wither-damage", true));
|
||||
public static final StateFlag ENDER_BUILD = register(new StateFlag("enderman-grief", true));
|
||||
public static final StateFlag SNOWMAN_TRAILS = register(new StateFlag("snowman-trails", true));
|
||||
public static final StateFlag RAVAGER_RAVAGE = register(new StateFlag("ravager-grief", true));
|
||||
public static final StateFlag ENTITY_PAINTING_DESTROY = register(new StateFlag("entity-painting-destroy", true));
|
||||
public static final StateFlag ENTITY_ITEM_FRAME_DESTROY = register(new StateFlag("entity-item-frame-destroy", true));
|
||||
|
||||
@@ -116,6 +119,7 @@ public final class Flags {
|
||||
public static final StateFlag VINE_GROWTH = register(new StateFlag("vine-growth", true));
|
||||
public static final StateFlag CROP_GROWTH = register(new StateFlag("crop-growth", true));
|
||||
public static final StateFlag SOIL_DRY = register(new StateFlag("soil-dry", true));
|
||||
public static final StateFlag CORAL_FADE = register(new StateFlag("coral-fade", true));
|
||||
public static final StateFlag WATER_FLOW = register(new StateFlag("water-flow", true));
|
||||
public static final StateFlag LAVA_FLOW = register(new StateFlag("lava-flow", true));
|
||||
|
||||
@@ -132,9 +136,20 @@ public final class Flags {
|
||||
public static final LocationFlag TELE_LOC = register(new LocationFlag("teleport", RegionGroup.MEMBERS));
|
||||
public static final LocationFlag SPAWN_LOC = register(new LocationFlag("spawn", RegionGroup.MEMBERS));
|
||||
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag TELE_MESSAGE = register(new StringFlag("teleport-message",
|
||||
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of(
|
||||
"Teleported you to the region '%id%'.", TextColor.LIGHT_PURPLE)))));
|
||||
|
||||
// idk?
|
||||
public static final StateFlag INVINCIBILITY = register(new StateFlag("invincible", false));
|
||||
public static final StateFlag FALL_DAMAGE = register(new StateFlag("fall-damage", true));
|
||||
public static final StateFlag HEALTH_REGEN = register(new StateFlag("natural-health-regen", true));
|
||||
public static final StateFlag HUNGER_DRAIN = register(new StateFlag("natural-hunger-drain", true));
|
||||
|
||||
// session and movement based flags
|
||||
public static final StateFlag ENTRY = register(new StateFlag("entry", true, RegionGroup.NON_MEMBERS));
|
||||
@@ -145,9 +160,29 @@ public final class Flags {
|
||||
public static final StateFlag ENDERPEARL = register(new StateFlag("enderpearl", true));
|
||||
public static final StateFlag CHORUS_TELEPORT = register(new StateFlag("chorus-fruit-teleport", true));
|
||||
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag GREET_MESSAGE = register(new StringFlag("greeting"));
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag FAREWELL_MESSAGE = register(new StringFlag("farewell"));
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag GREET_TITLE = register(new StringFlag("greeting-title"));
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag FAREWELL_TITLE = register(new StringFlag("farewell-title"));
|
||||
|
||||
public static final BooleanFlag NOTIFY_ENTER = register(new BooleanFlag("notify-enter"));
|
||||
@@ -155,25 +190,45 @@ public final class Flags {
|
||||
|
||||
public static final RegistryFlag<GameMode> GAME_MODE = register(new RegistryFlag<>("game-mode", GameMode.REGISTRY));
|
||||
|
||||
public static final IntegerFlag HEAL_DELAY = register(new IntegerFlag("heal-delay"));
|
||||
public static final IntegerFlag HEAL_AMOUNT = register(new IntegerFlag("heal-amount"));
|
||||
public static final DoubleFlag MIN_HEAL = register(new DoubleFlag("heal-min-health"));
|
||||
public static final DoubleFlag MAX_HEAL = register(new DoubleFlag("heal-max-health"));
|
||||
private static final Number[] DELAY_VALUES = {0, 1, 5};
|
||||
private static final Number[] VITALS_VALUES = {0, 5, 10, 20};
|
||||
private static final Number[] VITALS_MINS = {0, 10};
|
||||
private static final Number[] VITALS_MAXS = {10, 20};
|
||||
|
||||
public static final IntegerFlag FEED_DELAY = register(new IntegerFlag("feed-delay"));
|
||||
public static final IntegerFlag FEED_AMOUNT = register(new IntegerFlag("feed-amount"));
|
||||
public static final IntegerFlag MIN_FOOD = register(new IntegerFlag("feed-min-hunger"));
|
||||
public static final IntegerFlag MAX_FOOD = register(new IntegerFlag("feed-max-hunger"));
|
||||
public static final IntegerFlag HEAL_DELAY = register(new IntegerFlag("heal-delay"), f -> f.setSuggestedValues(DELAY_VALUES));
|
||||
public static final IntegerFlag HEAL_AMOUNT = register(new IntegerFlag("heal-amount"), f -> f.setSuggestedValues(VITALS_VALUES));
|
||||
public static final DoubleFlag MIN_HEAL = register(new DoubleFlag("heal-min-health"), f -> f.setSuggestedValues(VITALS_MINS));
|
||||
public static final DoubleFlag MAX_HEAL = register(new DoubleFlag("heal-max-health"), f -> f.setSuggestedValues(VITALS_MAXS));
|
||||
|
||||
public static final IntegerFlag FEED_DELAY = register(new IntegerFlag("feed-delay"), f -> f.setSuggestedValues(DELAY_VALUES));
|
||||
public static final IntegerFlag FEED_AMOUNT = register(new IntegerFlag("feed-amount"), f -> f.setSuggestedValues(VITALS_VALUES));
|
||||
public static final IntegerFlag MIN_FOOD = register(new IntegerFlag("feed-min-hunger"), f -> f.setSuggestedValues(VITALS_MINS));
|
||||
public static final IntegerFlag MAX_FOOD = register(new IntegerFlag("feed-max-hunger"), f -> f.setSuggestedValues(VITALS_MAXS));
|
||||
|
||||
// deny messages
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag DENY_MESSAGE = register(new StringFlag("deny-message",
|
||||
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of("Hey!",
|
||||
TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(TextComponent.of(" Sorry, but you can't %what% here.", TextColor.GRAY)))));
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag ENTRY_DENY_MESSAGE = register(new StringFlag("entry-deny-message",
|
||||
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of("Hey!",
|
||||
TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
.append(TextComponent.of(" You are not permitted to enter this area.", TextColor.GRAY)))));
|
||||
/**
|
||||
* @deprecated The type of this flag will change from a StringFlag to a ComponentFlag to support JSON text
|
||||
* in a future release. If you depend on the type of this flag, take proper precaution for future breakage.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final StringFlag EXIT_DENY_MESSAGE = register(new StringFlag("exit-deny-message",
|
||||
LegacyComponentSerializer.INSTANCE.serialize(TextComponent.of("").append(TextComponent.of("Hey!",
|
||||
TextColor.RED, Sets.newHashSet(TextDecoration.BOLD)))
|
||||
@@ -188,6 +243,12 @@ public final class Flags {
|
||||
return flag;
|
||||
}
|
||||
|
||||
private static <T extends Flag<?>> T register(final T flag, Consumer<T> cfg) throws FlagConflictException {
|
||||
T f = register(flag);
|
||||
cfg.accept(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to match the flag with the given ID using a fuzzy name match.
|
||||
*
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ package com.sk89q.worldguard.protection.flags;
|
||||
/**
|
||||
* Stores an integer.
|
||||
*/
|
||||
public class IntegerFlag extends Flag<Integer> {
|
||||
public class IntegerFlag extends NumberFlag<Integer> {
|
||||
|
||||
public IntegerFlag(String name, RegionGroup defaultGroup) {
|
||||
super(name, defaultGroup);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.flags;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Stores an Number.
|
||||
*/
|
||||
public abstract class NumberFlag<T extends Number> extends Flag<T> {
|
||||
|
||||
private static final Number[] EMPTY_NUMBER_ARRAY = new Number[0];
|
||||
private Number[] suggestions = EMPTY_NUMBER_ARRAY;
|
||||
|
||||
protected NumberFlag(String name, RegionGroup defaultGroup) {
|
||||
super(name, defaultGroup);
|
||||
}
|
||||
|
||||
protected NumberFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not recommended for public use. Will likely be moved when migrating to piston for commands.
|
||||
* @param values suggested values
|
||||
*/
|
||||
@Beta
|
||||
public void setSuggestedValues(Number[] values) {
|
||||
this.suggestions = checkNotNull(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not recommended for public use. Will likely be moved when migrating to piston for commands.
|
||||
* @return suggested values
|
||||
*/
|
||||
@Beta
|
||||
public Number[] getSuggestedValues() {
|
||||
return suggestions;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import com.sk89q.worldguard.commands.CommandUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
@@ -56,7 +58,10 @@ public class StringFlag extends Flag<String> {
|
||||
|
||||
@Override
|
||||
public String parseInput(FlagContext context) throws InvalidFlagFormat {
|
||||
return context.getUserInput().replaceAll("(?!<\\\\)\\\\n", "\n").replaceAll("\\\\\\\\n", "\\n");
|
||||
String lines = context.getUserInput().replaceAll("(?<!\\\\)\\\\n", "\n").replaceAll("\\\\\\\\n", "\\\\n");
|
||||
// Add color codes
|
||||
lines = CommandUtils.replaceColorMacros(lines);
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-2
@@ -24,8 +24,6 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
|
||||
+23
-6
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.managers;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.managers.index.ChunkHashTable;
|
||||
import com.sk89q.worldguard.protection.managers.index.ConcurrentRegionIndex;
|
||||
@@ -29,15 +31,22 @@ import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Manages different {@link RegionManager}s for different worlds or dimensions.
|
||||
*
|
||||
@@ -52,8 +61,8 @@ public class RegionContainerImpl {
|
||||
private final ConcurrentMap<Normal, RegionManager> mapping = new ConcurrentHashMap<>();
|
||||
private final Object lock = new Object();
|
||||
private final RegionDriver driver;
|
||||
private final Supplier<? extends ConcurrentRegionIndex> indexFactory = new ChunkHashTable.Factory(new PriorityRTreeIndex.Factory());
|
||||
private final Timer timer = new Timer();
|
||||
private final Function<String, ? extends ConcurrentRegionIndex> indexFactory = new ChunkHashTable.Factory(new PriorityRTreeIndex.Factory());
|
||||
private final Timer timer = new Timer("WorldGuard Region I/O");
|
||||
private final FlagRegistry flagRegistry;
|
||||
|
||||
private final Set<Normal> failingLoads = new HashSet<>();
|
||||
@@ -182,6 +191,14 @@ public class RegionContainerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable completely.
|
||||
*/
|
||||
public void shutdown() {
|
||||
timer.cancel();
|
||||
unloadAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region manager for the given world name.
|
||||
*
|
||||
|
||||
+6
-7
@@ -37,6 +37,7 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.util.RegionCollectionConsumer;
|
||||
import com.sk89q.worldguard.util.Normal;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -47,9 +48,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A region manager holds the regions for a world.
|
||||
@@ -57,7 +56,7 @@ import javax.annotation.Nullable;
|
||||
public final class RegionManager {
|
||||
|
||||
private final RegionDatabase store;
|
||||
private final Supplier<? extends ConcurrentRegionIndex> indexFactory;
|
||||
private final Function<String, ? extends ConcurrentRegionIndex> indexFactory;
|
||||
private final FlagRegistry flagRegistry;
|
||||
private ConcurrentRegionIndex index;
|
||||
|
||||
@@ -68,14 +67,14 @@ public final class RegionManager {
|
||||
* @param indexFactory the factory for creating new instances of the index
|
||||
* @param flagRegistry the flag registry
|
||||
*/
|
||||
public RegionManager(RegionDatabase store, Supplier<? extends ConcurrentRegionIndex> indexFactory, FlagRegistry flagRegistry) {
|
||||
public RegionManager(RegionDatabase store, Function<String, ? extends ConcurrentRegionIndex> indexFactory, FlagRegistry flagRegistry) {
|
||||
checkNotNull(store);
|
||||
checkNotNull(indexFactory);
|
||||
checkNotNull(flagRegistry, "flagRegistry");
|
||||
|
||||
this.store = store;
|
||||
this.indexFactory = indexFactory;
|
||||
this.index = indexFactory.get();
|
||||
this.index = indexFactory.apply(store.getName());
|
||||
this.flagRegistry = flagRegistry;
|
||||
}
|
||||
|
||||
@@ -218,7 +217,7 @@ public final class RegionManager {
|
||||
public void setRegions(Collection<ProtectedRegion> regions) {
|
||||
checkNotNull(regions);
|
||||
|
||||
ConcurrentRegionIndex newIndex = indexFactory.get();
|
||||
ConcurrentRegionIndex newIndex = indexFactory.apply(getName());
|
||||
newIndex.addAll(regions);
|
||||
newIndex.getAndClearDifference(); // Clear changes
|
||||
this.index = newIndex;
|
||||
|
||||
+12
-9
@@ -41,8 +41,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -52,6 +52,7 @@ import javax.annotation.Nullable;
|
||||
*/
|
||||
public class ChunkHashTable implements ConcurrentRegionIndex {
|
||||
|
||||
private final String name;
|
||||
private ListeningExecutorService executor = createExecutor();
|
||||
private LongHashTable<ChunkState> states = new LongHashTable<>();
|
||||
private final RegionIndex index;
|
||||
@@ -63,10 +64,12 @@ public class ChunkHashTable implements ConcurrentRegionIndex {
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param index the index
|
||||
* @param name
|
||||
*/
|
||||
public ChunkHashTable(RegionIndex index) {
|
||||
public ChunkHashTable(RegionIndex index, String name) {
|
||||
checkNotNull(index);
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,8 +78,8 @@ public class ChunkHashTable implements ConcurrentRegionIndex {
|
||||
* @return an executor service
|
||||
*/
|
||||
private ListeningExecutorService createExecutor() {
|
||||
return MoreExecutors.listeningDecorator(
|
||||
EvenMoreExecutors.newBoundedCachedThreadPool(0, 4, Integer.MAX_VALUE));
|
||||
return MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 4, Integer.MAX_VALUE,
|
||||
"WorldGuard Region Chunk Table - " + name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,17 +364,17 @@ public class ChunkHashTable implements ConcurrentRegionIndex {
|
||||
/**
|
||||
* A factory for instances of {@code ChunkHashCache}.
|
||||
*/
|
||||
public static class Factory implements Supplier<ChunkHashTable> {
|
||||
private final Supplier<? extends ConcurrentRegionIndex> supplier;
|
||||
public static class Factory implements Function<String, ChunkHashTable> {
|
||||
private final Function<String, ? extends ConcurrentRegionIndex> supplier;
|
||||
|
||||
public Factory(Supplier<? extends ConcurrentRegionIndex> supplier) {
|
||||
public Factory(Function<String, ? extends ConcurrentRegionIndex> supplier) {
|
||||
checkNotNull(supplier);
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkHashTable get() {
|
||||
return new ChunkHashTable(supplier.get());
|
||||
public ChunkHashTable apply(String name) {
|
||||
return new ChunkHashTable(supplier.apply(name), name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -28,6 +28,7 @@ import com.sk89q.worldguard.protection.managers.RegionDifference;
|
||||
import com.sk89q.worldguard.protection.managers.RemovalStrategy;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -35,10 +36,8 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An index that stores regions in a hash map, which allows for fast lookup
|
||||
@@ -287,9 +286,9 @@ public class HashMapIndex extends AbstractRegionIndex implements ConcurrentRegio
|
||||
/**
|
||||
* A factory for new instances using this index.
|
||||
*/
|
||||
public static final class Factory implements Supplier<HashMapIndex> {
|
||||
public static final class Factory implements Function<String, HashMapIndex> {
|
||||
@Override
|
||||
public HashMapIndex get() {
|
||||
public HashMapIndex apply(String name) {
|
||||
return new HashMapIndex();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -30,8 +30,8 @@ import org.khelekore.prtree.SimpleMBR;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* An implementation of an index that uses {@link HashMapIndex} for queries
|
||||
@@ -103,9 +103,9 @@ public class PriorityRTreeIndex extends HashMapIndex {
|
||||
/**
|
||||
* A factory for new instances using this index.
|
||||
*/
|
||||
public static final class Factory implements Supplier<PriorityRTreeIndex> {
|
||||
public static final class Factory implements Function<String, PriorityRTreeIndex> {
|
||||
@Override
|
||||
public PriorityRTreeIndex get() {
|
||||
public PriorityRTreeIndex apply(String name) {
|
||||
return new PriorityRTreeIndex();
|
||||
}
|
||||
}
|
||||
|
||||
+9
-4
@@ -20,8 +20,8 @@
|
||||
package com.sk89q.worldguard.protection.managers.migration;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.sk89q.squirrelid.Profile;
|
||||
import com.sk89q.squirrelid.resolver.ProfileService;
|
||||
import com.sk89q.worldguard.util.profile.Profile;
|
||||
import com.sk89q.worldguard.util.profile.resolver.ProfileService;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.domains.PlayerDomain;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
@@ -31,7 +31,12 @@ import com.sk89q.worldguard.protection.managers.storage.StorageException;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
@@ -47,7 +52,7 @@ public class UUIDMigration extends AbstractMigration {
|
||||
private static final Logger log = Logger.getLogger(UUIDMigration.class.getCanonicalName());
|
||||
private static final int LOG_DELAY = 5000;
|
||||
|
||||
private final Timer timer = new Timer();
|
||||
private final Timer timer = new Timer("WorldGuard UUID Migration");
|
||||
private final ProfileService profileService;
|
||||
private final FlagRegistry flagRegistry;
|
||||
private final ConcurrentMap<String, UUID> resolvedNames = new ConcurrentHashMap<>();
|
||||
|
||||
Loaded 100 of 121 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user