Compare commits
228
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82a274bad2 | ||
|
|
8aa01026ea | ||
|
|
750d1ea4fa | ||
|
|
586ac4a90e | ||
|
|
816d5f86d6 | ||
|
|
7e8ebfb8cd | ||
|
|
350d228975 | ||
|
|
2126efe27c | ||
|
|
3330bd3031 | ||
|
|
4f5b4126f4 | ||
|
|
c4a80d7b78 | ||
|
|
d31f7e9d87 | ||
|
|
356d67edf4 | ||
|
|
8865cfb53f | ||
|
|
bf72328c37 | ||
|
|
9a80620aa1 | ||
|
|
982eb28f2a | ||
|
|
4ecd65a589 | ||
|
|
5fbe16ed5a | ||
|
|
582d256f38 | ||
|
|
26e587805d | ||
|
|
3ad2322db7 | ||
|
|
8764108edd | ||
|
|
5fa8e9acf6 | ||
|
|
0ead2da16f | ||
|
|
fd4bc7cf60 | ||
|
|
ad296fde1f | ||
|
|
6f39a2c97d | ||
|
|
befb2b54d8 | ||
|
|
efcd14830e | ||
|
|
491bb2467f | ||
|
|
dfbe81c785 | ||
|
|
986bafc13d | ||
|
|
9b4613ce84 | ||
|
|
48e875d13e | ||
|
|
14b54d5269 | ||
|
|
1c24b17c90 | ||
|
|
346ac94737 | ||
|
|
6d351300de | ||
|
|
8a69d6ad43 | ||
|
|
3b44ea218d | ||
|
|
68c97f7ae6 | ||
|
|
68411ae6bf | ||
|
|
2c5e86c689 | ||
|
|
4eca331430 | ||
|
|
b6574245b8 | ||
|
|
85d744d79f | ||
|
|
e536dff1a8 | ||
|
|
39287f55ef | ||
|
|
d5ebde53b9 | ||
|
|
101ddae443 | ||
|
|
c3eb0ee8bd | ||
|
|
6a8c0b6255 | ||
|
|
2b97f7310f | ||
|
|
073091525b | ||
|
|
79b9c12319 | ||
|
|
01f745b027 | ||
|
|
9725bdfeeb | ||
|
|
cdf9767959 | ||
|
|
66e21da6b2 | ||
|
|
87b14d3944 | ||
|
|
7bbeb90320 | ||
|
|
cd895d03dc | ||
|
|
ee2a304148 | ||
|
|
06e9e33da4 | ||
|
|
7065ffaea2 | ||
|
|
1bc4e68ff9 | ||
|
|
4e53d13290 | ||
|
|
90344d36df | ||
|
|
f36a56e854 | ||
|
|
5d4bacc80e | ||
|
|
d88bf6e137 | ||
|
|
63f5d769d8 | ||
|
|
9a9bfc03b9 | ||
|
|
28112ef4d8 | ||
|
|
7e5a3238b8 | ||
|
|
3279a6a38d | ||
|
|
b64e48769d | ||
|
|
ff8002fc13 | ||
|
|
2af835f0c3 | ||
|
|
bf25b65f09 | ||
|
|
52eb3d820f | ||
|
|
908fcb1e44 | ||
|
|
73cd26aea3 | ||
|
|
758d25812b | ||
|
|
fa0ef421c7 | ||
|
|
e936a6271f | ||
|
|
7362e543da | ||
|
|
8a46d70301 | ||
|
|
a168e5cb48 | ||
|
|
ae578f9491 | ||
|
|
e72122378d | ||
|
|
fd2ea3df09 | ||
|
|
e94e071c6e | ||
|
|
0e19236cdc | ||
|
|
1c12756acf | ||
|
|
bcfde80c07 | ||
|
|
8dc9e864eb | ||
|
|
fec820f4ba | ||
|
|
ff9ffad302 | ||
|
|
fc2cb6aeae | ||
|
|
d2776ef448 | ||
|
|
36ef41b710 | ||
|
|
9258ebd8c7 | ||
|
|
d528cbcafd | ||
|
|
760c193b0e | ||
|
|
7c6edcb081 | ||
|
|
009a94f74d | ||
|
|
bd6fb4e51c | ||
|
|
2fdef44744 | ||
|
|
5b991f44e2 | ||
|
|
871ba16b67 | ||
|
|
e90c50d170 | ||
|
|
d1be3bd0be | ||
|
|
4d40b3f7e4 | ||
|
|
1877479094 | ||
|
|
20ce469aec | ||
|
|
70c91f777f | ||
|
|
cc24f38d83 | ||
|
|
5ec27db284 | ||
|
|
5d6bc806f0 | ||
|
|
5868ad64b4 | ||
|
|
ac6fcf5ed6 | ||
|
|
231824fd34 | ||
|
|
a3e7efcc58 | ||
|
|
a649307a29 | ||
|
|
b0235757cc | ||
|
|
06ee82a745 | ||
|
|
d2cad7ca8d | ||
|
|
2390aa8f92 | ||
|
|
674c4a4a06 | ||
|
|
768402088a | ||
|
|
084033cc90 | ||
|
|
51801b1b36 | ||
|
|
71054197f2 | ||
|
|
610f96415f | ||
|
|
34fa336f00 | ||
|
|
d92d62bce9 | ||
|
|
cf14d41d19 | ||
|
|
719ade19f7 | ||
|
|
1a8a97daf1 | ||
|
|
d9dffa8e6d | ||
|
|
973588defb | ||
|
|
c704c1ca3a | ||
|
|
c33a268b91 | ||
|
|
9821f1d9c8 | ||
|
|
be6e0b67be | ||
|
|
b9b1fa6164 | ||
|
|
28585dd6f9 | ||
|
|
47ca7b821b | ||
|
|
9ce2dfd100 | ||
|
|
473ccd09d7 | ||
|
|
cc2e1d44b2 | ||
|
|
2e8f159d38 | ||
|
|
6581d16125 | ||
|
|
562bc56e83 | ||
|
|
4493cd7916 | ||
|
|
1cd9e45915 | ||
|
|
acb6bc6dd6 | ||
|
|
b7b17c5d21 | ||
|
|
bbd9211845 | ||
|
|
fc6796e20f | ||
|
|
6040a27126 | ||
|
|
1c483148dc | ||
|
|
128442c062 | ||
|
|
141854f076 | ||
|
|
f72cc6764b | ||
|
|
d95ecfaa8e | ||
|
|
6c96f4e974 | ||
|
|
28cee291c6 | ||
|
|
155f32c00f | ||
|
|
071ba05d81 | ||
|
|
2ee5aea06b | ||
|
|
3bb8de6d33 | ||
|
|
79ac01da34 | ||
|
|
6e4fbb0ece | ||
|
|
167ed5e0d3 | ||
|
|
91f3304f78 | ||
|
|
7928e73a32 | ||
|
|
d61d186544 | ||
|
|
dc356e88d0 | ||
|
|
d0d5574580 | ||
|
|
29617059b3 | ||
|
|
bf05fc81dd | ||
|
|
a2c5bf70f0 | ||
|
|
ea19006465 | ||
|
|
89f685ff9a | ||
|
|
ecc76033dc | ||
|
|
e843b0711d | ||
|
|
eddfaf7df0 | ||
|
|
d1150ab5f8 | ||
|
|
cc3996ca76 | ||
|
|
1965aecfba | ||
|
|
ce34ae44d8 | ||
|
|
f5a2d7bc47 | ||
|
|
24295025ef | ||
|
|
e3f56f6498 | ||
|
|
bd0c3cff3f | ||
|
|
7c4ab035a0 | ||
|
|
2593080f77 | ||
|
|
0d4595d511 | ||
|
|
bf820c2c27 | ||
|
|
a12718d354 | ||
|
|
b23c1ae606 | ||
|
|
7c59dcbcb9 | ||
|
|
15cacba7c9 | ||
|
|
adbe88daa6 | ||
|
|
5350c012f7 | ||
|
|
a91f377cf5 | ||
|
|
c3ae5ac210 | ||
|
|
f4ce740c06 | ||
|
|
3ff8d34053 | ||
|
|
f362f09380 | ||
|
|
62b789dff5 | ||
|
|
84a9db597a | ||
|
|
89fd700e32 | ||
|
|
9741b1794c | ||
|
|
001a6000f8 | ||
|
|
bf61069fed | ||
|
|
d93def8b5b | ||
|
|
540394e266 | ||
|
|
425b1c80cc | ||
|
|
47ae6f5378 | ||
|
|
48601e4215 | ||
|
|
5d3d732c25 | ||
|
|
ed77cacb1a | ||
|
|
cfae997de4 | ||
|
|
59b6522d59 |
No files matched your search
@@ -0,0 +1,77 @@
|
||||
name: 🐛 Report a Bug
|
||||
description: Report a problem with Multiverse-Core.
|
||||
title: "[Bug]: "
|
||||
labels: ["Bug: Unconfirmed"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
If you are having issues with other submodules of Multiverse, please go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues/new/choose
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues/new/choose
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues/new/choose
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues/new/choose
|
||||
|
||||
Not sure if this is a bug with Multiverse-Core? Feel free to ask on our Discord server: https://discord.gg/NZtfKky
|
||||
|
||||
When completing the report, please ensure all fields are filled with the correct details requested. Failure to do so will result in your issue being closed.
|
||||
- type: input
|
||||
id: mutliverse-version-info
|
||||
attributes:
|
||||
label: '`/mv version -p` output'
|
||||
description: Run `/mv version -p` in the console, then copy and paste the link from the output of the command into this box.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: server-logs
|
||||
attributes:
|
||||
label: Server logs
|
||||
description: >
|
||||
Include full startup log and console error (if any). upload all relevant logs to either https://paste.gg
|
||||
or https://gist.github.com, save and the paste the link in this box.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: server-version
|
||||
attributes:
|
||||
label: Server Version
|
||||
description: Output of `/version` command.
|
||||
placeholder: server version info
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: bug-description
|
||||
attributes:
|
||||
label: Bug Description
|
||||
description: Describe in detail what the bug is about. Include the expected behaviour and actual behaviour.
|
||||
placeholder: "Example: When running `/mv` it cause the server to crash..."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide detailed intructions to trigger the bug.
|
||||
placeholder: |
|
||||
Example:
|
||||
1. Start a server with only multiverse installed.
|
||||
2. Run `/mv` command.
|
||||
3. Players all get kicked with a "server closed" message.
|
||||
...
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: agreements
|
||||
attributes:
|
||||
label: Agreements
|
||||
description: Ensure you have done the following being submitting this issue.
|
||||
options:
|
||||
- label: I have searched for and ensured there isn't already an open or resolved issue(s) regarding this.
|
||||
required: true
|
||||
- label: >
|
||||
I was able to reproduce my issue on a freshly setup and up-to-date server with the latest
|
||||
version of Multiverse plugins with no other plugins and with no kinds of other server or client mods.
|
||||
required: true
|
||||
@@ -1,5 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 💬 Multiverse Discord Server
|
||||
- name: 💬 Multiverse Discord Server
|
||||
url: https://discord.gg/NZtfKky
|
||||
about: Need help with using Multiverse-Core or just want to chat with the devs? Join the Multiverse Discord Server for help!
|
||||
@@ -0,0 +1,41 @@
|
||||
name: 💡 Request a Feature
|
||||
description: Suggest a feature you want to see in Multiverse-Core!
|
||||
title: "[Idea]: "
|
||||
labels: ["Type: Idea"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to share your ideas!
|
||||
|
||||
If you are look for other submodules of Multiverse, go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues/new/choose
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues/new/choose
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues/new/choose
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues/new/choose
|
||||
|
||||
Not sure if your feature fits in Multiverse-Core? Feel free to ask on our Discord server: https://discord.gg/NZtfKky
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
attributes:
|
||||
label: Describe the feature
|
||||
description: What feature are you suggesting?
|
||||
placeholder: "Example: I hope multiverse can implement random teleport feature..."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: feature-reasoning
|
||||
attributes:
|
||||
label: How is the feature useful to all Multiverse users?
|
||||
description: How is the feature useful to all players, server owners and/or developers?
|
||||
placeholder: "Example: Random teleporting can be integrated into many multiverse modules such as mv-portals..."
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: agreements
|
||||
attributes:
|
||||
label: Agreements
|
||||
description: Ensure you have done the following being submitting this issue.
|
||||
options:
|
||||
- label: I have searched for and ensured there isn't already an open issue regarding this.
|
||||
required: true
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
name: ❓ Help!
|
||||
about: Encountered a problem with Multiverse-Core? Not sure how to fix it?
|
||||
title: ''
|
||||
labels: 'Type: Assistance'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Multiverse-Core help guide
|
||||
|
||||
Don't write inside the arrows as they will be hidden when you post your issue.
|
||||
|
||||
Get latest build from: http://ci.onarandombox.com/view/Multiverse/
|
||||
|
||||
If you need help other submodules of Multiverse, go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues
|
||||
|
||||
Or come join our Discord server to get help sooner: https://discord.gg/NZtfKky
|
||||
|
||||
If you're happy to wait (or you were sent here from Discord), read on:
|
||||
|
||||
1. Check the Usage and FAQ pages to see if it answers your queries:
|
||||
https://github.com/Multiverse/Multiverse-Core/wiki/Basics
|
||||
https://github.com/Multiverse/Multiverse-Core/wiki/FAQ
|
||||
|
||||
2. Fill out the template.
|
||||
This will help us understand what problem you've encountered and help us
|
||||
find a solution.
|
||||
|
||||
3. When linking files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/ or other similar service.
|
||||
|
||||
4. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Information
|
||||
|
||||
* **Server version:** <!-- Insert output of `/version` command -->
|
||||
|
||||
* **Full output of `/mv version -p`:** <!-- Replace this with the command output's https://paste.gg/ link -->
|
||||
|
||||
* **Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
|
||||
### Help request
|
||||
|
||||
**Problem**
|
||||
<!-- What problem did you encounter? -->
|
||||
|
||||
**What I have tried**
|
||||
<!-- What have you tried so far? -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- If relevant, include any screenshots here. -->
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
name: 🐛 Report a Bug
|
||||
about: Report a Multiverse-Core bug. Only use this if you're 100% sure it's something wrong with Multiverse-Core - otherwise, try "Help!".
|
||||
title: ''
|
||||
labels: 'Bug: Unconfirmed'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Multiverse-Core bug reporting guide
|
||||
|
||||
Don't put anything inside this block, as it won't be included in the issue.
|
||||
|
||||
Get latest build from: http://ci.onarandombox.com/view/Multiverse/
|
||||
|
||||
If you are having issues with other submodules of Multiverse, go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues
|
||||
|
||||
If you are reporting a bug, please follow the following steps:
|
||||
|
||||
1. Fill out the template in full.
|
||||
Run the commands in the console. Don't just put "latest" as a version,
|
||||
or we will ignore it.
|
||||
|
||||
2. When linking files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/, then paste a
|
||||
link to them in the relevant parts of the template.
|
||||
**DO NOT drag files into this box!**
|
||||
|
||||
3. Make sure not to write between the arrows, as anything there will be
|
||||
hidden.
|
||||
|
||||
4. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Information
|
||||
|
||||
* **Server version:** <!-- Insert output of `/version` command -->
|
||||
|
||||
* **Full output of `/mv version -p`:** <!-- Replace this with the command output's https://paste.gg/ link -->
|
||||
|
||||
* **Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
|
||||
### Details
|
||||
I was **`<able / not able>`** to reproduce my issue on a freshly setup and up-to-date server with the latest version of Multiverse plugins with no other plugins and with no kinds of other server or client mods.
|
||||
|
||||
**Description**
|
||||
<!-- Replace this with a brief summary of the bug. -->
|
||||
|
||||
**Steps to reproduce**
|
||||
<!-- Replace this with exactly what you did to cause the bug. -->
|
||||
|
||||
**Expected behavior**
|
||||
<!-- Replace this with what you expected to happen. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- Replace this with screenshots, if necessary. -->
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
name: 💡 Request a Feature
|
||||
about: Suggest a feature you want to see in Multiverse-Core!
|
||||
title: ''
|
||||
labels: 'Type: Idea'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Multiverse-Core feature request guide
|
||||
|
||||
Fill out the template. Don't write inside the arrows as they will be hidden
|
||||
when you post your issue.
|
||||
|
||||
Get latest build from: http://ci.onarandombox.com/view/Multiverse/
|
||||
|
||||
If you are look for other submodules of Multiverse, go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues
|
||||
|
||||
Not sure if your feature fits in Multiverse-Core? Feel free to ask on our Discord
|
||||
server: https://discord.gg/NZtfKky
|
||||
|
||||
If you have a feature suggestion for Multiverse-Core, read the following tips:
|
||||
|
||||
1. Fill out the template.
|
||||
This will help us understand what you're requesting and why you want us
|
||||
to add it.
|
||||
|
||||
2. Keep it simple.
|
||||
Make sure it's easy to understand what you're requesting. A good way is
|
||||
to keep it to one request per GitHub issue, as we can then easily track
|
||||
feature requests.
|
||||
|
||||
3. Check whether it has already been asked or added.
|
||||
You can search the issue tracker to see if your feature has already been
|
||||
requested at https://github.com/Multiverse/Multiverse-Core/issues.
|
||||
|
||||
4. Ask yourself: "Does this belong in Multiverse-Core?"
|
||||
There are lots of features that we reject because most servers won't
|
||||
need or use them. If your feature is very specific or already exists in
|
||||
another plugin, it might not be a good fit for Multiverse-Core.
|
||||
|
||||
5. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Feature request
|
||||
|
||||
**Feature description**
|
||||
<!-- What feature are you suggesting? -->
|
||||
|
||||
**How the feature is useful**
|
||||
<!-- How is the feature useful to players, server owners and/or developers? -->
|
||||
@@ -0,0 +1,55 @@
|
||||
name: Manually upload specific release to dev.bukkit.org
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Release to upload'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
manually_upload_dbo_release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get release info
|
||||
id: release-info
|
||||
uses: cardinalby/git-get-release-action@1.2.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag: ${{ steps.release.outputs.tag_name }}
|
||||
|
||||
- name: Download release artifact
|
||||
id: release-artifact
|
||||
uses: dsaltares/fetch-gh-release-asset@1.1.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
version: tags/${{ github.event.inputs.version }}
|
||||
file: multiverse-core-${{ github.event.inputs.version }}.jar
|
||||
|
||||
- name: Parse release type
|
||||
run: |
|
||||
if [[ "${{ steps.release-info.outputs.prerelease }}" == "true" ]]; then
|
||||
echo "RELEASE_TYPE=beta" >> $GITHUB_ENV
|
||||
else
|
||||
echo "RELEASE_TYPE=release" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Upload to dev.bukkit.org
|
||||
uses: benwoo1110/dbo-upload-action@v0.1.0
|
||||
with:
|
||||
api_token: ${{ secrets.DBO_UPLOAD_API_TOKEN }}
|
||||
project_id: 30765
|
||||
changelog: ${{ steps.release-artifact.outputs.body }}
|
||||
changelog_type: markdown
|
||||
display_name: ${{ steps.release-artifact.outputs.version }}
|
||||
game_versions: 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2, 1.19.3, 1.19.4, 1.20, 1.20.1
|
||||
release_type: ${{ env.RELEASE_TYPE }}
|
||||
project_relations: >
|
||||
[
|
||||
{"slug": "multiverse-portals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-netherportals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-signportals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-inventories", "type": "optionalDependency"}
|
||||
]
|
||||
file_path: ${{ github.workspace }}/subdir/multiverse-core-${{ steps.release-artifact.outputs.version }}.jar
|
||||
@@ -0,0 +1,53 @@
|
||||
name: Manually upload specific release to modrinth.com
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Release to upload'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
manually_upload_modrinth_release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get release info
|
||||
id: release-info
|
||||
uses: cardinalby/git-get-release-action@1.2.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag: ${{ steps.release.outputs.tag_name }}
|
||||
|
||||
- name: Modify version scheme
|
||||
run: |
|
||||
if [[ "${{ steps.release.outputs.tag_name }}" == *"pre"* ]]; then
|
||||
echo "Replacing prerelease version scheme with SNAPSHOT"
|
||||
echo "VERSION=$(echo ${{ steps.release.outputs.tag_name }} | sed -E 's/-pre.*/-SNAPSHOT/')" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Using release version scheme"
|
||||
echo "VERSION=${{ steps.release.outputs.tag_name }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Parse release type
|
||||
run: |
|
||||
if [[ "${{ steps.release-info.outputs.prerelease }}" == "true" ]]; then
|
||||
echo "RELEASE_TYPE=beta" >> $GITHUB_ENV
|
||||
else
|
||||
echo "RELEASE_TYPE=release" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ steps.release-info.outputs.tag_name }}
|
||||
|
||||
- name: Upload to modrinth.com
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: build modrinth
|
||||
env:
|
||||
GITHUB_VERSION: ${{ env.VERSION }}
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
CHANGELOG: ${{ steps.release-info.outputs.body }}
|
||||
VERSION_NUMBER: ${{ steps.release-info.outputs.tag_name }}
|
||||
VERSION_TYPE: ${{ env.RELEASE_TYPE }}
|
||||
@@ -0,0 +1,109 @@
|
||||
name: Manually promote prerelease to release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to promote'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
manually_promote_release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Verify input version is prerelease
|
||||
run: |
|
||||
if [[ "${{ github.event.inputs.version }}" != *"pre"* ]]; then
|
||||
echo "Version must be a prerelease"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Get release info
|
||||
id: get-release
|
||||
uses: cardinalby/git-get-release-action@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
tag: ${{ github.event.inputs.version }}
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ steps.get-release.outputs.tag_name }}
|
||||
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: Build and test
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: clean build -x assemble -x shadowJar
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create release
|
||||
id: release
|
||||
uses: benwoo1110/semantic-release-action@main
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
release_mode: promote
|
||||
promote_from: ${{ github.event.inputs.version }}
|
||||
|
||||
- name: Publish package
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: publish
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_VERSION: ${{ steps.release.outputs.publish_version }}
|
||||
|
||||
- name: Upload release artifact
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: build/libs/multiverse-core-${{ steps.release.outputs.publish_version }}.jar
|
||||
asset_name: multiverse-core-${{ steps.release.outputs.tag_name }}.jar
|
||||
tag: ${{ steps.release.outputs.tag_name }}
|
||||
|
||||
- name: Download release artifact
|
||||
id: release-artifact
|
||||
uses: dsaltares/fetch-gh-release-asset@1.1.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
version: tags/${{ steps.release.outputs.tag_name }}
|
||||
file: multiverse-core-${{ github.event.inputs.version }}.jar
|
||||
|
||||
- name: Upload to modrinth.com
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: build modrinth
|
||||
env:
|
||||
GITHUB_VERSION: ${{ env.VERSION }}
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
CHANGELOG: ${{ steps.release.outputs.body }}
|
||||
VERSION_NUMBER: ${{ steps.release.outputs.tag_name }}
|
||||
VERSION_TYPE: ${{ env.RELEASE_TYPE }}
|
||||
|
||||
- name: Upload to dev.bukkit.org
|
||||
uses: benwoo1110/dbo-upload-action@v0.2.0
|
||||
with:
|
||||
api_token: ${{ secrets.DBO_UPLOAD_API_TOKEN }}
|
||||
project_id: 30765
|
||||
changelog: ${{ steps.release.outputs.body }}
|
||||
changelog_type: markdown
|
||||
display_name: ${{ steps.release.outputs.tag_name }}
|
||||
game_versions: 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2, 1.19.3, 1.19.4, 1.20, 1.20.1
|
||||
release_type: ${{ env.RELEASE_TYPE }}
|
||||
project_relations: >
|
||||
[
|
||||
{"slug": "multiverse-portals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-netherportals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-signportals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-inventories", "type": "optionalDependency"}
|
||||
]
|
||||
file_path: ${{ github.workspace }}/subdir/multiverse-core-${{ steps.release.outputs.tag_name }}.jar
|
||||
@@ -0,0 +1,93 @@
|
||||
name: Create Release Version & Publish Package
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
release_on_push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: Build and test
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: clean build -x assemble -x shadowJar
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create release
|
||||
id: release
|
||||
uses: benwoo1110/semantic-release-action@main
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
version_bump: prlabel
|
||||
release_mode: prerelease
|
||||
|
||||
- name: Publish package
|
||||
if: steps.release.outputs.release_created == 'true'
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: publish
|
||||
env:
|
||||
GITHUB_VERSION: ${{ steps.release.outputs.publish_version }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload release artifact
|
||||
if: steps.release.outputs.release_created == 'true'
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: build/libs/multiverse-core-${{ steps.release.outputs.publish_version }}.jar
|
||||
asset_name: multiverse-core-${{ steps.release.outputs.tag_name }}.jar
|
||||
tag: ${{ steps.release.outputs.tag_name }}
|
||||
|
||||
- name: Download release artifact
|
||||
if: steps.release.outputs.release_created == 'true'
|
||||
uses: dsaltares/fetch-gh-release-asset@1.1.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
version: tags/${{ steps.release.outputs.tag_name }}
|
||||
file: multiverse-core-${{ steps.release.outputs.tag_name }}.jar
|
||||
|
||||
- name: Upload to modrinth.com
|
||||
if: steps.release.outputs.release_created == 'true'
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: build modrinth -x checkstyleMain -x checkstyleTest
|
||||
env:
|
||||
GITHUB_VERSION: ${{ steps.release.outputs.publish_version }}
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
CHANGELOG: ${{ steps.release.outputs.body }}
|
||||
VERSION_NUMBER: ${{ steps.release.outputs.tag_name }}
|
||||
VERSION_TYPE: ${{ steps.release.outputs.release_type }}
|
||||
|
||||
- name: Upload to dev.bukkit.org
|
||||
if: steps.release.outputs.release_created == 'true'
|
||||
uses: benwoo1110/dbo-upload-action@v0.2.0
|
||||
with:
|
||||
api_token: ${{ secrets.DBO_UPLOAD_API_TOKEN }}
|
||||
project_id: 30765
|
||||
changelog: ${{ steps.release.outputs.body }}
|
||||
changelog_type: markdown
|
||||
display_name: ${{ steps.release.outputs.tag_name }}
|
||||
game_versions: 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2, 1.19.3, 1.19.4, 1.20, 1.20.1
|
||||
release_type: ${{ steps.release.outputs.release_type }}
|
||||
project_relations: >
|
||||
[
|
||||
{"slug": "multiverse-portals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-netherportals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-signportals", "type": "optionalDependency"},
|
||||
{"slug": "multiverse-inventories", "type": "optionalDependency"}
|
||||
]
|
||||
file_path: ${{ github.workspace }}/multiverse-core-${{ steps.release.outputs.tag_name }}.jar
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Require PR Labels
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, labeled, unlabeled, synchronize]
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
require_label:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: mheap/github-action-required-labels@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
mode: exactly
|
||||
count: 1
|
||||
labels: "release:major, release:minor, release:patch, no release"
|
||||
@@ -0,0 +1,36 @@
|
||||
name: Run unit tests against all PRs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: Run unit tests
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: build
|
||||
env:
|
||||
GITHUB_VERSION: pr${{ github.event.pull_request.number }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Artifact output
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: multiverse-core-pr${{ github.event.pull_request.number }}
|
||||
path: build/libs/multiverse-core-pr${{ github.event.pull_request.number }}.jar
|
||||
@@ -43,3 +43,6 @@ debug.log
|
||||
# Doxygen
|
||||
/docs/html
|
||||
debug.txt
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
@@ -1,6 +0,0 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
notifications:
|
||||
email: false
|
||||
dist: trusty
|
||||
@@ -0,0 +1,6 @@
|
||||
Copyright (c) 2011, The Multiverse Team All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 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. Neither the name of the The Multiverse Team 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
|
||||
|
||||
@@ -1,16 +1,48 @@
|
||||
Building
|
||||
========
|
||||
Simply build the source with maven:
|
||||
<p align="center">
|
||||
<img src="config/multiverse2-long.png" alt="Multiverse Logo">
|
||||
</p>
|
||||
|
||||
$ mvn install
|
||||
[](https://dev.bukkit.org/projects/multiverse-core)
|
||||
[](https://www.spigotmc.org/resources/multiverse-core.390/)
|
||||
|
||||
[](https://dev.bukkit.org/projects/multiverse-core)
|
||||
[](https://ci.onarandombox.com/job/Multiverse-Core/)
|
||||
[](https://discord.gg/NZtfKky)
|
||||
[](https://patreon.com/dumptruckman)
|
||||
[](LICENSE.md)
|
||||
|
||||
|
||||
# About
|
||||
|
||||
[Multiverse](https://dev.bukkit.org/projects/multiverse-core) was created at the dawn of Bukkit multiworld support. It has since then grown into a **complete world management solution!** Multiverse provides the easiest to use world management solution for your Minecraft server, big or small, and with great addons like [Portals](https://dev.bukkit.org/projects/multiverse-portals) and [NetherPortals](https://dev.bukkit.org/projects/multiverse-netherportals/), what's not to love!
|
||||
|
||||
Now it's time to create your very own Multiverse server, do check out our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki) and [Usage Guide](https://github.com/Multiverse/Multiverse-Core/wiki/Basics) to get started. Feel free to hop onto our [Discord](https://discord.gg/NZtfKky) if you have any question or just want to have a chat with us!
|
||||
|
||||
## Amazing sub-modules available:
|
||||
|
||||
* [Multiverse-NetherPortals](https://github.com/Multiverse/Multiverse-NetherPortals) -> Have separate nether and end worlds for each of your overworlds!
|
||||
* [Multiverse-Portals](https://github.com/Multiverse/Multiverse-Portals) -> Make custom portals to go to any destination!
|
||||
* [Multiverse-Inventories](https://github.com/Multiverse/Multiverse-Inventories) -> Have separated players stats and inventories per world or per group of worlds.
|
||||
* [Multiverse-SignPortals](https://github.com/Multiverse/Multiverse-SignPortals) -> Signs as teleporters!
|
||||
|
||||
## Building
|
||||
Simply build the source with Gradle:
|
||||
```
|
||||
./gradlew build
|
||||
```
|
||||
More details are available on the [build instructions wiki page](https://github.com/Multiverse/Multiverse-Core/wiki/Building).
|
||||
|
||||
License
|
||||
=======
|
||||
Copyright (c) 2011, The Multiverse Team All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
## Contributing
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 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. Neither the name of the The Multiverse Team 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
|
||||
**Want to help improve Multiverse?** There are several ways you can support and contribute to the project.
|
||||
* Take a look at our "Bug: Unconfirmed" issues, where you can find issues that need extra testing and investigation.
|
||||
* Want others to love Multiverse too? You can join the [Multiverse Discord community](https://discord.gg/NZtfKky) and help others with issues and setup!
|
||||
* A Multiverse guru? You can update our [Wiki](https://github.com/Multiverse/Multiverse-Core/wiki) with your latest tip, tricks and guides! The wiki open for all to edit and improve.
|
||||
* Love coding? You could look at ["State: Open to PR"](https://github.com/Multiverse/Multiverse-Core/labels/State%3A%20Open%20to%20PR) and ["Resolution: Accepted"](https://github.com/Multiverse/Multiverse-Core/labels/Resolution%3A%20Accepted) issues. We're always happy to receive bug fixes and feature additions as [pull requests](https://www.freecodecamp.org/news/how-to-make-your-first-pull-request-on-github-3/).
|
||||
* If you'd like to make a financial contribution to the project, do consider joining our [Patreon](https://www.patreon.com/dumptruckman) or make a one-time donation [here](https://paypal.me/dumptruckman)!
|
||||
|
||||
Additionally, we would like to give a big thanks to everyone that has supported Multiverse over the years, as well as those in the years to come. Thank you!
|
||||
|
||||
## License
|
||||
Multiverse-Core is licensed under BSD-3-Clause License. Please see [LICENSE.md](LICENSE.md) for more info.
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'maven-publish'
|
||||
id 'checkstyle'
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.2'
|
||||
id "com.modrinth.minotaur" version "2.+"
|
||||
}
|
||||
|
||||
version = System.getenv('GITHUB_VERSION') ?: 'local'
|
||||
group = 'com.onarandombox.multiversecore'
|
||||
description = 'Multiverse-Core'
|
||||
|
||||
java.sourceCompatibility = JavaVersion.VERSION_11
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
|
||||
maven {
|
||||
url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.onarandombox.com/content/groups/public')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://hub.spigotmc.org/nexus/content/groups/public/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://jitpack.io')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.minebench.de/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.maven.apache.org/maven2/')
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT'
|
||||
|
||||
implementation('com.github.MilkBowl:VaultAPI:1.7') {
|
||||
exclude group: 'org.bukkit', module: 'bukkit'
|
||||
}
|
||||
|
||||
api('me.main__.util:SerializationConfig:1.7') {
|
||||
exclude group: 'org.bukkit', module: 'bukkit'
|
||||
}
|
||||
api('com.pneumaticraft.commandhandler:CommandHandler:11') {
|
||||
exclude group: 'org.bukkit', module: 'bukkit'
|
||||
exclude group: 'junit', module: 'junit'
|
||||
}
|
||||
api 'com.dumptruckman.minecraft:buscript:2.0-SNAPSHOT'
|
||||
api 'org.bstats:bstats-bukkit:2.2.1'
|
||||
api('com.dumptruckman.minecraft:Logging:1.1.1') {
|
||||
exclude group: 'junit', module: 'junit'
|
||||
}
|
||||
api 'de.themoep.idconverter:mappings:1.2-SNAPSHOT'
|
||||
api 'org.jetbrains:annotations:16.0.2'
|
||||
|
||||
testImplementation 'org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT'
|
||||
testImplementation('com.googlecode.json-simple:json-simple:1.1.1') {
|
||||
exclude group: 'junit', module: 'junit'
|
||||
}
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.mockito:mockito-core:3.11.2'
|
||||
testImplementation 'commons-io:commons-io:2.4'
|
||||
}
|
||||
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
tasks.withType(Javadoc) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
|
||||
configurations {
|
||||
[apiElements, runtimeElements].each {
|
||||
it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
|
||||
it.outgoing.artifact(shadowJar)
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
name = "GitHubPackages"
|
||||
url = "https://maven.pkg.github.com/Multiverse/Multiverse-Core"
|
||||
credentials {
|
||||
username = System.getenv("GITHUB_ACTOR")
|
||||
password = System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ext.bitlyAccessToken = System.getenv('BITLY_ACCESS_TOKEN') ?: 'bitly-access-token'
|
||||
|
||||
task prepareSource(type: Sync) {
|
||||
inputs.property 'bitlyAccessToken', bitlyAccessToken
|
||||
from sourceSets.main.java
|
||||
into "$buildDir/src"
|
||||
filter(ReplaceTokens, tokens: [
|
||||
'bitly-access-token': bitlyAccessToken,
|
||||
])
|
||||
}
|
||||
|
||||
compileJava {
|
||||
source = prepareSource.outputs
|
||||
}
|
||||
|
||||
processResources {
|
||||
def props = [version: "${project.version}"]
|
||||
inputs.properties props
|
||||
filteringCharset 'UTF-8'
|
||||
filesMatching('plugin.yml') {
|
||||
expand props
|
||||
}
|
||||
|
||||
// This task should never be skipped. The tests depend on this having been run but we want the new version number
|
||||
// that is created after tests are run and before we run again to publish.
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
|
||||
checkstyle {
|
||||
toolVersion = '6.1.1'
|
||||
configFile file('config/mv_checks.xml')
|
||||
ignoreFailures = true
|
||||
}
|
||||
|
||||
|
||||
javadoc {
|
||||
source = sourceSets.main.allJava
|
||||
classpath = configurations.compileClasspath
|
||||
}
|
||||
|
||||
|
||||
project.configurations.api.canBeResolved = true
|
||||
|
||||
shadowJar {
|
||||
relocate 'me.main__.util', 'com.onarandombox.serializationconfig'
|
||||
relocate 'com.pneumaticraft.commandhandler', 'com.onarandombox.commandhandler'
|
||||
relocate 'buscript', 'com.onarandombox.buscript'
|
||||
relocate 'org.bstats', 'com.onarandombox.bstats'
|
||||
relocate 'com.dumptruckman.minecraft.util.Logging', 'com.onarandombox.MultiverseCore.utils.CoreLogging'
|
||||
relocate 'com.dumptruckman.minecraft.util.DebugLog', 'com.onarandombox.MultiverseCore.utils.DebugFileLogger'
|
||||
relocate 'org.codehaus.jettison', 'com.onarandombox.jettison'
|
||||
relocate 'de.themoep.idconverter', 'com.onarandombox.idconverter'
|
||||
|
||||
configurations = [project.configurations.api]
|
||||
|
||||
archiveFileName = "$baseName-$version.$extension"
|
||||
classifier = ''
|
||||
}
|
||||
|
||||
build.dependsOn shadowJar
|
||||
jar.enabled = false
|
||||
|
||||
modrinth {
|
||||
token = System.getenv("MODRINTH_TOKEN")
|
||||
projectId = "multiverse-core"
|
||||
versionNumber = System.getenv("VERSION_NUMBER")
|
||||
versionType = System.getenv("VERSION_TYPE")
|
||||
uploadFile = jar
|
||||
gameVersions = ["1.20.1", "1.20", "1.19.4", "1.19.3", "1.19.2", "1.19.1", "1.19", "1.18.2", "1.18.1", "1.18", "1.17.1", "1.17", "1.16.5", "1.16.4", "1.16.3", "1.16.2", "1.16.1", "1.16", "1.15.2", "1.15.1", "1.15", "1.14.4", "1.14.3", "1.14.2", "1.14.1", "1.14", "1.13.2", "1.13.1", "1.13"]
|
||||
loaders = ["bukkit", "spigot", "paper"]
|
||||
changelog = System.getenv("CHANGELOG")
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
+6
@@ -0,0 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,244 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
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##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# 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
|
||||
|
||||
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 ;; #(
|
||||
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
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
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=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=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" )
|
||||
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 \
|
||||
"$@"
|
||||
|
||||
# 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" "$@"
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-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
|
||||
|
||||
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
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
: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 %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,397 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.onarandombox.multiversecore</groupId>
|
||||
<artifactId>Multiverse-Core</artifactId>
|
||||
<version>4.2.3-SNAPSHOT</version>
|
||||
<name>Multiverse-Core</name>
|
||||
<description>World Management Plugin</description>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.number>UNKNOWN</project.build.number>
|
||||
<project.bitly-access-token>bitly-access-token</project.bitly-access-token>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<!-- Spigot -->
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>onarandombox</id>
|
||||
<url>http://repo.onarandombox.com/content/groups/public</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>vault-repo</id>
|
||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>minebench-repo</id>
|
||||
<url>https://repo.minebench.de/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>CodeMC</id>
|
||||
<url>https://repo.codemc.org/repository/maven-public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>doodleproject-repo</id>
|
||||
<name>DoodleProject Maven 2 Repository</name>
|
||||
<url>http://doodleproject.sourceforge.net/maven2/release</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<ciManagement>
|
||||
<system>jenkins</system>
|
||||
<url>http://ci.onarandombox.com</url>
|
||||
</ciManagement>
|
||||
|
||||
<!-- Profiles are used to detect whether this is a local or Jenkins build
|
||||
and adjust the build number accordingly -->
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jenkins</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.BUILD_NUMBER</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.build.number>${env.BUILD_NUMBER}</project.build.number>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>bitly</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.BITLY_ACCESS_TOKEN</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.bitly-access-token>${env.BITLY_ACCESS_TOKEN}</project.bitly-access-token>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<plugins>
|
||||
<!-- Compiler -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.google.code.maven-replacer-plugin</groupId>
|
||||
<artifactId>maven-replacer-plugin</artifactId>
|
||||
<version>1.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>replace-bitly-access-token</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>replace</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<basedir>${project.build.sourceDirectory}</basedir>
|
||||
<includes>
|
||||
<include>com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java</include>
|
||||
</includes>
|
||||
<replacements>
|
||||
<replacement>
|
||||
<token>bitly-access-token</token>
|
||||
<value>${project.bitly-access-token}</value>
|
||||
</replacement>
|
||||
</replacements>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>replace-maven-version-number</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>replace</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<basedir>${project.build.directory}/classes</basedir>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
</includes>
|
||||
<replacements>
|
||||
<replacement>
|
||||
<token>maven-version-number</token>
|
||||
<value>${project.version}-b${project.build.number}</value>
|
||||
</replacement>
|
||||
</replacements>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Jar Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M3</version>
|
||||
<configuration>
|
||||
<parallel>methods</parallel>
|
||||
<threadCount>10</threadCount>
|
||||
<excludes>
|
||||
<exclude>**/TestCommandSender.java</exclude>
|
||||
<exclude>**/TestInstanceCreator.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.surefire</groupId>
|
||||
<artifactId>surefire-junit47</artifactId>
|
||||
<version>3.0.0-M3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>2.17</version>
|
||||
<configuration>
|
||||
<enableRulesSummary>true</enableRulesSummary>
|
||||
<configLocation>${project.basedir}/config/mv_checks.xml</configLocation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>javadoc-jar</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<failOnError>false</failOnError>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>me.main__.util</pattern>
|
||||
<shadedPattern>com.onarandombox.serializationconfig</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.pneumaticraft.commandhandler</pattern>
|
||||
<shadedPattern>com.onarandombox.commandhandler</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>buscript</pattern>
|
||||
<shadedPattern>com.onarandombox.buscript</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>com.onarandombox.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.dumptruckman.minecraft.util.Logging</pattern>
|
||||
<shadedPattern>com.onarandombox.MultiverseCore.utils.CoreLogging</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.dumptruckman.minecraft.util.DebugLog</pattern>
|
||||
<shadedPattern>com.onarandombox.MultiverseCore.utils.DebugFileLogger</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.codehaus.jettison</pattern>
|
||||
<shadedPattern>com.onarandombox.jettison</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>de.themoep.idconverter</pattern>
|
||||
<shadedPattern>com.onarandombox.idconverter</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>se.eris</groupId>
|
||||
<artifactId>notnull-instrumenter-maven-plugin</artifactId>
|
||||
<version>0.6.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>instrument</goal>
|
||||
<goal>tests-instrument</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.13.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- SerializationConfig Dependency -->
|
||||
<dependency>
|
||||
<groupId>me.main__.util</groupId>
|
||||
<artifactId>SerializationConfig</artifactId>
|
||||
<version>1.7</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- End of SerializationConfig Dependency -->
|
||||
<!-- Start of Economy Dependency -->
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- End of Economy Dependency -->
|
||||
<!-- Start of CommandHandler Dependency -->
|
||||
<dependency>
|
||||
<groupId>com.pneumaticraft.commandhandler</groupId>
|
||||
<artifactId>CommandHandler</artifactId>
|
||||
<version>11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dumptruckman.minecraft</groupId>
|
||||
<artifactId>buscript</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>1.7</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dumptruckman.minecraft</groupId>
|
||||
<artifactId>Logging</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>16.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.themoep.idconverter</groupId>
|
||||
<artifactId>mappings</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Start of Test Dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<type>jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-easymock</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<type>jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<type>jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>OnARandomBox</id>
|
||||
<url>http://repo.onarandombox.com/content/repositories/multiverse</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>OnARandomBox</id>
|
||||
<url>http://repo.onarandombox.com/content/repositories/multiverse-snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = 'multiverse-core'
|
||||
@@ -214,7 +214,7 @@ public class MVWorld implements MultiverseWorld {
|
||||
public Double validateChange(String property, Double newValue, Double oldValue,
|
||||
MVWorld object) throws ChangeDeniedException {
|
||||
if (newValue <= 0) {
|
||||
plugin.log(Level.FINE, "Someone tried to set a scale <= 0, aborting!");
|
||||
Logging.fine("Someone tried to set a scale <= 0, aborting!");
|
||||
throw new ChangeDeniedException();
|
||||
}
|
||||
return super.validateChange(property, newValue, oldValue, object);
|
||||
@@ -297,7 +297,7 @@ public class MVWorld implements MultiverseWorld {
|
||||
public GameMode validateChange(String property, GameMode newValue, GameMode oldValue,
|
||||
MVWorld object) throws ChangeDeniedException {
|
||||
for (Player p : plugin.getServer().getWorld(getName()).getPlayers()) {
|
||||
plugin.log(Level.FINER, String.format("Setting %s's GameMode to %s",
|
||||
Logging.finer(String.format("Setting %s's GameMode to %s",
|
||||
p.getName(), newValue.toString()));
|
||||
plugin.getPlayerListener().handleGameModeAndFlight(p, MVWorld.this);
|
||||
}
|
||||
@@ -319,16 +319,16 @@ public class MVWorld implements MultiverseWorld {
|
||||
// verify that the location is safe
|
||||
if (!bs.playerCanSpawnHereSafely(newValue)) {
|
||||
// it's not ==> find a better one!
|
||||
plugin.log(Level.WARNING, String.format("Somebody tried to set the spawn location for '%s' to an unsafe value! Adjusting...", getAlias()));
|
||||
plugin.log(Level.WARNING, "Old Location: " + plugin.getLocationManipulation().strCoordsRaw(oldValue));
|
||||
plugin.log(Level.WARNING, "New (unsafe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
|
||||
Logging.warning(String.format("Somebody tried to set the spawn location for '%s' to an unsafe value! Adjusting...", getAlias()));
|
||||
Logging.warning("Old Location: " + plugin.getLocationManipulation().strCoordsRaw(oldValue));
|
||||
Logging.warning("New (unsafe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
|
||||
SafeTTeleporter teleporter = plugin.getSafeTTeleporter();
|
||||
newValue = teleporter.getSafeLocation(newValue, SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
|
||||
if (newValue == null) {
|
||||
plugin.log(Level.WARNING, "Couldn't fix the location. I have to abort the spawn location-change :/");
|
||||
Logging.warning("Couldn't fix the location. I have to abort the spawn location-change :/");
|
||||
throw new ChangeDeniedException();
|
||||
}
|
||||
plugin.log(Level.WARNING, "New (safe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
|
||||
Logging.warning("New (safe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
|
||||
}
|
||||
}
|
||||
return super.validateChange(property, newValue, oldValue, object);
|
||||
@@ -356,7 +356,7 @@ public class MVWorld implements MultiverseWorld {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
return Collections.EMPTY_MAP;
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -411,7 +411,7 @@ public class MVWorld implements MultiverseWorld {
|
||||
// Add limit bypass to it's parent
|
||||
this.limitbypassperm.addParent("mv.bypass.playerlimit.*", true);
|
||||
} catch (IllegalArgumentException e) {
|
||||
this.plugin.log(Level.FINER, "Permissions nodes were already added for " + this.name);
|
||||
Logging.finer("Permissions nodes were already added for " + this.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,16 +422,16 @@ public class MVWorld implements MultiverseWorld {
|
||||
// Verify that location was safe
|
||||
if (!bs.playerCanSpawnHereSafely(location)) {
|
||||
if (!this.getAdjustSpawn()) {
|
||||
this.plugin.log(Level.FINE, "Spawn location from world.dat file was unsafe!!");
|
||||
this.plugin.log(Level.FINE, "NOT adjusting spawn for '" + this.getAlias() + "' because you told me not to.");
|
||||
this.plugin.log(Level.FINE, "To turn on spawn adjustment for this world simply type:");
|
||||
this.plugin.log(Level.FINE, "/mvm set adjustspawn true " + this.getAlias());
|
||||
Logging.fine("Spawn location from world.dat file was unsafe!!");
|
||||
Logging.fine("NOT adjusting spawn for '" + this.getAlias() + "' because you told me not to.");
|
||||
Logging.fine("To turn on spawn adjustment for this world simply type:");
|
||||
Logging.fine("/mvm set adjustspawn true " + this.getAlias());
|
||||
return location;
|
||||
}
|
||||
// If it's not, find a better one.
|
||||
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
|
||||
this.plugin.log(Level.WARNING, "Spawn location from world.dat file was unsafe. Adjusting...");
|
||||
this.plugin.log(Level.WARNING, "Original Location: " + plugin.getLocationManipulation().strCoordsRaw(location));
|
||||
Logging.warning("Spawn location from world.dat file was unsafe. Adjusting...");
|
||||
Logging.warning("Original Location: " + plugin.getLocationManipulation().strCoordsRaw(location));
|
||||
Location newSpawn = teleporter.getSafeLocation(location,
|
||||
SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
|
||||
// I think we could also do this, as I think this is what Notch does.
|
||||
@@ -450,7 +450,7 @@ public class MVWorld implements MultiverseWorld {
|
||||
this.getName(), plugin.getLocationManipulation().locationToString(newerSpawn));
|
||||
return newerSpawn;
|
||||
} else {
|
||||
this.plugin.log(Level.SEVERE, "Safe spawn NOT found!!!");
|
||||
Logging.severe("Safe spawn NOT found!!!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ import com.onarandombox.MultiverseCore.commands.TeleportCommand;
|
||||
import com.onarandombox.MultiverseCore.commands.UnloadCommand;
|
||||
import com.onarandombox.MultiverseCore.commands.VersionCommand;
|
||||
import com.onarandombox.MultiverseCore.commands.WhoCommand;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.CommandQueueManager;
|
||||
import com.onarandombox.MultiverseCore.destination.AnchorDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.BedDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.CannonDestination;
|
||||
@@ -88,6 +89,7 @@ import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
|
||||
import com.onarandombox.MultiverseCore.listeners.MVWorldInitListener;
|
||||
import com.onarandombox.MultiverseCore.listeners.MVWorldListener;
|
||||
import com.onarandombox.MultiverseCore.utils.AnchorManager;
|
||||
import com.onarandombox.MultiverseCore.utils.CompatibilityLayer;
|
||||
import com.onarandombox.MultiverseCore.utils.MVEconomist;
|
||||
import com.onarandombox.MultiverseCore.utils.MVMessaging;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPermissions;
|
||||
@@ -203,6 +205,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
|
||||
// Setup our Map for our Commands using the CommandHandler.
|
||||
private CommandHandler commandHandler;
|
||||
private CommandQueueManager commandQueueManager;
|
||||
|
||||
private static final String LOG_TAG = "[Multiverse-Core]";
|
||||
|
||||
@@ -254,6 +257,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
// Setup our SafeTTeleporter
|
||||
this.safeTTeleporter = new SimpleSafeTTeleporter(this);
|
||||
this.unsafeCallWrapper = new UnsafeCallWrapper(this);
|
||||
// Setup our CompatibilityLayer
|
||||
CompatibilityLayer.init();
|
||||
}
|
||||
|
||||
|
||||
@@ -285,6 +290,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
|
||||
// Setup the command manager
|
||||
this.commandHandler = new CommandHandler(this, this.ph);
|
||||
this.commandQueueManager = new CommandQueueManager(this);
|
||||
// Call the Function to assign all the Commands to their Class.
|
||||
this.registerCommands();
|
||||
|
||||
@@ -306,7 +312,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
this.worldManager.loadDefaultWorlds();
|
||||
this.worldManager.loadWorlds(true);
|
||||
} else {
|
||||
this.log(Level.SEVERE, "Your configs were not loaded. Very little will function in Multiverse.");
|
||||
Logging.severe("Your configs were not loaded. Very little will function in Multiverse.");
|
||||
}
|
||||
this.anchorManager.loadAnchors();
|
||||
|
||||
@@ -353,13 +359,18 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
* Initializes the buscript javascript library.
|
||||
*/
|
||||
private void initializeBuscript() {
|
||||
try {
|
||||
buscript = new Buscript(this);
|
||||
// Add global variable "multiverse" to javascript environment
|
||||
buscript.setScriptVariable("multiverse", this);
|
||||
} catch (NullPointerException e) {
|
||||
buscript = null;
|
||||
Logging.warning("Buscript failed to load! The script command will be disabled!");
|
||||
buscript = null;
|
||||
|
||||
if (this.getMVConfig().getEnableBuscript()) {
|
||||
try {
|
||||
buscript = new Buscript(this);
|
||||
// Add global variable "multiverse" to javascript environment
|
||||
buscript.setScriptVariable("multiverse", this);
|
||||
} catch (NullPointerException e) {
|
||||
Logging.warning("Buscript failed to load! The script command will be disabled! " +
|
||||
"If you would like not to see this message, " +
|
||||
"use `/mv conf enablebuscript false` to disable Buscript from loading.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +394,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
pm.registerEvents(this.entityListener, this);
|
||||
pm.registerEvents(this.weatherListener, this);
|
||||
pm.registerEvents(this.portalListener, this);
|
||||
log(Level.INFO, ChatColor.GREEN + "We are aware of the warning about the deprecated event. There is no alternative that allows us to do what we need to do and performance impact is negligible. It is safe to ignore.");
|
||||
Logging.info(ChatColor.GREEN + "We are aware of the warning about the deprecated event. There is no alternative that allows us to do what we need to do and performance impact is negligible. It is safe to ignore.");
|
||||
pm.registerEvents(this.worldListener, this);
|
||||
pm.registerEvents(new MVMapListener(this), this);
|
||||
}
|
||||
@@ -502,13 +513,13 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
try {
|
||||
wconf.load(worldsFile);
|
||||
} catch (IOException e) {
|
||||
log(Level.WARNING, "Cannot load worlds.yml");
|
||||
Logging.warning("Cannot load worlds.yml");
|
||||
} catch (InvalidConfigurationException e) {
|
||||
log(Level.WARNING, "Your worlds.yml is invalid!");
|
||||
Logging.warning("Your worlds.yml is invalid!");
|
||||
}
|
||||
|
||||
if (!wconf.isConfigurationSection("worlds")) { // empty config
|
||||
this.log(Level.FINE, "No worlds to migrate!");
|
||||
Logging.fine("No worlds to migrate!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -521,9 +532,9 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
// fine
|
||||
newValues.put(entry.getKey(), entry.getValue());
|
||||
} else if (entry.getValue() instanceof ConfigurationSection) {
|
||||
this.log(Level.FINE, "Migrating: " + entry.getKey());
|
||||
Logging.fine("Migrating: " + entry.getKey());
|
||||
// we have to migrate this
|
||||
WorldProperties world = new WorldProperties(Collections.EMPTY_MAP);
|
||||
WorldProperties world = new WorldProperties(Collections.emptyMap());
|
||||
ConfigurationSection section = (ConfigurationSection) entry.getValue();
|
||||
|
||||
// migrate animals and monsters
|
||||
@@ -687,8 +698,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
try {
|
||||
difficulty = Difficulty.valueOf(section.getString("difficulty").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
this.log(Level.WARNING, "Could not parse difficulty: " + section.getString("difficulty"));
|
||||
this.log(Level.WARNING, "Setting world " + entry.getKey() + " difficulty to NORMAL");
|
||||
Logging.warning("Could not parse difficulty: " + section.getString("difficulty"));
|
||||
Logging.warning("Setting world " + entry.getKey() + " difficulty to NORMAL");
|
||||
difficulty = Difficulty.NORMAL;
|
||||
}
|
||||
if (difficulty != null) {
|
||||
@@ -705,7 +716,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
wasChanged = true;
|
||||
} else {
|
||||
// huh?
|
||||
this.log(Level.WARNING, "Removing unknown entry in the config: " + entry);
|
||||
Logging.warning("Removing unknown entry in the config: " + entry);
|
||||
// just don't add to newValues
|
||||
wasChanged = true;
|
||||
}
|
||||
@@ -839,8 +850,12 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated This is now deprecated, nobody needs it any longer.
|
||||
* All logging is now done with {@link Logging}.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void log(Level level, String msg) {
|
||||
Logging.log(level, msg);
|
||||
}
|
||||
@@ -907,6 +922,15 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
return this.commandHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public CommandQueueManager getCommandQueueManager() {
|
||||
return commandQueueManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the log-tag.
|
||||
*
|
||||
@@ -1059,7 +1083,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
this.multiverseConfig.save(new File(getDataFolder(), "config.yml"));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
this.log(Level.SEVERE, "Could not save Multiverse config.yml config. Please check your file permissions.");
|
||||
Logging.severe("Could not save Multiverse config.yml config. Please check your file permissions.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1107,12 +1131,22 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @deprecated This is deprecated!
|
||||
* @deprecated This is deprecated! Do not use!
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed) {
|
||||
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed);
|
||||
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @deprecated This is deprecated! Do not use!
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed, Boolean keepGameRules) {
|
||||
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed, keepGameRules);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -56,6 +56,8 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
@Property
|
||||
private volatile boolean displaypermerrors;
|
||||
@Property
|
||||
private volatile boolean enablebuscript;
|
||||
@Property
|
||||
private volatile int globaldebug;
|
||||
@Property
|
||||
private volatile boolean silentstart;
|
||||
@@ -94,17 +96,18 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
|
||||
enforceaccess = false;
|
||||
useasyncchat = true;
|
||||
prefixchat = true;
|
||||
prefixchat = false;
|
||||
prefixchatformat = "[%world%]%chat%";
|
||||
teleportintercept = true;
|
||||
firstspawnoverride = true;
|
||||
displaypermerrors = true;
|
||||
enablebuscript = true;
|
||||
globaldebug = 0;
|
||||
messagecooldown = 5000;
|
||||
teleportcooldown = 1000;
|
||||
this.version = 2.9;
|
||||
silentstart = false;
|
||||
defaultportalsearch = false;
|
||||
defaultportalsearch = true;
|
||||
portalsearchradius = 128;
|
||||
autopurge = true;
|
||||
idonotwanttodonate = false;
|
||||
@@ -213,6 +216,22 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
return this.displaypermerrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean getEnableBuscript() {
|
||||
return this.enablebuscript;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setEnableBuscript(boolean enableBuscript) {
|
||||
this.enablebuscript = enableBuscript;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package com.onarandombox.MultiverseCore.api;
|
||||
|
||||
import buscript.Buscript;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.CommandQueueManager;
|
||||
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.AnchorManager;
|
||||
import com.onarandombox.MultiverseCore.utils.MVEconomist;
|
||||
@@ -86,6 +87,15 @@ public interface Core {
|
||||
*/
|
||||
CommandHandler getCommandHandler();
|
||||
|
||||
/**
|
||||
* Manager for command that requires /mv confirm before execution.
|
||||
*
|
||||
* @return A non-null {@link CommandQueueManager}.
|
||||
* @deprecated To be moved to new command manager in 5.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
CommandQueueManager getCommandQueueManager();
|
||||
|
||||
/**
|
||||
* Gets the factory class responsible for loading many different destinations
|
||||
* on demand.
|
||||
@@ -116,20 +126,38 @@ public interface Core {
|
||||
AnchorManager getAnchorManager();
|
||||
|
||||
/**
|
||||
* Used by queued commands to regenerate a world on a delay.
|
||||
* Previously used by queued commands to regenerate a world on a delay.
|
||||
* Do not use api method for any other purpose.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed IF the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*
|
||||
* @deprecated Use {@link MVWorldManager#regenWorld(String, boolean, boolean, String)} instead.
|
||||
* @deprecated Use {@link MVWorldManager#regenWorld(String, boolean, boolean, String, boolean)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed);
|
||||
|
||||
/**
|
||||
* Used by queued commands to regenerate a world on a delay.
|
||||
* Do not use api method for any other purpose.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param keepGameRules If GameRules should be kept on world regen.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*
|
||||
* @deprecated Use {@link MVWorldManager#regenWorld(String, boolean, boolean, String, boolean)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed, Boolean keepGameRules);
|
||||
|
||||
/**
|
||||
* Decrements the number of plugins that have specifically hooked into core.
|
||||
*/
|
||||
|
||||
@@ -7,11 +7,17 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.api;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
/** A simple API to require plugins to have a log method. */
|
||||
/**
|
||||
* A simple API to require plugins to have a log method.
|
||||
*
|
||||
* @deprecated Replaced by {@link Logging}.
|
||||
* */
|
||||
@Deprecated
|
||||
public interface LoggablePlugin {
|
||||
/**
|
||||
* Logs a message at the specified level.
|
||||
|
||||
@@ -174,6 +174,16 @@ public interface MVWorldManager {
|
||||
*/
|
||||
MultiverseWorld getMVWorld(String name);
|
||||
|
||||
/**
|
||||
* Returns a {@link MultiverseWorld} if the world with name given exists, and null if it does not.
|
||||
* This will search optionally for alias names.
|
||||
*
|
||||
* @param name The name or optionally the alias of the world to get.
|
||||
* @param checkAliases Indicates whether to check for world alias name.
|
||||
* @return A {@link MultiverseWorld} or null.
|
||||
*/
|
||||
MultiverseWorld getMVWorld(String name, boolean checkAliases);
|
||||
|
||||
/**
|
||||
* Returns a {@link MultiverseWorld} if it exists, and null if it does not.
|
||||
*
|
||||
@@ -183,13 +193,24 @@ public interface MVWorldManager {
|
||||
MultiverseWorld getMVWorld(World world);
|
||||
|
||||
/**
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}.
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}
|
||||
* Searches based on world name AND alias.
|
||||
*
|
||||
* @param name The name or alias of the world to check.
|
||||
* @return True if the world exists, false if not.
|
||||
*/
|
||||
boolean isMVWorld(String name);
|
||||
|
||||
/**
|
||||
* Checks to see if the given name is a valid {@link MultiverseWorld}.
|
||||
* Optionally searches by alias is specified.
|
||||
*
|
||||
* @param name The name or alias of the world to check.
|
||||
* @param checkAliases Indicates whether to check for world alias name.
|
||||
* @return True if the world exists, false if not.
|
||||
*/
|
||||
boolean isMVWorld(String name, boolean checkAliases);
|
||||
|
||||
/**
|
||||
* Checks to see if the given world is a valid {@link MultiverseWorld}.
|
||||
*
|
||||
@@ -292,15 +313,28 @@ public interface MVWorldManager {
|
||||
/**
|
||||
* Regenerates a world.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed IF the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*/
|
||||
boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed);
|
||||
|
||||
/**
|
||||
* Regenerates a world.
|
||||
*
|
||||
* @param name Name of the world to regenerate
|
||||
* @param useNewSeed If a new seed should be used
|
||||
* @param randomSeed If the new seed should be random
|
||||
* @param seed The seed of the world.
|
||||
* @param keepGameRules If GameRules should be kept on world regen.
|
||||
*
|
||||
* @return True if success, false if fail.
|
||||
*/
|
||||
boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed, boolean keepGameRules);
|
||||
|
||||
boolean isKeepingSpawnInMemory(World world);
|
||||
|
||||
/**
|
||||
@@ -314,4 +348,11 @@ public interface MVWorldManager {
|
||||
* does not exist. {@code includeLoaded} if the world exists and is loaded.
|
||||
*/
|
||||
boolean hasUnloadedWorld(String name, boolean includeLoaded);
|
||||
|
||||
/**
|
||||
* Get all the possible worlds that Multiverse has detected to be importable.
|
||||
*
|
||||
* @return A collection of world names that are deemed importable.
|
||||
*/
|
||||
Collection<String> getPotentialWorlds();
|
||||
}
|
||||
@@ -86,6 +86,18 @@ public interface MultiverseCoreConfig extends ConfigurationSerializable {
|
||||
*/
|
||||
boolean getDisplayPermErrors();
|
||||
|
||||
/**
|
||||
* Sets enableBuscript.
|
||||
* @param enableBuscript The new value.
|
||||
*/
|
||||
void setEnableBuscript(boolean enableBuscript);
|
||||
|
||||
/**
|
||||
* Gets enableBuscript.
|
||||
* @return enableBuscript.
|
||||
*/
|
||||
boolean getEnableBuscript();
|
||||
|
||||
/**
|
||||
* Sets firstSpawnOverride.
|
||||
* @param firstSpawnOverride The new value.
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPermissions;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -37,7 +38,7 @@ public class CheckCommand extends MultiverseCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
Player p = this.plugin.getServer().getPlayer(args.get(0));
|
||||
Player p = PlayerFinder.get(args.get(0), sender);
|
||||
if (p == null) {
|
||||
sender.sendMessage("Could not find player " + ChatColor.GREEN + args.get(0));
|
||||
sender.sendMessage("Are they online?");
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ConfirmCommand extends MultiverseCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
this.plugin.getCommandHandler().confirmQueuedCommand(sender);
|
||||
this.plugin.getCommandQueueManager().runQueuedCommand(sender);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,10 +46,15 @@ public class CreateCommand extends MultiverseCommand {
|
||||
this.addCommandExample("/mv create " + ChatColor.GOLD + "moonworld" + ChatColor.GREEN + " normal" + ChatColor.DARK_AQUA + " -g BukkitFullOfMoon");
|
||||
this.worldManager = this.plugin.getMVWorldManager();
|
||||
}
|
||||
|
||||
|
||||
private String trimWorldName(String userInput) {
|
||||
// Removes relative paths.
|
||||
return userInput.replaceAll("^[./\\\\]+", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
String worldName = args.get(0);
|
||||
String worldName = trimWorldName(args.get(0));
|
||||
File worldFile = new File(this.plugin.getServer().getWorldContainer(), worldName);
|
||||
String env = args.get(1);
|
||||
String seed = CommandHandler.getFlag("-s", args);
|
||||
@@ -66,7 +71,13 @@ public class CreateCommand extends MultiverseCommand {
|
||||
useSpawnAdjust = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make sure the world name doesn't contain the words 'plugins' and '.dat'
|
||||
if(worldName.contains("plugins")||worldName.contains(".dat")){
|
||||
sender.sendMessage(ChatColor.RED + "Multiverse cannot create a world that contains 'plugins' or '.dat'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.worldManager.isMVWorld(worldName)) {
|
||||
sender.sendMessage(ChatColor.RED + "Multiverse cannot create " + ChatColor.GOLD + ChatColor.UNDERLINE
|
||||
+ "another" + ChatColor.RESET + ChatColor.RED + " world named " + worldName);
|
||||
@@ -117,4 +128,4 @@ public class CreateCommand extends MultiverseCommand {
|
||||
Command.broadcastCommandMessage(sender, "FAILED.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -60,7 +61,7 @@ public class DebugCommand extends MultiverseCommand {
|
||||
sender.sendMessage("Multiverse Debug mode is " + ChatColor.RED + "OFF");
|
||||
} else {
|
||||
sender.sendMessage("Multiverse Debug mode is " + ChatColor.GREEN + debugLevel);
|
||||
this.plugin.log(Level.FINE, "Multiverse Debug ENABLED");
|
||||
Logging.fine("Multiverse Debug ENABLED");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,11 @@
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -35,11 +37,24 @@ public class DeleteCommand extends MultiverseCommand {
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
String worldName = args.get(0);
|
||||
|
||||
Class<?>[] paramTypes = {String.class};
|
||||
List<Object> objectArgs = new ArrayList<Object>(args);
|
||||
this.plugin.getCommandHandler()
|
||||
.queueCommand(sender, "mvdelete", "deleteWorld", objectArgs,
|
||||
paramTypes, ChatColor.GREEN + "World '" + worldName + "' Deleted!",
|
||||
ChatColor.RED + "World '" + worldName + "' could NOT be deleted!");
|
||||
this.plugin.getCommandQueueManager().addToQueue(new QueuedCommand(
|
||||
sender,
|
||||
deleteRunnable(sender, worldName),
|
||||
String.format("Are you sure you want to delete world '%s'? You cannot undo this action.", worldName)
|
||||
));
|
||||
}
|
||||
|
||||
private Runnable deleteRunnable(@NotNull CommandSender sender,
|
||||
@NotNull String worldName) {
|
||||
|
||||
return () -> {
|
||||
sender.sendMessage(String.format("Deleting world '%s'...", worldName));
|
||||
if (this.plugin.getMVWorldManager().deleteWorld(worldName)) {
|
||||
sender.sendMessage(String.format("%sWorld %s was deleted!", ChatColor.GREEN, worldName));
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(String.format("%sThere was an issue deleting '%s'! Please check console for errors.",
|
||||
ChatColor.RED, worldName));
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,9 @@
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.display.ColorAlternator;
|
||||
import com.onarandombox.MultiverseCore.display.ContentDisplay;
|
||||
import com.onarandombox.MultiverseCore.display.settings.MapDisplaySettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameRule;
|
||||
@@ -16,7 +19,9 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Allows management of Anchor Destinations.
|
||||
@@ -68,15 +73,23 @@ public class GamerulesCommand extends MultiverseCommand {
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder gameRules = new StringBuilder();
|
||||
for (final String gameRule : world.getGameRules()) {
|
||||
if (gameRules.length() != 0) {
|
||||
gameRules.append(ChatColor.WHITE).append(", ");
|
||||
ContentDisplay.forContent(getGameRuleMap(world))
|
||||
.header("=== Gamerules for %s%s%s ===", ChatColor.AQUA, world.getName(), ChatColor.WHITE)
|
||||
.colorTool(ColorAlternator.with(ChatColor.GREEN, ChatColor.GOLD))
|
||||
.setting(MapDisplaySettings.OPERATOR, ": ")
|
||||
.show(sender);
|
||||
}
|
||||
|
||||
private Map<String, Object> getGameRuleMap(World world) {
|
||||
Map<String, Object> gameRuleMap = new HashMap<>();
|
||||
for (GameRule<?> rule : GameRule.values()) {
|
||||
Object value = world.getGameRuleValue(rule);
|
||||
if (value == null) {
|
||||
gameRuleMap.put(rule.getName(), "null");
|
||||
continue;
|
||||
}
|
||||
gameRules.append(ChatColor.AQUA).append(gameRule).append(ChatColor.WHITE).append(": ");
|
||||
gameRules.append(ChatColor.GREEN).append(world.getGameRuleValue(GameRule.getByName(gameRule)));
|
||||
gameRuleMap.put(rule.getName(), value);
|
||||
}
|
||||
sender.sendMessage("=== Gamerules for " + ChatColor.AQUA + world.getName() + ChatColor.WHITE + " ===");
|
||||
sender.sendMessage(gameRules.toString());
|
||||
return gameRuleMap;
|
||||
}
|
||||
}
|
||||
@@ -40,24 +40,16 @@ public class HelpCommand extends PaginatedCoreCommand<Command> {
|
||||
|
||||
@Override
|
||||
protected List<Command> getFilteredItems(List<Command> availableItems, String filter) {
|
||||
String expression = "(?i).*" + cleanFilter(filter) + ".*";
|
||||
List<Command> filtered = new ArrayList<Command>();
|
||||
|
||||
for (Command c : availableItems) {
|
||||
if (stitchThisString(c.getKeyStrings()).matches("(?i).*" + filter + ".*")) {
|
||||
if (stitchThisString(c.getKeyStrings()).matches(expression)
|
||||
|| c.getCommandName().matches(expression)
|
||||
|| c.getCommandDesc().matches(expression)
|
||||
|| c.getCommandUsage().matches(expression)
|
||||
|| c.getCommandExamples().stream().anyMatch(eg -> eg.matches(expression))) {
|
||||
filtered.add(c);
|
||||
} else if (c.getCommandName().matches("(?i).*" + filter + ".*")) {
|
||||
filtered.add(c);
|
||||
} else if (c.getCommandDesc().matches("(?i).*" + filter + ".*")) {
|
||||
filtered.add(c);
|
||||
} else if (c.getCommandUsage().matches("(?i).*" + filter + ".*")) {
|
||||
filtered.add(c);
|
||||
} else {
|
||||
for (String example : c.getCommandExamples()) {
|
||||
if (example.matches("(?i).*" + filter + ".*")) {
|
||||
filtered.add(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
|
||||
@@ -9,7 +9,7 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.utils.WorldNameChecker;
|
||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World.Environment;
|
||||
@@ -18,8 +18,6 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -45,55 +43,17 @@ public class ImportCommand extends MultiverseCommand {
|
||||
this.worldManager = this.plugin.getMVWorldManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* A very basic check to see if a folder has a level.dat file.
|
||||
* If it does, we can safely assume it's a world folder.
|
||||
*
|
||||
* @param worldFolder The File that may be a world.
|
||||
* @return True if it looks like a world, false if not.
|
||||
*/
|
||||
private static boolean checkIfIsWorld(File worldFolder) {
|
||||
if (worldFolder.isDirectory()) {
|
||||
File[] files = worldFolder.listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File file, String name) {
|
||||
return name.toLowerCase().endsWith(".dat");
|
||||
}
|
||||
});
|
||||
if (files != null && files.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getPotentialWorlds() {
|
||||
File worldFolder = this.plugin.getServer().getWorldContainer();
|
||||
if (worldFolder == null) {
|
||||
return "";
|
||||
}
|
||||
File[] files = worldFolder.listFiles();
|
||||
String worldList = "";
|
||||
Collection<MultiverseWorld> worlds = this.worldManager.getMVWorlds();
|
||||
List<String> worldStrings = new ArrayList<String>();
|
||||
for (MultiverseWorld world : worlds) {
|
||||
worldStrings.add(world.getName());
|
||||
}
|
||||
for (String world : this.worldManager.getUnloadedWorlds()) {
|
||||
worldStrings.add(world);
|
||||
}
|
||||
private String getPotentialWorldStrings() {
|
||||
final Collection<String> potentialWorlds = this.worldManager.getPotentialWorlds();
|
||||
StringBuilder worldList = new StringBuilder();
|
||||
ChatColor currColor = ChatColor.WHITE;
|
||||
for (File file : files) {
|
||||
if (file.isDirectory() && checkIfIsWorld(file) && !worldStrings.contains(file.getName())) {
|
||||
worldList += currColor + file.getName() + " ";
|
||||
if (currColor == ChatColor.WHITE) {
|
||||
currColor = ChatColor.YELLOW;
|
||||
} else {
|
||||
currColor = ChatColor.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
for (String world : potentialWorlds) {
|
||||
worldList.append(currColor).append(world).append(' ');
|
||||
currColor = currColor == ChatColor.WHITE ? ChatColor.YELLOW : ChatColor.WHITE;
|
||||
}
|
||||
return worldList;
|
||||
|
||||
return worldList.toString();
|
||||
}
|
||||
|
||||
private String trimWorldName(String userInput) {
|
||||
@@ -106,7 +66,7 @@ public class ImportCommand extends MultiverseCommand {
|
||||
String worldName = trimWorldName(args.get(0));
|
||||
|
||||
if (worldName.toLowerCase().equals("--list") || worldName.toLowerCase().equals("-l")) {
|
||||
String worldList = this.getPotentialWorlds();
|
||||
String worldList = this.getPotentialWorldStrings();
|
||||
if (worldList.length() > 2) {
|
||||
sender.sendMessage(ChatColor.AQUA + "====[ These look like worlds ]====");
|
||||
sender.sendMessage(worldList);
|
||||
@@ -121,6 +81,12 @@ public class ImportCommand extends MultiverseCommand {
|
||||
this.showHelp(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the world name doesn't contain the words 'plugins' and '.dat'
|
||||
if(worldName.contains("plugins")||worldName.contains(".dat")){
|
||||
sender.sendMessage(ChatColor.RED + "Multiverse cannot create a world that contains 'plugins' or '.dat'");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we don't already know about this world.
|
||||
if (this.worldManager.isMVWorld(worldName)) {
|
||||
@@ -149,10 +115,10 @@ public class ImportCommand extends MultiverseCommand {
|
||||
|
||||
if (!worldFile.exists()) {
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
String worldList = this.getPotentialWorlds();
|
||||
String worldList = this.getPotentialWorldStrings();
|
||||
sender.sendMessage("That world folder does not exist. These look like worlds to me:");
|
||||
sender.sendMessage(worldList);
|
||||
} else if (!checkIfIsWorld(worldFile)) {
|
||||
} else if (!WorldNameChecker.isValidWorldFolder(worldFile)) {
|
||||
sender.sendMessage(ChatColor.RED + "FAILED.");
|
||||
sender.sendMessage(String.format("'%s' does not appear to be a world. It is lacking a .dat file.",
|
||||
worldName));
|
||||
@@ -168,4 +134,4 @@ public class ImportCommand extends MultiverseCommand {
|
||||
Command.broadcastCommandMessage(sender, ChatColor.RED + "Failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,6 +115,7 @@ public class InfoCommand extends MultiverseCommand {
|
||||
FancyColorScheme colors = new FancyColorScheme(ChatColor.AQUA, ChatColor.AQUA, ChatColor.GOLD, ChatColor.WHITE);
|
||||
message.add(new FancyHeader("General Info", colors));
|
||||
message.add(new FancyMessage("World Name: ", world.getName(), colors));
|
||||
message.add(new FancyMessage("World UID: ", world.getCBWorld().getUID().toString(), colors));
|
||||
message.add(new FancyMessage("World Alias: ", world.getColoredWorldString(), colors));
|
||||
message.add(new FancyMessage("Game Mode: ", world.getGameMode().toString(), colors));
|
||||
message.add(new FancyMessage("Difficulty: ", world.getDifficulty().toString(), colors));
|
||||
@@ -151,6 +152,7 @@ public class InfoCommand extends MultiverseCommand {
|
||||
message = new ArrayList<FancyText>();
|
||||
message.add(new FancyHeader("More World Settings", colors));
|
||||
message.add(new FancyMessage("World Type: ", world.getWorldType().toString(), colors));
|
||||
message.add(new FancyMessage("Generator: ", world.getGenerator(), colors));
|
||||
message.add(new FancyMessage("Structures: ", world.getCBWorld().canGenerateStructures() + "", colors));
|
||||
message.add(new FancyMessage("Weather: ", world.isWeatherEnabled() + "", colors));
|
||||
message.add(new FancyMessage("Players will get hungry: ", world.getHunger() + "", colors));
|
||||
|
||||
@@ -9,122 +9,111 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.display.ColorAlternator;
|
||||
import com.onarandombox.MultiverseCore.display.ContentDisplay;
|
||||
import com.onarandombox.MultiverseCore.display.ContentFilter;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayHandlers;
|
||||
import com.onarandombox.MultiverseCore.display.settings.PagedDisplaySettings;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Displays a listing of all worlds that a player can enter.
|
||||
*/
|
||||
public class ListCommand extends PaginatedCoreCommand<String> {
|
||||
public class ListCommand extends MultiverseCommand {
|
||||
|
||||
public ListCommand(MultiverseCore plugin) {
|
||||
super(plugin);
|
||||
this.setName("World Listing");
|
||||
this.setCommandUsage("/mv list [page]");
|
||||
this.setCommandUsage("/mv list [filter] [page]");
|
||||
this.setArgRange(0, 2);
|
||||
this.addKey("mvlist");
|
||||
this.addKey("mvl");
|
||||
this.addKey("mv list");
|
||||
this.setPermission("multiverse.core.list.worlds", "Displays a listing of all worlds that you can enter.", PermissionDefault.OP);
|
||||
this.setItemsPerPage(8); // SUPPRESS CHECKSTYLE: MagicNumberCheck
|
||||
}
|
||||
|
||||
private List<String> getFancyWorldList(Player p) {
|
||||
List<String> worldList = new ArrayList<String>();
|
||||
for (MultiverseWorld world : this.plugin.getMVWorldManager().getMVWorlds()) {
|
||||
|
||||
if (p != null && (!this.plugin.getMVPerms().canEnterWorld(p, world))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ChatColor color = ChatColor.GOLD;
|
||||
Environment env = world.getEnvironment();
|
||||
if (env == Environment.NETHER) {
|
||||
color = ChatColor.RED;
|
||||
} else if (env == Environment.NORMAL) {
|
||||
color = ChatColor.GREEN;
|
||||
} else if (env == Environment.THE_END) {
|
||||
color = ChatColor.AQUA;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(world.getColoredWorldString()).append(ChatColor.WHITE);
|
||||
builder.append(" - ").append(color).append(world.getEnvironment());
|
||||
if (world.isHidden()) {
|
||||
if (p == null || this.plugin.getMVPerms().hasPermission(p, "multiverse.core.modify", true)) {
|
||||
// Prefix hidden worlds with an "[H]"
|
||||
worldList.add(ChatColor.GRAY + "[H]" + builder.toString());
|
||||
}
|
||||
} else {
|
||||
worldList.add(builder.toString());
|
||||
}
|
||||
}
|
||||
for (String name : this.plugin.getMVWorldManager().getUnloadedWorlds()) {
|
||||
if (p == null || this.plugin.getMVPerms().hasPermission(p, "multiverse.access." + name, true)) {
|
||||
worldList.add(ChatColor.GRAY + name + " - UNLOADED");
|
||||
}
|
||||
}
|
||||
return worldList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getFilteredItems(List<String> availableItems, String filter) {
|
||||
List<String> filtered = new ArrayList<String>();
|
||||
|
||||
for (String s : availableItems) {
|
||||
if (s.matches("(?i).*" + filter + ".*")) {
|
||||
filtered.add(s);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getItemText(String item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
sender.sendMessage(ChatColor.LIGHT_PURPLE + "====[ Multiverse World List ]====");
|
||||
Player p = null;
|
||||
if (sender instanceof Player) {
|
||||
p = (Player) sender;
|
||||
}
|
||||
ContentFilter filter = ContentFilter.DEFAULT;
|
||||
int page = 1;
|
||||
|
||||
|
||||
FilterObject filterObject = this.getPageAndFilter(args);
|
||||
|
||||
List<String> availableWorlds = new ArrayList<String>(this.getFancyWorldList(p));
|
||||
if (filterObject.getFilter().length() > 0) {
|
||||
availableWorlds = this.getFilteredItems(availableWorlds, filterObject.getFilter());
|
||||
if (availableWorlds.size() == 0) {
|
||||
sender.sendMessage(ChatColor.RED + "Sorry... " + ChatColor.WHITE
|
||||
+ "No worlds matched your filter: " + ChatColor.AQUA + filterObject.getFilter());
|
||||
return;
|
||||
// Either page or filter.
|
||||
if (args.size() == 1) {
|
||||
try {
|
||||
page = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignore) {
|
||||
filter = new ContentFilter(args.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(sender instanceof Player)) {
|
||||
for (String c : availableWorlds) {
|
||||
sender.sendMessage(c);
|
||||
// Filter then page.
|
||||
if (args.size() == 2) {
|
||||
filter = new ContentFilter(args.get(0));
|
||||
try {
|
||||
page = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignore) {
|
||||
sender.sendMessage(ChatColor.RED + args.get(1) + " is not valid number!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int totalPages = (int) Math.ceil(availableWorlds.size() / (this.itemsPerPage + 0.0));
|
||||
ContentDisplay.forContent(getListContents(sender))
|
||||
.header("%s====[ Multiverse World List ]====", ChatColor.GOLD)
|
||||
.displayHandler(DisplayHandlers.PAGE_LIST)
|
||||
.colorTool(ColorAlternator.with(ChatColor.AQUA, ChatColor.GOLD))
|
||||
.filter(filter)
|
||||
.setting(PagedDisplaySettings.SHOW_PAGE, page)
|
||||
.show(sender);
|
||||
}
|
||||
|
||||
if (filterObject.getPage() > totalPages) {
|
||||
filterObject.setPage(totalPages);
|
||||
private Collection<String> getListContents(@NotNull CommandSender sender) {
|
||||
Player player = (sender instanceof Player) ? (Player) sender : null;
|
||||
|
||||
List<String> worldList = this.plugin.getMVWorldManager().getMVWorlds().stream()
|
||||
.filter(world -> player == null || plugin.getMVPerms().canEnterWorld(player, world))
|
||||
.filter(world -> canSeeWorld(player, world))
|
||||
.map(world -> hiddenText(world) + world.getColoredWorldString() + " - " + parseColouredEnvironment(world.getEnvironment()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
this.plugin.getMVWorldManager().getUnloadedWorlds().stream()
|
||||
.filter(world -> plugin.getMVPerms().hasPermission(sender, "multiverse.access." + world, true))
|
||||
.map(world -> ChatColor.GRAY + world + " - UNLOADED")
|
||||
.forEach(worldList::add);
|
||||
|
||||
return worldList;
|
||||
}
|
||||
|
||||
private boolean canSeeWorld(Player player, MultiverseWorld world) {
|
||||
return !world.isHidden()
|
||||
|| player == null
|
||||
|| this.plugin.getMVPerms().hasPermission(player, "multiverse.core.modify", true);
|
||||
}
|
||||
|
||||
private String hiddenText(MultiverseWorld world) {
|
||||
return (world.isHidden()) ? String.format("%s[H] ", ChatColor.GRAY) : "";
|
||||
}
|
||||
|
||||
private String parseColouredEnvironment(World.Environment env) {
|
||||
ChatColor color = ChatColor.GOLD;
|
||||
switch (env) {
|
||||
case NETHER:
|
||||
color = ChatColor.RED;
|
||||
break;
|
||||
case NORMAL:
|
||||
color = ChatColor.GREEN;
|
||||
break;
|
||||
case THE_END:
|
||||
color = ChatColor.AQUA;
|
||||
break;
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.AQUA + " Page " + filterObject.getPage() + " of " + totalPages);
|
||||
|
||||
this.showPage(filterObject.getPage(), sender, availableWorlds);
|
||||
return color + env.toString();
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,14 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A generic paginated command.
|
||||
* @param <T> The type of items on the page.
|
||||
*/
|
||||
public abstract class PaginatedCommand<T> extends Command {
|
||||
private final Pattern REGEX_SPECIAL_CHARS = Pattern.compile("[.+*?\\[^\\]$(){}=!<>|:-\\\\]");
|
||||
private static final int DEFAULT_ITEMS_PER_PAGE = 9;
|
||||
/**
|
||||
* The number of items per page.
|
||||
@@ -40,12 +42,23 @@ public abstract class PaginatedCommand<T> extends Command {
|
||||
|
||||
/**
|
||||
* Gets filtered items.
|
||||
*
|
||||
* @param availableItems All available items.
|
||||
* @param filter The filter-{@link String}.
|
||||
* @return A list of items that match the filter.
|
||||
*/
|
||||
protected abstract List<T> getFilteredItems(List<T> availableItems, String filter);
|
||||
|
||||
/**
|
||||
* Escape regex special characters from filter
|
||||
*
|
||||
* @param filter The filter-{@link String}.
|
||||
* @return String with regex characters escaped
|
||||
*/
|
||||
protected String cleanFilter(String filter) {
|
||||
return REGEX_SPECIAL_CHARS.matcher(filter).replaceAll("\\\\$0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a single string from a list of strings.
|
||||
*
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
|
||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -23,8 +25,8 @@ public class RegenCommand extends MultiverseCommand {
|
||||
public RegenCommand(MultiverseCore plugin) {
|
||||
super(plugin);
|
||||
this.setName("Regenerates a World");
|
||||
this.setCommandUsage("/mv regen" + ChatColor.GREEN + " {WORLD}" + ChatColor.GOLD + " [-s [SEED]]");
|
||||
this.setArgRange(1, 3);
|
||||
this.setCommandUsage("/mv regen" + ChatColor.GREEN + " {WORLD}" + ChatColor.GOLD + " [-s [SEED]] [--keep-gamerules]");
|
||||
this.setArgRange(1, 4);
|
||||
this.addKey("mvregen");
|
||||
this.addKey("mv regen");
|
||||
this.addCommandExample("You can use the -s with no args to get a new seed:");
|
||||
@@ -37,17 +39,34 @@ public class RegenCommand extends MultiverseCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
Boolean useseed = (!(args.size() == 1));
|
||||
Boolean randomseed = (args.size() == 2 && args.get(1).equalsIgnoreCase("-s"));
|
||||
String seed = (args.size() == 3) ? args.get(2) : "";
|
||||
String worldName = args.get(0);
|
||||
boolean useseed = CommandHandler.hasFlag("-s", args);
|
||||
String seedflag = CommandHandler.getFlag("-s", args);
|
||||
boolean keepGamerules = CommandHandler.hasFlag("--keep-gamerules", args);
|
||||
|
||||
Class<?>[] paramTypes = {String.class, Boolean.class, Boolean.class, String.class};
|
||||
List<Object> objectArgs = new ArrayList<Object>();
|
||||
objectArgs.add(args.get(0));
|
||||
objectArgs.add(useseed);
|
||||
objectArgs.add(randomseed);
|
||||
objectArgs.add(seed);
|
||||
this.plugin.getCommandHandler().queueCommand(sender, "mvregen", "regenWorld", objectArgs,
|
||||
paramTypes, ChatColor.GREEN + "World Regenerated!", ChatColor.RED + "World could NOT be regenerated!");
|
||||
boolean randomseed = seedflag == null || seedflag.isEmpty() || seedflag.equalsIgnoreCase("--keep-gamerules");
|
||||
String seed = randomseed ? "" : seedflag;
|
||||
|
||||
this.plugin.getCommandQueueManager().addToQueue(new QueuedCommand(
|
||||
sender,
|
||||
doWorldRegen(sender, worldName, useseed, randomseed, seed, keepGamerules),
|
||||
String.format("Are you sure you want to regen '%s'? You cannot undo this action.", worldName)
|
||||
));
|
||||
}
|
||||
|
||||
private Runnable doWorldRegen(@NotNull CommandSender sender,
|
||||
@NotNull String worldName,
|
||||
boolean useSeed,
|
||||
boolean randomSeed,
|
||||
@NotNull String seed,
|
||||
boolean keepGamerules) {
|
||||
|
||||
return () -> {
|
||||
if (this.plugin.getMVWorldManager().regenWorld(worldName, useSeed, randomSeed, seed, keepGamerules)) {
|
||||
sender.sendMessage(ChatColor.GREEN + "World Regenerated!");
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(ChatColor.RED + "World could NOT be regenerated!");
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -50,7 +51,7 @@ public class SpawnCommand extends MultiverseCommand {
|
||||
sender.sendMessage("You don't have permission to teleport another player to spawn. (multiverse.core.spawn.other)");
|
||||
return;
|
||||
}
|
||||
Player target = this.plugin.getServer().getPlayer(args.get(0));
|
||||
Player target = PlayerFinder.get(args.get(0), sender);
|
||||
if (target != null) {
|
||||
target.sendMessage("Teleporting to this world's spawn...");
|
||||
spawnAccurately(target);
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.commands;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.Teleporter;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
|
||||
import com.onarandombox.MultiverseCore.destination.CustomTeleporterDestination;
|
||||
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
|
||||
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
|
||||
@@ -17,6 +19,7 @@ import com.onarandombox.MultiverseCore.destination.WorldDestination;
|
||||
import com.onarandombox.MultiverseCore.enums.TeleportResult;
|
||||
import com.onarandombox.MultiverseCore.event.MVTeleportEvent;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@@ -27,7 +30,6 @@ import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Used to teleport players.
|
||||
@@ -58,7 +60,7 @@ public class TeleportCommand extends MultiverseCommand {
|
||||
String destinationName;
|
||||
|
||||
if (args.size() == 2) {
|
||||
teleportee = this.plugin.getServer().getPlayer(args.get(0));
|
||||
teleportee = PlayerFinder.get(args.get(0), sender);
|
||||
if (teleportee == null) {
|
||||
this.messaging.sendMessage(sender, String.format("Sorry, I couldn't find player: %s%s",
|
||||
ChatColor.GOLD, args.get(0)), false);
|
||||
@@ -74,27 +76,14 @@ public class TeleportCommand extends MultiverseCommand {
|
||||
}
|
||||
teleportee = (Player) sender;
|
||||
}
|
||||
// Special case for cannons:
|
||||
if (destinationName.matches("(?i)cannon-[\\d]+(\\.[\\d]+)?")) {
|
||||
String[] cannonSpeed = destinationName.split("-");
|
||||
try {
|
||||
double speed = Double.parseDouble(cannonSpeed[1]);
|
||||
destinationName = "ca:" + teleportee.getWorld().getName() + ":" + teleportee.getLocation().getX()
|
||||
+ "," + teleportee.getLocation().getY() + "," + teleportee.getLocation().getZ() + ":"
|
||||
+ teleportee.getLocation().getPitch() + ":" + teleportee.getLocation().getYaw() + ":" + speed;
|
||||
} catch (Exception e) {
|
||||
destinationName = "i:invalid";
|
||||
}
|
||||
|
||||
}
|
||||
DestinationFactory df = this.plugin.getDestFactory();
|
||||
MVDestination d = df.getDestination(destinationName);
|
||||
|
||||
MVDestination d = df.getPlayerAwareDestination(teleportee, destinationName);
|
||||
|
||||
MVTeleportEvent teleportEvent = new MVTeleportEvent(d, teleportee, teleporter, true);
|
||||
this.plugin.getServer().getPluginManager().callEvent(teleportEvent);
|
||||
if (teleportEvent.isCancelled()) {
|
||||
this.plugin.log(Level.FINE, "Someone else cancelled the MVTeleport Event!!!");
|
||||
Logging.fine("Someone else cancelled the MVTeleport Event!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,26 +151,29 @@ public class TeleportCommand extends MultiverseCommand {
|
||||
((CustomTeleporterDestination)d).getTeleporter() : this.playerTeleporter;
|
||||
TeleportResult result = teleportObject.teleport(teleporter, teleportee, d);
|
||||
if (result == TeleportResult.FAIL_UNSAFE) {
|
||||
this.plugin.log(Level.FINE, "Could not teleport " + teleportee.getName()
|
||||
Logging.fine("Could not teleport " + teleportee.getName()
|
||||
+ " to " + plugin.getLocationManipulation().strCoordsRaw(d.getLocation(teleportee)));
|
||||
this.plugin.log(Level.FINE, "Queueing Command");
|
||||
Class<?>[] paramTypes = { CommandSender.class, Player.class, Location.class };
|
||||
List<Object> items = new ArrayList<Object>();
|
||||
items.add(teleporter);
|
||||
items.add(teleportee);
|
||||
items.add(d.getLocation(teleportee));
|
||||
|
||||
String player = "you";
|
||||
if (!teleportee.equals(teleporter)) {
|
||||
player = teleportee.getName();
|
||||
}
|
||||
String message = String.format("%sMultiverse %sdid not teleport %s%s %sto %s%s %sbecause it was unsafe.",
|
||||
ChatColor.GREEN, ChatColor.WHITE, ChatColor.AQUA, player, ChatColor.WHITE, ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE);
|
||||
this.plugin.getCommandHandler().queueCommand(sender, "mvteleport", "teleportPlayer", items,
|
||||
paramTypes, message, "Would you like to try anyway?", "", "", UNSAFE_TELEPORT_EXPIRE_DELAY);
|
||||
|
||||
this.plugin.getCommandQueueManager().addToQueue(new QueuedCommand(
|
||||
sender,
|
||||
doUnsafeTeleport(teleporter, teleportee, d.getLocation(teleportee)),
|
||||
String.format("%sMultiverse %sdid not teleport %s%s %sto %s%s %sbecause it was unsafe. Would you like to try anyway?",
|
||||
ChatColor.GREEN, ChatColor.WHITE, ChatColor.AQUA, player, ChatColor.WHITE, ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE),
|
||||
UNSAFE_TELEPORT_EXPIRE_DELAY
|
||||
));
|
||||
}
|
||||
// else: Player was teleported successfully (or the tp event was fired I should say)
|
||||
}
|
||||
|
||||
private Runnable doUnsafeTeleport(CommandSender teleporter, Player player, Location location) {
|
||||
return () -> this.plugin.getSafeTTeleporter().safelyTeleport(teleporter, player, location, false);
|
||||
}
|
||||
|
||||
private boolean checkSendPermissions(CommandSender teleporter, Player teleportee, MVDestination destination) {
|
||||
if (teleporter.equals(teleportee)) {
|
||||
if (!this.plugin.getMVPerms().hasPermission(teleporter, "multiverse.teleport.self." + destination.getIdentifier(), true)) {
|
||||
|
||||
@@ -45,8 +45,11 @@ public class VersionCommand extends MultiverseCommand {
|
||||
this.addKey("mvver");
|
||||
this.addKey("mvv");
|
||||
this.addKey("mvversion");
|
||||
this.setPermission("multiverse.core.version",
|
||||
"Dumps version info to the console, optionally to pastebin.com with -b, to hastebin.com using -h, or to paste.gg with -p.", PermissionDefault.TRUE);
|
||||
this.setPermission(
|
||||
"multiverse.core.version",
|
||||
"Dumps version info to the console, optionally to pastebin.com with -b, to hastebin.com using -h, or to paste.gg with -p.",
|
||||
PermissionDefault.OP)
|
||||
;
|
||||
}
|
||||
|
||||
private String getLegacyString() {
|
||||
@@ -64,6 +67,7 @@ public class VersionCommand extends MultiverseCommand {
|
||||
+ "[Multiverse-Core] teleportintercept: " + plugin.getMVConfig().getTeleportIntercept() + '\n'
|
||||
+ "[Multiverse-Core] firstspawnoverride: " + plugin.getMVConfig().getFirstSpawnOverride() + '\n'
|
||||
+ "[Multiverse-Core] displaypermerrors: " + plugin.getMVConfig().getDisplayPermErrors() + '\n'
|
||||
+ "[Multiverse-Core] enablebuscript: " + plugin.getMVConfig().getEnableBuscript() + '\n'
|
||||
+ "[Multiverse-Core] globaldebug: " + plugin.getMVConfig().getGlobalDebug() + '\n'
|
||||
+ "[Multiverse-Core] silentstart: " + plugin.getMVConfig().getSilentStart() + '\n'
|
||||
+ "[Multiverse-Core] messagecooldown: " + plugin.getMessaging().getCooldown() + '\n'
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/******************************************************************************
|
||||
* Multiverse 2 Copyright (c) the Multiverse Team 2020. *
|
||||
* Multiverse 2 is licensed under the BSD License. *
|
||||
* For more information please check the README.md file included *
|
||||
* with this project. *
|
||||
******************************************************************************/
|
||||
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.block.data.type.CommandBlock;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* <p>Manages the queuing of dangerous commands that require {@code /mv confirm} before executing.</p>
|
||||
*
|
||||
* <p>Each sender can only have one command in queue at any given time. When a queued command is added
|
||||
* for a sender that already has a command in queue, it will replace the old queued command.</p>
|
||||
*/
|
||||
public class CommandQueueManager {
|
||||
|
||||
private static final long TICKS_PER_SECOND = 20;
|
||||
private static final DummyCommandBlockSender COMMAND_BLOCK = new DummyCommandBlockSender();
|
||||
|
||||
private final MultiverseCore plugin;
|
||||
private final Map<CommandSender, QueuedCommand> queuedCommandMap;
|
||||
|
||||
public CommandQueueManager(@NotNull MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
this.queuedCommandMap = new WeakHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link QueuedCommand} into queue.
|
||||
*
|
||||
* @param queuedCommand The queued command to add.
|
||||
*/
|
||||
public void addToQueue(QueuedCommand queuedCommand) {
|
||||
CommandSender targetSender = parseSender(queuedCommand.getSender());
|
||||
|
||||
// Since only one command is stored in queue per sender, we remove the old one.
|
||||
this.removeFromQueue(targetSender);
|
||||
|
||||
Logging.finer("Add new command to queue for sender %s.", targetSender);
|
||||
this.queuedCommandMap.put(targetSender, queuedCommand);
|
||||
queuedCommand.setExpireTask(runExpireLater(queuedCommand));
|
||||
|
||||
queuedCommand.getSender().sendMessage(queuedCommand.getPrompt());
|
||||
queuedCommand.getSender().sendMessage(String.format("Run %s/mv confirm %sto continue. This will expire in %s seconds.",
|
||||
ChatColor.GREEN, ChatColor.WHITE, queuedCommand.getValidDuration()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Expire task that removes a {@link QueuedCommand} from queue after valid duration defined.
|
||||
*
|
||||
* @param queuedCommand Command to run the expire task on.
|
||||
* @return The expire {@link BukkitTask}.
|
||||
*/
|
||||
@NotNull
|
||||
private BukkitTask runExpireLater(@NotNull QueuedCommand queuedCommand) {
|
||||
return Bukkit.getScheduler().runTaskLater(
|
||||
this.plugin,
|
||||
expireRunnable(queuedCommand),
|
||||
queuedCommand.getValidDuration() * TICKS_PER_SECOND
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runnable responsible for expiring the queued command.
|
||||
*
|
||||
* @param queuedCommand Command to create the expire task on.
|
||||
* @return The expire runnable.
|
||||
*/
|
||||
@NotNull
|
||||
private Runnable expireRunnable(@NotNull QueuedCommand queuedCommand) {
|
||||
return () -> {
|
||||
CommandSender targetSender = parseSender(queuedCommand.getSender());
|
||||
QueuedCommand matchingQueuedCommand = this.queuedCommandMap.get(targetSender);
|
||||
if (!queuedCommand.equals(matchingQueuedCommand) || queuedCommand.getExpireTask().isCancelled()) {
|
||||
// To be safe, but this shouldn't happen since we cancel old commands before add new once.
|
||||
Logging.finer("This is an old queue command already.");
|
||||
return;
|
||||
}
|
||||
queuedCommand.getSender().sendMessage("Your queued command has expired.");
|
||||
this.queuedCommandMap.remove(queuedCommand.getSender());
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command in queue for the given sender, if any.
|
||||
*
|
||||
* @param sender {@link CommandSender} that confirmed the command.
|
||||
* @return True if queued command ran successfully, else false.
|
||||
*/
|
||||
public boolean runQueuedCommand(@NotNull CommandSender sender) {
|
||||
CommandSender targetSender = parseSender(sender);
|
||||
QueuedCommand queuedCommand = this.queuedCommandMap.get(targetSender);
|
||||
if (queuedCommand == null) {
|
||||
sender.sendMessage(ChatColor.RED + "You do not have any commands in queue.");
|
||||
return false;
|
||||
}
|
||||
Logging.finer("Running queued command...");
|
||||
queuedCommand.getAction().run();
|
||||
return removeFromQueue(targetSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since only one command is stored in queue per sender, we remove the old one.
|
||||
*
|
||||
* @param sender The {@link CommandSender} that executed the command.
|
||||
* @return True if queue command is removed from sender successfully, else false.
|
||||
*/
|
||||
public boolean removeFromQueue(@NotNull CommandSender sender) {
|
||||
CommandSender targetSender = parseSender(sender);
|
||||
QueuedCommand previousCommand = this.queuedCommandMap.remove(targetSender);
|
||||
if (previousCommand == null) {
|
||||
Logging.finer("No queue command to remove for sender %s.", targetSender.getName());
|
||||
return false;
|
||||
}
|
||||
previousCommand.getExpireTask().cancel();
|
||||
Logging.finer("Removed queue command for sender %s.", targetSender.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* To allow all CommandBlocks to be a common sender with use of {@link DummyCommandBlockSender}.
|
||||
* So confirm command can be used for a queued command on another command block.
|
||||
*
|
||||
* @param sender The sender to parse.
|
||||
* @return The sender, or if its a command block, a {@link DummyCommandBlockSender}.
|
||||
*/
|
||||
@NotNull
|
||||
private CommandSender parseSender(@NotNull CommandSender sender) {
|
||||
Logging.fine(sender.getClass().getName());
|
||||
if (isCommandBlock(sender)) {
|
||||
Logging.finer("Is command block.");
|
||||
return COMMAND_BLOCK;
|
||||
}
|
||||
return sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the sender is a command block.
|
||||
*
|
||||
* @param sender The sender to check.
|
||||
* @return True if sender is a command block, else false.
|
||||
*/
|
||||
private boolean isCommandBlock(@NotNull CommandSender sender) {
|
||||
return sender instanceof BlockCommandSender
|
||||
&& ((BlockCommandSender) sender).getBlock().getBlockData() instanceof CommandBlock;
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Used by {@link CommandQueueManager}, so different commands block can be recognised as one.
|
||||
*/
|
||||
class DummyCommandBlockSender implements CommandSender {
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NotNull String message) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NotNull String[] messages) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Server getServer() {
|
||||
return Bukkit.getServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "DummyCommandBlockSender";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NotNull String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NotNull Permission perm) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NotNull Permission perm) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value, int ticks) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PermissionAttachment addAttachment(@NotNull Plugin plugin, int ticks) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttachment(@NotNull PermissionAttachment attachment) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/******************************************************************************
|
||||
* Multiverse 2 Copyright (c) the Multiverse Team 2020. *
|
||||
* Multiverse 2 is licensed under the BSD License. *
|
||||
* For more information please check the README.md file included *
|
||||
* with this project. *
|
||||
******************************************************************************/
|
||||
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a single command used in {@link CommandQueueManager} for confirming before running potentially
|
||||
* dangerous action.
|
||||
*/
|
||||
public class QueuedCommand {
|
||||
|
||||
private static final String DEFAULT_PROMPT_MESSAGE = "The command you are trying to run is deemed dangerous.";
|
||||
private static final int DEFAULT_VALID_TIME = 10;
|
||||
|
||||
private final CommandSender sender;
|
||||
private final Runnable action;
|
||||
private final String prompt;
|
||||
private final int validDuration;
|
||||
private BukkitTask expireTask;
|
||||
|
||||
public QueuedCommand(CommandSender sender, Runnable action) {
|
||||
this(sender, action, DEFAULT_PROMPT_MESSAGE, DEFAULT_VALID_TIME);
|
||||
}
|
||||
|
||||
public QueuedCommand(CommandSender sender, Runnable action, String prompt) {
|
||||
this(sender, action, prompt, DEFAULT_VALID_TIME);
|
||||
}
|
||||
|
||||
public QueuedCommand(CommandSender sender, Runnable action, int validDuration) {
|
||||
this(sender, action, DEFAULT_PROMPT_MESSAGE, validDuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new queue command, to be registered at {@link CommandQueueManager#addToQueue(QueuedCommand)}.
|
||||
*
|
||||
* @param sender The sender that ran the command needed for confirmation.
|
||||
* @param action The logic to execute upon confirming.
|
||||
* @param prompt Question to ask sender to confirm.
|
||||
* @param validDuration Duration in which the command is valid for confirm in seconds.
|
||||
*/
|
||||
public QueuedCommand(CommandSender sender, Runnable action, String prompt, int validDuration) {
|
||||
this.sender = sender;
|
||||
this.action = action;
|
||||
this.prompt = prompt;
|
||||
this.validDuration = validDuration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
CommandSender getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
int getValidDuration() {
|
||||
return validDuration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Runnable getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
BukkitTask getExpireTask() {
|
||||
return expireTask;
|
||||
}
|
||||
|
||||
void setExpireTask(@NotNull BukkitTask expireTask) {
|
||||
if (this.expireTask != null) {
|
||||
throw new IllegalStateException("This queue command already has an expire task. You can't register twice!");
|
||||
}
|
||||
this.expireTask = expireTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Manager queuing of dangerous commands in need of confirmation.
|
||||
*/
|
||||
package com.onarandombox.MultiverseCore.commandtools.queue;
|
||||
@@ -22,6 +22,8 @@ public class EntryFee extends SerializationConfig {
|
||||
@Nullable
|
||||
private Material currency;
|
||||
|
||||
private final Material DISABLED_MATERIAL = Material.AIR;
|
||||
|
||||
public EntryFee() {
|
||||
super();
|
||||
}
|
||||
@@ -51,6 +53,9 @@ public class EntryFee extends SerializationConfig {
|
||||
*/
|
||||
@Nullable
|
||||
public Material getCurrency() {
|
||||
if (currency == null || currency.equals(DISABLED_MATERIAL)) {
|
||||
return null;
|
||||
}
|
||||
return currency;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,16 +11,29 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.commands.TeleportCommand;
|
||||
import com.onarandombox.MultiverseCore.utils.PermissionTools;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
|
||||
import com.pneumaticraft.commandhandler.Command;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** A factory class that will create destinations from specific strings. */
|
||||
/**
|
||||
* A factory class that will create destinations from specific strings.
|
||||
*/
|
||||
public class DestinationFactory {
|
||||
|
||||
private static final Pattern CANNON_PATTERN = Pattern.compile("(?i)cannon-[\\d]+(\\.[\\d]+)?");
|
||||
|
||||
private MultiverseCore plugin;
|
||||
private Map<String, Class<? extends MVDestination>> destList;
|
||||
private Command teleportCommand;
|
||||
@@ -36,6 +49,59 @@ public class DestinationFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a destination that has relation to sender, such as a cannon or player destination.
|
||||
*
|
||||
* @param teleportee The player that is going to be teleported.
|
||||
* @param destinationName The destination to parse.
|
||||
* @return A non-null MVDestination
|
||||
*/
|
||||
@NotNull
|
||||
public MVDestination getPlayerAwareDestination(@NotNull Player teleportee,
|
||||
@NotNull String destinationName) {
|
||||
|
||||
// Prioritise world, in the event that a world is named after a player online.
|
||||
if (Bukkit.getWorld(destinationName) != null) {
|
||||
return getDestination(destinationName);
|
||||
}
|
||||
|
||||
Player targetPlayer = PlayerFinder.get(destinationName, teleportee);
|
||||
if (targetPlayer != null) {
|
||||
return getDestination("pl:" + targetPlayer.getName());
|
||||
}
|
||||
|
||||
if (CANNON_PATTERN.matcher(destinationName).matches()) {
|
||||
return getDestination(parseCannonDest(teleportee, destinationName));
|
||||
}
|
||||
|
||||
return getDestination(destinationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a cannon destination.
|
||||
*
|
||||
* @param teleportee The player that is going to be teleported.
|
||||
* @param destinationName The destination to parse.
|
||||
* @return A destination string.
|
||||
*/
|
||||
@NotNull
|
||||
private String parseCannonDest(@NotNull Player teleportee,
|
||||
@NotNull String destinationName) {
|
||||
|
||||
String[] cannonSpeed = destinationName.split("-");
|
||||
try {
|
||||
double speed = Double.parseDouble(cannonSpeed[1]);
|
||||
destinationName = "ca:" + teleportee.getWorld().getName() + ":" + teleportee.getLocation().getX()
|
||||
+ "," + teleportee.getLocation().getY() + "," + teleportee.getLocation().getZ() + ":"
|
||||
+ teleportee.getLocation().getPitch() + ":" + teleportee.getLocation().getYaw() + ":" + speed;
|
||||
}
|
||||
catch (Exception e) {
|
||||
destinationName = "i:invalid";
|
||||
}
|
||||
|
||||
return destinationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new destination from a string.
|
||||
* Returns a new InvalidDestination if the string could not be parsed.
|
||||
@@ -101,4 +167,13 @@ public class DestinationFactory {
|
||||
this.teleportCommand.addAdditonalPermission(other);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the {@link MVDestination} identifiers registered.
|
||||
*
|
||||
* @return A collection of destination identifiers.
|
||||
*/
|
||||
public Collection<String> getRegisteredIdentifiers() {
|
||||
return this.destList.keySet();
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public class PlayerDestination implements MVDestination {
|
||||
*/
|
||||
@Override
|
||||
public Location getLocation(Entity e) {
|
||||
Player p = plugin.getServer().getPlayer(this.player);
|
||||
Player p = plugin.getServer().getPlayerExact(this.player);
|
||||
Player plLoc = null;
|
||||
if (e instanceof Player) {
|
||||
plLoc = (Player) e;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.onarandombox.MultiverseCore.display;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Helper class to switch between 2 {@link ChatColor}.
|
||||
*/
|
||||
public class ColorAlternator implements ColorTool {
|
||||
|
||||
/**
|
||||
* Creates a new {@link ColorAlternator} with 2 {@link ChatColor}s.
|
||||
*
|
||||
* @param colorThis The first color.
|
||||
* @param colorThat The second color.
|
||||
* @return The {@link ColorAlternator} created for you.
|
||||
*/
|
||||
public static ColorAlternator with(@NotNull ChatColor colorThis,
|
||||
@NotNull ChatColor colorThat) {
|
||||
|
||||
return new ColorAlternator(colorThis, colorThat);
|
||||
}
|
||||
|
||||
private boolean switcher;
|
||||
private final ChatColor thisColor;
|
||||
private final ChatColor thatColor;
|
||||
|
||||
/**
|
||||
* @param colorThis The first color.
|
||||
* @param colorThat The second color.
|
||||
*/
|
||||
public ColorAlternator(@NotNull ChatColor colorThis,
|
||||
@NotNull ChatColor colorThat) {
|
||||
|
||||
this.thisColor = colorThis;
|
||||
this.thatColor = colorThat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color. Everytime this method is called, it swaps the color that it returns.
|
||||
*
|
||||
* @return The color.
|
||||
*/
|
||||
@Override
|
||||
public ChatColor get() {
|
||||
return (this.switcher ^= true) ? this.thisColor : this.thatColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The first color.
|
||||
*/
|
||||
public ChatColor getThisColor() {
|
||||
return thisColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The second color.
|
||||
*/
|
||||
public ChatColor getThatColor() {
|
||||
return thatColor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.onarandombox.MultiverseCore.display;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
/**
|
||||
* Tools to allow customisation.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ColorTool {
|
||||
|
||||
/**
|
||||
* Gets a chat color.
|
||||
*
|
||||
* @return The color.
|
||||
*/
|
||||
ChatColor get();
|
||||
|
||||
/**
|
||||
* Default implementation of this interface. Returns a default white color.
|
||||
*/
|
||||
ColorTool DEFAULT = () -> ChatColor.WHITE;
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package com.onarandombox.MultiverseCore.display;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.settings.DisplaySetting;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Helps to display contents such as list and maps in a nicely formatted fashion.
|
||||
*
|
||||
* @param <T> Type of content to display.
|
||||
*/
|
||||
public class ContentDisplay<T> {
|
||||
|
||||
public static final String LINE_BREAK = "%br%";
|
||||
|
||||
/**
|
||||
* Creates a ContentDisplay.Builder for the given content.
|
||||
*
|
||||
* @param content The content to be displayed.
|
||||
* @param <T> The type of the content which can be inferred.
|
||||
* @return A new Builder.
|
||||
*/
|
||||
public static <T> Builder<T> forContent(T content) {
|
||||
return new Builder<>(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContentDisplay.Builder for the given collection of content.
|
||||
*
|
||||
* @param content The content to be displayed.
|
||||
* @return A new Builder.
|
||||
*/
|
||||
public static Builder<Collection<String>> forContent(Collection<String> content) {
|
||||
return new Builder<>(content).displayHandler(DisplayHandlers.LIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContentDisplay.Builder for the given map of content.
|
||||
*
|
||||
* @param content The content to be displayed.
|
||||
* @return A new Builder.
|
||||
*/
|
||||
public static Builder<Map<String, Object>> forContent(Map<String, Object> content) {
|
||||
return new Builder<>(content).displayHandler(DisplayHandlers.INLINE_MAP);
|
||||
}
|
||||
|
||||
private final T contents;
|
||||
|
||||
private String header;
|
||||
private String emptyMessage = "No matching content to display.";
|
||||
private DisplayHandler<T> displayHandler;
|
||||
private ColorTool colorTool = ColorTool.DEFAULT;
|
||||
private ContentFilter filter = ContentFilter.DEFAULT;
|
||||
private final Map<DisplaySetting<?>, Object> settingsMap = new WeakHashMap<>();
|
||||
|
||||
private ContentDisplay(T contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the actual displaying of contents to the sender.
|
||||
*
|
||||
* @param sender The CommandSender to show the display to.
|
||||
*/
|
||||
public void show(@NotNull CommandSender sender) {
|
||||
Collection<String> formattedContent;
|
||||
try {
|
||||
formattedContent = (this.contents == null) ? null : this.displayHandler.format(sender, this);
|
||||
} catch (DisplayFormatException e) {
|
||||
sender.sendMessage(String.format("%sError: %s", ChatColor.RED, e.getMessage()));
|
||||
return;
|
||||
}
|
||||
this.displayHandler.sendHeader(sender, this);
|
||||
this.displayHandler.sendSubHeader(sender, this);
|
||||
this.displayHandler.sendBody(sender, this, formattedContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the header to display.
|
||||
*/
|
||||
public String getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the header text.
|
||||
*/
|
||||
public void setHeader(@NotNull String header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the contents to display.
|
||||
*/
|
||||
public T getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the message to display when no content is shown.
|
||||
*/
|
||||
@NotNull
|
||||
public String getEmptyMessage() {
|
||||
return emptyMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the display handler that formats and sends content to sender.
|
||||
*/
|
||||
@NotNull
|
||||
public DisplayHandler<T> getDisplayHandler() {
|
||||
return displayHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the color tool used.
|
||||
*/
|
||||
@NotNull
|
||||
public ColorTool getColorTool() {
|
||||
return colorTool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the filter used.
|
||||
*/
|
||||
@NotNull
|
||||
public ContentFilter getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for a given setting option.
|
||||
*
|
||||
* @param setting The setting option.
|
||||
* @param <S> The setting type.
|
||||
* @return Value set for the given setting.
|
||||
*/
|
||||
public <S> S getSetting(@NotNull DisplaySetting<S> setting) {
|
||||
return (S) settingsMap.getOrDefault(setting, setting.defaultValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets other specific settings that may be used by the {@link DisplayHandler}.
|
||||
*
|
||||
* @param setting The settings option.
|
||||
* @param value The value to set.
|
||||
* @param <S> The type of setting.
|
||||
*/
|
||||
public <S> void setSetting(@NotNull DisplaySetting<S> setting, S value) {
|
||||
this.settingsMap.put(setting, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link ContentDisplay}.
|
||||
*
|
||||
* @param <T> Type of content to display.
|
||||
*/
|
||||
public static class Builder<T> {
|
||||
|
||||
private final ContentDisplay<T> display;
|
||||
|
||||
private Builder(T content) {
|
||||
this.display = new ContentDisplay<>(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets header to be displayed.
|
||||
*
|
||||
* @param header The header text.
|
||||
* @param replacements String formatting replacements.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
public Builder<T> header(@NotNull String header, Object...replacements) {
|
||||
this.display.header = String.format(header, replacements);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message to show when no content is available for display.
|
||||
*
|
||||
* @param emptyMessage The message text.
|
||||
* @param replacements String formatting replacements.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
public Builder<T> emptyMessage(@NotNull String emptyMessage, Object...replacements) {
|
||||
this.display.emptyMessage = String.format(emptyMessage, replacements);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the display handler that does the formatting and sending of content. <b>Required.</b>
|
||||
*
|
||||
* @param displayHandler The display handler for the given content type.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
public Builder<T> displayHandler(@NotNull DisplayHandler<T> displayHandler) {
|
||||
this.display.displayHandler = displayHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color tool used to make messages more colourful.
|
||||
*
|
||||
* @param colorTool The color tool to use.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
public Builder<T> colorTool(@NotNull ColorTool colorTool) {
|
||||
this.display.colorTool = colorTool;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets content filter used to match specific content to be displayed.
|
||||
*
|
||||
* @param filter The filter to use.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
public Builder<T> filter(@NotNull ContentFilter filter) {
|
||||
this.display.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets other specific settings that may be used by the {@link DisplayHandler}.
|
||||
*
|
||||
* @param setting The settings option.
|
||||
* @param value The value to set.
|
||||
* @param <S> The type of setting.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
public <S> Builder<T> setting(@NotNull DisplaySetting<S> setting, S value) {
|
||||
this.display.settingsMap.put(setting, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and build the content display.
|
||||
*
|
||||
* @return The content display.
|
||||
*/
|
||||
@NotNull
|
||||
public ContentDisplay<T> build() {
|
||||
Objects.requireNonNull(this.display.displayHandler);
|
||||
return this.display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and show the content to the sender.
|
||||
*
|
||||
* @param sender The CommandSender to show the display to.
|
||||
*/
|
||||
public void show(CommandSender sender) {
|
||||
this.build().show(sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.onarandombox.MultiverseCore.display;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* <p>Filter content and text based on regex matching.</p>
|
||||
*
|
||||
* <p>Compile regex pattern based on {@link ContentFilter#filterString}. When prefixed with 'r=',
|
||||
* use {@link ContentFilter#filterString} as the full regex pattern. Else, set to any match that
|
||||
* contains the {@link ContentFilter#filterString}.<p>
|
||||
*/
|
||||
public class ContentFilter {
|
||||
|
||||
public static final ContentFilter DEFAULT = new ContentFilter();
|
||||
private static final Pattern REGEX_SPECIAL_CHARS = Pattern.compile("[.+*?\\[^\\]$(){}=!<>|:-\\\\]");
|
||||
|
||||
private String filterString;
|
||||
private Pattern filterPattern;
|
||||
private boolean exactMatch;
|
||||
|
||||
private ContentFilter() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filterString The text to do matching, either plaintext or regex.
|
||||
*/
|
||||
public ContentFilter(@NotNull String filterString) {
|
||||
this(filterString, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filterString The text to do matching, else plaintext or regex.
|
||||
* @param exactMatch Should check for exact match when doing regex matching.
|
||||
*/
|
||||
public ContentFilter(@NotNull String filterString,
|
||||
boolean exactMatch) {
|
||||
|
||||
this.filterString = filterString;
|
||||
this.exactMatch = exactMatch;
|
||||
parseFilter();
|
||||
}
|
||||
|
||||
private void parseFilter() {
|
||||
if (filterString == null) {
|
||||
return;
|
||||
}
|
||||
if (filterString.startsWith("r=")) {
|
||||
convertToMatcher(filterString.substring(2));
|
||||
return;
|
||||
}
|
||||
String cleanedFilter = REGEX_SPECIAL_CHARS.matcher(filterString.toLowerCase()).replaceAll("\\\\$0");
|
||||
convertToMatcher("(?i).*" + cleanedFilter + ".*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile and store the regex into a {@link Pattern}.
|
||||
*
|
||||
* @param regex The regex text.
|
||||
*/
|
||||
private void convertToMatcher(@NotNull String regex) {
|
||||
try {
|
||||
this.filterPattern = Pattern.compile(regex);
|
||||
Logging.finest("Parsed regex pattern: %s", this.filterPattern.toString());
|
||||
}
|
||||
catch (PatternSyntaxException ignored) {
|
||||
Logging.warning("Error parsing regex: %s", filterString);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do regex matching.
|
||||
*
|
||||
* @param text String to check regex on.
|
||||
* @return True of matches regex pattern, false otherwise.
|
||||
*/
|
||||
public boolean checkMatch(@Nullable Object text) {
|
||||
if (!hasFilter()) {
|
||||
return true;
|
||||
}
|
||||
if (text == null || !hasValidPattern()) {
|
||||
return false;
|
||||
}
|
||||
text = ChatColor.stripColor(String.valueOf(text));
|
||||
return (exactMatch)
|
||||
? filterPattern.matcher((CharSequence) text).matches()
|
||||
: filterPattern.matcher((CharSequence) text).find();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a filter string is present.
|
||||
*
|
||||
* @return True if there is a filter string, else false.
|
||||
*/
|
||||
public boolean hasFilter() {
|
||||
return filterString != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if regex pattern syntax is valid.
|
||||
*
|
||||
* @return True if valid, else false.
|
||||
*/
|
||||
public boolean hasValidPattern() {
|
||||
return filterPattern != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The filter string.
|
||||
*/
|
||||
@Nullable
|
||||
public String getString() {
|
||||
return filterString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The regex pattern.
|
||||
*/
|
||||
@Nullable
|
||||
public Pattern getPattern() {
|
||||
return filterPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if filter is set to do exact matching, else false.
|
||||
*/
|
||||
public boolean isExactMatch() {
|
||||
return exactMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nicely format the filter string to be used for showing the sender.
|
||||
*
|
||||
* @return The formatted filter string.
|
||||
*/
|
||||
public @NotNull String getFormattedString() {
|
||||
return String.format("%sFilter: '%s'", ChatColor.ITALIC, filterString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContentFilter{" +
|
||||
"filterString='" + filterString + '\'' +
|
||||
", filterPattern=" + filterPattern +
|
||||
", exactMatch=" + exactMatch +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.onarandombox.MultiverseCore.display;
|
||||
|
||||
/**
|
||||
* Thrown when an issue occur while formatting content.
|
||||
*/
|
||||
public class DisplayFormatException extends Exception {
|
||||
public DisplayFormatException() {
|
||||
}
|
||||
|
||||
public DisplayFormatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DisplayFormatException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public DisplayFormatException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public DisplayFormatException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.onarandombox.MultiverseCore.display;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Handles the formatting and sending of all content by the {@link ContentDisplay}.
|
||||
*
|
||||
* @param <T> Type of content to display.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DisplayHandler<T> {
|
||||
|
||||
/**
|
||||
* Formats the raw content into a {@link Collection} for displaying to the given sender.
|
||||
*
|
||||
* @param sender The {@link CommandSender} who will the content will be displayed to.
|
||||
* @param display The responsible {@link ContentDisplay}.
|
||||
* @return The formatted content.
|
||||
* @throws DisplayFormatException Issue occurred while formatting content. E.g. invalid page.
|
||||
*/
|
||||
Collection<String> format(@NotNull CommandSender sender, @NotNull ContentDisplay<T> display)
|
||||
throws DisplayFormatException;
|
||||
|
||||
/**
|
||||
* Sends the header.
|
||||
*
|
||||
* @param sender The {@link CommandSender} who will the header will be displayed to.
|
||||
* @param display The responsible {@link ContentDisplay}.
|
||||
*/
|
||||
default void sendHeader(@NotNull CommandSender sender, @NotNull ContentDisplay<T> display) {
|
||||
if (!Strings.isNullOrEmpty(display.getHeader())) {
|
||||
sender.sendMessage(display.getHeader());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends info such as filter and page.
|
||||
*
|
||||
* @param sender The {@link CommandSender} who will the sub header will be displayed to.
|
||||
* @param display The responsible {@link ContentDisplay}.
|
||||
*/
|
||||
default void sendSubHeader(@NotNull CommandSender sender, @NotNull ContentDisplay<T> display) {
|
||||
if (display.getFilter().hasFilter()) {
|
||||
sender.sendMessage(String.format("%s[ %s ]", ChatColor.GRAY, display.getFilter().getFormattedString()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the content.
|
||||
*
|
||||
* @param sender The {@link CommandSender} who will the body will be displayed to.
|
||||
* @param display The responsible {@link ContentDisplay}.
|
||||
* @param formattedContent The content after being formatted by {@link #format(CommandSender, ContentDisplay)}
|
||||
*/
|
||||
default void sendBody(@NotNull CommandSender sender, @NotNull ContentDisplay<T> display,
|
||||
Collection<String> formattedContent) {
|
||||
if (formattedContent == null || formattedContent.size() == 0) {
|
||||
sender.sendMessage(display.getEmptyMessage());
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(formattedContent.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.onarandombox.MultiverseCore.display;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.handlers.InlineListDisplayHandler;
|
||||
import com.onarandombox.MultiverseCore.display.handlers.InlineMapDisplayHandler;
|
||||
import com.onarandombox.MultiverseCore.display.handlers.ListDisplayHandler;
|
||||
import com.onarandombox.MultiverseCore.display.handlers.PagedListDisplayHandler;
|
||||
import com.onarandombox.MultiverseCore.display.settings.InlineDisplaySettings;
|
||||
import com.onarandombox.MultiverseCore.display.settings.PagedDisplaySettings;
|
||||
import com.onarandombox.MultiverseCore.display.settings.MapDisplaySettings;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Various implementations of {@link DisplayHandler}.
|
||||
*/
|
||||
public class DisplayHandlers {
|
||||
|
||||
/**
|
||||
* Standard list display.
|
||||
*
|
||||
* Supported settings: none.
|
||||
*/
|
||||
public static final DisplayHandler<Collection<String>> LIST = new ListDisplayHandler();
|
||||
|
||||
/**
|
||||
* List display with paging.
|
||||
*
|
||||
* Supported settings: {@link PagedDisplaySettings#SHOW_PAGE}, {@link PagedDisplaySettings#LINES_PER_PAGE},
|
||||
* {@link PagedDisplaySettings#PAGE_IN_CONSOLE}, {@link PagedDisplaySettings#DO_END_PADDING}.
|
||||
*/
|
||||
public static final DisplayHandler<Collection<String>> PAGE_LIST = new PagedListDisplayHandler();
|
||||
|
||||
/**
|
||||
* Display a list inline.
|
||||
*
|
||||
* Supported settings: {@link InlineDisplaySettings#SEPARATOR}.
|
||||
*/
|
||||
public static final DisplayHandler<Collection<String>> INLINE_LIST = new InlineListDisplayHandler();
|
||||
|
||||
/**
|
||||
* Display key value pair inline.
|
||||
*
|
||||
* Supported settings: {@link InlineDisplaySettings#SEPARATOR}, {@link MapDisplaySettings#OPERATOR}.
|
||||
*/
|
||||
public static final DisplayHandler<Map<String, Object>> INLINE_MAP = new InlineMapDisplayHandler();
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.onarandombox.MultiverseCore.display.handlers;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.ContentDisplay;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayFormatException;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayHandler;
|
||||
import com.onarandombox.MultiverseCore.display.settings.InlineDisplaySettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class InlineListDisplayHandler implements DisplayHandler<Collection<String>> {
|
||||
|
||||
@Override
|
||||
public Collection<String> format(@NotNull CommandSender sender, @NotNull ContentDisplay<Collection<String>> display)
|
||||
throws DisplayFormatException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String separator = display.getSetting(InlineDisplaySettings.SEPARATOR);
|
||||
|
||||
for (Iterator<String> iterator = display.getContents().iterator(); iterator.hasNext(); ) {
|
||||
String content = iterator.next();
|
||||
if (!display.getFilter().checkMatch(content)) {
|
||||
continue;
|
||||
}
|
||||
builder.append(display.getColorTool().get()).append(content);
|
||||
if (iterator.hasNext()) {
|
||||
builder.append(separator);
|
||||
}
|
||||
}
|
||||
return (builder.length() == 0)
|
||||
? Collections.singletonList(display.getEmptyMessage())
|
||||
: Collections.singleton(builder.toString());
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.onarandombox.MultiverseCore.display.handlers;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.ContentDisplay;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayFormatException;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayHandler;
|
||||
import com.onarandombox.MultiverseCore.display.settings.InlineDisplaySettings;
|
||||
import com.onarandombox.MultiverseCore.display.settings.MapDisplaySettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class InlineMapDisplayHandler implements DisplayHandler<Map<String, Object>> {
|
||||
|
||||
@Override
|
||||
public Collection<String> format(@NotNull CommandSender sender,
|
||||
@NotNull ContentDisplay<Map<String, Object>> display)
|
||||
throws DisplayFormatException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String separator = display.getSetting(InlineDisplaySettings.SEPARATOR);
|
||||
String operator = display.getSetting(MapDisplaySettings.OPERATOR);
|
||||
|
||||
for (Iterator<Map.Entry<String, Object>> iterator = display.getContents().entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<String, Object> entry = iterator.next();
|
||||
if (!display.getFilter().checkMatch(entry.getKey()) && !display.getFilter().checkMatch(entry.getValue())) {
|
||||
continue;
|
||||
}
|
||||
builder.append(display.getColorTool().get())
|
||||
.append(entry.getKey())
|
||||
.append(operator)
|
||||
.append(display.getColorTool().get())
|
||||
.append(entry.getValue());
|
||||
if (iterator.hasNext()) {
|
||||
builder.append(separator);
|
||||
}
|
||||
}
|
||||
return (builder.length() == 0)
|
||||
? Collections.singletonList(display.getEmptyMessage())
|
||||
: Collections.singleton(builder.toString());
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.onarandombox.MultiverseCore.display.handlers;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.ContentDisplay;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayFormatException;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayHandler;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ListDisplayHandler implements DisplayHandler<Collection<String>> {
|
||||
|
||||
@Override
|
||||
public Collection<String> format(@NotNull CommandSender sender, @NotNull ContentDisplay<Collection<String>> display)
|
||||
throws DisplayFormatException {
|
||||
return display.getContents().stream()
|
||||
.filter(display.getFilter()::checkMatch)
|
||||
.map(s -> (ContentDisplay.LINE_BREAK.equals(s)) ? "" : display.getColorTool().get() + s)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
package com.onarandombox.MultiverseCore.display.handlers;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.ContentDisplay;
|
||||
import com.onarandombox.MultiverseCore.display.DisplayFormatException;
|
||||
import com.onarandombox.MultiverseCore.display.settings.PagedDisplaySettings;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class PagedListDisplayHandler extends ListDisplayHandler {
|
||||
|
||||
@Override
|
||||
public Collection<String> format(@NotNull CommandSender sender, @NotNull ContentDisplay<Collection<String>> display)
|
||||
throws DisplayFormatException {
|
||||
if (dontNeedPaging(sender, display)) {
|
||||
return super.format(sender, display);
|
||||
}
|
||||
|
||||
int pages = 1;
|
||||
int currentLength = 0;
|
||||
int targetPage = display.getSetting(PagedDisplaySettings.SHOW_PAGE);
|
||||
int linesPerPage = display.getSetting(PagedDisplaySettings.LINES_PER_PAGE);
|
||||
List<String> content = new ArrayList<>(linesPerPage);
|
||||
|
||||
// Calculate the paging.
|
||||
for (String line : display.getContents()) {
|
||||
if (!display.getFilter().checkMatch(line)) {
|
||||
continue;
|
||||
}
|
||||
// When it's the next page.
|
||||
boolean isLineBreak = ContentDisplay.LINE_BREAK.equals(line);
|
||||
if (isLineBreak || ++currentLength > linesPerPage) {
|
||||
pages++;
|
||||
currentLength = 0;
|
||||
if (isLineBreak) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (pages == targetPage) {
|
||||
// Let first line be the header when no header is defined.
|
||||
if (display.getHeader() == null) {
|
||||
display.setHeader(line);
|
||||
currentLength--;
|
||||
continue;
|
||||
}
|
||||
content.add(display.getColorTool().get() + line);
|
||||
}
|
||||
}
|
||||
|
||||
// Page out of range.
|
||||
if (targetPage < 1 || targetPage > pages) {
|
||||
if (pages == 1) {
|
||||
throw new DisplayFormatException("There is only 1 page!");
|
||||
}
|
||||
throw new DisplayFormatException("Please enter a page from 1 to " + pages + ".");
|
||||
}
|
||||
|
||||
// No content
|
||||
if (content.size() == 0) {
|
||||
content.add(display.getEmptyMessage());
|
||||
}
|
||||
|
||||
// Add empty lines to make output length consistent.
|
||||
if (display.getSetting(PagedDisplaySettings.DO_END_PADDING)) {
|
||||
IntStream.range(0, linesPerPage - content.size()).forEach(i -> content.add(""));
|
||||
}
|
||||
display.setSetting(PagedDisplaySettings.TOTAL_PAGE, pages);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubHeader(@NotNull CommandSender sender, @NotNull ContentDisplay<Collection<String>> display) {
|
||||
if (dontNeedPaging(sender, display)) {
|
||||
super.sendSubHeader(sender, display);
|
||||
return;
|
||||
}
|
||||
|
||||
if (display.getFilter().hasFilter()) {
|
||||
sender.sendMessage(String.format("%s[ Page %s of %s, %s ]",
|
||||
ChatColor.GRAY,
|
||||
display.getSetting(PagedDisplaySettings.SHOW_PAGE),
|
||||
display.getSetting(PagedDisplaySettings.TOTAL_PAGE),
|
||||
display.getFilter().getFormattedString())
|
||||
);
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(String.format("%s[ Page %s of %s ]",
|
||||
ChatColor.GRAY,
|
||||
display.getSetting(PagedDisplaySettings.SHOW_PAGE),
|
||||
display.getSetting(PagedDisplaySettings.TOTAL_PAGE))
|
||||
);
|
||||
}
|
||||
|
||||
private boolean dontNeedPaging(CommandSender sender, ContentDisplay<Collection<String>> display) {
|
||||
return sender instanceof ConsoleCommandSender
|
||||
&& !display.getSetting(PagedDisplaySettings.PAGE_IN_CONSOLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.onarandombox.MultiverseCore.display.settings;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.DisplayHandler;
|
||||
|
||||
/**
|
||||
* Represents a setting option that can be used by {@link DisplayHandler}.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DisplaySetting<T> {
|
||||
|
||||
/**
|
||||
* Gets the default value of this Display Setting.
|
||||
*
|
||||
* @return The default value.
|
||||
*/
|
||||
T defaultValue();
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.onarandombox.MultiverseCore.display.settings;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.DisplayHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
/**
|
||||
* Collection of {@link DisplaySetting} that are used by various {@link DisplayHandler}.
|
||||
*/
|
||||
public class InlineDisplaySettings {
|
||||
|
||||
/**
|
||||
* Inline separator. E.g. '1, 2, 3'
|
||||
*/
|
||||
public static final DisplaySetting<String> SEPARATOR = () -> ChatColor.WHITE + ", ";
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.onarandombox.MultiverseCore.display.settings;
|
||||
|
||||
import com.onarandombox.MultiverseCore.display.DisplayHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
/**
|
||||
* Collection of {@link DisplaySetting} that are used by various {@link DisplayHandler}.
|
||||
*/
|
||||
public class MapDisplaySettings {
|
||||
|
||||
/**
|
||||
* The thing between a key value pair. E.g. 'Me = Smart'
|
||||
*/
|
||||
public static final DisplaySetting<String> OPERATOR = () -> ChatColor.WHITE + " = ";
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.onarandombox.MultiverseCore.display.settings;
|
||||
|
||||
public class PagedDisplaySettings {
|
||||
|
||||
/**
|
||||
* Page to display.
|
||||
*/
|
||||
public static final DisplaySetting<Integer> SHOW_PAGE = () -> 1;
|
||||
|
||||
/**
|
||||
* Total pages available to display.
|
||||
*/
|
||||
public static final DisplaySetting<Integer> TOTAL_PAGE = () -> 1;
|
||||
|
||||
/**
|
||||
* The max number of lines per page. This excludes header.
|
||||
*/
|
||||
public static final DisplaySetting<Integer> LINES_PER_PAGE = () -> 8;
|
||||
|
||||
/**
|
||||
* Should add empty lines if content lines shown is less that {@link #LINES_PER_PAGE}.
|
||||
*/
|
||||
public static final DisplaySetting<Boolean> DO_END_PADDING = () -> true;
|
||||
|
||||
/**
|
||||
* Should display with paging when it's sent to console.
|
||||
*/
|
||||
public static final DisplaySetting<Boolean> PAGE_IN_CONSOLE = () -> false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.onarandombox.MultiverseCore.enums;
|
||||
|
||||
public enum RespawnType {
|
||||
BED,
|
||||
ANCHOR,
|
||||
OTHER
|
||||
}
|
||||
+2
-1
@@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
@@ -20,7 +21,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
public class MVAsyncPlayerChatListener extends MVChatListener {
|
||||
public MVAsyncPlayerChatListener(MultiverseCore plugin, MVPlayerListener playerListener) {
|
||||
super(plugin, playerListener);
|
||||
plugin.log(Level.FINE, "Created AsyncPlayerChatEvent listener.");
|
||||
Logging.fine("Created AsyncPlayerChatEvent listener.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.utils.CompatibilityLayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -17,6 +19,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
@@ -98,7 +101,7 @@ public class MVEntityListener implements Listener {
|
||||
* Handle people with non-standard animals: ie a patched craftbukkit.
|
||||
*/
|
||||
if (type == null || type.getName() == null) {
|
||||
this.plugin.log(Level.FINER, "Found a null typed creature.");
|
||||
Logging.finer("Found a null typed creature.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,4 +109,17 @@ public class MVEntityListener implements Listener {
|
||||
event.setCancelled(this.plugin.getMVWorldManager().getTheWorldPurger().shouldWeKillThisCreature(mvworld, event.getEntity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles portal search radius adjustment.
|
||||
* @param event The Event that was fired.
|
||||
*/
|
||||
@EventHandler
|
||||
public void entityPortal(EntityPortalEvent event) {
|
||||
if (event.isCancelled() || event.getTo() == null) {
|
||||
return;
|
||||
}
|
||||
if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) {
|
||||
CompatibilityLayer.setPortalSearchRadius(event, this.plugin.getMVConfig().getPortalSearchRadius());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerChatEvent;
|
||||
|
||||
@@ -21,7 +22,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
public class MVPlayerChatListener extends MVChatListener {
|
||||
public MVPlayerChatListener(MultiverseCore plugin, MVPlayerListener playerListener) {
|
||||
super(plugin, playerListener);
|
||||
plugin.log(Level.FINE, "Registered PlayerChatEvent listener.");
|
||||
Logging.fine("Registered PlayerChatEvent listener.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,15 +7,13 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.enums.RespawnType;
|
||||
import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
|
||||
import com.onarandombox.MultiverseCore.utils.CompatibilityLayer;
|
||||
import com.onarandombox.MultiverseCore.utils.PermissionTools;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@@ -33,6 +31,9 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Multiverse's {@link Listener} for players.
|
||||
*/
|
||||
@@ -69,9 +70,16 @@ public class MVPlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
RespawnType respawnType = RespawnType.OTHER;
|
||||
if (event.isBedSpawn()) {
|
||||
respawnType = RespawnType.BED;
|
||||
}
|
||||
if (CompatibilityLayer.isAnchorSpawn(event)) {
|
||||
respawnType = RespawnType.ANCHOR;
|
||||
}
|
||||
|
||||
if (mvWorld.getBedRespawn() && event.isBedSpawn()) {
|
||||
this.plugin.log(Level.FINE, "Spawning " + event.getPlayer().getName() + " at their bed");
|
||||
if (mvWorld.getBedRespawn() && (respawnType == RespawnType.BED || respawnType == RespawnType.ANCHOR)) {
|
||||
Logging.fine("Spawning %s at their %s", event.getPlayer().getName(), respawnType);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,15 +118,15 @@ public class MVPlayerListener implements Listener {
|
||||
public void playerJoin(PlayerJoinEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
if (!p.hasPlayedBefore()) {
|
||||
this.plugin.log(Level.FINER, "Player joined for the FIRST time!");
|
||||
Logging.finer("Player joined for the FIRST time!");
|
||||
if (plugin.getMVConfig().getFirstSpawnOverride()) {
|
||||
this.plugin.log(Level.FINE, "Moving NEW player to(firstspawnoverride): "
|
||||
Logging.fine("Moving NEW player to(firstspawnoverride): "
|
||||
+ worldManager.getFirstSpawnWorld().getSpawnLocation());
|
||||
this.sendPlayerToDefaultWorld(p);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
this.plugin.log(Level.FINER, "Player joined AGAIN!");
|
||||
Logging.finer("Player joined AGAIN!");
|
||||
if (this.plugin.getMVConfig().getEnforceAccess() // check this only if we're enforcing access!
|
||||
&& !this.plugin.getMVPerms().hasPermission(p, "multiverse.access." + p.getWorld().getName(), false)) {
|
||||
p.sendMessage("[MV] - Sorry you can't be in this world anymore!");
|
||||
@@ -156,35 +164,35 @@ public class MVPlayerListener implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void playerTeleport(PlayerTeleportEvent event) {
|
||||
this.plugin.log(Level.FINER, "Got teleport event for player '"
|
||||
Logging.finer("Got teleport event for player '"
|
||||
+ event.getPlayer().getName() + "' with cause '" + event.getCause() + "'");
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Player teleportee = event.getPlayer();
|
||||
CommandSender teleporter = null;
|
||||
CommandSender teleporter = teleportee;
|
||||
String teleporterName = MultiverseCore.getPlayerTeleporter(teleportee.getName());
|
||||
if (teleporterName != null) {
|
||||
if (teleporterName.equals("CONSOLE")) {
|
||||
this.plugin.log(Level.FINER, "We know the teleporter is the console! Magical!");
|
||||
Logging.finer("We know the teleporter is the console! Magical!");
|
||||
teleporter = this.plugin.getServer().getConsoleSender();
|
||||
} else {
|
||||
teleporter = this.plugin.getServer().getPlayer(teleporterName);
|
||||
teleporter = this.plugin.getServer().getPlayerExact(teleporterName);
|
||||
}
|
||||
}
|
||||
this.plugin.log(Level.FINER, "Inferred sender '" + teleporter + "' from name '"
|
||||
Logging.finer("Inferred sender '" + teleporter + "' from name '"
|
||||
+ teleporterName + "', fetched from name '" + teleportee.getName() + "'");
|
||||
MultiverseWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
|
||||
MultiverseWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
|
||||
if (toWorld == null) {
|
||||
this.plugin.log(Level.FINE, "Player '" + teleportee.getName() + "' is teleporting to world '"
|
||||
Logging.fine("Player '" + teleportee.getName() + "' is teleporting to world '"
|
||||
+ event.getTo().getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
|
||||
+ "actions will be taken by Multiverse-Core.");
|
||||
return;
|
||||
}
|
||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
||||
// The player is Teleporting to the same world.
|
||||
this.plugin.log(Level.FINER, "Player '" + teleportee.getName() + "' is teleporting to the same world.");
|
||||
Logging.finer("Player '" + teleportee.getName() + "' is teleporting to the same world.");
|
||||
this.stateSuccess(teleportee.getName(), toWorld.getAlias());
|
||||
return;
|
||||
}
|
||||
@@ -192,7 +200,7 @@ public class MVPlayerListener implements Listener {
|
||||
// Charge the teleporter
|
||||
event.setCancelled(!pt.playerHasMoneyToEnter(fromWorld, toWorld, teleporter, teleportee, true));
|
||||
if (event.isCancelled() && teleporter != null) {
|
||||
this.plugin.log(Level.FINE, "Player '" + teleportee.getName()
|
||||
Logging.fine("Player '" + teleportee.getName()
|
||||
+ "' was DENIED ACCESS to '" + toWorld.getAlias()
|
||||
+ "' because '" + teleporter.getName()
|
||||
+ "' don't have the FUNDS required to enter it.");
|
||||
@@ -203,14 +211,14 @@ public class MVPlayerListener implements Listener {
|
||||
if (plugin.getMVConfig().getEnforceAccess()) {
|
||||
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, teleporter, teleportee));
|
||||
if (event.isCancelled() && teleporter != null) {
|
||||
this.plugin.log(Level.FINE, "Player '" + teleportee.getName()
|
||||
Logging.fine("Player '" + teleportee.getName()
|
||||
+ "' was DENIED ACCESS to '" + toWorld.getAlias()
|
||||
+ "' because '" + teleporter.getName()
|
||||
+ "' don't have: multiverse.access." + event.getTo().getWorld().getName());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.plugin.log(Level.FINE, "Player '" + teleportee.getName()
|
||||
Logging.fine("Player '" + teleportee.getName()
|
||||
+ "' was allowed to go to '" + toWorld.getAlias() + "' because enforceaccess is off.");
|
||||
}
|
||||
|
||||
@@ -220,7 +228,7 @@ public class MVPlayerListener implements Listener {
|
||||
if (toWorld.getCBWorld().getPlayers().size() >= toWorld.getPlayerLimit()) {
|
||||
// Ouch the world is full, lets see if the player can bypass that limitation
|
||||
if (!pt.playerCanBypassPlayerLimit(toWorld, teleporter, teleportee)) {
|
||||
this.plugin.log(Level.FINE, "Player '" + teleportee.getName()
|
||||
Logging.fine("Player '" + teleportee.getName()
|
||||
+ "' was DENIED ACCESS to '" + toWorld.getAlias()
|
||||
+ "' because the world is full and '" + teleporter.getName()
|
||||
+ "' doesn't have: mv.bypass.playerlimit." + event.getTo().getWorld().getName());
|
||||
@@ -235,7 +243,7 @@ public class MVPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
private void stateSuccess(String playerName, String worldName) {
|
||||
this.plugin.log(Level.FINE, "MV-Core is allowing Player '" + playerName
|
||||
Logging.fine("MV-Core is allowing Player '" + playerName
|
||||
+ "' to go to '" + worldName + "'.");
|
||||
}
|
||||
|
||||
@@ -282,12 +290,12 @@ public class MVPlayerListener implements Listener {
|
||||
MultiverseWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
|
||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
||||
// The player is Portaling to the same world.
|
||||
this.plugin.log(Level.FINER, "Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
|
||||
Logging.finer("Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
|
||||
return;
|
||||
}
|
||||
event.setCancelled(!pt.playerHasMoneyToEnter(fromWorld, toWorld, event.getPlayer(), event.getPlayer(), true));
|
||||
if (event.isCancelled()) {
|
||||
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName()
|
||||
Logging.fine("Player '" + event.getPlayer().getName()
|
||||
+ "' was DENIED ACCESS to '" + event.getTo().getWorld().getName()
|
||||
+ "' because they don't have the FUNDS required to enter.");
|
||||
return;
|
||||
@@ -295,25 +303,17 @@ public class MVPlayerListener implements Listener {
|
||||
if (plugin.getMVConfig().getEnforceAccess()) {
|
||||
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, event.getPlayer(), event.getPlayer()));
|
||||
if (event.isCancelled()) {
|
||||
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName()
|
||||
Logging.fine("Player '" + event.getPlayer().getName()
|
||||
+ "' was DENIED ACCESS to '" + event.getTo().getWorld().getName()
|
||||
+ "' because they don't have: multiverse.access." + event.getTo().getWorld().getName());
|
||||
}
|
||||
} else {
|
||||
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName()
|
||||
Logging.fine("Player '" + event.getPlayer().getName()
|
||||
+ "' was allowed to go to '" + event.getTo().getWorld().getName()
|
||||
+ "' because enforceaccess is off.");
|
||||
}
|
||||
if (!plugin.getMVConfig().isUsingDefaultPortalSearch()) {
|
||||
try {
|
||||
Class.forName("org.bukkit.TravelAgent");
|
||||
if (event.getPortalTravelAgent() != null) {
|
||||
event.getPortalTravelAgent().setSearchRadius(plugin.getMVConfig().getPortalSearchRadius());
|
||||
}
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
plugin.log(Level.FINE, "TravelAgent not available for PlayerPortalEvent for " + event.getPlayer().getName());
|
||||
}
|
||||
|
||||
if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) {
|
||||
CompatibilityLayer.setPortalSearchRadius(event, this.plugin.getMVConfig().getPortalSearchRadius());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ public class MVPlayerListener implements Listener {
|
||||
if (mvWorld != null) {
|
||||
this.handleGameModeAndFlight(player, mvWorld);
|
||||
} else {
|
||||
this.plugin.log(Level.FINER, "Not handling gamemode and flight for world '" + world.getName()
|
||||
Logging.finer("Not handling gamemode and flight for world '" + world.getName()
|
||||
+ "' not managed by Multiverse.");
|
||||
}
|
||||
}
|
||||
@@ -376,7 +376,7 @@ public class MVPlayerListener implements Listener {
|
||||
player.getName(), player.getWorld().getName(), world.getName());
|
||||
}
|
||||
} else {
|
||||
MVPlayerListener.this.plugin.log(Level.FINE, "Player: " + player.getName() + " is IMMUNE to gamemode changes!");
|
||||
Logging.fine("Player: " + player.getName() + " is IMMUNE to gamemode changes!");
|
||||
}
|
||||
}
|
||||
}, 1L);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import org.bukkit.Material;
|
||||
@@ -56,7 +57,7 @@ public class MVPortalListener implements Listener {
|
||||
public void portalForm(PortalCreateEvent event) {
|
||||
MultiverseWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getWorld());
|
||||
if (world != null && !world.getAllowedPortals().isPortalAllowed(PortalType.NETHER)) {
|
||||
plugin.log(Level.FINE, "Cancelling creation of nether portal because portalForm disallows.");
|
||||
Logging.fine("Cancelling creation of nether portal because portalForm disallows.");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -79,7 +80,7 @@ public class MVPortalListener implements Listener {
|
||||
}
|
||||
MultiverseWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getPlayer().getWorld());
|
||||
if (world != null && !world.getAllowedPortals().isPortalAllowed(PortalType.ENDER)) {
|
||||
plugin.log(Level.FINE, "Cancelling creation of ender portal because portalForm disallows.");
|
||||
Logging.fine("Cancelling creation of ender portal because portalForm disallows.");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class AnchorManager {
|
||||
this.anchorConfig.save(new File(this.plugin.getDataFolder(), "anchors.yml"));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
this.plugin.log(Level.SEVERE, "Failed to save anchors.yml. Please check your file permissions.");
|
||||
Logging.severe("Failed to save anchors.yml. Please check your file permissions.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.destination.CannonDestination;
|
||||
import org.bukkit.Location;
|
||||
@@ -89,7 +90,7 @@ public class BukkitTravelAgent implements TravelAgent {
|
||||
private Location getSafeLocation() {
|
||||
// At this time, these can never use the velocity.
|
||||
if (agent.destination instanceof CannonDestination) {
|
||||
agent.core.log(Level.FINE, "Using Stock TP method. This cannon will have 0 velocity");
|
||||
Logging.fine("Using Stock TP method. This cannon will have 0 velocity");
|
||||
}
|
||||
SafeTTeleporter teleporter = agent.core.getSafeTTeleporter();
|
||||
Location newLoc = agent.destination.getLocation(agent.player);
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Utility class to enable version specific minecraft features.
|
||||
*/
|
||||
public class CompatibilityLayer {
|
||||
|
||||
private static Method checkAnchorSpawn;
|
||||
private static boolean useTravelAgent;
|
||||
private static Method playerPortalSearchRadius;
|
||||
private static Method entityPortalSearchRadius;
|
||||
|
||||
/**
|
||||
* Initialise the reflection class, methods and fields.
|
||||
*/
|
||||
public static void init() {
|
||||
checkAnchorSpawn = ReflectHelper.getMethod(PlayerRespawnEvent.class, "isAnchorSpawn");
|
||||
useTravelAgent = ReflectHelper.hasClass("org.bukkit.TravelAgent");
|
||||
playerPortalSearchRadius = ReflectHelper.getMethod(PlayerPortalEvent.class, "setSearchRadius", int.class);
|
||||
entityPortalSearchRadius = ReflectHelper.getMethod(EntityPortalEvent.class, "setSearchRadius", int.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Check if the respawn point is of respawn anchor type.</p>
|
||||
* <p>Introduced in minecraft 1.16</p>
|
||||
*
|
||||
* @param event A player respawn event.
|
||||
* @return If the respawn location is an anchor point.
|
||||
*/
|
||||
public static boolean isAnchorSpawn(PlayerRespawnEvent event) {
|
||||
if (checkAnchorSpawn == null) {
|
||||
return false;
|
||||
}
|
||||
Boolean result = ReflectHelper.invokeMethod(event, checkAnchorSpawn);
|
||||
if (result == null) {
|
||||
Logging.warning("Unable to check if spawning at respawn anchor!");
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets if Travel Agent is supported on the server's minecraft version.</p>
|
||||
* <p>Removed in minecraft 1.14</p>
|
||||
*
|
||||
* @return True if Travel Agent is supported, else false.
|
||||
*/
|
||||
public static boolean isUseTravelAgent() {
|
||||
return useTravelAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets search radius for a PlayerPortalEvent.</p>
|
||||
*
|
||||
* <p>Use travel agent if available, else using new PlayerPortalEvent.setSearchRadius(int) method
|
||||
* introduced in minecraft 1.15</p>
|
||||
*
|
||||
* @param event A Player Portal Event.
|
||||
* @param searchRadius Target search radius to set to.
|
||||
*/
|
||||
public static void setPortalSearchRadius(PlayerPortalEvent event, int searchRadius) {
|
||||
if (useTravelAgent) {
|
||||
event.getPortalTravelAgent().setSearchRadius(searchRadius);
|
||||
event.useTravelAgent(true);
|
||||
Logging.finer("Used travel agent to set player portal search radius.");
|
||||
return;
|
||||
}
|
||||
if (playerPortalSearchRadius == null) {
|
||||
Logging.warning("Unable to set player portal search radius!");
|
||||
return;
|
||||
}
|
||||
ReflectHelper.invokeMethod(event, playerPortalSearchRadius, searchRadius);
|
||||
Logging.finer("Used new method to set player portal search radius.");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets search radius for a EntityPortalEvent.</p>
|
||||
*
|
||||
* <p>Use travel agent if available, else using new EntityPortalEvent.setSearchRadius(int) method
|
||||
* introduced in minecraft 1.15</p>
|
||||
*
|
||||
* @param event A Entity Portal Event.
|
||||
* @param searchRadius Target search radius to set to.
|
||||
*/
|
||||
public static void setPortalSearchRadius(EntityPortalEvent event, int searchRadius) {
|
||||
if (useTravelAgent) {
|
||||
event.getPortalTravelAgent().setSearchRadius(searchRadius);
|
||||
event.useTravelAgent(true);
|
||||
Logging.finer("Used travel agent to set entity portal search radius.");
|
||||
return;
|
||||
}
|
||||
if (entityPortalSearchRadius == null) {
|
||||
Logging.warning("Unable to set entity portal search radius!");
|
||||
return;
|
||||
}
|
||||
ReflectHelper.invokeMethod(event, entityPortalSearchRadius, searchRadius);
|
||||
Logging.finer("Used new method to set entity portal search radius.");
|
||||
}
|
||||
}
|
||||
@@ -72,12 +72,11 @@ public class FileUtils {
|
||||
* Helper method to copy the world-folder.
|
||||
* @param source Source-File
|
||||
* @param target Target-File
|
||||
* @param log A logger that logs the operation
|
||||
*
|
||||
* @return true if it had success
|
||||
*/
|
||||
public static boolean copyFolder(File source, File target, Logger log) {
|
||||
return copyFolder(source, target, null, log);
|
||||
public static boolean copyFolder(File source, File target) {
|
||||
return copyFolder(source, target, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,11 +84,10 @@ public class FileUtils {
|
||||
* @param source Source-File
|
||||
* @param target Target-File
|
||||
* @param excludeFiles files to ignore and not copy over to Target-File
|
||||
* @param log A logger that logs the operation
|
||||
*
|
||||
* @return true if it had success
|
||||
*/
|
||||
public static boolean copyFolder(File source, File target, List<String> excludeFiles, Logger log) {
|
||||
public static boolean copyFolder(File source, File target, List<String> excludeFiles) {
|
||||
Path sourceDir = source.toPath();
|
||||
Path targetDir = target.toPath();
|
||||
|
||||
@@ -97,7 +95,7 @@ public class FileUtils {
|
||||
Files.walkFileTree(sourceDir, new CopyDirFileVisitor(sourceDir, targetDir, excludeFiles));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Unable to copy directory", e);
|
||||
Logging.warning("Unable to copy directory", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
@@ -100,7 +101,7 @@ public class MVPermissions implements PermissionsInterface {
|
||||
public boolean canEnterWorld(Player p, MultiverseWorld w) {
|
||||
// If we're not enforcing access, anyone can enter.
|
||||
if (!plugin.getMVConfig().getEnforceAccess()) {
|
||||
this.plugin.log(Level.FINEST, "EnforceAccess is OFF. Player was allowed in " + w.getAlias());
|
||||
Logging.finest("EnforceAccess is OFF. Player was allowed in " + w.getAlias());
|
||||
return true;
|
||||
}
|
||||
return this.hasPermission(p, "multiverse.access." + w.getName(), false);
|
||||
@@ -257,14 +258,14 @@ public class MVPermissions implements PermissionsInterface {
|
||||
|
||||
boolean hasPermission = sender.hasPermission(node);
|
||||
if (!sender.isPermissionSet(node)) {
|
||||
this.plugin.log(Level.FINER, String.format("The node [%s%s%s] was %sNOT%s set for [%s%s%s].",
|
||||
Logging.finer(String.format("The node [%s%s%s] was %sNOT%s set for [%s%s%s].",
|
||||
ChatColor.RED, node, ChatColor.WHITE, ChatColor.RED, ChatColor.WHITE, ChatColor.AQUA,
|
||||
player.getDisplayName(), ChatColor.WHITE));
|
||||
}
|
||||
if (hasPermission) {
|
||||
this.plugin.log(Level.FINER, "Checking to see if player [" + player.getName() + "] has permission [" + node + "]... YES");
|
||||
Logging.finer("Checking to see if player [" + player.getName() + "] has permission [" + node + "]... YES");
|
||||
} else {
|
||||
this.plugin.log(Level.FINER, "Checking to see if player [" + player.getName() + "] has permission [" + node + "]... NO");
|
||||
Logging.finer("Checking to see if player [" + player.getName() + "] has permission [" + node + "]... NO");
|
||||
}
|
||||
return hasPermission;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import org.bukkit.Material;
|
||||
@@ -195,7 +196,7 @@ public class PermissionTools {
|
||||
* @return True if they can't go to the world, False if they can.
|
||||
*/
|
||||
public boolean playerCanGoFromTo(MultiverseWorld fromWorld, MultiverseWorld toWorld, CommandSender teleporter, Player teleportee) {
|
||||
this.plugin.log(Level.FINEST, "Checking '" + teleporter + "' can send '" + teleportee + "' somewhere");
|
||||
Logging.finest("Checking '" + teleporter + "' can send '" + teleportee + "' somewhere");
|
||||
|
||||
Player teleporterPlayer;
|
||||
if (plugin.getMVConfig().getTeleportIntercept()) {
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Helper class to get {@link Player} from name, UUID or Selectors.
|
||||
*/
|
||||
public class PlayerFinder {
|
||||
|
||||
private static final Pattern UUID_REGEX = Pattern.compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}");
|
||||
private static final Pattern COMMA_SPLIT = Pattern.compile(",");
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on an identifier of name UUID or selector.
|
||||
*
|
||||
* @param playerIdentifier An identifier of name UUID or selector.
|
||||
* @param sender Target sender for selector.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player get(@NotNull String playerIdentifier,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
Player targetPlayer = getByName(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
return targetPlayer;
|
||||
}
|
||||
targetPlayer = getByUuid(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
return targetPlayer;
|
||||
}
|
||||
return getBySelector(playerIdentifier, sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple {@link Player} based on many identifiers of name UUID or selector.
|
||||
*
|
||||
* @param playerIdentifiers An identifier of multiple names, UUIDs or selectors, separated by comma.
|
||||
* @param sender Target sender for selector.
|
||||
* @return A list of all the {@link Player} found.
|
||||
*/
|
||||
@Nullable
|
||||
public static List<Player> getMulti(@NotNull String playerIdentifiers,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
String[] playerIdentifierArray = COMMA_SPLIT.split(playerIdentifiers);
|
||||
if (playerIdentifierArray == null || playerIdentifierArray.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Player> playerResults = new ArrayList<>();
|
||||
for (String playerIdentifier : playerIdentifierArray) {
|
||||
Player targetPlayer = getByName(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
playerResults.add(targetPlayer);
|
||||
continue;
|
||||
}
|
||||
targetPlayer = getByUuid(playerIdentifier);
|
||||
if (targetPlayer != null) {
|
||||
playerResults.add(targetPlayer);
|
||||
continue;
|
||||
}
|
||||
List<Player> targetPlayers = getMultiBySelector(playerIdentifier, sender);
|
||||
if (targetPlayers != null) {
|
||||
playerResults.addAll(targetPlayers);
|
||||
}
|
||||
}
|
||||
return playerResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on player name.
|
||||
*
|
||||
* @param playerName Name of a {@link Player}.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getByName(@NotNull String playerName) {
|
||||
return Bukkit.getPlayerExact(playerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on player UUID.
|
||||
*
|
||||
* @param playerUuid UUID of a player.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getByUuid(@NotNull String playerUuid) {
|
||||
if (!UUID_REGEX.matcher(playerUuid).matches()) {
|
||||
return null;
|
||||
}
|
||||
UUID uuid;
|
||||
try {
|
||||
uuid = UUID.fromString(playerUuid);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return getByUuid(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on playerUUID.
|
||||
*
|
||||
* @param playerUuid UUID of a player.
|
||||
* @return The player if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getByUuid(@NotNull UUID playerUuid) {
|
||||
return Bukkit.getPlayer(playerUuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link Player} based on vanilla selectors.
|
||||
* https://minecraft.gamepedia.com/Commands#Target_selectors
|
||||
*
|
||||
* @param playerSelector A target selector, usually starts with an '@'.
|
||||
* @param sender Target sender for selector.
|
||||
* @return The player if only one found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Player getBySelector(@NotNull String playerSelector,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
List<Player> matchedPlayers = getMultiBySelector(playerSelector, sender);
|
||||
if (matchedPlayers == null || matchedPlayers.isEmpty()) {
|
||||
Logging.fine("No player found with selector '%s' for %s.", playerSelector, sender.getName());
|
||||
return null;
|
||||
}
|
||||
if (matchedPlayers.size() > 1) {
|
||||
Logging.warning("Ambiguous selector result '%s' for %s (more than one player matched) - %s",
|
||||
playerSelector, sender.getName(), matchedPlayers.toString());
|
||||
return null;
|
||||
}
|
||||
return matchedPlayers.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple {@link Player} based on selector.
|
||||
* https://minecraft.gamepedia.com/Commands#Target_selectors
|
||||
*
|
||||
* @param playerSelector A target selector, usually starts with an '@'.
|
||||
* @param sender Target sender for selector.
|
||||
* @return A list of all the {@link Player} found.
|
||||
*/
|
||||
@Nullable
|
||||
public static List<Player> getMultiBySelector(@NotNull String playerSelector,
|
||||
@NotNull CommandSender sender) {
|
||||
|
||||
if (playerSelector.charAt(0) != '@') {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Bukkit.selectEntities(sender, playerSelector).stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> ((Player) e))
|
||||
.collect(Collectors.toList());
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logging.warning("An error occurred while parsing selector '%s' for %s. Is it is the correct format?",
|
||||
playerSelector, sender.getName());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
|
||||
@@ -86,7 +87,7 @@ public class PurgeWorlds {
|
||||
}
|
||||
int entitiesKilled = 0;
|
||||
for (Entity e : world.getEntities()) {
|
||||
this.plugin.log(Level.FINEST, "Entity list (aval for purge) from WORLD < " + mvworld.getName() + " >: " + e.toString());
|
||||
Logging.finest("Entity list (aval for purge) from WORLD < " + mvworld.getName() + " >: " + e.toString());
|
||||
|
||||
// Check against Monsters
|
||||
if (killMonster(mvworld, e, thingsToKill, negateMonsters)) {
|
||||
@@ -133,16 +134,16 @@ public class PurgeWorlds {
|
||||
entityName = e.toString().replaceAll("Craft", "").toUpperCase();
|
||||
}
|
||||
if (e instanceof Slime || e instanceof Monster || e instanceof Ghast || e instanceof EnderDragon) {
|
||||
this.plugin.log(Level.FINEST, "Looking at a monster: " + e);
|
||||
Logging.finest("Looking at a monster: " + e);
|
||||
if (creaturesToKill.contains(entityName) || creaturesToKill.contains("ALL") || creaturesToKill.contains("MONSTERS")) {
|
||||
if (!negate) {
|
||||
this.plugin.log(Level.FINEST, "Removing a monster: " + e);
|
||||
Logging.finest("Removing a monster: " + e);
|
||||
e.remove();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (negate) {
|
||||
this.plugin.log(Level.FINEST, "Removing a monster: " + e);
|
||||
Logging.finest("Removing a monster: " + e);
|
||||
e.remove();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Utility class used to help in doing various reflection actions.
|
||||
*/
|
||||
public class ReflectHelper {
|
||||
|
||||
/**
|
||||
* Try to get the {@link Class} based on its classpath.
|
||||
*
|
||||
* @param classPath The target classpath.
|
||||
* @return A {@link Class} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Class<?> getClass(String classPath) {
|
||||
try {
|
||||
return Class.forName(classPath);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the {@link Class} for a give classpath is present/valid.
|
||||
*
|
||||
* @param classPath Target classpath.
|
||||
* @return True if class path is a valid class, else false.
|
||||
*/
|
||||
public static boolean hasClass(String classPath) {
|
||||
return getClass(classPath) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Method} from a given class.
|
||||
*
|
||||
* @param clazz The class to search the method on.
|
||||
* @param methodName Name of the method to get.
|
||||
* @param parameterTypes Parameters present for that method.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Method} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Method getMethod(Class<C> clazz, String methodName, Class<?>... parameterTypes) {
|
||||
try {
|
||||
Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Method} from a given class.
|
||||
*
|
||||
* @param classInstance Instance of the class to search the method on.
|
||||
* @param methodName Name of the method to get.
|
||||
* @param parameterTypes Parameters present for that method.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Method} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Method getMethod(C classInstance, String methodName, Class<?>... parameterTypes) {
|
||||
return getMethod(classInstance.getClass(), methodName, parameterTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a {@link Method}.
|
||||
*
|
||||
* @param classInstance Instance of the class responsible for the method.
|
||||
* @param method The method to call.
|
||||
* @param parameters Parameters needed when calling the method.
|
||||
* @param <C> The class type.
|
||||
* @param <R> The return type.
|
||||
* @return Return value of the method call if any, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C, R> R invokeMethod(C classInstance, Method method, Object...parameters) {
|
||||
try {
|
||||
return (R) method.invoke(classInstance, parameters);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Field} from a given class.
|
||||
*
|
||||
* @param clazz The class to search the field on.
|
||||
* @param fieldName Name of the field to get.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Field} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Field getField(Class<C> clazz, String fieldName) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (NoSuchFieldException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a {@link Field} from a given class.
|
||||
*
|
||||
* @param classInstance Instance of the class to search the field on.
|
||||
* @param fieldName Name of the field to get.
|
||||
* @param <C> The class type.
|
||||
* @return A {@link Field} if found, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C> Field getField(C classInstance, String fieldName) {
|
||||
return getField(classInstance.getClass(), fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of an {@link Field} from an instance of the class responsible.
|
||||
*
|
||||
* @param classInstance Instance of the class to get the field value from.
|
||||
* @param field The field to get value from.
|
||||
* @param <C> The class type.
|
||||
* @param <V> The field value type.
|
||||
* @return The field value if any, else null.
|
||||
*/
|
||||
@Nullable
|
||||
public static <C, V> V getFieldValue(C classInstance, Field field) {
|
||||
try {
|
||||
return (V) field.get(classInstance);
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,15 @@ public class SimpleLocationManipulation implements LocationManipulation {
|
||||
orientationInts.put("w", 90);
|
||||
orientationInts.put("nw", 135);
|
||||
|
||||
orientationInts.put("north", 180);
|
||||
orientationInts.put("northeast", 225);
|
||||
orientationInts.put("east", 270);
|
||||
orientationInts.put("southeast", 315);
|
||||
orientationInts.put("south", 0);
|
||||
orientationInts.put("southwest", 45);
|
||||
orientationInts.put("west", 90);
|
||||
orientationInts.put("northwest", 135);
|
||||
|
||||
// "freeze" the map:
|
||||
ORIENTATION_INTS = Collections.unmodifiableMap(orientationInts);
|
||||
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
|
||||
import com.onarandombox.MultiverseCore.enums.TeleportResult;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
@@ -24,8 +25,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* The default-implementation of {@link SafeTTeleporter}.
|
||||
*/
|
||||
@@ -36,6 +35,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
private static final Vector DEFAULT_VECTOR = new Vector();
|
||||
private static final int DEFAULT_TOLERANCE = 6;
|
||||
private static final int DEFAULT_RADIUS = 9;
|
||||
|
||||
@@ -58,9 +58,9 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
|
||||
if (safe != null) {
|
||||
safe.setX(safe.getBlockX() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
|
||||
safe.setZ(safe.getBlockZ() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
|
||||
this.plugin.log(Level.FINE, "Hey! I found one: " + plugin.getLocationManipulation().strCoordsRaw(safe));
|
||||
Logging.fine("Hey! I found one: " + plugin.getLocationManipulation().strCoordsRaw(safe));
|
||||
} else {
|
||||
this.plugin.log(Level.FINE, "Uh oh! No safe place found!");
|
||||
Logging.fine("Uh oh! No safe place found!");
|
||||
}
|
||||
return safe;
|
||||
}
|
||||
@@ -72,8 +72,8 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
|
||||
}
|
||||
// We want half of it, so we can go up and down
|
||||
tolerance /= 2;
|
||||
this.plugin.log(Level.FINER, "Given Location of: " + plugin.getLocationManipulation().strCoordsRaw(l));
|
||||
this.plugin.log(Level.FINER, "Checking +-" + tolerance + " with a radius of " + radius);
|
||||
Logging.finer("Given Location of: " + plugin.getLocationManipulation().strCoordsRaw(l));
|
||||
Logging.finer("Checking +-" + tolerance + " with a radius of " + radius);
|
||||
|
||||
// For now this will just do a straight up block.
|
||||
Location locToCheck = l.clone();
|
||||
@@ -191,7 +191,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
|
||||
@Override
|
||||
public TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, MVDestination d) {
|
||||
if (d instanceof InvalidDestination) {
|
||||
this.plugin.log(Level.FINER, "Entity tried to teleport to an invalid destination");
|
||||
Logging.finer("Entity tried to teleport to an invalid destination");
|
||||
return TeleportResult.FAIL_INVALID;
|
||||
}
|
||||
Player teleporteePlayer = null;
|
||||
@@ -213,8 +213,11 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
|
||||
|
||||
if (safeLoc != null) {
|
||||
if (teleportee.teleport(safeLoc)) {
|
||||
if (!d.getVelocity().equals(new Vector(0, 0, 0))) {
|
||||
teleportee.setVelocity(d.getVelocity());
|
||||
Vector v = d.getVelocity();
|
||||
if (v != null && !DEFAULT_VECTOR.equals(v)) {
|
||||
Bukkit.getScheduler().runTaskLater(this.plugin, () -> {
|
||||
teleportee.setVelocity(d.getVelocity());
|
||||
}, 1);
|
||||
}
|
||||
return TeleportResult.SUCCESS;
|
||||
}
|
||||
@@ -248,7 +251,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
|
||||
public Location getSafeLocation(Entity e, MVDestination d) {
|
||||
Location l = d.getLocation(e);
|
||||
if (plugin.getBlockSafety().playerCanSpawnHereSafely(l)) {
|
||||
plugin.log(Level.FINE, "The first location you gave me was safe.");
|
||||
Logging.fine("The first location you gave me was safe.");
|
||||
return l;
|
||||
}
|
||||
if (e instanceof Minecart) {
|
||||
@@ -267,21 +270,21 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
|
||||
// Add offset to account for a vehicle on dry land!
|
||||
if (e instanceof Minecart && !plugin.getBlockSafety().isEntitiyOnTrack(safeLocation)) {
|
||||
safeLocation.setY(safeLocation.getBlockY() + .5);
|
||||
this.plugin.log(Level.FINER, "Player was inside a minecart. Offsetting Y location.");
|
||||
Logging.finer("Player was inside a minecart. Offsetting Y location.");
|
||||
}
|
||||
this.plugin.log(Level.FINE, "Had to look for a bit, but I found a safe place for ya!");
|
||||
Logging.finer("Had to look for a bit, but I found a safe place for ya!");
|
||||
return safeLocation;
|
||||
}
|
||||
if (e instanceof Player) {
|
||||
Player p = (Player) e;
|
||||
this.plugin.getMessaging().sendMessage(p, "No safe locations found!", false);
|
||||
this.plugin.log(Level.FINER, "No safe location found for " + p.getName());
|
||||
Logging.finer("No safe location found for " + p.getName());
|
||||
} else if (e.getPassenger() instanceof Player) {
|
||||
Player p = (Player) e.getPassenger();
|
||||
this.plugin.getMessaging().sendMessage(p, "No safe locations found!", false);
|
||||
this.plugin.log(Level.FINER, "No safe location found for " + p.getName());
|
||||
Logging.finer("No safe location found for " + p.getName());
|
||||
}
|
||||
this.plugin.log(Level.FINE, "Sorry champ, you're basically trying to teleport into a minefield. I should just kill you now.");
|
||||
Logging.fine("Sorry champ, you're basically trying to teleport into a minefield. I should just kill you now.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.api.WorldPurger;
|
||||
import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
@@ -36,25 +37,25 @@ import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Public facing API to add/remove Multiverse worlds.
|
||||
*/
|
||||
public class WorldManager implements MVWorldManager {
|
||||
private final MultiverseCore plugin;
|
||||
private final Pattern worldNamePattern = Pattern.compile("[a-zA-Z0-9/._-]+");
|
||||
private final WorldPurger worldPurger;
|
||||
private final Map<String, MultiverseWorld> worlds;
|
||||
private Map<String, WorldProperties> worldsFromTheConfig;
|
||||
@@ -62,8 +63,6 @@ public class WorldManager implements MVWorldManager {
|
||||
private Map<String, String> defaultGens;
|
||||
private String firstSpawn;
|
||||
|
||||
private static final List<String> CLONE_IGNORE_FILES = Arrays.asList("session.lock", "uid.dat");
|
||||
|
||||
public WorldManager(MultiverseCore core) {
|
||||
this.plugin = core;
|
||||
this.worldsFromTheConfig = new HashMap<String, WorldProperties>();
|
||||
@@ -92,191 +91,7 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.plugin.log(Level.WARNING, "Could not read 'bukkit.yml'. Any Default worldgenerators will not be loaded!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes cloning easier to understand and manage.
|
||||
*/
|
||||
private class CloneHelper {
|
||||
private String oldName;
|
||||
private String newName;
|
||||
private File oldWorldFile;
|
||||
private File newWorldFile;
|
||||
private MultiverseWorld oldWorld;
|
||||
|
||||
public CloneHelper(String oldName, String newName) {
|
||||
this.oldName = oldName;
|
||||
this.newName = newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The clone operation.
|
||||
*
|
||||
* @return True if clone is successful, false otherwise.
|
||||
*/
|
||||
public boolean run() {
|
||||
if (!validCloneParameters()) {
|
||||
Logging.warning("Invalid clone parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
initWorldFiles();
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.warning("Folder for new world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
|
||||
oldWorld = getMVWorld(oldName);
|
||||
if (!isOldWorldLoadable()) {
|
||||
Logging.severe("Old world '%s' is not loadable", oldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean wasAutoSave = manuallySaveWorld();
|
||||
|
||||
if (!copyWorldFolder()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
revertBackAutoSave(wasAutoSave);
|
||||
|
||||
return initNewCloneWorld();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that world with oldName can be clone to a world called newName.
|
||||
*
|
||||
* @return True if parameters are valid, otherwise false.
|
||||
*/
|
||||
private boolean validCloneParameters() {
|
||||
String originalOldName = oldName;
|
||||
if (!isWorldFromConfig(oldName)) {
|
||||
oldName = getWorldByAliasFromConfig(oldName);
|
||||
}
|
||||
|
||||
if (oldName == null) {
|
||||
Logging.warning("Old world '%s' does not exist", originalOldName);
|
||||
return false;
|
||||
}
|
||||
if (isWorldFromConfig(newName)) {
|
||||
Logging.warning("New world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
if (!isValidWorldName(newName)) {
|
||||
Logging.warning("New world name '%s' is invalid", newName);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get world folders from world container.
|
||||
*/
|
||||
private void initWorldFiles() {
|
||||
oldWorldFile = new File(plugin.getServer().getWorldContainer(), oldName);
|
||||
newWorldFile = new File(plugin.getServer().getWorldContainer(), newName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that old world can be loaded and saved properly.
|
||||
*
|
||||
* @return True if old world can be loaded successfully, false otherwise.
|
||||
*/
|
||||
private boolean isOldWorldLoadable() {
|
||||
if (oldWorld != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.fine("Old world '%s' is currently unloaded. Attempting to load it...", oldName);
|
||||
WorldProperties props = worldsFromTheConfig.get(oldName);
|
||||
boolean wasLoadSpawn = worldsFromTheConfig.get(oldName).isKeepingSpawnInMemory();
|
||||
if (wasLoadSpawn) {
|
||||
props.setKeepSpawnInMemory(false);
|
||||
}
|
||||
|
||||
if (!loadWorld(oldName)) {
|
||||
Logging.severe("Failed to load the old world '%s'", oldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
getMVWorld(oldName).getCBWorld().setAutoSave(false);
|
||||
|
||||
if (!unloadWorld(oldName, true)) {
|
||||
Logging.severe("Failed to unload the old world '%S'", oldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wasLoadSpawn) {
|
||||
props.setKeepSpawnInMemory(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicating old world folder to the new world folder.
|
||||
*
|
||||
* @return True if copy process was successful, false otherwise.
|
||||
*/
|
||||
private boolean copyWorldFolder() {
|
||||
Logging.fine("Copying files for world '%s'", oldName);
|
||||
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, CLONE_IGNORE_FILES, Logging.getLogger()) || !newWorldFile.exists()) {
|
||||
Logging.severe("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
}
|
||||
Logging.fine("Succeeded at copying files");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure world is save being copying world files.
|
||||
*
|
||||
* @return Previous auto-save setting for the old world.
|
||||
*/
|
||||
private boolean manuallySaveWorld() {
|
||||
if (oldWorld != null && oldWorld.getCBWorld().isAutoSave()) {
|
||||
Logging.config("Saving world '%s'", oldName);
|
||||
oldWorld.getCBWorld().setAutoSave(false);
|
||||
oldWorld.getCBWorld().save();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void revertBackAutoSave(boolean wasAutoSave) {
|
||||
if (oldWorld != null && wasAutoSave) {
|
||||
Logging.fine("Revert back to enabling auto-save");
|
||||
oldWorld.getCBWorld().setAutoSave(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize new properties with old ones.
|
||||
*/
|
||||
private void copyPropertiesToNewWorld() {
|
||||
WorldProperties newProps = new WorldProperties();
|
||||
newProps.copyValues(worldsFromTheConfig.get(oldName));
|
||||
newProps.setAlias(""); // don't keep the alias the same -- that would be useless
|
||||
worldsFromTheConfig.put(newName, newProps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load up the newly copied clone world.
|
||||
*/
|
||||
private boolean initNewCloneWorld() {
|
||||
copyPropertiesToNewWorld();
|
||||
if (!saveWorldsConfig()) {
|
||||
Logging.severe("Failed to save worlds.yml");
|
||||
return false;
|
||||
}
|
||||
if (!doLoad(newName)) {
|
||||
Logging.severe("Failed to load the cloned world '" + newName + "'");
|
||||
return false;
|
||||
}
|
||||
Logging.fine("Succeeded at loading cloned world '" + newName + "'");
|
||||
return true;
|
||||
Logging.warning("Could not read 'bukkit.yml'. Any Default worldgenerators will not be loaded!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +110,113 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean cloneWorld(String oldName, String newName) {
|
||||
return new CloneHelper(oldName, newName).run();
|
||||
// Make sure we already know about the old world and that we don't
|
||||
// already know about the new world.
|
||||
if (!this.worldsFromTheConfig.containsKey(oldName)) {
|
||||
for (Map.Entry<String, WorldProperties> entry : this.worldsFromTheConfig.entrySet()) {
|
||||
if (oldName.equals(entry.getValue().getAlias())) {
|
||||
oldName = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!this.worldsFromTheConfig.containsKey(oldName)) {
|
||||
Logging.warning("Old world '%s' does not exist", oldName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this.isMVWorld(newName)) {
|
||||
Logging.warning("New world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for valid world name
|
||||
if (!(WorldNameChecker.isValidWorldName(oldName) && WorldNameChecker.isValidWorldName(newName))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File oldWorldFile = new File(this.plugin.getServer().getWorldContainer(), oldName);
|
||||
final File newWorldFile = new File(this.plugin.getServer().getWorldContainer(), newName);
|
||||
final List<String> ignoreFiles = new ArrayList<>(Arrays.asList("session.lock", "uid.dat"));
|
||||
|
||||
// Make sure the new world doesn't exist outside of multiverse.
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.warning("Folder for new world '%s' already exists", newName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the old world... but just the metadata.
|
||||
boolean wasJustLoaded = false;
|
||||
boolean wasLoadSpawn = false;
|
||||
if (this.plugin.getServer().getWorld(oldName) == null) {
|
||||
wasJustLoaded = true;
|
||||
WorldProperties props = this.worldsFromTheConfig.get(oldName);
|
||||
wasLoadSpawn = props.isKeepingSpawnInMemory();
|
||||
if (wasLoadSpawn) {
|
||||
// No chunks please.
|
||||
props.setKeepSpawnInMemory(false);
|
||||
}
|
||||
if (!this.loadWorld(oldName)) {
|
||||
return false;
|
||||
}
|
||||
this.plugin.getServer().getWorld(oldName).setAutoSave(false);
|
||||
}
|
||||
|
||||
// Grab a bit of metadata from the old world.
|
||||
MultiverseWorld oldWorld = getMVWorld(oldName);
|
||||
|
||||
// Don't need the loaded world anymore.
|
||||
if (wasJustLoaded) {
|
||||
this.unloadWorld(oldName, true);
|
||||
oldWorld = null;
|
||||
if (wasLoadSpawn) {
|
||||
this.worldsFromTheConfig.get(oldName).setKeepSpawnInMemory(true);
|
||||
}
|
||||
}
|
||||
|
||||
boolean wasAutoSave = false;
|
||||
if (oldWorld != null && oldWorld.getCBWorld().isAutoSave()) {
|
||||
wasAutoSave = true;
|
||||
Logging.config("Saving world '%s'", oldName);
|
||||
oldWorld.getCBWorld().setAutoSave(false);
|
||||
oldWorld.getCBWorld().save();
|
||||
}
|
||||
Logging.config("Copying files for world '%s'", oldName);
|
||||
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, ignoreFiles)) {
|
||||
Logging.warning("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
}
|
||||
if (oldWorld != null && wasAutoSave) {
|
||||
oldWorld.getCBWorld().setAutoSave(true);
|
||||
}
|
||||
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.fine("Succeeded at copying files");
|
||||
|
||||
// initialize new properties with old ones
|
||||
WorldProperties newProps = new WorldProperties();
|
||||
newProps.copyValues(this.worldsFromTheConfig.get(oldName));
|
||||
// don't keep the alias the same -- that would be useless
|
||||
newProps.setAlias("");
|
||||
// store the new properties in worlds config map
|
||||
this.worldsFromTheConfig.put(newName, newProps);
|
||||
|
||||
// save the worlds config to disk (worlds.yml)
|
||||
if (!saveWorldsConfig()) {
|
||||
Logging.severe("Failed to save worlds.yml");
|
||||
return false;
|
||||
}
|
||||
|
||||
// actually load the world
|
||||
if (doLoad(newName)) {
|
||||
Logging.fine("Succeeded at loading cloned world '" + newName + "'");
|
||||
return true;
|
||||
}
|
||||
Logging.severe("Failed to load the cloned world '" + newName + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.warning("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +238,9 @@ public class WorldManager implements MVWorldManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isValidWorldName(name)) {
|
||||
if (!WorldNameChecker.isValidWorldName(name)) {
|
||||
Logging.warning("Invalid world name '" + name + "'");
|
||||
Logging.warning("World name should not contain spaces or special characters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -363,7 +286,7 @@ public class WorldManager implements MVWorldManager {
|
||||
Logging.info(builder.toString());
|
||||
|
||||
if (!doLoad(c, true)) {
|
||||
this.plugin.log(Level.SEVERE, "Failed to Create/Load the world '" + name + "'");
|
||||
Logging.severe("Failed to Create/Load the world '" + name + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -436,7 +359,7 @@ public class WorldManager implements MVWorldManager {
|
||||
MultiverseWorld world = this.getMVWorld(this.firstSpawn);
|
||||
if (world == null) {
|
||||
// If the spawn world was unloaded, get the default world
|
||||
this.plugin.log(Level.WARNING, "The world specified as the spawn world (" + this.firstSpawn + ") did not exist!!");
|
||||
Logging.warning("The world specified as the spawn world (" + this.firstSpawn + ") did not exist!!");
|
||||
try {
|
||||
return this.getMVWorld(this.plugin.getServer().getWorlds().get(0));
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
@@ -464,14 +387,14 @@ public class WorldManager implements MVWorldManager {
|
||||
this.worldsFromTheConfig.get(name).cacheVirtualProperties();
|
||||
if (unloadBukkit && this.unloadWorldFromBukkit(name, true)) {
|
||||
this.worlds.remove(name);
|
||||
Logging.info("World '%s' was unloaded from memory.", name);
|
||||
Logging.info("World '%s' was unloaded from Bukkit.", name);
|
||||
return true;
|
||||
} else if (!unloadBukkit){
|
||||
this.worlds.remove(name);
|
||||
Logging.info("World '%s' was unloaded from memory.", name);
|
||||
Logging.info("World '%s' was unloaded from Multiverse.", name);
|
||||
return true;
|
||||
} else {
|
||||
Logging.warning("World '%s' could not be unloaded. Is it a default world?", name);
|
||||
Logging.warning("World '%s' could not be unloaded from Bukkit. Is it a default world?", name);
|
||||
}
|
||||
} else if (this.plugin.getServer().getWorld(name) != null) {
|
||||
Logging.warning("Hmm Multiverse does not know about this world but it's loaded in memory.");
|
||||
@@ -503,31 +426,16 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the world name is allowed
|
||||
*
|
||||
* @param name Name of the world
|
||||
* @return True if the world world name is valid based on regex
|
||||
*/
|
||||
private boolean isValidWorldName(String name) {
|
||||
if (!worldNamePattern.matcher(name).matches()) {
|
||||
Logging.warning("Invalid world name '" + name + "'");
|
||||
Logging.warning("World name should not contain spaces or special characters!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void brokenWorld(String name) {
|
||||
this.plugin.log(Level.SEVERE, "The world '" + name + "' could NOT be loaded because it contains errors and is probably corrupt!");
|
||||
this.plugin.log(Level.SEVERE, "Try using Minecraft Region Fixer to repair your world! '" + name + "'");
|
||||
this.plugin.log(Level.SEVERE, "https://github.com/Fenixin/Minecraft-Region-Fixer");
|
||||
Logging.severe("The world '" + name + "' could NOT be loaded because it contains errors and is probably corrupt!");
|
||||
Logging.severe("Try using Minecraft Region Fixer to repair your world! '" + name + "'");
|
||||
Logging.severe("https://github.com/Fenixin/Minecraft-Region-Fixer");
|
||||
}
|
||||
|
||||
private void nullWorld(String name) {
|
||||
this.plugin.log(Level.SEVERE, "The world '" + name + "' could NOT be loaded because the server didn't like it!");
|
||||
this.plugin.log(Level.SEVERE, "We don't really know why this is. Contact the developer of your server software!");
|
||||
this.plugin.log(Level.SEVERE, "Server version info: " + Bukkit.getServer().getVersion());
|
||||
Logging.severe("The world '" + name + "' could NOT be loaded because the server didn't like it!");
|
||||
Logging.severe("We don't really know why this is. Contact the developer of your server software!");
|
||||
Logging.severe("Server version info: " + Bukkit.getServer().getVersion());
|
||||
}
|
||||
|
||||
private boolean doLoad(String name) {
|
||||
@@ -567,8 +475,8 @@ public class WorldManager implements MVWorldManager {
|
||||
throw new IllegalArgumentException("That world is already loaded!");
|
||||
|
||||
if (!ignoreExists && !new File(this.plugin.getServer().getWorldContainer(), worldName).exists() && !new File(this.plugin.getServer().getWorldContainer().getParent(), worldName).exists()) {
|
||||
this.plugin.log(Level.WARNING, "WorldManager: Can't load this world because the folder was deleted/moved: " + worldName);
|
||||
this.plugin.log(Level.WARNING, "Use '/mv remove' to remove it from the config!");
|
||||
Logging.warning("WorldManager: Can't load this world because the folder was deleted/moved: " + worldName);
|
||||
Logging.warning("Use '/mv remove' to remove it from the config!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -615,7 +523,7 @@ public class WorldManager implements MVWorldManager {
|
||||
MVWorldDeleteEvent mvwde = new MVWorldDeleteEvent(getMVWorld(name), removeFromConfig);
|
||||
this.plugin.getServer().getPluginManager().callEvent(mvwde);
|
||||
if (mvwde.isCancelled()) {
|
||||
this.plugin.log(Level.FINE, "Tried to delete a world, but the event was cancelled!");
|
||||
Logging.fine("Tried to delete a world, but the event was cancelled!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -631,7 +539,7 @@ public class WorldManager implements MVWorldManager {
|
||||
|
||||
try {
|
||||
File worldFile = world.getWorldFolder();
|
||||
plugin.log(Level.FINER, "deleteWorld(): worldFile: " + worldFile.getAbsolutePath());
|
||||
Logging.finer("deleteWorld(): worldFile: " + worldFile.getAbsolutePath());
|
||||
if (deleteWorldFolder ? FileUtils.deleteFolder(worldFile) : FileUtils.deleteFolderContents(worldFile)) {
|
||||
Logging.info("World '%s' was DELETED.", name);
|
||||
return true;
|
||||
@@ -709,6 +617,14 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public MultiverseWorld getMVWorld(String name) {
|
||||
return this.getMVWorld(name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MultiverseWorld getMVWorld(String name, boolean checkAliases) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -716,7 +632,7 @@ public class WorldManager implements MVWorldManager {
|
||||
if (world != null) {
|
||||
return world;
|
||||
}
|
||||
return this.getMVWorldByAlias(name);
|
||||
return (checkAliases) ? this.getMVWorldByAlias(name) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,7 +641,7 @@ public class WorldManager implements MVWorldManager {
|
||||
@Override
|
||||
public MultiverseWorld getMVWorld(World world) {
|
||||
if (world != null) {
|
||||
return this.getMVWorld(world.getName());
|
||||
return this.getMVWorld(world.getName(), false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -750,7 +666,15 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean isMVWorld(final String name) {
|
||||
return (this.worlds.containsKey(name) || isMVWorldAlias(name));
|
||||
return this.isMVWorld(name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isMVWorld(final String name, boolean checkAliases) {
|
||||
return this.worlds.containsKey(name) || (checkAliases && this.isMVWorldAlias(name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -776,19 +700,6 @@ public class WorldManager implements MVWorldManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isWorldFromConfig(String name) {
|
||||
return this.worldsFromTheConfig.containsKey(name);
|
||||
}
|
||||
|
||||
private String getWorldByAliasFromConfig(String name) {
|
||||
return this.worldsFromTheConfig.entrySet()
|
||||
.stream()
|
||||
.filter(worldEntry -> name.equals(worldEntry.getValue().getAlias()))
|
||||
.map(Map.Entry::getKey)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -958,7 +869,7 @@ public class WorldManager implements MVWorldManager {
|
||||
this.configWorlds.save(new File(this.plugin.getDataFolder(), "worlds.yml"));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
this.plugin.log(Level.SEVERE, "Could not save worlds.yml. Please check your settings.");
|
||||
Logging.severe("Could not save worlds.yml. Please check your settings.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -986,12 +897,23 @@ public class WorldManager implements MVWorldManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed) {
|
||||
return regenWorld(name, useNewSeed, randomSeed, seed, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed, boolean keepGameRules) {
|
||||
MultiverseWorld world = this.getMVWorld(name);
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
Logging.warning("Unable to regen a world that does not exist!");
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Player> ps = world.getCBWorld().getPlayers();
|
||||
|
||||
// Apply new seed if needed.
|
||||
if (useNewSeed) {
|
||||
long theSeed;
|
||||
|
||||
@@ -1007,19 +929,64 @@ public class WorldManager implements MVWorldManager {
|
||||
|
||||
world.setSeed(theSeed);
|
||||
}
|
||||
|
||||
WorldType type = world.getWorldType();
|
||||
|
||||
if (this.deleteWorld(name, false, false)) {
|
||||
this.doLoad(name, true, type);
|
||||
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
|
||||
Location newSpawn = world.getSpawnLocation();
|
||||
// Send all players that were in the old world, BACK to it!
|
||||
for (Player p : ps) {
|
||||
teleporter.safelyTeleport(null, p, newSpawn, true);
|
||||
// Save current GameRules if needed.
|
||||
Map<GameRule<?>, Object> gameRuleMap = null;
|
||||
if (keepGameRules) {
|
||||
gameRuleMap = new HashMap<>(GameRule.values().length);
|
||||
World CBWorld = world.getCBWorld();
|
||||
for (GameRule<?> gameRule : GameRule.values()) {
|
||||
// Only save if not default value.
|
||||
Object value = CBWorld.getGameRuleValue(gameRule);
|
||||
if (value != CBWorld.getGameRuleDefault(gameRule)) {
|
||||
gameRuleMap.put(gameRule, value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
// Do the regen.
|
||||
if (!this.deleteWorld(name, false, false)) {
|
||||
Logging.severe("Unable to regen world as world cannot be deleted.");
|
||||
return false;
|
||||
}
|
||||
if (!this.doLoad(name, true, type)) {
|
||||
Logging.severe("Unable to regen world as world cannot be loaded.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get new MultiverseWorld reference.
|
||||
world = this.getMVWorld(name);
|
||||
|
||||
// Load back GameRules if needed.
|
||||
if (keepGameRules) {
|
||||
Logging.fine("Restoring previous world's GameRules...");
|
||||
World CBWorld = world.getCBWorld();
|
||||
for (Map.Entry<GameRule<?>, Object> gameRuleEntry : gameRuleMap.entrySet()) {
|
||||
if (!setGameRuleValue(CBWorld, gameRuleEntry.getKey(), gameRuleEntry.getValue())) {
|
||||
Logging.warning("Unable to set GameRule '%s' to '%s' on regen world.",
|
||||
gameRuleEntry.getKey().getName(), gameRuleEntry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send all players that were in the old world, BACK to it!
|
||||
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
|
||||
Location newSpawn = world.getSpawnLocation();
|
||||
for (Player p : ps) {
|
||||
teleporter.safelyTeleport(null, p, newSpawn, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private <T> boolean setGameRuleValue(World world, GameRule<T> gameRule, Object value) {
|
||||
try {
|
||||
return world.setGameRule(gameRule, (T) value);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1045,4 +1012,21 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Collection<String> getPotentialWorlds() {
|
||||
File worldContainer = this.plugin.getServer().getWorldContainer();
|
||||
if (worldContainer == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.stream(worldContainer.listFiles())
|
||||
.filter(File::isDirectory)
|
||||
.filter(folder -> !this.isMVWorld(folder.getName(), false))
|
||||
.filter(WorldNameChecker::isValidWorldFolder)
|
||||
.map(File::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <p>Utility class in helping to check the status of a world name and it's associated world folder.</p>
|
||||
*
|
||||
* <p>Note this is for preliminary checks and better command output. A valid result will suggest but not
|
||||
* 100% determine that a world name can be created, loaded or imported.</p>
|
||||
*/
|
||||
public class WorldNameChecker {
|
||||
|
||||
private static final Pattern WORLD_NAME_PATTERN = Pattern.compile("[a-zA-Z0-9/._-]+");
|
||||
private static final Set<String> BLACKLIST_NAMES = Collections.unmodifiableSet(new HashSet<String>() {{
|
||||
add("plugins");
|
||||
add("logs");
|
||||
add("cache");
|
||||
add("crash-reports");
|
||||
}});
|
||||
|
||||
/**
|
||||
* Checks if a world name is valid.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public static boolean isValidWorldName(@Nullable String worldName) {
|
||||
return checkName(worldName) == NameStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current validity status of a world name.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return The resulting name status.
|
||||
*/
|
||||
@NotNull
|
||||
public static NameStatus checkName(@Nullable String worldName) {
|
||||
if (BLACKLIST_NAMES.contains(worldName)) {
|
||||
return NameStatus.BLACKLISTED;
|
||||
}
|
||||
if (worldName == null || !WORLD_NAME_PATTERN.matcher(worldName).matches()) {
|
||||
return NameStatus.INVALID_CHARS;
|
||||
}
|
||||
return NameStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a world name has a valid world folder.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public static boolean isValidWorldFolder(@Nullable String worldName) {
|
||||
return checkFolder(worldName) == FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a world folder is valid.
|
||||
*
|
||||
* @param worldFolder The world folder to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public static boolean isValidWorldFolder(@Nullable File worldFolder) {
|
||||
return checkFolder(worldFolder) == FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current folder status for a world name.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return The resulting folder status.
|
||||
*/
|
||||
@NotNull
|
||||
public static FolderStatus checkFolder(@Nullable String worldName) {
|
||||
if (worldName == null) {
|
||||
return FolderStatus.DOES_NOT_EXIST;
|
||||
}
|
||||
File worldFolder = new File(Bukkit.getWorldContainer(), worldName);
|
||||
return checkFolder(worldFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current folder status.
|
||||
*
|
||||
* @param worldFolder The world folder to check on.
|
||||
* @return The resulting folder status.
|
||||
*/
|
||||
@NotNull
|
||||
public static FolderStatus checkFolder(@Nullable File worldFolder) {
|
||||
if (worldFolder == null || !worldFolder.exists() || !worldFolder.isDirectory()) {
|
||||
return FolderStatus.DOES_NOT_EXIST;
|
||||
}
|
||||
if (!folderHasDat(worldFolder)) {
|
||||
return FolderStatus.NOT_A_WORLD;
|
||||
}
|
||||
return FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* A very basic check to see if a folder has a level.dat file. If it does, we can safely assume
|
||||
* it's a world folder.
|
||||
*
|
||||
* @param worldFolder The File that may be a world.
|
||||
* @return True if it looks like a world, else false.
|
||||
*/
|
||||
private static boolean folderHasDat(@NotNull File worldFolder) {
|
||||
File[] files = worldFolder.listFiles((file, name) -> name.toLowerCase().endsWith(".dat"));
|
||||
return files != null && files.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result after checking validity of world name.
|
||||
*/
|
||||
public enum NameStatus {
|
||||
/**
|
||||
* Name is valid.
|
||||
*/
|
||||
VALID,
|
||||
|
||||
/**
|
||||
* Name not valid as it contains invalid characters.
|
||||
*/
|
||||
INVALID_CHARS,
|
||||
|
||||
/**
|
||||
* Name not valid as it is deemed blacklisted.
|
||||
*/
|
||||
BLACKLISTED
|
||||
}
|
||||
|
||||
/**
|
||||
* Result after checking validity of world folder.
|
||||
*/
|
||||
public enum FolderStatus {
|
||||
/**
|
||||
* Folder is valid.
|
||||
*/
|
||||
VALID,
|
||||
|
||||
/**
|
||||
* Folder exist, but contents in it doesnt look like a world.
|
||||
*/
|
||||
NOT_A_WORLD,
|
||||
|
||||
/**
|
||||
* Folder does not exist.
|
||||
*/
|
||||
DOES_NOT_EXIST
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package com.onarandombox.MultiverseCore.utils.metrics;
|
||||
|
||||
import org.bstats.charts.AdvancedPie;
|
||||
import org.bstats.charts.MultiLineChart;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bstats.bukkit.Metrics;
|
||||
|
||||
enum MetricsHelper {
|
||||
;
|
||||
|
||||
@@ -17,16 +18,16 @@ enum MetricsHelper {
|
||||
map.put(key, count + 1);
|
||||
}
|
||||
|
||||
static Metrics.AdvancedPie createAdvancedPieChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
static AdvancedPie createAdvancedPieChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
metricsFunc.accept(map);
|
||||
return new Metrics.AdvancedPie(chartId, () -> map);
|
||||
return new AdvancedPie(chartId, () -> map);
|
||||
}
|
||||
|
||||
static Metrics.MultiLineChart createMultiLineChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
static MultiLineChart createMultiLineChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
metricsFunc.accept(map);
|
||||
return new Metrics.MultiLineChart(chartId, () -> map);
|
||||
return new MultiLineChart(chartId, () -> map);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
||||
* A {@link URLShortener} using {@code bit.ly}. Requires an access token.
|
||||
*/
|
||||
class BitlyURLShortener extends URLShortener {
|
||||
private static final String ACCESS_TOKEN = "Bearer bitly-access-token";
|
||||
private static final String ACCESS_TOKEN = "Bearer @bitly-access-token@";
|
||||
private static final String BITLY_POST_REQUEST = "https://api-ssl.bitly.com/v4/shorten";
|
||||
|
||||
BitlyURLShortener() {
|
||||
@@ -27,7 +27,6 @@ class BitlyURLShortener extends URLShortener {
|
||||
@Override
|
||||
String encodeData(String data) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("domain", "j.mp");
|
||||
json.put("long_url", data);
|
||||
return json.toJSONString();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ authors: ['dumptruckman', 'Rigby', 'fernferret', 'lithium3141', 'main--']
|
||||
website: 'https://dev.bukkit.org/projects/multiverse-core'
|
||||
softdepend: ['Vault']
|
||||
api-version: 1.13
|
||||
version: maven-version-number
|
||||
version: ${version}
|
||||
commands:
|
||||
mv:
|
||||
description: Generic Multiverse Command
|
||||
|
||||
@@ -14,15 +14,9 @@ import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -31,9 +25,6 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class, JavaPluginLoader.class})
|
||||
@PowerMockIgnore("javax.script.*")
|
||||
public class TestDebugMode {
|
||||
TestInstanceCreator creator;
|
||||
Server mockServer;
|
||||
|
||||
@@ -7,35 +7,29 @@ import com.onarandombox.MultiverseCore.utils.MockWorldFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class, JavaPluginLoader.class})
|
||||
@PowerMockIgnore("javax.script.*")
|
||||
public class TestEntitySpawnRules {
|
||||
TestInstanceCreator creator;
|
||||
MultiverseCore core;
|
||||
@@ -107,42 +101,42 @@ public class TestEntitySpawnRules {
|
||||
@Test
|
||||
public void test() {
|
||||
// test 1: no spawning at all allowed
|
||||
adjustSettings(false, false, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
|
||||
adjustSettings(false, false, Collections.emptyList(), Collections.emptyList());
|
||||
createAnimals();
|
||||
spawnAllNatural();
|
||||
verify(sheepEvent).setCancelled(true);
|
||||
verify(zombieEvent).setCancelled(true);
|
||||
|
||||
// test 2: only monsters
|
||||
adjustSettings(false, true, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
|
||||
adjustSettings(false, true, Collections.emptyList(), Collections.emptyList());
|
||||
createAnimals();
|
||||
spawnAllNatural();
|
||||
verify(sheepEvent).setCancelled(true);
|
||||
verify(zombieEvent).setCancelled(false);
|
||||
|
||||
// test 3: all spawning allowed
|
||||
adjustSettings(true, true, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
|
||||
adjustSettings(true, true, Collections.emptyList(), Collections.emptyList());
|
||||
createAnimals();
|
||||
spawnAllNatural();
|
||||
verify(sheepEvent).setCancelled(false);
|
||||
verify(zombieEvent).setCancelled(false);
|
||||
|
||||
// test 4: no spawning with zombie exception
|
||||
adjustSettings(false, false, Collections.EMPTY_LIST, Arrays.asList("ZOMBIE"));
|
||||
adjustSettings(false, false, Collections.emptyList(), Arrays.asList("ZOMBIE"));
|
||||
createAnimals();
|
||||
spawnAllNatural();
|
||||
verify(sheepEvent).setCancelled(true);
|
||||
verify(zombieEvent).setCancelled(false);
|
||||
|
||||
// test 5: all spawning with sheep exception
|
||||
adjustSettings(true, true, Arrays.asList("SHEEP"), Collections.EMPTY_LIST);
|
||||
adjustSettings(true, true, Arrays.asList("SHEEP"), Collections.emptyList());
|
||||
createAnimals();
|
||||
spawnAllNatural();
|
||||
verify(sheepEvent).setCancelled(true);
|
||||
verify(zombieEvent).setCancelled(false);
|
||||
|
||||
// test 6: eggs
|
||||
adjustSettings(false, false, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
|
||||
adjustSettings(false, false, Collections.emptyList(), Collections.emptyList());
|
||||
createAnimals();
|
||||
spawnAll(SpawnReason.SPAWNER_EGG);
|
||||
verify(sheepEvent, never()).setCancelled(anyBoolean());
|
||||
@@ -157,6 +151,6 @@ public class TestEntitySpawnRules {
|
||||
when(zombie.getType()).thenReturn(EntityType.ZOMBIE);
|
||||
when(zombie.getWorld()).thenReturn(this.cbworld);
|
||||
|
||||
when(cbworld.getEntities()).thenReturn(Arrays.asList((Entity) sheep, (Entity) zombie));
|
||||
when(cbworld.getEntities()).thenReturn(Arrays.asList(sheep, zombie));
|
||||
}
|
||||
}
|
||||
@@ -2,24 +2,17 @@ package com.onarandombox.MultiverseCore;
|
||||
|
||||
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class, JavaPluginLoader.class})
|
||||
@PowerMockIgnore("javax.script.*")
|
||||
public class TestEntryFeeConversion {
|
||||
|
||||
private TestInstanceCreator creator;
|
||||
@@ -50,6 +43,10 @@ public class TestEntryFeeConversion {
|
||||
WorldProperties props = new WorldProperties(config);
|
||||
assertNull(props.entryfee.getCurrency());
|
||||
|
||||
entryFee.put("currency", 0);
|
||||
props = new WorldProperties(config);
|
||||
assertNull(props.entryfee.getCurrency());
|
||||
|
||||
entryFee.put("currency", 1);
|
||||
props = new WorldProperties(config);
|
||||
assertEquals(Material.STONE, props.entryfee.getCurrency());
|
||||
|
||||
@@ -6,24 +6,16 @@ import org.bukkit.Server;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class, JavaPluginLoader.class })
|
||||
@PowerMockIgnore("javax.script.*")
|
||||
public class TestModifyCommand {
|
||||
TestInstanceCreator creator;
|
||||
Server mockServer;
|
||||
|
||||
@@ -13,8 +13,6 @@ import com.onarandombox.MultiverseCore.configuration.SpawnLocation;
|
||||
import com.onarandombox.MultiverseCore.listeners.MVAsyncPlayerChatListener;
|
||||
import com.onarandombox.MultiverseCore.utils.MockWorldFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
|
||||
import com.onarandombox.MultiverseCore.utils.WorldManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -36,33 +34,26 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.weather.ThunderChangeEvent;
|
||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.internal.verification.VerificationModeFactory;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ PluginManager.class, MultiverseCore.class, Permission.class, Bukkit.class,
|
||||
WeatherChangeEvent.class, ThunderChangeEvent.class, AsyncPlayerChatEvent.class,
|
||||
PlayerJoinEvent.class, PlayerRespawnEvent.class, EntityRegainHealthEvent.class,
|
||||
FoodLevelChangeEvent.class, WorldManager.class, PluginDescriptionFile.class, JavaPluginLoader.class })
|
||||
@PowerMockIgnore("javax.script.*")
|
||||
public class TestWorldProperties {
|
||||
private TestInstanceCreator creator;
|
||||
private MultiverseCore core;
|
||||
@@ -122,7 +113,7 @@ public class TestWorldProperties {
|
||||
String[] netherArgs = new String[] { "import", "world_nether", "nether" };
|
||||
core.onCommand(mockCommandSender, mockCommand, "", netherArgs);
|
||||
verify(mockCommandSender).sendMessage("Starting import of world 'world_nether'...");
|
||||
verify(mockCommandSender, VerificationModeFactory.times(2)).sendMessage(
|
||||
verify(mockCommandSender, times(2)).sendMessage(
|
||||
ChatColor.GREEN + "Complete!");
|
||||
|
||||
assertEquals(core.getServer().getWorlds().size(), 2);
|
||||
@@ -222,7 +213,7 @@ public class TestWorldProperties {
|
||||
assertTrue(mvWorld.setColor("BLACK"));
|
||||
assertFalse(mvWorld.setColor("INVALID COLOR"));
|
||||
assertEquals(ChatColor.BLACK, mvWorld.getColor());
|
||||
assertEquals(ChatColor.BLACK.toString() + "alias" + ChatColor.WHITE.toString(), mvWorld.getColoredWorldString());
|
||||
assertEquals(ChatColor.BLACK + "alias" + ChatColor.WHITE, mvWorld.getColoredWorldString());
|
||||
mvWorld.setPVPMode(false);
|
||||
assertEquals(false, mvWorld.isPVPEnabled());
|
||||
assertTrue(mvWorld.setScaling(2D));
|
||||
@@ -329,7 +320,7 @@ public class TestWorldProperties {
|
||||
assertEquals(true, mvWorld.isHidden());
|
||||
assertEquals("alias", mvWorld.getAlias());
|
||||
assertEquals(ChatColor.GREEN, mvWorld.getColor());
|
||||
assertEquals(ChatColor.GREEN.toString() + "alias" + ChatColor.WHITE.toString(), mvWorld.getColoredWorldString());
|
||||
assertEquals(ChatColor.GREEN + "alias" + ChatColor.WHITE, mvWorld.getColoredWorldString());
|
||||
assertEquals(false, mvWorld.isPVPEnabled());
|
||||
assertEquals(2D, mvWorld.getScaling(), 0);
|
||||
assertSame(worldManager.getMVWorld("world_nether").getCBWorld(),
|
||||
@@ -366,36 +357,36 @@ public class TestWorldProperties {
|
||||
when(mockPlayer.hasPlayedBefore()).thenReturn(true);
|
||||
when(mockPlayer.hasPermission("multiverse.access.world")).thenReturn(true);
|
||||
when(mockPlayer.getName()).thenReturn("MultiverseMan");
|
||||
playerChatEvent = PowerMockito.mock(AsyncPlayerChatEvent.class);
|
||||
playerChatEvent = mock(AsyncPlayerChatEvent.class);
|
||||
when(playerChatEvent.getPlayer()).thenReturn(mockPlayer);
|
||||
when(playerChatEvent.getFormat()).thenReturn("format");
|
||||
// player join
|
||||
mockNewPlayer = mock(Player.class);
|
||||
when(mockNewPlayer.hasPlayedBefore()).thenReturn(false);
|
||||
playerJoinEvent = PowerMockito.mock(PlayerJoinEvent.class);
|
||||
playerJoinEvent = mock(PlayerJoinEvent.class);
|
||||
when(playerJoinEvent.getPlayer()).thenReturn(mockPlayer);
|
||||
playerNewJoinEvent = PowerMockito.mock(PlayerJoinEvent.class);
|
||||
playerNewJoinEvent = mock(PlayerJoinEvent.class);
|
||||
when(playerNewJoinEvent.getPlayer()).thenReturn(mockNewPlayer);
|
||||
// player respawn
|
||||
playerRespawnBed = PowerMockito.mock(PlayerRespawnEvent.class);
|
||||
playerRespawnBed = mock(PlayerRespawnEvent.class);
|
||||
when(playerRespawnBed.getPlayer()).thenReturn(mockPlayer);
|
||||
when(playerRespawnBed.isBedSpawn()).thenReturn(true);
|
||||
playerRespawnNormal = PowerMockito.mock(PlayerRespawnEvent.class);
|
||||
playerRespawnNormal = mock(PlayerRespawnEvent.class);
|
||||
when(playerRespawnNormal.getPlayer()).thenReturn(mockPlayer);
|
||||
when(playerRespawnNormal.isBedSpawn()).thenReturn(false);
|
||||
//// Entity events
|
||||
mockHumanEntity = mock(HumanEntity.class);
|
||||
// entity regain health
|
||||
entityRegainHealthEvent = PowerMockito.mock(EntityRegainHealthEvent.class);
|
||||
entityRegainHealthEvent = mock(EntityRegainHealthEvent.class);
|
||||
when(entityRegainHealthEvent.getRegainReason()).thenReturn(RegainReason.REGEN);
|
||||
when(mockHumanEntity.getLocation()).thenReturn(new Location(world, 0, 0, 0));
|
||||
when(entityRegainHealthEvent.getEntity()).thenReturn(mockHumanEntity);
|
||||
// entity food level change event
|
||||
entityFoodLevelChangeEvent = PowerMockito.mock(FoodLevelChangeEvent.class);
|
||||
entityFoodLevelChangeEvent = mock(FoodLevelChangeEvent.class);
|
||||
// this won't do anything since we're not mocking a player,
|
||||
// but the plugin should be able to handle this!
|
||||
when(entityFoodLevelChangeEvent.getEntity()).thenReturn(mockHumanEntity);
|
||||
entityFoodLevelRiseEvent = PowerMockito.mock(FoodLevelChangeEvent.class);
|
||||
entityFoodLevelRiseEvent = mock(FoodLevelChangeEvent.class);
|
||||
when(mockPlayer.getFoodLevel()).thenReturn(2);
|
||||
when(entityFoodLevelRiseEvent.getEntity()).thenReturn(mockPlayer);
|
||||
when(entityFoodLevelRiseEvent.getFoodLevel()).thenReturn(3);
|
||||
|
||||
@@ -4,28 +4,21 @@ import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.api.WorldPurger;
|
||||
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class, JavaPluginLoader.class })
|
||||
@PowerMockIgnore("javax.script.*")
|
||||
public class TestWorldPurger {
|
||||
TestInstanceCreator creator;
|
||||
MultiverseCore core;
|
||||
@@ -121,6 +114,6 @@ public class TestWorldPurger {
|
||||
zombie = mock(Zombie.class);
|
||||
when(zombie.getType()).thenReturn(EntityType.ZOMBIE);
|
||||
when(zombie.getWorld()).thenReturn(world);
|
||||
when(cbworld.getEntities()).thenReturn(Arrays.asList((Entity) sheep, (Entity) zombie));
|
||||
when(cbworld.getEntities()).thenReturn(Arrays.asList(sheep, zombie));
|
||||
}
|
||||
}
|
||||
@@ -12,39 +12,30 @@ import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
|
||||
import com.onarandombox.MultiverseCore.utils.MockWorldFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
|
||||
import com.onarandombox.MultiverseCore.utils.WorldCreatorMatcher;
|
||||
import com.onarandombox.MultiverseCore.utils.WorldManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.internal.verification.VerificationModeFactory;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static junit.framework.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ PluginManager.class, MultiverseCore.class, Permission.class, Bukkit.class, WorldManager.class,
|
||||
PluginDescriptionFile.class, JavaPluginLoader.class })
|
||||
@PowerMockIgnore("javax.script.*")
|
||||
public class TestWorldStuff {
|
||||
|
||||
private TestInstanceCreator creator;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -10,10 +11,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class FileUtilsTest {
|
||||
|
||||
@@ -81,7 +80,7 @@ public class FileUtilsTest {
|
||||
assertFalse(Files.isDirectory(targetChildDir));
|
||||
assertFalse(Files.isRegularFile(targetChildDirFile));
|
||||
|
||||
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile(), Logging.getLogger()));
|
||||
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile()));
|
||||
|
||||
assertTrue(Files.isDirectory(targetDir));
|
||||
assertTrue(Files.isRegularFile(targetFile));
|
||||
@@ -107,7 +106,7 @@ public class FileUtilsTest {
|
||||
assertFalse(Files.isRegularFile(targetChildDirFile));
|
||||
assertFalse(Files.isRegularFile(targetChildIgnoreFile));
|
||||
|
||||
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile(), excludeFiles, Logging.getLogger()));
|
||||
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile(), excludeFiles));
|
||||
|
||||
assertTrue(Files.isDirectory(targetDir));
|
||||
assertTrue(Files.isRegularFile(targetFile));
|
||||
@@ -129,7 +128,7 @@ public class FileUtilsTest {
|
||||
assertFalse(Files.isDirectory(targetChildDir));
|
||||
assertFalse(Files.isRegularFile(targetChildDirFile));
|
||||
|
||||
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile(), Logging.getLogger()));
|
||||
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile()));
|
||||
|
||||
assertTrue(Files.isDirectory(targetDir));
|
||||
assertTrue(Files.isRegularFile(targetFile));
|
||||
@@ -137,7 +136,7 @@ public class FileUtilsTest {
|
||||
assertTrue(Files.isRegularFile(targetChildDirFile));
|
||||
}
|
||||
|
||||
@Test()
|
||||
@Test
|
||||
public void copyFolder_intoExistingFolder_whereFileExists() throws Exception {
|
||||
Path targetDir = Files.createDirectory(tempDir.resolve("target"));
|
||||
Path targetFile = Files.createFile(targetDir.resolve("parentDirFile.txt"));
|
||||
@@ -145,6 +144,6 @@ public class FileUtilsTest {
|
||||
assertTrue(Files.isDirectory(targetDir));
|
||||
assertTrue(Files.isRegularFile(targetFile));
|
||||
|
||||
assertFalse(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile(), Logging.getLogger()));
|
||||
assertFalse(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile()));
|
||||
}
|
||||
}
|
||||
@@ -21,13 +21,17 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class MockWorldFactory {
|
||||
|
||||
|
||||
@@ -27,13 +27,9 @@ import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.internal.util.reflection.ReflectionMemberAccessor;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.powermock.api.easymock.PowerMock;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.MockGateway;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -44,15 +40,16 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.anyLong;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.isA;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class TestInstanceCreator {
|
||||
private MultiverseCore core;
|
||||
@@ -69,28 +66,20 @@ public class TestInstanceCreator {
|
||||
pluginDirectory.mkdirs();
|
||||
assertTrue(pluginDirectory.exists());
|
||||
|
||||
MockGateway.MOCK_STANDARD_METHODS = false;
|
||||
|
||||
// Initialize the Mock server.
|
||||
mockServer = mock(Server.class);
|
||||
JavaPluginLoader mockPluginLoader = PowerMock.createMock(JavaPluginLoader.class);
|
||||
Whitebox.setInternalState(mockPluginLoader, "server", mockServer);
|
||||
JavaPluginLoader mockPluginLoader = mock(JavaPluginLoader.class);
|
||||
new ReflectionMemberAccessor().set(JavaPluginLoader.class.getDeclaredField("server"), mockPluginLoader, mockServer);
|
||||
when(mockServer.getName()).thenReturn("TestBukkit");
|
||||
Logger.getLogger("Minecraft").setParent(Util.logger);
|
||||
when(mockServer.getLogger()).thenReturn(Util.logger);
|
||||
when(mockServer.getWorldContainer()).thenReturn(worldsDirectory);
|
||||
|
||||
// Return a fake PDF file.
|
||||
PluginDescriptionFile pdf = PowerMockito.spy(new PluginDescriptionFile("Multiverse-Core", "2.2-Test",
|
||||
PluginDescriptionFile pdf = spy(new PluginDescriptionFile("Multiverse-Core", "2.2-Test",
|
||||
"com.onarandombox.MultiverseCore.MultiverseCore"));
|
||||
when(pdf.getAuthors()).thenReturn(new ArrayList<String>());
|
||||
core = PowerMockito.spy(new MultiverseCore(mockPluginLoader, pdf, pluginDirectory, new File(pluginDirectory, "testPluginFile")));
|
||||
PowerMockito.doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
return null; // don't run metrics in tests
|
||||
}
|
||||
}).when(core, "setupMetrics");
|
||||
core = spy(new MultiverseCore(mockPluginLoader, pdf, pluginDirectory, new File(pluginDirectory, "testPluginFile")));
|
||||
|
||||
// Let's let all MV files go to bin/test
|
||||
doReturn(pluginDirectory).when(core).getDataFolder();
|
||||
@@ -103,7 +92,7 @@ public class TestInstanceCreator {
|
||||
JavaPlugin[] plugins = new JavaPlugin[] { core };
|
||||
|
||||
// Mock the Plugin Manager
|
||||
PluginManager mockPluginManager = PowerMockito.mock(PluginManager.class);
|
||||
PluginManager mockPluginManager = mock(PluginManager.class);
|
||||
when(mockPluginManager.getPlugins()).thenReturn(plugins);
|
||||
when(mockPluginManager.getPlugin("Multiverse-Core")).thenReturn(core);
|
||||
when(mockPluginManager.getPermission(anyString())).thenReturn(null);
|
||||
@@ -157,7 +146,7 @@ public class TestInstanceCreator {
|
||||
|
||||
when(mockServer.getPluginManager()).thenReturn(mockPluginManager);
|
||||
|
||||
when(mockServer.createWorld(ArgumentMatchers.isA(WorldCreator.class))).thenAnswer(
|
||||
when(mockServer.createWorld(isA(WorldCreator.class))).thenAnswer(
|
||||
new Answer<World>() {
|
||||
@Override
|
||||
public World answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -214,32 +203,39 @@ public class TestInstanceCreator {
|
||||
serverfield.set(core, mockServer);
|
||||
|
||||
// Set buscript
|
||||
Buscript buscript = PowerMockito.spy(new Buscript(core));
|
||||
Buscript buscript;
|
||||
Field buscriptfield = MultiverseCore.class.getDeclaredField("buscript");
|
||||
buscriptfield.setAccessible(true);
|
||||
|
||||
try {
|
||||
buscript = spy(new Buscript(core));
|
||||
when(buscript.getPlugin()).thenReturn(core);
|
||||
} catch (NullPointerException e) {
|
||||
buscript = null;
|
||||
}
|
||||
|
||||
buscriptfield.set(core, buscript);
|
||||
when(buscript.getPlugin()).thenReturn(core);
|
||||
|
||||
// Set worldManager
|
||||
WorldManager wm = PowerMockito.spy(new WorldManager(core));
|
||||
WorldManager wm = spy(new WorldManager(core));
|
||||
Field worldmanagerfield = MultiverseCore.class.getDeclaredField("worldManager");
|
||||
worldmanagerfield.setAccessible(true);
|
||||
worldmanagerfield.set(core, wm);
|
||||
|
||||
// Set playerListener
|
||||
MVPlayerListener pl = PowerMockito.spy(new MVPlayerListener(core));
|
||||
MVPlayerListener pl = spy(new MVPlayerListener(core));
|
||||
Field playerlistenerfield = MultiverseCore.class.getDeclaredField("playerListener");
|
||||
playerlistenerfield.setAccessible(true);
|
||||
playerlistenerfield.set(core, pl);
|
||||
|
||||
// Set entityListener
|
||||
MVEntityListener el = PowerMockito.spy(new MVEntityListener(core));
|
||||
MVEntityListener el = spy(new MVEntityListener(core));
|
||||
Field entitylistenerfield = MultiverseCore.class.getDeclaredField("entityListener");
|
||||
entitylistenerfield.setAccessible(true);
|
||||
entitylistenerfield.set(core, el);
|
||||
|
||||
// Set weatherListener
|
||||
MVWeatherListener wl = PowerMockito.spy(new MVWeatherListener(core));
|
||||
MVWeatherListener wl = spy(new MVWeatherListener(core));
|
||||
Field weatherlistenerfield = MultiverseCore.class.getDeclaredField("weatherListener");
|
||||
weatherlistenerfield.setAccessible(true);
|
||||
weatherlistenerfield.set(core, wl);
|
||||
@@ -257,9 +253,9 @@ public class TestInstanceCreator {
|
||||
when(commandSender.getServer()).thenReturn(mockServer);
|
||||
when(commandSender.getName()).thenReturn("MockCommandSender");
|
||||
when(commandSender.isPermissionSet(anyString())).thenReturn(true);
|
||||
when(commandSender.isPermissionSet(ArgumentMatchers.isA(Permission.class))).thenReturn(true);
|
||||
when(commandSender.isPermissionSet(isA(Permission.class))).thenReturn(true);
|
||||
when(commandSender.hasPermission(anyString())).thenReturn(true);
|
||||
when(commandSender.hasPermission(ArgumentMatchers.isA(Permission.class))).thenReturn(true);
|
||||
when(commandSender.hasPermission(isA(Permission.class))).thenReturn(true);
|
||||
when(commandSender.addAttachment(core)).thenReturn(null);
|
||||
when(commandSender.isOp()).thenReturn(true);
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ package com.onarandombox.MultiverseCore.utils;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
public class Util {
|
||||
private Util() {}
|
||||
|
||||
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user