Compare commits

..
Author SHA1 Message Date
wizjany d296e6e429 Handle BlockExplodeEvent as other explosion.
Also misc cleanup.
Closes #407, WORLDGUARD-3843.
2019-06-08 15:53:25 -04:00
466 changed files with 17929 additions and 22447 deletions

No files matched your search

+2 -34
View File
@@ -1,34 +1,2 @@
* text=auto eol=lf
# Force Batch files to CRLF
*.bat eol=crlf -text
# Java sources
*.java text diff=java
*.kt text diff=java
*.gradle text diff=java
*.gradle.kts text diff=java
# These files are text and should be normalized (Convert crlf => lf)
*.css text diff=css
*.df text
*.htm text diff=html
*.html text diff=html
*.js text
*.jsp text
*.jspf text
*.jspx text
*.properties text
*.tld text
*.tag text
*.tagx text
*.xml text
# These files are binary and should be left untouched
# (binary is a macro for -text -diff)
*.class binary
*.dll binary
*.ear binary
*.jar binary
*.so binary
*.war binary
*.jks binary
*.java diff=java
-1
View File
@@ -1 +0,0 @@
github: enginehub
-93
View File
@@ -1,93 +0,0 @@
name: Bug report
description: Report a way in which WorldGuard is not working as intended
labels: ['type:bug', 'status:pending']
body:
- type: markdown
attributes:
value: |
Please note that this is only for bugs, help with installation or other types of support should
be taken to the Discord Guild instead.
- type: input
attributes:
label: WorldEdit Version
description: The full version of WorldEdit, can be found by using `/we version`.
placeholder: e.g. 7.2.3 or 7.3.0-SNAPSHOT
validations:
required: true
- type: input
attributes:
label: WorldGuard Version
description: The full version of WorldGuard, can be found by using `/wg version`.
placeholder: e.g. 7.0.5 or 7.0.6-SNAPSHOT
validations:
required: true
- type: input
attributes:
label: Platform Version
description: |
The version of the platform you are on, i.e. Spigot or Paper.
Please ensure you are running up-to-date software before making a bug report.
Old versions, paper forks or hybrids will receive little to no support.
placeholder: e.g. git-Spigot-21fe707-e1ebe52, git-Paper-463
validations:
required: true
- type: checkboxes
id: confirmations
attributes:
label: Confirmations
description: Please confirm the following before submitting the bug. Your report will be closed if you are running hybrids or old software.
options:
- label: I am using the most recent Minecraft release.
required: true
- label: I am using a version of WorldEdit compatible with my Minecraft version.
required: true
- label: I am using a version of WorldGuard compatible with my Minecraft version.
required: true
- label: I am using the latest or recommended version of my platform software.
required: true
- label: I am NOT using a hybrid server, e.g. a server that combines Bukkit and Forge. Examples include Arclight, Mohist, and Cardboard.
required: true
- label: I am NOT using a fork of WorldEdit, such as FastAsyncWorldEdit (FAWE) or AsyncWorldEdit (AWE)
required: true
- type: textarea
attributes:
label: Bug Description
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: The behavior that you expected, instead of the bugged behavior that occurs.
validations:
required: true
- type: textarea
attributes:
label: Reproduction Steps
description: Steps to reproduce the behavior.
value: |
1. ...
2. ...
validations:
required: true
- type: input
attributes:
label: Optional WorldGuard-Report
description: Link to WorldGuard Region report for bugs with regions, received with `/wg report -p`
validations:
required: false
- type: textarea
attributes:
label: Anything Else?
description: Add any additional context you can provide below.
-5
View File
@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: EngineHub Discord
url: https://discord.gg/EngineHub
about: Please ask and answer questions here.
@@ -1,35 +0,0 @@
name: Feature request
description: Suggest an idea for WorldGuard
labels: ['type:feature-request', 'status:pending']
body:
- type: textarea
attributes:
label: The Problem
description: >
What is making your WorldGuard experience sub-optimal? This should be something that
cannot be easily solved by existing WorldGuard features.
placeholder: It's hard to ... ; I'm unable to ...
validations:
required: true
- type: textarea
attributes:
label: A Solution
description: What is your proposed solution to the above problem?
validations:
required: true
- type: textarea
attributes:
label: Alternatives
description: |
Alternative solutions or workarounds to the problem.
You should also describe why these are not preferable to the given solution.
validations:
required: false
- type: textarea
attributes:
label: Anything Else?
description: Add any additional context you can provide below.
+8 -10
View File
@@ -1,19 +1,17 @@
.classpath
.project
.settings/
target/
/.classpath
/.project
/.settings
/target
.DS_Store
**/*.iml
**/.idea
bin/
dependency-reduced-pom.xml
/bin
/dependency-reduced-pom.xml
*-private.sh
.gradle/
**/build/
out/
/.gradle
**/build
scripts/
+7
View File
@@ -0,0 +1,7 @@
language: java
jdk:
- oraclejdk8
notifications:
email: false
before_install: chmod +x gradlew
script: ./gradlew build -S
-223
View File
@@ -1,228 +1,5 @@
# Changelog
## 7.0.12
* Fix a change in the default behavior of explosion flag handling.
## 7.0.11
* Add support for MC 1.21.
* Add wind-charge-burst flag which is checked along with `use` (for the interaction) or `pvp` (for the knockback).
* Add breeze-charge-explosion flag for breeze charges (i.e. from the mob, not player wind charges).
* Add moisture-change flag and config options.
* Fix an error if a player logged in to an unloaded world.
* Fix chest boat usage always being counted as ride.
* Consider potions thrown by mobs as mob-damage.
* Workaround spigot no longer sending block change events when a book is placed on a lectern.
* Improve accuracy of target blocks in blacklist/build-perms events.
## 7.0.10
* Add support for MC 1.20.5 and 1.20.6, drop support for other 1.20 versions
## 7.0.9
* Add support for MC 1.20, drop support for MC 1.19
* Made entities spawned via the `/summon` command get treated as plugin-spawned entities
* Add sniffer egg trample protection options
## 7.0.8
* Add support for MC 1.19
* Add skulk-growth flag and config option
* Add copper-fade flag
* Add data packs to report output
* Add protection for allay inventory slot
* Categorize allay item pickups under item-pickup flag
* Categorize dragon egg interaction (teleporting) as building
* Ignore most NPC-based actions for Player events
* Optimize handling of tamed animals where the owner was offline (Paper only)
* Optimize additional InventoryHolder accesses (Paper only)
* Fix an exception that occurred when plugins created portals with non-player entities
* Fix possible error when using Paper's entity origin API
* Update bstats and squirrelid libs
## 7.0.7
* Add rock-growth flag for budding amethyst and pointed dripstone.
* Add /rg migrateheights command. See https://worldguard.enginehub.org/en/latest/regions/commands/#migrate-region-heights
* Add regions.set-parent-on-claim config (set to a region id for /rg claim to automatically assign the parent region).
* Add `-i search` and `-s` flags to /rg list, -c to /rg teleport.
* Fix an error in blacklist logging caused by non-player actions (eg on-dispense)
* Treat unknown causes as known if using paper-entity-origin config option.
* Improve lightning strike handling from channeling tridents (PaperMC only).
* Ignore an error caused by lingering player references of offline players.
* Add red sand to no-physics-sand.
* Fix potion splash events being cancelled if no entities were affected.
## 7.0.6
* Add support for 1.17 blocks/items, drop support for 1.16.
* Add use-dripleaf flag for "toggling" big dripleaf blocks.
* Fix support for fully negative-height regions.
* Fix crop-growth config option.
* Be more rigorous with protecting blocks against dispenser behaviors.
* Fix handling of lingering splash potion effects.
* Handle other-explosion flag consistently for block-like entities (armor frames etc.)
* Allow inheriting values for all flags (previously wasn't used for things like teleport.)
* Region commands that defaulted to the region the player was standing in no longer check parents.
* Fix child regions being unlinked when redefining a parent region.
## 7.0.5
* Add a use-anvil flag and exclude it from the use flag (since they can break on use.)
* Add nonplayer-protection-domains flag which allows merging region borders from the perspective of pistons, saplings, etc.
* Expand crop-related options (crop-growth, etc) to sweet berry bushes, nether wart, and bamboo.
* Add a config option (`mobs.block-vehicle-entry`) to prevent non-players from entering vehicles.
* Add a UUID flag (for developers/API usage).
* Add map query methods with fallback flag (for developers/API usage).
* Add `on` and `off` optional arguments for `/rg toggle-bypass` command.
* Add additional timings info for session handlers.
* Fix sponge-simulation clearing NBT from blocks. Note that if you are using sponge simulation you should switch to something like CraftBook as the feature will be removed from WorldGuard in a future (major) version.
* Fix the `/rg` command showing up as unknown client-side to players without bypass perms.
* Fix error propagation from third-party flag loading causing WG to error.
* Fix a (harmless) exception that occurred when swapping armor slots to the offhand slot.
* Fix empty lines being sent on enderpearl/chorus-fruit teleport if the deny messages were empty.
* Fix an issue with falling blocks when using max-priority-association.
* Fix performance issues with third-party plugins querying protection for offline players.
* Fix dispensing shulkers over region boundaries.
* Fix iron door interaction being denied as if it were a regular door.
* Fix being able to enter/exit regions with the flag denied by using entity mounting functions in other plugins.
## 7.0.4 (including beta1)
* Add support for MC 1.16. Dropped support for previous versions.
* Add respawn-anchors flag mirroring the sleep flag (e.g. to prevent using respawn anchors to cause explosions in the overworld)
* Add nether vines to vine-growth flag.
* Add config option to disable the bypass permission cache.
* Fix water-flow flags not checking waterlogged blocks.
* Add config option to consider non-player causes (e.g. pistons, flowing water) to only be members of the highest priority region. This should be enabled for plots-within-city-like setups to prevent things in plots from modifying the city.
* Fix items dropping from falling blocks that were suppressed by other plugins.
* Add config option to block turtle egg trampling.
* Fix ride flag being checked on striders that didn't have saddles.
* Add config option to have /rg bypass toggled off on login.
* Developer changes: Methods taking names in Domains are now explicitly deprecated (was previously just a javadoc comment.); These will eventually be removed: there is no reason to use names over UUIDs. Offline players and NPCs alike have stable UUIDs.
* Also for developers; The new `com.sk89q.worldguard.protection.util.WorldEditRegionConverter` class has some useful static methods to convert to and from WorldEdit's Region and WorldGuard's ProtectedRegion classes.
## 7.0.3
* This is the last release supporting MC 1.14 and 1.15.
* Decouple chest-access flag from interact flag. IMPORTANT: If you relied on allowing players to access chests via setting
the interact flag to allow, you will now need to set the chest-access flag to allow instead (or as well). This does not
affect any setups where users were *not* supposed to be able to access chests and other inventories.
* Add natural-health-regen and natural-hunger-drain flags. Unlike the heal/feed flags, these can not restore or deplete health/hunger.
* Fix the interact flag allowing breaking of turtle eggs (now tied directly to block-trampling flag).
* Fix a memory leak that could occur with many many explosives.
* Add regions.titles-always-use-default-times config option. Set this to true if you use greeting/farewell titles and another plugin
makes the titles disappear too quickly.
* Add protection for cauldrons water level changing.
* Improve diagnostic hints and information, such as spawn protection warnings, flag colors in region info, etc.
* Fix waterlogged blocks bypassing water-flow flag.
* Workaround for a CraftBukkit change that made no-physics-sand/gravel non-functional.
* Workaround for CraftBukkit throttling move events.
* Track projectiles shot by dispensers.
* Allowed setting passthrough allow on global to unprotect it if members/owners are added.
* Add support for newer forge clients (FML2) in host keys.
* Allow using WorldEdit's `//world <worldname>` command to select a world for region commands. This removes the need to
use `-w <worldname>` in every command when running commands from console.
* Add a teleport-message flag, shown when using `/rg tp`.
* Add coral-fade flag, which prevents corals from drying when out of water.
* Fix spammy deny-message when walking over redstone ore with certain flag setups.
* Improve handling of interacting with various tools in hand that didn't modify blocks. (eg opening a chest with an axe in hand)
* Fix allow-all-interact option not being read from per-world configs.
* Fix misattribution of pets (eg wolves) in PvP.
* Improve performance of hopper checks when on recent builds of Paper.
* Add event-handling.break-hoppers-on-denied-move config option to prevent hoppers from being broken (but items still won't be moved).
* Note to developers using the WorldGuard API: If you specifically relied on flags such as greeting/farewell, deny-message, etc being
StringFlags, be warned that this will change in a future version to support JSON text components. Please plan accordingly.
## 7.0.2
* Update to MC 1.15. Still compatible with 1.14, and incompatible with 1.13, as before.
* Add an informational message when defining a region that overlaps vanilla spawn protection.
* Protect against pushing a piston with another piston on a region border.
* Protect against buckets in dispensers on region borders.
## 7.0.1
* Add `/rg toggle-bypass` command which temporarily turns off region bypassing until used again.
* More improvements to `/rg flag` and `/rg flags` commands.
* 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.
* Added `/rg flags` command which allows viewing and interactively setting all flags on a region.
* Large behind-the-scenes changes to WorldGuard's API (developers, see https://worldguard.enginehub.org/en/latest/developer/)
* Places that used numeric block ids (e.g. blacklist) should now use Minecraft's new string IDs.
* Fix various interactions with NPCs and region protection.
* Sponge-simulation now destroys kelp and seagrass, and de-waterlogs blocks.
* Added an option to block conduit effects.
* Fix using newlines in string flags such as greeting and farewell.
* Add item-frame-rotation flag.
* Ender chests no longer require chest-access (since they don't have inventories).
* Add kelp to vine-growth flag/config.
* Add block-trampling flag (for turtle eggs and farmland).
* Add snowman-trails flag.
* Track potion area-of-effect cloud causes for pvp etc. protection.
* Add confirmation to /stoplag command.
* Forcefully eject players from vehicles trying to force their way into entry deny regions (and out of exit deny).
* Fix removing child regions when removing a region with children.
* Fix some over-protectiveness of pistons.
* Chat and command flags (send-/receive- and allowed-/blocked-) now respect deny-message flag.
* Misc fixes.
## 6.2.2
* Added support for MC 1.12.
* Changed flower pots to fall under the build flag.
* Fix heal flag not functioning.
* Add option to allow Forge clients with host-keys setting.
* Add mobs.block-armor-stand-destroy config.
* Add firework-damage flag.
* Add config option to ignore hopper checks.
* Misc fixes.
## 6.2
* Added support for MC 1.11.
* Add a custom flag and session API (for developers, see https://worldguard.enginehub.org/en/latest/developer/)
* Add a config option to ensure location flags (teleport, spawn) are inside their region.
* Misc fixes.
## 6.1.2
* Added support for new blocks in 1.8, 1.9, and 1.10.
* Added protection from nether portals being created in protected region (enable via config `nether-portal-protection`).
-39
View File
@@ -1,39 +0,0 @@
Compiling
=========
You can compile WorldGuard as long as you have some version of Java greater than or equal to 21 installed.
Gradle will download JDK 21 specifically if needed, but it needs some version of Java to bootstrap from.
The build process uses Gradle, which you do *not* need to download. WorldGuard is a multi-module project with three modules:
* `worldguard-core` contains the WorldGuard API
* `worldguard-bukkit` is the Bukkit plugin
* `worldguard-libs` contains library relocations
## To compile...
### On Windows
1. **Shift** + **right click** the folder with WorldGuard's files and click "Open PowerShell window here".
2. `gradlew build`
### On Linux, BSD, or Mac OS X
1. In your terminal, navigate to the folder with WorldGuard's files (`cd /folder/of/worldguard/files`)
2. `./gradlew build`
## Then you will find...
You will find:
* The core WorldGuard API in **worldguard-core/build/libs**
* WorldGuard for Bukkit in **worldguard-bukkit/build/libs**
If you want to use WorldGuard, use the `-dist` version.
(The -dist version includes WorldGuard + necessary libraries.)
## Other commands
* `gradlew idea` will generate an [IntelliJ IDEA](http://www.jetbrains.com/idea/) module for each folder.
* `gradlew eclipse` will generate an [Eclipse](https://www.eclipse.org/downloads/) project for each folder.
+4 -2
View File
@@ -4,10 +4,12 @@ Thank you for your interest in contributing to WorldGuard! We appreciate your
effort, but to make sure that the inclusion of your patch is a smooth process, we
ask that you make note of the following guidelines.
* **Follow the [Oracle coding conventions](https://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).**
* **Follow the [Oracle coding conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html).**
We can't stress this enough; if your code has notable issues, it may delay
the process significantly.
* **Target Java 16 for source and compilation.**
* **Target Java 6 for source and compilation.** Make sure to mark methods with
` @Override` that override methods of parent classes, or that implement
methods of interfaces (Java 6+).
* **Use only spaces for indentation.** Our indents are 4-spaces long, and tabs
are unacceptable.
* **Wrap code to a 89 column limit.** We do this to make side by side diffs
-16
View File
@@ -1,16 +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/>.
+200 -200
View File
@@ -1,201 +1,201 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
----------------------------------------------------------------------------
This work includes Robert Olofsson's Priority R-Tree implementation, for which
its license is reproduced below.
Copyright (c) 2008-2010 Robert Olofsson.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the authors nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
----------------------------------------------------------------------------
This work includes Robert Olofsson's Priority R-Tree implementation, for which
its license is reproduced below.
Copyright (c) 2008-2010 Robert Olofsson.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the authors nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
+46 -47
View File
@@ -1,47 +1,46 @@
<h1>
<img src="worldguard-logo.svg" alt="WorldGuard" width="400" />
</h1>
WorldGuard lets you and players guard areas of land against griefers and undesirables, as well as tweak and disable various gameplay features of Minecraft.
* Block creeper and wither block damage, falling damage, etc.
* Disable fire spread, lava fire spread, ice formation, Endermen picking up blocks, etc.
* Blacklist certain items and blocks so they can't be used
* Warn moderators when certain items and blocks are used
* Protect areas of your world so only certain people can build in them
* Set areas where PVP, TNT, mob damage, and other features are disabled
* Protect your server from various 'exploits' like magical obsidian creation machines
* Disable, or enable, various Minecraft features, like sponges from classic
* Add useful commands like an immediate "STOP ALL FIRE SPREAD" command
* Enable only features you want! Everything is off by default
WorldGuard is open source and is available under the GNU Lesser
General Public License v3.
A Bukkit server implementation (such as [Paper](https://papermc.io)) and the [WorldEdit plugin](https://dev.bukkit.org/projects/worldedit) are required to use WorldGuard. You can get a release copy of WorldGuard from the [BukkitDev site](https://dev.bukkit.org/projects/worldguard).
Compiling
---------
The project is written for Java 17 and our build process makes use of
[Gradle](http://gradle.org).
Dependencies are automatically handled by Gradle.
Contributing
------------
We happily accept contributions, especially through pull requests on GitHub.
Please read CONTRIBUTING.md for important guidelines to follow.
Submissions must be licensed under the GNU Lesser General Public License v3.
Links
-----
* [Homepage](https://enginehub.org/worldguard)
* [Discord](https://discord.gg/enginehub)
* [Issue tracker](https://github.com/EngineHub/WorldGuard/issues)
* [Continuous integration](https://builds.enginehub.org) [![Build Status](https://ci.enginehub.org/app/rest/builds/buildType:bt11,branch:master/statusIcon.svg)](http://ci.enginehub.org/viewType.html?buildTypeId=bt11&guest=1)
* [End-user documentation](https://worldguard.enginehub.org/en/latest/)
# ![WorldGuard](http://static.sk89q.com/readme/worldguard-new.png)
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.
WorldGuard is open source and is available under the GNU Lesser
General Public License v3.
Currently, Bukkit is required to use WorldGuard. You can get a release copy of WorldGuard from the [BukkitDev site](http://dev.bukkit.org/bukkit-plugins/worldguard/).
Compiling
---------
The project is written for Java 6 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).
Dependencies are automatically handled by Gradle.
Contributing
------------
We happily accept contributions, especially through pull requests on GitHub.
Please read CONTRIBUTING.md for important guidelines to follow.
Submissions must be licensed under the GNU Lesser General Public License v3.
Links
-----
* [Homepage](http://enginehub.org/worldguard)
* [IRC channel](http://skq.me/irc/irc.esper.net/sk89q/) (#sk89q on irc.esper.net)
* [Issue tracker](http://youtrack.sk89q.com/issues/WORLDGUARD)
* [Continuous integration](http://builds.enginehub.org)
* [End-user documentation](http://wiki.sk89q.com/wiki/WorldGuard)
-29
View File
@@ -1,29 +0,0 @@
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
}
dependencies {
implementation(gradleApi())
implementation(libs.licenser)
implementation(libs.grgit)
implementation(libs.shadow)
implementation(libs.jfrog.buildinfo)
implementation(libs.gson)
constraints {
val asmVersion = "[${libs.versions.minimumAsm.get()},)"
implementation("org.ow2.asm:asm:$asmVersion") {
because("Need Java 21 support in shadow")
}
implementation("org.ow2.asm:asm-commons:$asmVersion") {
because("Need Java 21 support in shadow")
}
implementation("org.vafer:jdependency:[${libs.versions.minimumJdependency.get()},)") {
because("Need Java 21 support in shadow")
}
}
}
-9
View File
@@ -1,9 +0,0 @@
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "build-logic"
@@ -1,32 +0,0 @@
import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention
import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask
plugins {
id("com.jfrog.artifactory")
}
val ARTIFACTORY_CONTEXT_URL = "artifactory_contextUrl"
val ARTIFACTORY_USER = "artifactory_user"
val ARTIFACTORY_PASSWORD = "artifactory_password"
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] = ""
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
}
@@ -1,10 +0,0 @@
plugins {
id("com.jfrog.artifactory")
}
// Artifactory eagerly evaluates publications, so this must run after all changes to artifacts are done
afterEvaluate {
tasks.named<org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask>("artifactoryPublish") {
publications("maven")
}
}
@@ -1,65 +0,0 @@
import buildlogic.getLibrary
import buildlogic.stringyLibs
plugins {
id("eclipse")
id("idea")
id("checkstyle")
id("buildlogic.common")
}
tasks
.withType<JavaCompile>()
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
.configureEach {
val disabledLint = listOf(
"processing", "path", "fallthrough", "serial", "overloads",
)
options.release.set(21)
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
options.isDeprecation = true
options.encoding = "UTF-8"
options.compilerArgs.add("-parameters")
//options.compilerArgs.add("-Werror")
}
configure<CheckstyleExtension> {
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
toolVersion = "10.16.0"
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
dependencies {
"compileOnly"(stringyLibs.getLibrary("jsr305"))
"testImplementation"(platform(stringyLibs.getLibrary("junit-bom")))
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-api"))
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-params"))
"testRuntimeOnly"(stringyLibs.getLibrary("junit-jupiter-engine"))
}
// Java 8 turns on doclint which we fail
tasks.withType<Javadoc>().configureEach {
options.encoding = "UTF-8"
(options as StandardJavadocDocletOptions).apply {
//addBooleanOption("Werror", true)
addBooleanOption("Xdoclint:all", true)
addBooleanOption("Xdoclint:-missing", true)
tags(
"apiNote:a:API Note:",
"implSpec:a:Implementation Requirements:",
"implNote:a:Implementation Note:"
)
}
}
configure<JavaPluginExtension> {
withJavadocJar()
withSourcesJar()
}
tasks.named("check").configure {
dependsOn("checkstyleMain", "checkstyleTest")
}
@@ -1,69 +0,0 @@
import buildlogic.getLibrary
import buildlogic.stringyLibs
import org.gradle.plugins.ide.idea.model.IdeaModel
plugins {
id("org.cadixdev.licenser")
}
group = rootProject.group
version = rootProject.version
repositories {
mavenCentral()
maven {
name = "EngineHub"
url = uri("https://maven.enginehub.org/repo/")
}
}
configurations.all {
resolutionStrategy {
cacheChangingModulesFor(1, TimeUnit.DAYS)
}
}
plugins.withId("java") {
the<JavaPluginExtension>().toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
dependencies {
for (conf in listOf("implementation", "api")) {
if (!configurations.names.contains(conf)) {
continue
}
add(conf, platform(stringyLibs.getLibrary("log4j-bom")).map {
val dep = create(it)
dep.because("Mojang provides Log4j")
dep
})
constraints {
add(conf, stringyLibs.getLibrary("guava")) {
because("Mojang provides Guava")
}
add(conf, stringyLibs.getLibrary("gson")) {
because("Mojang provides Gson")
}
add(conf, stringyLibs.getLibrary("fastutil")) {
because("Mojang provides FastUtil")
}
}
}
}
license {
header(rootProject.file("HEADER.txt"))
include("**/*.java")
include("**/*.kt")
}
plugins.withId("idea") {
configure<IdeaModel> {
module {
isDownloadSources = true
isDownloadJavadoc = true
}
}
}
@@ -1,23 +0,0 @@
plugins {
id("java")
id("maven-publish")
id("buildlogic.common-java")
id("buildlogic.artifactory-sub")
}
ext["internalVersion"] = "$version+${rootProject.ext["gitCommitHash"]}"
publishing {
publications {
register<MavenPublication>("maven") {
versionMapping {
usage("java-api") {
fromResolutionOf("runtimeClasspath")
}
usage("java-runtime") {
fromResolutionResult()
}
}
}
}
}
@@ -1,179 +0,0 @@
plugins {
id("java-base")
id("maven-publish")
id("com.github.johnrengelman.shadow")
id("com.jfrog.artifactory")
id("buildlogic.common")
id("buildlogic.artifactory-sub")
}
// A horrible hack because `softwareComponentFactory` has to be gotten via plugin
// gradle why
internal open class LibsConfigPluginHack @Inject constructor(
private val softwareComponentFactory: SoftwareComponentFactory
) : Plugin<Project> {
override fun apply(project: Project) {
val libsComponents = softwareComponentFactory.adhoc("libs")
project.components.add(libsComponents)
}
}
configurations {
create("shade")
}
group = "${rootProject.group}.worldguard-libs"
val relocations = mapOf(
"org.enginehub.squirrelid" to "com.sk89q.worldguard.util.profile",
)
tasks.register<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("jar") {
configurations = listOf(project.configurations["shade"])
archiveClassifier.set("")
// Yeet module-info's
exclude("module-info.class")
dependencies {
exclude(dependency("com.google.guava:guava"))
exclude(dependency("com.google.code.gson:gson"))
exclude(dependency("com.google.errorprone:error_prone_annotations"))
exclude(dependency("com.google.guava:failureaccess"))
exclude(dependency("org.checkerframework:checker-qual"))
exclude(dependency("org.jetbrains:annotations"))
exclude(dependency("org.apache.logging.log4j:log4j-api"))
exclude(dependency("com.google.code.findbugs:jsr305"))
exclude {
it.moduleGroup == "org.jetbrains.kotlin"
}
}
relocations.forEach { (from, to) ->
relocate(from, to)
}
}
val altConfigFiles = { artifactType: String ->
val deps = configurations["shade"].incoming.dependencies
.filterIsInstance<ModuleDependency>()
.map { it.copy() }
.map { dependency ->
val category = dependency.attributes.getAttribute(Category.CATEGORY_ATTRIBUTE)?.name
if (category == Category.REGULAR_PLATFORM || category == Category.ENFORCED_PLATFORM) {
return@map dependency
}
try {
dependency.artifact {
name = dependency.name
type = artifactType
extension = "jar"
classifier = artifactType
}
} catch (e: Exception) {
throw RuntimeException("Failed to add artifact to dependency: $dependency", e)
}
dependency
}
files(configurations.detachedConfiguration(*deps.toTypedArray())
.resolvedConfiguration.lenientConfiguration.artifacts
.filter { it.classifier == artifactType }
.map { zipTree(it.file) })
}
tasks.register<Jar>("sourcesJar") {
from({
altConfigFiles("sources")
})
// Yeet module-info's
exclude("module-info.java")
relocations.forEach { (from, to) ->
val filePattern = Regex("(.*)${from.replace('.', '/')}((?:/|$).*)")
val textPattern = Regex.fromLiteral(from)
eachFile {
filter {
it.replaceFirst(textPattern, to)
}
path = path.replaceFirst(filePattern, "$1${to.replace('.', '/')}$2")
}
}
archiveClassifier.set("sources")
}
tasks.named("assemble").configure {
dependsOn("jar", "sourcesJar")
}
project.apply<LibsConfigPluginHack>()
val libsComponent = project.components["libs"] as AdhocComponentWithVariants
val apiElements = project.configurations.register("apiElements") {
isVisible = false
description = "API elements for libs"
isCanBeResolved = false
isCanBeConsumed = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API))
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
}
outgoing.artifact(tasks.named("jar"))
}
val runtimeElements = project.configurations.register("runtimeElements") {
isVisible = false
description = "Runtime elements for libs"
isCanBeResolved = false
isCanBeConsumed = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
}
outgoing.artifact(tasks.named("jar"))
}
val sourcesElements = project.configurations.register("sourcesElements") {
isVisible = false
description = "Source elements for libs"
isCanBeResolved = false
isCanBeConsumed = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.DOCUMENTATION))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.objects.named(DocsType.SOURCES))
}
outgoing.artifact(tasks.named("sourcesJar"))
}
libsComponent.addVariantsFromConfiguration(apiElements.get()) {
mapToMavenScope("compile")
}
libsComponent.addVariantsFromConfiguration(runtimeElements.get()) {
mapToMavenScope("runtime")
}
libsComponent.addVariantsFromConfiguration(sourcesElements.get()) {
mapToMavenScope("runtime")
}
configure<PublishingExtension> {
publications {
register<MavenPublication>("maven") {
from(libsComponent)
}
}
}
if (project != project(":worldguard-libs:core")) {
evaluationDependsOn(":worldguard-libs:core")
configurations["shade"].shouldResolveConsistentlyWith(project(":worldguard-libs:core").configurations["shade"])
}
@@ -1,39 +0,0 @@
plugins {
id("com.github.johnrengelman.shadow")
id("buildlogic.core-and-platform")
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
archiveClassifier.set("dist")
dependencies {
include(project(":worldguard-libs:core"))
include(project(":worldguard-core"))
relocate("org.flywaydb", "com.sk89q.worldguard.internal.flywaydb") {
include(dependency("org.flywaydb:flyway-core"))
}
exclude("com.google.code.findbugs:jsr305")
}
exclude("GradleStart**")
exclude(".cache")
exclude("LICENSE*")
exclude("META-INF/maven/**")
minimize()
}
val javaComponent = components["java"] as AdhocComponentWithVariants
// I don't think we want this published (it's the shadow jar)
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
skip()
}
afterEvaluate {
tasks.named<Jar>("jar") {
val version = project(":worldguard-core").version
inputs.property("version", version)
val attributes = mutableMapOf(
"Implementation-Version" to version,
"WorldGuard-Version" to version,
)
manifest.attributes(attributes)
}
}
@@ -1,24 +0,0 @@
package buildlogic
import org.gradle.api.Project
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.artifacts.VersionConstraint
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.getByType
val Project.ext: ExtraPropertiesExtension
get() = extensions.getByType()
val Project.stringyLibs: VersionCatalog
get() = extensions.getByType<VersionCatalogsExtension>().named("libs")
fun VersionCatalog.getLibrary(name: String): Provider<MinimalExternalModuleDependency> = findLibrary(name).orElseThrow {
error("Library $name not found in version catalog")
}
fun VersionCatalog.getVersion(name: String): VersionConstraint = findVersion(name).orElseThrow {
error("Version $name not found in version catalog")
}
+131
View File
@@ -0,0 +1,131 @@
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:1.2.1'
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1'
classpath 'org.ajoberstar:gradle-git:0.12.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"
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'checkstyle'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'com.jfrog.artifactory-upload'
group = 'com.sk89q.worldguard'
version = '7.0.0-SNAPSHOT'
ext.internalVersion = version + ";" + gitCommitHash
sourceCompatibility = 1.8
targetCompatibility = 1.8
checkstyle.configFile = new File(rootProject.projectDir, "config/checkstyle/checkstyle.xml")
repositories {
mavenCentral()
maven { url "http://repo.spongepowered.org/maven/" }
maven { url "https://hub.spigotmc.org/nexus/content/groups/public" }
maven { url "http://maven.sk89q.com/repo/" }
maven { url "http://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'))
}
exclude 'GradleStart**'
exclude '.cache'
exclude 'LICENSE*'
}
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
}
}
resolve {
repository {
repoKey = 'repo'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
}
-17
View File
@@ -1,17 +0,0 @@
import org.ajoberstar.grgit.Grgit
plugins {
id("buildlogic.common")
id("buildlogic.artifactory-root")
}
if (!project.hasProperty("gitCommitHash")) {
apply(plugin = "org.ajoberstar.grgit")
ext["gitCommitHash"] = try {
extensions.getByName<Grgit>("grgit").head()?.abbreviatedId
} catch (e: Exception) {
logger.warn("Error getting commit hash", e)
"no.git.id"
}
}
@@ -1,86 +0,0 @@
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.plugins.quality.CheckstyleExtension
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.api.tasks.testing.Test
import org.gradle.external.javadoc.StandardJavadocDocletOptions
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.withType
fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, javaRelease: Int = 8, banSlf4j: Boolean = true) {
applyCommonConfiguration()
apply(plugin = "eclipse")
apply(plugin = "idea")
apply(plugin = "checkstyle")
tasks
.withType<JavaCompile>()
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
.configureEach {
val disabledLint = listOf(
"processing", "path", "fallthrough", "serial"
)
options.release.set(javaRelease)
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
options.isDeprecation = true
options.encoding = "UTF-8"
options.compilerArgs.add("-parameters")
}
configure<CheckstyleExtension> {
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
toolVersion = "9.1"
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
dependencies {
"compileOnly"("com.google.code.findbugs:jsr305:${Versions.FINDBUGS}")
"testImplementation"("org.junit.jupiter:junit-jupiter-api:${Versions.JUNIT}")
"testImplementation"("org.junit.jupiter:junit-jupiter-params:${Versions.JUNIT}")
"testImplementation"("org.mockito:mockito-core:${Versions.MOCKITO}")
"testImplementation"("org.mockito:mockito-junit-jupiter:${Versions.MOCKITO}")
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:${Versions.JUNIT}")
}
// Java 8 turns on doclint which we fail
tasks.withType<Javadoc>().configureEach {
options.encoding = "UTF-8"
(options as StandardJavadocDocletOptions).apply {
addStringOption("Xdoclint:none", "-quiet")
tags(
"apiNote:a:API Note:",
"implSpec:a:Implementation Requirements:",
"implNote:a:Implementation Note:"
)
}
}
configure<JavaPluginExtension> {
disableAutoTargetJvm()
withJavadocJar()
if (sourcesJar) {
withSourcesJar()
}
}
if (banSlf4j) {
configurations["compileClasspath"].apply {
resolutionStrategy.componentSelection {
withModule("org.slf4j:slf4j-api") {
reject("No SLF4J allowed on compile classpath")
}
}
}
}
tasks.named("check").configure {
dependsOn("checkstyleMain", "checkstyleTest")
}
}
+11 -10
View File
@@ -1,28 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<!-- Tabs are strictly banned -->
<module name="FileTabCharacter"/>
<module name="SuppressionFilter">
<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 -->
<module name="OuterTypeFilename"/> <!-- TypeName -> TypeName.java -->
<!--
Control package usage, so people don't insert Bukkit into WG where it shouldn't belong, etc.
Control package usage, so people don't insert Bukkit into WE where it shouldn't belong, etc.
It is a bit draconian, so update as necessary!
-->
<module name="ImportControl">
<property name="file" value="${config_loc}/import-control.xml"/>
<property name="file" value="config/checkstyle/import-control.xml"/>
</module>
<!-- Code -->
@@ -33,6 +27,7 @@
<property name="max" value="2"/>
</module>
<module name="SuperFinalize"/> <!-- We don't actually use this -->
<module name="JUnitTestCase"/> <!-- Checks tearDown(), setUp() etc. -->
<!-- Style -->
<module name="LeftCurly"> <!-- Left brace never goes on another line -->
@@ -60,4 +55,10 @@
<!-- <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="config/checkstyle/header.txt"/>
<property name="fileExtensions" value="java"/>
</module>
</module>
+18
View File
@@ -0,0 +1,18 @@
/*
* 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/>.
*/
+11 -15
View File
@@ -7,32 +7,28 @@
<allow pkg="javax"/>
<allow pkg="org.junit"/>
<allow pkg="org.hamcrest"/>
<allow pkg="junit.framework"/>
<allow pkg="org.mockito"/>
<allow pkg="com.sk89q"/>
<allow pkg="com.google.common"/>
<subpackage name="worldguard">
<allow pkg="org.khelekore"/>
<allow pkg="org.flywaydb"/>
<allow pkg="org.yaml"/>
<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="org.bstats.charts"/>
<allow pkg="io.papermc.lib"/>
<allow pkg="com.destroystokyo.paper"/>
<allow pkg="io.papermc.paper"/>
<allow pkg="org.spigotmc" />
<allow pkg="net.minecraft.server"/>
</subpackage>
<subpackage name="sponge">
<allow pkg="org.spongepowered"/>
<allow pkg="com.flowpowered"/>
</subpackage>
<subpackage name="forge">
<allow pkg="net.minecraft"/>
<allow pkg="net.minecraftforge"/>
</subpackage>
</subpackage>
</import-control>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<suppress files="ProtectedRegion.java" checks="EqualsHashCode"/>
</suppressions>
-4
View File
@@ -1,4 +0,0 @@
group=com.sk89q.worldguard
version=7.1.0-SNAPSHOT
org.gradle.parallel=true
-2
View File
@@ -1,2 +0,0 @@
#This file is generated by updateDaemonJvm
toolchainVersion=21
-66
View File
@@ -1,66 +0,0 @@
[versions]
worldedit = "7.3.0"
# Minimum versions we apply to make dependencies support newer Java
minimumAsm = "9.7"
minimumJdependency = "2.10"
minimumTinyRemapper = "0.8.11"
# lang-version = ""
[libraries]
licenser = "gradle.plugin.org.cadixdev.gradle:licenser:0.6.1"
grgit = "org.ajoberstar.grgit:grgit-gradle:5.2.2"
shadow = "com.github.johnrengelman:shadow:8.1.1"
jfrog-buildinfo = "org.jfrog.buildinfo:build-info-extractor-gradle:5.2.0"
squirrelid = "org.enginehub:squirrelid:0.3.2"
autoService = "com.google.auto.service:auto-service:1.1.1"
jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
jetbrains-annotations = "org.jetbrains:annotations:24.1.0"
junit-bom = "org.junit:junit-bom:5.10.2"
junit-jupiter-api.module = "org.junit.jupiter:junit-jupiter-api"
junit-jupiter-params.module = "org.junit.jupiter:junit-jupiter-params"
junit-jupiter-engine.module = "org.junit.jupiter:junit-jupiter-engine"
spigot = "org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT"
paperApi = "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT"
paperLib = "io.papermc:paperlib:1.0.8"
dummypermscompat = "com.sk89q:dummypermscompat:1.10"
bstats-bukkit = "org.bstats:bstats-bukkit:2.2.1"
prtree = "org.khelekore:prtree:1.5.0"
flyway-core = "org.flywaydb:flyway-core:3.0"
commandbook = "com.sk89q:commandbook:2.3"
hamcrest-library = "org.hamcrest:hamcrest-library:2.2"
# Mojang-provided libraries, CHECK AGAINST MINECRAFT for versions
guava = "com.google.guava:guava:32.1.3-jre!!"
log4j-bom = "org.apache.logging.log4j:log4j-bom:2.22.1!!"
gson = "com.google.code.gson:gson:2.10.1!!"
fastutil = "it.unimi.dsi:fastutil:8.5.12!!"
# Bukkit-provided libraries, CHECK AGAINST SPIGOT for versions
# Note that we need to balance support for older MC versus working at all on newer ones, so the exact versions here
# may not be the same as the ones in the latest Bukkit API.
snakeyaml = "org.yaml:snakeyaml:2.0"
[libraries.worldedit-core]
module = "com.sk89q.worldedit:worldedit-core"
version.ref = "worldedit"
[libraries.worldedit-bukkit]
module = "com.sk89q.worldedit:worldedit-bukkit"
version.ref = "worldedit"
[libraries.worldedit-libs-ap]
module = "com.sk89q.worldedit.worldedit-libs:ap"
version.ref = "worldedit"
Binary file not shown.
+2 -3
View File
@@ -1,7 +1,6 @@
#Fri Nov 13 12:12:21 EST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip
Vendored Executable → Regular
+117 -202
View File
@@ -1,127 +1,79 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#!/usr/bin/env bash
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
MAX_FD="maximum"
warn () {
warn ( ) {
echo "$*"
} >&2
}
die () {
die ( ) {
echo
echo "$*"
echo
exit 1
} >&2
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD=$JAVA_HOME/bin/java
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -130,120 +82,83 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
Vendored
+42 -44
View File
@@ -1,20 +1,4 @@
@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
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -24,30 +8,26 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@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=
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
if "%ERRORLEVEL%" == "0" goto init
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
@@ -55,36 +35,54 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
if exist "%JAVA_EXE%" goto init
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
+3
View File
@@ -0,0 +1,3 @@
rootProject.name = 'worldguard'
include 'worldguard-core', 'worldguard-sponge', 'worldguard-legacy'
-33
View File
@@ -1,33 +0,0 @@
pluginManagement {
repositories {
gradlePluginPortal()
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
logger.lifecycle("""
*******************************************
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 Discord! https://discord.gg/enginehub
Output files will be in [subproject]/build/libs
*******************************************
""")
rootProject.name = "worldguard"
includeBuild("build-logic")
include("worldguard-libs")
include("worldguard-libs:core")
listOf("bukkit", "core").forEach {
include("worldguard-$it")
}
-68
View File
@@ -1,68 +0,0 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
`java-library`
id("buildlogic.platform")
}
val localImplementation = configurations.create("localImplementation") {
description = "Dependencies used locally, but provided by the runtime Bukkit implementation"
isCanBeConsumed = false
isCanBeResolved = false
}
configurations["compileOnly"].extendsFrom(localImplementation)
configurations["testImplementation"].extendsFrom(localImplementation)
dependencies {
"api"(project(":worldguard-core"))
"api"(libs.worldedit.bukkit) { isTransitive = false }
"compileOnly"(libs.commandbook) { isTransitive = false }
// Technically this is api, but everyone should already have some form of the bukkit API
// Avoid pulling in another one, especially one so outdated.
"localImplementation"(libs.spigot) {
exclude("junit", "junit")
}
"compileOnly"(libs.jetbrains.annotations) {
because("Resolving Spigot annotations")
}
"testCompileOnly"(libs.jetbrains.annotations) {
because("Resolving Spigot annotations")
}
"compileOnly"(libs.paperApi) {
exclude("org.slf4j", "slf4j-api")
exclude("junit", "junit")
}
"implementation"(libs.paperLib)
"implementation"(libs.bstats.bukkit)
}
tasks.named<Copy>("processResources") {
val internalVersion = project.ext["internalVersion"]
inputs.property("internalVersion", internalVersion)
filesMatching("plugin.yml") {
expand("internalVersion" to internalVersion)
}
}
tasks.named<ShadowJar>("shadowJar") {
dependencies {
include(dependency(":worldguard-core"))
include(dependency("org.bstats:"))
include(dependency("io.papermc:paperlib"))
relocate("org.bstats", "com.sk89q.worldguard.bukkit.bstats")
relocate("io.papermc.lib", "com.sk89q.worldguard.bukkit.paperlib")
}
}
tasks.named("assemble").configure {
dependsOn("shadowJar")
}
configure<PublishingExtension> {
publications.named<MavenPublication>("maven") {
from(components["java"])
}
}
@@ -1,127 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.world.World;
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;
public class BukkitConfigurationManager extends YamlConfigurationManager {
@Unreported private WorldGuardPlugin plugin;
@Unreported private ConcurrentMap<String, BukkitWorldConfiguration> worlds = new ConcurrentHashMap<>();
private boolean hasCommandBookGodMode;
boolean extraStats;
/**
* Construct the object.
*
* @param plugin The plugin instance
*/
public BukkitConfigurationManager(WorldGuardPlugin plugin) {
super();
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();
}
@Override
public void copyDefaults() {
// Create the default configuration file
plugin.createDefaultConfiguration(new File(plugin.getDataFolder(), "config.yml"), "config.yml");
}
@Override
public void unload() {
worlds.clear();
}
@Override
public void postLoad() {
// Load configurations for each world
for (World world : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
get(world);
}
getConfig().save();
}
/**
* Get the configuration for a world.
*
* @param world The world to get the configuration for
* @return {@code world}'s configuration
*/
@Override
public BukkitWorldConfiguration get(World world) {
String worldName = world.getName();
return get(worldName);
}
public BukkitWorldConfiguration get(String worldName) {
BukkitWorldConfiguration config = worlds.get(worldName);
BukkitWorldConfiguration newConfig = null;
while (config == null) {
if (newConfig == null) {
newConfig = new BukkitWorldConfiguration(plugin, worldName, this.getConfig());
}
worlds.putIfAbsent(worldName, newConfig);
config = worlds.get(worldName);
}
return config;
}
public void updateCommandBookGodMode() {
try {
if (plugin.getServer().getPluginManager().isPluginEnabled("CommandBook")) {
Class.forName("com.sk89q.commandbook.GodComponent");
hasCommandBookGodMode = true;
return;
}
} catch (ClassNotFoundException ignore) {}
hasCommandBookGodMode = false;
}
public boolean hasCommandBookGodMode() {
return hasCommandBookGodMode;
}
}
@@ -1,241 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.weather.WeatherType;
import org.bukkit.OfflinePlayer;
import java.util.UUID;
import javax.annotation.Nullable;
class BukkitOfflinePlayer extends BukkitPlayer {
private final OfflinePlayer player;
BukkitOfflinePlayer(WorldGuardPlugin plugin, OfflinePlayer offlinePlayer) {
super(plugin, offlinePlayer.getPlayer()); // null if they are offline
this.player = offlinePlayer;
}
/// ========================================
/// These are checked for RegionAssociable
/// (to see if a player belongs to a region)
/// ========================================
@Override
public String getName() {
return player.getName();
}
@Override
public UUID getUniqueId() {
return player.getUniqueId();
}
@Override
public boolean hasGroup(String group) {
return plugin.inGroup(player, group);
}
@Override
public String[] getGroups() {
return plugin.getGroups(player);
}
/// ==========================================
/// None of the following should ever be used.
/// ==========================================
@Override
public boolean hasPermission(String perm) {
throw new UnsupportedOperationException();
}
@Override
public void kick(String msg) {
throw new UnsupportedOperationException();
}
@Override
public void ban(String msg) {
throw new UnsupportedOperationException();
}
@Override
public double getHealth() {
throw new UnsupportedOperationException();
}
@Override
public void setHealth(double health) {
throw new UnsupportedOperationException();
}
@Override
public double getMaxHealth() {
throw new UnsupportedOperationException();
}
@Override
public double getFoodLevel() {
throw new UnsupportedOperationException();
}
@Override
public void setFoodLevel(double foodLevel) {
throw new UnsupportedOperationException();
}
@Override
public double getSaturation() {
throw new UnsupportedOperationException();
}
@Override
public void setSaturation(double saturation) {
throw new UnsupportedOperationException();
}
@Override
public float getExhaustion() {
throw new UnsupportedOperationException();
}
@Override
public void setExhaustion(float exhaustion) {
throw new UnsupportedOperationException();
}
@Override
public WeatherType getPlayerWeather() {
throw new UnsupportedOperationException();
}
@Override
public void setPlayerWeather(WeatherType weather) {
throw new UnsupportedOperationException();
}
@Override
public void resetPlayerWeather() {
throw new UnsupportedOperationException();
}
@Override
public boolean isPlayerTimeRelative() {
throw new UnsupportedOperationException();
}
@Override
public long getPlayerTimeOffset() {
throw new UnsupportedOperationException();
}
@Override
public void setPlayerTime(long time, boolean relative) {
throw new UnsupportedOperationException();
}
@Override
public void resetPlayerTime() {
throw new UnsupportedOperationException();
}
@Override
public void printRaw(String msg) {
throw new UnsupportedOperationException();
}
@Override
public void printDebug(String msg) {
throw new UnsupportedOperationException();
}
@Override
public void print(String msg) {
throw new UnsupportedOperationException();
}
@Override
public void printError(String msg) {
throw new UnsupportedOperationException();
}
@Override
public World getWorld() {
throw new UnsupportedOperationException();
}
@Override
public BaseItemStack getItemInHand(HandSide handSide) {
throw new UnsupportedOperationException();
}
@Override
public void giveItem(BaseItemStack itemStack) {
throw new UnsupportedOperationException();
}
@Override
public BlockBag getInventoryBlockBag() {
throw new UnsupportedOperationException();
}
@Override
public void setPosition(Vector3 pos, float pitch, float yaw) {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public BaseEntity getState() {
throw new UnsupportedOperationException();
}
@Override
public Location getLocation() {
throw new UnsupportedOperationException();
}
@Override
public void setCompassTarget(Location location) {
throw new UnsupportedOperationException();
}
@Override
public SessionKey getSessionKey() {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public <T> T getFacet(Class<? extends T> cls) {
throw new UnsupportedOperationException();
}
}
@@ -1,221 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
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;
public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implements LocalPlayer {
protected final WorldGuardPlugin plugin;
private final boolean silenced;
private String name;
public BukkitPlayer(WorldGuardPlugin plugin, Player player) {
this(plugin, player, false);
}
BukkitPlayer(WorldGuardPlugin plugin, Player player, boolean silenced) {
super(player);
this.plugin = plugin;
this.silenced = silenced;
}
@Override
public String getName() {
if (this.name == null) {
// getName() takes longer than before in newer versions of Minecraft
this.name = getPlayer().getName();
}
return name;
}
@Override
public boolean hasGroup(String group) {
return plugin.inGroup(getPlayer(), group);
}
@Override
public void kick(String msg) {
if (!silenced) {
getPlayer().kickPlayer(msg);
}
}
@Override
public void ban(String msg) {
if (!silenced) {
Bukkit.getBanList(Type.NAME).addBan(getName(), null, null, null);
getPlayer().kickPlayer(msg);
}
}
@Override
public double getHealth() {
return getPlayer().getHealth();
}
@Override
public void setHealth(double health) {
getPlayer().setHealth(health);
}
@Override
public double getMaxHealth() {
return getPlayer().getMaxHealth();
}
@Override
public double getFoodLevel() {
return getPlayer().getFoodLevel();
}
@Override
public void setFoodLevel(double foodLevel) {
getPlayer().setFoodLevel((int) foodLevel);
}
@Override
public double getSaturation() {
return getPlayer().getSaturation();
}
@Override
public void setSaturation(double saturation) {
getPlayer().setSaturation((float) saturation);
}
@Override
public float getExhaustion() {
return getPlayer().getExhaustion();
}
@Override
public void setExhaustion(float exhaustion) {
getPlayer().setExhaustion(exhaustion);
}
@Override
public WeatherType getPlayerWeather() {
org.bukkit.WeatherType playerWeather = getPlayer().getPlayerWeather();
return playerWeather == null ? null : playerWeather == org.bukkit.WeatherType.CLEAR ? WeatherTypes.CLEAR : WeatherTypes.RAIN;
}
@Override
public void setPlayerWeather(WeatherType weather) {
getPlayer().setPlayerWeather(weather == WeatherTypes.CLEAR ? org.bukkit.WeatherType.CLEAR : org.bukkit.WeatherType.DOWNFALL);
}
@Override
public void resetPlayerWeather() {
getPlayer().resetPlayerWeather();
}
@Override
public boolean isPlayerTimeRelative() {
return getPlayer().isPlayerTimeRelative();
}
@Override
public long getPlayerTimeOffset() {
return getPlayer().getPlayerTimeOffset();
}
@Override
public void setPlayerTime(long time, boolean relative) {
getPlayer().setPlayerTime(time, relative);
}
@Override
public void resetPlayerTime() {
getPlayer().resetPlayerTime();
}
@Override
public int getFireTicks() {
return getPlayer().getFireTicks();
}
@Override
public void setFireTicks(int fireTicks) {
getPlayer().setFireTicks(fireTicks);
}
@Override
public void setCompassTarget(Location location) {
getPlayer().setCompassTarget(BukkitAdapter.adapt(location));
}
@Override
public void sendTitle(String title, String subtitle) {
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
public String[] getGroups() {
return plugin.getGroups(getPlayer());
}
@Override
public void printRaw(String msg) {
if (!silenced) {
super.printRaw(msg);
}
}
@Override
public boolean hasPermission(String perm) {
return plugin.hasPermission(getPlayer(), perm);
}
}
@@ -1,132 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
public class BukkitRegionContainer extends RegionContainer {
/**
* Invalidation frequency in ticks.
*/
private static final int CACHE_INVALIDATION_INTERVAL = 2;
private final WorldGuardPlugin plugin;
/**
* Create a new instance.
*
* @param plugin the plugin
*/
public BukkitRegionContainer(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
@Override
public void initialize() {
super.initialize();
Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler
public void onWorldLoad(WorldLoadEvent event) {
load(BukkitAdapter.adapt(event.getWorld()));
}
@EventHandler
public void onWorldUnload(WorldUnloadEvent event) {
unload(BukkitAdapter.adapt(event.getWorld()));
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
RegionManager manager = get(BukkitAdapter.adapt(event.getWorld()));
if (manager != null) {
Chunk chunk = event.getChunk();
manager.loadChunk(BlockVector2.at(chunk.getX(), chunk.getZ()));
}
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) {
RegionManager manager = get(BukkitAdapter.adapt(event.getWorld()));
if (manager != null) {
Chunk chunk = event.getChunk();
manager.unloadChunk(BlockVector2.at(chunk.getX(), chunk.getZ()));
}
}
}, plugin);
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, cache::invalidateAll, CACHE_INVALIDATION_INTERVAL, CACHE_INVALIDATION_INTERVAL);
}
public void shutdown() {
container.shutdown();
}
@Override
@Nullable
protected RegionManager load(World world) {
checkNotNull(world);
WorldConfiguration config = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world);
if (!config.useRegions) {
return null;
}
RegionManager manager;
synchronized (lock) {
manager = container.load(world.getName());
if (manager != null) {
// Bias the region data for loaded chunks
List<BlockVector2> positions = new ArrayList<>();
for (Chunk chunk : ((BukkitWorld) world).getWorld().getLoadedChunks()) {
positions.add(BlockVector2.at(chunk.getX(), chunk.getZ()));
}
manager.loadChunks(positions);
}
}
return manager;
}
}
@@ -1,246 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.internal.platform.StringMatcher;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class BukkitStringMatcher implements StringMatcher {
@Override
public World matchWorld(Actor sender, String filter) throws CommandException {
List<? extends World> worlds = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds();
// Handle special hash tag groups
if (filter.charAt(0) == '#') {
// #main for the main world
if (filter.equalsIgnoreCase("#main")) {
return worlds.get(0);
// #normal for the first normal world
} else if (filter.equalsIgnoreCase("#normal")) {
for (World world : worlds) {
if (BukkitAdapter.adapt(world).getEnvironment() == org.bukkit.World.Environment.NORMAL) {
return world;
}
}
throw new CommandException("No normal world found.");
// #nether for the first nether world
} else if (filter.equalsIgnoreCase("#nether")) {
for (World world : worlds) {
if (BukkitAdapter.adapt(world).getEnvironment() == org.bukkit.World.Environment.NETHER) {
return world;
}
}
throw new CommandException("No nether world found.");
// #end for the first nether world
} else if (filter.equalsIgnoreCase("#end")) {
for (World world : worlds) {
if (BukkitAdapter.adapt(world).getEnvironment() == org.bukkit.World.Environment.THE_END) {
return world;
}
}
throw new CommandException("No end world found.");
// Handle getting a world from a player
} else if (filter.matches("^#player$")) {
String[] parts = filter.split(":", 2);
// They didn't specify an argument for the player!
if (parts.length == 1) {
throw new CommandException("Argument expected for #player.");
}
return matchPlayers(sender, parts[1]).iterator().next().getWorld();
} else {
throw new CommandException("Invalid identifier '" + filter + "'.");
}
}
for (World world : worlds) {
if (world.getName().equals(filter)) {
return world;
}
}
throw new CommandException("No world by that exact name found.");
}
@Override
public List<LocalPlayer> matchPlayerNames(String filter) {
List<LocalPlayer> wgPlayers = Bukkit.getServer().getOnlinePlayers().stream().map(player -> WorldGuardPlugin.inst().wrapPlayer(player)).collect(Collectors.toList());
filter = filter.toLowerCase();
// Allow exact name matching
if (filter.charAt(0) == '@' && filter.length() >= 2) {
filter = filter.substring(1);
for (LocalPlayer player : wgPlayers) {
if (player.getName().equalsIgnoreCase(filter)) {
List<LocalPlayer> list = new ArrayList<>();
list.add(player);
return list;
}
}
return new ArrayList<>();
// Allow partial name matching
} else if (filter.charAt(0) == '*' && filter.length() >= 2) {
filter = filter.substring(1);
List<LocalPlayer> list = new ArrayList<>();
for (LocalPlayer player : wgPlayers) {
if (player.getName().toLowerCase().contains(filter)) {
list.add(player);
}
}
return list;
// Start with name matching
} else {
List<LocalPlayer> list = new ArrayList<>();
for (LocalPlayer player : wgPlayers) {
if (player.getName().toLowerCase().startsWith(filter)) {
list.add(player);
}
}
return list;
}
}
@Override
public Iterable<? extends LocalPlayer> matchPlayers(Actor source, String filter) throws CommandException {
if (Bukkit.getServer().getOnlinePlayers().isEmpty()) {
throw new CommandException("No players matched query.");
}
List<LocalPlayer> wgPlayers = Bukkit.getServer().getOnlinePlayers().stream().map(player -> WorldGuardPlugin.inst().wrapPlayer(player)).collect(Collectors.toList());
if (filter.equals("*")) {
return checkPlayerMatch(wgPlayers);
}
// Handle special hash tag groups
if (filter.charAt(0) == '#') {
// Handle #world, which matches player of the same world as the
// calling source
if (filter.equalsIgnoreCase("#world")) {
List<LocalPlayer> players = new ArrayList<>();
LocalPlayer sourcePlayer = WorldGuard.getInstance().checkPlayer(source);
World sourceWorld = sourcePlayer.getWorld();
for (LocalPlayer player : wgPlayers) {
if (player.getWorld().equals(sourceWorld)) {
players.add(player);
}
}
return checkPlayerMatch(players);
// Handle #near, which is for nearby players.
} else if (filter.equalsIgnoreCase("#near")) {
List<LocalPlayer> players = new ArrayList<>();
LocalPlayer sourcePlayer = WorldGuard.getInstance().checkPlayer(source);
World sourceWorld = sourcePlayer.getWorld();
Vector3 sourceVector = sourcePlayer.getLocation().toVector();
for (LocalPlayer player : wgPlayers) {
if (player.getWorld().equals(sourceWorld) && player.getLocation().toVector().distanceSq(sourceVector) < 900) {
players.add(player);
}
}
return checkPlayerMatch(players);
} else {
throw new CommandException("Invalid group '" + filter + "'.");
}
}
List<LocalPlayer> players = matchPlayerNames(filter);
return checkPlayerMatch(players);
}
@Override
public Actor matchPlayerOrConsole(Actor sender, String filter) throws CommandException {
// Let's see if console is wanted
if (filter.equalsIgnoreCase("#console")
|| filter.equalsIgnoreCase("*console*")
|| filter.equalsIgnoreCase("!")) {
return WorldGuardPlugin.inst().wrapCommandSender(Bukkit.getServer().getConsoleSender());
}
return matchSinglePlayer(sender, filter);
}
@Override
public World getWorldByName(String worldName) {
final org.bukkit.World bukkitW = Bukkit.getServer().getWorld(worldName);
if (bukkitW == null) {
return null;
}
return BukkitAdapter.adapt(bukkitW);
}
@Override
public String replaceMacros(Actor sender, String message) {
Collection<? extends Player> online = Bukkit.getServer().getOnlinePlayers();
message = message.replace("%name%", sender.getName());
message = message.replace("%id%", sender.getUniqueId().toString());
message = message.replace("%online%", String.valueOf(online.size()));
if (sender instanceof LocalPlayer) {
LocalPlayer player = (LocalPlayer) sender;
World world = (World) player.getExtent();
message = message.replace("%world%", world.getName());
message = message.replace("%health%", String.valueOf(player.getHealth()));
}
return message;
}
}
@@ -1,96 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.blacklist.target.BlockTarget;
import com.sk89q.worldguard.blacklist.target.ItemTarget;
import com.sk89q.worldguard.blacklist.target.Target;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
public class BukkitUtil {
private BukkitUtil() {
}
/**
* Checks if the given potion is a vial of water.
*
* @param item the item to check
* @return true if it's a water vial
*/
public static boolean isWaterPotion(ItemStack item) {
return (item.getDurability() & 0x3F) == 0;
}
/**
* Get just the potion effect bits. This is to work around bugs with potion
* parsing.
*
* @param item item
* @return new bits
*/
public static int getPotionEffectBits(ItemStack item) {
return item.getDurability() & 0x3F;
}
/**
* Get a blacklist target for the given block.
*
* @param block the block
* @return a target
*/
public static Target createTarget(Block block) {
checkNotNull(block);
checkNotNull(block.getType());
return createTarget(block.getType());
}
/**
* Get a blacklist target for the given item.
*
* @param item the item
* @return a target
*/
public static Target createTarget(ItemStack item) {
checkNotNull(item);
checkNotNull(item.getType());
return createTarget(item.getType()); // Delegate it, ItemStacks can contain both Blocks and Items in Spigot
}
/**
* Get a blacklist target for the given material.
*
* @param material the material
* @return a target
*/
public static Target createTarget(Material material) {
checkNotNull(material);
if (material.isBlock()) {
return new BlockTarget(BukkitAdapter.asBlockType(material));
} else {
return new ItemTarget(BukkitAdapter.asItemType(material));
}
}
}
@@ -1,276 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
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.PaperPlayerService;
import com.sk89q.worldguard.bukkit.protection.events.flags.FlagContextCreateEvent;
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
import com.sk89q.worldguard.bukkit.util.report.DatapackReport;
import com.sk89q.worldguard.bukkit.util.report.PerformanceReport;
import com.sk89q.worldguard.bukkit.util.report.PluginReport;
import com.sk89q.worldguard.bukkit.util.report.SchedulerReport;
import com.sk89q.worldguard.bukkit.util.report.ServerReport;
import com.sk89q.worldguard.bukkit.util.report.ServicesReport;
import com.sk89q.worldguard.bukkit.util.report.WorldReport;
import com.sk89q.worldguard.internal.platform.DebugHandler;
import com.sk89q.worldguard.internal.platform.StringMatcher;
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;
public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
private BukkitSessionManager sessionManager;
private BukkitConfigurationManager configuration;
private BukkitRegionContainer regionContainer;
private BukkitDebugHandler debugHandler;
private StringMatcher stringMatcher;
public BukkitWorldGuardPlatform() {
}
@Override
public String getPlatformName() {
return "Bukkit-Official";
}
@Override
public String getPlatformVersion() {
return WorldGuardPlugin.inst().getDescription().getVersion();
}
@Override
public void notifyFlagContextCreate(FlagContext.FlagContextBuilder flagContextBuilder) {
Bukkit.getServer().getPluginManager().callEvent(new FlagContextCreateEvent(flagContextBuilder));
}
@Override
public BukkitConfigurationManager getGlobalStateManager() {
return configuration;
}
@Override
public StringMatcher getMatcher() {
return stringMatcher;
}
@Override
public SessionManager getSessionManager() {
return this.sessionManager;
}
@Override
public void broadcastNotification(String message) {
Bukkit.broadcast(message, "worldguard.notify");
Set<Permissible> subs = Bukkit.getPluginManager().getPermissionSubscriptions("worldguard.notify");
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
if (!(subs.contains(player) && player.hasPermission("worldguard.notify")) &&
WorldGuardPlugin.inst().hasPermission(player, "worldguard.notify")) { // Make sure the player wasn't already broadcasted to.
player.sendMessage(message);
}
}
WorldGuard.logger.info(message);
}
@Override
public void broadcastNotification(TextComponent component) {
List<LocalPlayer>
wgPlayers = Bukkit.getServer().getOnlinePlayers().stream().map(player -> WorldGuardPlugin.inst().wrapPlayer(player)).collect(
Collectors.toList());
for (LocalPlayer player : wgPlayers) {
if (player.hasPermission("worldguard.notify")) {
player.print(component);
}
}
}
@Override
public void load() {
stringMatcher = new BukkitStringMatcher();
sessionManager = new BukkitSessionManager();
configuration = new BukkitConfigurationManager(WorldGuardPlugin.inst());
configuration.load();
regionContainer = new BukkitRegionContainer(WorldGuardPlugin.inst());
regionContainer.initialize();
debugHandler = new BukkitDebugHandler(WorldGuardPlugin.inst());
}
@Override
public void unload() {
sessionManager.shutdown();
configuration.unload();
regionContainer.shutdown();
}
@Override
public RegionContainer getRegionContainer() {
return this.regionContainer;
}
@Override
public DebugHandler getDebugHandler() {
return debugHandler;
}
@Override
public GameMode getDefaultGameMode() {
return GameModes.get(Bukkit.getServer().getDefaultGameMode().name().toLowerCase());
}
@Override
public Path getConfigDir() {
return WorldGuardPlugin.inst().getDataFolder().toPath();
}
@Override
public void stackPlayerInventory(LocalPlayer localPlayer) {
boolean ignoreMax = localPlayer.hasPermission("worldguard.stack.illegitimate");
Player player = ((BukkitPlayer) localPlayer).getPlayer();
ItemStack[] items = player.getInventory().getContents();
int len = items.length;
int affected = 0;
for (int i = 0; i < len; i++) {
ItemStack item = items[i];
// Avoid infinite stacks and stacks with durability
if (item == null || item.getAmount() <= 0
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
continue;
}
int max = ignoreMax ? 64 : item.getMaxStackSize();
if (item.getAmount() < max) {
int needed = max - item.getAmount(); // Number of needed items until max
// Find another stack of the same type
for (int j = i + 1; j < len; j++) {
ItemStack item2 = items[j];
// Avoid infinite stacks and stacks with durability
if (item2 == null || item2.getAmount() <= 0
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
continue;
}
// Same type?
if (item2.isSimilar(item)) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(max);
item2.setAmount(item2.getAmount() - needed);
break;
// This stack will
} else {
items[j] = null;
item.setAmount(item.getAmount() + item2.getAmount());
needed = max - item.getAmount();
}
affected++;
}
}
}
}
if (affected > 0) {
player.getInventory().setContents(items);
}
}
@Override
public void addPlatformReports(ReportList report) {
report.add(new ServerReport());
report.add(new PluginReport());
report.add(new SchedulerReport());
report.add(new ServicesReport());
report.add(new WorldReport());
report.add(new PerformanceReport());
if (PaperLib.isPaper()) report.add(new DatapackReport());
}
@Override
public ProfileService createProfileService(ProfileCache profileCache) {
List<ProfileService> services = new ArrayList<>();
if (PaperLib.isPaper()) {
// Paper has a shared cache
services.add(PaperPlayerService.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().y()),
spawnLoc.add(radius, 0, radius).withY(world.getMaxY()));
}
}
}
return null;
}
}
@@ -1,529 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import com.google.common.collect.ImmutableList;
import com.sk89q.bukkit.util.CommandsManagerRegistration;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.minecraft.util.commands.CommandUsageException;
import com.sk89q.minecraft.util.commands.CommandsManager;
import com.sk89q.minecraft.util.commands.MissingNestedCommandException;
import com.sk89q.minecraft.util.commands.SimpleInjector;
import com.sk89q.minecraft.util.commands.WrappedCommandException;
import com.sk89q.wepif.PermissionsResolverManager;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitCommandSender;
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.blacklist.Blacklist;
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
import com.sk89q.worldguard.bukkit.listener.BlacklistListener;
import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener;
import com.sk89q.worldguard.bukkit.listener.BuildPermissionListener;
import com.sk89q.worldguard.bukkit.listener.ChestProtectionListener;
import com.sk89q.worldguard.bukkit.listener.DebuggingListener;
import com.sk89q.worldguard.bukkit.listener.EventAbstractionListener;
import com.sk89q.worldguard.bukkit.listener.InvincibilityListener;
import com.sk89q.worldguard.bukkit.listener.PlayerModesListener;
import com.sk89q.worldguard.bukkit.listener.PlayerMoveListener;
import com.sk89q.worldguard.bukkit.listener.RegionFlagsListener;
import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardBlockListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardCommandBookListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardEntityListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardHangingListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardPlayerListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardServerListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardVehicleListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener;
import com.sk89q.worldguard.bukkit.listener.WorldRulesListener;
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
import com.sk89q.worldguard.bukkit.util.ClassSourceValidator;
import com.sk89q.worldguard.bukkit.util.Entities;
import com.sk89q.worldguard.bukkit.util.Events;
import com.sk89q.worldguard.commands.GeneralCommands;
import com.sk89q.worldguard.commands.ProtectionCommands;
import com.sk89q.worldguard.commands.ToggleCommands;
import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
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.ProtectedRegion;
import com.sk89q.worldguard.util.logging.RecordMessagePrefixer;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.DrilldownPie;
import org.bstats.charts.SimplePie;
import org.bstats.charts.SingleLineChart;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The main class for WorldGuard as a Bukkit plugin.
*/
public class WorldGuardPlugin extends JavaPlugin {
private static WorldGuardPlugin inst;
private static BukkitWorldGuardPlatform platform;
private final CommandsManager<Actor> commands;
private PlayerMoveListener playerMoveListener;
private static final int BSTATS_PLUGIN_ID = 3283;
/**
* Construct objects. Actual loading occurs when the plugin is enabled, so
* this merely instantiates the objects.
*/
public WorldGuardPlugin() {
inst = this;
commands = new CommandsManager<Actor>() {
@Override
public boolean hasPermission(Actor player, String perm) {
return player.hasPermission(perm);
}
};
}
/**
* Get the current instance of WorldGuard
* @return WorldGuardPlugin instance
*/
public static WorldGuardPlugin inst() {
return inst;
}
/**
* Called on plugin enable.
*/
@Override
public void onEnable() {
// Catch bad things being done by naughty plugins that include WorldGuard's classes
ClassSourceValidator verifier = new ClassSourceValidator(this);
verifier.reportMismatches(ImmutableList.of(WorldGuard.class, ProtectedRegion.class, Flag.class));
configureLogger();
getDataFolder().mkdirs(); // Need to create the plugins/WorldGuard folder
PermissionsResolverManager.initialize(this);
WorldGuard.getInstance().setPlatform(platform = new BukkitWorldGuardPlatform()); // Initialise WorldGuard
WorldGuard.getInstance().setup();
BukkitSessionManager sessionManager = (BukkitSessionManager) platform.getSessionManager();
// Set the proper command injector
commands.setInjector(new SimpleInjector(WorldGuard.getInstance()));
// Register command classes
final CommandsManagerRegistration reg = new CommandsManagerRegistration(this, commands);
reg.register(ToggleCommands.class);
reg.register(ProtectionCommands.class);
if (!platform.getGlobalStateManager().hasCommandBookGodMode()) {
reg.register(GeneralCommands.class);
}
getServer().getScheduler().scheduleSyncRepeatingTask(this, sessionManager, BukkitSessionManager.RUN_DELAY, BukkitSessionManager.RUN_DELAY);
// Register events
getServer().getPluginManager().registerEvents(sessionManager, this);
(new WorldGuardPlayerListener(this)).registerEvents();
(new WorldGuardBlockListener(this)).registerEvents();
(new WorldGuardEntityListener(this)).registerEvents();
(new WorldGuardWeatherListener(this)).registerEvents();
(new WorldGuardVehicleListener(this)).registerEvents();
(new WorldGuardServerListener(this)).registerEvents();
(new WorldGuardHangingListener(this)).registerEvents();
// Modules
(playerMoveListener = new PlayerMoveListener(this)).registerEvents();
(new BlacklistListener(this)).registerEvents();
(new ChestProtectionListener(this)).registerEvents();
(new RegionProtectionListener(this)).registerEvents();
(new RegionFlagsListener(this)).registerEvents();
(new WorldRulesListener(this)).registerEvents();
(new BlockedPotionsListener(this)).registerEvents();
(new EventAbstractionListener(this)).registerEvents();
(new PlayerModesListener(this)).registerEvents();
(new BuildPermissionListener(this)).registerEvents();
(new InvincibilityListener(this)).registerEvents();
if ("true".equalsIgnoreCase(System.getProperty("worldguard.debug.listener"))) {
(new DebuggingListener(this, WorldGuard.logger)).registerEvents();
}
platform.getGlobalStateManager().updateCommandBookGodMode();
if (getServer().getPluginManager().isPluginEnabled("CommandBook")) {
getServer().getPluginManager().registerEvents(new WorldGuardCommandBookListener(this), this);
}
// handle worlds separately to initialize already loaded worlds
WorldGuardWorldListener worldListener = (new WorldGuardWorldListener(this));
for (World world : getServer().getWorlds()) {
worldListener.initWorld(world);
}
worldListener.registerEvents();
Bukkit.getScheduler().runTask(this, () -> {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
ProcessPlayerEvent event = new ProcessPlayerEvent(player);
Events.fire(event);
}
});
((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).setInitialized(true);
((SimpleDomainRegistry) WorldGuard.getInstance().getDomainRegistry()).setInitialized(true);
// Enable metrics
final Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID); // bStats plugin id
if (platform.getGlobalStateManager().extraStats) {
setupCustomCharts(metrics);
}
}
private void setupCustomCharts(Metrics metrics) {
metrics.addCustomChart(new SingleLineChart("region_count", () ->
platform.getRegionContainer().getLoaded().stream().mapToInt(RegionManager::size).sum()));
metrics.addCustomChart(new SimplePie("region_driver", () -> {
RegionDriver driver = platform.getGlobalStateManager().selectedRegionStoreDriver;
return driver instanceof DirectoryYamlDriver ? "yaml" : driver instanceof SQLDriver ? "sql" : "unknown";
}));
metrics.addCustomChart(new 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 SimplePie("chest_protection", () ->
"" + platform.getGlobalStateManager().getWorldConfigs().stream().anyMatch(cfg -> cfg.signChestProtection)));
metrics.addCustomChart(new SimplePie("build_permissions", () ->
"" + platform.getGlobalStateManager().getWorldConfigs().stream().anyMatch(cfg -> cfg.buildPermissions)));
metrics.addCustomChart(new SimplePie("custom_flags", () ->
"" + (WorldGuard.getInstance().getFlagRegistry().size() > Flags.INBUILT_FLAGS.size())));
metrics.addCustomChart(new SimplePie("custom_handlers", () ->
"" + (WorldGuard.getInstance().getPlatform().getSessionManager().customHandlersRegistered())));
}
@Override
public void onDisable() {
WorldGuard.getInstance().disable();
this.getServer().getScheduler().cancelTasks(this);
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
try {
Actor actor = wrapCommandSender(sender);
try {
commands.execute(cmd.getName(), args, actor, actor);
} catch (Throwable t) {
Throwable next = t;
do {
try {
WorldGuard.getInstance().getExceptionConverter().convert(next);
} catch (org.enginehub.piston.exception.CommandException pce) {
if (pce.getCause() instanceof CommandException) {
throw ((CommandException) pce.getCause());
}
}
next = next.getCause();
} while (next != null);
throw t;
}
} catch (CommandPermissionsException e) {
sender.sendMessage(ChatColor.RED + "You don't have permission.");
} catch (MissingNestedCommandException e) {
sender.sendMessage(ChatColor.RED + e.getUsage());
} catch (CommandUsageException e) {
sender.sendMessage(ChatColor.RED + e.getMessage());
sender.sendMessage(ChatColor.RED + e.getUsage());
} catch (WrappedCommandException e) {
sender.sendMessage(ChatColor.RED + e.getCause().getMessage());
} catch (CommandException e) {
sender.sendMessage(ChatColor.RED + e.getMessage());
}
return true;
}
/**
* Check whether a player is in a group.
* This calls the corresponding method in PermissionsResolverManager
*
* @param player The player to check
* @param group The group
* @return whether {@code player} is in {@code group}
*/
public boolean inGroup(OfflinePlayer player, String group) {
try {
return PermissionsResolverManager.getInstance().inGroup(player, group);
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
/**
* Get the groups of a player.
* This calls the corresponding method in PermissionsResolverManager.
* @param player The player to check
* @return The names of each group the playe is in.
*/
public String[] getGroups(OfflinePlayer player) {
try {
return PermissionsResolverManager.getInstance().getGroups(player);
} catch (Throwable t) {
t.printStackTrace();
return new String[0];
}
}
/**
* Checks permissions.
*
* @param sender The sender to check the permission on.
* @param perm The permission to check the permission on.
* @return whether {@code sender} has {@code perm}
*/
public boolean hasPermission(CommandSender sender, String perm) {
if (sender.isOp()) {
if (sender instanceof Player) {
if (platform.getGlobalStateManager().get(BukkitAdapter.adapt(((Player) sender).getWorld())).opPermissions) {
return true;
}
} else {
return true;
}
}
// Invoke the permissions resolver
if (sender instanceof Player) {
Player player = (Player) sender;
return PermissionsResolverManager.getInstance().hasPermission(player.getWorld().getName(), player, perm);
}
return false;
}
/**
* Checks permissions and throws an exception if permission is not met.
*
* @param sender The sender to check the permission on.
* @param perm The permission to check the permission on.
* @throws CommandPermissionsException if {@code sender} doesn't have {@code perm}
*/
public void checkPermission(CommandSender sender, String perm)
throws CommandPermissionsException {
if (!hasPermission(sender, perm)) {
throw new CommandPermissionsException();
}
}
/**
* Gets a copy of the WorldEdit plugin.
*
* @return The WorldEditPlugin instance
* @throws CommandException If there is no WorldEditPlugin available
*/
public WorldEditPlugin getWorldEdit() throws CommandException {
Plugin worldEdit = getServer().getPluginManager().getPlugin("WorldEdit");
if (worldEdit == null) {
throw new CommandException("WorldEdit does not appear to be installed.");
} else if (!worldEdit.isEnabled()) {
throw new CommandException("WorldEdit does not appear to be enabled.");
}
if (worldEdit instanceof WorldEditPlugin) {
return (WorldEditPlugin) worldEdit;
} else {
throw new CommandException("WorldEdit detection failed (report error).");
}
}
/**
* Wrap a player as a LocalPlayer.
*
* @param player The player to wrap
* @return The wrapped player
*/
public LocalPlayer wrapPlayer(Player player) {
return new BukkitPlayer(this, player);
}
/**
* Wrap a player as a LocalPlayer.
*
* @param player The player to wrap
* @param silenced True to silence messages
* @return The wrapped player
*/
public LocalPlayer wrapPlayer(Player player, boolean silenced) {
return new BukkitPlayer(this, player, silenced);
}
public Actor wrapCommandSender(CommandSender sender) {
if (sender instanceof Player player) {
if (Entities.isNPC(player)) return null;
return wrapPlayer(player);
}
try {
return new BukkitCommandSender(getWorldEdit(), sender);
} catch (CommandException e) {
e.printStackTrace();
}
return null;
}
public CommandSender unwrapActor(Actor sender) {
if (sender instanceof BukkitPlayer) {
return ((BukkitPlayer) sender).getPlayer();
} else if (sender instanceof BukkitCommandSender) {
return Bukkit.getConsoleSender(); // TODO Fix
} else {
throw new IllegalArgumentException("Unknown actor type. Please report");
}
}
/**
* Wrap a player as a LocalPlayer.
*
* <p>This implementation is incomplete -- permissions cannot be checked.</p>
*
* @param player The player to wrap
* @return The wrapped player
*/
public LocalPlayer wrapOfflinePlayer(OfflinePlayer player) {
return new BukkitOfflinePlayer(this, player);
}
/**
* Internal method. Do not use as API.
*/
public BukkitConfigurationManager getConfigManager() {
return platform.getGlobalStateManager();
}
/**
* Return a protection query helper object that can be used by another
* plugin to test whether WorldGuard permits an action at a particular
* place.
*
* @return an instance
*/
public ProtectionQuery createProtectionQuery() {
return new ProtectionQuery();
}
/**
* Configure WorldGuard's loggers.
*/
private void configureLogger() {
RecordMessagePrefixer.register(Logger.getLogger("com.sk89q.worldguard"), "[WorldGuard] ");
}
/**
* Create a default configuration file from the .jar.
*
* @param actual The destination file
* @param defaultName The name of the file inside the jar's defaults folder
*/
public void createDefaultConfiguration(File actual, String defaultName) {
// Make parent directories
File parent = actual.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
if (actual.exists()) {
return;
}
try (InputStream stream = getResource("defaults/" + defaultName)){
if (stream == null) throw new FileNotFoundException();
copyDefaultConfig(stream, actual, defaultName);
} catch (IOException e) {
getLogger().severe("Unable to read default configuration: " + defaultName);
}
}
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);
}
}
public PlayerMoveListener getPlayerMoveListener() {
return playerMoveListener;
}
}
@@ -1,54 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.chest;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.chest.SignChestProtection;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
public class BukkitSignChestProtection extends SignChestProtection {
private Boolean isProtectedSign(Sign sign, LocalPlayer player) {
if (sign.getLine(0).equalsIgnoreCase("[Lock]")) {
if (player == null) { // No player, no access
return true;
}
String name = player.getName();
return !name.equalsIgnoreCase(sign.getLine(1).trim())
&& !name.equalsIgnoreCase(sign.getLine(2).trim())
&& !name.equalsIgnoreCase(sign.getLine(3).trim());
}
return null;
}
@Override
public Boolean isProtectedSign(Location block, LocalPlayer player) {
BlockState state = BukkitAdapter.adapt(block).getBlock().getState();
if (!(state instanceof Sign)) {
return null;
}
return isProtectedSign((Sign) state, player);
}
}
@@ -1,156 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.listener;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.BukkitConfigurationManager;
import com.sk89q.worldguard.bukkit.BukkitPlayer;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.cause.Cause;
import com.sk89q.worldguard.bukkit.util.Entities;
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;
/**
* Abstract listener to ease creation of listeners.
*/
class AbstractListener implements Listener {
private final WorldGuardPlugin plugin;
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public AbstractListener(WorldGuardPlugin plugin) {
checkNotNull(plugin);
this.plugin = plugin;
}
/**
* Register events.
*/
public void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
/**
* Get the plugin.
*
* @return the plugin
*/
protected static WorldGuardPlugin getPlugin() {
return WorldGuardPlugin.inst();
}
/**
* Get the global configuration.
*
* @return the configuration
*/
protected static BukkitConfigurationManager getConfig() {
return getPlugin().getConfigManager();
}
/**
* Get the world configuration given a world.
*
* @param world The world to get the configuration for.
* @return The configuration for {@code world}
*/
protected static BukkitWorldConfiguration getWorldConfig(String world) {
return getConfig().get(world);
}
protected static BukkitWorldConfiguration getWorldConfig(org.bukkit.World world) {
return getWorldConfig(world.getName());
}
/**
* Get the world configuration given a player.
*
* @param player The player to get the wold from
* @return The {@link WorldConfiguration} for the player's world
*/
protected static BukkitWorldConfiguration getWorldConfig(LocalPlayer player) {
return getWorldConfig(((BukkitPlayer) player).getPlayer().getWorld());
}
/**
* Return whether region support is enabled.
*
* @param world the world
* @return true if region support is enabled
*/
protected static boolean isRegionSupportEnabled(org.bukkit.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 player && !Entities.isNPC(player)) {
return getPlugin().wrapPlayer(player);
} else if (rootCause instanceof OfflinePlayer offlinePlayer) {
return getPlugin().wrapOfflinePlayer(offlinePlayer);
} else if (rootCause instanceof Entity entity) {
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
BukkitWorldConfiguration config = getWorldConfig(entity.getWorld());
Location loc;
if (PaperLib.isPaper() && config.usePaperEntityOrigin) {
loc = entity.getOrigin();
// Origin world may be null, and thus a Location with a null world created, which cannot be adapted to a WorldEdit location
if (loc == null || loc.getWorld() == null) {
loc = entity.getLocation();
}
} else {
loc = entity.getLocation();
}
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(loc),
config.useMaxPriorityAssociation);
} else if (rootCause instanceof Block block) {
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
Location loc = block.getLocation();
return new DelayedRegionOverlapAssociation(query, BukkitAdapter.adapt(loc),
getWorldConfig(loc.getWorld()).useMaxPriorityAssociation);
} else {
return Associables.constant(Association.NON_MEMBER);
}
}
}
@@ -1,390 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.blacklist.event.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.BlockDispenseBlacklistEvent;
import com.sk89q.worldguard.blacklist.event.BlockInteractBlacklistEvent;
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.BukkitWorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
import com.sk89q.worldguard.bukkit.event.entity.DestroyEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
import com.sk89q.worldguard.bukkit.util.Materials;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.config.WorldConfiguration;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockDispenseArmorEvent;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCreativeEvent;
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 org.bukkit.inventory.PlayerInventory;
import static com.sk89q.worldguard.bukkit.BukkitUtil.createTarget;
/**
* Handle events that need to be processed by the blacklist.
*/
public class BlacklistListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public BlacklistListener(WorldGuardPlugin plugin) {
super(plugin);
}
@EventHandler(ignoreCancelled = true)
public void onBreakBlock(final BreakBlockEvent event) {
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
}
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
event.filter(target -> {
if (!wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target),
createTarget(target.getBlock())), false, false)) {
return false;
} else if (!wcfg.getBlacklist().check(
new ItemDestroyWithBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target),
createTarget(player.getInventory().getItemInMainHand())), false, false)) {
return false;
}
return true;
});
}
@EventHandler(ignoreCancelled = true)
public void onPlaceBlock(final PlaceBlockEvent event) {
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
}
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
event.filter(target -> wcfg.getBlacklist().check(new BlockPlaceBlacklistEvent(
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock())), false, false));
}
@EventHandler(ignoreCancelled = true)
public void onUseBlock(final UseBlockEvent event) {
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
}
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
event.filter(target -> wcfg.getBlacklist().check(new BlockInteractBlacklistEvent(
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock())), false, false));
}
@EventHandler(ignoreCancelled = true)
public void onSpawnEntity(SpawnEntityEvent event) {
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
}
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Material material = Materials.getRelatedMaterial(event.getEffectiveType());
if (material != null) {
if (!wcfg.getBlacklist().check(new ItemUseBlacklistEvent(
localPlayer, BukkitAdapter.asBlockVector(event.getTarget()), createTarget(material)), false, false)) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onDestroyEntity(DestroyEntityEvent event) {
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
}
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Entity target = event.getEntity();
if (target instanceof Item) {
Item item = (Item) target;
if (!wcfg.getBlacklist().check(
new ItemAcquireBlacklistEvent(localPlayer,
BukkitAdapter.asBlockVector(target.getLocation()), createTarget(item.getItemStack())), false, true)) {
event.setCancelled(true);
return;
}
}
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)) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onUseItem(UseItemEvent event) {
final WorldConfiguration wcfg = getWorldConfig(event.getWorld());
// Blacklist guard
if (wcfg.getBlacklist() == null) {
return;
}
Player player = event.getCause().getFirstPlayer();
if (player == null) {
return;
}
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
ItemStack target = event.getItemStack();
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);
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerDropItem(PlayerDropItemEvent event) {
WorldConfiguration wcfg = getWorldConfig(event.getPlayer().getWorld());
if (wcfg.getBlacklist() != null) {
Item ci = event.getItemDrop();
if (!wcfg.getBlacklist().check(
new ItemDropBlacklistEvent(getPlugin().wrapPlayer(event.getPlayer()),
BukkitAdapter.asBlockVector(ci.getLocation()), createTarget(ci.getItemStack())), false, false)) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onBlockDispense(BlockDispenseEvent event) {
BukkitWorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(new BlockDispenseBlacklistEvent(null, BukkitAdapter.asBlockVector(event.getBlock().getLocation()),
createTarget(event.getItem())), false, false)) {
event.setCancelled(true);
}
}
}
@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.getHolder() != null) {
Player player = (Player) entity;
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
new ItemAcquireBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(entity.getLocation()), createTarget(item)), false, false)) {
event.setCancelled(true);
if (inventory.getHolder().equals(player)) {
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:
if (event.getClick() == ClickType.SWAP_OFFHAND) {
return clickedInventory == null ? null : ((PlayerInventory) clickedInventory).getItemInOffHand();
}
return clickedInventory == null ? null : clickedInventory.getItem(event.getHotbarButton());
default:
break;
}
} else if (clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER
&& (event.getView().getTopInventory().getType() == InventoryType.PLAYER
|| event.getView().getTopInventory().getType() == InventoryType.CRAFTING)
&& 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.getType() != Material.AIR && entity instanceof Player) {
Player player = (Player) entity;
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
new ItemAcquireBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(entity.getLocation()), createTarget(item)), false, false)) {
event.setCancelled(true);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
Inventory inventory = player.getInventory();
ItemStack item = inventory.getItem(event.getNewSlot());
if (item != null) {
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
new ItemAcquireBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(player.getLocation()), createTarget(item)), false, false)) {
inventory.setItem(event.getNewSlot(), null);
}
}
}
@EventHandler(ignoreCancelled = true)
public void onBlockDispenseArmor(BlockDispenseArmorEvent event) {
if (!(event.getTargetEntity() instanceof Player)) return;
Player player = ((Player) event.getTargetEntity());
ItemStack stack = event.getItem();
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
if (wcfg.getBlacklist() != null && !wcfg.getBlacklist().check(
new ItemEquipBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(player.getLocation()), createTarget(stack)), false, true)) {
event.setCancelled(true);
}
}
}
@@ -1,160 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.entity.DamageEntityEvent;
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
import com.sk89q.worldguard.bukkit.util.Entities;
import 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.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import java.util.ArrayList;
import java.util.List;
/**
* Handles blocked potions.
*/
public class BlockedPotionsListener extends AbstractListener {
/**
* Construct the listener.
*
* @param plugin an instance of WorldGuardPlugin
*/
public BlockedPotionsListener(WorldGuardPlugin plugin) {
super(plugin);
}
private PotionEffectType getBlockedEffectByArrow(Arrow arrow, BukkitWorldConfiguration wcfg) {
List<PotionEffect> effects = new ArrayList<>();
PotionType potionType = arrow.getBasePotionType();
if (potionType != null) {
effects.addAll(potionType.getPotionEffects());
}
effects.addAll(arrow.getCustomEffects());
for (PotionEffect potionEffect : effects) {
if (wcfg.blockPotions.contains(potionEffect.getType())) {
return potionEffect.getType();
}
}
return null;
}
@EventHandler
public void onProjectile(DamageEntityEvent event) {
if (!(event.getOriginalEvent() instanceof EntityDamageByEntityEvent originalEvent)) {
return;
}
if (!Entities.isPotionArrow(originalEvent.getDamager())) {
return;
}
BukkitWorldConfiguration wcfg = getWorldConfig(event.getWorld());
PotionEffectType blockedEffect = null;
if (originalEvent.getDamager() instanceof SpectralArrow) {
if (wcfg.blockPotions.contains(PotionEffectType.GLOWING)) {
blockedEffect = PotionEffectType.GLOWING;
}
} else if (originalEvent.getDamager() instanceof Arrow arrow) {
blockedEffect = getBlockedEffectByArrow(arrow, wcfg);
}
if (blockedEffect != null) {
Player player = event.getCause().getFirstPlayer();
if (player != null) {
if (getPlugin().hasPermission(player, "worldguard.override.potions")) {
return;
}
player.sendMessage(ChatColor.RED + "Sorry, arrows with "
+ blockedEffect.getName() + " are presently disabled.");
}
event.setCancelled(true);
}
}
@EventHandler
public void onItemInteract(UseItemEvent event) {
BukkitWorldConfiguration wcfg = getWorldConfig(event.getWorld());
ItemStack item = event.getItemStack();
if (item.getType() != Material.POTION
&& item.getType() != Material.SPLASH_POTION
&& item.getType() != Material.LINGERING_POTION) {
return;
}
if (!wcfg.blockPotions.isEmpty()) {
PotionEffectType blockedEffect = null;
if (!(item.getItemMeta() instanceof PotionMeta meta)) {
return;
}
// Find the first blocked effect
List<PotionEffect> effects = new ArrayList<>();
if (meta.getBasePotionType() != null) {
effects.addAll(meta.getBasePotionType().getPotionEffects());
}
effects.addAll(meta.getCustomEffects());
for (PotionEffect potionEffect : effects) {
if (wcfg.blockPotions.contains(potionEffect.getType())) {
blockedEffect = potionEffect.getType();
break;
}
}
if (blockedEffect != null) {
Player player = event.getCause().getFirstPlayer();
if (player != null) {
if (getPlugin().hasPermission(player, "worldguard.override.potions")) {
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, " +
"due to limitations (and because overly-reliable potion blocking is on).");
event.setCancelled(true);
}
} else {
player.sendMessage(ChatColor.RED + "Sorry, potions with "
+ blockedEffect.getName() + " are presently disabled.");
event.setCancelled(true);
}
} else {
event.setCancelled(true);
}
}
}
}
}
@@ -1,161 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityMountEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;
import org.bukkit.plugin.PluginManager;
import org.bukkit.util.Vector;
public class PlayerMoveListener extends AbstractListener {
public PlayerMoveListener(WorldGuardPlugin plugin) {
super(plugin);
}
@Override
public void registerEvents() {
if (WorldGuard.getInstance().getPlatform().getGlobalStateManager().usePlayerMove) {
PluginManager pm = getPlugin().getServer().getPluginManager();
pm.registerEvents(this, getPlugin());
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerRespawn(PlayerRespawnEvent event) {
LocalPlayer player = getPlugin().wrapPlayer(event.getPlayer());
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
session.testMoveTo(player, BukkitAdapter.adapt(event.getRespawnLocation()), MoveType.RESPAWN, true);
}
@EventHandler
public void onVehicleEnter(VehicleEnterEvent event) {
Entity entity = event.getEntered();
if (entity instanceof Player) {
LocalPlayer player = getPlugin().wrapPlayer((Player) entity);
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
if (null != session.testMoveTo(player, BukkitAdapter.adapt(event.getVehicle().getLocation()), MoveType.EMBARK, true)) {
event.setCancelled(true);
}
}
}
@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 = getPlugin().wrapPlayer(player);
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer);
MoveType moveType = MoveType.MOVE;
if (event.getPlayer().isGliding()) {
moveType = MoveType.GLIDE;
} else if (event.getPlayer().isSwimming()) {
moveType = MoveType.SWIM;
} else if (event.getPlayer().getVehicle() != null && event.getPlayer().getVehicle() instanceof AbstractHorse) {
moveType = MoveType.RIDE;
}
com.sk89q.worldedit.util.Location weLocation = session.testMoveTo(localPlayer, BukkitAdapter.adapt(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(to.getPitch());
override.setYaw(to.getYaw());
event.setTo(override.clone());
Entity vehicle = player.getVehicle();
if (vehicle != null) {
vehicle.eject();
Entity current = vehicle;
while (current != null) {
current.eject();
vehicle.setVelocity(new Vector());
if (vehicle instanceof LivingEntity) {
vehicle.teleport(override.clone());
} else {
vehicle.teleport(override.clone().add(0, 1, 0));
}
current = current.getVehicle();
}
player.teleport(override.clone().add(0, 1, 0));
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> player.teleport(override.clone().add(0, 1, 0)), 1);
}
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
final Player player = event.getPlayer();
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer);
com.sk89q.worldedit.util.Location loc = session.testMoveTo(localPlayer,
BukkitAdapter.adapt(event.getPlayer().getLocation()), MoveType.OTHER_CANCELLABLE); // white lie
if (loc != null) {
player.teleport(BukkitAdapter.adapt(loc));
}
session.uninitialize(localPlayer);
}
@EventHandler
public void onEntityMount(EntityMountEvent event) {
Entity entity = event.getEntity();
if (entity instanceof Player) {
LocalPlayer player = getPlugin().wrapPlayer((Player) entity);
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
if (null != session.testMoveTo(player, BukkitAdapter.adapt(event.getMount().getLocation()), MoveType.EMBARK, true)) {
event.setCancelled(true);
}
}
}
}
@@ -1,750 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.util.Materials;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.config.WorldConfiguration;
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.util.SpongeUtil;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.entity.Player;
import org.bukkit.entity.Snowman;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockGrowEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.block.MoistureChangeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
/**
* The listener for block events.
*/
public class WorldGuardBlockListener extends AbstractListener {
/**
* Construct the object.
*
* @param plugin The plugin instance
*/
public WorldGuardBlockListener(WorldGuardPlugin plugin) {
super(plugin);
}
/*
* Called when a block is broken.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = getWorldConfig(player.getWorld());
if (!wcfg.itemDurability) {
ItemStack held = player.getInventory().getItemInMainHand();
ItemMeta meta = held.getItemMeta();
if (meta != null) {
((Damageable) meta).setDamage(0);
held.setItemMeta(meta);
player.getInventory().setItemInMainHand(held);
}
}
}
/*
* Called when fluids flow.
*/
@EventHandler(ignoreCancelled = true)
public void onBlockFromTo(BlockFromToEvent event) {
World world = event.getBlock().getWorld();
Block blockFrom = event.getBlock();
Block blockTo = event.getToBlock();
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
Material fromType = blockFrom.getType();
boolean isWater = Materials.isWater(fromType);
boolean isLava = fromType == Material.LAVA;
boolean isAir = fromType == Material.AIR;
WorldConfiguration wcfg = getWorldConfig(world);
if (wcfg.simulateSponge && isWater) {
int ox = blockTo.getX();
int oy = blockTo.getY();
int oz = blockTo.getZ();
for (int cx = -wcfg.spongeRadius; cx <= wcfg.spongeRadius; cx++) {
for (int cy = -wcfg.spongeRadius; cy <= wcfg.spongeRadius; cy++) {
for (int cz = -wcfg.spongeRadius; cz <= wcfg.spongeRadius; cz++) {
Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz);
if (sponge.getType() == Material.SPONGE
&& (!wcfg.redstoneSponges || !sponge.isBlockIndirectlyPowered())) {
event.setCancelled(true);
return;
}
}
}
}
}
/*if (plugin.classicWater && isWater) {
int blockBelow = blockFrom.getRelative(0, -1, 0).getTypeId();
if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) {
blockFrom.setTypeId(9);
if (blockTo.getTypeId() == 0) {
blockTo.setTypeId(9);
}
return;
}
}*/
// Check the fluid block (from) whether it is air.
// If so and the target block is protected, cancel the event
if (!wcfg.preventWaterDamage.isEmpty()) {
Material targetId = blockTo.getType();
if ((isAir || isWater) &&
wcfg.preventWaterDamage.contains(BukkitAdapter.asBlockType(targetId).getId())) {
event.setCancelled(true);
return;
}
}
if (!wcfg.allowedLavaSpreadOver.isEmpty() && isLava) {
Material targetId = blockTo.getRelative(0, -1, 0).getType();
if (!wcfg.allowedLavaSpreadOver.contains(BukkitAdapter.asBlockType(targetId).getId())) {
event.setCancelled(true);
return;
}
}
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;
}
if (wcfg.highFreqFlags && isLava
&& !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().queryState(BukkitAdapter.adapt(blockFrom.getLocation()), (RegionAssociable) null, Flags.LAVA_FLOW))) {
event.setCancelled(true);
return;
}
}
/*
* Called when a block gets ignited.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockIgnite(BlockIgniteEvent event) {
IgniteCause cause = event.getCause();
Block block = event.getBlock();
World world = block.getWorld();
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
WorldConfiguration wcfg = getWorldConfig(world);
boolean isFireSpread = cause == IgniteCause.SPREAD;
if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) {
event.setCancelled(true);
return;
}
if (wcfg.preventLavaFire && cause == IgniteCause.LAVA) {
event.setCancelled(true);
return;
}
if (wcfg.disableFireSpread && isFireSpread) {
event.setCancelled(true);
return;
}
if (wcfg.blockLighter && (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL)
&& event.getPlayer() != null
&& !getPlugin().hasPermission(event.getPlayer(), "worldguard.override.lighter")) {
event.setCancelled(true);
return;
}
if (wcfg.fireSpreadDisableToggle && isFireSpread) {
event.setCancelled(true);
return;
}
if (!wcfg.disableFireSpreadBlocks.isEmpty() && isFireSpread) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
if (wcfg.disableFireSpreadBlocks.contains(BukkitAdapter.asBlockType(world.getBlockAt(x, y - 1, z).getType()).getId())
|| wcfg.disableFireSpreadBlocks.contains(BukkitAdapter.asBlockType(world.getBlockAt(x + 1, y, z).getType()).getId())
|| wcfg.disableFireSpreadBlocks.contains(BukkitAdapter.asBlockType(world.getBlockAt(x - 1, y, z).getType()).getId())
|| wcfg.disableFireSpreadBlocks.contains(BukkitAdapter.asBlockType(world.getBlockAt(x, y, z - 1).getType()).getId())
|| wcfg.disableFireSpreadBlocks.contains(BukkitAdapter.asBlockType(world.getBlockAt(x, y, z + 1).getType()).getId())) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions) {
ApplicableRegionSet set =
WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(block.getLocation()));
if (wcfg.highFreqFlags && isFireSpread
&& !set.testState(null, Flags.FIRE_SPREAD)) {
event.setCancelled(true);
return;
}
if (wcfg.highFreqFlags && cause == IgniteCause.LAVA
&& !set.testState(null, Flags.LAVA_FIRE)) {
event.setCancelled(true);
return;
}
if (cause == IgniteCause.FIREBALL && event.getPlayer() == null) {
// wtf bukkit, FIREBALL is supposed to be reserved to players
if (!set.testState(null, Flags.GHAST_FIREBALL)) {
event.setCancelled(true);
return;
}
}
if (cause == IgniteCause.LIGHTNING && !set.testState(null, Flags.LIGHTNING)) {
event.setCancelled(true);
return;
}
}
}
/*
* Called when a block is destroyed from burning.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockBurn(BlockBurnEvent event) {
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
BukkitWorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
if (wcfg.disableFireSpread) {
event.setCancelled(true);
return;
}
if (wcfg.fireSpreadDisableToggle) {
Block block = event.getBlock();
event.setCancelled(true);
checkAndDestroyFireAround(block.getWorld(), block.getX(), block.getY(), block.getZ());
return;
}
if (!wcfg.disableFireSpreadBlocks.isEmpty()) {
Block block = event.getBlock();
if (wcfg.disableFireSpreadBlocks.contains(BukkitAdapter.asBlockType(block.getType()).getId())) {
event.setCancelled(true);
checkAndDestroyFireAround(block.getWorld(), block.getX(), block.getY(), block.getZ());
return;
}
}
if (wcfg.isChestProtected(BukkitAdapter.adapt(event.getBlock().getLocation()))) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions) {
Block block = event.getBlock();
int x = block.getX();
int y = block.getY();
int z = block.getZ();
ApplicableRegionSet set =
WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(block.getLocation()));
if (!set.testState(null, Flags.FIRE_SPREAD)) {
checkAndDestroyFireAround(block.getWorld(), x, y, z);
event.setCancelled(true);
}
}
}
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 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);
}
}
/*
* Called when block physics occurs.
*/
@EventHandler(ignoreCancelled = true)
public void onBlockPhysics(BlockPhysicsEvent event) {
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
final Material id = event.getBlock().getType();
if (id == Material.GRAVEL && wcfg.noPhysicsGravel) {
event.setCancelled(true);
return;
}
if ((id == Material.SAND || id == Material.RED_SAND) && wcfg.noPhysicsSand) {
event.setCancelled(true);
return;
}
if (id == Material.NETHER_PORTAL && wcfg.allowPortalAnywhere) {
event.setCancelled(true);
return;
}
if (id == Material.LADDER && wcfg.ropeLadders) {
if (event.getBlock().getRelative(0, 1, 0).getType() == Material.LADDER) {
event.setCancelled(true);
return;
}
}
}
/*
* Called when a player places a block.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) {
Block target = event.getBlock();
World world = target.getWorld();
WorldConfiguration wcfg = getWorldConfig(world);
if (wcfg.simulateSponge && target.getType() == Material.SPONGE) {
if (wcfg.redstoneSponges && target.isBlockIndirectlyPowered()) {
return;
}
int ox = target.getX();
int oy = target.getY();
int oz = target.getZ();
SpongeUtil.clearSpongeWater(BukkitAdapter.adapt(world), ox, oy, oz);
}
}
/*
* Called when redstone changes.
*/
@EventHandler(priority = EventPriority.HIGH)
public void onBlockRedstoneChange(BlockRedstoneEvent event) {
Block blockTo = event.getBlock();
World world = blockTo.getWorld();
WorldConfiguration wcfg = getWorldConfig(world);
if (wcfg.simulateSponge && wcfg.redstoneSponges) {
int ox = blockTo.getX();
int oy = blockTo.getY();
int oz = blockTo.getZ();
for (int cx = -1; cx <= 1; cx++) {
for (int cy = -1; cy <= 1; cy++) {
for (int cz = -1; cz <= 1; cz++) {
Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz);
if (sponge.getType() == Material.SPONGE
&& sponge.isBlockIndirectlyPowered()) {
SpongeUtil.clearSpongeWater(BukkitAdapter.adapt(world), ox + cx, oy + cy, oz + cz);
} else if (sponge.getType() == Material.SPONGE
&& !sponge.isBlockIndirectlyPowered()) {
SpongeUtil.addSpongeWater(BukkitAdapter.adapt(world), ox + cx, oy + cy, oz + cz);
}
}
}
}
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onLeavesDecay(LeavesDecayEvent event) {
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
if (wcfg.disableLeafDecay) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions) {
if (!StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.LEAF_DECAY))) {
event.setCancelled(true);
}
}
}
/*
* Called when a block is formed based on world conditions.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockForm(BlockFormEvent event) {
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
Material type = event.getNewState().getType();
if (event instanceof EntityBlockFormEvent) {
if (((EntityBlockFormEvent) event).getEntity() instanceof Snowman) {
if (wcfg.disableSnowmanTrails) {
event.setCancelled(true);
return;
}
}
return;
}
if (type == Material.ICE) {
if (wcfg.disableIceFormation) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.ICE_FORM))) {
event.setCancelled(true);
return;
}
}
if (type == Material.SNOW) {
if (wcfg.disableSnowFormation) {
event.setCancelled(true);
return;
}
if (!wcfg.allowedSnowFallOver.isEmpty()) {
Material targetId = event.getBlock().getRelative(0, -1, 0).getType();
if (!wcfg.allowedSnowFallOver.contains(BukkitAdapter.asBlockType(targetId).getId())) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.SNOW_FALL))) {
event.setCancelled(true);
return;
}
}
if (Materials.isUnwaxedCopper(event.getBlock().getType())) {
if (wcfg.disableCopperBlockFade) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.COPPER_FADE))) {
event.setCancelled(true);
return;
}
}
}
/*
* Called when a block spreads based on world conditions.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockSpread(BlockSpreadEvent event) {
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
Material newType = event.getNewState().getType(); // craftbukkit randomly gives AIR as event.getSource even if that block is not air
if (Materials.isMushroom(newType)) {
if (wcfg.disableMushroomSpread) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.MUSHROOMS))) {
event.setCancelled(true);
return;
}
}
if (newType == Material.GRASS_BLOCK) {
if (wcfg.disableGrassGrowth) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.GRASS_SPREAD))) {
event.setCancelled(true);
return;
}
}
if (newType == Material.MYCELIUM) {
if (wcfg.disableMyceliumSpread) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.MYCELIUM_SPREAD))) {
event.setCancelled(true);
return;
}
}
if (Materials.isVine(newType)) {
if (wcfg.disableVineGrowth) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.VINE_GROWTH))) {
event.setCancelled(true);
return;
}
}
if (Materials.isAmethystGrowth(newType) || newType == Material.POINTED_DRIPSTONE) {
if (wcfg.disableRockGrowth) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.ROCK_GROWTH))) {
event.setCancelled(true);
return;
}
}
if (Materials.isSculkGrowth(newType)) {
if (wcfg.disableSculkGrowth) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.SCULK_GROWTH))) {
event.setCancelled(true);
return;
}
}
handleGrow(event, event.getBlock().getLocation(), newType);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockGrow(BlockGrowEvent event) {
Location loc = event.getBlock().getLocation();
final Material type = event.getNewState().getType();
handleGrow(event, loc, type);
}
private void handleGrow(Cancellable event, Location loc, Material type) {
WorldConfiguration wcfg = getWorldConfig(loc.getWorld());
if (Materials.isCrop(type)) {
if (wcfg.disableCropGrowth) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(loc), (RegionAssociable) null, Flags.CROP_GROWTH))) {
event.setCancelled(true);
return;
}
}
}
/*
* Called when a block fades.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockFade(BlockFadeEvent event) {
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
if (event.getBlock().getType() == Material.ICE) {
if (wcfg.disableIceMelting) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.ICE_MELT))) {
event.setCancelled(true);
return;
}
} else if (event.getBlock().getType() == Material.FROSTED_ICE) {
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.FROSTED_ICE_MELT))) {
event.setCancelled(true);
return;
}
} else if (event.getBlock().getType() == Material.SNOW) {
if (wcfg.disableSnowMelting) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.SNOW_MELT))) {
event.setCancelled(true);
return;
}
} else if (event.getBlock().getType() == Material.FARMLAND) {
if (wcfg.disableSoilDehydration) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.SOIL_DRY))) {
event.setCancelled(true);
return;
}
} else if (Materials.isCoral(event.getBlock().getType())) {
if (wcfg.disableCoralBlockFade) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions && !StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.CORAL_FADE))) {
event.setCancelled(true);
return;
}
}
}
@EventHandler(ignoreCancelled = true)
public void onBlockExplode(BlockExplodeEvent event) {
ConfigurationManager cfg = getConfig();
if (cfg.activityHaltToggle) {
event.setCancelled(true);
return;
}
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
if (wcfg.blockOtherExplosions) {
event.setCancelled(true);
}
}
/**
* Called when the moisture level of a block changes
*/
@EventHandler(ignoreCancelled = true)
public void onMoistureChange(MoistureChangeEvent event) {
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
if (wcfg.disableSoilMoistureChange) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions) {
if (!StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.MOISTURE_CHANGE))) {
event.setCancelled(true);
}
}
}
}
@@ -1,80 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.listener;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.util.Entities;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.util.Locations;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.util.Vector;
import java.util.List;
import java.util.stream.Collectors;
public class WorldGuardVehicleListener extends AbstractListener {
public WorldGuardVehicleListener(WorldGuardPlugin plugin) {
super(plugin);
}
@EventHandler
public void onVehicleMove(VehicleMoveEvent event) {
Vehicle vehicle = event.getVehicle();
if (vehicle.getPassengers().isEmpty()) return;
List<Player> playerPassengers = vehicle.getPassengers().stream()
.filter(ent -> ent instanceof Player).map(ent -> (Player) ent).collect(Collectors.toList());
if (playerPassengers.isEmpty()) {
return;
}
World world = vehicle.getWorld();
WorldConfiguration wcfg = getWorldConfig(world);
if (wcfg.useRegions) {
// Did we move a block?
if (Locations.isDifferentBlock(BukkitAdapter.adapt(event.getFrom()), BukkitAdapter.adapt(event.getTo()))) {
for (Player player : playerPassengers) {
if (Entities.isNPC(player)) continue;
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
Location lastValid;
if ((lastValid = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer)
.testMoveTo(localPlayer, BukkitAdapter.adapt(event.getTo()), MoveType.RIDE)) != null) {
vehicle.setVelocity(new Vector(0, 0, 0));
vehicle.teleport(event.getFrom());
if (Locations.isDifferentBlock(lastValid, BukkitAdapter.adapt(event.getFrom()))) {
Vector dir = player.getLocation().getDirection();
player.teleport(BukkitAdapter.adapt(lastValid).setDirection(dir));
}
return;
}
}
}
}
}
}
@@ -1,95 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.session;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.BukkitPlayer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
import com.sk89q.worldguard.bukkit.util.Entities;
import com.sk89q.worldguard.session.AbstractSessionManager;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.util.Collection;
/**
* Keeps tracks of sessions and also does session-related handling
* (flags, etc.).
*/
public class BukkitSessionManager extends AbstractSessionManager implements Runnable, Listener {
/**
* Re-initialize handlers and clear "last position," "last state," etc.
* information for all players.
*/
@Override
public void resetAllStates() {
Collection<? extends Player> players = Bukkit.getServer().getOnlinePlayers();
for (Player player : players) {
BukkitPlayer bukkitPlayer = new BukkitPlayer(WorldGuardPlugin.inst(), player);
Session session = getIfPresent(bukkitPlayer);
if (session != null) {
session.resetState(bukkitPlayer);
}
}
}
@EventHandler
public void onPlayerProcess(ProcessPlayerEvent event) {
// Pre-load a session
LocalPlayer player = WorldGuardPlugin.inst().wrapPlayer(event.getPlayer());
get(player).initialize(player);
}
@Override
public void run() {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
get(localPlayer).tick(localPlayer);
}
}
@Override
public boolean hasBypass(LocalPlayer player, World world) {
if (player instanceof BukkitPlayer bukkitPlayer) {
if (Entities.isNPC(bukkitPlayer.getPlayer())
&& WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).fakePlayerBuildOverride) {
return true;
}
if (!((BukkitPlayer) player).getPlayer().isOnline()) {
return false;
}
}
return super.hasBypass(player, world);
}
public void shutdown() {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
get(localPlayer).uninitialize(localPlayer);
}
}
}
@@ -1,69 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.util;
import io.papermc.lib.PaperLib;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Bed;
import org.bukkit.block.data.type.Chest;
import org.bukkit.util.Vector;
import java.util.Collections;
import java.util.List;
/**
* Utility methods to deal with blocks.
*/
public final class Blocks {
private Blocks() {
}
/**
* Get a list of connected blocks to the given block, not including
* the given block.
*
* @param block the block
* @return a list of connected blocks, not including the given block
*/
public static List<Block> getConnected(Block block) {
BlockState state = PaperLib.getBlockState(block, false).getState();
BlockData data = state.getBlockData();
if (data instanceof Bed) {
Bed bed = (Bed) data;
return Collections.singletonList(block.getRelative(bed.getPart() == Bed.Part.FOOT
? bed.getFacing() : bed.getFacing().getOppositeFace()));
} else if (data instanceof Chest) {
final Chest chest = (Chest) data;
Chest.Type type = chest.getType();
if (type == Chest.Type.SINGLE) {
return Collections.emptyList();
}
Vector offset = chest.getFacing().getDirection().rotateAroundY(Math.PI / 2 * (type == Chest.Type.LEFT ? -1 : 1));
return Collections.singletonList(block.getRelative((int) Math.round(offset.getX()), 0, (int) Math.round(offset.getZ())));
} else {
return Collections.emptyList();
}
}
}
@@ -1,167 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.util;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.PluginClassLoader;
import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Validates that certain specified classes came from the same source as
* a plugin.
* This is copied from the same class in WorldEdit because unfortunately
* trying to use WorldEdit's means we're susceptible to getting a bad version
* of this class if another plugin shades it....which is exactly what we're
* trying to detect and report.
*/
public class ClassSourceValidator {
private static final String SEPARATOR_LINE = Strings.repeat("*", 46);
private static final Method loadClass;
private static Class<?> pluginClassLoaderClass;
static {
Method tmp;
try {
pluginClassLoaderClass = Class.forName("org.bukkit.plugin.java.PluginClassLoader", false,
Bukkit.class.getClassLoader());
tmp = pluginClassLoaderClass.getDeclaredMethod("loadClass0",
String.class, boolean.class, boolean.class, boolean.class);
tmp.setAccessible(true);
} catch (NoSuchMethodException | ClassNotFoundException e) {
tmp = null;
}
loadClass = tmp;
}
private final Plugin plugin;
@Nullable
private final ClassLoader expectedClassLoader;
/**
* Create a new instance.
*
* @param plugin The plugin
*/
public ClassSourceValidator(Plugin plugin) {
checkNotNull(plugin, "plugin");
this.plugin = plugin;
this.expectedClassLoader = plugin.getClass().getClassLoader();
}
/**
* Return a map of classes that been loaded from a different source.
*
* @param classes A list of classes to check
* @return The results
*/
public Map<Class<?>, Plugin> findMismatches(List<Class<?>> classes) {
checkNotNull(classes, "classes");
if (expectedClassLoader == null || loadClass == null) {
return ImmutableMap.of();
}
Map<Class<?>, Plugin> mismatches = new HashMap<>();
for (Plugin target : Bukkit.getPluginManager().getPlugins()) {
if (target == plugin) {
continue;
}
ClassLoader targetLoader = target.getClass().getClassLoader();
if (!(pluginClassLoaderClass.isAssignableFrom(targetLoader.getClass()))) {
continue;
}
for (Class<?> testClass : classes) {
Class<?> targetClass;
try {
targetClass = (Class<?>) loadClass.invoke(targetLoader, testClass.getName(), false, false, false);
} catch (IllegalAccessException | InvocationTargetException ignored) {
continue;
}
if (targetClass.getClassLoader() != expectedClassLoader) {
mismatches.putIfAbsent(testClass, targetClass.getClassLoader() == targetLoader ? target : null);
}
}
}
return mismatches;
}
/**
* Reports classes that have come from a different source.
*
* <p>The warning is emitted to the log.</p>
*
* @param classes The list of classes to check
*/
public void reportMismatches(List<Class<?>> classes) {
if (Boolean.getBoolean("enginehub.disable.class.source.validation")) {
return;
}
Map<Class<?>, Plugin> mismatches = findMismatches(classes);
if (mismatches.isEmpty()) {
return;
}
StringBuilder builder = new StringBuilder("\n");
builder.append(SEPARATOR_LINE).append("\n");
builder.append("** /!\\ SEVERE WARNING /!\\\n");
builder.append("** \n");
builder.append("** A plugin developer has included a portion of \n");
builder.append("** ").append(plugin.getName()).append(" into their own plugin, so rather than using\n");
builder.append("** the version of ").append(plugin.getName()).append(" that you downloaded, you\n");
builder.append("** will be using a broken mix of old ").append(plugin.getName()).append(" (that came\n");
builder.append("** with the plugin) and your downloaded version. THIS MAY\n");
builder.append("** SEVERELY BREAK ").append(plugin.getName().toUpperCase(Locale.ROOT)).append(" AND ALL OF ITS FEATURES.\n");
builder.append("**\n");
builder.append("** This may have happened because the developer is using\n");
builder.append("** the ").append(plugin.getName()).append(" API and thinks that including\n");
builder.append("** ").append(plugin.getName()).append(" is necessary. However, it is not!\n");
builder.append("**\n");
builder.append("** Here are some files that have been overridden:\n");
builder.append("** \n");
for (Map.Entry<Class<?>, Plugin> entry : mismatches.entrySet()) {
Plugin badPlugin = entry.getValue();
String url = badPlugin == null
? "(unknown)"
: badPlugin.getName() + " (" + badPlugin.getClass().getProtectionDomain().getCodeSource().getLocation() + ")";
builder.append("** '").append(entry.getKey().getSimpleName()).append("' came from '").append(url).append("'\n");
}
builder.append("**\n");
builder.append("** Please report this to the plugins' developers.\n");
builder.append(SEPARATOR_LINE).append("\n");
plugin.getLogger().severe(builder.toString());
}
}
File diff suppressed because it is too large. Load diff
@@ -1,48 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.util.report;
import com.sk89q.worldedit.util.report.DataReport;
import io.papermc.paper.datapack.Datapack;
import org.bukkit.Bukkit;
import java.util.Collection;
/**
* A report for current datapacks with some information. Only available on Paper
*/
public class DatapackReport extends DataReport {
public DatapackReport() {
super("DataPacks");
Collection<Datapack> packs = Bukkit.getDatapackManager().getPacks();
append("Datapack Count", packs.size());
append("Datapack Enabled Count", Bukkit.getDatapackManager().getEnabledPacks().size());
for (Datapack pack : packs) {
DataReport report = new DataReport("DataPack: " + pack.getName());
report.append("Enabled?", pack.isEnabled());
report.append("Name", pack.getName());
report.append("Compatibility", pack.getCompatibility().name());
append(report.getTitle(), report);
}
}
}
@@ -1,63 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.util.profile.resolver;
import com.sk89q.worldguard.util.profile.Profile;
import io.papermc.lib.PaperLib;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.UUID;
/**
* @deprecated Use {@link com.sk89q.worldguard.util.profile.resolver.PaperPlayerService} instead
*/
@Deprecated(forRemoval = true)
public final class PaperProfileService extends SingleRequestService {
private static final PaperPlayerService SUPER = PaperPlayerService.getInstance();
private static final PaperProfileService INSTANCE = new PaperProfileService();
private PaperProfileService() {
if (!PaperLib.isPaper()) {
throw new IllegalStateException("Attempt to access PaperProfileService on non-Paper server.");
}
}
@Override
public int getIdealRequestLimit() {
return SUPER.getIdealRequestLimit();
}
@Override
@Nullable
public Profile findByName(String name) throws IOException, InterruptedException {
return SUPER.findByName(name);
}
@Nullable
@Override
public Profile findByUuid(UUID uuid) throws IOException, InterruptedException {
return SUPER.findByUuid(uuid);
}
public static PaperProfileService getInstance() {
return INSTANCE;
}
}
@@ -1,6 +0,0 @@
name: WorldGuard
main: com.sk89q.worldguard.bukkit.WorldGuardPlugin
version: "${internalVersion}"
depend: [WorldEdit]
softdepend: [CommandBook]
api-version: "1.21"
+23
View File
@@ -0,0 +1,23 @@
apply plugin: 'eclipse'
apply plugin: 'idea'
dependencies {
compile 'com.sk89q.worldedit:worldedit-core:6.1.1-SNAPSHOT'
compile 'com.sk89q.intake:intake:4.2-SNAPSHOT'
compile 'com.sk89q:squirrelid:0.1.0'
compile 'org.flywaydb:flyway-core:3.0'
compile 'org.khelekore:prtree:1.5.0'
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/main/resources'
}
}
}
build.dependsOn(shadowJar)
-51
View File
@@ -1,51 +0,0 @@
import org.cadixdev.gradle.licenser.LicenseExtension
plugins {
`java-library`
id("buildlogic.core-and-platform")
}
dependencies {
constraints {
"implementation"(libs.snakeyaml) {
because("Bukkit provides SnakeYaml")
}
}
"api"(project(":worldguard-libs:core"))
"api"(libs.worldedit.core)
"implementation"(libs.flyway.core)
"implementation"(libs.snakeyaml)
"implementation"(libs.guava)
"compileOnlyApi"(libs.jsr305)
"implementation"(libs.gson)
"compileOnly"(libs.worldedit.libs.ap)
"annotationProcessor"(libs.worldedit.libs.ap)
// ensure this is on the classpath for the AP
"annotationProcessor"(libs.guava)
"compileOnly"(libs.autoService) {
because("Needed to resolve annotations in Piston")
}
"testImplementation"(libs.hamcrest.library)
}
tasks.compileJava {
dependsOn(":worldguard-libs:build")
options.compilerArgs.add("-Aarg.name.key.prefix=")
}
configure<LicenseExtension> {
exclude {
it.file.startsWith(project.layout.buildDirectory.get().asFile)
}
}
configure<PublishingExtension> {
publications.named<MavenPublication>("maven") {
artifactId = the<BasePluginExtension>().archivesName.get()
from(components["java"])
}
}
@@ -1,223 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard;
import com.google.common.annotations.Beta;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldguard.domains.Association;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.util.List;
public interface LocalPlayer extends Player, RegionAssociable {
/**
* Returns true if this player is inside a group.
*
* @param group The group to check
* @return Whether this player is in {@code group}
*/
boolean hasGroup(String group);
/**
* Kick this player.
*
* @param msg The message to kick the player with
*/
void kick(String msg);
/**
* Ban this player.
*
* @param msg The message to ban the player with
*/
void ban(String msg);
@Override
default Association getAssociation(List<ProtectedRegion> regions) {
boolean member = false;
for (ProtectedRegion region : regions) {
if (region.isOwner(this)) {
return Association.OWNER;
} else if (!member && region.isMember(this)) {
member = true;
}
}
return member ? Association.MEMBER : Association.NON_MEMBER;
}
/**
* Gets the health of this player.
*
* @return The health
*/
double getHealth();
/**
* Sets the health of this player.
*
* @param health The health
*/
void setHealth(double health);
/**
* Gets the max health of this player.
*
* @return The max health
*/
double getMaxHealth();
/**
* Gets the food level of this player.
*
* @return The food level
*/
double getFoodLevel();
/**
* Sets the food level of this player.
*
* @param foodLevel The food level
*/
void setFoodLevel(double foodLevel);
/**
* Gets the saturation of this player.
*
* @return The saturation
*/
double getSaturation();
/**
* Sets the saturation of this player.
*
* @param saturation The saturation
*/
void setSaturation(double saturation);
/**
* Gets the exhaustion of this player.
*
* @return The exhaustion
*/
float getExhaustion();
/**
* Sets the exhaustion of this player.
*
* @param exhaustion The exhaustion
*/
void setExhaustion(float exhaustion);
/**
* Gets the players weather
*
* @return The players weather
*/
WeatherType getPlayerWeather();
/**
* Sets the players WeatherType
*
* @param weather The weather type
*/
void setPlayerWeather(WeatherType weather);
/**
* Resets the players weather to normal.
*/
void resetPlayerWeather();
/**
* Gets if the players time is relative.
*
* @return If the time is relative
*/
boolean isPlayerTimeRelative();
/**
* Gets the time offset of the player.
*
* @return The players time offset
*/
long getPlayerTimeOffset();
/**
* Sets the players time.
*
* @param time The players time
* @param relative If it's relative
*/
void setPlayerTime(long time, boolean relative);
/**
* Resets the players time to normal.
*/
void resetPlayerTime();
// TODO Move this to WorldEdit's Entity class - honestly most of this class could be a Facet
/**
* Gets the number of ticks the player is on fire for.
*
* @return The number of fire ticks
*/
int getFireTicks();
/**
* Sets the number of ticks the player is on fire for.
*
* @param fireTicks The fire ticks
*/
void setFireTicks(int fireTicks);
/**
* Sets the target of the compass
*
* @param location The location
*/
void setCompassTarget(Location location);
/**
* This should preferably take Components but there's no way to do that yet
*
* @param title the title to display
* @param subtitle the subtitle to display
*/
@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);
}
@@ -1,251 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldguard.domains.registry.DomainRegistry;
import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
import com.sk89q.worldguard.util.profile.cache.HashMapCache;
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import com.sk89q.worldguard.util.profile.cache.SQLiteCache;
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;
import com.sk89q.worldedit.util.task.Task;
import com.sk89q.worldguard.internal.platform.WorldGuardPlatform;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
import com.sk89q.worldguard.util.WorldGuardExceptionConverter;
import com.sk89q.worldguard.util.concurrent.EvenMoreExecutors;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public final class WorldGuard {
public static final Logger logger = Logger.getLogger(WorldGuard.class.getCanonicalName());
private static String version;
private static final WorldGuard instance = new WorldGuard();
private WorldGuardPlatform platform;
private final SimpleFlagRegistry flagRegistry = new SimpleFlagRegistry();
private final SimpleDomainRegistry domainRegistry = new SimpleDomainRegistry();
private final Supervisor supervisor = new SimpleSupervisor();
private ProfileCache profileCache;
private ProfileService profileService;
private ListeningExecutorService executorService;
private WorldGuardExceptionConverter exceptionConverter = new WorldGuardExceptionConverter();
static {
Flags.registerAll();
}
public static WorldGuard getInstance() {
return instance;
}
private WorldGuard() {
}
public void setup() {
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 | UnsatisfiedLinkError ignored) {
logger.log(Level.WARNING, "Failed to initialize SQLite profile cache. Cache is memory-only.");
profileCache = new HashMapCache();
}
profileService = getPlatform().createProfileService(profileCache);
getPlatform().load();
}
/**
* The WorldGuard Platform.
* The Platform is only available after WorldGuard is enabled.
*
* @return The platform
*/
public WorldGuardPlatform getPlatform() {
checkNotNull(platform, "WorldGuard is not enabled, unable to access the platform.");
return platform;
}
public void setPlatform(WorldGuardPlatform platform) {
checkNotNull(platform);
this.platform = platform;
}
/**
* Get the flag registry.
*
* @return the flag registry
*/
public FlagRegistry getFlagRegistry() {
return this.flagRegistry;
}
/**
* Get the domain registry.
*
* @return the domain registry
*/
public DomainRegistry getDomainRegistry() {
return this.domainRegistry;
}
/**
* Get the supervisor.
*
* @return the supervisor
*/
public Supervisor getSupervisor() {
return supervisor;
}
/**
* Get the global executor service for internal usage (please use your
* own executor service).
*
* @return the global executor service
*/
public ListeningExecutorService getExecutorService() {
return executorService;
}
/**
* Get the profile lookup service.
*
* @return the profile lookup service
*/
public ProfileService getProfileService() {
return profileService;
}
/**
* Get the profile cache.
*
* @return the profile cache
*/
public ProfileCache getProfileCache() {
return profileCache;
}
/**
* Get the exception converter
*
* @return the exception converter
*/
public WorldGuardExceptionConverter getExceptionConverter() {
return exceptionConverter;
}
/**
* Checks to see if the sender is a player, otherwise throw an exception.
*
* @param sender The sender
* @return The player
* @throws CommandException if it isn't a player
*/
public LocalPlayer checkPlayer(Actor sender) throws CommandException {
if (sender instanceof LocalPlayer) {
return (LocalPlayer) sender;
} else {
throw new CommandException("A player is expected.");
}
}
/**
* Called when WorldGuard should be disabled.
*/
public void disable() {
executorService.shutdown();
try {
logger.log(Level.INFO, "Shutting down executor and cancelling any pending tasks...");
List<Task<?>> tasks = supervisor.getTasks();
if (!tasks.isEmpty()) {
StringBuilder builder = new StringBuilder("Known tasks:");
for (Task<?> task : tasks) {
builder.append("\n");
builder.append(task.getName());
task.cancel(true);
}
logger.log(Level.INFO, builder.toString());
}
//Futures.successfulAsList(tasks).get();
executorService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
platform.unload();
}
/**
* Get the version.
*
* @return the version of WorldEdit
*/
public static String getVersion() {
if (version != null) {
return version;
}
Package p = WorldGuard.class.getPackage();
if (p == null) {
p = Package.getPackage("com.sk89q.worldguard");
}
if (p == null) {
version = "(unknown)";
} else {
version = p.getImplementationVersion();
if (version == null) {
version = "(unknown)";
}
}
return version;
}
}
@@ -1,46 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.blacklist.target;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
public class TargetMatcherParser {
public TargetMatcher fromInput(String input) throws TargetMatcherParseException {
input = input.toLowerCase().trim();
BlockType blockType = BlockTypes.get(input);
if (blockType != null) {
if (blockType.hasItemType()) {
return new ItemBlockMatcher(blockType);
} else {
return new BlockMatcher(blockType);
}
} else {
ItemType itemType = ItemTypes.get(input);
if (itemType == null) {
throw new TargetMatcherParseException("Unknown block or item name: " + input);
}
return new ItemMatcher(itemType);
}
}
}
@@ -1,117 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.chest;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldguard.LocalPlayer;
/**
* Sign-based chest protection.
*
* @author sk89q
*/
public abstract class SignChestProtection implements ChestProtection {
public abstract Boolean isProtectedSign(Location block, LocalPlayer player);
public boolean isProtected(Location location, LocalPlayer player) {
com.sk89q.worldedit.world.block.BlockState blockState = location.getExtent().getBlock(location.toVector().toBlockPoint());
if (isChest(blockState.getBlockType())) {
return isProtectedSignAround(location.setY(location.getY() - 1), player);
} else if (blockState.getBlockType() == BlockTypes.SIGN) {
return isProtectedSignAndChestBinary(location, player);
} else {
Boolean res = isProtectedSign(location.setY(location.getY() + 1), player);
if (res != null) return res;
return false;
}
}
public boolean isProtectedPlacement(Location block, LocalPlayer player) {
return isProtectedSignAround(block, player);
}
private boolean isProtectedSignAround(Location searchBlock, LocalPlayer player) {
Location side;
Boolean res;
side = searchBlock;
res = isProtectedSign(side, player);
if (res != null && res) return res;
side = searchBlock.setX(searchBlock.getX() - 1);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
side = searchBlock.setX(searchBlock.getX() + 1);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
side = searchBlock.setZ(searchBlock.getZ() - 1);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
side = searchBlock.setZ(searchBlock.getZ() + 1);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
return false;
}
private Boolean isProtectedSignAndChest(Location block, LocalPlayer player) {
if (!isChest(block.getExtent().getBlock(block.setY(block.getY() + 1).toVector().toBlockPoint()).getBlockType())) {
return null;
}
return isProtectedSign(block, player);
}
private boolean isProtectedSignAndChestBinary(Location block, LocalPlayer player) {
Boolean res = isProtectedSignAndChest(block, player);
return !(res == null || !res);
}
public boolean isAdjacentChestProtected(Location searchBlock, LocalPlayer player) {
Location side;
boolean res;
side = searchBlock;
res = isProtected(side, player);
if (res) return res;
side = searchBlock.setX(searchBlock.getX() - 1);
res = isProtected(side, player);
if (res) return res;
side = searchBlock.setX(searchBlock.getX() + 1);
res = isProtected(side, player);
if (res) return res;
side = searchBlock.setZ(searchBlock.getZ() - 1);
res = isProtected(side, player);
if (res) return res;
side = searchBlock.setZ(searchBlock.getZ() + 1);
res = isProtected(side, player);
if (res) return res;
return false;
}
}
@@ -1,111 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
import javax.annotation.Nullable;
import java.util.Map;
public abstract class CommandInputContext<T extends Exception> {
protected final Actor sender;
protected final String input;
protected Map<String, Object> context;
protected CommandInputContext(Actor sender, String input, Map<String, Object> values) {
this.sender = sender;
this.input = input;
this.context = values;
}
public void put(String name, Object value) {
context.put(name, value);
}
public Actor getSender() {
return sender;
}
public String getUserInput() {
return input;
}
/**
* Gets the CommandSender as a player.
*
* @return Player
* @throws T if the sender is not a player
*/
public LocalPlayer getPlayerSender() throws T {
if (sender.isPlayer() && sender instanceof LocalPlayer) {
return (LocalPlayer) sender;
} else {
throw createException("Not a player");
}
}
public Integer getUserInputAsInt() throws T {
try {
return Integer.parseInt(input);
} catch (NumberFormatException e) {
throw createException("Not a number: " + input);
}
}
public Double getUserInputAsDouble() throws T {
try {
return Double.parseDouble(input);
} catch (NumberFormatException e) {
throw createException("Not a number: " + input);
}
}
protected abstract T createException(String str);
/**
* Get an object from the context by key name.
* May return null if the object does not exist in the context.
*
* @param name key name of the object
* @return the object matching the key, or null
*/
@Nullable
public Object get(String name) {
return get(name, null);
}
/**
* Get an object from the context by key name.
* Will only return null if
* a) you provide null as the default
* b) the key has explicity been set to null
*
* @param name key name of the object
* @return the object matching the key
*/
@Nullable
public Object get(String name, Object defaultValue) {
Object obj;
return (((obj = context.get(name)) != null) || context.containsKey(name)
? obj : defaultValue);
}
}
@@ -1,136 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands;
import com.sk89q.worldedit.extension.platform.Actor;
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.
*/
public final class CommandUtils {
private CommandUtils() {
}
/**
* Replace color macros in a string.
*
* @param str the string
* @return the new string
*/
public static String replaceColorMacros(String str) {
// TODO: Make this more efficient
str = str.replace("`r", "&c");
str = str.replace("`R", "&4");
str = str.replace("`y", "&e");
str = str.replace("`Y", "&6");
str = str.replace("`g", "&a");
str = str.replace("`G", "&2");
str = str.replace("`c", "&b");
str = str.replace("`C", "&3");
str = str.replace("`b", "&9");
str = str.replace("`B", "&1");
str = str.replace("`p", "&d");
str = str.replace("`P", "&5");
str = str.replace("`0", "&0");
str = str.replace("`1", "&8");
str = str.replace("`2", "&7");
str = str.replace("`w", "&F");
str = str.replace("`k", "&k");
str = str.replace("`l", "&l");
str = str.replace("`m", "&m");
str = str.replace("`n", "&n");
str = str.replace("`o", "&o");
str = str.replace("`x", "&r");
// MC classic
// 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;
}
/**
* Get the name of the given owner object.
*
* @param owner the owner object
* @return a name
*/
public static String getOwnerName(@Nullable Object owner) {
if (owner == null) {
return "?";
} else if (owner instanceof Actor) {
return ((Actor) owner).getName();
} else {
return "?";
}
}
/**
* Return a function that accepts a string to send a message to the
* given sender.
*
* @param sender the sender
* @return a function
*/
public static Function<String, ?> messageFunction(final Actor sender) {
return s -> {
sender.printRaw(s);
return null;
};
}
/**
* Return a function that accepts a TextComponent to send a message to the
* given sender.
*
* @param sender the sender
* @return a function
*/
public static Function<TextComponent, ?> messageComponentFunction(final Actor sender) {
return s -> {
sender.print(s);
return null;
};
}
}
@@ -1,71 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands;
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.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
public class DebuggingCommands {
private final WorldGuard worldGuard;
/**
* Create a new instance.
*
* @param worldGuard The worldGuard instance
*/
public DebuggingCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"testbreak"}, usage = "[player]", desc = "Simulate a block break", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireBreakEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testBreak(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
@Command(aliases = {"testplace"}, usage = "[player]", desc = "Simulate a block place", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void firePlaceEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testPlace(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
@Command(aliases = {"testinteract"}, usage = "[player]", desc = "Simulate a block interact", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireInteractEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testInteract(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
@Command(aliases = {"testdamage"}, usage = "[player]", desc = "Simulate an entity damage", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireDamageEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testDamage(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
}
@@ -1,241 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands;
import com.google.common.collect.Lists;
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.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.handler.GodMode;
public class GeneralCommands {
private final WorldGuard worldGuard;
public GeneralCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"god"}, usage = "[player]",
desc = "Enable godmode on a player", flags = "s", max = 1)
public void god(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.god");
} else {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.god.other");
}
for (LocalPlayer player : targets) {
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
if (GodMode.set(player, session, true)) {
player.setFireTicks(0);
// Tell the user
if (player.equals(sender)) {
player.print("God mode enabled! Use /ungod to disable.");
// Keep track of this
included = true;
} else if (!args.hasFlag('s')) {
player.print("God enabled by " + sender.getDisplayName() + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included) {
sender.print("Players now have god mode.");
}
}
@Command(aliases = {"ungod"}, usage = "[player]",
desc = "Disable godmode on a player", flags = "s", max = 1)
public void ungod(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.god");
} else {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.god.other");
}
for (LocalPlayer player : targets) {
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
if (GodMode.set(player, session, false)) {
// Tell the user
if (player.equals(sender)) {
player.print("God mode disabled!");
// Keep track of this
included = true;
} else if (!args.hasFlag('s')) {
player.print("God disabled by " + sender.getDisplayName() + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included) {
sender.print("Players no longer have god mode.");
}
}
@Command(aliases = {"heal"}, usage = "[player]", desc = "Heal a player", flags = "s", max = 1)
public void heal(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.heal");
} else if (args.argsLength() == 1) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.heal.other");
}
for (LocalPlayer player : targets) {
player.setHealth(player.getMaxHealth());
player.setFoodLevel(20);
player.setSaturation(20);
player.setExhaustion(0);
// Tell the user
if (player.equals(sender)) {
player.print("Healed!");
// Keep track of this
included = true;
} else if (!args.hasFlag('s')) {
player.print("Healed by " + sender.getDisplayName() + ".");
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included) {
sender.print("Players healed.");
}
}
@Command(aliases = {"slay"}, usage = "[player]", desc = "Slay a player", flags = "s", max = 1)
public void slay(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets = Lists.newArrayList();
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.slay");
} else if (args.argsLength() == 1) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.slay.other");
}
for (LocalPlayer player : targets) {
player.setHealth(0);
// Tell the user
if (player.equals(sender)) {
player.print("Slain!");
// Keep track of this
included = true;
} else if (!args.hasFlag('s')) {
player.print("Slain by " + sender.getDisplayName() + ".");
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included) {
sender.print("Players slain.");
}
}
@Command(aliases = {"locate"}, usage = "[player]", desc = "Locate a player", max = 1)
@CommandPermissions({"worldguard.locate"})
public void locate(CommandContext args, Actor sender) throws CommandException {
LocalPlayer player = worldGuard.checkPlayer(sender);
if (args.argsLength() == 0) {
player.setCompassTarget(new Location(player.getWorld(), player.getWorld().getSpawnPosition().toVector3()));
sender.print("Compass reset to spawn.");
} else {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
player.setCompassTarget(target.getLocation());
sender.print("Compass repointed.");
}
}
@Command(aliases = {"stack", ";"}, usage = "", desc = "Stack items", max = 0)
@CommandPermissions({"worldguard.stack"})
public void stack(CommandContext args, Actor sender) throws CommandException {
LocalPlayer player = worldGuard.checkPlayer(sender);
WorldGuard.getInstance().getPlatform().stackPlayerInventory(player);
player.print("Items compacted into stacks!");
}
}
@@ -1,182 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands;
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.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.util.formatting.component.CodeFormat;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
import com.sk89q.worldedit.util.formatting.component.LabelFormat;
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;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.util.Entities;
public class ToggleCommands {
private final WorldGuard worldGuard;
public ToggleCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"stopfire"}, usage = "[<world>]",
desc = "Disables all fire spread temporarily", max = 1)
@CommandPermissions({"worldguard.fire-toggle.stop"})
public void stopFire(CommandContext args, Actor sender) throws CommandException {
World world;
if (args.argsLength() == 0) {
world = worldGuard.checkPlayer(sender).getWorld();
} else {
world = worldGuard.getPlatform().getMatcher().matchWorld(sender, args.getString(0));
}
WorldConfiguration wcfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world);
if (!wcfg.fireSpreadDisableToggle) {
worldGuard.getPlatform().broadcastNotification(
LabelFormat.wrap("Fire spread has been globally disabled for '" + world.getName() + "' by "
+ sender.getDisplayName() + "."));
} else {
sender.print("Fire spread was already globally disabled.");
}
wcfg.fireSpreadDisableToggle = true;
}
@Command(aliases = {"allowfire"}, usage = "[<world>]",
desc = "Allows all fire spread temporarily", max = 1)
@CommandPermissions({"worldguard.fire-toggle.stop"})
public void allowFire(CommandContext args, Actor sender) throws CommandException {
World world;
if (args.argsLength() == 0) {
world = worldGuard.checkPlayer(sender).getWorld();
} else {
world = worldGuard.getPlatform().getMatcher().matchWorld(sender, args.getString(0));
}
WorldConfiguration wcfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world);
if (wcfg.fireSpreadDisableToggle) {
worldGuard.getPlatform().broadcastNotification(LabelFormat.wrap("Fire spread has been globally for '" + world.getName() + "' re-enabled by "
+ sender.getDisplayName() + "."));
} else {
sender.print("Fire spread was already globally enabled.");
}
wcfg.fireSpreadDisableToggle = false;
}
@Command(aliases = {"halt-activity", "stoplag", "haltactivity"}, usage = "[confirm]",
desc = "Attempts to cease as much activity in order to stop lag", flags = "cis", max = 1)
@CommandPermissions({"worldguard.halt-activity"})
public void stopLag(CommandContext args, Actor sender) throws CommandException {
ConfigurationManager configManager = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
if (args.hasFlag('i')) {
if (configManager.activityHaltToggle) {
sender.print("ALL intensive server activity is not allowed.");
} else {
sender.print("ALL intensive server activity is allowed.");
}
} else {
boolean activityHaltToggle = !args.hasFlag('c');
if (activityHaltToggle && (args.argsLength() == 0 || !args.getString(0).equalsIgnoreCase("confirm"))) {
String confirmCommand = "/" + args.getCommand() + " confirm";
TextComponent message = TextComponent.builder("")
.append(ErrorFormat.wrap("This command will "))
.append(ErrorFormat.wrap("PERMANENTLY")
.decoration(TextDecoration.BOLD, TextDecoration.State.TRUE))
.append(ErrorFormat.wrap(" erase ALL animals in ALL loaded chunks in ALL loaded worlds. "))
.append(TextComponent.newline())
.append(TextComponent.of("[Click]", TextColor.GREEN)
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, confirmCommand))
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to confirm /" + args.getCommand()))))
.append(ErrorFormat.wrap(" or type "))
.append(CodeFormat.wrap(confirmCommand)
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, confirmCommand)))
.append(ErrorFormat.wrap(" to confirm."))
.build();
sender.print(message);
return;
}
configManager.activityHaltToggle = activityHaltToggle;
if (activityHaltToggle) {
if (!(sender instanceof LocalPlayer)) {
sender.print("ALL intensive server activity halted.");
}
if (!args.hasFlag('s')) {
worldGuard.getPlatform().broadcastNotification(LabelFormat.wrap("ALL intensive server activity halted by " + sender.getDisplayName() + "."));
} else {
sender.print("(Silent) ALL intensive server activity halted by " + sender.getDisplayName() + ".");
}
for (World world : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
int removed = 0;
for (Entity entity : world.getEntities()) {
if (Entities.isIntensiveEntity(entity)) {
entity.remove();
removed++;
}
}
if (removed > 10) {
sender.printRaw("" + removed + " entities (>10) auto-removed from "
+ world.getName());
}
}
} else {
if (!args.hasFlag('s')) {
worldGuard.getPlatform().broadcastNotification(LabelFormat.wrap("ALL intensive server activity is now allowed."));
if (!(sender instanceof LocalPlayer)) {
sender.print("ALL intensive server activity is now allowed.");
}
} else {
sender.print("(Silent) ALL intensive server activity is now allowed.");
}
}
}
}
}
@@ -1,309 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands;
import com.google.common.io.Files;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
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.NestedCommand;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.formatting.component.MessageBox;
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.paste.ActorCallbackPaste;
import com.sk89q.worldedit.util.report.ReportList;
import com.sk89q.worldedit.util.report.SystemInfoReport;
import com.sk89q.worldedit.util.task.FutureForwardingTask;
import com.sk89q.worldedit.util.task.Task;
import com.sk89q.worldedit.util.task.TaskStateComparator;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
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.StandardCharsets;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
public class WorldGuardCommands {
private final WorldGuard worldGuard;
@Nullable
private Sampler activeSampler;
public WorldGuardCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"version"}, desc = "Get the WorldGuard version", max = 0)
public void version(CommandContext args, Actor sender) throws CommandException {
sender.print("WorldGuard " + WorldGuard.getVersion());
sender.print("http://www.enginehub.org");
sender.printDebug("----------- Platforms -----------");
sender.printDebug(String.format("* %s (%s)", worldGuard.getPlatform().getPlatformName(), worldGuard.getPlatform().getPlatformVersion()));
}
@Command(aliases = {"reload"}, desc = "Reload WorldGuard configuration", max = 0)
@CommandPermissions({"worldguard.reload"})
public void reload(CommandContext args, Actor sender) throws CommandException {
// TODO: This is subject to a race condition, but at least other commands are not being processed concurrently
List<Task<?>> tasks = WorldGuard.getInstance().getSupervisor().getTasks();
if (!tasks.isEmpty()) {
throw new CommandException("There are currently pending tasks. Use /wg running to monitor these tasks first.");
}
LoggerToChatHandler handler = null;
Logger minecraftLogger = null;
if (sender instanceof LocalPlayer) {
handler = new LoggerToChatHandler(sender);
handler.setLevel(Level.ALL);
minecraftLogger = Logger.getLogger("com.sk89q.worldguard");
minecraftLogger.addHandler(handler);
}
try {
ConfigurationManager config = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
config.unload();
config.load();
for (World world : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
config.get(world);
}
WorldGuard.getInstance().getPlatform().getRegionContainer().reload();
// WGBukkit.cleanCache();
sender.print("WorldGuard configuration reloaded.");
} catch (Throwable t) {
sender.printError("Error while reloading: " + t.getMessage());
} finally {
if (minecraftLogger != null) {
minecraftLogger.removeHandler(handler);
}
}
}
@Command(aliases = {"report"}, desc = "Writes a report on WorldGuard", flags = "p", max = 0)
@CommandPermissions({"worldguard.report"})
public void report(CommandContext args, final Actor sender) throws CommandException, AuthorizationException {
ReportList report = new ReportList("Report");
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, StandardCharsets.UTF_8);
sender.print("WorldGuard report written to " + dest.getAbsolutePath());
} catch (IOException e) {
throw new CommandException("Failed to write report: " + e.getMessage());
}
if (args.hasFlag('p')) {
sender.checkPermission("worldguard.report.pastebin");
ActorCallbackPaste.pastebin(worldGuard.getSupervisor(), sender, result, "WorldGuard report: %s.report");
}
}
@Command(aliases = {"profile"}, usage = "[-p] [-i <interval>] [-t <thread filter>] [<minutes>]",
desc = "Profile the CPU usage of the server", min = 0, max = 1,
flags = "t:i:p")
@CommandPermissions("worldguard.profile")
public void profile(final CommandContext args, final Actor sender) throws CommandException, AuthorizationException {
Predicate<ThreadInfo> threadFilter;
String threadName = args.getFlag('t');
final boolean pastebin;
if (args.hasFlag('p')) {
sender.checkPermission("worldguard.report.pastebin");
pastebin = true;
} else {
pastebin = false;
}
if (threadName == null) {
threadFilter = new ThreadIdFilter(Thread.currentThread().getId());
} else if (threadName.equals("*")) {
threadFilter = thread -> true;
} else {
threadFilter = new ThreadNameFilter(threadName);
}
int minutes;
if (args.argsLength() == 0) {
minutes = 5;
} else {
minutes = args.getInteger(0);
if (minutes < 1) {
throw new CommandException("You must run the profile for at least 1 minute.");
} else if (minutes > 10) {
throw new CommandException("You can profile for, at maximum, 10 minutes.");
}
}
int interval = 20;
if (args.hasFlag('i')) {
interval = args.getFlagInteger('i');
if (interval < 1 || interval > 100) {
throw new CommandException("Interval must be between 1 and 100 (in milliseconds)");
}
if (interval < 10) {
sender.printDebug("Note: A low interval may cause additional slowdown during profiling.");
}
}
Sampler sampler;
synchronized (this) {
if (activeSampler != null) {
throw new CommandException("A profile is currently in progress! Please use /wg stopprofile to cancel the current profile.");
}
SamplerBuilder builder = new SamplerBuilder();
builder.setThreadFilter(threadFilter);
builder.setRunTime(minutes, TimeUnit.MINUTES);
builder.setInterval(interval);
sampler = activeSampler = builder.start();
}
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.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));
sampler.getFuture().addListener(() -> {
synchronized (WorldGuardCommands.this) {
activeSampler = null;
}
}, MoreExecutors.directExecutor());
Futures.addCallback(sampler.getFuture(), new FutureCallback<>() {
@Override
public void onSuccess(Sampler result) {
String output = result.toString();
try {
File dest = new File(worldGuard.getPlatform().getConfigDir().toFile(), "profile.txt");
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());
}
if (pastebin) {
ActorCallbackPaste.pastebin(worldGuard.getSupervisor(), sender, output, "Profile result: %s.profile");
}
}
@Override
public void onFailure(Throwable throwable) {
}
}, MoreExecutors.directExecutor());
}
@Command(aliases = {"stopprofile"}, usage = "",desc = "Stop a running profile", min = 0, max = 0)
@CommandPermissions("worldguard.profile")
public void stopProfile(CommandContext args, final Actor sender) throws CommandException {
synchronized (this) {
if (activeSampler == null) {
throw new CommandException("No CPU profile is currently running.");
}
activeSampler.cancel();
activeSampler = null;
}
sender.print("The running CPU profile has been cancelled.");
}
@Command(aliases = {"flushstates", "clearstates"},
usage = "[player]", desc = "Flush the state manager", max = 1)
@CommandPermissions("worldguard.flushstates")
public void flushStates(CommandContext args, Actor sender) throws CommandException {
if (args.argsLength() == 0) {
WorldGuard.getInstance().getPlatform().getSessionManager().resetAllStates();
sender.print("Cleared all states.");
} else {
LocalPlayer player = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
if (player != null) {
WorldGuard.getInstance().getPlatform().getSessionManager().resetState(player);
sender.print("Cleared states for player \"" + player.getName() + "\".");
}
}
}
@Command(aliases = {"running", "queue"}, desc = "List running tasks", max = 0)
@CommandPermissions("worldguard.running")
public void listRunningTasks(CommandContext args, Actor sender) throws CommandException {
List<Task<?>> tasks = WorldGuard.getInstance().getSupervisor().getTasks();
if (tasks.isEmpty()) {
sender.print("There are currently no running tasks.");
} else {
tasks.sort(new TaskStateComparator());
MessageBox builder = new MessageBox("Running Tasks", new TextComponentProducer());
builder.append(TextComponent.of("Note: Some 'running' tasks may be waiting to be start.", TextColor.GRAY));
for (Task<?> task : tasks) {
builder.append(TextComponent.newline());
builder.append(TextComponent.of("(" + task.getState().name() + ") ", TextColor.BLUE));
builder.append(TextComponent.of(CommandUtils.getOwnerName(task.getOwner()) + ": ", TextColor.YELLOW));
builder.append(TextComponent.of(task.getName(), TextColor.WHITE));
}
sender.print(builder.create());
}
}
@Command(aliases = {"debug"}, desc = "Debugging commands")
@NestedCommand({DebuggingCommands.class})
public void debug(CommandContext args, Actor sender) {}
}
@@ -1,500 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands.region;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.sk89q.worldedit.registry.Keyed;
import com.sk89q.worldedit.registry.Registry;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
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.util.formatting.text.serializer.legacy.LegacyComponentSerializer;
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.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
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;
import com.sk89q.worldguard.protection.flags.StringFlag;
import com.sk89q.worldguard.protection.flags.registry.UnknownFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collectors;
class FlagHelperBox extends PaginationBox {
private static final List<Flag<?>> FLAGS = WorldGuard.getInstance().getFlagRegistry().getAll().stream()
.sorted((f1, f2) -> {
if (f1 == f2) return 0;
int idx1 = Flags.INBUILT_FLAGS.indexOf(f1.getName());
int idx2 = Flags.INBUILT_FLAGS.indexOf(f2.getName());
if (idx1 < 0 && idx2 >= 0) return 1;
if (idx2 < 0 && idx1 >= 0) return -1;
if (idx1 < 0) return f1.getName().compareTo(f2.getName());
return idx1 < idx2 ? -1 : 1;
})
.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());
this.world = world;
this.region = region;
this.perms = perms;
}
@Override
public Component getComponent(int number) {
if (number == Flags.INBUILT_FLAGS.size()) {
return centerAndBorder(TextComponent.of("Third-Party Flags", TextColor.AQUA));
} else if (number > Flags.INBUILT_FLAGS.size()) {
number -= 1;
}
Flag<?> flag = FLAGS.get(number);
return createLine(flag, number >= Flags.INBUILT_FLAGS.size());
}
@Override
public int getComponentsSize() {
return SIZE;
}
private Component createLine(Flag<?> flag, boolean thirdParty) {
final TextComponent.Builder builder = TextComponent.builder("");
appendFlagName(builder, flag, flag instanceof UnknownFlag ? TextColor.GRAY : thirdParty ? TextColor.LIGHT_PURPLE : TextColor.GOLD);
appendFlagValue(builder, flag);
return builder.build();
}
private void appendFlagName(TextComponent.Builder builder, Flag<?> flag, TextColor color) {
final String name = flag.getName();
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 += 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 += monoSpace ? 1 : FlagFontInfo.getPxLength('*');
}
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(".", monoSpace ? leftover : leftover / 2), TextColor.DARK_GRAY));
}
}
private void appendFlagValue(TextComponent.Builder builder, Flag<?> flag) {
if (flag instanceof StateFlag) {
appendStateFlagValue(builder, (StateFlag) flag);
} else if (flag instanceof BooleanFlag) {
appendBoolFlagValue(builder, ((BooleanFlag) flag));
} else if (flag instanceof SetFlag) {
appendSetFlagValue(builder, ((SetFlag<?>) flag));
} else if (flag instanceof RegistryFlag) {
appendRegistryFlagValue(builder, ((RegistryFlag<?>) flag));
} else if (flag instanceof StringFlag) {
appendStringFlagValue(builder, ((StringFlag) flag));
} else if (flag instanceof LocationFlag) {
appendLocationFlagValue(builder, ((LocationFlag) flag));
} else if (flag instanceof NumberFlag) {
appendNumericFlagValue(builder, (NumberFlag<? extends Number>) flag);
} else {
String display = String.valueOf(region.getFlag(flag));
if (display.length() > 23) {
display = display.substring(0, 20) + "...";
}
appendValueText(builder, flag, display, null);
}
}
private <T> T getInheritedValue(ProtectedRegion region, Flag<T> flag) {
ProtectedRegion parent = region.getParent();
T val;
while (parent != null) {
val = parent.getFlag(flag);
if (val != null) {
return val;
}
parent = parent.getParent();
}
return null;
}
private <V> void appendValueChoices(TextComponent.Builder builder, Flag<V> flag, Iterator<V> choices, @Nullable String suggestChoice) {
V defVal = flag.getDefault();
V currVal = region.getFlag(flag);
boolean inherited = false;
if (currVal == null) {
currVal = getInheritedValue(region, flag);
if (currVal != null) {
inherited = true;
}
}
while (choices.hasNext()) {
V choice = choices.next();
boolean isExplicitSet = currVal == choice && !inherited;
boolean maySet = perms.maySetFlag(region, flag, isExplicitSet ? null : String.valueOf(choice));
TextColor col = isExplicitSet ? TextColor.WHITE : inherited && currVal == choice ? TextColor.GRAY : TextColor.DARK_GRAY;
Set<TextDecoration> styles = choice == defVal ? ImmutableSet.of(TextDecoration.UNDERLINED) : Collections.emptySet();
Component choiceComponent = TextComponent.empty().append(TextComponent.of(capitalize(String.valueOf(choice)), col, styles));
List<Component> hoverTexts = new ArrayList<>();
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));
}
}
Component valType = getToolTipHint(defVal, choice, inherited);
if (valType != null) {
hoverTexts.add(valType);
}
if (!hoverTexts.isEmpty()) {
TextComponent.Builder hoverBuilder = TextComponent.builder("");
for (Iterator<Component> hovIt = hoverTexts.iterator(); hovIt.hasNext(); ) {
hoverBuilder.append(hovIt.next());
if (hovIt.hasNext()) {
hoverBuilder.append(TextComponent.newline());
}
}
choiceComponent = choiceComponent.hoverEvent(
HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hoverBuilder.build()));
}
if (maySet && (isExplicitSet || !DANGER_ZONE.contains(flag))) {
builder.append(choiceComponent.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
makeCommand(flag, isExplicitSet ? "" : choice))));
} else {
builder.append(choiceComponent);
}
builder.append(TextComponent.space());
}
if (suggestChoice != null && perms.maySetFlag(region, flag)) {
builder.append(TextComponent.of(suggestChoice, TextColor.DARK_GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
TextComponent.of("Click to set custom value", TextColor.GOLD)))
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, makeCommand(flag, ""))));
}
}
private <V> void appendValueText(TextComponent.Builder builder, Flag<V> flag, String display, @Nullable Component hover) {
V defVal = flag.getDefault();
V currVal = region.getFlag(flag);
boolean inherited = false;
if (currVal == null) {
currVal = getInheritedValue(region, flag);
if (currVal != null) {
inherited = true;
}
}
boolean isExplicitSet = currVal != null && !inherited;
boolean maySet = !(flag instanceof UnknownFlag) && perms.maySetFlag(region, flag);
TextColor col = isExplicitSet ? TextColor.WHITE : inherited ? TextColor.GRAY : TextColor.DARK_GRAY;
Set<TextDecoration> styles = currVal == defVal ? ImmutableSet.of(TextDecoration.UNDERLINED) : Collections.emptySet();
Component displayComponent = TextComponent.empty().append(TextComponent.of(display, col, styles));
List<Component> hoverTexts = new ArrayList<>();
if (maySet) {
if (isExplicitSet) {
hoverTexts.add(TextComponent.of("Click to change", TextColor.GOLD));
} else {
hoverTexts.add(TextComponent.of("Click to set", TextColor.GOLD));
}
}
Component valType = getToolTipHint(defVal, currVal, inherited);
if (valType != null) {
hoverTexts.add(valType);
}
if (!hoverTexts.isEmpty()) {
TextComponent.Builder hoverBuilder = TextComponent.builder("");
for (Iterator<Component> hovIt = hoverTexts.iterator(); hovIt.hasNext(); ) {
hoverBuilder.append(hovIt.next());
if (hovIt.hasNext()) {
hoverBuilder.append(TextComponent.newline());
}
}
if (hover != null) {
hoverBuilder.append(TextComponent.newline());
hoverBuilder.append(hover);
}
displayComponent = displayComponent.hoverEvent(
HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hoverBuilder.build()));
}
if (maySet) {
builder.append(displayComponent.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
makeCommand(flag, ""))));
} else {
builder.append(displayComponent);
}
builder.append(TextComponent.space());
}
private String makeCommand(Flag<?> flag, Object choice) {
return "/rg flag -w \"" + world.getName() + "\" -h " + getCurrentPage()
+ " " + region.getId() + " " + flag.getName() + " " + choice;
}
private String capitalize(String value) {
if (value.isEmpty()) return value;
value = value.toLowerCase();
return value.length() > 1
? Character.toUpperCase(value.charAt(0)) + value.substring(1)
: String.valueOf(Character.toUpperCase(value.charAt(0)));
}
@Nullable
private <V> Component getToolTipHint(V defVal, V currVal, boolean inherited) {
Component valType;
if (inherited) {
if (currVal == defVal) {
valType = TextComponent.of("Inherited & ")
.append(TextComponent.of("default")
.decoration(TextDecoration.UNDERLINED, true))
.append(TextComponent.of(" value"));
} else {
valType = TextComponent.of("Inherited value");
}
} else {
if (currVal == defVal) {
valType = TextComponent.empty()
.append(TextComponent.of("Default")
.decoration(TextDecoration.UNDERLINED, true))
.append(TextComponent.of(" value"));
} else {
valType = null;
}
}
return valType;
}
private void appendStateFlagValue(TextComponent.Builder builder, StateFlag flag) {
final Iterator<StateFlag.State> choices = Iterators.forArray(StateFlag.State.values());
appendValueChoices(builder, flag, choices, null);
}
private void appendBoolFlagValue(TextComponent.Builder builder, BooleanFlag flag) {
final Iterator<Boolean> choices = Iterators.forArray(Boolean.TRUE, Boolean.FALSE);
appendValueChoices(builder, flag, choices, null);
}
private <V> void appendSetFlagValue(TextComponent.Builder builder, SetFlag<V> flag) {
Flag<V> subType = flag.getType();
Class<?> clazz = subType.getClass();
String subName;
subName = clazz.isAssignableFrom(RegistryFlag.class)
? ((RegistryFlag<?>) subType).getRegistry().getName()
: subType.getClass().getSimpleName().replace("Flag", "");
Set<V> currVal = region.getFlag(flag);
if (currVal == null) {
currVal = getInheritedValue(region, flag);
}
String display = (currVal == null ? "" : currVal.size() + "x ") + subName;
final String stringValue = currVal == null ? ""
: currVal.stream().map(String::valueOf).collect(Collectors.joining(","));
TextComponent hoverComp = TextComponent.of("");
if (currVal != null) {
hoverComp = hoverComp.append(TextComponent.of("Current values:"))
.append(TextComponent.newline()).append(TextComponent.of(stringValue));
}
appendValueText(builder, flag, display, hoverComp);
}
private void appendRegistryFlagValue(TextComponent.Builder builder, RegistryFlag<?> flag) {
final Registry<?> registry = flag.getRegistry();
String regName = registry.getName();
Keyed currVal = region.getFlag(flag);
if (currVal == null) {
currVal = getInheritedValue(region, flag);
}
String display = currVal == null ? regName : currVal.id();
appendValueText(builder, flag, display, null);
}
private void appendLocationFlagValue(TextComponent.Builder builder, LocationFlag flag) {
Location currVal = region.getFlag(flag);
if (currVal == null) {
currVal = getInheritedValue(region, flag);
}
if (currVal == null) {
final Location defVal = flag.getDefault();
if (defVal == null) {
appendValueText(builder, flag, "unset location", null);
} else {
appendValueText(builder, flag, defVal.toString(), TextComponent.of("Default value:")
.append(TextComponent.newline()).append(TextComponent.of(defVal.toString())));
}
} else {
appendValueText(builder, flag, currVal.toString(), TextComponent.of("Current value:")
.append(TextComponent.newline()).append(TextComponent.of(currVal.toString())));
}
}
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 = flag.getSuggestedValues();
SortedSet<Number> choices = new TreeSet<>(Comparator.comparing(Number::doubleValue));
if (currVal != null) {
choices.add(currVal);
}
if (defVal != null) {
choices.add(defVal);
}
if (suggested.length > 0) {
choices.addAll(Arrays.asList(suggested));
}
//noinspection unchecked
appendValueChoices(builder, flag, (Iterator<V>) choices.iterator(), choices.isEmpty() ? "unset number" : "[custom]");
}
private void appendStringFlagValue(TextComponent.Builder builder, StringFlag flag) {
String currVal = region.getFlag(flag);
if (currVal == null) {
currVal = getInheritedValue(region, flag);
}
if (currVal == null) {
final String defVal = flag.getDefault();
if (defVal == null) {
appendValueText(builder, flag, "unset string", null);
} else {
final TextComponent defComp = LegacyComponentSerializer.INSTANCE.deserialize(defVal);
String display = reduceToText(defComp);
display = display.replace("\n", "\\n");
if (display.length() > 23) {
display = display.substring(0, 20) + "...";
}
appendValueText(builder, flag, display, TextComponent.of("Default value:")
.append(TextComponent.newline()).append(defComp));
}
} else {
TextComponent currComp = LegacyComponentSerializer.INSTANCE.deserialize(currVal);
String display = reduceToText(currComp);
display = display.replace("\n", "\\n");
if (display.length() > 23) {
display = display.substring(0, 20) + "...";
}
appendValueText(builder, flag, display, TextComponent.of("Current value:")
.append(TextComponent.newline()).append(currComp));
}
}
private static String reduceToText(Component component) {
StringBuilder text = new StringBuilder();
appendTextTo(text, component);
return text.toString();
}
private static void appendTextTo(StringBuilder builder, Component component) {
if (component instanceof TextComponent) {
builder.append(((TextComponent) component).content());
} else if (component instanceof TranslatableComponent) {
builder.append(((TranslatableComponent) component).key());
}
for (Component child : component.children()) {
appendTextTo(builder, child);
}
}
void tryMonoSpacing() {
this.monoSpace = true;
}
private static final class FlagFontInfo {
static int getPxLength(char c) {
switch (c) {
case 'i':
case ':':
return 1;
case 'l':
return 2;
case '*':
case 't':
return 3;
case 'f':
case 'k':
return 4;
default:
return 5;
}
}
static int getPxLength(String string) {
return string.chars().reduce(0, (p, i) -> p + getPxLength((char) i) + 1);
}
}
}
@@ -1,250 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands.region;
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.CommandPermissionsException;
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.domains.registry.DomainFactory;
import com.sk89q.worldguard.domains.registry.DomainRegistry;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.util.DomainInputResolver;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Callable;
public class MemberCommands extends RegionCommandsBase {
private final WorldGuard worldGuard;
public MemberCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"addmember", "addmember", "addmem", "am"},
usage = "<id> <members...>",
flags = "nw:",
desc = "Add a member to a region",
min = 2)
public void addMember(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
// Check permissions
if (!getPermissionModel(sender).mayAddMembers(region)) {
throw new CommandPermissionsException();
}
// Resolve members asynchronously
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
resolver.setActor(sender);
resolver.setRegion(region);
final String description = String.format("Adding members to the region '%s' on '%s'", region.getId(), world.getName());
AsyncCommandBuilder.wrap(resolver, sender)
.registerWithSupervisor(worldGuard.getSupervisor(), description)
.onSuccess(String.format("Region '%s' updated with new members.", region.getId()), region.getMembers()::addAll)
.onFailure("Failed to add new members", worldGuard.getExceptionConverter())
.buildAndExec(worldGuard.getExecutorService());
}
@Command(aliases = {"addowner", "addowner", "ao"},
usage = "<id> <owners...>",
flags = "nw:",
desc = "Add an owner to a region",
min = 2)
public void addOwner(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
// Check permissions
if (!getPermissionModel(sender).mayAddOwners(region)) {
throw new CommandPermissionsException();
}
// Resolve owners asynchronously
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
resolver.setActor(sender);
resolver.setRegion(region);
final String description = String.format("Adding owners to the region '%s' on '%s'", region.getId(), world.getName());
AsyncCommandBuilder.wrap(checkedAddOwners(sender, manager, region, world, resolver), sender)
.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:",
desc = "Remove an owner to a region",
min = 1)
public void removeMember(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
// Check permissions
if (!getPermissionModel(sender).mayRemoveMembers(region)) {
throw new CommandPermissionsException();
}
Callable<DefaultDomain> callable;
if (args.hasFlag('a')) {
callable = region::getMembers;
} else {
if (args.argsLength() < 2) {
throw new CommandException("List some names to remove, or use -a to remove all.");
}
// Resolve members asynchronously
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
resolver.setActor(sender);
resolver.setRegion(region);
callable = resolver;
}
final String description = String.format("Removing members from the region '%s' on '%s'", region.getId(), world.getName());
AsyncCommandBuilder.wrap(callable, sender)
.registerWithSupervisor(worldGuard.getSupervisor(), description)
.sendMessageAfterDelay("(Please wait... querying player names...)")
.onSuccess(String.format("Region '%s' updated with members removed.", region.getId()), region.getMembers()::removeAll)
.onFailure("Failed to remove members", worldGuard.getExceptionConverter())
.buildAndExec(worldGuard.getExecutorService());
}
@Command(aliases = {"removeowner", "remowner", "ro"},
usage = "<id> <owners...>",
flags = "naw:",
desc = "Remove an owner to a region",
min = 1)
public void removeOwner(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
// Check permissions
if (!getPermissionModel(sender).mayRemoveOwners(region)) {
throw new CommandPermissionsException();
}
Callable<DefaultDomain> callable;
if (args.hasFlag('a')) {
callable = region::getOwners;
} else {
if (args.argsLength() < 2) {
throw new CommandException("List some names to remove, or use -a to remove all.");
}
// Resolve owners asynchronously
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
resolver.setActor(sender);
resolver.setRegion(region);
callable = resolver;
}
final String description = String.format("Removing owners from the region '%s' on '%s'", region.getId(), world.getName());
AsyncCommandBuilder.wrap(callable, sender)
.registerWithSupervisor(worldGuard.getSupervisor(), description)
.sendMessageAfterDelay("(Please wait... querying player names...)")
.onSuccess(String.format("Region '%s' updated with owners removed.", region.getId()), region.getOwners()::removeAll)
.onFailure("Failed to remove owners", worldGuard.getExceptionConverter())
.buildAndExec(worldGuard.getExecutorService());
}
}
@@ -1,426 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.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;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Actor;
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.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.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormatException;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery.QueryOption;
import com.sk89q.worldguard.protection.util.WorldEditRegionConverter;
import java.util.Set;
import java.util.stream.Collectors;
class RegionCommandsBase {
protected RegionCommandsBase() {
}
/**
* Get the permission model to lookup permissions.
*
* @param sender the sender
* @return the permission model
*/
protected static RegionPermissionModel getPermissionModel(Actor sender) {
return new RegionPermissionModel(sender);
}
/**
* Gets the world from the given flag, or falling back to the the current player
* if the sender is a player, otherwise reporting an error.
*
* @param args the arguments
* @param sender the sender
* @param flag the flag (such as 'w')
* @return a world
* @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 {
throw new CommandException("Please specify " + "the world with -" + flag + " world_name.");
}
}
}
/**
* Validate a region ID.
*
* @param id the id
* @param allowGlobal whether __global__ is allowed
* @return the id given
* @throws CommandException thrown on an error
*/
protected static String checkRegionId(String id, boolean allowGlobal) throws CommandException {
if (!ProtectedRegion.isValidId(id)) {
throw new CommandException(
"The region name of '" + id + "' contains characters that are not allowed.");
}
if (!allowGlobal && id.equalsIgnoreCase("__global__")) { // Sorry, no global
throw new CommandException(
"Sorry, you can't use __global__ here.");
}
return id;
}
/**
* Get a protected region by a given name, otherwise throw a
* {@link CommandException}.
*
* <p>This also validates the region ID.</p>
*
* @param regionManager the region manager
* @param id the name to search
* @param allowGlobal true to allow selecting __global__
* @throws CommandException thrown if no region is found by the given name
*/
protected static ProtectedRegion checkExistingRegion(RegionManager regionManager, String id, boolean allowGlobal) throws CommandException {
// Validate the id
checkRegionId(id, allowGlobal);
ProtectedRegion region = regionManager.getRegion(id);
// No region found!
if (region == null) {
// But we want a __global__, so let's create one
if (id.equalsIgnoreCase("__global__")) {
region = new GlobalProtectedRegion(id);
regionManager.addRegion(region);
return region;
}
throw new CommandException(
"No region could be found with the name of '" + id + "'.");
}
return region;
}
/**
* Get the region at the player's location, if possible.
*
* <p>If the player is standing in several regions, an error will be raised
* and a list of regions will be provided.</p>
*
* @param regionManager the region manager
* @param player the player
* @return a region
* @throws CommandException thrown if no region was found
*/
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, LocalPlayer player, String rgCmd) throws CommandException {
return checkRegionStandingIn(regionManager, player, false, rgCmd);
}
/**
* Get the region at the player's location, if possible.
*
* <p>If the player is standing in several regions, an error will be raised
* and a list of regions will be provided.</p>
*
* <p>If the player is not standing in any regions, the global region will
* returned if allowGlobal is true and it exists.</p>
*
* @param regionManager the region manager
* @param player the player
* @param allowGlobal whether to search for a global region if no others are found
* @return a region
* @throws CommandException thrown if no region was found
*/
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, LocalPlayer player, boolean allowGlobal, String rgCmd) throws CommandException {
ApplicableRegionSet set = regionManager.getApplicableRegions(player.getLocation().toVector().toBlockPoint(), QueryOption.SORT);
if (set.size() == 0) {
if (allowGlobal) {
ProtectedRegion global = checkExistingRegion(regionManager, "__global__", true);
player.printDebug("You're not standing in any " +
"regions. Using the global region for this world instead.");
return global;
}
throw new CommandException(
"You're not standing in a region. " +
"Specify an ID if you want to select a specific region.");
} else if (set.size() > 1) {
boolean first = true;
final TextComponent.Builder builder = TextComponent.builder("");
builder.append(TextComponent.of("Current regions: ", TextColor.GOLD));
for (ProtectedRegion region : set) {
if (!first) {
builder.append(TextComponent.of(", "));
}
first = false;
TextComponent regionComp = TextComponent.of(region.getId(), TextColor.AQUA);
if (rgCmd != null && rgCmd.contains("%id%")) {
regionComp = regionComp.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to pick this region")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, rgCmd.replace("%id%", region.getId())));
}
builder.append(regionComp);
}
player.print(builder.build());
throw new CommandException("You're standing in several regions (please pick one).");
}
return set.iterator().next();
}
/**
* Get a WorldEdit selection for an actor, or emit an exception if there is none
* available.
*
* @param actor the actor
* @return the selection
* @throws CommandException thrown on an error
*/
protected static Region checkSelection(Actor actor) throws CommandException {
LocalSession localSession = WorldEdit.getInstance().getSessionManager().get(actor);
try {
if (localSession == null || localSession.getSelectionWorld() == null) {
throw new IncompleteRegionException();
}
return localSession.getRegionSelector(localSession.getSelectionWorld()).getRegion();
} catch (IncompleteRegionException e) {
throw new CommandException("Please select an area first. " +
"Use WorldEdit to make a selection! " +
"(see: https://worldedit.enginehub.org/en/latest/usage/regions/selections/).");
}
}
/**
* Check that a region with the given ID does not already exist.
*
* @param manager the manager
* @param id the ID
* @throws CommandException thrown if the ID already exists
*/
protected static void checkRegionDoesNotExist(RegionManager manager, String id, boolean mayRedefine) throws CommandException {
if (manager.hasRegion(id)) {
throw new CommandException("A region with that name already exists. Please choose another name." +
(mayRedefine ? " To change the shape, use /region redefine " + id + "." : ""));
}
}
/**
* Check that the given region manager is not null.
*
* @param world the world
* @throws CommandException thrown if the manager is null
*/
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. " +
"However, you may need to restart your server afterwards.");
}
RegionManager manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(world);
if (manager == null) {
throw new CommandException("Region data failed to load for this world. " +
"Please ask a server administrator to read the logs to identify the reason.");
}
return manager;
}
/**
* Create a {@link ProtectedRegion} from the actor's selection.
*
* @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(Actor actor, String id) throws CommandException {
Region selection = checkSelection(actor);
// Detect the type of region from WorldEdit
if (selection instanceof Polygonal2DRegion) {
Polygonal2DRegion polySel = (Polygonal2DRegion) selection;
int minY = polySel.getMinimumPoint().y();
int maxY = polySel.getMaximumPoint().y();
return new ProtectedPolygonalRegion(id, polySel.getPoints(), minY, maxY);
} else if (selection instanceof CuboidRegion) {
BlockVector3 min = selection.getMinimumPoint();
BlockVector3 max = selection.getMaximumPoint();
return new ProtectedCuboidRegion(id, min, max);
} else {
throw new CommandException("Sorry, you can only use cuboids and polygons for WorldGuard regions.");
}
}
/**
* Warn the region saving is failing.
*
* @param sender the sender to send the message to
*/
protected static void warnAboutSaveFailures(Actor sender) {
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
Set<RegionManager> failures = container.getSaveFailures();
if (!failures.isEmpty()) {
String failingList = Joiner.on(", ").join(failures.stream()
.map(regionManager -> "'" + regionManager.getName() + "'").collect(Collectors.toList()));
sender.print(TextComponent.of("(Warning: The background saving of region data is failing for these worlds: " + failingList + ". " +
"Your changes are getting lost. See the server log for more information.)", TextColor.GOLD));
}
}
/**
* Warn the sender if the dimensions of the given region are worrying.
*
* @param sender the sender to send the message to
* @param region the region
*/
protected static void warnAboutDimensions(Actor sender, ProtectedRegion region) {
if (region instanceof GlobalProtectedRegion) {
return;
}
int height = region.getMaximumPoint().y() - region.getMinimumPoint().y();
if (height <= 2) {
sender.printDebug("(Warning: The height of the region was " + (height + 1) + " block(s).)");
}
}
/**
* Inform a new user about automatic protection.
*
* @param sender the sender to send the message to
* @param manager the region manager
* @param region the region
*/
protected static void informNewUser(Actor sender, RegionManager manager, ProtectedRegion region) {
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)));
}
}
/**
* Inform a user if the region overlaps spawn protection.
*
* @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(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("Can't select that region! " +
"The region type '" + region.getType().getName() + "' can't be selected.");
}
}
/**
* Utility method to set a flag.
*
* @param region the region
* @param flag the flag
* @param sender the sender
* @param value the value
* @throws InvalidFlagFormatException thrown if the value is invalid
*/
protected static <V> V setFlag(ProtectedRegion region, Flag<V> flag, Actor sender, String value) throws InvalidFlagFormatException {
V val = flag.parseInput(FlagContext.create().setSender(sender).setInput(value).setObject("region", region).build());
region.setFlag(flag, val);
return val;
}
}
@@ -1,397 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands.region;
import com.sk89q.worldguard.protection.flags.registry.UnknownFlag;
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
import com.sk89q.worldedit.util.formatting.component.LabelFormat;
import com.sk89q.worldedit.util.formatting.component.MessageBox;
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
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.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.FlagValueCalculator;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.Callable;
import javax.annotation.Nullable;
/**
* Create a region printout, as used in /region info to show information about
* a region.
*/
public class RegionPrintoutBuilder implements Callable<TextComponent> {
private final String world;
private final ProtectedRegion region;
@Nullable
private final ProfileCache cache;
private final TextComponentProducer builder = new TextComponentProducer();
private final RegionPermissionModel perms;
/**
* Create a new instance with a region to report on.
*
* @param region the region
* @param cache a profile cache, or {@code null}
*/
public RegionPrintoutBuilder(String world, ProtectedRegion region, @Nullable ProfileCache cache, @Nullable Actor actor) {
this.world = world;
this.region = region;
this.cache = cache;
this.perms = actor != null && actor.isPlayer() ? new RegionPermissionModel(actor) : null;
}
/**
* Add a new line.
*/
public void newline() {
builder.append(TextComponent.newline());
}
/**
* Add region name, type, and priority.
*/
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())));
builder.append(TextComponent.of(" (type=", TextColor.GRAY));
builder.append(TextComponent.of(region.getType().getName()));
builder.append(TextComponent.of(", priority=", TextColor.GRAY));
appendPriorityComponent(region);
builder.append(TextComponent.of(")", TextColor.GRAY));
newline();
}
/**
* Add information about flags.
*/
public void appendFlags() {
builder.append(TextComponent.of("Flags: ", TextColor.BLUE));
appendFlagsList(true);
newline();
}
/**
* Append just the list of flags (without "Flags:"), including colors.
*
* @param useColors true to use colors
*/
public void appendFlagsList(boolean useColors) {
boolean hasFlags = false;
for (Flag<?> flag : WorldGuard.getInstance().getFlagRegistry()) {
Object val = region.getFlag(flag);
// No value
if (val == null) {
continue;
}
if (hasFlags) {
builder.append(TextComponent.of(", "));
}
RegionGroupFlag groupFlag = flag.getRegionGroupFlag();
Object group = null;
if (groupFlag != null) {
group = region.getFlag(groupFlag);
}
String flagString;
if (group == null) {
flagString = flag.getName() + ": ";
} else {
flagString = flag.getName() + " -g " + group + ": ";
}
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() + " "));
}
builder.append(flagText);
hasFlags = true;
}
if (!hasFlags) {
TextComponent noFlags = TextComponent.of("(none)", useColors ? TextColor.RED : TextColor.WHITE);
builder.append(noFlags);
}
if (perms != null && perms.maySetFlag(region)) {
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())));
}
}
/**
* Add information about parents.
*/
public void appendParents() {
appendParentTree(true);
}
/**
* Add information about parents.
*
* @param useColors true to use colors
*/
public void appendParentTree(boolean useColors) {
if (region.getParent() == null) {
return;
}
List<ProtectedRegion> inheritance = new ArrayList<>();
ProtectedRegion r = region;
inheritance.add(r);
while (r.getParent() != null) {
r = r.getParent();
inheritance.add(r);
}
ListIterator<ProtectedRegion> it = inheritance.listIterator(
inheritance.size());
ProtectedRegion last = null;
int indent = 0;
while (it.hasPrevious()) {
ProtectedRegion cur = it.previous();
StringBuilder namePrefix = new StringBuilder();
// Put symbol for child
if (indent != 0) {
for (int i = 0; i < indent; i++) {
namePrefix.append(" ");
}
namePrefix.append("\u2937"); //⤷
}
// Put name
builder.append(TextComponent.of(namePrefix.toString(), useColors ? TextColor.GREEN : TextColor.WHITE));
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())));
} else {
builder.append(TextComponent.of(cur.getId(), useColors ? TextColor.GREEN : TextColor.WHITE));
}
// Put (parent)
if (!cur.equals(region)) {
builder.append(TextComponent.of(" (parent, priority=", useColors ? TextColor.GRAY : TextColor.WHITE));
appendPriorityComponent(cur);
builder.append(TextComponent.of(")", useColors ? TextColor.GRAY : TextColor.WHITE));
}
if (last != null && cur.equals(region) && perms != null && perms.maySetParent(cur, last)) {
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())));
}
last = cur;
indent++;
newline();
}
}
/**
* Add information about members.
*/
public void appendDomain() {
builder.append(TextComponent.of("Owners: ", TextColor.BLUE));
addDomainString(region.getOwners(),
perms != null && perms.mayAddOwners(region) ? "addowner" : null,
perms != null && perms.mayRemoveOwners(region) ? "removeowner" : null);
newline();
builder.append(TextComponent.of("Members: ", TextColor.BLUE));
addDomainString(region.getMembers(),
perms != null && perms.mayAddMembers(region) ? "addmember" : null,
perms != null && perms.mayRemoveMembers(region) ? "removemember" : null);
newline();
}
private void addDomainString(DefaultDomain domain, String addCommand, String removeCommand) {
if (domain.size() == 0) {
builder.append(ErrorFormat.wrap("(none)"));
} else {
if (perms != null) {
builder.append(domain.toUserFriendlyComponent(cache));
} else {
builder.append(LabelFormat.wrap(domain.toUserFriendlyString(cache)));
}
}
if (addCommand != null) {
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() + " "))));
}
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() + " "))));
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()))));
}
}
/**
* Add information about coordinates.
*/
public void appendBounds() {
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
builder.append(TextComponent.of("Bounds:", TextColor.BLUE));
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")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg select " + region.getId()));
}
builder.append(bound);
final Location teleFlag = FlagValueCalculator.getEffectiveFlagOf(region, Flags.TELE_LOC, perms != null && perms.getSender() instanceof RegionAssociable ? (RegionAssociable) perms.getSender() : null);
if (teleFlag != null && perms != null && perms.mayTeleportTo(region)) {
builder.append(TextComponent.space().append(TextComponent.of("[Teleport]", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
TextComponent.of("Click to teleport").append(TextComponent.newline()).append(
TextComponent.of(teleFlag.getBlockX() + ", "
+ teleFlag.getBlockY() + ", "
+ teleFlag.getBlockZ()))))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -w \"" + world + "\" " + region.getId()))));
} else if (perms != null && perms.mayTeleportToCenter(region) && region.isPhysicalArea()) {
builder.append(TextComponent.space().append(TextComponent.of("[Center Teleport]", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
TextComponent.of("Click to teleport to the center of the region")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -c -w \"" + world + "\" " + region.getId()))));
}
newline();
}
private void appendPriorityComponent(ProtectedRegion rg) {
final String content = String.valueOf(rg.getPriority());
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() + " ")));
} else {
builder.append(TextComponent.of(content, TextColor.WHITE));
}
}
private void appendRegionInformation() {
appendBasics();
appendFlags();
appendParents();
appendDomain();
appendBounds();
if (cache != null && perms == null) {
builder.append(SubtleFormat.wrap("Any names suffixed by * are 'last seen names' and may not be up to date."));
}
}
@Override
public TextComponent call() {
MessageBox box = new MessageBox("Region Info", builder);
appendRegionInformation();
return box.create();
}
/**
* Send the report to a {@link Actor}.
*
* @param sender the recipient
*/
public void send(Actor sender) {
sender.print(toComponent());
}
public TextComponentProducer append(String str) {
return builder.append(TextComponent.of(str));
}
public TextComponentProducer append(TextComponent component) {
return builder.append(component);
}
public TextComponent toComponent() {
return builder.create();
}
@Override
public String toString() {
return builder.toString().trim();
}
}
@@ -1,310 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.commands.task;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldguard.util.profile.Profile;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
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.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.FlagValueCalculator;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
public class RegionLister implements Callable<Integer> {
private static final Logger log = Logger.getLogger(RegionLister.class.getCanonicalName());
private final Actor sender;
private final RegionManager manager;
private final String world;
private OwnerMatcher ownerMatcher;
private String idFilter;
private ProtectedRegion filterByIntersecting;
private int page;
private String playerName;
private boolean nameOnly;
public RegionLister(RegionManager manager, Actor sender, String world) {
checkNotNull(manager);
checkNotNull(sender);
checkNotNull(world);
this.manager = manager;
this.sender = sender;
this.world = world;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public void filterByIntersecting(ProtectedRegion region) {
this.filterByIntersecting = region;
}
public void filterOwnedByName(String name, boolean nameOnly) {
this.playerName = name;
this.nameOnly = nameOnly;
if (nameOnly) {
filterOwnedByName(name);
} else {
filterOwnedByProfile(name);
}
}
private void filterOwnedByName(final String name) {
ownerMatcher = new OwnerMatcher() {
@Override
public String getName() {
return name;
}
@Override
public boolean isContainedWithin(DefaultDomain domain) {
return domain.contains(name);
}
};
}
private void filterOwnedByProfile(final String name) {
ownerMatcher = new OwnerMatcher() {
private UUID uniqueId;
@Override
public String getName() {
return name;
}
@Override
public boolean isContainedWithin(DefaultDomain domain) throws CommandException {
if (domain.contains(name)) {
return true;
}
if (uniqueId == null) {
Profile profile;
try {
profile = WorldGuard.getInstance().getProfileService().findByName(name);
} catch (IOException e) {
log.log(Level.WARNING, "Failed UUID lookup of '" + name + "'", e);
throw new CommandException("Failed to lookup the UUID of '" + name + "'");
} catch (InterruptedException e) {
log.log(Level.WARNING, "Failed UUID lookup of '" + name + "'", e);
throw new CommandException("The lookup the UUID of '" + name + "' was interrupted");
}
if (profile == null) {
throw new CommandException("A user by the name of '" + name + "' does not seem to exist.");
}
uniqueId = profile.getUniqueId();
}
return domain.contains(uniqueId);
}
};
}
public void filterIdByMatch(String idFilter) {
this.idFilter = idFilter;
}
@Override
public Integer call() throws Exception {
Map<String, ProtectedRegion> regions = manager.getRegions();
Collection<ProtectedRegion> iterableRegions = regions.values();
if (filterByIntersecting != null) {
iterableRegions = filterByIntersecting.getIntersectingRegions(iterableRegions);
}
// Build a list of regions to show
List<RegionListEntry> entries = new ArrayList<>();
for (ProtectedRegion rg : iterableRegions) {
if (rg.getId().equals("__global__")) {
continue;
}
final RegionListEntry entry = new RegionListEntry(rg);
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
entries.add(entry);
}
}
if (ownerMatcher == null) {
Collections.sort(entries);
}
// insert global on top
if (regions.containsKey("__global__")) {
final RegionListEntry entry = new RegionListEntry(regions.get("__global__"));
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
entries.add(0, entry);
}
}
// unless we're matching owners, then sort by ownership
if (ownerMatcher != null) {
Collections.sort(entries);
}
RegionPermissionModel perms = sender.isPlayer() ? new RegionPermissionModel(sender) : null;
String title = ownerMatcher == null ? "Regions" : "Regions for " + ownerMatcher.getName();
String cmd = "/rg list -w \"" + world + "\""
+ (playerName != null ? " -p " + playerName : "")
+ (nameOnly ? " -n" : "")
+ (filterByIntersecting != null ? " -s" : "")
+ (idFilter != null ? " -i " + idFilter : "")
+ " %page%";
PaginationBox box = new RegionListBox(title, cmd, perms, entries, world);
sender.print(box.create(page));
return page;
}
private interface OwnerMatcher {
String getName();
boolean isContainedWithin(DefaultDomain domain) throws CommandException;
}
private static final class RegionListEntry implements Comparable<RegionListEntry> {
private final ProtectedRegion region;
private boolean isOwner;
private boolean isMember;
private RegionListEntry(ProtectedRegion rg) {
this.region = rg;
}
public boolean matches(OwnerMatcher matcher) throws CommandException {
return matcher == null
|| (isOwner = matcher.isContainedWithin(region.getOwners()))
|| (isMember = matcher.isContainedWithin(region.getMembers()));
}
public boolean matches(String idMatcher) {
return idMatcher == null || region.getId().contains(idMatcher);
}
public ProtectedRegion getRegion() {
return region;
}
public boolean isOwner() {
return isOwner;
}
public boolean isMember() {
return isMember;
}
@Override
public int compareTo(RegionListEntry o) {
if (isOwner != o.isOwner) {
return isOwner ? -1 : 1;
}
if (isMember != o.isMember) {
return isMember ? -1 : 1;
}
return region.getId().compareTo(o.region.getId());
}
}
private static class RegionListBox extends PaginationBox {
private final RegionPermissionModel perms;
private final List<RegionListEntry> entries;
private String world;
RegionListBox(String title, String cmd, RegionPermissionModel perms, List<RegionListEntry> entries, String world) {
super(title, cmd);
this.perms = perms;
this.entries = entries;
this.world = world;
}
@Override
public Component getComponent(int number) {
final RegionListEntry entry = entries.get(number);
final TextComponent.Builder builder = TextComponent.builder(number + 1 + ".").color(TextColor.LIGHT_PURPLE);
if (entry.isOwner()) {
builder.append(TextComponent.space()).append(TextComponent.of("+", TextColor.DARK_AQUA)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Region Owner", TextColor.GOLD))));
} else if (entry.isMember()) {
builder.append(TextComponent.space()).append(TextComponent.of("-", TextColor.AQUA)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Region Member", TextColor.GOLD))));
}
builder.append(TextComponent.space()).append(TextComponent.of(entry.getRegion().getId(), TextColor.GOLD));
if (perms != null && perms.mayLookup(entry.region)) {
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()))));
}
final Location teleFlag = FlagValueCalculator.getEffectiveFlagOf(entry.region, Flags.TELE_LOC, perms != null && perms.getSender() instanceof RegionAssociable ? (RegionAssociable) perms.getSender() : null);
if (perms != null && teleFlag != null && perms.mayTeleportTo(entry.region)) {
builder.append(TextComponent.space().append(TextComponent.of("[TP]", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to teleport")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -w \"" + world + "\" " + entry.region.getId()))));
} else if (perms != null && perms.mayTeleportToCenter(entry.getRegion()) && entry.getRegion().isPhysicalArea()) {
builder.append(TextComponent.space().append(TextComponent.of("[TP-Center]", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT,
TextComponent.of("Click to teleport to the center")))
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND,
"/rg tp -c -w \"" + world + "\" " + entry.region.getId()))));
}
return builder.build();
}
@Override
public int getComponentsSize() {
return entries.size();
}
}
}
@@ -1,173 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.config;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.managers.storage.DriverType;
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
import com.sk89q.worldguard.session.handler.WaterBreathing;
import com.sk89q.worldedit.util.report.Unreported;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
/**
* Represents the global configuration and also delegates configuration
* for individual worlds.
*
* @author sk89q
* @author Michael
*/
public abstract class ConfigurationManager {
protected static final Logger log = Logger.getLogger(ConfigurationManager.class.getCanonicalName());
static final String CONFIG_HEADER = "#\r\n" +
"# WorldGuard's main configuration file\r\n" +
"#\r\n" +
"# This is the global configuration file. Anything placed into here will\r\n" +
"# be applied to all worlds. However, each world has its own configuration\r\n" +
"# file to allow you to replace most settings in here for that world only.\r\n" +
"#\r\n" +
"# About editing this file:\r\n" +
"# - DO NOT USE TABS. You MUST use spaces or Bukkit will complain. If\r\n" +
"# you use an editor like Notepad++ (recommended for Windows users), you\r\n" +
"# must configure it to \"replace tabs with spaces.\" In Notepad++, this can\r\n" +
"# be changed in Settings > Preferences > Language Menu.\r\n" +
"# - Don't get rid of the indents. They are indented so some entries are\r\n" +
"# in categories (like \"enforce-single-session\" is in the \"protection\"\r\n" +
"# category.\r\n" +
"# - If you want to check the format of this file before putting it\r\n" +
"# into WorldGuard, paste it into http://yaml-online-parser.appspot.com/\r\n" +
"# and see if it gives \"ERROR:\".\r\n" +
"# - Lines starting with # are comments and so they are ignored.\r\n" +
"#\r\n";
public boolean useRegionsCreatureSpawnEvent;
public boolean activityHaltToggle = false;
public boolean useGodPermission;
public boolean useGodGroup;
public boolean useAmphibiousGroup;
public boolean usePlayerMove;
public boolean usePlayerTeleports;
public boolean deopOnJoin;
public boolean blockInGameOp;
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;
/**
* Region Storage Configuration method, and config values
*/
@Unreported public RegionDriver selectedRegionStoreDriver;
@Unreported public Map<DriverType, RegionDriver> regionStoreDriverMap;
/**
* Get the folder for storing data files and configuration.
*
* @return the data folder
*/
public abstract File getDataFolder();
/**
* Get the folder for storing data files and configuration for each
* world.
*
* @return the data folder
*/
public File getWorldsDataFolder() {
return new File(getDataFolder(), "worlds");
}
/**
* Load the configuration.
*/
public abstract void load();
/**
* Unload the configuration.
*/
public abstract void unload();
/**
* Get the configuration for a world.
*
* @param world The world to get the configuration for
* @return {@code world}'s configuration
*/
public abstract WorldConfiguration get(World world);
public abstract void disableUuidMigration();
/**
* Check to see if god mode is enabled for a player.
*
* @param player The player to check
* @return Whether the player has godmode through WorldGuard or CommandBook
*/
public boolean hasGodMode(LocalPlayer player) {
return WorldGuard.getInstance().getPlatform().getSessionManager().get(player).isInvincible(player);
}
/**
* Enable amphibious mode for a player.
*
* @param player The player to enable amphibious mode for
*/
public void enableAmphibiousMode(LocalPlayer player) {
WaterBreathing handler = WorldGuard.getInstance().getPlatform().getSessionManager().get(player).getHandler(WaterBreathing.class);
if (handler != null) {
handler.setWaterBreathing(true);
}
}
/**
* Disable amphibious mode for a player.
*
* @param player The player to disable amphibious mode for
*/
public void disableAmphibiousMode(LocalPlayer player) {
WaterBreathing handler = WorldGuard.getInstance().getPlatform().getSessionManager().get(player).getHandler(WaterBreathing.class);
if (handler != null) {
handler.setWaterBreathing(false);
}
}
/**
* Check to see if amphibious mode is enabled for a player.
*
* @param player The player to check
* @return Whether {@code player} has amphibious mode
*/
public boolean hasAmphibiousMode(LocalPlayer player) {
WaterBreathing handler = WorldGuard.getInstance().getPlatform().getSessionManager().get(player).getHandler(WaterBreathing.class);
return handler != null && handler.hasWaterBreathing();
}
}
@@ -1,271 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.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 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;
/**
* Holds the configuration for individual worlds.
*
* @author sk89q
* @author Michael
*/
public abstract class WorldConfiguration {
public static final Logger log = Logger.getLogger(WorldConfiguration.class.getCanonicalName());
public static final String CONFIG_HEADER = "#\r\n" +
"# WorldGuard's world configuration file\r\n" +
"#\r\n" +
"# This is a world configuration file. Anything placed into here will only\r\n" +
"# affect this world. If you don't put anything in this file, then the\r\n" +
"# settings will be inherited from the main configuration file.\r\n" +
"#\r\n" +
"# If you see {} below, that means that there are NO entries in this file.\r\n" +
"# Remove the {} and add your own entries.\r\n" +
"#\r\n";
protected File blacklistFile;
@Unreported
protected Blacklist blacklist;
public boolean boundedLocationFlags;
public boolean useRegions;
public boolean simulateSponge;
public int spongeRadius;
public boolean redstoneSponges;
public boolean summaryOnStart;
public boolean opPermissions;
public boolean buildPermissions;
public String buildPermissionDenyMessage = "";
public boolean fireSpreadDisableToggle;
public boolean itemDurability;
public boolean disableExpDrops;
public boolean blockPotionsAlways;
public boolean disableConduitEffects;
public boolean pumpkinScuba;
public boolean noPhysicsGravel;
public boolean noPhysicsSand;
public boolean ropeLadders;
public boolean allowPortalAnywhere;
public Set<String> preventWaterDamage;
public boolean blockLighter;
public boolean disableFireSpread;
public Set<String> disableFireSpreadBlocks;
public boolean preventLavaFire;
public Set<String> allowedLavaSpreadOver;
public boolean blockTNTExplosions;
public boolean blockTNTBlockDamage;
public boolean blockCreeperExplosions;
public boolean blockCreeperBlockDamage;
public boolean blockWitherExplosions;
public boolean blockWitherBlockDamage;
public boolean blockWitherSkullExplosions;
public boolean blockWitherSkullBlockDamage;
public boolean blockEnderDragonBlockDamage;
public boolean blockEnderDragonPortalCreation;
public boolean blockFireballExplosions;
public boolean blockFireballBlockDamage;
public boolean blockWindChargeExplosions;
public boolean blockOtherExplosions;
public boolean blockEntityPaintingDestroy;
public boolean blockEntityItemFrameDestroy;
public boolean blockEntityArmorStandDestroy;
public boolean blockEntityVehicleEntry;
public boolean blockPluginSpawning;
public boolean blockGroundSlimes;
public boolean blockZombieDoorDestruction;
public boolean disableContactDamage;
public boolean disableFallDamage;
public boolean disableLavaDamage;
public boolean disableFireDamage;
public boolean disableLightningDamage;
public boolean disableDrowningDamage;
public boolean disableSuffocationDamage;
public boolean teleportOnSuffocation;
public boolean disableVoidDamage;
public boolean teleportOnVoid;
public boolean safeFallOnVoid;
public boolean disableExplosionDamage;
public boolean disableMobDamage;
public boolean highFreqFlags;
public boolean checkLiquidFlow;
public String regionWand;
public Set<EntityType> blockCreatureSpawn;
public boolean allowTamedSpawns;
public int maxClaimVolume;
public boolean claimOnlyInsideExistingRegions;
public String setParentOnClaim;
public int maxRegionCountPerPlayer;
public boolean antiWolfDumbness;
public boolean signChestProtection;
public boolean disableSignChestProtectionCheck;
public boolean removeInfiniteStacks;
public boolean disableCreatureCropTrampling;
public boolean disablePlayerCropTrampling;
public boolean disableCreatureTurtleEggTrampling;
public boolean disablePlayerTurtleEggTrampling;
public boolean disableCreatureSnifferEggTrampling;
public boolean disablePlayerSnifferEggTrampling;
public boolean preventLightningFire;
public Set<String> disallowedLightningBlocks;
public boolean disableThunder;
public boolean disableWeather;
public boolean alwaysRaining;
public boolean alwaysThundering;
public boolean disablePigZap;
public boolean disableVillagerZap;
public boolean disableCreeperPower;
public boolean disableHealthRegain;
public boolean disableMushroomSpread;
public boolean disableIceMelting;
public boolean disableSnowMelting;
public boolean disableSnowFormation;
public boolean disableIceFormation;
public boolean disableLeafDecay;
public boolean disableGrassGrowth;
public boolean disableMyceliumSpread;
public boolean disableVineGrowth;
public boolean disableRockGrowth;
public boolean disableSculkGrowth;
public boolean disableCropGrowth;
public boolean disableEndermanGriefing;
public boolean disableSnowmanTrails;
public boolean disableSoilDehydration;
public boolean disableSoilMoistureChange;
public boolean disableCoralBlockFade;
public boolean disableCopperBlockFade;
public Set<String> allowedSnowFallOver;
public boolean regionInvinciblityRemovesMobs;
public boolean regionCancelEmptyChatEvents;
public boolean regionNetherPortalProtection;
public boolean forceDefaultTitleTimes;
public boolean fakePlayerBuildOverride;
public boolean explosionFlagCancellation;
public boolean disableDeathMessages;
public boolean strictEntitySpawn;
public boolean ignoreHopperMoveEvents;
public boolean breakDeniedHoppers;
public boolean useMaxPriorityAssociation;
protected Map<String, Integer> maxRegionCounts;
/**
* Load the configuration.
*/
public abstract void loadConfiguration();
public Blacklist getBlacklist() {
return this.blacklist;
}
public List<String> convertLegacyItems(List<String> legacyItems) {
return legacyItems.stream().map(this::convertLegacyItem).filter(Objects::nonNull).collect(Collectors.toList());
}
public String convertLegacyItem(String legacy) {
String[] splitter = legacy.split(":", 2);
try {
int id;
byte data;
if (splitter.length == 1) {
id = Integer.parseInt(splitter[0]);
data = 0;
} else {
id = Integer.parseInt(splitter[0]);
data = Byte.parseByte(splitter[1]);
}
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 null;
}
public List<String> convertLegacyBlocks(List<String> legacyBlocks) {
return legacyBlocks.stream().map(this::convertLegacyBlock).filter(Objects::nonNull).collect(Collectors.toList());
}
public String convertLegacyBlock(String legacy) {
String[] splitter = legacy.split(":", 2);
try {
int id;
byte data;
if (splitter.length == 1) {
id = Integer.parseInt(splitter[0]);
data = 0;
} else {
id = Integer.parseInt(splitter[0]);
data = Byte.parseByte(splitter[1]);
}
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 null;
}
public int getMaxRegionCount(LocalPlayer player) {
int max = -1;
for (String group : player.getGroups()) {
if (maxRegionCounts.containsKey(group)) {
int groupMax = maxRegionCounts.get(group);
if (max < groupMax) {
max = groupMax;
}
}
}
if (max <= -1) {
max = maxRegionCountPerPlayer;
}
return max;
}
}
@@ -1,131 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.config;
import com.google.common.collect.ImmutableMap;
import com.sk89q.util.yaml.YAMLFormat;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldguard.protection.managers.storage.DriverType;
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.worldedit.util.report.Unreported;
import com.sk89q.worldguard.util.sql.DataSourceConfig;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public abstract class YamlConfigurationManager extends ConfigurationManager {
@Unreported private YAMLProcessor config;
public abstract void copyDefaults();
@Override
public void load() {
copyDefaults();
config = new YAMLProcessor(new File(getDataFolder(), "config.yml"), true, YAMLFormat.EXTENDED);
try {
config.load();
} catch (IOException e) {
log.severe("Error reading configuration for global config: ");
e.printStackTrace();
}
config.removeProperty("suppress-tick-sync-warnings");
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);
config.removeProperty("auto-invincible-permission");
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);
hostKeys = new HashMap<>();
Object hostKeysRaw = config.getProperty("host-keys");
if (!(hostKeysRaw instanceof Map)) {
config.setProperty("host-keys", new HashMap<String, String>());
} else {
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) hostKeysRaw).entrySet()) {
String key = String.valueOf(entry.getKey());
String value = String.valueOf(entry.getValue());
hostKeys.put(key.toLowerCase(), value);
}
}
hostKeysAllowFMLClients = config.getBoolean("security.host-keys-allow-forge-clients", false);
// ====================================================================
// Region store drivers
// ====================================================================
boolean useSqlDatabase = config.getBoolean("regions.sql.use", false);
String sqlDsn = config.getString("regions.sql.dsn", "jdbc:mysql://localhost/worldguard");
String sqlUsername = config.getString("regions.sql.username", "worldguard");
String sqlPassword = config.getString("regions.sql.password", "worldguard");
String sqlTablePrefix = config.getString("regions.sql.table-prefix", "");
if (!useSqlDatabase) {
config.removeProperty("regions.sql");
} else {
log.warning("SQL support for WorldGuard region storage is deprecated for removal in a future version. Please migrate to YAML storage.");
log.warning("For details, see https://worldguard.enginehub.org/en/latest/regions/storage/");
}
DataSourceConfig dataSourceConfig = new DataSourceConfig(sqlDsn, sqlUsername, sqlPassword, sqlTablePrefix);
SQLDriver sqlDriver = new SQLDriver(dataSourceConfig);
DirectoryYamlDriver yamlDriver = new DirectoryYamlDriver(getWorldsDataFolder(), "regions.yml");
this.regionStoreDriverMap = ImmutableMap.<DriverType, RegionDriver>builder()
.put(DriverType.MYSQL, sqlDriver)
.put(DriverType.YAML, yamlDriver)
.build();
this.selectedRegionStoreDriver = useSqlDatabase ? sqlDriver : yamlDriver;
postLoad();
config.setHeader(CONFIG_HEADER);
}
public void postLoad() {}
public YAMLProcessor getConfig() {
return config;
}
@Override
public void disableUuidMigration() {
config.setProperty("regions.uuid-migration.perform-on-next-start", false);
if (!config.save()) {
log.severe("Error saving configuration!");
}
}
}
@@ -1,125 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.config;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.util.report.Unreported;
import java.util.ArrayList;
import java.util.List;
public abstract class YamlWorldConfiguration extends WorldConfiguration {
@Unreported protected YAMLProcessor parentConfig;
@Unreported protected YAMLProcessor config;
public boolean getBoolean(String node, boolean def) {
boolean val = parentConfig.getBoolean(node, def);
if (config.getProperty(node) != null) {
return config.getBoolean(node, def);
} else {
return val;
}
}
public String getString(String node, String def) {
String val = parentConfig.getString(node, def);
if (config.getProperty(node) != null) {
return config.getString(node, def);
} else {
return val;
}
}
public int getInt(String node, int def) {
int val = parentConfig.getInt(node, def);
if (config.getProperty(node) != null) {
return config.getInt(node, def);
} else {
return val;
}
}
@SuppressWarnings("unused")
private double getDouble(String node, double def) {
double val = parentConfig.getDouble(node, def);
if (config.getProperty(node) != null) {
return config.getDouble(node, def);
} else {
return val;
}
}
public List<Integer> getIntList(String node, List<Integer> def) {
List<Integer> res = parentConfig.getIntList(node, def);
if (res == null || res.size() == 0) {
parentConfig.setProperty(node, new ArrayList<Integer>());
}
if (config.getProperty(node) != null) {
res = config.getIntList(node, def);
}
return res;
}
public List<String> getStringList(String node, List<String> def) {
List<String> res = parentConfig.getStringList(node, def);
if (res == null || res.size() == 0) {
parentConfig.setProperty(node, new ArrayList<String>());
}
if (config.getProperty(node) != null) {
res = config.getStringList(node, def);
}
return res;
}
public List<String> getKeys(String node) {
List<String> res = parentConfig.getKeys(node);
if (res == null || res.size() == 0) {
res = config.getKeys(node);
}
if (res == null) {
res = new ArrayList<>();
}
return res;
}
public Object getProperty(String node) {
Object res = parentConfig.getProperty(node);
if (config.getProperty(node) != null) {
res = config.getProperty(node);
}
return res;
}
}
@@ -1,108 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.domains.registry.CustomDomainContext;
import com.sk89q.worldguard.domains.registry.InvalidDomainFormatException;
import com.sk89q.worldguard.util.ChangeTracked;
import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
public abstract class CustomDomain implements Domain, ChangeTracked {
private static final Pattern VALID_NAME = Pattern.compile("^[a-z0-9\\-]{1,40}$");
private final String name;
private boolean dirty;
public CustomDomain(String name) {
if (name == null ||!isValidName(name)) {
throw new IllegalArgumentException("Invalid Domain name used.");
}
this.name = name;
}
/**
* Get the name of the domain resolver.
*
* @return The name of the domain
*/
public String getName() {
return name;
}
/**
* Parse a given input to fill the context of the CustomDomain.
*
* @param context the {@link CustomDomainContext}
* @throws InvalidDomainFormatException Raised if the input is invalid
*/
public abstract void parseInput(CustomDomainContext context) throws InvalidDomainFormatException;
/**
* Convert a raw type that was loaded (from a YAML file, for example)
* into the custom domain.
*
* @param o The object
*/
public abstract void unmarshal(Object o);
/**
* Convert the current Domain to a storable foramt
*
* @return The marshalled type
*/
public abstract Object marshal();
/**
* Test whether a flag name is valid.
*
* @param name The flag name
* @return Whether the name is valid
*/
public static boolean isValidName(String name) {
checkNotNull(name, "name");
// g is already reserved by the group domain
return VALID_NAME.matcher(name).matches() && !name.equalsIgnoreCase("g");
}
@Override
public boolean contains(LocalPlayer player) {
return contains(player.getUniqueId());
}
@Override
public int size() {
return 1;
}
@Override
public boolean isDirty() {
return dirty;
}
@Override
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
}
@@ -1,560 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.util.ChangeTracked;
import com.sk89q.worldguard.util.profile.Profile;
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A combination of a {@link PlayerDomain} and a {@link GroupDomain}.
*/
public class DefaultDomain implements Domain, ChangeTracked {
private PlayerDomain playerDomain = new PlayerDomain();
private GroupDomain groupDomain = new GroupDomain();
private final Map<String, CustomDomain> customDomains = new ConcurrentHashMap<>();
private boolean customDomainsChanged = false;
/**
* Create a new domain.
*/
public DefaultDomain() {
}
/**
* Create a new domain from an existing one, making a copy of all values.
*
* @param existing the other domain to copy values from
*/
public DefaultDomain(DefaultDomain existing) {
setPlayerDomain(existing.getPlayerDomain());
setGroupDomain(existing.getGroupDomain());
setCustomDomains(existing.customDomains);
}
/**
* Get the domain that holds the players.
*
* @return a domain
*/
public PlayerDomain getPlayerDomain() {
return playerDomain;
}
/**
* Set a new player domain.
*
* @param playerDomain a domain
*/
public void setPlayerDomain(PlayerDomain playerDomain) {
checkNotNull(playerDomain);
this.playerDomain = new PlayerDomain(playerDomain);
}
/**
* Set the domain that holds the groups.
*
* @return a domain
*/
public GroupDomain getGroupDomain() {
return groupDomain;
}
/**
* Set a new group domain.
*
* @param groupDomain a domain
*/
public void setGroupDomain(GroupDomain groupDomain) {
checkNotNull(groupDomain);
this.groupDomain = new GroupDomain(groupDomain);
}
/**
* Add new custom domains
*
* @param customDomain a domain
*/
public void addCustomDomain(CustomDomain customDomain) {
checkNotNull(customDomain);
this.customDomains.put(customDomain.getName(), customDomain);
this.customDomainsChanged = true;
}
/**
* Remove a custom domain matched by the name
*
* @param name the name
*/
public void removeCustomDomain(String name) {
checkNotNull(name);
if (this.customDomains.remove(name) != null) {
this.customDomainsChanged = true;
}
}
/**
* Remove a custom domain
*
* @param customDomain a domain
*/
public void removeCustomDomain(CustomDomain customDomain) {
checkNotNull(customDomain);
if (this.customDomains.remove(customDomain.getName()) != null) {
this.customDomainsChanged = true;
}
}
/**
* Set the api domains to a specified value
*
* @param customDomains the domains
*/
public void setCustomDomains(Map<String, CustomDomain> customDomains) {
checkNotNull(customDomains);
this.customDomains.clear();
this.customDomains.putAll(customDomains);
this.customDomainsChanged = true;
}
/**
* Get all api domains
*
* @return a unmodifiable copy of the domains
*/
public Collection<CustomDomain> getCustomDomains() {
return Collections.unmodifiableCollection(this.customDomains.values());
}
/**
* Get the api domain specified by its name
*
* @param name the name of the domain
* @return the custom domain
*/
public @Nullable CustomDomain getCustomDomain(String name) {
return this.customDomains.get(name);
}
/**
* Add the given player to the domain, identified by the player's name.
*
* @param name the name of the player
*/
public void addPlayer(String name) {
playerDomain.addPlayer(name);
}
/**
* Remove the given player from the domain, identified by the player's name.
*
* @param name the name of the player
*/
public void removePlayer(String name) {
playerDomain.removePlayer(name);
}
/**
* Remove the given player from the domain, identified by the player's UUID.
*
* @param uuid the UUID of the player
*/
public void removePlayer(UUID uuid) {
playerDomain.removePlayer(uuid);
}
/**
* Add the given player to the domain, identified by the player's UUID.
*
* @param uniqueId the UUID of the player
*/
public void addPlayer(UUID uniqueId) {
playerDomain.addPlayer(uniqueId);
}
/**
* Remove the given player from the domain, identified by either the
* player's name, the player's unique ID, or both.
*
* @param player the player
*/
public void removePlayer(LocalPlayer player) {
playerDomain.removePlayer(player);
}
/**
* Add the given player to the domain, identified by the player's UUID.
*
* @param player the player
*/
public void addPlayer(LocalPlayer player) {
playerDomain.addPlayer(player);
}
/**
* Add all the entries from another domain.
*
* @param other the other domain
*/
public void addAll(DefaultDomain other) {
checkNotNull(other);
for (String player : other.getPlayers()) {
addPlayer(player);
}
for (UUID uuid : other.getUniqueIds()) {
addPlayer(uuid);
}
for (String group : other.getGroups()) {
addGroup(group);
}
for (CustomDomain domain : other.getCustomDomains()) {
addCustomDomain(domain);
}
}
/**
* Remove all the entries from another domain.
*
* @param other the other domain
*/
public void removeAll(DefaultDomain other) {
checkNotNull(other);
for (String player : other.getPlayers()) {
removePlayer(player);
}
for (UUID uuid : other.getUniqueIds()) {
removePlayer(uuid);
}
for (String group : other.getGroups()) {
removeGroup(group);
}
for (CustomDomain domain : other.getCustomDomains()) {
removeCustomDomain(domain.getName());
}
}
/**
* Get the set of player names.
*
* @return the set of player names
*/
public Set<String> getPlayers() {
return playerDomain.getPlayers();
}
/**
* Get the set of player UUIDs.
*
* @return the set of player UUIDs
*/
public Set<UUID> getUniqueIds() {
return playerDomain.getUniqueIds();
}
/**
* Add the name of the group to the domain.
*
* @param name the name of the group.
*/
public void addGroup(String name) {
groupDomain.addGroup(name);
}
/**
* Remove the given group from the domain.
*
* @param name the name of the group
*/
public void removeGroup(String name) {
groupDomain.removeGroup(name);
}
/**
* Get the set of group names.
*
* @return the set of group names
*/
public Set<String> getGroups() {
return groupDomain.getGroups();
}
@Override
public boolean contains(LocalPlayer player) {
return playerDomain.contains(player) || groupDomain.contains(player) || customDomains.values().stream().anyMatch(d -> d.contains(player));
}
@Override
public boolean contains(UUID uniqueId) {
return playerDomain.contains(uniqueId) || customDomains.values().stream().anyMatch(d -> d.contains(uniqueId));
}
@Override
public boolean contains(String playerName) {
return playerDomain.contains(playerName);
}
@Override
public int size() {
return groupDomain.size() + playerDomain.size() + customDomains.size();
}
@Override
public void clear() {
playerDomain.clear();
groupDomain.clear();
}
public void removeAll() {
clear();
}
public String toPlayersString() {
return toPlayersString(null);
}
public String toPlayersString(@Nullable ProfileCache cache) {
List<String> output = new ArrayList<>();
for (String name : playerDomain.getPlayers()) {
output.add("name:" + name);
}
if (cache != null) {
ImmutableMap<UUID, Profile> results = cache.getAllPresent(playerDomain.getUniqueIds());
for (UUID uuid : playerDomain.getUniqueIds()) {
Profile profile = results.get(uuid);
if (profile != null) {
output.add(profile.getName() + "*");
} else {
output.add("uuid:" + uuid);
}
}
} else {
for (UUID uuid : playerDomain.getUniqueIds()) {
output.add("uuid:" + uuid);
}
}
output.sort(String.CASE_INSENSITIVE_ORDER);
return String.join(", ", output);
}
public String toGroupsString() {
StringBuilder str = new StringBuilder();
for (Iterator<String> it = groupDomain.getGroups().iterator(); it.hasNext(); ) {
str.append("g:");
str.append(it.next());
if (it.hasNext()) {
str.append(", ");
}
}
return str.toString();
}
public String toCustomDomainsString() {
List<String> output = new ArrayList<>();
for (CustomDomain customDomain : customDomains.values()) {
output.add(customDomain.getName() + ":" + customDomain.toString());
}
output.sort(String.CASE_INSENSITIVE_ORDER);
return String.join(", ", output);
}
public String toUserFriendlyString() {
return toUserFriendlyString(null);
}
public String toUserFriendlyString(@Nullable ProfileCache cache) {
StringBuilder str = new StringBuilder();
if (playerDomain.size() > 0) {
str.append(toPlayersString(cache));
}
if (groupDomain.size() > 0) {
if (str.length() > 0) {
str.append("; ");
}
str.append(toGroupsString());
}
if (!customDomains.isEmpty()) {
if (str.length() > 0) {
str.append("; ");
}
str.append(toCustomDomainsString());
}
return str.toString();
}
public Component toUserFriendlyComponent(@Nullable ProfileCache cache) {
final TextComponent.Builder builder = TextComponent.builder("");
if (playerDomain.size() > 0) {
builder.append(toPlayersComponent(cache));
}
if (groupDomain.size() > 0) {
if (playerDomain.size() > 0) {
builder.append(TextComponent.of("; "));
}
builder.append(toGroupsComponent());
}
if (!customDomains.isEmpty()) {
if (playerDomain.size() > 0 || groupDomain.size() > 0) {
builder.append(TextComponent.of("; "));
}
builder.append(toCustomDomainsComponent());
}
return builder.build();
}
private Component toGroupsComponent() {
final TextComponent.Builder builder = TextComponent.builder("");
for (Iterator<String> it = groupDomain.getGroups().iterator(); it.hasNext(); ) {
builder.append(TextComponent.of("g:", TextColor.GRAY))
.append(TextComponent.of(it.next(), TextColor.GOLD));
if (it.hasNext()) {
builder.append(TextComponent.of(", "));
}
}
return builder.build().hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Groups")));
}
private Component toPlayersComponent(ProfileCache cache) {
List<String> uuids = Lists.newArrayList();
Map<String, UUID> profileMap = Maps.newHashMap();
for (String name : playerDomain.getPlayers()) {
profileMap.put(name, null);
}
if (cache != null) {
ImmutableMap<UUID, Profile> results = cache.getAllPresent(playerDomain.getUniqueIds());
for (UUID uuid : playerDomain.getUniqueIds()) {
Profile profile = results.get(uuid);
if (profile != null) {
profileMap.put(profile.getName(), uuid);
} else {
uuids.add(uuid.toString());
}
}
} else {
for (UUID uuid : playerDomain.getUniqueIds()) {
uuids.add(uuid.toString());
}
}
final TextComponent.Builder builder = TextComponent.builder("");
final Iterator<TextComponent> profiles = profileMap.keySet().stream().sorted().map(name -> {
final UUID uuid = profileMap.get(name);
if (uuid == null) {
return TextComponent.of(name, TextColor.YELLOW)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Name only", TextColor.GRAY)
.append(TextComponent.newline()).append(TextComponent.of("Click to copy"))))
.clickEvent(ClickEvent.of(ClickEvent.Action.COPY_TO_CLIPBOARD, name));
} else {
return TextComponent.of(name, TextColor.YELLOW)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Last known name of uuid: ", TextColor.GRAY)
.append(TextComponent.of(uuid.toString(), TextColor.WHITE))
.append(TextComponent.newline()).append(TextComponent.of("Click to copy"))))
.clickEvent(ClickEvent.of(ClickEvent.Action.COPY_TO_CLIPBOARD, uuid.toString()));
}
}).iterator();
while (profiles.hasNext()) {
builder.append(profiles.next());
if (profiles.hasNext() || !uuids.isEmpty()) {
builder.append(TextComponent.of(", "));
}
}
if (!uuids.isEmpty()) {
builder.append(TextComponent.of(uuids.size() + " unknown uuid" + (uuids.size() == 1 ? "" : "s"), TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Unable to resolve the name for:", TextColor.GRAY)
.append(TextComponent.newline())
.append(TextComponent.of(String.join("\n", uuids), TextColor.WHITE))
.append(TextComponent.newline().append(TextComponent.of("Click to copy")))))
.clickEvent(ClickEvent.of(ClickEvent.Action.COPY_TO_CLIPBOARD, String.join(",", uuids))));
}
return builder.build();
}
private Component toCustomDomainsComponent() {
final TextComponent.Builder builder = TextComponent.builder("");
for (Iterator<CustomDomain> it = customDomains.values().iterator(); it.hasNext(); ) {
CustomDomain domain = it.next();
builder.append(TextComponent.of(domain.getName() + ":", TextColor.LIGHT_PURPLE))
.append(TextComponent.of(domain.toString(), TextColor.GOLD));
if (it.hasNext()) {
builder.append(TextComponent.of(", "));
}
}
return builder.build().hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("CustomDomain")));
}
@Override
public boolean isDirty() {
return playerDomain.isDirty() || groupDomain.isDirty() ||
customDomainsChanged || customDomains.values().stream().anyMatch(ChangeTracked::isDirty);
}
@Override
public void setDirty(boolean dirty) {
playerDomain.setDirty(dirty);
groupDomain.setDirty(dirty);
customDomainsChanged = dirty;
customDomains.values().forEach(d -> d.setDirty(dirty));
}
@Override
public String toString() {
return "{players=" + playerDomain +
", groups=" + groupDomain +
", custom=" + customDomains +
'}';
}
}
@@ -1,98 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains.registry;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.commands.CommandInputContext;
import javax.annotation.Nullable;
import java.util.Map;
public final class CustomDomainContext extends CommandInputContext<InvalidDomainFormatException> {
private CustomDomainContext(Actor sender, String input, Map<String, Object> values) {
super(sender, input, values);
}
public static CustomDomainContext.CustomDomainContextBuilder create() {
return new CustomDomainContext.CustomDomainContextBuilder();
}
/**
* Create a copy of this CustomDomainContext, with optional substitutions for values
*
* <p>If any supplied variable is null, it will be ignored.
* If a map is supplied, it will override this CustomDomainContext's values of the same key,
* but unprovided keys will not be overriden and will be returned as shallow copies.</p>
*
* @param commandSender CommandSender for the new CustomDomainContext to run under
* @param s String of the user input for the new CustomDomainContext
* @param values map of values to override from the current CustomDomainContext
* @return a copy of this CustomDomainContext
*/
public CustomDomainContext copyWith(@Nullable Actor commandSender, @Nullable String s, @Nullable Map<String, Object> values) {
Map<String, Object> map = Maps.newHashMap();
map.putAll(context);
if (values != null) {
map.putAll(values);
}
return new CustomDomainContext(commandSender == null ? this.sender : commandSender, s == null ? this.input : s, map);
}
@Override
protected InvalidDomainFormatException createException(String str) {
return new InvalidDomainFormatException(str);
}
public static class CustomDomainContextBuilder {
private Actor sender;
private String input;
private Map<String, Object> map = Maps.newHashMap();
public CustomDomainContextBuilder setSender(Actor sender) {
this.sender = sender;
return this;
}
public CustomDomainContextBuilder setInput(String input) {
this.input = input;
return this;
}
public CustomDomainContextBuilder setObject(String key, Object value) {
this.map.put(key, value);
return this;
}
public boolean tryAddToMap(String key, Object value) {
if (map.containsKey(key)) return false;
this.map.put(key, value);
return true;
}
public CustomDomainContext build() {
return new CustomDomainContext(sender, input, map);
}
}
}
@@ -1,94 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains.registry;
import com.sk89q.worldguard.domains.CustomDomain;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
public interface DomainRegistry extends Iterable<DomainFactory<?>> {
/**
* Register a new Domain
*
* <p>There may be an appropiate time to register domains. if domains are
* registered outside this time, then an exception may be thrown.</p>
*
* @param domain The domain
* @throws DomainConflictException Thrown when already an existing domain exists with the same name
* @throws IllegalStateException If it is not the right time to register new domains
*/
void register(String name, DomainFactory<?> domain) throws DomainConflictException;
/**
* Register a collection of domains.
*
* <p>There may be an appropriate time to register domains. If domains are
* registered outside this time, then an exception may be thrown.</p>
*
* <p>If there is a domain conflict, then an error will be logged but
* no exception will be thrown.</p>
*
* @param domains a collection of domain factories
* @throws IllegalStateException If it is not the right time to register new domains
*/
void registerAll(Map<String, DomainFactory<?>> domains);
/**
* Get the domain by its name.
*
* @param name The name
* @return The domain, if it has been registered
*/
@Nullable
DomainFactory<?> get(String name);
/**
* Try to get a domain by its name
*/
@Nullable
CustomDomain createDomain(String name);
/**
* Get all domains keyed by the registered name
*
* @return All domains
*/
Map<String, DomainFactory<?>> getAll();
/**
* Unmarshal a raw map of values into a list of domains with their
* unmarshalled values.
*
* @param rawValues The raw values map
* @param createUnknown Whether "just in time" domains should be created for unknown domains
* @return The unmarshalled domain list
*/
Map<String, CustomDomain> unmarshal(Map<String, Object> rawValues, boolean createUnknown);
/**
* Get the number of registered domains.
*
* @return The number of registered domains
*/
int size();
}
@@ -1,166 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains.registry;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
import com.sk89q.worldguard.domains.CustomDomain;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
public class SimpleDomainRegistry implements DomainRegistry {
private static final Logger log = Logger.getLogger(SimpleDomainRegistry.class.getCanonicalName());
private final Object lock = new Object();
private final ConcurrentMap<String, DomainFactory<?>> domains = Maps.newConcurrentMap();
private boolean initialized = false;
public boolean isInitialized() {
return initialized;
}
public void setInitialized(boolean initialized) {
this.initialized = initialized;
}
@Override
public void register(String name, DomainFactory<?> domain) throws DomainConflictException {
synchronized (lock) {
if (initialized) {
throw new IllegalStateException("New domains cannot be registered at this time");
}
forceRegister(name, domain);
}
}
@Override
public void registerAll(Map<String, DomainFactory<?>> domains) {
synchronized (lock) {
for (Map.Entry<String, DomainFactory<?>> entry : domains.entrySet()) {
try {
register(entry.getKey(), entry.getValue());
} catch (DomainConflictException e) {
log.log(Level.WARNING, e.getMessage());
}
}
}
}
private <T extends DomainFactory<?>> T forceRegister(String name, T domain) throws DomainConflictException {
checkNotNull(domain, "domain");
checkNotNull(name, "name");
if (!CustomDomain.isValidName(name)) {
throw new IllegalArgumentException("Invalid Domain name used.");
}
synchronized (lock) {
if (domains.containsKey(name)) {
throw new DomainConflictException("A domain already exists by the name " + name);
}
domains.put(name, domain);
}
return domain;
}
@Nullable
@Override
public DomainFactory<?> get(String name) {
checkNotNull(name, "name");
return domains.get(name.toLowerCase());
}
@Nullable
@Override
public CustomDomain createDomain(String name) {
DomainFactory<?> factory = get(name);
if (factory == null) return null;
return factory.create(name);
}
@Override
public Map<String, DomainFactory<?>> getAll() {
return ImmutableMap.copyOf(domains);
}
private CustomDomain getOrCreate(String name, Object value, boolean createUnknown) {
CustomDomain customDomain = createDomain(name);
if (customDomain != null) {
customDomain.unmarshal(value);
return customDomain;
}
synchronized (lock) {
customDomain = createDomain(name); // Load again because the previous load was not synchronized
if (customDomain != null) {
customDomain.unmarshal(value);
return customDomain;
}
if (createUnknown) {
DomainFactory<UnknownDomain> unknownFactory = forceRegister(name, UnknownDomain.FACTORY);
if (unknownFactory != null) {
customDomain = unknownFactory.create(name);
if (customDomain != null) customDomain.unmarshal(value);
return customDomain;
}
}
}
return null;
}
public Map<String, CustomDomain> unmarshal(Map<String, Object> rawValues, boolean createUnknown) {
checkNotNull(rawValues, "rawValues");
Map<String, CustomDomain> domains = new HashMap<>();
for (Map.Entry<String, Object> entry : rawValues.entrySet()) {
try {
CustomDomain domain = getOrCreate(entry.getKey(), entry.getValue(), createUnknown);
domains.put(domain.getName(), domain);
} catch (Throwable e) {
log.log(Level.WARNING, "Failed to unmarshal domain for " + entry.getKey(), e);
}
}
return domains;
}
@Override
public int size() {
return domains.size();
}
@Override
public Iterator<DomainFactory<?>> iterator() {
return Iterators.unmodifiableIterator(domains.values().iterator());
}
}
@@ -1,35 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.platform;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
public interface DebugHandler {
void testBreak(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
void testPlace(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
void testInteract(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
void testDamage(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
}
@@ -1,174 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.internal.platform;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
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 javax.annotation.Nullable;
import java.util.Iterator;
import java.util.List;
public interface StringMatcher {
/**
* Match a world.
*
* The filter string syntax is as follows:
* #main returns the main world
* #normal returns the first world with a normal environment
* #nether return the first world with a nether environment
* #player:[name] returns the world that a player named {@code name} is located in, if the player is online.
* [name] A world with the name {@code name}
*
* @param sender The sender requesting a match
* @param filter The filter string
* @return The resulting world
* @throws CommandException if no world matches
*/
World matchWorld(Actor sender, String filter) throws CommandException;
/**
* Match player names.
*
* The filter string uses the following format:
* \@[name] looks up all players with the exact {@code name}
* *[name] matches any player whose name contains {@code name}
* [name] matches any player whose name starts with {@code name}
*
* @param filter The filter string to check.
* @return A {@link List} of players who match {@code filter}
*/
List<LocalPlayer> matchPlayerNames(String filter);
/**
* Checks if the given list of players is greater than size 0, otherwise
* throw an exception.
*
* @param players The {@link List} to check
* @return {@code players} as an {@link Iterable}
* @throws CommandException If {@code players} is empty
*/
default Iterable<? extends LocalPlayer> checkPlayerMatch(List<? extends LocalPlayer> players) throws CommandException {
// Check to see if there were any matches
if (players.isEmpty()) {
throw new CommandException("No players matched query.");
}
return players;
}
/**
* Matches players based on the specified filter string
*
* The filter string format is as follows:
* * returns all the players currently online
* If {@code sender} is a {@link Player}:
* #world returns all players in the world that {@code sender} is in
* #near reaturns all players within 30 blocks of {@code sender}'s location
* Otherwise, the format is as specified in {@link #matchPlayerNames(String)}
*
* @param source The CommandSender who is trying to find a player
* @param filter The filter string for players
* @return iterator for players
* @throws CommandException if no matches are found
*/
Iterable<? extends LocalPlayer> matchPlayers(Actor source, String filter) throws CommandException;
/**
* Match only a single player.
*
* @param sender The {@link Actor} who is requesting a player match
* @param filter The filter string.
* @see #matchPlayers(LocalPlayer) for filter string syntax
* @return The single player
* @throws CommandException If more than one player match was found
*/
default LocalPlayer matchSinglePlayer(Actor sender, String filter) throws CommandException {
// This will throw an exception if there are no matches
Iterator<? extends LocalPlayer> players = matchPlayers(sender, filter).iterator();
LocalPlayer match = players.next();
// We don't want to match the wrong person, so fail if if multiple
// players were found (we don't want to just pick off the first one,
// as that may be the wrong player)
if (players.hasNext()) {
throw new CommandException("More than one player found! " +
"Use @<name> for exact matching.");
}
return match;
}
/**
* Match only a single player or console.
*
* The filter string syntax is as follows:
* #console, *console, or ! return the server console
* All syntax from {@link #matchSinglePlayer(Actor, String)}
* @param sender The sender trying to match a CommandSender
* @param filter The filter string
* @return The resulting CommandSender
* @throws CommandException if either zero or more than one player matched.
*/
Actor matchPlayerOrConsole(Actor sender, String filter) throws CommandException;
/**
* Get a single player as an iterator for players.
*
* @param player The player to return in an Iterable
* @return iterator for player
*/
default Iterable<LocalPlayer> matchPlayers(LocalPlayer player) {
return Lists.newArrayList(player);
}
/**
* Gets a world by name, if possible.
*
* @param worldName The name
* @return The world
*/
@Nullable
World getWorldByName(String worldName);
/**
* Replace macros in the text.
*
* The macros replaced are as follows:
* %name%: The name of {@code sender}.
* %id%: The unique name of the sender.
* %online%: The number of players currently online on the server
* If {@code sender} is a Player:
* %world%: The name of the world {@code sender} is located in
* %health%: The health of {@code sender}.
*
* @param sender The sender to check
* @param message The message to replace macros in
* @return The message with macros replaced
*/
String replaceMacros(Actor sender, String message);
}
@@ -1,172 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.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;
/**
* A platform for implementing.
*/
public interface WorldGuardPlatform {
/**
* Gets the name of the platform.
*
* @return The platform name
*/
String getPlatformName();
/**
* Gets the version of the platform.
*
* @return The platform version
*/
String getPlatformVersion();
/**
* Notifies the platform when a flag context is created.
*
* @param flagContextBuilder The flag context
*/
void notifyFlagContextCreate(FlagContext.FlagContextBuilder flagContextBuilder);
/**
* Get the global ConfigurationManager.
* Use this to access global configuration values and per-world configuration values.
*
* @return The global ConfigurationManager
*/
ConfigurationManager getGlobalStateManager();
/**
* Gets an instance of the matcher, which handles matching
* worlds, players, colours, etc from strings.
*
* @return The matcher
*/
StringMatcher getMatcher();
/**
* Gets the session manager.
*
* @return The session manager
*/
SessionManager getSessionManager();
/**
* Notifies all with the worldguard.notify permission.
* This will check both superperms and WEPIF,
* but makes sure WEPIF checks don't result in duplicate notifications
*
* @param message The notification to broadcast
*/
void broadcastNotification(String message);
/**
* Notifies all with the worldguard.notify permission.
* This will check both superperms and WEPIF,
* but makes sure WEPIF checks don't result in duplicate notifications
*
* @param component The notification to broadcast
*/
void broadcastNotification(TextComponent component);
/**
* Load the platform
*/
void load();
/**
* Unload the platform
*/
void unload();
/**
* Gets a RegionContainer.
*
* @return The region container
*/
RegionContainer getRegionContainer();
/**
* Gets the handler for debug commands.
*
* @return The debug handler
*/
DebugHandler getDebugHandler();
/**
* Gets the servers default game mode.
*
* @return The default game mode
*/
GameMode getDefaultGameMode();
/**
* Gets the configuration directory.
*
* @return The config directory
*/
Path getConfigDir();
/**
* Stack the inventory of the player
*
* @param localPlayer The player
*/
void stackPlayerInventory(LocalPlayer localPlayer);
/**
* Adds reports specific to this platform.
*
* @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;
}
}
@@ -1,47 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
import com.sk89q.worldedit.util.Location;
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>
*
* @deprecated Use {@link com.sk89q.worldguard.protection.association.DelayedRegionOverlapAssociation} instead. This class is mis-packaged.
*/
@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) {
super(query, location, false);
}
}
@@ -1,127 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.association;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldguard.domains.Association;
import com.sk89q.worldguard.protection.FlagValueCalculator;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public abstract class AbstractRegionOverlapAssociation implements RegionAssociable {
@Nullable
protected Set<ProtectedRegion> source;
private boolean useMaxPriorityAssociation;
private int maxPriority;
private Set<ProtectedRegion> maxPriorityRegions;
protected AbstractRegionOverlapAssociation(@Nullable Set<ProtectedRegion> source, boolean useMaxPriorityAssociation) {
this.source = source;
this.useMaxPriorityAssociation = useMaxPriorityAssociation;
}
protected void calcMaxPriority() {
checkNotNull(source);
int best = 0;
Set<ProtectedRegion> bestRegions = new HashSet<>();
for (ProtectedRegion region : source) {
int priority = region.getPriority();
if (priority > best) {
best = priority;
bestRegions.clear();
bestRegions.add(region);
} else if (priority == best) {
bestRegions.add(region);
}
}
this.maxPriority = best;
this.maxPriorityRegions = bestRegions;
}
private boolean checkNonplayerProtectionDomains(Iterable<? extends ProtectedRegion> source, Collection<?> domains) {
if (source == null || domains == null || domains.isEmpty()) {
return false;
}
for (ProtectedRegion region : source) {
// Potential endless recurrence? No, because there is no region group flag.
Set<String> regionDomains = FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, this);
if (regionDomains == null || regionDomains.isEmpty()) {
continue;
}
if (!Collections.disjoint(regionDomains, domains)) {
return true;
}
}
return false;
}
@Override
public Association getAssociation(List<ProtectedRegion> regions) {
checkNotNull(source);
for (ProtectedRegion region : regions) {
while (region != null) {
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty())) {
return Association.OWNER;
}
if (source.contains(region)) {
if (useMaxPriorityAssociation) {
int priority = region.getPriority();
if (priority == maxPriority) {
return Association.OWNER;
}
} else {
return Association.OWNER;
}
}
Set<ProtectedRegion> source;
if (useMaxPriorityAssociation) {
source = maxPriorityRegions;
} else {
source = this.source;
}
// Potential endless recurrence? No, because there is no region group flag.
if (checkNonplayerProtectionDomains(source, FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, this))) {
return Association.OWNER;
}
region = region.getParent();
}
}
return Association.NON_MEMBER;
}
}
@@ -1,62 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes;
import javax.annotation.Nullable;
/**
* Stores an entity type.
* @deprecated replaced by {@link RegistryFlag<EntityType>}, will be removed in WorldGuard 8
*/
@Deprecated
public class EntityTypeFlag extends Flag<EntityType> {
protected EntityTypeFlag(String name, @Nullable RegionGroup defaultGroup) {
super(name, defaultGroup);
}
protected EntityTypeFlag(String name) {
super(name);
}
@Override
public EntityType parseInput(FlagContext context) throws InvalidFlagFormatException {
String input = context.getUserInput();
input = input.trim();
EntityType entityType = unmarshal(input);
if (entityType == null) {
throw new InvalidFlagFormatException("Unknown entity type: " + input);
}
return entityType;
}
@Override
public EntityType unmarshal(@Nullable Object o) {
return EntityTypes.get(String.valueOf(o).toLowerCase());
}
@Override
public Object marshal(EntityType o) {
return o.id();
}
}
@@ -1,99 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.CommandInputContext;
import javax.annotation.Nullable;
import java.util.Map;
public final class FlagContext extends CommandInputContext<InvalidFlagFormatException> {
private FlagContext(Actor sender, String input, Map<String, Object> values) {
super(sender, input, values);
}
public static FlagContext.FlagContextBuilder create() {
return new FlagContextBuilder();
}
/**
* Create a copy of this FlagContext, with optional substitutions for values
*
* <p>If any supplied variable is null, it will be ignored.
* If a map is supplied, it will override this FlagContext's values of the same key,
* but unprovided keys will not be overriden and will be returned as shallow copies.</p>
*
* @param commandSender CommandSender for the new FlagContext to run under
* @param s String of the user input for the new FlagContext
* @param values map of values to override from the current FlagContext
* @return a copy of this FlagContext
*/
public FlagContext copyWith(@Nullable Actor commandSender, @Nullable String s, @Nullable Map<String, Object> values) {
Map<String, Object> map = Maps.newHashMap();
map.putAll(context);
if (values != null) {
map.putAll(values);
}
return new FlagContext(commandSender == null ? this.sender : commandSender, s == null ? this.input : s, map);
}
@Override
protected InvalidFlagFormatException createException(String str) {
return new InvalidFlagFormatException(str);
}
public static class FlagContextBuilder {
private Actor sender;
private String input;
private Map<String, Object> map = Maps.newHashMap();
public FlagContextBuilder setSender(Actor sender) {
this.sender = sender;
return this;
}
public FlagContextBuilder setInput(String input) {
this.input = input;
return this;
}
public FlagContextBuilder setObject(String key, Object value) {
this.map.put(key, value);
return this;
}
public boolean tryAddToMap(String key, Object value) {
if (map.containsKey(key)) return false;
this.map.put(key, value);
return true;
}
public FlagContext build() {
WorldGuard.getInstance().getPlatform().notifyFlagContextCreate(this);
return new FlagContext(sender, input, map);
}
}
}
@@ -1,284 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import com.google.common.collect.Sets;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
import com.sk89q.worldedit.util.formatting.text.serializer.legacy.LegacyComponentSerializer;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
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.
*/
public final class Flags {
private static final List<String> INBUILT_FLAGS_LIST = new ArrayList<>();
public static final List<String> INBUILT_FLAGS = Collections.unmodifiableList(INBUILT_FLAGS_LIST);
// Overrides membership check
public static final StateFlag PASSTHROUGH = register(new StateFlag("passthrough", false));
public static final SetFlag<String> NONPLAYER_PROTECTION_DOMAINS = register(new SetFlag<>("nonplayer-protection-domains", null, new StringFlag(null)));
// This flag is unlike the others. It forces the checking of region membership
public static final StateFlag BUILD = register(new BuildFlag("build", true));
// These flags are used in tandem with the BUILD flag - if the player can
// build, then the following flags do not need to be checked (although they
// are still checked for DENY), so they are false by default
public static final StateFlag BLOCK_BREAK = register(new StateFlag("block-break", false));
public static final StateFlag BLOCK_PLACE = register(new StateFlag("block-place", false));
public static final StateFlag USE = register(new StateFlag("use", false));
public static final StateFlag INTERACT = register(new StateFlag("interact", false));
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));
public static final StateFlag DESTROY_VEHICLE = register(new StateFlag("vehicle-destroy", false));
public static final StateFlag LIGHTER = register(new StateFlag("lighter", false));
public static final StateFlag RIDE = register(new StateFlag("ride", false));
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));
public static final StateFlag USE_ANVIL = register(new StateFlag("use-anvil", false));
public static final StateFlag USE_DRIPLEAF = register(new StateFlag("use-dripleaf", false));
public static final StateFlag WIND_CHARGE_BURST = register(new StateFlag("wind-charge-burst", 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.
// However, it is not possible to disable these flags by default in all
// regions because setting DENY in __global__ would also override the
// BUILD flag. In the future, StateFlags will need a DISALLOW state.
public static final StateFlag ITEM_PICKUP = register(new StateFlag("item-pickup", true)); // Intentionally true
public static final StateFlag ITEM_DROP = register(new StateFlag("item-drop", true)); // Intentionally true
public static final StateFlag EXP_DROPS = register(new StateFlag("exp-drops", true)); // Intentionally true
// These flags adjust behavior and are not checked in tandem with the
// BUILD flag so they need to be TRUE for their defaults.
// mob griefing related
public static final StateFlag MOB_DAMAGE = register(new StateFlag("mob-damage", true));
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 OTHER_EXPLOSION = register(new StateFlag("other-explosion", true));
public static final StateFlag BREEZE_WIND_CHARGE = register(new StateFlag("breeze-charge-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));
// mob spawning related
public static final StateFlag MOB_SPAWNING = register(new StateFlag("mob-spawning", true));
public static final SetFlag<EntityType> DENY_SPAWN = register(new SetFlag<>("deny-spawn", new RegistryFlag<>(null, EntityType.REGISTRY)));
// block dynamics
public static final StateFlag PISTONS = register(new StateFlag("pistons", true));
public static final StateFlag FIRE_SPREAD = register(new StateFlag("fire-spread", true));
public static final StateFlag LAVA_FIRE = register(new StateFlag("lava-fire", true));
public static final StateFlag LIGHTNING = register(new StateFlag("lightning", true));
public static final StateFlag SNOW_FALL = register(new StateFlag("snow-fall", true));
public static final StateFlag SNOW_MELT = register(new StateFlag("snow-melt", true));
public static final StateFlag ICE_FORM = register(new StateFlag("ice-form", true));
public static final StateFlag ICE_MELT = register(new StateFlag("ice-melt", true));
public static final StateFlag FROSTED_ICE_MELT = register(new StateFlag("frosted-ice-melt", true));
public static final StateFlag FROSTED_ICE_FORM = register(new StateFlag("frosted-ice-form", false)); // this belongs in the first category of "checked with build"
public static final StateFlag MUSHROOMS = register(new StateFlag("mushroom-growth", true));
public static final StateFlag LEAF_DECAY = register(new StateFlag("leaf-decay", true));
public static final StateFlag GRASS_SPREAD = register(new StateFlag("grass-growth", true));
public static final StateFlag MYCELIUM_SPREAD = register(new StateFlag("mycelium-spread", true));
public static final StateFlag VINE_GROWTH = register(new StateFlag("vine-growth", true));
public static final StateFlag ROCK_GROWTH = register(new StateFlag("rock-growth", true));
public static final StateFlag SCULK_GROWTH = register (new StateFlag("sculk-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 COPPER_FADE = register(new StateFlag("copper-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));
public static final StateFlag MOISTURE_CHANGE = register(new StateFlag("moisture-change", true));
public static final RegistryFlag<WeatherType> WEATHER_LOCK = register(new RegistryFlag<>("weather-lock", WeatherType.REGISTRY));
public static final StringFlag TIME_LOCK = register(new StringFlag("time-lock"));
// chat related flags
public static final StateFlag SEND_CHAT = register(new StateFlag("send-chat", true));
public static final StateFlag RECEIVE_CHAT = register(new StateFlag("receive-chat", true));
public static final SetFlag<String> BLOCKED_CMDS = register(new SetFlag<>("blocked-cmds", new CommandStringFlag(null)));
public static final SetFlag<String> ALLOWED_CMDS = register(new SetFlag<>("allowed-cmds", new CommandStringFlag(null)));
// locations
public static final LocationFlag TELE_LOC = register(new LocationFlag("teleport"));
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));
public static final StateFlag EXIT = register(new StateFlag("exit", true, RegionGroup.NON_MEMBERS));
public static final BooleanFlag EXIT_OVERRIDE = register(new BooleanFlag("exit-override"));
public static final StateFlag EXIT_VIA_TELEPORT = register(new StateFlag("exit-via-teleport", true));
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"));
public static final BooleanFlag NOTIFY_LEAVE = register(new BooleanFlag("notify-leave"));
public static final RegistryFlag<GameMode> GAME_MODE = register(new RegistryFlag<>("game-mode", GameMode.REGISTRY));
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 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)))
.append(TextComponent.of(" You are not permitted to leave this area.", TextColor.GRAY)))));
private Flags() {
}
private static <T extends Flag<?>> T register(final T flag) throws FlagConflictException {
WorldGuard.getInstance().getFlagRegistry().register(flag);
INBUILT_FLAGS_LIST.add(flag.getName());
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.
*
* @param flagRegistry the flag registry
* @param id the flag ID
* @return a flag, or null
*/
public static Flag<?> fuzzyMatchFlag(FlagRegistry flagRegistry, String id) {
final String compId = id.replace("-", "");
for (Flag<?> flag : flagRegistry) {
if (flag.getName().replace("-", "").equalsIgnoreCase(compId)) {
return flag;
}
}
return null;
}
/**
* Dummy method to call that initialises the class.
*/
public static void registerAll() {
}
}
@@ -1,62 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import javax.annotation.Nullable;
/**
* Stores an gamemode type.
* @deprecated replaced by {@link RegistryFlag<GameMode>}, will be removed in WorldGuard 8
*/
@Deprecated
public class GameModeTypeFlag extends Flag<GameMode> {
protected GameModeTypeFlag(String name, @Nullable RegionGroup defaultGroup) {
super(name, defaultGroup);
}
protected GameModeTypeFlag(String name) {
super(name);
}
@Override
public GameMode parseInput(FlagContext context) throws InvalidFlagFormatException {
String input = context.getUserInput();
input = input.trim();
GameMode gamemode = unmarshal(input);
if (gamemode == null) {
throw new InvalidFlagFormatException("Unknown game mode: " + input);
}
return gamemode;
}
@Override
public GameMode unmarshal(@Nullable Object o) {
return GameModes.get(String.valueOf(o).toLowerCase());
}
@Override
public Object marshal(GameMode o) {
return o.id();
}
}
@@ -1,101 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.NullWorld;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.WorldGuard;
import javax.annotation.Nullable;
import java.util.Optional;
/**
* A location that stores the name of the world in case the world is unloaded.
*/
class LazyLocation extends Location {
private final String worldName;
@Nullable
private static World findWorld(String worldName) {
return WorldGuard.getInstance().getPlatform().getMatcher().getWorldByName(worldName);
}
LazyLocation(String worldName, Vector3 position, float yaw, float pitch) {
super(Optional.ofNullable(findWorld(worldName)).orElse(NullWorld.getInstance()), position, yaw, pitch);
this.worldName = worldName;
}
LazyLocation(String worldName, Vector3 position) {
super(Optional.ofNullable(findWorld(worldName)).orElse(NullWorld.getInstance()), position);
this.worldName = worldName;
}
@Override
public Extent getExtent() {
if (super.getExtent() != NullWorld.getInstance()) {
return super.getExtent();
}
// try loading the world again now
// if it fails it will throw an error later (presumably when trying to teleport someone there)
return Optional.ofNullable(findWorld(getWorldName())).orElse(new NullWorld() {
@Override
public String getName() {
return worldName;
}
});
}
public String getWorldName() {
return worldName;
}
public LazyLocation setAngles(float yaw, float pitch) {
return new LazyLocation(worldName, toVector(), yaw, pitch);
}
@Override
public LazyLocation setPosition(Vector3 position) {
return new LazyLocation(worldName, position, getYaw(), getPitch());
}
public LazyLocation add(Vector3 other) {
return this.setPosition(toVector().add(other));
}
public LazyLocation add(double x, double y, double z) {
return this.setPosition(toVector().add(x, y, z));
}
@Override
public String toString() {
if (getPitch() == 0 && getYaw() == 0) {
return String.join(", ", worldName,
String.valueOf((int) getX()), String.valueOf((int) getY()), String.valueOf((int) getZ()));
} else {
return String.join(", ", worldName,
String.valueOf((int) getX()), String.valueOf((int) getY()), String.valueOf((int) getZ()),
String.valueOf((int) getPitch()), String.valueOf((int) getYaw()));
}
}
}
@@ -1,129 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import com.google.common.collect.Maps;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.Map.Entry;
import static java.util.Objects.requireNonNull;
/**
* Stores a key value map of typed {@link Flag}s.
*/
public class MapFlag<K, V> extends Flag<Map<K, V>> {
private final Flag<K> keyFlag;
private final Flag<V> valueFlag;
public MapFlag(final String name, final Flag<K> keyFlag, final Flag<V> valueFlag) {
super(name);
requireNonNull(keyFlag, "keyFlag cannot be null.");
requireNonNull(valueFlag, "valueFlag cannot be null.");
this.keyFlag = keyFlag;
this.valueFlag = valueFlag;
}
public MapFlag(final String name, @Nullable final RegionGroup defaultGroup, final Flag<K> keyFlag, final Flag<V> valueFlag) {
super(name, defaultGroup);
requireNonNull(keyFlag, "keyFlag cannot be null.");
requireNonNull(valueFlag, "valueFlag cannot be null.");
this.keyFlag = keyFlag;
this.valueFlag = valueFlag;
}
/**
* Get the flag that is stored as the key flag type.
*
* @return The key flag type.
*/
public Flag<K> getKeyFlag() {
return this.keyFlag;
}
/**
* Get the flag type that is stored as values.
*
* @return The value flag type.
*/
public Flag<V> getValueFlag() {
return this.valueFlag;
}
@Override
public Map<K, V> parseInput(final FlagContext context) throws InvalidFlagFormatException {
final String input = context.getUserInput();
if (input.isEmpty()) {
return Maps.newHashMap();
}
final Map<K, V> items = Maps.newHashMap();
for (final String str : input.split(",")) {
final char split = str.indexOf('=') == -1 ? ':' : '=';
final String[] keyVal = str.split(String.valueOf(split));
if (keyVal.length != 2) {
throw new InvalidFlagFormatException("Input must be in a 'key:value,key1=value1' format. Either ':' or '=' can be used.");
}
final FlagContext key = context.copyWith(null, keyVal[0], null);
final FlagContext value = context.copyWith(null, keyVal[1], null);
items.put(this.keyFlag.parseInput(key), this.valueFlag.parseInput(value));
}
return items;
}
@Override
public Map<K, V> unmarshal(@Nullable final Object o) {
if (o instanceof Map<?, ?>) {
final Map<?, ?> map = (Map<?, ?>) o;
final Map<K, V> items = Maps.newHashMap();
for (final Entry<?, ?> entry : map.entrySet()) {
final K keyItem = this.keyFlag.unmarshal(entry.getKey());
final V valueItem = this.valueFlag.unmarshal(entry.getValue());
if (keyItem != null && valueItem != null) {
items.put(keyItem, valueItem);
}
}
return items;
}
return null;
}
@Override
public Object marshal(final Map<K, V> o) {
final Map<Object, Object> map = Maps.newHashMap();
for (final Entry<K, V> entry : o.entrySet()) {
map.put(this.keyFlag.marshal(entry.getKey()), this.valueFlag.marshal(entry.getValue()));
}
return map;
}
}
Loaded 100 of 466 files, more files were not shown because too many files have changed in this diff. Show more