Compare commits

...
30 Commits
Author SHA1 Message Date
wizjany 79a3b70d8d Release 7.0.7. 2022-03-03 14:21:45 -05:00
wizjany cf69425153 Don't cancel potion splashes with no targets. 2022-03-03 07:59:00 -05:00
wizjany e2fe770e6f Disregard that, definitely need to duplicate. 2022-03-01 18:27:45 -05:00
wizjany 7e06088c1a Switch to WE's ClassSourceValidator.
Since it's (being) fixed there and no need to duplicate any more.
2022-02-27 19:25:58 -05:00
wizjany f9d1c2d4e0 Fix some errors in config loading.
Technically removing a nonexistant property should be fixed in WE's yaml utils but eh.
2022-02-27 17:51:52 -05:00
wizjany f883899cfe Add deprecation warnings.
Also remove the nodes from config if unused.
2022-02-27 16:34:27 -05:00
wizjany de386fb4d8 Provisional changelog for 7.0.7. 2022-02-26 19:04:13 -05:00
wizjany 660f9ffa0d Use deny-message for nether portal protection.
Closes #1882.
2022-02-26 18:49:35 -05:00
wizjany e05d42371f Protect modification of candles and cake as building.
Closes #1880.
2022-02-26 18:43:04 -05:00
JOO200 dca0515104 Optimize Region List and Region Teleport commands (#1868)
* Optimized command usage for /rg list and /rg teleport:
* added a flag to the teleport command to teleport the actor to the center of the region
* added a flag to the list command to filter the regions for special ids
* added a flag to the list command to get regions intersecting your selection

* Fixed wrong pagination in RegionLister
2022-01-23 13:03:40 -05:00
wizjany 4abf971cf6 Add red sand to sand physics.
This option is still at the mercy of bukkit api and might still not work ¯\_(ツ)_/¯
2022-01-16 11:13:18 -05:00
wizjany 875a6fc827 Add space in an error message. 2022-01-16 11:13:15 -05:00
JOO200 3cb4abdbf7 Updated amount of modules, Windows command prompt and outdated hints 2022-01-08 21:23:11 +01:00
JOO200 4caf0afb38 Add COMPILING.md and set Java Version to 16 2022-01-08 21:03:11 +01:00
JOO200 054a73416b Update Java-Version in README.md to Java 17 2022-01-07 13:17:54 +01:00
Cristobal Lopez b59da5992f Allows claimed regions to inherit from a template region (#1864)
* Allows claimed regions to inherit from a template region

* Replace template-when-claiming with set-parent-on-claim

* Make the set-parent-on-claim option check secure
2022-01-02 10:07:00 -05:00
wizjany 46251f5ffa Don't check bypass for offline players.
This is someone else's problem now (╯°□°)╯︵ ┻━┻
2022-01-01 20:08:16 -05:00
wizjany 98bef4e0ab Remove extra import. 2021-12-31 10:55:51 -05:00
JOO200 f1c8649f9a Improve Checks for LightningStrikes (fixes #1845) 2021-12-31 10:55:51 -05:00
JOO200 aad698af84 Update Paper and Spigot to 1.17.1 2021-12-31 10:55:51 -05:00
JOO200 ad7ecbaefe Exclude paper-api from squirrelid dependency (Compilefix for removed maven mirrors) 2021-12-30 20:41:57 +01:00
wizjany 81750e191d Add /rg migrateheights. (#1857)
Closes #1856.
2021-12-02 15:44:25 -05:00
wizjany 703146bc18 Update guava to match MC 1.18 guava. 2021-11-30 20:42:54 -05:00
JOO200 2541483ebc Fixed invalid label 2021-11-25 22:00:40 +01:00
JOO200 0a601dbc28 Improved Bug Report and Feature Request Template 2021-11-25 21:59:46 +01:00
stonar96 f55802c176 Make cause known if origin can be used (#1838) 2021-11-25 12:33:43 -05:00
wizjany a0922cb467 Add rock-growth flag.
Handles amethyst and dripstone.

Closes #1855.
2021-11-25 12:32:24 -05:00
wizjany fb9705e4f0 Update gradle.
Getting ready for java 17.
2021-11-25 11:27:00 -05:00
JOO200 9b665136d0 Fix Blacklist log entry not by player results in NPE (#1837) 2021-09-25 13:22:33 +02:00
wizjany efac79fd38 Bump to 7.0.7-SNAPSHOT. 2021-09-16 18:51:54 -04:00
39 changed files with 971 additions and 410 deletions

No files matched your search

-34
View File
@@ -1,34 +0,0 @@
---
name: Bug report
about: Report a way in which WorldGuard is not working as intended
title: ''
labels: type:bug, status:pending
assignees: ''
---
**Versions**
<!-- Please include the full version of WorldEdit, WorldGuard and the platform (Bukkit/Spigot/Paper) you are running, e.g. output from `/we version`, `/wg version` `/version` commands. Please ensure you are running up to date software before making a bug report. Old versions will receive little to no support. -->
WorldEdit version:
WorldGuard version:
Platform version:
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**To Reproduce**
<!-- Steps to reproduce the behavior: -->
1. ...
2. ...
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. Screenshots of `/rg info` for any applicable regions (or simply the link from `/wg report -p`) are good to include. -->
**Additional context**
<!-- Add any other context about the problem here. -->
+93
View File
@@ -0,0 +1,93 @@
name: Bug report
description: Report a way in which WorldGuard is not working as intended
labels: ['type:bug', 'status:pending']
body:
- type: markdown
attributes:
value: |
Please note that this is only for bugs, help with installation or other types of support should
be taken to the Discord Guild instead.
- type: input
attributes:
label: WorldEdit Version
description: The full version of WorldEdit, can be found by using `/we version`.
placeholder: e.g. 7.2.3 or 7.3.0-SNAPSHOT
validations:
required: true
- type: input
attributes:
label: WorldGuard Version
description: The full version of WorldGuard, can be found by using `/wg version`.
placeholder: e.g. 7.0.5 or 7.0.6-SNAPSHOT
validations:
required: true
- type: input
attributes:
label: Platform Version
description: |
The version of the platform you are on, i.e. Spigot or Paper.
Please ensure you are running up-to-date software before making a bug report.
Old versions, paper forks or hybrids will receive little to no support.
placeholder: e.g. git-Spigot-21fe707-e1ebe52, git-Paper-463
validations:
required: true
- type: checkboxes
id: confirmations
attributes:
label: Confirmations
description: Please confirm the following before submitting the bug. Your report will be closed if you are running hybrids or old software.
options:
- label: I am using the most recent Minecraft release.
required: true
- label: I am using a version of WorldEdit compatible with my Minecraft version.
required: true
- label: I am using a version of WorldGuard compatible with my Minecraft version.
required: true
- label: I am using the latest or recommended version of my platform software.
required: true
- label: I am NOT using a hybrid server, e.g. a server that combines Bukkit and Forge. Examples include Arclight, Mohist, and Cardboard.
required: true
- label: I am NOT using a fork of WorldEdit, such as FastAsyncWorldEdit (FAWE) or AsyncWorldEdit (AWE)
required: true
- type: textarea
attributes:
label: Bug Description
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: The behavior that you expected, instead of the bugged behavior that occurs.
validations:
required: true
- type: textarea
attributes:
label: Reproduction Steps
description: Steps to reproduce the behavior.
value: |
1. ...
2. ...
validations:
required: true
- type: input
attributes:
label: Optional WorldGuard-Report
description: Link to WorldGuard Region report for bugs with regions, received with `/wg report -p`
validations:
required: false
- type: textarea
attributes:
label: Anything Else?
description: Add any additional context you can provide below.
-20
View File
@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for WorldGuard
title: ''
labels: type:feature-request, status:pending
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
@@ -0,0 +1,35 @@
name: Feature request
description: Suggest an idea for WorldGuard
labels: ['type:feature-request', 'status:pending']
body:
- type: textarea
attributes:
label: The Problem
description: >
What is making your WorldGuard experience sub-optimal? This should be something that
cannot be easily solved by existing WorldGuard features.
placeholder: It's hard to ... ; I'm unable to ...
validations:
required: true
- type: textarea
attributes:
label: A Solution
description: What is your proposed solution to the above problem?
validations:
required: true
- type: textarea
attributes:
label: Alternatives
description: |
Alternative solutions or workarounds to the problem.
You should also describe why these are not preferable to the given solution.
validations:
required: false
- type: textarea
attributes:
label: Anything Else?
description: Add any additional context you can provide below.
+12
View File
@@ -1,5 +1,17 @@
# Changelog
## 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.
+42
View File
@@ -0,0 +1,42 @@
Compiling
=========
You can compile WorldGuard as long as you have some version of Java greater than or equal to 16 installed. Gradle will download JDK 16 specifically if needed,
but it needs some version of Java to bootstrap from.
Note that if you have JRE 16 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 16 and
replace it with JDK 16.
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.
+1 -3
View File
@@ -7,9 +7,7 @@ ask that you make note of the following guidelines.
* **Follow the [Oracle coding conventions](https://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).**
We can't stress this enough; if your code has notable issues, it may delay
the process significantly.
* **Target Java 8 for source and compilation.** Make sure to mark methods with
` @Override` that override methods of parent classes, or that implement
methods of interfaces.
* **Target Java 16 for source and compilation.**
* **Use only spaces for indentation.** Our indents are 4-spaces long, and tabs
are unacceptable.
* **Wrap code to a 89 column limit.** We do this to make side by side diffs
+1 -1
View File
@@ -23,7 +23,7 @@ A Bukkit server implementation (such as [Paper](https://papermc.io)) and the [Wo
Compiling
---------
The project is written for Java 8 and our build process makes use of
The project is written for Java 16 and our build process makes use of
[Gradle](http://gradle.org).
Dependencies are automatically handled by Gradle.
+1 -1
View File
@@ -10,7 +10,7 @@ repositories {
dependencies {
implementation(gradleApi())
implementation("gradle.plugin.org.cadixdev.gradle:licenser:0.6.0")
implementation("gradle.plugin.org.cadixdev.gradle:licenser:0.6.1")
implementation("org.ajoberstar.grgit:grgit-gradle:4.1.0")
implementation("com.github.jengelman.gradle.plugins:shadow:6.1.0")
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.21.0")
+2 -2
View File
@@ -1,9 +1,9 @@
object Versions {
// const val PISTON = "0.4.3"
// const val AUTO_VALUE = "1.6.5"
const val WORLDEDIT = "7.2.6-SNAPSHOT"
const val WORLDEDIT = "7.2.7"
const val JUNIT = "5.7.0"
const val SQUIRRELID = "0.3.0"
const val GUAVA = "21.0"
const val GUAVA = "31.0.1-jre"
const val MOCKITO = "3.7.7"
}
+1 -1
View File
@@ -1,2 +1,2 @@
group=com.sk89q.worldguard
version=7.0.6
version=7.0.7
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+158 -112
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# 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.
@@ -17,78 +17,113 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
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
@@ -105,84 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# 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" "$@"
Vendored
+7 -18
View File
@@ -29,6 +29,9 @@ 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"
@@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -51,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -61,28 +64,14 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
+3 -3
View File
@@ -28,14 +28,14 @@ configurations {
dependencies {
"api"(project(":worldguard-core"))
"compileOnly"("io.papermc.paper:paper-api:1.17-R0.1-SNAPSHOT")
"runtimeOnly"("org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT") {
"compileOnly"("io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT")
"runtimeOnly"("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT") {
exclude("junit", "junit")
}
"api"("com.sk89q.worldedit:worldedit-bukkit:${Versions.WORLDEDIT}") { isTransitive = false }
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
"compileOnly"("com.sk89q:commandbook:2.3") { isTransitive = false }
"shadeOnly"("io.papermc:paperlib:1.0.6")
"shadeOnly"("io.papermc:paperlib:1.0.7")
"shadeOnly"("org.bstats:bstats-bukkit:2.1.0")
"shadeOnly"("co.aikar:minecraft-timings:1.0.4")
}
@@ -140,6 +140,8 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
throw e;
}
boolean needParentSave = false;
summaryOnStart = getBoolean("summary-on-start", true);
opPermissions = getBoolean("op-permissions", true);
@@ -158,7 +160,8 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
itemDurability = getBoolean("protection.item-durability", true);
removeInfiniteStacks = getBoolean("protection.remove-infinite-stacks", false);
disableExpDrops = getBoolean("protection.disable-xp-orb-drops", false);
disableObsidianGenerators = getBoolean("protection.disable-obsidian-generators", false);
needParentSave |= removeProperty("protection.disable-obsidian-generators");
useMaxPriorityAssociation = getBoolean("protection.use-max-priority-association", false);
@@ -178,6 +181,11 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
simulateSponge = getBoolean("simulation.sponge.enable", false);
spongeRadius = Math.max(1, getInt("simulation.sponge.radius", 3)) - 1;
redstoneSponges = getBoolean("simulation.sponge.redstone", false);
if (simulateSponge) {
log.warning("Sponge simulation is deprecated for removal in a future version. We recommend using CraftBook's sponge simulation instead.");
} else {
needParentSave |= removeProperty("simulation");
}
pumpkinScuba = getBoolean("default.pumpkin-scuba", false);
disableHealthRegain = getBoolean("default.disable-health-regain", false);
@@ -237,6 +245,11 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
signChestProtection = getBoolean("chest-protection.enable", false);
disableSignChestProtectionCheck = getBoolean("chest-protection.disable-off-check", false);
if (signChestProtection) {
log.warning("Sign-based chest protection is deprecated for removal in a future version. See https://worldguard.enginehub.org/en/latest/chest-protection/ for details.");
} else {
needParentSave |= removeProperty("chest-protection");
}
disableCreatureCropTrampling = getBoolean("crops.disable-creature-trampling", false);
disablePlayerCropTrampling = getBoolean("crops.disable-player-trampling", false);
@@ -263,6 +276,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
disableGrassGrowth = getBoolean("dynamics.disable-grass-growth", false);
disableMyceliumSpread = getBoolean("dynamics.disable-mycelium-spread", false);
disableVineGrowth = getBoolean("dynamics.disable-vine-growth", false);
disableRockGrowth = getBoolean("dynamics.disable-rock-growth", false);
disableCropGrowth = getBoolean("dynamics.disable-crop-growth", false);
disableSoilDehydration = getBoolean("dynamics.disable-soil-dehydration", false);
disableCoralBlockFade = getBoolean("dynamics.disable-coral-block-fade", false);
@@ -280,6 +294,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
regionWand = convertLegacyItem(getString("regions.wand", ItemTypes.LEATHER.getId()));
maxClaimVolume = getInt("regions.max-claim-volume", 30000);
claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false);
setParentOnClaim = getString("regions.set-parent-on-claim", "");
boundedLocationFlags = getBoolean("regions.location-flags-only-inside-regions", false);
maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7);
@@ -401,6 +416,20 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
config.setHeader(CONFIG_HEADER);
config.save();
if (needParentSave) {
parentConfig.save();
}
}
private boolean removeProperty(String prop) {
if (config.getProperty(prop) != null) {
config.removeProperty(prop);
}
if (parentConfig.getProperty(prop) != null) {
parentConfig.removeProperty(prop);
return true;
}
return false;
}
public boolean isChestProtected(Location block, LocalPlayer player) {
@@ -59,8 +59,8 @@ 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.Events;
import com.sk89q.worldguard.bukkit.util.logging.ClassSourceValidator;
import com.sk89q.worldguard.commands.GeneralCommands;
import com.sk89q.worldguard.commands.ProtectionCommands;
import com.sk89q.worldguard.commands.ToggleCommands;
@@ -71,7 +71,6 @@ import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
import com.sk89q.worldguard.protection.managers.storage.file.DirectoryYamlDriver;
import com.sk89q.worldguard.protection.managers.storage.sql.SQLDriver;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.util.logging.RecordMessagePrefixer;
import org.bstats.bukkit.Metrics;
@@ -137,6 +136,10 @@ public class WorldGuardPlugin extends JavaPlugin {
*/
@Override
public void onEnable() {
// Catch bad things being done by naughty plugins that include WorldGuard's classes
ClassSourceValidator verifier = new ClassSourceValidator(this);
verifier.reportMismatches(ImmutableList.of(WorldGuard.class, ProtectedRegion.class, Flag.class));
configureLogger();
getDataFolder().mkdirs(); // Need to create the plugins/WorldGuard folder
@@ -150,11 +153,6 @@ public class WorldGuardPlugin extends JavaPlugin {
// Set the proper command injector
commands.setInjector(new SimpleInjector(WorldGuard.getInstance()));
// Catch bad things being done by naughty plugins that include
// WorldGuard's classes
ClassSourceValidator verifier = new ClassSourceValidator(this);
verifier.reportMismatches(ImmutableList.of(ProtectedRegion.class, ProtectedCuboidRegion.class, Flag.class));
// Register command classes
final CommandsManagerRegistration reg = new CommandsManagerRegistration(this, commands);
reg.register(ToggleCommands.class);
@@ -21,6 +21,8 @@ package com.sk89q.worldguard.bukkit.cause;
import com.google.common.base.Joiner;
import com.google.common.collect.Sets;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.internal.WGMetadata;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
@@ -30,6 +32,7 @@ import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework;
import org.bukkit.entity.LightningStrike;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
@@ -98,7 +101,25 @@ public final class Cause {
*/
public boolean isKnown() {
Object object = getRootCause();
return !(object == null || object instanceof TNTPrimed || object instanceof Vehicle);
if (object == null) {
return false;
}
if (object instanceof TNTPrimed || object instanceof Vehicle) {
if (!PaperLib.isPaper()) {
return false;
}
Entity entity = (Entity) object;
BukkitWorldConfiguration config = WorldGuardPlugin.inst().getConfigManager().get(entity.getWorld().getName());
if (!config.usePaperEntityOrigin || entity.getOrigin() == null) {
return false;
}
}
return true;
}
@Nullable
@@ -249,56 +270,61 @@ public final class Cause {
}
private void addAll(@Nullable Object... element) {
if (element != null) {
for (Object o : element) {
if (o == null || seen.contains(o)) {
continue;
}
if (element == null) {
return;
}
for (Object o : element) {
if (o == null || seen.contains(o)) {
continue;
}
seen.add(o);
seen.add(o);
if (o instanceof TNTPrimed) {
addAll(((TNTPrimed) o).getSource());
} else if (o instanceof Projectile) {
ProjectileSource shooter = ((Projectile) o).getShooter();
addAll(shooter);
if (shooter == null && o instanceof Firework && PaperLib.isPaper()) {
UUID spawningUUID = ((Firework) o).getSpawningEntity();
if (spawningUUID != null) {
Entity spawningEntity = Bukkit.getEntity(spawningUUID);
if (spawningEntity != null) {
addAll(spawningEntity);
}
if (o instanceof TNTPrimed) {
addAll(((TNTPrimed) o).getSource());
} else if (o instanceof Projectile) {
ProjectileSource shooter = ((Projectile) o).getShooter();
addAll(shooter);
if (shooter == null && o instanceof Firework && PaperLib.isPaper()) {
UUID spawningUUID = ((Firework) o).getSpawningEntity();
if (spawningUUID != null) {
Entity spawningEntity = Bukkit.getEntity(spawningUUID);
if (spawningEntity != null) {
addAll(spawningEntity);
}
}
} else if (o instanceof Vehicle) {
((Vehicle) o).getPassengers().forEach(this::addAll);
} else if (o instanceof AreaEffectCloud) {
indirect = true;
addAll(((AreaEffectCloud) o).getSource());
} else if (o instanceof Tameable) {
indirect = true;
addAll(((Tameable) o).getOwner());
} else if (o instanceof Creature && ((Creature) o).getTarget() != null) {
indirect = true;
addAll(((Creature) o).getTarget());
} else if (o instanceof BlockProjectileSource) {
addAll(((BlockProjectileSource) o).getBlock());
}
// Add manually tracked parent causes
Object source = o;
int index = causes.size();
while (source instanceof Metadatable && !(source instanceof Block)) {
source = WGMetadata.getIfPresent((Metadatable) source, CAUSE_KEY, Object.class);
if (source != null) {
causes.add(index, source);
seen.add(source);
}
}
causes.add(o);
} else if (o instanceof Vehicle) {
((Vehicle) o).getPassengers().forEach(this::addAll);
} else if (o instanceof AreaEffectCloud) {
indirect = true;
addAll(((AreaEffectCloud) o).getSource());
} else if (o instanceof Tameable) {
indirect = true;
addAll(((Tameable) o).getOwner());
} else if (o instanceof Creature && ((Creature) o).getTarget() != null) {
indirect = true;
addAll(((Creature) o).getTarget());
} else if (o instanceof BlockProjectileSource) {
addAll(((BlockProjectileSource) o).getBlock());
} else if (o instanceof LightningStrike && PaperLib.isPaper() &&
((LightningStrike) o).getCausingEntity() != null) {
indirect = true;
addAll(((LightningStrike) o).getCausingEntity());
}
// Add manually tracked parent causes
Object source = o;
int index = causes.size();
while (source instanceof Metadatable && !(source instanceof Block)) {
source = WGMetadata.getIfPresent((Metadatable) source, CAUSE_KEY, Object.class);
if (source != null) {
causes.add(index, source);
seen.add(source);
}
}
causes.add(o);
}
}
@@ -21,6 +21,7 @@ package com.sk89q.worldguard.bukkit.listener;
import static com.sk89q.worldguard.bukkit.cause.Cause.create;
import com.destroystokyo.paper.event.entity.EntityZapEvent;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
@@ -47,6 +48,7 @@ import com.sk89q.worldguard.bukkit.util.Events;
import com.sk89q.worldguard.bukkit.util.Materials;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.protection.flags.Flags;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
@@ -83,6 +85,7 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
@@ -142,6 +145,7 @@ import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.projectiles.ProjectileSource;
@@ -181,6 +185,17 @@ public class EventAbstractionListener extends AbstractListener {
super(plugin);
}
@Override
public void registerEvents() {
super.registerEvents();
if (PaperLib.isPaper()) {
PluginManager pm = getPlugin().getServer().getPluginManager();
pm.registerEvents(new EventAbstractionListener.PaperListener(), getPlugin());
}
}
//-------------------------------------------------------------------------
// Block break / place
//-------------------------------------------------------------------------
@@ -1032,7 +1047,7 @@ public class EventAbstractionListener extends AbstractListener {
}
}
if (blocked == affectedSize) { // server does weird things with this if the event is modified, so use cached number
if (affectedSize > 0 && blocked == affectedSize) { // server does weird things with this if the event is modified, so use cached number
event.setCancelled(true);
}
}
@@ -1264,4 +1279,10 @@ public class EventAbstractionListener extends AbstractListener {
}
}
private class PaperListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onEntityTransform(EntityZapEvent event) {
Events.fireToCancel(event, new DamageEntityEvent(event, create(event.getBolt()), event.getEntity()));
}
}
}
@@ -365,7 +365,7 @@ public class WorldGuardBlockListener extends AbstractListener {
return;
}
if (id == Material.SAND && wcfg.noPhysicsSand) {
if ((id == Material.SAND || id == Material.RED_SAND) && wcfg.noPhysicsSand) {
event.setCancelled(true);
return;
}
@@ -588,6 +588,19 @@ public class WorldGuardBlockListener extends AbstractListener {
}
}
if (newType == Material.BUDDING_AMETHYST || 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;
}
}
handleGrow(event, event.getBlock().getLocation(), newType);
}
@@ -684,7 +684,8 @@ public class WorldGuardEntityListener extends AbstractListener {
if (associable != null) {
// NB there is no way to cancel the teleport without PTA (since PlayerPortal doesn't have block info)
// removing PTA was a mistake
associable.print("Destination is an a protected area.");
String message = regions.queryValue(associable, Flags.DENY_MESSAGE);
RegionProtectionListener.formatAndSendDenyMessage("create portals", associable, message);
}
event.setCancelled(true);
}
@@ -788,7 +789,7 @@ public class WorldGuardEntityListener extends AbstractListener {
return;
}
if (id == Material.SAND && wcfg.noPhysicsSand) {
if ((id == Material.SAND || id == Material.RED_SAND) && wcfg.noPhysicsSand) {
event.setCancelled(true);
return;
}
@@ -83,8 +83,12 @@ public class BukkitSessionManager extends AbstractSessionManager implements Runn
public boolean hasBypass(LocalPlayer player, World world) {
if (player instanceof BukkitPlayer) {
if (((BukkitPlayer) player).getPlayer().hasMetadata("NPC")
&& WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).fakePlayerBuildOverride)
&& WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).fakePlayerBuildOverride) {
return true;
}
if (!((BukkitPlayer) player).getPlayer().isOnline()) {
return false;
}
}
return super.hasBypass(player, world);
}
@@ -0,0 +1,164 @@
/*
* 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;
static {
Method tmp;
try {
tmp = PluginClassLoader.class.getDeclaredMethod("loadClass0",
String.class, boolean.class, boolean.class, boolean.class);
tmp.setAccessible(true);
} catch (NoSuchMethodException 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 (!(targetLoader instanceof PluginClassLoader)) {
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());
}
}
@@ -1491,7 +1491,10 @@ public final class Materials {
public static boolean isConsideredBuildingIfUsed(Material type) {
return type == Material.REPEATER
|| type == Material.COMPARATOR
|| Tag.FLOWER_POTS.isTagged(type);
|| type == Material.CAKE
|| Tag.FLOWER_POTS.isTagged(type)
|| Tag.CANDLES.isTagged(type)
|| Tag.CANDLE_CAKES.isTagged(type);
}
/**
@@ -1,127 +0,0 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.util.logging;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import org.bukkit.plugin.Plugin;
import javax.annotation.Nullable;
import java.security.CodeSource;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Validates that certain specified classes came from the same source as
* a plugin.
*/
public class ClassSourceValidator {
private static final Logger log = Logger.getLogger(ClassSourceValidator.class.getCanonicalName());
private static final String separatorLine = Strings.repeat("*", 46);
private final Plugin plugin;
@Nullable
private final CodeSource expectedCodeSource;
/**
* Create a new instance.
*
* @param plugin The plugin
*/
public ClassSourceValidator(Plugin plugin) {
checkNotNull(plugin, "plugin");
this.plugin = plugin;
this.expectedCodeSource = plugin.getClass().getProtectionDomain().getCodeSource();
}
/**
* Return a map of classes that been loaded from a different source.
*
* @param classes A list of classes to check
* @return The results
*/
public Map<Class<?>, CodeSource> findMismatches(List<Class<?>> classes) {
checkNotNull(classes, "classes");
Map<Class<?>, CodeSource> mismatches = Maps.newHashMap();
if (expectedCodeSource != null) {
for (Class<?> testClass : classes) {
CodeSource testSource = testClass.getProtectionDomain().getCodeSource();
if (!expectedCodeSource.equals(testSource)) {
mismatches.put(testClass, testSource);
}
}
}
return mismatches;
}
/**
* Reports classes that have come from a different source.
*
* <p>The warning is emitted to the log.</p>
*
* @param classes The list of classes to check
*/
public void reportMismatches(List<Class<?>> classes) {
if (Boolean.getBoolean("worldguard.disable.class.validation")) {
return;
}
Map<Class<?>, CodeSource> mismatches = findMismatches(classes);
if (!mismatches.isEmpty()) {
StringBuilder builder = new StringBuilder("\n");
builder.append(separatorLine).append("\n");
builder.append("** /!\\ SEVERE WARNING /!\\\n");
builder.append("** \n");
builder.append("** A plugin developer has copied and pasted a portion of \n");
builder.append("** ").append(plugin.getName()).append(" into their own plugin, so rather than using\n");
builder.append("** the version of ").append(plugin.getName()).append(" that you downloaded, you\n");
builder.append("** will be using a broken mix of old ").append(plugin.getName()).append(" (that came\n");
builder.append("** with the plugin) and your downloaded version. THIS MAY\n");
builder.append("** SEVERELY BREAK ").append(plugin.getName().toUpperCase()).append(" AND ALL OF ITS FEATURES.\n");
builder.append("**\n");
builder.append("** This may have happened because the developer is using\n");
builder.append("** the ").append(plugin.getName()).append(" API and thinks that including\n");
builder.append("** ").append(plugin.getName()).append(" is necessary. However, it is not!\n");
builder.append("**\n");
builder.append("** Here are some files that have been overridden:\n");
builder.append("** \n");
for (Map.Entry<Class<?>, CodeSource> entry : mismatches.entrySet()) {
CodeSource codeSource = entry.getValue();
String url = codeSource != null ? codeSource.getLocation().toExternalForm() : "(unknown)";
builder.append("** '").append(entry.getKey().getSimpleName()).append("' came from '").append(url).append("'\n");
}
builder.append("**\n");
builder.append("** Please report this to the plugins' developers.\n");
builder.append(separatorLine).append("\n");
log.log(Level.SEVERE, builder.toString());
}
}
}
@@ -24,6 +24,7 @@ import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.event.BlacklistEvent;
import com.sk89q.worldguard.blacklist.target.Target;
import javax.annotation.Nullable;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
@@ -87,13 +88,13 @@ public class FileHandler implements LoggerHandler {
* Build the path.
*
* @param playerName The name of the player
* @return The path for the logfile
* @return The path for the logfile, null when no applicable path could be found
*/
private String buildPath(String playerName) {
private @Nullable String buildPath(@Nullable String playerName) {
GregorianCalendar calendar = new GregorianCalendar();
Matcher m = pattern.matcher(pathPattern);
StringBuffer buffer = new StringBuffer();
StringBuilder buffer = new StringBuilder();
// Pattern replacements
while (m.find()) {
@@ -103,12 +104,13 @@ public class FileHandler implements LoggerHandler {
if (group.matches("%%")) {
rep = "%";
} else if (group.matches("%u")) {
if (playerName == null) return null; // Unable to create a path for non player logging events
rep = playerName.toLowerCase().replaceAll("[^A-Za-z0-9_]", "_");
if (rep.length() > 32) { // Actual max length is 16
rep = rep.substring(0, 32);
}
}else if (group.matches("%w")) {
} else if (group.matches("%w")) {
rep = worldName.toLowerCase().replaceAll("[^A-Za-z0-9_]", "_");
if (rep.length() > 32) { // Actual max length is 16
rep = rep.substring(0, 32);
@@ -148,11 +150,12 @@ public class FileHandler implements LoggerHandler {
* @param message The message to log
* @param comment The comment associated with the logged event
*/
private void log(LocalPlayer player, String message, String comment) {
String path = buildPath(player.getName());
private void log(@Nullable LocalPlayer player, String message, String comment) {
String path = buildPath(player != null ? player.getName() : null);
if (path == null) return;
try {
String date = dateFormat.format(new Date());
String line = "[" + date + "] " + player.getName() + ": " + message
String line = "[" + date + "] " + (player != null ? player.getName() : "Unknown Source") + ": " + message
+ (comment != null ? " (" + comment + ")" : "") + "\r\n";
LogFileWriter writer = writers.get(path);
@@ -190,7 +193,7 @@ public class FileHandler implements LoggerHandler {
writers.entrySet().iterator();
// Remove some entries
for (; it.hasNext(); ) {
while (it.hasNext()) {
Map.Entry<String,LogFileWriter> entry = it.next();
try {
entry.getValue().getWriter().close();
@@ -226,7 +226,7 @@ public class WorldGuardCommands {
}
}, MoreExecutors.directExecutor());
Futures.addCallback(sampler.getFuture(), new FutureCallback<Sampler>() {
Futures.addCallback(sampler.getFuture(), new FutureCallback<>() {
@Override
public void onSuccess(Sampler result) {
String output = result.toString();
@@ -247,7 +247,7 @@ public class WorldGuardCommands {
@Override
public void onFailure(Throwable throwable) {
}
});
}, MoreExecutors.directExecutor());
}
@Command(aliases = {"stopprofile"}, usage = "",desc = "Stop a running profile", min = 0, max = 0)
@@ -21,6 +21,7 @@ package com.sk89q.worldguard.commands.region;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
@@ -30,6 +31,7 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
import com.sk89q.worldedit.util.formatting.component.LabelFormat;
@@ -41,6 +43,7 @@ import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.task.RegionAdder;
@@ -65,6 +68,7 @@ import com.sk89q.worldguard.protection.managers.RemovalStrategy;
import com.sk89q.worldguard.protection.managers.migration.DriverMigration;
import com.sk89q.worldguard.protection.managers.migration.MigrationException;
import com.sk89q.worldguard.protection.managers.migration.UUIDMigration;
import com.sk89q.worldguard.protection.managers.migration.WorldHeightMigration;
import com.sk89q.worldguard.protection.managers.storage.DriverType;
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
@@ -73,6 +77,7 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
import com.sk89q.worldguard.protection.util.WorldEditRegionConverter;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.util.Enums;
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
@@ -280,7 +285,7 @@ public final class RegionCommands extends RegionCommandsBase {
}
}
// We have to check whether this region violates the space of any other reion
// We have to check whether this region violates the space of any other region
ApplicableRegionSet regions = manager.getApplicableRegions(region);
// Check if this region overlaps any other region
@@ -313,6 +318,18 @@ public final class RegionCommands extends RegionCommandsBase {
}
}
// Inherit from a template region
if (!Strings.isNullOrEmpty(wcfg.setParentOnClaim)) {
ProtectedRegion templateRegion = manager.getRegion(wcfg.setParentOnClaim);
if (templateRegion != null) {
try {
region.setParent(templateRegion);
} catch (CircularInheritanceException e) {
throw new CommandException(e.getMessage());
}
}
}
RegionAdder task = new RegionAdder(manager, region);
task.setLocatorPolicy(UserLocatorPolicy.UUID_ONLY);
task.setOwnersInput(new String[]{player.getName()});
@@ -435,9 +452,9 @@ public final class RegionCommands extends RegionCommandsBase {
* @throws CommandException any error
*/
@Command(aliases = {"list"},
usage = "[page]",
usage = "[-w world] [-p owner [-n]] [-s] [-i filter] [page]",
desc = "Get a list of regions",
flags = "np:w:",
flags = "np:w:i:s",
max = 1)
public void list(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
@@ -474,6 +491,16 @@ public final class RegionCommands extends RegionCommandsBase {
task.filterOwnedByName(ownedBy, args.hasFlag('n'));
}
if (args.hasFlag('s')) {
ProtectedRegion existing = checkRegionFromSelection(sender, "tmp");
task.filterByIntersecting(existing);
}
// -i string is in region id
if (args.hasFlag('i')) {
task.filterIdByMatch(args.getFlag('i'));
}
AsyncCommandBuilder.wrap(task, sender)
.registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Getting region list")
.sendMessageAfterDelay("(Please wait... fetching region list...)")
@@ -1068,6 +1095,62 @@ public final class RegionCommands extends RegionCommandsBase {
}
}
/**
* Migrate regions that went from 0-255 to new world heights.
*
* @param args the arguments
* @param sender the sender
* @throws CommandException any error
*/
@Command(aliases = {"migrateheights"},
usage = "[world]", max = 1,
flags = "yw:",
desc = "Migrate regions from old height limits to new height limits")
public void migrateHeights(CommandContext args, Actor sender) throws CommandException {
// Check permissions
if (!getPermissionModel(sender).mayMigrateRegionHeights()) {
throw new CommandPermissionsException();
}
if (!args.hasFlag('y')) {
throw new CommandException("This command is potentially dangerous.\n" +
"Please ensure you have made a backup of your data, and then re-enter the command with -y tacked on at the end to proceed.");
}
World world = null;
try {
world = checkWorld(args, sender, 'w');
} catch (CommandException ignored) {
}
LoggerToChatHandler handler = null;
Logger minecraftLogger = null;
if (sender instanceof LocalPlayer) {
handler = new LoggerToChatHandler(sender);
handler.setLevel(Level.ALL);
minecraftLogger = Logger.getLogger("com.sk89q.worldguard");
minecraftLogger.addHandler(handler);
}
try {
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionDriver driver = container.getDriver();
WorldHeightMigration migration = new WorldHeightMigration(driver, WorldGuard.getInstance().getFlagRegistry(), world);
container.migrate(migration);
sender.print("Migration complete!");
} catch (MigrationException e) {
log.log(Level.WARNING, "Failed to migrate", e);
throw new CommandException("Error encountered while migrating: " + e.getMessage());
} finally {
if (minecraftLogger != null) {
minecraftLogger.removeHandler(handler);
}
}
}
/**
* Teleport to a region
*
@@ -1076,8 +1159,8 @@ public final class RegionCommands extends RegionCommandsBase {
* @throws CommandException any error
*/
@Command(aliases = {"teleport", "tp"},
usage = "<id>",
flags = "sw:",
usage = "[-w world] [-c|s] <id>",
flags = "csw:",
desc = "Teleports you to the location associated with the region.",
min = 1, max = 1)
public void teleport(CommandContext args, Actor sender) throws CommandException {
@@ -1102,6 +1185,23 @@ public final class RegionCommands extends RegionCommandsBase {
throw new CommandException(
"The region has no spawn point associated.");
}
} else if (args.hasFlag('c')) {
// Check permissions
if (!getPermissionModel(player).mayTeleportToCenter(existing)) {
throw new CommandPermissionsException();
}
Region region = WorldEditRegionConverter.convertToRegion(existing);
if (region == null || region.getCenter() == null) {
throw new CommandException("The region has no center point.");
}
if (player.getGameMode() == GameModes.SPECTATOR) {
teleportLocation = new Location(world, region.getCenter(), 0, 0);
} else {
// TODO: Add some method to create a safe teleport location.
// The method AbstractPlayerActor$findFreePoisition(Location loc) is no good way for this.
// It doesn't return the found location and it can't be checked if the location is inside the region.
throw new CommandException("Center teleport is only availible in Spectator gamemode.");
}
} else {
teleportLocation = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.TELE_LOC, player);
@@ -211,7 +211,7 @@ class RegionCommandsBase {
return global;
}
throw new CommandException(
"You're not standing in a region." +
"You're not standing in a region. " +
"Specify an ID if you want to select a specific region.");
} else if (set.size() > 1) {
boolean first = true;
@@ -327,6 +327,12 @@ public class RegionPrintoutBuilder implements Callable<TextComponent> {
+ 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();
@@ -42,6 +42,7 @@ 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;
@@ -58,6 +59,8 @@ public class RegionLister implements Callable<Integer> {
private final RegionManager manager;
private final String world;
private OwnerMatcher ownerMatcher;
private String idFilter;
private ProtectedRegion filterByIntersecting;
private int page;
private String playerName;
private boolean nameOnly;
@@ -80,6 +83,10 @@ public class RegionLister implements Callable<Integer> {
this.page = page;
}
public void filterByIntersecting(ProtectedRegion region) {
this.filterByIntersecting = region;
}
public void filterOwnedByName(String name, boolean nameOnly) {
this.playerName = name;
this.nameOnly = nameOnly;
@@ -144,20 +151,29 @@ public class RegionLister implements Callable<Integer> {
};
}
public void filterIdByMatch(String idFilter) {
this.idFilter = idFilter;
}
@Override
public Integer call() throws Exception {
Map<String, ProtectedRegion> regions = manager.getRegions();
Collection<ProtectedRegion> iterableRegions = regions.values();
if (filterByIntersecting != null) {
iterableRegions = filterByIntersecting.getIntersectingRegions(iterableRegions);
}
// Build a list of regions to show
List<RegionListEntry> entries = new ArrayList<>();
for (Map.Entry<String, ProtectedRegion> rg : regions.entrySet()) {
if (rg.getKey().equals("__global__")) {
for (ProtectedRegion rg : iterableRegions) {
if (rg.getId().equals("__global__")) {
continue;
}
final ProtectedRegion region = rg.getValue();
final RegionListEntry entry = new RegionListEntry(region);
if (entry.matches(ownerMatcher)) {
final RegionListEntry entry = new RegionListEntry(rg);
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
entries.add(entry);
}
}
@@ -168,7 +184,7 @@ public class RegionLister implements Callable<Integer> {
// insert global on top
if (regions.containsKey("__global__")) {
final RegionListEntry entry = new RegionListEntry(regions.get("__global__"));
if (entry.matches(ownerMatcher)) {
if (entry.matches(idFilter) && entry.matches(ownerMatcher)) {
entries.add(0, entry);
}
}
@@ -182,6 +198,8 @@ public class RegionLister implements Callable<Integer> {
String cmd = "/rg list -w \"" + world + "\""
+ (playerName != null ? " -p " + playerName : "")
+ (nameOnly ? " -n" : "")
+ (filterByIntersecting != null ? " -s" : "")
+ (idFilter != null ? " -i " + idFilter : "")
+ " %page%";
PaginationBox box = new RegionListBox(title, cmd, perms, entries, world);
sender.print(box.create(page));
@@ -210,6 +228,10 @@ public class RegionLister implements Callable<Integer> {
|| (isMember = matcher.isContainedWithin(region.getMembers()));
}
public boolean matches(String idMatcher) {
return idMatcher == null || region.getId().contains(idMatcher);
}
public ProtectedRegion getRegion() {
return region;
}
@@ -270,6 +292,12 @@ public class RegionLister implements Callable<Integer> {
.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();
}
@@ -129,6 +129,7 @@ public abstract class WorldConfiguration {
public boolean allowTamedSpawns;
public int maxClaimVolume;
public boolean claimOnlyInsideExistingRegions;
public String setParentOnClaim;
public int maxRegionCountPerPlayer;
public boolean antiWolfDumbness;
public boolean signChestProtection;
@@ -157,6 +158,7 @@ public abstract class WorldConfiguration {
public boolean disableGrassGrowth;
public boolean disableMyceliumSpread;
public boolean disableVineGrowth;
public boolean disableRockGrowth;
public boolean disableCropGrowth;
public boolean disableEndermanGriefing;
public boolean disableSnowmanTrails;
@@ -170,7 +172,6 @@ public abstract class WorldConfiguration {
public boolean fakePlayerBuildOverride;
public boolean explosionFlagCancellation;
public boolean disableDeathMessages;
public boolean disableObsidianGenerators;
public boolean strictEntitySpawn;
public boolean ignoreHopperMoveEvents;
public boolean breakDeniedHoppers;
@@ -93,6 +93,12 @@ public abstract class YamlConfigurationManager extends ConfigurationManager {
String sqlUsername = config.getString("regions.sql.username", "worldguard");
String sqlPassword = config.getString("regions.sql.password", "worldguard");
String sqlTablePrefix = config.getString("regions.sql.table-prefix", "");
if (!useSqlDatabase) {
config.removeProperty("regions.sql");
} else {
log.warning("SQL support for WorldGuard region storage is deprecated for removal in a future version. Please migrate to YAML storage.");
log.warning("For details, see https://worldguard.enginehub.org/en/latest/regions/storage/");
}
DataSourceConfig dataSourceConfig = new DataSourceConfig(sqlDsn, sqlUsername, sqlPassword, sqlTablePrefix);
SQLDriver sqlDriver = new SQLDriver(dataSourceConfig);
@@ -63,7 +63,11 @@ public class RegionPermissionModel extends AbstractPermissionModel {
public boolean mayMigrateRegionNames() {
return hasPluginPermission("region.migrateuuid");
}
public boolean mayMigrateRegionHeights() {
return hasPluginPermission("region.migrateheights");
}
public boolean mayDefine() {
return hasPluginPermission("region.define");
}
@@ -106,6 +110,10 @@ public class RegionPermissionModel extends AbstractPermissionModel {
return hasPatternPermission("teleport", region);
}
public boolean mayTeleportToCenter(ProtectedRegion region) {
return hasPatternPermission("teleportcenter", region);
}
public boolean mayOverrideLocationFlagBounds(ProtectedRegion region) {
return hasPatternPermission("locationoverride", region);
}
@@ -125,7 +133,7 @@ public class RegionPermissionModel extends AbstractPermissionModel {
return mayList();
}
}
public boolean maySetFlag(ProtectedRegion region) {
return hasPatternPermission("flag.regions", region);
}
@@ -195,5 +203,4 @@ public class RegionPermissionModel extends AbstractPermissionModel {
return hasPluginPermission(effectivePerm);
}
}
@@ -120,6 +120,7 @@ public final class Flags {
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 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));
@@ -72,7 +72,7 @@ abstract class AbstractMigration implements Migration {
* @param store the region store
* @throws MigrationException on migration error
*/
protected abstract void migrate(RegionDatabase store)throws MigrationException;
protected abstract void migrate(RegionDatabase store) throws MigrationException;
/**
* Called after migration has successfully completed.
@@ -0,0 +1,114 @@
/*
* 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.managers.migration;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
import com.sk89q.worldguard.protection.managers.storage.RegionDatabase;
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
import com.sk89q.worldguard.protection.managers.storage.StorageException;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class WorldHeightMigration extends AbstractMigration {
private static final Logger log = Logger.getLogger(WorldHeightMigration.class.getCanonicalName());
private static final Field minField;
private static final Field maxField;
static {
try {
minField = ProtectedRegion.class.getDeclaredField("min");
minField.setAccessible(true);
maxField = ProtectedRegion.class.getDeclaredField("max");
maxField.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new ExceptionInInitializerError(new MigrationException("Migrator broke.", e));
}
}
private final FlagRegistry flagRegistry;
private final World world;
private int changed = 0;
public WorldHeightMigration(RegionDriver driver, FlagRegistry flagRegistry, @Nullable World world) {
super(driver);
this.flagRegistry = flagRegistry;
this.world = world;
}
@Override
protected void migrate(RegionDatabase store) throws MigrationException {
if (world != null && !store.getName().equals(world.getName())) return;
log.log(Level.INFO, "Migrating regions in '" + store.getName() + "' to new height limits...");
Set<ProtectedRegion> regions;
try {
regions = store.loadAll(flagRegistry);
} catch (StorageException e) {
throw new MigrationException("Failed to load region data for the world '" + store.getName() + "'", e);
}
int min = -64;
int max = 319;
World world = WorldGuard.getInstance().getPlatform().getMatcher().getWorldByName(store.getName());
if (world != null) {
min = world.getMinY();
max = world.getMaxY();
// in theory someone could run a data pack that keeps their world height
// at the old defaults...? either way if this is the case there are no changes to make.
if (min == 0 && max == 255) return;
}
for (ProtectedRegion region : regions) {
if (region.getMinimumPoint().getBlockY() <= 0
&& region.getMaximumPoint().getBlockY() >= 255) {
expand(region, min, max);
changed++;
}
}
try {
store.saveAll(regions);
} catch (StorageException e) {
throw new MigrationException("Failed to save region data after migration of the world '" + store.getName() + "'", e);
}
}
private static void expand(ProtectedRegion region, int min, int max) throws MigrationException {
try {
minField.set(region, region.getMinimumPoint().withY(min));
maxField.set(region, region.getMaximumPoint().withY(max));
region.setDirty(true);
} catch (IllegalAccessException e) {
throw new MigrationException("Migrator broke.", e);
}
}
@Override
protected void postMigration() {
log.log(Level.INFO, "A total of " + changed + " top-to-bottom regions were vertically expanded.");
}
}
+3 -1
View File
@@ -3,7 +3,9 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
applyLibrariesConfiguration()
dependencies {
"shade"("org.enginehub:squirrelid:${Versions.SQUIRRELID}")
"shade"("org.enginehub:squirrelid:${Versions.SQUIRRELID}") {
exclude(group = "com.destroystokyo.paper", module = "paper-api")
}
"shade"("org.khelekore:prtree:1.5.0")
}