Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d73d550293 | ||
|
|
0dedcd630d | ||
|
|
dc03a93dfe | ||
|
|
6ab98f8e35 | ||
|
|
216bd81bef | ||
|
|
91e3bfd050 | ||
|
|
8c32dd3e19 | ||
|
|
4390af779c | ||
|
|
3093b81fee | ||
|
|
1af696a05d |
No files matched your search
+1
-29
@@ -1,34 +1,6 @@
|
||||
[*]
|
||||
[*.java]
|
||||
charset=utf-8
|
||||
end_of_line=lf
|
||||
insert_final_newline=true
|
||||
indent_style=space
|
||||
indent_size=4
|
||||
ij_any_block_comment_add_space = false
|
||||
ij_any_block_comment_at_first_column = false
|
||||
ij_any_line_comment_at_first_column = false
|
||||
ij_any_line_comment_add_space = true
|
||||
|
||||
[*.tiny]
|
||||
indent_style=tab
|
||||
|
||||
[*.bat]
|
||||
end_of_line=crlf
|
||||
|
||||
[*.yml]
|
||||
indent_size=2
|
||||
|
||||
[*.patch]
|
||||
trim_trailing_whitespace=false
|
||||
|
||||
[*.java]
|
||||
ij_continuation_indent_size = 4
|
||||
ij_java_class_count_to_use_import_on_demand = 999999
|
||||
ij_java_insert_inner_class_imports = false
|
||||
ij_java_names_count_to_use_import_on_demand = 999999
|
||||
ij_java_imports_layout = *,|,$*
|
||||
ij_java_generate_final_locals = true
|
||||
ij_java_generate_final_parameters = true
|
||||
|
||||
[test-plugin/**/*.java]
|
||||
ij_java_use_fq_class_names = false
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
* text=auto
|
||||
|
||||
*.sh text eol=lf
|
||||
gradlew text eol=lf
|
||||
*.bat text eol=crlf
|
||||
|
||||
*.jar binary
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
* @PaperMC/paper-maintainers
|
||||
* @PaperMC/core-team @PaperMC/maintainers
|
||||
/.github/CODEOWNERS @PaperMC/core-team
|
||||
@@ -1,37 +1,36 @@
|
||||
name: Behavior Bug or Plugin Incompatibility
|
||||
description: Report issues with plugin incompatbility or other behavior related issues.
|
||||
labels: [ "status: needs triage", "type: bug" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before reporting a crash here, please make sure you are on the latest version of Paper.
|
||||
Forks of Paper receive no support here. If you are using a fork, please make sure that this issue also happens when using Paper.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: What you expected to see.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Observed/Actual behavior
|
||||
description: What you actually saw.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps/models to reproduce
|
||||
description: This may include a build schematic, a video, or detailed instructions to help reconstruct the issue.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugin and Datapack List
|
||||
description: |
|
||||
All plugins and datapacks running on your server.
|
||||
To list plugins, run `/plugins`. For datapacks, run `/datapack list`.
|
||||
label: Plugin list
|
||||
description: All plugins running on the server.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Paper version
|
||||
@@ -51,27 +50,24 @@ body:
|
||||
```
|
||||
|
||||
</details>
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other
|
||||
description: |
|
||||
Please include other helpful information below.
|
||||
The more information we receive, the quicker and more effective we can be at finding the solution to the issue.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Agreements
|
||||
description: Please agree to the following.
|
||||
options:
|
||||
- label: I am running the latest version of Paper available from https://papermc.io/downloads.
|
||||
required: true
|
||||
- label: I have searched for and ensured there isn't already an open issue regarding this.
|
||||
required: true
|
||||
- label: My version of Minecraft is supported by Paper.
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before submitting this issue, please ensure the following:
|
||||
|
||||
1. You are running the latest version of Paper from [our downloads page](https://papermc.io/downloads/paper).
|
||||
2. You searched for and ensured there isn't already an open issue regarding this.
|
||||
3. Your version of Minecraft is supported by Paper.
|
||||
|
||||
If you think you have a bug but are not sure, feel free to ask the `#paper-help` channel of our
|
||||
[Discord](https://discord.gg/papermc).
|
||||
Please include other helpful information below.
|
||||
The more information we receive, the quicker and more effective we can be at finding the solution to the issue.
|
||||
|
||||
@@ -3,8 +3,3 @@ contact_links:
|
||||
- name: PaperMC Discord
|
||||
url: https://discord.gg/papermc
|
||||
about: If you are having issues with timings or have other minor issues, come ask us on our Discord server!
|
||||
- name: Exploit Report
|
||||
url: https://discord.gg/papermc
|
||||
about: |
|
||||
Due to GitHub not currently allowing private issues, exploit reports are currently handled via our Discord.
|
||||
To report an exploit, see the #paper-exploit-report channel.
|
||||
@@ -1,6 +1,5 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for Paper
|
||||
labels: [ "status: needs triage", "type: feature" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -15,14 +14,12 @@ body:
|
||||
description: Please give some context for this request. Why do you want it added?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the solution you'd like.
|
||||
description: A clear and concise description of what you want.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe alternatives you've considered.
|
||||
@@ -30,15 +27,16 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Other
|
||||
description: Add any other context or screenshots about the feature request below.
|
||||
validations:
|
||||
required: false
|
||||
label: Agreements
|
||||
description: Please agree to the following.
|
||||
options:
|
||||
- label: I have searched for and ensured there isn't already an open issue regarding this.
|
||||
required: true
|
||||
- label: I have ensured the feature I'm requesting isn't already in the latest supported Paper build.
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before submitting this feature request, please search our issue tracker to ensure your feature has not
|
||||
already been requested.
|
||||
value: Add any other context or screenshots about the feature request below.
|
||||
@@ -1,13 +1,11 @@
|
||||
name: Performance Problem
|
||||
description: Report performance related problems or other areas of concern
|
||||
labels: [ "status: needs triage", "type: performance" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before creating an issue regarding server performance, please consider reaching out for support in the
|
||||
`#paper-help` channel of [our Discord](https://discord.gg/papermc)!
|
||||
|
||||
Before reporting performance problems here, please make sure you are on the latest version of Paper.
|
||||
Forks of Paper receive no support here. If you are using a fork, please make sure that this problem also affects Paper.
|
||||
- type: input
|
||||
attributes:
|
||||
label: Timings or Profile link
|
||||
@@ -15,27 +13,22 @@ body:
|
||||
placeholder: "Example: https://timings.aikar.co/?id=6b48586fbbdd48e585ca0ebb07c59dd0"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description of issue
|
||||
description: If applicable, please describe your issue.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugin and Datapack List
|
||||
description: |
|
||||
All plugins and datapacks running on your server.
|
||||
To list plugins, run `/plugins`. For datapacks, run `/datapack list`.
|
||||
label: Plugin list
|
||||
description: All plugins running on the server.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Server config files
|
||||
description: We need bukkit.yml, spigot.yml, paper-global.yml, paper-world-defaults.yml and server.properties. If you use per-world Paper configs, make sure to include them. You can paste it below or use a paste site like https://paste.gg.
|
||||
description: We need bukkit.yml, spigot.yml, paper.yml, and server.properties. You can paste it below or use a paste site like https://paste.gg.
|
||||
value: |
|
||||
```
|
||||
Paste configs or paste.gg link here!
|
||||
@@ -43,7 +36,6 @@ body:
|
||||
placeholder: Please don't remove the backticks; it makes your issue a lot harder to read!
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Paper version
|
||||
@@ -63,22 +55,23 @@ body:
|
||||
```
|
||||
|
||||
</details>
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other
|
||||
description: |
|
||||
Please include other helpful links below.
|
||||
The more information we receive, the quicker and more effective we can be at finding the solution to the issue.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Agreements
|
||||
description: Please agree to the following.
|
||||
options:
|
||||
- label: I am running the latest version of Paper available from https://papermc.io/downloads.
|
||||
required: true
|
||||
- label: I have searched for and ensured there isn't already an open issue regarding this.
|
||||
required: true
|
||||
- label: My version of Minecraft is supported by Paper.
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before submitting this issue, please ensure the following:
|
||||
|
||||
1. You are running the latest version of Paper from [our downloads page](https://papermc.io/downloads/paper).
|
||||
2. You searched for and ensured there isn't already an open issue regarding this.
|
||||
3. Your version of Minecraft is supported by Paper.
|
||||
Please include other helpful links below.
|
||||
The more information we receive, the quicker and more effective we can be at finding the solution to the issue.
|
||||
@@ -1,7 +1,13 @@
|
||||
name: Server crash or Stacktrace
|
||||
description: Report server crashes or scary stacktraces
|
||||
labels: [ "status: needs triage" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before reporting a crash here, please make sure you are on the latest version of Paper.
|
||||
Forks of Paper receive no support here. If you are using a fork, please make sure that this crash also happens when using Paper.
|
||||
Please do not make reports when the report says "DO NOT REPORT THIS TO PAPER". These are simply messages informing you of lag, to find what is causing it. Ask for tips on Discord or IRC instead.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Stack trace
|
||||
@@ -15,23 +21,18 @@ body:
|
||||
placeholder: Please don't remove the backticks; it makes your issue a lot harder to read!
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugin and Datapack List
|
||||
description: |
|
||||
All plugins and datapacks running on your server.
|
||||
To list plugins, run `/plugins`. For datapacks, run `/datapack list`.
|
||||
label: Plugin list
|
||||
description: All plugins running on the server.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Actions to reproduce (if known)
|
||||
description: This may include a build schematic, a video, or detailed instructions to help reconstruct the issue. Anything helps!
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Paper version
|
||||
@@ -51,26 +52,23 @@ body:
|
||||
```
|
||||
|
||||
</details>
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other
|
||||
description: |
|
||||
Please include other helpful information below, if any.
|
||||
The more information we receive, the quicker and more effective we can be at finding the solution to the issue.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Agreements
|
||||
description: Please agree to the following.
|
||||
options:
|
||||
- label: I am running the latest version of Paper available from https://papermc.io/downloads.
|
||||
required: true
|
||||
- label: I have searched for and ensured there isn't already an open issue regarding this.
|
||||
required: true
|
||||
- label: My version of Minecraft is supported by Paper.
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before submitting this issue, please ensure the following:
|
||||
|
||||
1. You are running the latest version of Paper from [our downloads page](https://papermc.io/downloads/paper).
|
||||
2. Your version of Minecraft is supported by Paper.
|
||||
|
||||
If your server crash log contains `DO NOT REPORT THIS TO PAPER`, please ask in our
|
||||
[Discord](https://discord.gg/papermc) before opening this issue. These messages are informing you of server
|
||||
lag and providing debug information.
|
||||
Please include other helpful information below, if any.
|
||||
The more information we receive, the quicker and more effective we can be at finding the solution to the issue.
|
||||
@@ -0,0 +1,18 @@
|
||||
daysUntilStale: 60
|
||||
daysUntilClose: 7
|
||||
exemptLabels:
|
||||
- "for: future"
|
||||
- "type: bug"
|
||||
- "status: accepted"
|
||||
- "status: blocked"
|
||||
- "status: in progress"
|
||||
- "status: rebase required"
|
||||
staleLabel: "resolution: stale"
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
closeComment: >
|
||||
This issue has been automatically closed because it has not had activity in
|
||||
a long time. If the issue still applies to the most recent supported
|
||||
version, please open a new issue referencing this original issue.
|
||||
+32
-83
@@ -1,89 +1,38 @@
|
||||
# Here lie dragons!
|
||||
#
|
||||
# This action either builds the server or
|
||||
# builds a paperclip jar to be updated in the body
|
||||
# of the PR relating to this action.
|
||||
# Note that there is no artifact step in this script. We do not want Paperclip
|
||||
# jars to be built for every push & PR; our CI handles pushes to branches, while
|
||||
# PRs can themselves link to Paperclip jars if it is necessary. Official such
|
||||
# PRs will take use of testing builds.
|
||||
|
||||
name: Build Paper
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- labeled
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# Run on all label events (won't be duplicated) or all push events or on PR syncs not from the same repo
|
||||
if: (github.event_name == 'pull_request' && github.event.action == 'labeled') || github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [17]
|
||||
fail-fast: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: JDK ${{ matrix.java }}
|
||||
uses: actions/setup-java@v3.11.0
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
- name: Setup Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
|
||||
- name: Configure Build
|
||||
uses: actions/github-script@v6
|
||||
id: determine
|
||||
with:
|
||||
script: |
|
||||
const {owner, repo} = context.repo;
|
||||
const event_name = "${{ github.event_name }}";
|
||||
const event = ${{ toJSON(github.event) }};
|
||||
const ref_type = "${{ github.ref_type }}";
|
||||
const ref_name = "${{ github.ref_name }}";
|
||||
const result = {
|
||||
action: "build"
|
||||
};
|
||||
|
||||
if (event_name === "push" && ref_type === "branch") {
|
||||
const {data: pulls} = await github.rest.pulls.list({ owner, repo, head: `${owner}:${ref_name}`, state: "open" });
|
||||
const pull = pulls.find((pr) => !!pr.labels.find((l) => l.name === "build-pr-jar"));
|
||||
if (pull) {
|
||||
result["pr"] = pull.number;
|
||||
result["action"] = "paperclip";
|
||||
core.notice(`This is a push action but to a branch with an open PR with the build paperclip label (${JSON.stringify(result)})`);
|
||||
return result;
|
||||
}
|
||||
} else if (event_name === "pull_request" && event.pull_request.labels.find((l) => l.name === "build-pr-jar")) {
|
||||
result["pr"] = event.pull_request.number;
|
||||
result["action"] = "paperclip";
|
||||
core.notice(`This is a pull request action with a build paperclip label (${JSON.stringify(result)})`);
|
||||
return result;
|
||||
}
|
||||
core.notice("This will not build a paperclip jar");
|
||||
return result;
|
||||
|
||||
- name: Apply Patches
|
||||
run: |
|
||||
git config --global user.email "no-reply@github.com"
|
||||
git config --global user.name "Github Actions"
|
||||
./gradlew applyPatches --stacktrace
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew build --stacktrace
|
||||
|
||||
- name: Create Paperclip Jar
|
||||
if: fromJSON(steps.determine.outputs.result).action == 'paperclip'
|
||||
run: ./gradlew createReobfPaperclipJar --stacktrace
|
||||
|
||||
- name: Upload Paperclip Jar
|
||||
if: fromJSON(steps.determine.outputs.result).action == 'paperclip'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: paper-${{ fromJSON(steps.determine.outputs.result).pr }}
|
||||
path: build/libs/paper-paperclip-*-reobf.jar
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [11, 8]
|
||||
fail-fast: true
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: JDK ${{ matrix.java }}
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- name: Cache maven
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.m2/repository/
|
||||
work/Minecraft
|
||||
key: ${{ runner.os }}-paper-2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-paper-2
|
||||
- name: Patch and build
|
||||
run: |
|
||||
git config --global user.email "no-reply@github.com"
|
||||
git config --global user.name "Github Actions"
|
||||
./paper build
|
||||
- name: Build javadocs
|
||||
run: mvn -pl Paper-API,Paper-MojangAPI -am javadoc:javadoc
|
||||
@@ -1,14 +0,0 @@
|
||||
name: Close invalid PRs
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [ opened ]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.repository != github.event.pull_request.head.repo.full_name && github.head_ref == 'master' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: superbrothers/close-pull-request@v3
|
||||
with:
|
||||
comment: "Please do not open pull requests from the `master` branch, create a new branch instead."
|
||||
@@ -1,76 +0,0 @@
|
||||
# This workflow run on the completion of the
|
||||
# build workflow but only does anything if the
|
||||
# triggering workflow uploaded an artifact.
|
||||
#
|
||||
# Do note that it is then the trigger workflow that
|
||||
# determines if this will update the PR text body. All
|
||||
# this workflow does is check if an uploaded artifact
|
||||
# exists and there is a PR tied to the previous workflow.
|
||||
|
||||
name: Comment on pull request
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ['Build Paper']
|
||||
types: [completed]
|
||||
jobs:
|
||||
pr_comment:
|
||||
if: github.event.workflow_run.conclusion == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
# This snippet is public-domain, taken from
|
||||
# https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml
|
||||
# Modified extensively by Machine_Maker
|
||||
script: |
|
||||
async function updatePR(owner, repo, issue_number, purpose, body) {
|
||||
const { data } = await github.rest.issues.get({ owner, repo, issue_number });
|
||||
core.debug(JSON.stringify(data, null, 2));
|
||||
|
||||
const marker = `<!-- bot: ${purpose} -->`;
|
||||
|
||||
let new_body = data.body ? data.body.trim().split(marker)[0].trim() : "";
|
||||
new_body += `\n${marker}\n---\n${body}`;
|
||||
|
||||
core.info(`Updating the text body of PR #${issue_number} in ${owner}/${repo}`);
|
||||
await github.rest.issues.update({ owner, repo, issue_number, body: new_body });
|
||||
}
|
||||
|
||||
const { owner, repo } = context.repo;
|
||||
const run_id = ${{ github.event.workflow_run.id }};
|
||||
const repo_id = ${{ github.event.repository.id }};
|
||||
|
||||
let pulls = [];
|
||||
const event_type = "${{ github.event.workflow_run.event}}";
|
||||
if (event_type === "push") { // if push, it's from the same repo which means `pull_requests` is populated
|
||||
pulls = ${{ toJSON(github.event.workflow_run.pull_requests) }};
|
||||
} else {
|
||||
const pr_branch = "${{ github.event.workflow_run.head_branch }}";
|
||||
const pr_sha = "${{ github.event.workflow_run.head_sha }}";
|
||||
const pr_owner = "${{ github.event.workflow_run.head_repository.owner.login }}";
|
||||
const { data } = await github.rest.pulls.list({ owner, repo, head: `${pr_owner}:${pr_branch}`, state: "open" });
|
||||
core.debug(JSON.stringify(data, null, 2));
|
||||
pulls = data.filter((pr) => pr.head.sha === pr_sha && pr.labels.find((l) => l.name === "build-pr-jar"));
|
||||
}
|
||||
|
||||
if (!pulls.length) {
|
||||
return core.notice("This workflow doesn't have any pull requests!");
|
||||
} else if (pulls.length > 1) {
|
||||
core.info(JSON.stringify(pulls, null, 2));
|
||||
return core.error("Found multiple matching PRs");
|
||||
}
|
||||
const pull_request = pulls[0];
|
||||
|
||||
const artifacts = await github.paginate(github.rest.actions.listWorkflowRunArtifacts, { owner, repo, run_id });
|
||||
if (!artifacts.length) {
|
||||
return core.info("Skipping comment due to no artifact found");
|
||||
}
|
||||
const artifact = artifacts.find((art) => art.name === `paper-${pull_request.number}`);
|
||||
if (!artifact) {
|
||||
return core.info("Skipping comment to no matching artifact found");
|
||||
}
|
||||
|
||||
const link = `https://nightly.link/${owner}/${repo}/actions/artifacts/${artifact.id}.zip`;
|
||||
const body = `Download the paperclip jar for this pull request: [${artifact.name}.zip](${link})`;
|
||||
core.info(`Adding a link to ${link}`);
|
||||
await updatePR(owner, repo, pull_request.number, "paperclip-pr-build", body);
|
||||
@@ -1,78 +0,0 @@
|
||||
name: Update Projects
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
- unlabeled
|
||||
- closed
|
||||
- reopened
|
||||
|
||||
jobs:
|
||||
bugs:
|
||||
if: "github.event_name == 'issues' && contains(github.event.*.labels.*.name, 'type: bug')"
|
||||
concurrency:
|
||||
group: update-bugs-project-${{ github.event.issue.number }}
|
||||
cancel-in-progress: true
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "authenticate"
|
||||
id: "authenticate"
|
||||
uses: "tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92" # v1
|
||||
with:
|
||||
app_id: "${{ secrets.PROJECTS_APP_ID }}"
|
||||
installation_id: "36153445"
|
||||
private_key: "${{ secrets.PROJECTS_PRIVATE_KEY }}"
|
||||
|
||||
- uses: PaperMC/update-projects-action@v0.2.0
|
||||
name: Update open issue
|
||||
if: github.event.issue.state == 'open'
|
||||
with:
|
||||
github-token: "${{ steps.authenticate.outputs.token }}"
|
||||
project-url: https://github.com/orgs/PaperMC/projects/5/views/2
|
||||
column-field: Status
|
||||
label-to-column-map: |
|
||||
{
|
||||
"status: needs triage": "🕑 Needs Triage",
|
||||
"status: accepted": "✅ Accepted",
|
||||
"status: unlikely": "✅ Accepted",
|
||||
"status: in progress": "Needs Work",
|
||||
"status: rebase required": "Needs Work",
|
||||
"status: blocked": "Needs Work",
|
||||
"status: defer upstream": "Needs Work",
|
||||
"status: input wanted": "Needs Work",
|
||||
"we must go deeper": "Needs Work",
|
||||
"has rough edges": "Needs Work",
|
||||
"status: waiting on reporter": "⌛ Waiting for Reporter",
|
||||
"resolution: works-as-intended": "Invalid",
|
||||
"resolution: invalid": "Invalid",
|
||||
"resolution: wontfix": "Invalid",
|
||||
"resolution: duplicate": "Invalid",
|
||||
"resolution: cannot reproduce": "Invalid",
|
||||
"resolution: unsupported": "Invalid",
|
||||
"resolution: incomplete": "Invalid",
|
||||
"resolution: superseded": "Invalid"
|
||||
}
|
||||
|
||||
- uses: PaperMC/update-projects-action@v0.2.0
|
||||
name: Update closed issue
|
||||
if: github.event.issue.state == 'closed'
|
||||
with:
|
||||
github-token: "${{ steps.authenticate.outputs.token }}"
|
||||
project-url: https://github.com/orgs/PaperMC/projects/5/views/2
|
||||
column-field: Status
|
||||
clear-on-no-match: false
|
||||
# include "status: needs triage" below to catch any closed issues without setting a resolution
|
||||
label-to-column-map: |
|
||||
{
|
||||
"status: accepted": "Done",
|
||||
"status: needs triage": "Invalid",
|
||||
"resolution: works-as-intended": "Invalid",
|
||||
"resolution: invalid": "Invalid",
|
||||
"resolution: wontfix": "Invalid",
|
||||
"resolution: duplicate": "Invalid",
|
||||
"resolution: cannot reproduce": "Invalid",
|
||||
"resolution: unsupported": "Invalid",
|
||||
"resolution: incomplete": "Invalid",
|
||||
"resolution: superseded": "Invalid"
|
||||
}
|
||||
+1
-5
@@ -24,6 +24,7 @@ dependency-reduced-pom.xml
|
||||
.*.sw[a-p]
|
||||
|
||||
# various other potential build files
|
||||
build/
|
||||
bin/
|
||||
dist/
|
||||
manifest.mf
|
||||
@@ -53,9 +54,6 @@ work/ForgeFlower
|
||||
.idea/
|
||||
out/
|
||||
|
||||
# JetBrains Fleet
|
||||
.fleet/
|
||||
|
||||
# Linux temp files
|
||||
*~
|
||||
|
||||
@@ -70,5 +68,3 @@ paperclip-*.jar
|
||||
paperclip.properties
|
||||
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
test-plugin.settings.gradle.kts
|
||||
@@ -10,3 +10,6 @@
|
||||
[submodule "work/Spigot"]
|
||||
path = work/Spigot
|
||||
url = https://hub.spigotmc.org/stash/scm/spigot/spigot.git
|
||||
[submodule "work/Paperclip"]
|
||||
path = work/Paperclip
|
||||
url = https://github.com/PaperMC/Paperclip.git
|
||||
+201
-165
@@ -4,11 +4,43 @@ PaperMC is happy you're willing to contribute to our projects. We are usually
|
||||
very lenient with all submitted PRs, but there are still some guidelines you
|
||||
can follow to make the approval process go more smoothly.
|
||||
|
||||
## Use a Personal Fork and not an Organization
|
||||
**Table of contents:**
|
||||
<!-- Please don't remove the following comments.
|
||||
To generate and update the TOC: https://github.com/mzlogin/vim-markdown-toc -->
|
||||
<!-- vim-markdown-toc GFM -->
|
||||
|
||||
* [Use a Personal Fork and not Organization](#use-a-personal-fork-and-not-organization)
|
||||
* [Requirements](#requirements)
|
||||
* [Understanding Patches](#understanding-patches)
|
||||
* [Adding Patches](#adding-patches)
|
||||
* [Modifying Patches](#modifying-patches)
|
||||
* [Method 1](#method-1)
|
||||
* [Using the Paper tool](#using-the-paper-tool)
|
||||
* [Manual method: Stashing](#manual-method-stashing)
|
||||
* [Method 2 - Fixup commits](#method-2---fixup-commits)
|
||||
* [Manual method](#manual-method)
|
||||
* [Automatic method](#automatic-method)
|
||||
* [PR Policy](#pr-policy)
|
||||
* [Formatting](#formatting)
|
||||
* [Patch Notes](#patch-notes)
|
||||
* [Obfuscation Helpers](#obfuscation-helpers)
|
||||
* [Configuration files](#configuration-files)
|
||||
* [PaperConfig example](#paperconfig-example)
|
||||
* [PaperWorldConfig example](#paperworldconfig-example)
|
||||
* [Frequently Asked Questions](#frequently-asked-questions)
|
||||
* [I can't find the NMS file I need!](#i-cant-find-the-nms-file-i-need)
|
||||
* [Where can I learn how to name method/field?](#where-can-i-learn-how-to-name-methodfield)
|
||||
* [My commit doesn't need a build, what do I do?](#my-commit-doesnt-need-a-build-what-do-i-do)
|
||||
* [Patching and building is *really* slow, what can I do?](#patching-and-building-is-really-slow-what-can-i-do)
|
||||
* [I wrote some API, how do I use it in Paper-Server?](#i-wrote-some-api-how-do-i-use-it-in-paper-server)
|
||||
|
||||
<!-- vim-markdown-toc -->
|
||||
|
||||
## Use a Personal Fork and not Organization
|
||||
|
||||
Paper will routinely modify your PR, whether it's a quick rebase or to take care
|
||||
of any minor nitpicks we might have. Often, it's better for us to solve these
|
||||
problems for you than make you go back and forth trying to fix them yourself.
|
||||
problems for you than make you go back and forth trying to fix it yourself.
|
||||
|
||||
Unfortunately, if you use an organization for your PR, it prevents Paper from
|
||||
modifying it. This requires us to manually merge your PR, resulting in us
|
||||
@@ -27,26 +59,25 @@ which can be obtained in (most) package managers such as `apt` (Debian / Ubuntu;
|
||||
you will most likely use this for WSL), `homebrew` (macOS / Linux), and more:
|
||||
|
||||
- `git` (package `git` everywhere);
|
||||
- A Java 17 or later JDK (packages vary, use Google/DuckDuckGo/etc.).
|
||||
- [Adoptium](https://adoptium.net/) has builds for most operating systems.
|
||||
- Paper requires JDK 17 to build, however, makes use of Gradle's
|
||||
[Toolchains](https://docs.gradle.org/current/userguide/toolchains.html)
|
||||
feature to allow building with only JRE 11 or later installed. (Gradle will
|
||||
automatically provision JDK 17 for compilation if it cannot find an existing
|
||||
install).
|
||||
- `patch` (often package `patch`);
|
||||
- A Java 8 or later JDK (packages vary, use Google/DuckDuckGo/etc.).
|
||||
If you need one, you can find them on [AdoptOpenJDK](https://adoptopenjdk.net/).
|
||||
- `maven` (often package `maven`; can be found on
|
||||
[Apache's site](https://maven.apache.org/download.cgi) too);
|
||||
- `curl` (package `curl` everywhere).
|
||||
|
||||
If you're on Windows, check
|
||||
[the section on WSL](#patching-and-building-is-really-slow-what-can-i-do).
|
||||
|
||||
If you're compiling with Docker, you can use Adoptium's
|
||||
[`eclipse-temurin`](https://hub.docker.com/_/eclipse-temurin/) images like so:
|
||||
If you're compiling with Docker, you can use the
|
||||
[`adoptopenjdk`](https://hub.docker.com/_/adoptopenjdk/) images like so:
|
||||
|
||||
```console
|
||||
# docker run -it -v "$(pwd)":/data --rm eclipse-temurin:17.0.1_12-jdk bash
|
||||
# docker run -it -v "$(pwd)":/data --rm adoptopenjdk:8-jdk-hotspot bash
|
||||
Pulling image...
|
||||
|
||||
root@abcdefg1234:/# javac -version
|
||||
javac 17.0.1
|
||||
javac 1.8.0_252
|
||||
```
|
||||
|
||||
## Understanding Patches
|
||||
@@ -56,7 +87,8 @@ split into different directories which target certain parts of the code. These
|
||||
directories are:
|
||||
|
||||
- `Paper-API` - Modifications to `Spigot-API`/`Bukkit`;
|
||||
- `Paper-MojangAPI` - An API for [Mojang's Brigadier](https://github.com/Mojang/brigadier);
|
||||
- `Paper-MojangAPI` - An API for
|
||||
[Mojang's Brigadier](https://github.com/Mojang/brigadier);
|
||||
- `Paper-Server` - Modifications to `Spigot`/`CraftBukkit`.
|
||||
|
||||
Because the entire structure is based on patches and git, a basic understanding
|
||||
@@ -66,18 +98,24 @@ of how to use git is required. A basic tutorial can be found here:
|
||||
Assuming you have already forked the repository:
|
||||
|
||||
1. Clone your fork to your local machine;
|
||||
2. Type `./gradlew applyPatches` in a terminal to apply the changes from upstream.
|
||||
On Windows, leave out the `./` at the beginning for all `gradlew` commands;
|
||||
3. cd into `Paper-Server` for server changes, and `Paper-API` for API changes.
|
||||
<!--You can also run `./paper server` or `./paper api` for these same directories
|
||||
1. Type `./paper patch` in a terminal to apply the changes from upstream;
|
||||
1. cd into `Paper-Server` for server changes, and `Paper-API` for API changes.
|
||||
You can also run `./paper server` or `./paper api` for these same directories
|
||||
respectively.
|
||||
1. You can also run `./paper setup`, which allows you to type `paper <command>`
|
||||
from anywhere in the Paper structure in most cases.-->
|
||||
from anywhere in the Paper structure in most cases.
|
||||
|
||||
`Paper-Server` and `Paper-API` aren't git repositories in the traditional sense:
|
||||
|
||||
- `base` points to the unmodified source before Paper patches have been applied.
|
||||
- Each commit after `base` is a patch.
|
||||
- Every single commit in `Paper-Server`/`Paper-API` is a patch;
|
||||
- `origin/master` points to a directory similar to `Paper-Server`/`Paper-API`
|
||||
but for Paper;
|
||||
- Typing `git status` should show that we are 10 or 11 commits ahead of master,
|
||||
meaning we have 10 or 11 patches Spigot and CraftBukkit don't.
|
||||
- If it says something like `212 commits ahead, 207 commits behind`,
|
||||
cd into the root directory of the cloned repository and type `git fetch` to
|
||||
update your upstream. Setting up a remote for the upstream Paper repository
|
||||
might be necessary.
|
||||
|
||||
## Adding Patches
|
||||
|
||||
@@ -86,7 +124,7 @@ Adding patches to Paper is very simple:
|
||||
1. Modify `Paper-Server` and/or `Paper-API` with the appropriate changes;
|
||||
1. Type `git add .` inside these directories to add your changes;
|
||||
1. Run `git commit` with the desired patch message;
|
||||
1. Run `./gradlew rebuildPatches` in the main directory to convert your commit into a new
|
||||
1. Run `./paper rebuild` in the main directory to convert your commit into a new
|
||||
patch;
|
||||
1. PR the generated patch file(s) back to this repository.
|
||||
|
||||
@@ -107,13 +145,38 @@ edit it using `git rebase`.
|
||||
> ❗ While in the middle of an edit, you will not be able to compile unless you
|
||||
> *also* reset the opposing module(s) to a related commit. In the API's case,
|
||||
> you must reset the Server, and reset the API if you're editing the Server.
|
||||
> Note also that either module _may_ not compile when doing so. This is not
|
||||
> ideal nor intentional, but it happens. Feel free to fix this in a PR to us!
|
||||
|
||||
#### Using the Paper tool
|
||||
|
||||
The PaperMC build tool provides a handy command to automatically do this type of
|
||||
patch modification.
|
||||
|
||||
1. Type `./paper edit server` or `./paper edit api` depending on which project
|
||||
you want to edit;
|
||||
- It should show something like
|
||||
[this](https://gist.github.com/zachbr/21e92993cb99f62ffd7905d7b02f3159) in
|
||||
the text editor you get.
|
||||
- If your editor does not have a "menu" at the bottom, you're using `vim`.
|
||||
If you don't know how to use `vim` and don't want to
|
||||
learn, enter `:q!` and press enter. Before redoing this step, do
|
||||
`export EDITOR=nano` for an easier editor to use.
|
||||
1. Replace `pick` with `edit` for the commit/patch you want to modify, and
|
||||
"save" the changes;
|
||||
- Only do this for **one** commit at a time.
|
||||
1. Make the changes you want to make to the patch;
|
||||
1. Type `./paper edit continue` in the root directory to finish and rebuild
|
||||
patches;
|
||||
1. PR your modified patch file(s) back to this repository.
|
||||
|
||||
#### Manual method: Stashing
|
||||
|
||||
In case you need something more complex or want more control, these step-by-step
|
||||
instruction do exactly what the above slightly automated system above does.
|
||||
|
||||
1. If you have changes you are working on, type `git stash` to store them for
|
||||
later;
|
||||
- You can type `git stash pop` to get them back at any point.
|
||||
1. Type `git rebase -i base`;
|
||||
1. Type `git rebase -i upstream/upstream`;
|
||||
- It should show something like
|
||||
[this](https://gist.github.com/zachbr/21e92993cb99f62ffd7905d7b02f3159) in
|
||||
the text editor you get.
|
||||
@@ -130,7 +193,7 @@ later;
|
||||
- **Make sure to add `--amend`** or else a new patch will be created.
|
||||
- You can also modify the commit message and author here.
|
||||
1. Type `git rebase --continue` to finish rebasing;
|
||||
1. Type `./gradlew rebuildPatches` in the root directory;
|
||||
1. Type `./paper rebuild` in the root directory;
|
||||
- This will modify the appropriate patches based on your commits.
|
||||
1. PR your modified patch file(s) back to this repository.
|
||||
|
||||
@@ -147,14 +210,14 @@ messing with your HEADs.
|
||||
|
||||
1. Make your change while at HEAD;
|
||||
1. Make a temporary commit. You don't need to make a message for this;
|
||||
1. Type `git rebase -i base`, move (cut) your temporary commit and
|
||||
1. Type `git rebase -i upstream/upstream`, move (cut) your temporary commit and
|
||||
move it under the line of the patch you wish to modify;
|
||||
1. Change the `pick` to the appropriate action:
|
||||
1. `f`/`fixup`: Merge your changes into the patch without touching the
|
||||
message.
|
||||
1. `s`/`squash`: Merge your changes into the patch and use your commit message
|
||||
and subject.
|
||||
1. Type `./gradlew rebuildPatches` in the root directory;
|
||||
1. Type `./paper rebuild` in the root directory;
|
||||
- This will modify the appropriate patches based on your commits.
|
||||
1. PR your modified patch file(s) back to this repository.
|
||||
|
||||
@@ -168,29 +231,13 @@ move it under the line of the patch you wish to modify;
|
||||
assist you too.
|
||||
- Alternatively, if you only know the name of the patch, you can do
|
||||
`git commit -a --fixup "Subject of Patch name"`.
|
||||
1. Rebase with autosquash: `git rebase -i --autosquash base`.
|
||||
1. Rebase with autosquash: `git rebase --autosquash -i upstream/upstream`.
|
||||
This will automatically move your fixup commit to the right place, and you just
|
||||
need to "save" the changes.
|
||||
1. Type `./gradlew rebuildPatches` in the root directory;
|
||||
1. Type `./paper rebuild` in the root directory;
|
||||
- This will modify the appropriate patches based on your commits.
|
||||
1. PR your modified patch file(s) back to this repository.
|
||||
|
||||
## Rebasing PRs
|
||||
|
||||
Steps to rebase a PR to include the latest changes from `master`.
|
||||
These steps assume the `origin` remote is your fork of this repository and `upstream` is the official PaperMC repository.
|
||||
|
||||
1. Pull the latest changes from upstreams master: `git checkout master && git pull upstream master`.
|
||||
1. Checkout feature/fix branch and rebase on master: `git checkout patch-branch && git rebase master`.
|
||||
1. Apply updated patches: `./gradlew applyPatches`.
|
||||
1. If there are conflicts, fix them.
|
||||
1. If your PR creates new patches instead of modifying existing ones, in both the `Paper-Server` and `Paper-API` directories, ensure your newly-created patch is the last commit by either:
|
||||
* Renaming the patch file with a large 4-digit number in front (e.g. 9999-Patch-to-add-some-new-stuff.patch), and re-applying patches.
|
||||
* Running `git rebase --interactive base` and moving the commits to the end.
|
||||
1. Rebuild patches: `./gradlew rebuildPatches`.
|
||||
1. Commit modified patches.
|
||||
1. Force push changes: `git push --force`.
|
||||
|
||||
## PR Policy
|
||||
|
||||
We'll accept changes that make sense. You should be able to justify their
|
||||
@@ -229,44 +276,13 @@ entity.getWorld().explode(new BlockPosition(spawnLocation.getX(), spawnLocation.
|
||||
// Paper end
|
||||
```
|
||||
|
||||
We generally follow the usual Java style (aka. Oracle style), or what is programmed
|
||||
We generally follow usual Java style (aka. Oracle style), or what is programmed
|
||||
into most IDEs and formatters by default. There are a few notes, however:
|
||||
- It is fine to go over 80 lines as long as it doesn't hurt readability.
|
||||
There are exceptions, especially in Spigot-related files
|
||||
- When in doubt or the code around your change is in a clearly different style,
|
||||
use the same style as the surrounding code.
|
||||
|
||||
## Access Transformers
|
||||
Sometimes, vanilla or CraftBukkit code already contains a field, method, or type you want to access
|
||||
but the visibility is too low (e.g. a private field in an entity class). Paper can use access transformers
|
||||
to change the visibility or remove the final modifier from fields, methods, and classes. Inside the `build-data/paper.at`
|
||||
file, you can add ATs that are applied when you `./gradlew applyPatches`. You can read about the format of ATs
|
||||
[here](https://mcforge.readthedocs.io/en/latest/advanced/accesstransformers/#access-modifiers).
|
||||
|
||||
### Important
|
||||
ATs should be included in the patch file which requires them within the commit message. Do not commit any changes to the
|
||||
`build-data/paper.at` file, just use it to initially change the visibility of members until you have finalized what you
|
||||
need. Then, in the commit message for the patch which requires the ATs, add a header at the bottom of the commit message
|
||||
before any co-authors. It should look like the following after you `./gradlew rebuildPatches`.
|
||||
```
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 8 Jun 2022 22:20:16 -0700
|
||||
Subject: [PATCH] Paper config files
|
||||
|
||||
This patch adds Paper configuration files.
|
||||
Access transformers for this patch are below, but before the co-authors.
|
||||
|
||||
== AT ==
|
||||
public org.spigotmc.SpigotWorldConfig getBoolean(Ljava/lang/String;Z)Z
|
||||
public net.minecraft.world.level.NaturalSpawner SPAWNING_CATEGORIES
|
||||
|
||||
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
...
|
||||
```
|
||||
|
||||
## Patch Notes
|
||||
|
||||
When submitting patches to Paper, we may ask you to add notes to the patch
|
||||
@@ -320,18 +336,31 @@ index a92bf8967..d0ab87d0f 100644
|
||||
|
||||
## Obfuscation Helpers
|
||||
|
||||
While rarely needed, obfuscation helpers are sometimes useful when it comes
|
||||
to unmapped local variables, or poorly named method parameters. In an effort
|
||||
to make future updates easier on ourselves, Paper tries to use obfuscation
|
||||
helpers wherever it makes sense. The purpose of these helpers is to make the
|
||||
code more readable and maintainable. These helpers should be made easy to
|
||||
inline by the JVM wherever possible.
|
||||
In an effort to make future updates easier on ourselves, Paper tries to use
|
||||
obfuscation helpers whenever possible. The purpose of these helpers is to make
|
||||
the code more readable and maintainable. These helpers should be be made as easy
|
||||
to inline as possible by the JVM whenever possible.
|
||||
|
||||
An obfuscation helper to access an obfuscated item may be as simple as something
|
||||
like this:
|
||||
|
||||
An example of an obfuscation helper for a local variable:
|
||||
```java
|
||||
double d0 = entity.getX(); final double fromX = d0; // Paper - OBFHELPER
|
||||
// ...
|
||||
this.someMethod(fromX); // Paper
|
||||
public final int getStuckArrows() { return this.bY(); } // Paper - OBFHELPER
|
||||
```
|
||||
|
||||
Or it may be as complex as forwarding an entire method so that it can be
|
||||
overridden later:
|
||||
|
||||
```java
|
||||
public boolean be() {
|
||||
// Paper start - OBFHELPER
|
||||
return this.pushedByWater();
|
||||
}
|
||||
|
||||
public boolean pushedByWater() {
|
||||
// Paper end
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
While they may not always be done in exactly the same way, the general goal is
|
||||
@@ -340,83 +369,56 @@ what fits best in your situation.
|
||||
|
||||
## Configuration files
|
||||
|
||||
To use a configurable value in your patch, add a new field in either the
|
||||
`GlobalConfiguration` or `WorldConfiguration` classes (inside the
|
||||
`io.papermc.paper.configuration` package). Use `GlobalConfiguration` if a value
|
||||
To use a configurable value in your patch, add a new entry in either the
|
||||
`PaperConfig` or `PaperWorldConfig` classes. Use `PaperConfig` if a value
|
||||
must remain the same throughout all worlds, or the latter if it can change
|
||||
between worlds. World-specific configuration options are preferred whenever
|
||||
possible.
|
||||
|
||||
### Example
|
||||
This is adding a new miscellaneous setting that doesn't seem to fit in other categories.
|
||||
Try to check and see if an existing category (inner class) exists that matches
|
||||
whatever configuration option you are adding.
|
||||
### PaperConfig example
|
||||
|
||||
```java
|
||||
public class GlobalConfiguration {
|
||||
// other sections
|
||||
public class Misc extends ConfigurationPart {
|
||||
// other settings
|
||||
public boolean lagCompensateBlockBreaking = true;
|
||||
public boolean useDimensionTypeForCustomSpawners = false;
|
||||
public int maxNumOfPlayers = 20; // This is the new setting
|
||||
}
|
||||
public static boolean saveEmptyScoreboardTeams = false;
|
||||
private static void saveEmptyScoreboardTeams() {
|
||||
// This is called automatically!
|
||||
// The name also doesn't matter.
|
||||
saveEmptyScoreboardTeams = getBoolean("settings.save-empty-scoreboard-teams", false);
|
||||
}
|
||||
```
|
||||
You set the type of the setting as the field type, and the default value is the
|
||||
initial field value. The name of the setting defaults to the snake-case of the
|
||||
field name, so in this case it would be `misc.max-num-of-players`. You can use
|
||||
the `@Setting` annotation to override that, but generally just try to set the
|
||||
field name to what you want the setting to be called.
|
||||
|
||||
#### Accessing the value
|
||||
If you added a new global config value, you can access it in the code just by
|
||||
doing
|
||||
Notice that the field is always public, but the setter is always private. This
|
||||
is important to the way the configuration generation system works. To access
|
||||
this value, reference it as you would any other static value:
|
||||
|
||||
```java
|
||||
int maxPlayers = GlobalConfiguration.get().misc.maxNumOfPlayers;
|
||||
```
|
||||
Generally for global config values you will use the fully qualified class name,
|
||||
`io.papermc.paper.configuration.GlobalConfiguration` since it's not imported in
|
||||
most places.
|
||||
---
|
||||
If you are adding a new world config value, you must have access to an instance
|
||||
of the `net.minecraft.world.level.Level` which you can then access the config by doing
|
||||
```java
|
||||
int maxPlayers = level.paperConfig().misc.maxNumOfPlayers;
|
||||
if (!PaperConfig.saveEmptyScoreboardTeams) {
|
||||
```
|
||||
|
||||
#### Committing changes
|
||||
All changes to the `GlobalConfiguration` and `WorldConfiguration` files
|
||||
should be done in the commit that created them. So do an interactive rebase
|
||||
or fixup to apply just those changes to that commit, then add a new commit
|
||||
that includes the logic that uses that option in the server somewhere.
|
||||
It is often preferred that you use the fully qualified name for the
|
||||
configuration class when accessing it, like so:
|
||||
`com.destroystokyo.paper.PaperConfig.valueHere`.
|
||||
If this is not done, a developer for Paper might fix that for you before
|
||||
merging, but it's always nice if you make it a habit where you only need 1-2
|
||||
lines changed.
|
||||
|
||||
## Testing API changes
|
||||
### PaperWorldConfig example
|
||||
|
||||
### Using the Paper Test Plugin
|
||||
```java
|
||||
public boolean useInhabitedTime = true;
|
||||
private void useInhabitedTime() {
|
||||
// This is called automatically!
|
||||
// The name also doesn't matter.
|
||||
useInhabitedTime = getBoolean("use-chunk-inhabited-timer", true);
|
||||
}
|
||||
```
|
||||
|
||||
The Paper project has a `test-plugin` module for easily testing out API changes
|
||||
and additions. To use the test plugin, enable it in `test-plugin.settings.gradle.kts`,
|
||||
which will be generated after running Gradle at least once. After this, you can edit
|
||||
the test plugin, and run a server with the plugin using `./gradlew runDev` (or any
|
||||
of the other Paper run tasks).
|
||||
Again, notice that the field is always public, but the setter is always private.
|
||||
To access this value, you'll need an instance of the `net.minecraft.World`
|
||||
object:
|
||||
|
||||
### Publishing to Maven local (use in external plugins)
|
||||
|
||||
To build and install the Paper APIs and Server to your local Maven repository, do the following:
|
||||
|
||||
- Run `./gradlew publishToMavenLocal` in the base directory.
|
||||
|
||||
If you use Gradle to build your plugin:
|
||||
- Add `mavenLocal()` as a repository. Gradle checks repositories in the order they are declared,
|
||||
so if you also have the Paper repository added, put the local repository above Paper's.
|
||||
- Make sure to remove `mavenLocal()` when you are done testing, see the [Gradle docs](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:case-for-maven-local)
|
||||
for more details.
|
||||
|
||||
If you use Maven to build your plugin:
|
||||
- If you later need to use the Paper-API, you might want to remove the jar
|
||||
from your local Maven repository.
|
||||
If you use Windows and don't usually build using WSL, you might not need to
|
||||
do this.
|
||||
```java
|
||||
return this.world.paperConfig.useInhabitedTime ? this.w : 0;
|
||||
```
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
@@ -431,25 +433,39 @@ patching process.
|
||||
progress will be lost if you do not;
|
||||
1. Identify the name(s) of the file(s) you want to import.
|
||||
- A complete list of all possible file names can be found at
|
||||
`./Paper-Server/.gradle/caches/paperweight/mc-dev-sources/net/minecraft/`. You might find
|
||||
[MappingViewer] useful if you need to translate between Mojang and Spigot mapped names.
|
||||
1. Open the file at `./build-data/dev-imports.txt` and add the name of your file to
|
||||
the script. Follow the instructions there;
|
||||
1. Re-patch the server `./gradlew applyPatches`;
|
||||
`./work/Minecraft/$MCVER/spigot/net/minecraft/server`. You might find
|
||||
[MiniMappingViewer] very useful to find the file you need.
|
||||
1. Open the file at `./scripts/importmcdev.sh` and add the name of your file to
|
||||
the script. Skip to the 2nd last header and follow the instructions there;
|
||||
1. Re-patch the server `./paper patch`;
|
||||
1. Edit away!
|
||||
|
||||
> ❗ This change is temporary! **DO NOT COMMIT CHANGES TO THIS FILE!**
|
||||
> Once you have made your changes to the new file, and rebuilt patches, you may
|
||||
> undo your changes to `dev-imports.txt`.
|
||||
> undo your changes to `importmcdev.sh`.
|
||||
|
||||
Any file modified in a patch file gets automatically imported, so you only need
|
||||
this temporarily to import it to create the first patch.
|
||||
|
||||
To undo your changes to the file, type `git checkout build-data/dev-imports.txt`.
|
||||
To undo your changes to the file, type `git checkout scripts/importmcdev.sh`.
|
||||
|
||||
### Where can I learn how to name method/field?
|
||||
|
||||
For most cases, it is preferred if you use [yarn], as their license works with
|
||||
Paper's license. If you can't do that, [MiniMappingViewer] is always around to
|
||||
provide you with more of a general idea, *but* you cannot use the Mojang names
|
||||
for more than understanding the code.
|
||||
|
||||
[yarn] is in general more thorough than Mojang's own mappings, as they include
|
||||
method arguments as well, whereas Mojang's do not. If you need local variables
|
||||
to understand the code, you might be more lucky with ModCoderPack.
|
||||
|
||||
For more information on the Mojang name licensing issues, check this out:
|
||||
<https://cpw.github.io/MinecraftMappingData.html>
|
||||
|
||||
### My commit doesn't need a build, what do I do?
|
||||
|
||||
Well, quite simple: You add `[ci skip]` to the start of your commit subject.
|
||||
Well, quite simple: You add `[CI-SKIP]` to the start of your commit subject.
|
||||
|
||||
This case most often applies to changes to files like `README.md`, this very
|
||||
file (`CONTRIBUTING.md`), the `LICENSE.md` file, and so forth.
|
||||
@@ -457,16 +473,16 @@ file (`CONTRIBUTING.md`), the `LICENSE.md` file, and so forth.
|
||||
### Patching and building is *really* slow, what can I do?
|
||||
|
||||
This only applies if you're running Windows. If you're running a prior Windows
|
||||
release, either update to Windows 10/11 or move to macOS/Linux/BSD.
|
||||
release, either update to Windows 10 or move to macOS/Linux/BSD.
|
||||
|
||||
In order to speed up patching process on Windows, it's recommended you get WSL
|
||||
2. This is available in Windows 10 v2004, build 19041 or higher. (You can check
|
||||
your version by running `winver` in the run window (Windows key + R)). If you're
|
||||
using an out of date version of Windows 10, update your system with the
|
||||
[Windows 10 Update Assistant](https://www.microsoft.com/en-us/software-download/windows10) or [Windows 11 Update Assistant](https://www.microsoft.com/en-us/software-download/windows11).
|
||||
out of date, update your system with the
|
||||
[Windows Update Assistant](https://www.microsoft.com/en-us/software-download/windows10).
|
||||
|
||||
To set up WSL 2, follow the information here:
|
||||
<https://docs.microsoft.com/en-us/windows/wsl/install>
|
||||
To setup WSL 2, follow the information here:
|
||||
<https://docs.microsoft.com/en-us/windows/wsl/install-win10>
|
||||
|
||||
You will most likely want to use the Ubuntu apps. Once it's set up, install the
|
||||
required tools with `sudo apt-get update && sudo apt-get install $TOOL_NAMES
|
||||
@@ -476,6 +492,26 @@ everything like usual.
|
||||
|
||||
> ❗ Do not use the `/mnt/` directory in WSL! Instead, mount the WSL directories
|
||||
> in Windows like described here:
|
||||
> <https://docs.microsoft.com/en-us/windows/wsl/filesystems#view-your-current-directory-in-windows-file-explorer>
|
||||
> <https://www.howtogeek.com/426749/how-to-access-your-linux-wsl-files-in-windows-10/>
|
||||
|
||||
[MappingViewer]: https://nms.screamingsandals.org/
|
||||
### I wrote some API, how do I use it in Paper-Server?
|
||||
|
||||
To install the API to your local maven repository, do the following:
|
||||
|
||||
- Enter the API directory by running `./paper api`;
|
||||
- Run `mvn install`.
|
||||
- If you are working on a patch without much care for whether the tests
|
||||
pass, you can instead run `mvn install -DskipTests`. Do not PR changes
|
||||
without running tests first.
|
||||
- If a test failed, you have to identify the failing tests by scrolling up a
|
||||
couple lines (i.e. around 50-200). You should find it fairly quickly.
|
||||
- If you later need to use the Paper-API, you might want to remove the jar
|
||||
from your local maven repository.
|
||||
If you use Windows and don't usually build using WSL, you might not need to
|
||||
do this.
|
||||
|
||||
You can now use the API in your plugin to test it before PRing. You will also
|
||||
need to do this to build the Server with the implemented API.
|
||||
|
||||
[MiniMappingViewer]: https://minidigger.github.io/MiniMappingViewer/
|
||||
[yarn]: https://github.com/FabricMC/yarn
|
||||
+4
-20
@@ -17,6 +17,7 @@ should submit a pull request to this project to add their name.
|
||||
```text
|
||||
Zach Brown <zach.brown@destroystokyo.com>
|
||||
Daniel Ennis <aikar@aikar.co>
|
||||
Kyle Wood <demonwav@gmail.com>
|
||||
kashike <kashike@vq.lc>
|
||||
Black Hole <black-hole@live.com>
|
||||
Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
@@ -28,11 +29,12 @@ chickeneer <emcchickeneer@gmail.com>
|
||||
Minecrell <minecrell@minecrell.net>
|
||||
Techcable <Techcable@outlook.com>
|
||||
BillyGalbreath <blake.galbreath@gmail.com>
|
||||
MiniDigger <admin@benndorf.dev>
|
||||
MiniDigger <admin@minidigger.me>
|
||||
Brokkonaut <hannos17@gmx.de>
|
||||
vemacs <d@nkmem.es>
|
||||
stonar96 <minecraft.stonar96@gmail.com>
|
||||
Hugo Manrique <hugmanrique@gmail.com>
|
||||
Andrew Steinborn <git@steinborn.me>
|
||||
willies952002 <admin@domnian.com>
|
||||
MicleBrick <miclebrick@outlook.com>
|
||||
Trigary <trigary0@gmail.com>
|
||||
@@ -40,27 +42,9 @@ rickyboy320 <rickw320@hotmail.com>
|
||||
DoNotSpamPls <7570108+DoNotSpamPls@users.noreply.github.com>
|
||||
JRoy <joshroy126@gmail.com>
|
||||
ysl3000 <yannicklamprecht@live.de>
|
||||
KennyTV <jahnke.nassim@gmail.com>
|
||||
Machine_Maker <machine@machinemaker.me>
|
||||
Ivan Pekov <ivan@mrivanplays.com>
|
||||
Camotoy <20743703+Camotoy@users.noreply.github.com>
|
||||
Bjarne Koll <lynxplay101@gmail.com>
|
||||
MeFisto94 <MeFisto94@users.noreply.github.com>
|
||||
Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
LemonCaramel <admin@caramel.moe>
|
||||
Noah van der Aa <ndvdaa@gmail.com>
|
||||
Doc <nachito94@msn.com>
|
||||
Nick Hensel <nickhensel25@icloud.com>
|
||||
vytskalt <vytskalt@protonmail.com>
|
||||
TheFruxz <cedricspitzer@outlook.de>
|
||||
Kieran Wallbanks <kieran.wallbanks@gmail.com>
|
||||
Denery <dorofeevij@gmail.com>
|
||||
Jakubk15 <jakubk15@protonmail.com>
|
||||
Redned <redned235@gmail.com>
|
||||
Luke Chambers <consolelogluke@gmail.com>
|
||||
Emily <emilia.lopezf.1999@gmail.com>
|
||||
dawon <dawon@dawon.eu>
|
||||
Ollie <69084614+olijeffers0n@users.noreply.github.com>
|
||||
Oliwier Miodun <naczs@blueflow.pl>
|
||||
aerulion <aerulion@gmail.com>
|
||||
Lukas Planz <lukas.planz@web.de>
|
||||
```
|
||||
@@ -1,36 +0,0 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":paper-api"))
|
||||
api("com.mojang:brigadier:1.0.18")
|
||||
|
||||
compileOnly("it.unimi.dsi:fastutil:8.5.6")
|
||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.hamcrest:hamcrest-library:1.3")
|
||||
testImplementation("org.ow2.asm:asm-tree:9.2")
|
||||
}
|
||||
|
||||
configure<PublishingExtension> {
|
||||
publications.create<MavenPublication>("maven") {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
|
||||
val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks.ScanJarForBadCalls::class) {
|
||||
badAnnotations.add("Lio/papermc/paper/annotation/DoNotUse;")
|
||||
jarToScan.set(tasks.jar.flatMap { it.archiveFile })
|
||||
classpath.from(configurations.compileClasspath)
|
||||
}
|
||||
tasks.check {
|
||||
dependsOn(scanJar)
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
|
||||
<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>
|
||||
<parent>
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
<artifactId>paper-parent</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
<artifactId>paper-mojangapi</artifactId>
|
||||
<version>1.16.5-R0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Paper-MojangAPI</name>
|
||||
<url>https://github.com/PaperMC/Paper</url>
|
||||
<description>API additions that utilize Mojang Specific API's</description>
|
||||
|
||||
<properties>
|
||||
<!-- <skipTests>true</skipTests> Paper - This [was] not going to end well -->
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigotmc-public</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>minecraft-libraries</id>
|
||||
<name>Minecraft Libraries</name>
|
||||
<url>https://libraries.minecraft.net</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spigotmc-public</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- mojang api -->
|
||||
<dependency>
|
||||
<groupId>com.mojang</groupId>
|
||||
<artifactId>brigadier</artifactId>
|
||||
<version>1.0.17</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>it.unimi.dsi</groupId>
|
||||
<artifactId>fastutil</artifactId>
|
||||
<version>8.2.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- annotations -->
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>18.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- testing -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>7.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean install</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<dependencies>
|
||||
<!-- we need our custom version as it fixes some bugs on case sensitive file systems -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-compiler-eclipse</artifactId>
|
||||
<version>2.8.5-spigotmc</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Automatic-Module-Name>org.bukkit</Automatic-Module-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
|
||||
<!-- when downloading via Maven we can pull depends individually -->
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>development</id>
|
||||
<properties>
|
||||
<skipTests>false</skipTests>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<configLocation>checkstyle.xml</configLocation>
|
||||
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>8.29</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||
<version>1.18</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<signature>
|
||||
<groupId>org.codehaus.mojo.signature</groupId>
|
||||
<artifactId>java18</artifactId>
|
||||
<version>1.0</version>
|
||||
</signature>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
-5
@@ -5,10 +5,5 @@ import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Brigadier {@link Command}, {@link SuggestionProvider}, and permission checker for Bukkit {@link Command}s.
|
||||
*
|
||||
* @param <S> command source type
|
||||
*/
|
||||
public interface BukkitBrigadierCommand <S extends BukkitBrigadierCommandSource> extends Command<S>, Predicate<S>, SuggestionProvider<S> {
|
||||
}
|
||||
+11
-18
@@ -6,30 +6,27 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Fired any time a Brigadier RootCommandNode is generated for a player to inform the client of commands.
|
||||
* You may manipulate this CommandNode to change what the client sees.
|
||||
*
|
||||
* <p>This event may fire on login, world change, and permission rebuilds, by plugin request, and potentially future means.</p>
|
||||
* This event may fire on login, world change, and permission rebuilds, by plugin request, and potentially future means.
|
||||
*
|
||||
* <p>This event will fire before {@link org.bukkit.event.player.PlayerCommandSendEvent}, so no filtering has been done by
|
||||
* other plugins yet.</p>
|
||||
* This event will fire before {@link org.bukkit.event.player.PlayerCommandSendEvent}, so no filtering has been done by
|
||||
* other plugins yet.
|
||||
*
|
||||
* <p>WARNING: This event will potentially (and most likely) fire twice! Once for Async, and once again for Sync.
|
||||
* WARNING: This event will potentially (and most likely) fire twice! Once for Async, and once again for Sync.
|
||||
* It is important that you check event.isAsynchronous() and event.hasFiredAsync() to ensure you only act once.
|
||||
* If for some reason we are unable to send this asynchronously in the future, only the sync method will fire.</p>
|
||||
* If for some reason we are unable to send this asynchronously in the future, only the sync method will fire.
|
||||
*
|
||||
* <p>Your logic should look like this:
|
||||
* {@code if (event.isAsynchronous() || !event.hasFiredAsync()) { // do stuff }}</p>
|
||||
* Your logic should look like this:
|
||||
* if (event.isAsynchronous() || !event.hasFiredAsync()) { do stuff }
|
||||
*
|
||||
* <p>If your logic is not safe to run asynchronously, only react to the synchronous version.</p>
|
||||
*
|
||||
* <p>This is a draft/experimental API and is subject to change.</p>
|
||||
* If your logic is not safe to run asynchronously, only react to the synchronous version.
|
||||
* @deprecated Draft API - Subject to change until confirmed solves desired use cases
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public class AsyncPlayerSendCommandsEvent <S extends BukkitBrigadierCommandSource> extends PlayerEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
@@ -43,18 +40,14 @@ public class AsyncPlayerSendCommandsEvent <S extends BukkitBrigadierCommandSourc
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full Root Command Node being sent to the client, which is mutable.
|
||||
*
|
||||
* @return the root command node
|
||||
* @return The full Root Command Node being sent to the client, which is mutable.
|
||||
*/
|
||||
public RootCommandNode<S> getCommandNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if this event has already fired asynchronously.
|
||||
*
|
||||
* @return whether this event has already fired asynchronously
|
||||
* @return If this event has already fired asynchronously.
|
||||
*/
|
||||
public boolean hasFiredAsync() {
|
||||
return hasFiredAsync;
|
||||
|
||||
+6
-13
@@ -10,9 +10,8 @@ import org.bukkit.event.player.PlayerEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when sending {@link Suggestions} to the client. Will be called asynchronously if a plugin
|
||||
* marks the {@link com.destroystokyo.paper.event.server.AsyncTabCompleteEvent} event handled asynchronously,
|
||||
* otherwise called synchronously.
|
||||
* Called when sending Suggestions to the client. Will be called asynchronously if a plugin
|
||||
* marks the AsyncTabComplete event handled asynchronously, otherwise called synchronously.
|
||||
*/
|
||||
public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
@@ -29,27 +28,21 @@ public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Canc
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input buffer sent to request these suggestions.
|
||||
*
|
||||
* @return the input buffer
|
||||
* @return The input buffer sent to request these suggestions
|
||||
*/
|
||||
public String getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the suggestions to be sent to client.
|
||||
*
|
||||
* @return the suggestions
|
||||
* @return The suggestions being sent to client
|
||||
*/
|
||||
public Suggestions getSuggestions() {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the suggestions to be sent to client.
|
||||
*
|
||||
* @param suggestions suggestions
|
||||
* @param suggestions The suggestions to be sent to client if need to change them
|
||||
*/
|
||||
public void setSuggestions(Suggestions suggestions) {
|
||||
this.suggestions = suggestions;
|
||||
@@ -64,7 +57,7 @@ public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Canc
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels sending suggestions to the client.
|
||||
* Cancels sending suggestions to the client
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
|
||||
+23
-69
@@ -9,20 +9,19 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.server.ServerEvent;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Fired anytime the server synchronizes Bukkit commands to Brigadier.
|
||||
* Fired anytime the server synchronizes Bukkit CommandMap to Brigadier.
|
||||
*
|
||||
* <p>Allows a plugin to control the command node structure for its commands.
|
||||
* This is done at Plugin Enable time after commands have been registered, but may also
|
||||
* run at a later point in the server lifetime due to plugins, a server reload, etc.</p>
|
||||
* Allows a plugin to control the Literal and Argument nodes for this command to be
|
||||
* sent to the client.
|
||||
* This is done at Plugin Enable time after commands have been registered, but some
|
||||
* plugins may use reflection to retrigger this rebuild during runtime.
|
||||
*
|
||||
* <p>This is a draft/experimental API and is subject to change.</p>
|
||||
* @deprecated Draft API - Subject to change until confirmed solves desired use cases
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public class CommandRegisteredEvent<S extends BukkitBrigadierCommandSource> extends ServerEvent implements Cancellable {
|
||||
public class CommandRegisteredEvent <S extends BukkitBrigadierCommandSource> extends ServerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final String commandLabel;
|
||||
@@ -31,7 +30,6 @@ public class CommandRegisteredEvent<S extends BukkitBrigadierCommandSource> exte
|
||||
private final RootCommandNode<S> root;
|
||||
private final ArgumentCommandNode<S, String> defaultArgs;
|
||||
private LiteralCommandNode<S> literal;
|
||||
private boolean rawCommand = false;
|
||||
private boolean cancelled = false;
|
||||
|
||||
public CommandRegisteredEvent(String commandLabel, BukkitBrigadierCommand<S> brigadierCommand, Command command, RootCommandNode<S> root, LiteralCommandNode<S> literal, ArgumentCommandNode<S, String> defaultArgs) {
|
||||
@@ -44,99 +42,55 @@ public class CommandRegisteredEvent<S extends BukkitBrigadierCommandSource> exte
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the command label of the {@link Command} being registered.
|
||||
*
|
||||
* @return the command label
|
||||
* @return The command name being registered
|
||||
*/
|
||||
public String getCommandLabel() {
|
||||
return this.commandLabel;
|
||||
return commandLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link BukkitBrigadierCommand} for the {@link Command} being registered. This can be used
|
||||
* as the {@link com.mojang.brigadier.Command command executor} or
|
||||
* {@link com.mojang.brigadier.suggestion.SuggestionProvider} of a {@link com.mojang.brigadier.tree.CommandNode}
|
||||
* to delegate to the {@link Command} being registered.
|
||||
*
|
||||
* @return the {@link BukkitBrigadierCommand}
|
||||
* @return The Bukkit API Brigadier Wrapped Command Object to handle executions and suggestions
|
||||
*/
|
||||
public BukkitBrigadierCommand<S> getBrigadierCommand() {
|
||||
return this.brigadierCommand;
|
||||
return brigadierCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Command} being registered.
|
||||
*
|
||||
* @return the {@link Command}
|
||||
*/
|
||||
public Command getCommand() {
|
||||
return this.command;
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link RootCommandNode} which is being registered to.
|
||||
*
|
||||
* @return the {@link RootCommandNode}
|
||||
* @return Gets the root command node being used to register a command to.
|
||||
*/
|
||||
public RootCommandNode<S> getRoot() {
|
||||
return this.root;
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bukkit APIs default arguments node (greedy string), for if
|
||||
* you wish to reuse it.
|
||||
*
|
||||
* @return default arguments node
|
||||
* Returns the Bukkit API's default handling of Arguments, if you wish to reuse it.
|
||||
* @return
|
||||
*/
|
||||
public ArgumentCommandNode<S, String> getDefaultArgs() {
|
||||
return this.defaultArgs;
|
||||
return defaultArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link LiteralCommandNode} to be registered for the {@link Command}.
|
||||
*
|
||||
* @return the {@link LiteralCommandNode}
|
||||
* Returns the Bukkit API's default literal for this command, including the {@link #getDefaultArgs()} as a child already.
|
||||
* @return
|
||||
*/
|
||||
public LiteralCommandNode<S> getLiteral() {
|
||||
return this.literal;
|
||||
return literal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link LiteralCommandNode} used to register this command. The default literal is mutable, so
|
||||
* this is primarily if you want to completely replace the object.
|
||||
*
|
||||
* @param literal new node
|
||||
* Changes the literal used to register this command. The previous literable is mutable, so this is primarily if
|
||||
* you want to completely replace the object.
|
||||
* @param literal
|
||||
*/
|
||||
public void setLiteral(LiteralCommandNode<S> literal) {
|
||||
this.literal = literal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this command should is treated as "raw".
|
||||
*
|
||||
* @see #setRawCommand(boolean)
|
||||
* @return whether this command is treated as "raw"
|
||||
*/
|
||||
public boolean isRawCommand() {
|
||||
return this.rawCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this command should be treated as "raw".
|
||||
*
|
||||
* <p>A "raw" command will only use the node provided by this event for
|
||||
* sending the command tree to the client. For execution purposes, the default
|
||||
* greedy string execution of a standard Bukkit {@link Command} is used.</p>
|
||||
*
|
||||
* <p>On older versions of Paper, this was the default and only behavior of this
|
||||
* event.</p>
|
||||
*
|
||||
* @param rawCommand whether this command should be treated as "raw"
|
||||
*/
|
||||
public void setRawCommand(final boolean rawCommand) {
|
||||
this.rawCommand = rawCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package io.papermc.paper.brigadier;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* Helper methods to bridge the gaps between Brigadier and Paper-MojangAPI.
|
||||
*/
|
||||
public final class PaperBrigadier {
|
||||
private PaperBrigadier() {
|
||||
throw new RuntimeException("PaperBrigadier is not to be instantiated!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Brigadier {@link Message} from a {@link ComponentLike}.
|
||||
*
|
||||
* <p>Mostly useful for creating rich suggestion tooltips in combination with other Paper-MojangAPI APIs.</p>
|
||||
*
|
||||
* @param componentLike The {@link ComponentLike} to use for the {@link Message} contents
|
||||
* @return A new Brigadier {@link Message}
|
||||
*/
|
||||
public static @NonNull Message message(final @NonNull ComponentLike componentLike) {
|
||||
return PaperBrigadierProvider.instance().message(componentLike);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link Component} from a Brigadier {@link Message}.
|
||||
*
|
||||
* <p>If the {@link Message} was created from a {@link Component}, it will simply be
|
||||
* converted back, otherwise a new {@link TextComponent} will be created with the
|
||||
* content of {@link Message#getString()}</p>
|
||||
*
|
||||
* @param message The {@link Message} to create a {@link Component} from
|
||||
* @return The created {@link Component}
|
||||
*/
|
||||
public static @NonNull Component componentFromMessage(final @NonNull Message message) {
|
||||
return PaperBrigadierProvider.instance().componentFromMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package io.papermc.paper.brigadier;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
interface PaperBrigadierProvider {
|
||||
final class Holder {
|
||||
private static @MonotonicNonNull PaperBrigadierProvider INSTANCE;
|
||||
}
|
||||
|
||||
static @NonNull PaperBrigadierProvider instance() {
|
||||
return requireNonNull(Holder.INSTANCE, "PaperBrigadierProvider has not yet been initialized!");
|
||||
}
|
||||
|
||||
static void initialize(final @NonNull PaperBrigadierProvider instance) {
|
||||
if (Holder.INSTANCE != null) {
|
||||
throw new IllegalStateException("PaperBrigadierProvider has already been initialized!");
|
||||
}
|
||||
Holder.INSTANCE = instance;
|
||||
}
|
||||
|
||||
@NonNull Message message(@NonNull ComponentLike componentLike);
|
||||
|
||||
@NonNull Component componentFromMessage(@NonNull Message message);
|
||||
}
|
||||
@@ -1,96 +1,114 @@
|
||||
Paper [](https://github.com/PaperMC/Paper/actions)
|
||||
[](https://discord.gg/papermc)
|
||||
[](https://github.com/sponsors/PaperMC)
|
||||
[](https://opencollective.com/papermc)
|
||||
===========
|
||||
Remapping Fork Patches
|
||||
======================
|
||||
|
||||
The most widely used, high-performance Minecraft server that aims to fix gameplay and mechanics inconsistencies.
|
||||
This repo is based on Paper 1.16.5. It can be used to remap patches of Paper forks.
|
||||
|
||||
This branch is specifically and only for fork remapping. This is not for Paper development or for general use. It
|
||||
requires special steps and special set up. Follow the instructions in this readme, don't ask for help if you haven't
|
||||
read this entire readme and followed all of these steps.
|
||||
|
||||
**Support and Project Discussion:**
|
||||
- [Our forums](https://forums.papermc.io/), [Discord](https://discord.gg/papermc), or [IRC](https://webchat.esper.net/?channels=paper)
|
||||
Remapping patches requires knowledge of how to fix issues when patches don't or can't apply correctly. Patches not
|
||||
applying correctly is not an issue with this repo or paperweight. You must fix them and continue the process manually
|
||||
yourself. This is identical to any other upstream update.
|
||||
|
||||
How To (Server Admins)
|
||||
------
|
||||
Paperclip is a jar file that you can download and run just like a normal jar file.
|
||||
Setup
|
||||
-----
|
||||
|
||||
Download Paper from our [downloads page](https://papermc.io/downloads/paper).
|
||||
Paper's unmapped 1.16.5 patches are in [`patches/server-unmapped/0001`](https://github.com/PaperMC/Paper/tree/mappings/mojang/base/patches/server-unmapped/0001).
|
||||
Place the patches you want to remap in `0002`. Paperweight will only remap patches placed in the last directory - for
|
||||
example if there are directories `0001`, `0002`, and `0003`, only the patches in `0003` will be remapped.
|
||||
|
||||
Run the Paperclip jar directly from your server. Just like old times
|
||||
If you are remapping patches for a fork of a fork, place you other upstream patches in `0002`, and your patches in `0003`.
|
||||
|
||||
* Documentation on using Paper: [docs.papermc.io](https://docs.papermc.io)
|
||||
* For a sneak peek at upcoming features, [see here](https://github.com/PaperMC/Paper/projects)
|
||||
|
||||
How To (Plugin Developers)
|
||||
------
|
||||
* See our API patches [here](patches/api)
|
||||
* See upcoming, pending, and recently added API [here](https://github.com/orgs/PaperMC/projects/2/views/4)
|
||||
* Paper API javadocs here: [papermc.io/javadocs](https://papermc.io/javadocs/)
|
||||
#### Repository (for paper-api)
|
||||
##### Maven
|
||||
|
||||
```xml
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
```
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.20.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
##### Gradle
|
||||
```kotlin
|
||||
repositories {
|
||||
maven {
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
```
|
||||
|
||||
How To (Compiling Jar From Source)
|
||||
------
|
||||
To compile Paper, you need JDK 17 and an internet connection.
|
||||
|
||||
Clone this repo, run `./gradlew applyPatches`, then `./gradlew createReobfBundlerJar` from your terminal. You can find the compiled jar in the project root's `build/libs` directory.
|
||||
|
||||
To get a full list of tasks, run `./gradlew tasks`.
|
||||
|
||||
How To (Pull Request)
|
||||
------
|
||||
See [Contributing](CONTRIBUTING.md)
|
||||
|
||||
Support Us
|
||||
------
|
||||
First of all, thank you for considering helping out, we really appreciate that!
|
||||
|
||||
PaperMC has various recurring expenses, mostly related to infrastructure. Paper uses [Open Collective](https://opencollective.com/) via the [Open Source Collective fiscal host](https://opencollective.com/opensource) to manage expenses. Open Collective allows us to be extremely transparent, so you can always see how your donations are used. You can read more about financially supporting PaperMC [on our website](https://papermc.io/sponsors).
|
||||
|
||||
You can find our collective [here](https://opencollective.com/papermc), or you can donate via GitHub Sponsors [here](https://github.com/sponsors/PaperMC), which will also go towards the collective.
|
||||
|
||||
Special Thanks To:
|
||||
Pre-remapping
|
||||
-------------
|
||||
|
||||
[](https://www.yourkit.com/)
|
||||
The patch remap task has no registered inputs, to make working with it repeated easier. That means if you run the task
|
||||
by itself, it will fail.
|
||||
|
||||
[YourKit](https://www.yourkit.com/), makers of the outstanding java profiler, support open source projects of all kinds with their full featured [Java](https://www.yourkit.com/java/profiler) and [.NET](https://www.yourkit.com/.net/profiler) application profilers. We thank them for granting Paper an OSS license so that we can make our software the best it can be.
|
||||
Before you start remapping patches, you must first set up the patch environment by running:
|
||||
|
||||
[<img src="https://user-images.githubusercontent.com/21148213/121807008-8ffc6700-cc52-11eb-96a7-2f6f260f8fda.png" alt="" width="150">](https://www.jetbrains.com)
|
||||
```shell
|
||||
./gradlew applyPatches
|
||||
```
|
||||
|
||||
[JetBrains](https://www.jetbrains.com/), creators of the IntelliJ IDEA, supports Paper with one of their [Open Source Licenses](https://www.jetbrains.com/opensource/). IntelliJ IDEA is the recommended IDE for working with Paper, and most of the Paper team uses it.
|
||||
You will only need to do this once to set up the environment before you start remapping.
|
||||
|
||||
All our sponsors!
|
||||
[](https://papermc.io/sponsors)
|
||||
Remapping
|
||||
---------
|
||||
|
||||
To start remapping patches, run the `remapPatches` task:
|
||||
|
||||
```shell
|
||||
./gradlew remapPatches
|
||||
```
|
||||
|
||||
This can take a very long time, hours even, as patch remapping is a very complex and CPU & disk intensive task. How long
|
||||
it takes depends entirely on how many patches there are to be remapped, and how powerful your computer is.
|
||||
|
||||
That said, while you may need to walk away during the process, the remapping process does require some amount of
|
||||
hands-on work to get it to complete. If you leave for a while and come back to a patch failure, you'll need to fix the
|
||||
issue and restart paperweight to pick up from where it left off, explained below.
|
||||
|
||||
### Fixing patch application issues
|
||||
|
||||
It is pretty unlikely that patch remapping will succeed first try. Paper's patches have already been fixed to apply
|
||||
correctly on this branch, but either your patches or your upstream patches are likely to fail in one way or another due
|
||||
to minor differences in tooling, setup, etc. Again, it is your responsibility to handle patch application issues as they
|
||||
come up just like any other upstream update.
|
||||
|
||||
While the process of fixing issues with patch application is the same, how to resume and complete the process is
|
||||
different, as it hopefully goes without saying that patch remapping is a more complex process which requires extra work
|
||||
vs just a simple patch update.
|
||||
|
||||
### Patch remap working directory setup
|
||||
|
||||
There are a variety of files and directories that paperweight uses during patch remap, but only one directory that you
|
||||
need to worry about. This is the directory where patches are applied, and code is remapped.
|
||||
|
||||
```
|
||||
<project_root>/.gradle/caches/paperweight/patch-remap-input
|
||||
```
|
||||
|
||||
That directory contains what would be the `Paper-Server` directory during the patch remapping process.
|
||||
|
||||
### Apply patch fixes
|
||||
|
||||
If a patch fails to apply, go to the `patch-remap-input` directory to fix the issue, like you normally would. This repo
|
||||
contains the `apatch.sh` script in the `scripts` directory if you want to use it.
|
||||
|
||||
Once you have fixed the issues in patch application, and are ready to continue, run `am --continue` in the
|
||||
`patch-remap-input` directory:
|
||||
|
||||
```shell
|
||||
git am --continue
|
||||
```
|
||||
|
||||
Each patch is applied in its own `am` session, so this won't cause any of the other patches to incidentally apply. After
|
||||
the `am` command in the above `patch-remap-input` directory is completed, continue the remapping process with:
|
||||
|
||||
```shell
|
||||
./gradlew remapPatches --continue-remap
|
||||
```
|
||||
|
||||
Due to the `--continue-remap` flag paperweight will pick up where it left off. If the patch that failed is in a
|
||||
pre-remap upstream patch set, it will simply continue applying the other patches. If the patch is in the remap patch
|
||||
set, paperweight will record the patch, remap it, and re-apply it on the remap branch as it normally would, then
|
||||
continue applying the rest of the patches from there.
|
||||
|
||||
### Completed patch remap
|
||||
|
||||
After the process is complete and all patches have been remapped, the new remapped patches (only including the remap
|
||||
patch set explained above) will be generated into `patches/server-remapped`.
|
||||
|
||||
Help, something went wrong
|
||||
--------------------------
|
||||
|
||||
If something goes wrong, it's almost certainly a patch application issue discussed above. We will not support or help
|
||||
you work through these kinds of issues. Dealing with patch breakages is part of the process of maintaining a fork, so if
|
||||
you don't already know what to do, don't expect us to teach you how to do it.
|
||||
|
||||
If there is an error in paperweight that is causing some issue other than patch application, then we can look into
|
||||
figuring out what's wrong and fixing it. Please, *please*, read through everything here first and follow the
|
||||
instructions word for word. Do not try to simplify the process. Do not make up your own steps. If you do, again, we will
|
||||
absolutely not help you.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Shit to check
|
||||
|
||||
* Mini: "Optimize World Server Map": Figure out how to fill PaperWorldMap, it needs a dim key which doesnt exist anymore?
|
||||
* Mini: "MC-50319": fix if still works
|
||||
* Make sure the flat bedrock setting doesn't do anything stupid
|
||||
* Check DataBits foreach
|
||||
* lighting is bork (load chunk, fly away, come back, everything or parts are black)
|
||||
* chunk generation seems slow with a lot of it happening
|
||||
* Fix IDE Debug JVM Flag for new versions of minecraft
|
||||
|
||||
* Check if `PlayerEditBookEvent`: https://github.com/PaperMC/Paper/pull/1751
|
||||
The PlayerEditBookEvent is straight up not called anymore.
|
||||
The method to call it must now be `PlayerConnection#a(List<String>, int)` (CB bug).
|
||||
The item is presumably edited with the new page contents before it ever reaches this method?
|
||||
@@ -0,0 +1,24 @@
|
||||
# CraftBukkit maps all of (mojmap names):
|
||||
# Merchant.getLevel()
|
||||
# Hopper.getLevel()
|
||||
# Entity.getCommandSenderWorld()
|
||||
# to getWorld(), which confuses our ability to map this method properly. This patch disambiguates it
|
||||
net/minecraft/world/level/block/entity/IHopper v ()Lnet/minecraft/world/level/World; getLevel
|
||||
net/minecraft/world/entity/vehicle/EntityMinecartHopper v ()Lnet/minecraft/world/level/World; getLevel
|
||||
net/minecraft/world/item/trading/IMerchant eV ()Lnet/minecraft/world/level/World; getLevel
|
||||
net/minecraft/world/entity/npc/EntityVillagerAbstract eV ()Lnet/minecraft/world/level/World; getLevel
|
||||
|
||||
# CraftBukkit mappings sometimes have mappings for child classes and not parent classes
|
||||
# We handle this fine for deobf but this breaks reobf. These Patches fix those cases
|
||||
|
||||
# BossBattle -> BossBattleServer
|
||||
net/minecraft/world/BossBattle a (F)V setProgress
|
||||
net/minecraft/world/BossBattle c (Z)Lnet/minecraft/world/BossBattle; setCreateFog
|
||||
net/minecraft/world/BossBattle a (Z)Lnet/minecraft/world/BossBattle; setDarkenSky
|
||||
net/minecraft/world/BossBattle b (Z)Lnet/minecraft/world/BossBattle; setPlayMusic
|
||||
|
||||
# IChunkProvider -> ChunkProviderServer
|
||||
net/minecraft/world/level/chunk/IChunkProvider b (II)Z isLoaded
|
||||
|
||||
# BehaviorWorkComposter -> BehaviorWork
|
||||
net/minecraft/world/entity/ai/behavior/BehaviorWorkComposter a (Lnet/minecraft/server/level/WorldServer;Lnet/minecraft/world/entity/npc/EntityVillager;)V doWork
|
||||
@@ -0,0 +1,17 @@
|
||||
--- a/net/minecraft/world/entity/ai/behavior/BehaviorWorkComposter.patch
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorWorkComposter.patch
|
||||
@@ -1,14 +1,5 @@
|
||||
--- a/net/minecraft/world/entity/ai/behavior/BehaviorWorkComposter.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorWorkComposter.java
|
||||
-@@ -24,7 +24,7 @@
|
||||
- public BehaviorWorkComposter() {}
|
||||
-
|
||||
- @Override
|
||||
-- protected void a(WorldServer worldserver, EntityVillager entityvillager) {
|
||||
-+ protected void doWork(WorldServer worldserver, EntityVillager entityvillager) { // PAIL
|
||||
- Optional<GlobalPos> optional = entityvillager.getBehaviorController().getMemory(MemoryModuleType.JOB_SITE);
|
||||
-
|
||||
- if (optional.isPresent()) {
|
||||
@@ -43,7 +43,7 @@
|
||||
BlockPosition blockposition = globalpos.getBlockPosition();
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
--- a/net/minecraft/server/level/ChunkProviderServer.patch
|
||||
+++ b/net/minecraft/server/level/ChunkProviderServer.patch
|
||||
@@ -74,8 +74,8 @@
|
||||
+ return playerchunk == null || playerchunk.oldTicketLevel > i; // CraftBukkit using oldTicketLevel for isLoaded checks
|
||||
}
|
||||
|
||||
- public boolean isLoaded(int i, int j) {
|
||||
-@@ -282,19 +308,19 @@
|
||||
+ @Override
|
||||
+@@ -283,19 +309,19 @@
|
||||
public boolean a(Entity entity) {
|
||||
long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4);
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
}
|
||||
|
||||
private boolean a(long i, Function<PlayerChunk, CompletableFuture<Either<Chunk, PlayerChunk.Failure>>> function) {
|
||||
-@@ -316,11 +342,31 @@
|
||||
+@@ -317,11 +343,31 @@
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
@@ -131,7 +131,7 @@
|
||||
public void tick(BooleanSupplier booleansupplier) {
|
||||
this.world.getMethodProfiler().enter("purge");
|
||||
this.chunkMapDistance.purgeTickets();
|
||||
-@@ -340,12 +386,12 @@
|
||||
+@@ -341,12 +387,12 @@
|
||||
this.lastTickTime = i;
|
||||
WorldData worlddata = this.world.getWorldData();
|
||||
boolean flag = this.world.isDebugWorld();
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
this.world.getMethodProfiler().enter("naturalSpawnCount");
|
||||
int l = this.chunkMapDistance.b();
|
||||
-@@ -532,12 +578,18 @@
|
||||
+@@ -533,12 +579,18 @@
|
||||
|
||||
@Override
|
||||
protected boolean executeNext() {
|
||||
@@ -1,11 +1,5 @@
|
||||
# You can use this file to import files from minecraft libraries into the project
|
||||
# format:
|
||||
# <artifactId> <fileName>
|
||||
# both fully qualified and a file based syntax are accepted for <fileName>:
|
||||
# authlib com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
|
||||
# datafixerupper com.mojang.datafixers.DataFixerBuilder
|
||||
# datafixerupper com/mojang/datafixers/util/Either.java
|
||||
# To import classes from the vanilla Minecraft jar use `minecraft` as the artifactId:
|
||||
# minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter
|
||||
# minecraft net/minecraft/world/level/entity/LevelEntityGetter.java
|
||||
|
||||
authlib com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
|
||||
datafixerupper com/mojang/datafixers/DataFixerBuilder.java
|
||||
datafixerupper com/mojang/datafixers/util/Either.java
|
||||
datafixerupper com/mojang/serialization/codecs/KeyDispatchCodec.java
|
||||
datafixerupper com/mojang/serialization/Dynamic.java
|
||||
@@ -3,3 +3,74 @@ tiny 2 0 spigot mojang+yarn
|
||||
# Originally DistanceManager, which also implements DistanceManager, so clashes since the implemented class
|
||||
# is imported and not fully qualified. Easiest fix is to just change the name
|
||||
c net/minecraft/server/level/PlayerChunkMap$a net/minecraft/server/level/ChunkMap$ChunkDistanceManager
|
||||
|
||||
# CraftBukkit adds the getServer() method, clashes with a Mojang method
|
||||
c net/minecraft/world/level/World net/minecraft/world/level/Level
|
||||
m ()Lorg/bukkit/craftbukkit/CraftServer; getServer getCraftServer
|
||||
|
||||
# CraftBukkit adds the server field, clashes with a Mojang field
|
||||
c net/minecraft/server/network/PlayerConnection net/minecraft/server/network/ServerGamePacketListenerImpl
|
||||
f Lorg/bukkit/craftbukkit/CraftServer; server craftServer
|
||||
|
||||
# CraftBukkit adds the player field, clashes with a Mojang field
|
||||
c net/minecraft/world/inventory/ContainerWorkbench net/minecraft/world/inventory/CraftingMenu
|
||||
f Lnet/minecraft/world/entity/player/PlayerInventory; player playerInventory
|
||||
|
||||
# CraftBukkit adds the getType() method, clashes with a Mojang method
|
||||
c net/minecraft/world/entity/EntityAreaEffectCloud net/minecraft/world/entity/AreaEffectCloud
|
||||
m ()Ljava/lang/String; getType getTypeCb
|
||||
|
||||
# CraftBukkit adds the getType() method, clashes with a Mojang method
|
||||
c net/minecraft/world/entity/projectile/EntityTippedArrow net/minecraft/world/entity/projectile/Arrow
|
||||
m ()Ljava/lang/String; getType getTypeCb
|
||||
|
||||
# CraftBukkit adds the getLevel() method, clashes with original method
|
||||
c net/minecraft/world/level/block/entity/TileEntityBeacon net/minecraft/world/level/block/entity/BeaconBlockEntity
|
||||
m ()I getLevel getLevelCb
|
||||
|
||||
# CraftBukkit adds the getLootTable() method, clashes with original method
|
||||
c net/minecraft/world/entity/EntityInsentient net/minecraft/world/entity/Mob
|
||||
m ()Lnet/minecraft/resources/MinecraftKey; getLootTable getLootTableCb
|
||||
|
||||
# CraftBukkit adds the canCollideWith() method, clashes with original method
|
||||
c net/minecraft/world/entity/Entity net/minecraft/world/entity/Entity
|
||||
m (Lnet/minecraft/world/entity/Entity;)Z canCollideWith canCollideWithCb
|
||||
|
||||
# CraftBukkit adds a new `a` method which allows passing the Entity parameter
|
||||
# It uses `a` to match the original method (with just 1 param), so this patch makes them match
|
||||
c net/minecraft/server/level/WorldServer net/minecraft/server/level/ServerLevel
|
||||
m (Lnet/minecraft/server/level/WorldServer;Lnet/minecraft/world/entity/Entity;)V a makeObsidianPlatform
|
||||
|
||||
# CraftBukkit adds `getMinecraftWorld()` to `GeneratorAccess`, which matches `WorldAccess.getMinecraftWorld()`
|
||||
# But that method in `WorldAccess` is called `getLevel()` in Mojang mappings
|
||||
c net/minecraft/world/level/GeneratorAccess net/minecraft/world/level/LevelAccessor
|
||||
m ()Lnet/minecraft/server/level/WorldServer; getMinecraftWorld getLevel
|
||||
|
||||
# SpecialSource2 automatically maps methods to the name of synthetic methods that point to it in an attempt to
|
||||
# normalize method names with what is expected by the super class. This is _extremely_ stupid and flawed however
|
||||
# because synthetic methods by definition have different descriptors than the base method, which means method
|
||||
# signature clashes become possible, which is what happens here.
|
||||
#
|
||||
# LootEntryAbstract$Serializer has a synthetic method pointing to the base serialize() method with the following descriptor:
|
||||
#
|
||||
# (JsonObject,Object,JsonSerializationContext)V <-- ProGuard names this method `a`
|
||||
#
|
||||
# and this synthetic method points to another method with the specialized descriptor:
|
||||
#
|
||||
# (JsonObject,LootEntryAbstract,JsonSerializationContext)V <-- ProGuard names this method `b`
|
||||
#
|
||||
# SpecialSource2 automatically maps the second method name to the name of the first method, in this case `a`.
|
||||
#
|
||||
# LootEntryAbstract$Serializer also has another method with the same descriptor as serialize(), which Spigot calls
|
||||
# serializeCustom(). Of course ProGuard strips the names and since this method is the first time it's seen this
|
||||
# descriptor, it renamed that method also to `a`.
|
||||
#
|
||||
# This is allowed because the synthetic method for serialize() has a different descriptor, using Object as the second
|
||||
# parameter. This breaks when SpecialSource2 does it's "magic" of course. This patch manually fixes this case by adding
|
||||
# both correct mappings
|
||||
c net/minecraft/world/level/storage/loot/entries/LootEntryAbstract$Serializer net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer$Serializer
|
||||
m (Lcom/google/gson/JsonObject;Lnet/minecraft/world/level/storage/loot/entries/LootEntryAbstract;Lcom/google/gson/JsonSerializationContext;)V a serialize
|
||||
p 0 json
|
||||
p 1 entry
|
||||
p 2 context
|
||||
m (Lcom/google/gson/JsonObject;Lnet/minecraft/world/level/storage/loot/entries/LootEntryAbstract;Lcom/google/gson/JsonSerializationContext;)V serializeType serializeCustom
|
||||
@@ -1,18 +0,0 @@
|
||||
# You can use this file to change the access modifiers on a member
|
||||
# This line would make the field rollAmount public in Bee
|
||||
#public net.minecraft.world.entity.animal.Bee rollAmount
|
||||
# This line would make the field public and remove the final modifier
|
||||
#public-f net.minecraft.network.protocol.game.ClientboundChatPacket sender
|
||||
# Leave out the member and it will apply to the class itself
|
||||
# More info, see here https://mcforge.readthedocs.io/en/latest/advanced/accesstransformers/#access-modifiers
|
||||
|
||||
# Remap/Decompile fix (unclear why this is happening)
|
||||
public net.minecraft.server.MinecraftServer doRunTask(Lnet/minecraft/server/TickTask;)V
|
||||
|
||||
# AT remap issue? todo 1.18
|
||||
public net.minecraft.world.level.dimension.end.EndDragonFight findExitPortal()Lnet/minecraft/world/level/block/state/pattern/BlockPattern$BlockPatternMatch;
|
||||
public net.minecraft.nbt.TagParser readArrayTag()Lnet/minecraft/nbt/Tag;
|
||||
|
||||
# TODO 1.20 remapSpigotAt.at doesn't remap the return type for this method for some reason
|
||||
public net/minecraft/world/entity/Display$TextDisplay getText()Lnet/minecraft/network/chat/Component;
|
||||
public net/minecraft/world/entity/Display$BlockDisplay getBlockState()Lnet/minecraft/world/level/block/state/BlockState;
|
||||
@@ -1,28 +0,0 @@
|
||||
# We would like for paperweight to generate 100% perfect reobf mappings (and deobf mappings for that matter).
|
||||
# But unfortunately it's not quite there yet - and it may be some time before that happens. Generating perfect mappings
|
||||
# from Spigot's mappings is extremely difficult due to Spigot's bad tooling and bad mappings. To add insult to injury
|
||||
# we remap Spigot's _source code_ which is a lot more complex and error-prone than bytecode remapping. So with all that
|
||||
# said, this file exists to help fill in the gap.
|
||||
#
|
||||
# We will continue to improve paperweight and will work on fixing these issues so they don't come up in the first place,
|
||||
# but these mappings exist to prevent these issues from holding everything else in Paper up while we work through all
|
||||
# of these issues. Due to the complex nature of mappings generation and the debugging difficulty involved it may take
|
||||
# a significant amount of time for us to track down every possible issue, so this file will likely be around and in
|
||||
# use - at least in some capacity - for a long time.
|
||||
|
||||
tiny 2 0 mojang+yarn spigot
|
||||
|
||||
# CraftBukkit changes type
|
||||
c net/minecraft/server/level/ServerLevel net/minecraft/server/level/WorldServer
|
||||
f Lnet/minecraft/world/level/storage/PrimaryLevelData; serverLevelData K
|
||||
|
||||
c net/minecraft/world/level/chunk/LevelChunk net/minecraft/world/level/chunk/Chunk
|
||||
f Lnet/minecraft/server/level/ServerLevel; level r
|
||||
|
||||
# See mappings-patch.tiny
|
||||
c net/minecraft/server/level/ChunkMap net/minecraft/server/level/PlayerChunkMap
|
||||
f Lnet/minecraft/server/level/ChunkMap$ChunkDistanceManager; distanceManager F
|
||||
|
||||
# Paper changes type
|
||||
c net/minecraft/core/MappedRegistry net/minecraft/core/RegistryMaterials
|
||||
f Lit/unimi/dsi/fastutil/objects/Reference2IntOpenHashMap; toId e
|
||||
+39
-110
@@ -1,154 +1,83 @@
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.set
|
||||
|
||||
plugins {
|
||||
java
|
||||
`maven-publish`
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1" apply false
|
||||
id("io.papermc.paperweight.core") version "1.5.5"
|
||||
id("com.github.johnrengelman.shadow") version "7.0.0" apply false
|
||||
id("io.papermc.paperweight.core") version "1.1.9-SNAPSHOT"
|
||||
}
|
||||
|
||||
allprojects {
|
||||
subprojects {
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "maven-publish")
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
languageVersion.set(JavaLanguageVersion.of(11))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||
|
||||
subprojects {
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
options.release.set(8)
|
||||
}
|
||||
tasks.withType<Javadoc> {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
tasks.withType<ProcessResources> {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
}
|
||||
tasks.withType<Test> {
|
||||
testLogging {
|
||||
showStackTraces = true
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
events(TestLogEvent.STANDARD_OUT)
|
||||
}
|
||||
|
||||
if (name == "Paper-MojangAPI") {
|
||||
return@subprojects
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven(paperMavenPublicUrl)
|
||||
maven("https://repo1.maven.org/maven2/")
|
||||
maven("https://oss.sonatype.org/content/groups/public/")
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://ci.emc.gs/nexus/content/groups/aikar/")
|
||||
maven("https://repo.md-5.net/content/repositories/releases/")
|
||||
maven("https://hub.spigotmc.org/nexus/content/groups/public/")
|
||||
}
|
||||
}
|
||||
|
||||
val spigotDecompiler: Configuration by configurations.creating
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven(paperMavenPublicUrl) {
|
||||
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||
content {
|
||||
onlyForConfigurations(
|
||||
configurations.paperclip.name,
|
||||
spigotDecompiler.name,
|
||||
)
|
||||
onlyForConfigurations("paperclip")
|
||||
}
|
||||
}
|
||||
maven("https://maven.quiltmc.org/repository/release/") {
|
||||
content {
|
||||
onlyForConfigurations("paramMappings", "remapper")
|
||||
}
|
||||
}
|
||||
maven("https://files.minecraftforge.net/maven/") {
|
||||
content {
|
||||
onlyForConfigurations("decompiler")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paramMappings("net.fabricmc:yarn:1.20.1+build.1:mergedv2")
|
||||
remapper("net.fabricmc:tiny-remapper:0.8.6:fat")
|
||||
decompiler("net.minecraftforge:forgeflower:2.0.627.2")
|
||||
spigotDecompiler("io.papermc:patched-spigot-fernflower:0.1+build.6")
|
||||
paperclip("io.papermc:paperclip:3.0.3")
|
||||
paramMappings("org.quiltmc:yarn:1.16.5+build.6:mergedv2")
|
||||
remapper("org.quiltmc:tiny-remapper:0.4.1")
|
||||
decompiler("net.minecraftforge:forgeflower:1.5.498.12")
|
||||
paperclip("io.papermc:paperclip:2.0.1")
|
||||
}
|
||||
|
||||
paperweight {
|
||||
minecraftVersion.set(providers.gradleProperty("mcVersion"))
|
||||
serverProject.set(project(":paper-server"))
|
||||
|
||||
paramMappingsRepo.set(paperMavenPublicUrl)
|
||||
remapRepo.set(paperMavenPublicUrl)
|
||||
decompileRepo.set(paperMavenPublicUrl)
|
||||
|
||||
craftBukkit {
|
||||
fernFlowerJar.set(layout.file(spigotDecompiler.elements.map { it.single().asFile }))
|
||||
}
|
||||
serverProject.set(project(":Paper-Server"))
|
||||
|
||||
paper {
|
||||
spigotApiPatchDir.set(layout.projectDirectory.dir("patches/api"))
|
||||
spigotServerPatchDir.set(layout.projectDirectory.dir("patches/server"))
|
||||
|
||||
mappingsPatch.set(layout.projectDirectory.file("build-data/mappings-patch.tiny"))
|
||||
reobfMappingsPatch.set(layout.projectDirectory.file("build-data/reobf-mappings-patch.tiny"))
|
||||
|
||||
reobfPackagesToFix.addAll(
|
||||
"co.aikar.timings",
|
||||
"com.destroystokyo.paper",
|
||||
"com.mojang",
|
||||
"io.papermc.paper",
|
||||
"ca.spottedleaf",
|
||||
"net.kyori.adventure.bossbar",
|
||||
"net.minecraft",
|
||||
"org.bukkit.craftbukkit",
|
||||
"org.spigotmc",
|
||||
)
|
||||
additionalSpigotMemberMappings.set(layout.projectDirectory.file("build-data/additional-spigot-member-mappings.csrg"))
|
||||
craftBukkitPatchPatchesDir.set(layout.projectDirectory.dir("build-data/craftbukkit-patch-patches"))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.generateDevelopmentBundle {
|
||||
apiCoordinates.set("io.papermc.paper:paper-api")
|
||||
mojangApiCoordinates.set("io.papermc.paper:paper-mojangapi")
|
||||
libraryRepositories.addAll(
|
||||
"https://repo.maven.apache.org/maven2/",
|
||||
paperMavenPublicUrl,
|
||||
)
|
||||
}
|
||||
val rebuildRemappedPatches by tasks.registering(io.papermc.paperweight.tasks.RebuildPaperPatches::class) {
|
||||
inputDir.set(layout.cache.resolve("paperweight/patch-remap-input"))
|
||||
|
||||
publishing {
|
||||
if (project.providers.gradleProperty("publishDevBundle").isPresent) {
|
||||
publications.create<MavenPublication>("devBundle") {
|
||||
artifact(tasks.generateDevelopmentBundle) {
|
||||
artifactId = "dev-bundle"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
baseRef.set("origin/master")
|
||||
|
||||
allprojects {
|
||||
publishing {
|
||||
repositories {
|
||||
maven("https://repo.papermc.io/repository/maven-snapshots/") {
|
||||
name = "paperSnapshots"
|
||||
credentials(PasswordCredentials::class)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.collectAtsFromPatches {
|
||||
// Uncomment while updating for a new Minecraft version
|
||||
// extraPatchDir.set(layout.projectDirectory.dir("patches/unapplied/server"))
|
||||
}
|
||||
|
||||
// Uncomment while updating for a new Minecraft version
|
||||
// tasks.withType<io.papermc.paperweight.tasks.RebuildGitPatches> {
|
||||
// filterPatches.set(false)
|
||||
// }
|
||||
|
||||
tasks.register("printMinecraftVersion") {
|
||||
doLast {
|
||||
println(providers.gradleProperty("mcVersion").get().trim())
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("printPaperVersion") {
|
||||
doLast {
|
||||
println(project.version)
|
||||
}
|
||||
patchDir.set(layout.projectDirectory.dir("patches/server-remapped"))
|
||||
}
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
group=io.papermc.paper
|
||||
version=1.20.1-R0.1-SNAPSHOT
|
||||
mcVersion=1.20.1
|
||||
group = io.papermc.paper
|
||||
version = 1.16.5-R0.1-SNAPSHOT
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.vfs.watch=false
|
||||
mcVersion = 1.16.5
|
||||
packageVersion = 1_16_R3
|
||||
|
||||
org.gradle.jvmargs=-Xmx4G
|
||||
Vendored
BIN
Binary file not shown.
+1
-3
@@ -1,7 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -17,99 +17,67 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# 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
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
@@ -119,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -130,120 +98,88 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=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
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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 Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin 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" )
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
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
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, 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' ' '
|
||||
)" '"$@"'
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+6
-9
@@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,8 +25,7 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -41,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -76,15 +75,13 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
+1
-1
@@ -672,4 +672,4 @@ program into proprietary programs. If your program is a subroutine
|
||||
library, you may consider it more useful to permit linking proprietary
|
||||
applications with the library. If this is what you want to do, use the
|
||||
GNU Lesser General Public License instead of this License. But first,
|
||||
please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
@@ -1,14 +1,11 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Wood <kyle@denwav.dev>
|
||||
From: Kyle Wood <demonwav@gmail.com>
|
||||
Date: Thu, 10 Dec 2020 20:50:33 -0800
|
||||
Subject: [PATCH] Convert project to Gradle
|
||||
|
||||
The pom.xml file is deleted in this patch so the patch will fail to
|
||||
apply if there are changes made to it from upstream - thus notifying us
|
||||
that changes were made.
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 11038da2e071699d6561a331565db0c8d7850d0e..317acfec5894101294a55abff61819431e6a5e65 100644
|
||||
index e431e3435737e28394d81b56568a08b3c3148b9b..c484aff2c192bf42059b5689327909e4af654401 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -1,3 +1,5 @@
|
||||
@@ -17,23 +14,15 @@ index 11038da2e071699d6561a331565db0c8d7850d0e..317acfec5894101294a55abff6181943
|
||||
# Eclipse stuff
|
||||
/.classpath
|
||||
/.project
|
||||
@@ -31,3 +33,7 @@
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
+
|
||||
+# vs code
|
||||
+/.vscode
|
||||
+/.factorypath
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c2e5d8006420aab5a60e5aaa188223aeb0396483
|
||||
index 0000000000000000000000000000000000000000..5cf81a0fdc112223d19a20c9be597b60e8a35173
|
||||
--- /dev/null
|
||||
+++ b/build.gradle.kts
|
||||
@@ -0,0 +1,86 @@
|
||||
@@ -0,0 +1,50 @@
|
||||
+plugins {
|
||||
+ `java-library`
|
||||
+ `maven-publish`
|
||||
+ checkstyle
|
||||
+}
|
||||
+
|
||||
+java {
|
||||
@@ -41,355 +30,43 @@ index 0000000000000000000000000000000000000000..c2e5d8006420aab5a60e5aaa188223ae
|
||||
+ withJavadocJar()
|
||||
+}
|
||||
+
|
||||
+val annotationsVersion = "24.0.1"
|
||||
+val bungeeCordChatVersion = "1.20-R0.1"
|
||||
+
|
||||
+dependencies {
|
||||
+ // api dependencies are listed transitively to API consumers
|
||||
+ api("com.google.guava:guava:31.1-jre")
|
||||
+ api("com.google.code.gson:gson:2.10")
|
||||
+ api("net.md-5:bungeecord-chat:$bungeeCordChatVersion")
|
||||
+ api("org.yaml:snakeyaml:2.0")
|
||||
+ api("org.joml:joml:1.10.5")
|
||||
+ api("commons-lang:commons-lang:2.6")
|
||||
+ api("com.google.guava:guava:21.0")
|
||||
+ api("com.google.code.gson:gson:2.8.0")
|
||||
+ api("net.md-5:bungeecord-chat:1.16-R0.4")
|
||||
+ api("org.yaml:snakeyaml:1.27")
|
||||
+
|
||||
+ compileOnly("org.apache.maven:maven-resolver-provider:3.8.5")
|
||||
+ compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3")
|
||||
+ compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3")
|
||||
+
|
||||
+ val annotations = "org.jetbrains:annotations-java5:$annotationsVersion"
|
||||
+ val annotations = "org.jetbrains:annotations-java5:20.1.0"
|
||||
+ compileOnly(annotations)
|
||||
+ testCompileOnly(annotations)
|
||||
+
|
||||
+ testImplementation("org.apache.commons:commons-lang3:3.12.0")
|
||||
+ testImplementation("junit:junit:4.13.2")
|
||||
+ testImplementation("junit:junit:4.13.1")
|
||||
+ testImplementation("org.hamcrest:hamcrest-library:1.3")
|
||||
+ testImplementation("org.ow2.asm:asm-tree:9.5")
|
||||
+}
|
||||
+ testImplementation("org.ow2.asm:asm-tree:9.1")
|
||||
+
|
||||
+configure<PublishingExtension> {
|
||||
+ publications.create<MavenPublication>("maven") {
|
||||
+ from(components["java"])
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+val generateApiVersioningFile by tasks.registering {
|
||||
+ inputs.property("version", project.version)
|
||||
+ val pomProps = layout.buildDirectory.file("pom.properties")
|
||||
+ outputs.file(pomProps)
|
||||
+ val projectVersion = project.version
|
||||
+ doLast {
|
||||
+ pomProps.get().asFile.writeText("version=$projectVersion")
|
||||
+ }
|
||||
+ checkstyle("com.puppycrawl.tools:checkstyle:8.39")
|
||||
+}
|
||||
+
|
||||
+tasks.jar {
|
||||
+ from(generateApiVersioningFile.map { it.outputs.files.singleFile }) {
|
||||
+ into("META-INF/maven/${project.group}/${project.name}")
|
||||
+ }
|
||||
+ manifest {
|
||||
+ attributes(
|
||||
+ attributes += mapOf(
|
||||
+ "Automatic-Module-Name" to "org.bukkit"
|
||||
+ )
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+tasks.withType<Javadoc> {
|
||||
+ val options = options as StandardJavadocDocletOptions
|
||||
+ options.overview = "src/main/javadoc/overview.html"
|
||||
+ options.use()
|
||||
+ options.isDocFilesSubDirs = true
|
||||
+ options.links(
|
||||
+ "https://guava.dev/releases/31.1-jre/api/docs/",
|
||||
+ "https://javadoc.io/doc/org.yaml/snakeyaml/2.0/",
|
||||
+ "https://javadoc.io/doc/org.jetbrains/annotations-java5/$annotationsVersion/",
|
||||
+ "https://javadoc.io/doc/net.md-5/bungeecord-chat/$bungeeCordChatVersion/",
|
||||
+tasks.withType<Javadoc>().configureEach {
|
||||
+ (options as StandardJavadocDocletOptions).links(
|
||||
+ "https://guava.dev/releases/21.0/api/docs/",
|
||||
+ "https://javadoc.io/doc/org.yaml/snakeyaml/1.27/",
|
||||
+ "https://javadoc.io/doc/org.jetbrains/annotations-java5/20.1.0/",
|
||||
+ "https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.4/"
|
||||
+ )
|
||||
+ options.tags("apiNote:a:API Note:")
|
||||
+
|
||||
+ // workaround for https://github.com/gradle/gradle/issues/4046
|
||||
+ inputs.dir("src/main/javadoc").withPropertyName("javadoc-sourceset")
|
||||
+ doLast {
|
||||
+ copy {
|
||||
+ from("src/main/javadoc") {
|
||||
+ include("**/doc-files/**")
|
||||
+ }
|
||||
+ into("build/docs/javadoc")
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/pom.xml b/pom.xml
|
||||
deleted file mode 100644
|
||||
index 068987ca1171857fc9996d645e775448a09f0feb..0000000000000000000000000000000000000000
|
||||
--- a/pom.xml
|
||||
+++ /dev/null
|
||||
@@ -1,270 +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>org.spigotmc</groupId>
|
||||
- <artifactId>spigot-api</artifactId>
|
||||
- <version>1.20.1-R0.1-SNAPSHOT</version>
|
||||
- <packaging>jar</packaging>
|
||||
-
|
||||
- <name>Spigot-API</name>
|
||||
- <url>https://www.spigotmc.org/</url>
|
||||
- <description>An enhanced plugin API for Minecraft servers.</description>
|
||||
-
|
||||
- <properties>
|
||||
- <skipTests>true</skipTests>
|
||||
- <maven.compiler.source>1.8</maven.compiler.source>
|
||||
- <maven.compiler.target>1.8</maven.compiler.target>
|
||||
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
- </properties>
|
||||
-
|
||||
- <distributionManagement>
|
||||
- <repository>
|
||||
- <id>spigotmc-releases</id>
|
||||
- <url>https://hub.spigotmc.org/nexus/content/repositories/releases/</url>
|
||||
- </repository>
|
||||
- <snapshotRepository>
|
||||
- <id>spigotmc-snapshots</id>
|
||||
- <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
- </snapshotRepository>
|
||||
- </distributionManagement>
|
||||
-
|
||||
- <dependencies>
|
||||
- <!-- bundled with Minecraft, should be kept in sync -->
|
||||
- <dependency>
|
||||
- <groupId>com.google.guava</groupId>
|
||||
- <artifactId>guava</artifactId>
|
||||
- <version>31.1-jre</version>
|
||||
- <scope>compile</scope>
|
||||
- </dependency>
|
||||
- <!-- bundled with Minecraft, should be kept in sync -->
|
||||
- <dependency>
|
||||
- <groupId>com.google.code.gson</groupId>
|
||||
- <artifactId>gson</artifactId>
|
||||
- <version>2.10</version>
|
||||
- <scope>compile</scope>
|
||||
- </dependency>
|
||||
- <!-- bundled with Minecraft, should be kept in sync -->
|
||||
- <dependency>
|
||||
- <groupId>org.joml</groupId>
|
||||
- <artifactId>joml</artifactId>
|
||||
- <version>1.10.5</version>
|
||||
- <scope>compile</scope>
|
||||
- </dependency>
|
||||
- <dependency>
|
||||
- <groupId>net.md-5</groupId>
|
||||
- <artifactId>bungeecord-chat</artifactId>
|
||||
- <version>1.20-R0.1</version>
|
||||
- <type>jar</type>
|
||||
- <scope>compile</scope>
|
||||
- </dependency>
|
||||
- <dependency>
|
||||
- <groupId>org.yaml</groupId>
|
||||
- <artifactId>snakeyaml</artifactId>
|
||||
- <version>2.0</version>
|
||||
- <scope>compile</scope>
|
||||
- </dependency>
|
||||
- <!-- not part of the API proper -->
|
||||
- <dependency>
|
||||
- <groupId>org.apache.maven</groupId>
|
||||
- <artifactId>maven-resolver-provider</artifactId>
|
||||
- <version>3.8.5</version>
|
||||
- <scope>provided</scope>
|
||||
- </dependency>
|
||||
- <dependency>
|
||||
- <groupId>org.apache.maven.resolver</groupId>
|
||||
- <artifactId>maven-resolver-connector-basic</artifactId>
|
||||
- <version>1.7.3</version>
|
||||
- <scope>provided</scope>
|
||||
- </dependency>
|
||||
- <dependency>
|
||||
- <groupId>org.apache.maven.resolver</groupId>
|
||||
- <artifactId>maven-resolver-transport-http</artifactId>
|
||||
- <version>1.7.3</version>
|
||||
- <scope>provided</scope>
|
||||
- </dependency>
|
||||
- <!-- annotations -->
|
||||
- <dependency>
|
||||
- <groupId>org.jetbrains</groupId>
|
||||
- <artifactId>annotations-java5</artifactId>
|
||||
- <version>24.0.1</version>
|
||||
- <scope>provided</scope>
|
||||
- </dependency>
|
||||
- <!-- testing -->
|
||||
- <dependency>
|
||||
- <groupId>junit</groupId>
|
||||
- <artifactId>junit</artifactId>
|
||||
- <version>4.13.2</version>
|
||||
- <scope>test</scope>
|
||||
- </dependency>
|
||||
- <dependency>
|
||||
- <groupId>org.hamcrest</groupId>
|
||||
- <artifactId>hamcrest-library</artifactId>
|
||||
- <version>1.3</version>
|
||||
- <scope>test</scope>
|
||||
- </dependency>
|
||||
- <dependency>
|
||||
- <groupId>org.ow2.asm</groupId>
|
||||
- <artifactId>asm-tree</artifactId>
|
||||
- <version>9.5</version>
|
||||
- <scope>test</scope>
|
||||
- </dependency>
|
||||
- </dependencies>
|
||||
-
|
||||
- <build>
|
||||
- <plugins>
|
||||
- <plugin>
|
||||
- <groupId>net.md-5</groupId>
|
||||
- <artifactId>scriptus</artifactId>
|
||||
- <version>0.5.0</version>
|
||||
- <executions>
|
||||
- <execution>
|
||||
- <phase>initialize</phase>
|
||||
- <goals>
|
||||
- <goal>describe</goal>
|
||||
- </goals>
|
||||
- </execution>
|
||||
- </executions>
|
||||
- </plugin>
|
||||
- <plugin>
|
||||
- <groupId>org.apache.maven.plugins</groupId>
|
||||
- <artifactId>maven-compiler-plugin</artifactId>
|
||||
- <version>3.11.0</version>
|
||||
- <configuration>
|
||||
- <!-- we use the Eclipse compiler as it doesn't need a JDK -->
|
||||
- <compilerId>eclipse</compilerId>
|
||||
- <!-- default changed with version 3.11.0 -->
|
||||
- <showWarnings>false</showWarnings>
|
||||
- </configuration>
|
||||
- <dependencies>
|
||||
- <dependency>
|
||||
- <groupId>org.codehaus.plexus</groupId>
|
||||
- <artifactId>plexus-compiler-eclipse</artifactId>
|
||||
- <version>2.13.0</version>
|
||||
- </dependency>
|
||||
- </dependencies>
|
||||
- </plugin>
|
||||
- <plugin>
|
||||
- <groupId>org.apache.maven.plugins</groupId>
|
||||
- <artifactId>maven-jar-plugin</artifactId>
|
||||
- <version>3.3.0</version>
|
||||
- <configuration>
|
||||
- <archive>
|
||||
- <manifest>
|
||||
- <addDefaultEntries>false</addDefaultEntries>
|
||||
- </manifest>
|
||||
- <manifestEntries>
|
||||
- <Automatic-Module-Name>org.bukkit</Automatic-Module-Name>
|
||||
- </manifestEntries>
|
||||
- </archive>
|
||||
- </configuration>
|
||||
- </plugin>
|
||||
- <plugin>
|
||||
- <groupId>org.apache.maven.plugins</groupId>
|
||||
- <artifactId>maven-shade-plugin</artifactId>
|
||||
- <version>3.5.0</version>
|
||||
- <executions>
|
||||
- <execution>
|
||||
- <phase>package</phase>
|
||||
- <goals>
|
||||
- <goal>shade</goal>
|
||||
- </goals>
|
||||
- </execution>
|
||||
- </executions>
|
||||
- <configuration>
|
||||
- <filters>
|
||||
- <filter>
|
||||
- <artifact>*:*</artifact>
|
||||
- <excludes>
|
||||
- <exclude>META-INF/MANIFEST.MF</exclude>
|
||||
- </excludes>
|
||||
- </filter>
|
||||
- </filters>
|
||||
- <!-- when downloading via Maven we can pull depends individually -->
|
||||
- <shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
- <!-- In 3.3.0 and later, shadedArtifactAttached causes dependant projects to use dependency reduced pom (bug?) -->
|
||||
- <createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
- </configuration>
|
||||
- </plugin>
|
||||
- <plugin>
|
||||
- <groupId>org.apache.maven.plugins</groupId>
|
||||
- <artifactId>maven-javadoc-plugin</artifactId>
|
||||
- <version>3.5.0</version>
|
||||
- <configuration>
|
||||
- <links>
|
||||
- <link>https://guava.dev/releases/31.1-jre/api/docs/</link>
|
||||
- <link>https://javadoc.io/doc/org.yaml/snakeyaml/2.0/</link>
|
||||
- <link>https://javadoc.io/doc/org.jetbrains/annotations-java5/24.0.1/</link>
|
||||
- <link>https://javadoc.io/doc/net.md-5/bungeecord-chat/1.20-R0.1/</link>
|
||||
- </links>
|
||||
- <tags>
|
||||
- <tag>
|
||||
- <name>apiNote</name>
|
||||
- <placement>a</placement>
|
||||
- <head>API Note:</head>
|
||||
- </tag>
|
||||
- </tags>
|
||||
- </configuration>
|
||||
- </plugin>
|
||||
- </plugins>
|
||||
- </build>
|
||||
-
|
||||
- <profiles>
|
||||
- <profile>
|
||||
- <id>development</id>
|
||||
- <properties>
|
||||
- <skipTests>false</skipTests>
|
||||
- </properties>
|
||||
- <build>
|
||||
- <plugins>
|
||||
- <plugin>
|
||||
- <groupId>org.apache.maven.plugins</groupId>
|
||||
- <artifactId>maven-checkstyle-plugin</artifactId>
|
||||
- <version>3.3.0</version>
|
||||
- <executions>
|
||||
- <execution>
|
||||
- <phase>process-classes</phase>
|
||||
- <goals>
|
||||
- <goal>check</goal>
|
||||
- </goals>
|
||||
- </execution>
|
||||
- </executions>
|
||||
- <configuration>
|
||||
- <configLocation>checkstyle.xml</configLocation>
|
||||
- <suppressionsLocation>checkstyle-suppressions.xml</suppressionsLocation>
|
||||
- <includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||
- </configuration>
|
||||
- <dependencies>
|
||||
- <dependency>
|
||||
- <groupId>com.puppycrawl.tools</groupId>
|
||||
- <artifactId>checkstyle</artifactId>
|
||||
- <version>8.45.1</version>
|
||||
- </dependency>
|
||||
- </dependencies>
|
||||
- </plugin>
|
||||
- <plugin>
|
||||
- <groupId>org.codehaus.mojo</groupId>
|
||||
- <artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||
- <version>1.23</version>
|
||||
- <executions>
|
||||
- <execution>
|
||||
- <phase>process-classes</phase>
|
||||
- <goals>
|
||||
- <goal>check</goal>
|
||||
- </goals>
|
||||
- </execution>
|
||||
- </executions>
|
||||
- <configuration>
|
||||
- <signature>
|
||||
- <groupId>org.codehaus.mojo.signature</groupId>
|
||||
- <artifactId>java18</artifactId>
|
||||
- <version>1.0</version>
|
||||
- </signature>
|
||||
- </configuration>
|
||||
- </plugin>
|
||||
- </plugins>
|
||||
- </build>
|
||||
- </profile>
|
||||
- </profiles>
|
||||
-</project>
|
||||
+
|
||||
+checkstyle {
|
||||
+ configFile = file("checkstyle.xml")
|
||||
+ sourceSets = listOf(project.sourceSets.main.get(), project.sourceSets.test.get())
|
||||
+}
|
||||
@@ -1,87 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Tue, 1 Mar 2016 00:16:08 +0100
|
||||
Subject: [PATCH] Build system changes
|
||||
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index c2e5d8006420aab5a60e5aaa188223aeb0396483..ffd1c792b0e0fe1ed3da85cf933202c5193734ce 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -18,15 +18,27 @@ dependencies {
|
||||
api("net.md-5:bungeecord-chat:$bungeeCordChatVersion")
|
||||
api("org.yaml:snakeyaml:2.0")
|
||||
api("org.joml:joml:1.10.5")
|
||||
+ // Paper start
|
||||
+ api("com.googlecode.json-simple:json-simple:1.1.1") {
|
||||
+ isTransitive = false // includes junit
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
compileOnly("org.apache.maven:maven-resolver-provider:3.8.5")
|
||||
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3")
|
||||
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3")
|
||||
+ compileOnly("com.google.code.findbugs:jsr305:1.3.9") // Paper
|
||||
|
||||
- val annotations = "org.jetbrains:annotations-java5:$annotationsVersion"
|
||||
+ val annotations = "org.jetbrains:annotations:$annotationsVersion" // Paper - we don't want Java 5 annotations...
|
||||
compileOnly(annotations)
|
||||
testCompileOnly(annotations)
|
||||
|
||||
+ // Paper start - add checker
|
||||
+ val checkerQual = "org.checkerframework:checker-qual:3.21.0"
|
||||
+ compileOnlyApi(checkerQual)
|
||||
+ testCompileOnly(checkerQual)
|
||||
+ // Paper end
|
||||
+
|
||||
testImplementation("org.apache.commons:commons-lang3:3.12.0")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.hamcrest:hamcrest-library:1.3")
|
||||
@@ -68,7 +80,7 @@ tasks.withType<Javadoc> {
|
||||
options.links(
|
||||
"https://guava.dev/releases/31.1-jre/api/docs/",
|
||||
"https://javadoc.io/doc/org.yaml/snakeyaml/2.0/",
|
||||
- "https://javadoc.io/doc/org.jetbrains/annotations-java5/$annotationsVersion/",
|
||||
+ "https://javadoc.io/doc/org.jetbrains/annotations/$annotationsVersion/", // Paper - we don't want Java 5 annotations
|
||||
"https://javadoc.io/doc/net.md-5/bungeecord-chat/$bungeeCordChatVersion/",
|
||||
)
|
||||
options.tags("apiNote:a:API Note:")
|
||||
@@ -84,3 +96,14 @@ tasks.withType<Javadoc> {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+// Paper start
|
||||
+val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks.ScanJarForBadCalls::class) {
|
||||
+ badAnnotations.add("Lio/papermc/paper/annotation/DoNotUse;")
|
||||
+ jarToScan.set(tasks.jar.flatMap { it.archiveFile })
|
||||
+ classpath.from(configurations.compileClasspath)
|
||||
+}
|
||||
+tasks.check {
|
||||
+ dependsOn(scanJar)
|
||||
+}
|
||||
+// Paper end
|
||||
diff --git a/src/main/java/io/papermc/paper/annotation/DoNotUse.java b/src/main/java/io/papermc/paper/annotation/DoNotUse.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4766e49d819e75e5c2127c698b44078bf2fd6219
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/annotation/DoNotUse.java
|
||||
@@ -0,0 +1,18 @@
|
||||
+package io.papermc.paper.annotation;
|
||||
+
|
||||
+import java.lang.annotation.ElementType;
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+import java.lang.annotation.Target;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+
|
||||
+/**
|
||||
+ * Annotation used to mark methods or constructors which should not be called.
|
||||
+ *
|
||||
+ * <p>Separate from {@link Deprecated} to differentiate from the large amount of deprecations.</p>
|
||||
+ */
|
||||
+@ApiStatus.Internal
|
||||
+@Retention(RetentionPolicy.RUNTIME)
|
||||
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
+public @interface DoNotUse {
|
||||
+}
|
||||
@@ -1,542 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 17 Mar 2019 23:04:30 +0000
|
||||
Subject: [PATCH] Test changes
|
||||
|
||||
- convert to mockito for mocking of types
|
||||
- Allow use of TYPE_USE annotations
|
||||
- Ignore package-private methods for nullability annotations
|
||||
- Add excludes for classes which don't pass
|
||||
- Disable stupid BukkitMirrorTest
|
||||
|
||||
Co-authored-by: Riley Park <rileysebastianpark@gmail.com>
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index ffd1c792b0e0fe1ed3da85cf933202c5193734ce..b38a9f4d628fa639e5d2b7dcd5a63f0bf6b8330b 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -38,6 +38,7 @@ dependencies {
|
||||
compileOnlyApi(checkerQual)
|
||||
testCompileOnly(checkerQual)
|
||||
// Paper end
|
||||
+ testImplementation("org.mockito:mockito-core:4.9.0") // Paper - add mockito
|
||||
|
||||
testImplementation("org.apache.commons:commons-lang3:3.12.0")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
diff --git a/src/test/java/io/papermc/paper/testing/EmptyRegistry.java b/src/test/java/io/papermc/paper/testing/EmptyRegistry.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ba9ddce87a9f385e729a5c2cf7c5eec120e388a7
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/testing/EmptyRegistry.java
|
||||
@@ -0,0 +1,23 @@
|
||||
+package io.papermc.paper.testing;
|
||||
+
|
||||
+import java.util.Collections;
|
||||
+import java.util.Iterator;
|
||||
+import org.bukkit.Keyed;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.bukkit.Registry;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public record EmptyRegistry() implements Registry<Keyed> {
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Iterator<Keyed> iterator() {
|
||||
+ return Collections.emptyIterator();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Nullable Keyed get(@NotNull final NamespacedKey key) {
|
||||
+ return null;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/test/java/io/papermc/paper/testing/EmptyTag.java b/src/test/java/io/papermc/paper/testing/EmptyTag.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..77154095cfb8b259bdb318e8ff40cb6f559ebc18
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/testing/EmptyTag.java
|
||||
@@ -0,0 +1,31 @@
|
||||
+package io.papermc.paper.testing;
|
||||
+
|
||||
+import java.util.Collections;
|
||||
+import java.util.Set;
|
||||
+import org.bukkit.Keyed;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.bukkit.Tag;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public record EmptyTag(NamespacedKey key) implements Tag<Keyed> {
|
||||
+
|
||||
+ @SuppressWarnings("deprecation")
|
||||
+ public EmptyTag() {
|
||||
+ this(NamespacedKey.randomKey());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull NamespacedKey getKey() {
|
||||
+ return this.key;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isTagged(@NotNull final Keyed item) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Set<Keyed> getValues() {
|
||||
+ return Collections.emptySet();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/test/java/io/papermc/paper/testing/TestServer.java b/src/test/java/io/papermc/paper/testing/TestServer.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..756acf231b1b076b08046d86992ba7ce7f62a94f
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/testing/TestServer.java
|
||||
@@ -0,0 +1,48 @@
|
||||
+package io.papermc.paper.testing;
|
||||
+
|
||||
+import java.util.logging.Logger;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.bukkit.Server;
|
||||
+import org.bukkit.command.SimpleCommandMap;
|
||||
+import org.bukkit.plugin.PluginManager;
|
||||
+import org.bukkit.plugin.SimplePluginManager;
|
||||
+
|
||||
+import static org.mockito.ArgumentMatchers.anyString;
|
||||
+import static org.mockito.Mockito.any;
|
||||
+import static org.mockito.Mockito.mock;
|
||||
+import static org.mockito.Mockito.when;
|
||||
+
|
||||
+public final class TestServer {
|
||||
+
|
||||
+ @SuppressWarnings("removal")
|
||||
+ public static void setup() {
|
||||
+ //noinspection ConstantValue
|
||||
+ if (Bukkit.getServer() != null) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ final Server dummyServer = mock(Server.class);
|
||||
+
|
||||
+ final Logger logger = Logger.getLogger(TestServer.class.getCanonicalName());
|
||||
+ when(dummyServer.getLogger()).thenReturn(logger);
|
||||
+ when(dummyServer.getName()).thenReturn(TestServer.class.getSimpleName());
|
||||
+ when(dummyServer.getVersion()).thenReturn("Version_" + TestServer.class.getPackage().getImplementationVersion());
|
||||
+ when(dummyServer.getBukkitVersion()).thenReturn("BukkitVersion_" + TestServer.class.getPackage().getImplementationVersion());
|
||||
+
|
||||
+
|
||||
+ final Thread currentThread = Thread.currentThread();
|
||||
+ when(dummyServer.isPrimaryThread()).thenAnswer(ignored -> Thread.currentThread().equals(currentThread));
|
||||
+
|
||||
+ when(dummyServer.getTag(anyString(), any(NamespacedKey.class), any())).thenAnswer(ignored -> new EmptyTag());
|
||||
+
|
||||
+ final PluginManager pluginManager = new SimplePluginManager(dummyServer, new SimpleCommandMap(dummyServer));
|
||||
+ when(dummyServer.getPluginManager()).thenReturn(pluginManager);
|
||||
+
|
||||
+ when(dummyServer.getRegistry(any())).thenAnswer(ignored -> new EmptyRegistry());
|
||||
+ when(dummyServer.getScoreboardCriteria(anyString())).thenReturn(null);
|
||||
+
|
||||
+ Bukkit.setServer(dummyServer);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java
|
||||
index 4ac3dd977e75cd8464163351d306e037ee32cb48..c26ea217927ba77611e6ae93f8df50a83bceb3dd 100644
|
||||
--- a/src/test/java/org/bukkit/AnnotationTest.java
|
||||
+++ b/src/test/java/org/bukkit/AnnotationTest.java
|
||||
@@ -29,7 +29,13 @@ public class AnnotationTest {
|
||||
"Lorg/jetbrains/annotations/Nullable;",
|
||||
"Lorg/jetbrains/annotations/NotNull;",
|
||||
"Lorg/jetbrains/annotations/Contract;",
|
||||
- "Lorg/bukkit/UndefinedNullability;"
|
||||
+ "Lorg/bukkit/UndefinedNullability;",
|
||||
+ // Paper start
|
||||
+ "Lorg/checkerframework/checker/nullness/qual/MonotonicNonNull;",
|
||||
+ "Lorg/checkerframework/checker/nullness/qual/NonNull;",
|
||||
+ "Lorg/checkerframework/checker/nullness/qual/Nullable;",
|
||||
+ "Lorg/checkerframework/checker/nullness/qual/PolyNull;",
|
||||
+ // Paper end
|
||||
};
|
||||
|
||||
private static final String[] EXCLUDED_CLASSES = {
|
||||
@@ -40,7 +46,17 @@ public class AnnotationTest {
|
||||
"org/bukkit/util/io/Wrapper",
|
||||
"org/bukkit/plugin/java/PluginClassLoader",
|
||||
// Generic functional interface
|
||||
- "org/bukkit/util/Consumer"
|
||||
+ "org/bukkit/util/Consumer",
|
||||
+ // Paper start
|
||||
+ // Timings history is broken in terms of nullability due to guavas Function defining that the param is NonNull
|
||||
+ "co/aikar/timings/TimingHistory$2",
|
||||
+ "co/aikar/timings/TimingHistory$2$1",
|
||||
+ "co/aikar/timings/TimingHistory$2$1$1",
|
||||
+ "co/aikar/timings/TimingHistory$2$1$2",
|
||||
+ "co/aikar/timings/TimingHistory$3",
|
||||
+ "co/aikar/timings/TimingHistory$4",
|
||||
+ "co/aikar/timings/TimingHistoryEntry$1"
|
||||
+ // Paper end
|
||||
};
|
||||
|
||||
@Test
|
||||
@@ -67,14 +83,40 @@ public class AnnotationTest {
|
||||
}
|
||||
|
||||
if (mustBeAnnotated(Type.getReturnType(method.desc)) && !isWellAnnotated(method.invisibleAnnotations)) {
|
||||
+ // Paper start - Allow use of TYPE_USE annotations
|
||||
+ boolean warn = true;
|
||||
+ if (isWellAnnotated(method.visibleTypeAnnotations)) {
|
||||
+ warn = false;
|
||||
+ } else if (method.invisibleTypeAnnotations != null) {
|
||||
+ dance: for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.invisibleTypeAnnotations) {
|
||||
+ final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef);
|
||||
+ if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_RETURN && java.util.Arrays.asList(ACCEPTED_ANNOTATIONS).contains(invisibleTypeAnnotation.desc)) {
|
||||
+ warn = false;
|
||||
+ break dance; // cha cha real smooth
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (warn)
|
||||
+ // Paper end
|
||||
warn(errors, clazz, method, "return value");
|
||||
}
|
||||
|
||||
Type[] paramTypes = Type.getArgumentTypes(method.desc);
|
||||
List<ParameterNode> parameters = method.parameters;
|
||||
|
||||
+ dancing: // Paper
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
if (mustBeAnnotated(paramTypes[i]) ^ isWellAnnotated(method.invisibleParameterAnnotations == null ? null : method.invisibleParameterAnnotations[i])) {
|
||||
+ // Paper start
|
||||
+ if (method.invisibleTypeAnnotations != null) {
|
||||
+ for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.invisibleTypeAnnotations) {
|
||||
+ final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef);
|
||||
+ if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_FORMAL_PARAMETER && ref.getTypeParameterIndex() == i && java.util.Arrays.asList(ACCEPTED_ANNOTATIONS).contains(invisibleTypeAnnotation.desc)) {
|
||||
+ continue dancing;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Allow use of TYPE_USE annotations
|
||||
ParameterNode paramNode = parameters == null ? null : parameters.get(i);
|
||||
String paramName = paramNode == null ? null : paramNode.name;
|
||||
|
||||
@@ -91,13 +133,18 @@ public class AnnotationTest {
|
||||
|
||||
Collections.sort(errors);
|
||||
|
||||
- System.out.println(errors.size() + " missing annotation(s):");
|
||||
+ StringBuilder builder = new StringBuilder()
|
||||
+ .append("There ")
|
||||
+ .append(errors.size() != 1 ? "are " : "is ")
|
||||
+ .append(errors.size())
|
||||
+ .append(" missing annotation")
|
||||
+ .append(errors.size() != 1 ? "s:\n" : ":\n");
|
||||
+
|
||||
for (String message : errors) {
|
||||
- System.out.print("\t");
|
||||
- System.out.println(message);
|
||||
+ builder.append("\t").append(message).append("\n");
|
||||
}
|
||||
|
||||
- Assert.fail("There " + errors.size() + " are missing annotation(s)");
|
||||
+ Assert.fail(builder.toString());
|
||||
}
|
||||
|
||||
private static void collectClasses(@NotNull File from, @NotNull Map<String, ClassNode> to) throws IOException {
|
||||
@@ -140,6 +187,11 @@ public class AnnotationTest {
|
||||
// Exceptions are excluded
|
||||
return false;
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (isInternal(clazz.invisibleAnnotations)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
for (String excludedClass : EXCLUDED_CLASSES) {
|
||||
if (excludedClass.equals(clazz.name)) {
|
||||
@@ -152,7 +204,7 @@ public class AnnotationTest {
|
||||
|
||||
private static boolean isMethodIncluded(@NotNull ClassNode clazz, @NotNull MethodNode method, @NotNull Map<String, ClassNode> allClasses) {
|
||||
// Exclude private, synthetic and deprecated methods
|
||||
- if ((method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED)) != 0) {
|
||||
+ if ((method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED)) != 0 || (method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0) { // Paper - ignore package-private
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -170,11 +222,30 @@ public class AnnotationTest {
|
||||
if ("<init>".equals(method.name) && isAnonymous(clazz)) {
|
||||
return false;
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (isInternal(method.invisibleAnnotations)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
return true;
|
||||
}
|
||||
+ // Paper start
|
||||
+ private static boolean isInternal(List<? extends AnnotationNode> annotations) {
|
||||
+ if (annotations == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ for (AnnotationNode node : annotations) {
|
||||
+ if (node.desc.equals("Lorg/jetbrains/annotations/ApiStatus$Internal;")) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
- private static boolean isWellAnnotated(@Nullable List<AnnotationNode> annotations) {
|
||||
+ private static boolean isWellAnnotated(@Nullable List<? extends AnnotationNode> annotations) { // Paper
|
||||
if (annotations == null) {
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/test/java/org/bukkit/BukkitMirrorTest.java b/src/test/java/org/bukkit/BukkitMirrorTest.java
|
||||
index 2dfada66067d79b84cd490eadbe0178e8cd8c260..06d66512c91c680130132b79e34fbf32245ff9ee 100644
|
||||
--- a/src/test/java/org/bukkit/BukkitMirrorTest.java
|
||||
+++ b/src/test/java/org/bukkit/BukkitMirrorTest.java
|
||||
@@ -20,6 +20,7 @@ public class BukkitMirrorTest {
|
||||
|
||||
@Parameters(name = "{index}: {1}")
|
||||
public static List<Object[]> data() {
|
||||
+ if (true) return List.of(); // Paper
|
||||
return Lists.transform(Arrays.asList(Server.class.getDeclaredMethods()), new Function<Method, Object[]>() {
|
||||
@Override
|
||||
public Object[] apply(Method input) {
|
||||
diff --git a/src/test/java/org/bukkit/TestServer.java b/src/test/java/org/bukkit/TestServer.java
|
||||
deleted file mode 100644
|
||||
index 701a17c10f31cd345238a3c568264178ce372faa..0000000000000000000000000000000000000000
|
||||
--- a/src/test/java/org/bukkit/TestServer.java
|
||||
+++ /dev/null
|
||||
@@ -1,139 +0,0 @@
|
||||
-package org.bukkit;
|
||||
-
|
||||
-import com.google.common.collect.ImmutableMap;
|
||||
-import java.lang.reflect.InvocationHandler;
|
||||
-import java.lang.reflect.Method;
|
||||
-import java.lang.reflect.Proxy;
|
||||
-import java.util.Iterator;
|
||||
-import java.util.Map;
|
||||
-import java.util.logging.Logger;
|
||||
-import org.bukkit.command.SimpleCommandMap;
|
||||
-import org.bukkit.plugin.PluginManager;
|
||||
-import org.bukkit.plugin.SimplePluginManager;
|
||||
-import org.jetbrains.annotations.NotNull;
|
||||
-import org.jetbrains.annotations.Nullable;
|
||||
-
|
||||
-public final class TestServer implements InvocationHandler {
|
||||
- private static interface MethodHandler {
|
||||
- Object handle(TestServer server, Object[] args);
|
||||
- }
|
||||
-
|
||||
- private static final Map<Method, MethodHandler> methods;
|
||||
-
|
||||
- static {
|
||||
- try {
|
||||
- ImmutableMap.Builder<Method, MethodHandler> methodMap = ImmutableMap.builder();
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("isPrimaryThread"),
|
||||
- new MethodHandler() {
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- return Thread.currentThread().equals(server.creatingThread);
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("getPluginManager"),
|
||||
- new MethodHandler() {
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- return server.pluginManager;
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("getLogger"),
|
||||
- new MethodHandler() {
|
||||
- final Logger logger = Logger.getLogger(TestServer.class.getCanonicalName());
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- return logger;
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("getName"),
|
||||
- new MethodHandler() {
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- return TestServer.class.getSimpleName();
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("getVersion"),
|
||||
- new MethodHandler() {
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- return "Version_" + TestServer.class.getPackage().getImplementationVersion();
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("getBukkitVersion"),
|
||||
- new MethodHandler() {
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- return "BukkitVersion_" + TestServer.class.getPackage().getImplementationVersion();
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("getRegistry", Class.class),
|
||||
- new MethodHandler() {
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- return new Registry() {
|
||||
- @NotNull
|
||||
- @Override
|
||||
- public Iterator iterator() {
|
||||
- return null;
|
||||
- }
|
||||
-
|
||||
- @Nullable
|
||||
- @Override
|
||||
- public Keyed get(@NotNull NamespacedKey key) {
|
||||
- return null;
|
||||
- }
|
||||
- };
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methodMap.put(
|
||||
- Server.class.getMethod("getScoreboardCriteria", String.class),
|
||||
- new MethodHandler() {
|
||||
- @Override
|
||||
- public Object handle(TestServer server, Object[] args) {
|
||||
- // Does not need to return anything. Exists solely to test CriteriaTest which has static init fields
|
||||
- return null;
|
||||
- }
|
||||
- }
|
||||
- );
|
||||
- methods = methodMap.build();
|
||||
-
|
||||
- TestServer server = new TestServer();
|
||||
- Server instance = Proxy.getProxyClass(Server.class.getClassLoader(), Server.class).asSubclass(Server.class).getConstructor(InvocationHandler.class).newInstance(server);
|
||||
- Bukkit.setServer(instance);
|
||||
- server.pluginManager = new SimplePluginManager(instance, new SimpleCommandMap(instance));
|
||||
- } catch (Throwable t) {
|
||||
- throw new Error(t);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- private Thread creatingThread = Thread.currentThread();
|
||||
- private PluginManager pluginManager;
|
||||
- private TestServer() {};
|
||||
-
|
||||
- public static Server getInstance() {
|
||||
- return Bukkit.getServer();
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public Object invoke(Object proxy, Method method, Object[] args) {
|
||||
- MethodHandler handler = methods.get(method);
|
||||
- if (handler != null) {
|
||||
- return handler.handle(this, args);
|
||||
- }
|
||||
- throw new UnsupportedOperationException(String.valueOf(method));
|
||||
- }
|
||||
-}
|
||||
diff --git a/src/test/java/org/bukkit/TestWorld.java b/src/test/java/org/bukkit/TestWorld.java
|
||||
index ab34f1199921d415fa2ca6e281a8125c9e6d7173..f64d024f5bbf9482aaddb56597b23b04c66f21bf 100644
|
||||
--- a/src/test/java/org/bukkit/TestWorld.java
|
||||
+++ b/src/test/java/org/bukkit/TestWorld.java
|
||||
@@ -18,7 +18,7 @@ public final class TestWorld implements InvocationHandler {
|
||||
|
||||
static {
|
||||
try {
|
||||
- TestServer.getInstance();
|
||||
+ io.papermc.paper.testing.TestServer.setup(); // Paper
|
||||
|
||||
ImmutableMap.Builder<Method, MethodHandler> methodMap = ImmutableMap.builder();
|
||||
methodMap.put(
|
||||
diff --git a/src/test/java/org/bukkit/event/SyntheticEventTest.java b/src/test/java/org/bukkit/event/SyntheticEventTest.java
|
||||
index d402cb59f508205ebe9ee450594826b04cecb90b..09886568ae6167141b463b6262565fa212af3385 100644
|
||||
--- a/src/test/java/org/bukkit/event/SyntheticEventTest.java
|
||||
+++ b/src/test/java/org/bukkit/event/SyntheticEventTest.java
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.bukkit.event;
|
||||
|
||||
-import org.bukkit.TestServer;
|
||||
import org.bukkit.plugin.PluginLoader;
|
||||
import org.bukkit.plugin.SimplePluginManager;
|
||||
import org.bukkit.plugin.TestPlugin;
|
||||
@@ -12,14 +11,15 @@ public class SyntheticEventTest {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void test() {
|
||||
- final JavaPluginLoader loader = new JavaPluginLoader(TestServer.getInstance());
|
||||
+ io.papermc.paper.testing.TestServer.setup(); // Paper
|
||||
+ final JavaPluginLoader loader = new JavaPluginLoader(org.bukkit.Bukkit.getServer()); // Paper
|
||||
TestPlugin plugin = new TestPlugin(getClass().getName()) {
|
||||
@Override
|
||||
public PluginLoader getPluginLoader() {
|
||||
return loader;
|
||||
}
|
||||
};
|
||||
- SimplePluginManager pluginManager = new SimplePluginManager(TestServer.getInstance(), null);
|
||||
+ SimplePluginManager pluginManager = new SimplePluginManager(org.bukkit.Bukkit.getServer(), null); // Paper
|
||||
|
||||
TestEvent event = new TestEvent(false);
|
||||
Impl impl = new Impl();
|
||||
diff --git a/src/test/java/org/bukkit/plugin/PluginManagerTest.java b/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
index f188cd4f3b07027c30d41f1162db77a506b7b6bb..c46ed2acb82db814d660459b705dd49e6d44240f 100644
|
||||
--- a/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
+++ b/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
@@ -2,7 +2,6 @@ package org.bukkit.plugin;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
-import org.bukkit.TestServer;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.TestEvent;
|
||||
import org.bukkit.permissions.Permission;
|
||||
@@ -14,7 +13,7 @@ public class PluginManagerTest {
|
||||
volatile Object value = null;
|
||||
}
|
||||
|
||||
- private static final PluginManager pm = TestServer.getInstance().getPluginManager();
|
||||
+ private static final PluginManager pm = org.bukkit.Bukkit.getServer().getPluginManager(); // Paper
|
||||
|
||||
private final MutableObject store = new MutableObject();
|
||||
|
||||
diff --git a/src/test/java/org/bukkit/scoreboard/CriteriaTest.java b/src/test/java/org/bukkit/scoreboard/CriteriaTest.java
|
||||
index eb94b6f4d58cd9f66b07791c57af7e359992e28c..a93f28e2f987a36e2c7e4f7d31506b750bdb222b 100644
|
||||
--- a/src/test/java/org/bukkit/scoreboard/CriteriaTest.java
|
||||
+++ b/src/test/java/org/bukkit/scoreboard/CriteriaTest.java
|
||||
@@ -2,7 +2,6 @@ package org.bukkit.scoreboard;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
-import org.bukkit.TestServer;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@@ -11,7 +10,7 @@ public class CriteriaTest {
|
||||
|
||||
@Test
|
||||
public void testStatistic() {
|
||||
- TestServer.getInstance();
|
||||
+ io.papermc.paper.testing.TestServer.setup(); // Paper
|
||||
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> Criteria.statistic(Statistic.AVIATE_ONE_CM, Material.STONE)); // Generic statistic with block
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> Criteria.statistic(Statistic.AVIATE_ONE_CM, EntityType.CREEPER)); // Generic statistic with entity type
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 1 Apr 2016 00:02:47 -0400
|
||||
Subject: [PATCH] Add FastUtil to Bukkit
|
||||
|
||||
Doesn't expose to plugins, just allows Paper-API to use it for optimization
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index b38a9f4d628fa639e5d2b7dcd5a63f0bf6b8330b..19720f73cb8454d6ddd8d75e7d08556d61436505 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -22,6 +22,7 @@ dependencies {
|
||||
api("com.googlecode.json-simple:json-simple:1.1.1") {
|
||||
isTransitive = false // includes junit
|
||||
}
|
||||
+ api("it.unimi.dsi:fastutil:8.5.6")
|
||||
// Paper end
|
||||
|
||||
compileOnly("org.apache.maven:maven-resolver-provider:3.8.5")
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 23 Feb 2019 11:26:21 -0500
|
||||
Subject: [PATCH] Paper Utils
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/util/SneakyThrow.java b/src/main/java/com/destroystokyo/paper/util/SneakyThrow.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9db0056ab94145819628b3ad8d8d26130d117fcf
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/util/SneakyThrow.java
|
||||
@@ -0,0 +1,16 @@
|
||||
+package com.destroystokyo.paper.util;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class SneakyThrow {
|
||||
+
|
||||
+ public static void sneaky(@NotNull Throwable exception) {
|
||||
+ SneakyThrow.<RuntimeException>throwSneaky(exception);
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ private static <T extends Throwable> void throwSneaky(@NotNull Throwable exception) throws T {
|
||||
+ throw (T) exception;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -1,370 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Thu, 3 Mar 2016 13:20:33 -0700
|
||||
Subject: [PATCH] Use ASM for event executors.
|
||||
|
||||
Uses method handles for private or static methods.
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index cbab63d2f3b045f6193f5a3422ae4b5509d3003b..ba6f0a70ba2442dbe60ed6cc92e4fb91a48d9f3b 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -42,6 +42,9 @@ dependencies {
|
||||
apiAndDocs("net.kyori:adventure-text-serializer-legacy")
|
||||
apiAndDocs("net.kyori:adventure-text-serializer-plain")
|
||||
apiAndDocs("net.kyori:adventure-text-logger-slf4j")
|
||||
+
|
||||
+ implementation("org.ow2.asm:asm:9.4")
|
||||
+ implementation("org.ow2.asm:asm-commons:9.4")
|
||||
// Paper end
|
||||
|
||||
compileOnly("org.apache.maven:maven-resolver-provider:3.8.5")
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5b28e9b1daba7834af67dbc193dd656bedd9a994
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
|
||||
@@ -0,0 +1,42 @@
|
||||
+package com.destroystokyo.paper.event.executor;
|
||||
+
|
||||
+import java.lang.invoke.MethodHandle;
|
||||
+import java.lang.invoke.MethodHandles;
|
||||
+import java.lang.reflect.Method;
|
||||
+
|
||||
+import com.destroystokyo.paper.util.SneakyThrow;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.EventException;
|
||||
+import org.bukkit.event.Listener;
|
||||
+import org.bukkit.plugin.EventExecutor;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class MethodHandleEventExecutor implements EventExecutor {
|
||||
+ private final Class<? extends Event> eventClass;
|
||||
+ private final MethodHandle handle;
|
||||
+
|
||||
+ public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull MethodHandle handle) {
|
||||
+ this.eventClass = eventClass;
|
||||
+ this.handle = handle;
|
||||
+ }
|
||||
+
|
||||
+ public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
|
||||
+ this.eventClass = eventClass;
|
||||
+ try {
|
||||
+ m.setAccessible(true);
|
||||
+ this.handle = MethodHandles.lookup().unreflect(m);
|
||||
+ } catch (IllegalAccessException e) {
|
||||
+ throw new AssertionError("Unable to set accessible", e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
|
||||
+ if (!eventClass.isInstance(event)) return;
|
||||
+ try {
|
||||
+ handle.invoke(listener, event);
|
||||
+ } catch (Throwable t) {
|
||||
+ SneakyThrow.sneaky(t);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c83672427324bd068ed52916f700b68446a226f6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
|
||||
@@ -0,0 +1,43 @@
|
||||
+package com.destroystokyo.paper.event.executor;
|
||||
+
|
||||
+import java.lang.invoke.MethodHandle;
|
||||
+import java.lang.invoke.MethodHandles;
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+
|
||||
+import com.destroystokyo.paper.util.SneakyThrow;
|
||||
+import com.google.common.base.Preconditions;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.EventException;
|
||||
+import org.bukkit.event.Listener;
|
||||
+import org.bukkit.plugin.EventExecutor;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class StaticMethodHandleEventExecutor implements EventExecutor {
|
||||
+ private final Class<? extends Event> eventClass;
|
||||
+ private final MethodHandle handle;
|
||||
+
|
||||
+ public StaticMethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
|
||||
+ Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
|
||||
+ Preconditions.checkArgument(eventClass != null, "eventClass is null");
|
||||
+ this.eventClass = eventClass;
|
||||
+ try {
|
||||
+ m.setAccessible(true);
|
||||
+ this.handle = MethodHandles.lookup().unreflect(m);
|
||||
+ } catch (IllegalAccessException e) {
|
||||
+ throw new AssertionError("Unable to set accessible", e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
|
||||
+ if (!eventClass.isInstance(event)) return;
|
||||
+ try {
|
||||
+ handle.invoke(event);
|
||||
+ } catch (Throwable throwable) {
|
||||
+ SneakyThrow.sneaky(throwable);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..084c31af1a7ba32bb4c3dc8f16f67fd09ce0b6a4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java
|
||||
@@ -0,0 +1,54 @@
|
||||
+package com.destroystokyo.paper.event.executor.asm;
|
||||
+
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+
|
||||
+import org.bukkit.plugin.EventExecutor;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.objectweb.asm.ClassWriter;
|
||||
+import org.objectweb.asm.Type;
|
||||
+import org.objectweb.asm.commons.GeneratorAdapter;
|
||||
+
|
||||
+import static org.objectweb.asm.Opcodes.*;
|
||||
+
|
||||
+public class ASMEventExecutorGenerator {
|
||||
+
|
||||
+ private static final String EXECUTE_DESCRIPTOR = "(Lorg/bukkit/event/Listener;Lorg/bukkit/event/Event;)V";
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static byte[] generateEventExecutor(@NotNull Method m, @NotNull String name) {
|
||||
+ ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
+ writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[] {Type.getInternalName(EventExecutor.class)});
|
||||
+ // Generate constructor
|
||||
+ GeneratorAdapter methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null), ACC_PUBLIC, "<init>", "()V");
|
||||
+ methodGenerator.loadThis();
|
||||
+ methodGenerator.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V", false); // Invoke the super class (Object) constructor
|
||||
+ methodGenerator.returnValue();
|
||||
+ methodGenerator.endMethod();
|
||||
+ // Generate the execute method
|
||||
+ methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "execute", EXECUTE_DESCRIPTOR, null, null), ACC_PUBLIC, "execute", EXECUTE_DESCRIPTOR);
|
||||
+ methodGenerator.loadArg(0);
|
||||
+ methodGenerator.checkCast(Type.getType(m.getDeclaringClass()));
|
||||
+ methodGenerator.loadArg(1);
|
||||
+ methodGenerator.checkCast(Type.getType(m.getParameterTypes()[0]));
|
||||
+ methodGenerator.visitMethodInsn(m.getDeclaringClass().isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, Type.getInternalName(m.getDeclaringClass()), m.getName(), Type.getMethodDescriptor(m), m.getDeclaringClass().isInterface());
|
||||
+ // The only purpose of this switch statement is to generate the correct pop instruction, should the event handler method return something other than void.
|
||||
+ // Non-void event handlers will be unsupported in a future release.
|
||||
+ switch (Type.getType(m.getReturnType()).getSize()) {
|
||||
+ // case 0 is omitted because the only type that has size 0 is void - no pop instruction needed.
|
||||
+ case 1 -> methodGenerator.pop(); // handles reference types and most primitives
|
||||
+ case 2 -> methodGenerator.pop2(); // handles long and double
|
||||
+ }
|
||||
+ methodGenerator.returnValue();
|
||||
+ methodGenerator.endMethod();
|
||||
+ writer.visitEnd();
|
||||
+ return writer.toByteArray();
|
||||
+ }
|
||||
+
|
||||
+ public static AtomicInteger NEXT_ID = new AtomicInteger(1);
|
||||
+ @NotNull
|
||||
+ public static String generateName() {
|
||||
+ int id = NEXT_ID.getAndIncrement();
|
||||
+ return "com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor" + id;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f79685b48bb581277a6891927988b6f7a4389dc4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package com.destroystokyo.paper.event.executor.asm;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface ClassDefiner {
|
||||
+
|
||||
+ /**
|
||||
+ * Returns if the defined classes can bypass access checks
|
||||
+ *
|
||||
+ * @return if classes bypass access checks
|
||||
+ */
|
||||
+ public default boolean isBypassAccessChecks() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Define a class
|
||||
+ *
|
||||
+ * @param parentLoader the parent classloader
|
||||
+ * @param name the name of the class
|
||||
+ * @param data the class data to load
|
||||
+ * @return the defined class
|
||||
+ * @throws ClassFormatError if the class data is invalid
|
||||
+ * @throws NullPointerException if any of the arguments are null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data);
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static ClassDefiner getInstance() {
|
||||
+ return SafeClassDefiner.INSTANCE;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ac99477e9f2c08041aeff31abc1d1edee58d0a67
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
|
||||
@@ -0,0 +1,66 @@
|
||||
+package com.destroystokyo.paper.event.executor.asm;
|
||||
+
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
+import java.util.concurrent.ConcurrentMap;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+
|
||||
+import com.google.common.collect.MapMaker;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.objectweb.asm.Type;
|
||||
+
|
||||
+public class SafeClassDefiner implements ClassDefiner {
|
||||
+ /* default */ static final SafeClassDefiner INSTANCE = new SafeClassDefiner();
|
||||
+
|
||||
+ private SafeClassDefiner() {}
|
||||
+
|
||||
+ private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new MapMaker().weakKeys().makeMap();
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data) {
|
||||
+ GeneratedClassLoader loader = loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
|
||||
+ synchronized (loader.getClassLoadingLock(name)) {
|
||||
+ Preconditions.checkState(!loader.hasClass(name), "%s already defined", name);
|
||||
+ Class<?> c = loader.define(name, data);
|
||||
+ assert c.getName().equals(name);
|
||||
+ return c;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static class GeneratedClassLoader extends ClassLoader {
|
||||
+ static {
|
||||
+ ClassLoader.registerAsParallelCapable();
|
||||
+ }
|
||||
+
|
||||
+ protected GeneratedClassLoader(@NotNull ClassLoader parent) {
|
||||
+ super(parent);
|
||||
+ }
|
||||
+
|
||||
+ private Class<?> define(@NotNull String name, byte[] data) {
|
||||
+ synchronized (getClassLoadingLock(name)) {
|
||||
+ assert !hasClass(name);
|
||||
+ Class<?> c = defineClass(name, data, 0, data.length);
|
||||
+ resolveClass(c);
|
||||
+ return c;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public Object getClassLoadingLock(@NotNull String name) {
|
||||
+ return super.getClassLoadingLock(name);
|
||||
+ }
|
||||
+
|
||||
+ public boolean hasClass(@NotNull String name) {
|
||||
+ synchronized (getClassLoadingLock(name)) {
|
||||
+ try {
|
||||
+ Class.forName(name);
|
||||
+ return true;
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/EventExecutor.java b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
index a850f0780de05463fc0d3f9e15ff7f19d88b2aed..9026e108ccd3a88aee1267ee275137befa646455 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
@@ -5,9 +5,75 @@ import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+// Paper start
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
+import java.util.concurrent.ConcurrentMap;
|
||||
+import java.util.function.Function;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.executor.MethodHandleEventExecutor;
|
||||
+import com.destroystokyo.paper.event.executor.StaticMethodHandleEventExecutor;
|
||||
+import com.destroystokyo.paper.event.executor.asm.ASMEventExecutorGenerator;
|
||||
+import com.destroystokyo.paper.event.executor.asm.ClassDefiner;
|
||||
+import com.google.common.base.Preconditions;
|
||||
+// Paper end
|
||||
+
|
||||
/**
|
||||
* Interface which defines the class for event call backs to plugins
|
||||
*/
|
||||
public interface EventExecutor {
|
||||
public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException;
|
||||
+
|
||||
+ // Paper start
|
||||
+ ConcurrentMap<Method, Class<? extends EventExecutor>> eventExecutorMap = new ConcurrentHashMap<Method, Class<? extends EventExecutor>>() {
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Class<? extends EventExecutor> computeIfAbsent(@NotNull Method key, @NotNull Function<? super Method, ? extends Class<? extends EventExecutor>> mappingFunction) {
|
||||
+ Class<? extends EventExecutor> executorClass = get(key);
|
||||
+ if (executorClass != null)
|
||||
+ return executorClass;
|
||||
+
|
||||
+ //noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
+ synchronized (key) {
|
||||
+ executorClass = get(key);
|
||||
+ if (executorClass != null)
|
||||
+ return executorClass;
|
||||
+
|
||||
+ return super.computeIfAbsent(key, mappingFunction);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static EventExecutor create(@NotNull Method m, @NotNull Class<? extends Event> eventClass) {
|
||||
+ Preconditions.checkNotNull(m, "Null method");
|
||||
+ Preconditions.checkArgument(m.getParameterCount() != 0, "Incorrect number of arguments %s", m.getParameterCount());
|
||||
+ Preconditions.checkArgument(m.getParameterTypes()[0] == eventClass, "First parameter %s doesn't match event class %s", m.getParameterTypes()[0], eventClass);
|
||||
+ ClassDefiner definer = ClassDefiner.getInstance();
|
||||
+ if (Modifier.isStatic(m.getModifiers())) {
|
||||
+ return new StaticMethodHandleEventExecutor(eventClass, m);
|
||||
+ } else if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
|
||||
+ // get the existing generated EventExecutor class for the Method or generate one
|
||||
+ Class<? extends EventExecutor> executorClass = eventExecutorMap.computeIfAbsent(m, (__) -> {
|
||||
+ String name = ASMEventExecutorGenerator.generateName();
|
||||
+ byte[] classData = ASMEventExecutorGenerator.generateEventExecutor(m, name);
|
||||
+ return definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);
|
||||
+ });
|
||||
+
|
||||
+ try {
|
||||
+ EventExecutor asmExecutor = executorClass.newInstance();
|
||||
+ // Define a wrapper to conform to bukkit stupidity (passing in events that don't match and wrapper exception)
|
||||
+ return (listener, event) -> {
|
||||
+ if (!eventClass.isInstance(event)) return;
|
||||
+ asmExecutor.execute(listener, event);
|
||||
+ };
|
||||
+ } catch (InstantiationException | IllegalAccessException e) {
|
||||
+ throw new AssertionError("Unable to initialize generated event executor", e);
|
||||
+ }
|
||||
+ } else {
|
||||
+ return new MethodHandleEventExecutor(eventClass, m);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,422 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 20 Mar 2022 10:42:28 -0700
|
||||
Subject: [PATCH] Add Position
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/math/BlockPosition.java b/src/main/java/io/papermc/paper/math/BlockPosition.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f0fdabce4af640da2a406412e67020761ded3ac1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/math/BlockPosition.java
|
||||
@@ -0,0 +1,98 @@
|
||||
+package io.papermc.paper.math;
|
||||
+
|
||||
+import org.bukkit.Axis;
|
||||
+import org.bukkit.block.BlockFace;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A position represented with integers.
|
||||
+ * <p>
|
||||
+ * <b>May see breaking changes until Experimental annotation is removed.</b>
|
||||
+ * @see FinePosition
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+public interface BlockPosition extends Position {
|
||||
+
|
||||
+ @Override
|
||||
+ default double x() {
|
||||
+ return this.blockX();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default double y() {
|
||||
+ return this.blockY();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default double z() {
|
||||
+ return this.blockZ();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean isBlock() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean isFine() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default @NotNull BlockPosition toBlock() {
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default @NotNull BlockPosition offset(int x, int y, int z) {
|
||||
+ return x == 0 && y == 0 && z == 0 ? this : new BlockPositionImpl(this.blockX() + x, this.blockY() + y, this.blockZ() + z);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default @NotNull FinePosition offset(double x, double y, double z) {
|
||||
+ return new FinePositionImpl(this.blockX() + x, this.blockY() + y, this.blockZ() + z);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a block position offset by 1 in the direction specified.
|
||||
+ *
|
||||
+ * @param blockFace the block face to offset towards
|
||||
+ * @return the offset block position
|
||||
+ */
|
||||
+ @Contract(value = "_ -> new", pure = true)
|
||||
+ default @NotNull BlockPosition offset(@NotNull BlockFace blockFace) {
|
||||
+ return this.offset(blockFace, 1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a block position offset in the direction specified
|
||||
+ * multiplied by the amount.
|
||||
+ *
|
||||
+ * @param blockFace the block face to offset towards
|
||||
+ * @param amount the number of times to move in that direction
|
||||
+ * @return the offset block position
|
||||
+ */
|
||||
+ @Contract(pure = true)
|
||||
+ default @NotNull BlockPosition offset(@NotNull BlockFace blockFace, int amount) {
|
||||
+ return amount == 0 ? this : new BlockPositionImpl(this.blockX() + (blockFace.getModX() * amount), this.blockY() + (blockFace.getModY() * amount), this.blockZ() + (blockFace.getModZ() * amount));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a block position offset by the amount along
|
||||
+ * the specified axis.
|
||||
+ *
|
||||
+ * @param axis the axis to offset along
|
||||
+ * @param amount the amount to offset along that axis
|
||||
+ * @return the offset block position
|
||||
+ */
|
||||
+ @Contract(pure = true)
|
||||
+ default @NotNull BlockPosition offset(@NotNull Axis axis, int amount) {
|
||||
+ return amount == 0 ? this : switch (axis) {
|
||||
+ case X -> new BlockPositionImpl(this.blockX() + amount, this.blockY(), this.blockZ());
|
||||
+ case Y -> new BlockPositionImpl(this.blockX(), this.blockY() + amount, this.blockZ());
|
||||
+ case Z -> new BlockPositionImpl(this.blockX(), this.blockY(), this.blockZ() + amount);
|
||||
+ };
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/math/BlockPositionImpl.java b/src/main/java/io/papermc/paper/math/BlockPositionImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..eb5a3f26c7ba56c6715827f52c0013a860ec7d9a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/math/BlockPositionImpl.java
|
||||
@@ -0,0 +1,4 @@
|
||||
+package io.papermc.paper.math;
|
||||
+
|
||||
+record BlockPositionImpl(int blockX, int blockY, int blockZ) implements BlockPosition {
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/math/FinePosition.java b/src/main/java/io/papermc/paper/math/FinePosition.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d8df70d731573cf2446044925f218876d62fd7cf
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/math/FinePosition.java
|
||||
@@ -0,0 +1,56 @@
|
||||
+package io.papermc.paper.math;
|
||||
+
|
||||
+import org.bukkit.util.NumberConversions;
|
||||
+import org.bukkit.util.Vector;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A position represented with doubles.
|
||||
+ * <p>
|
||||
+ * <b>May see breaking changes until Experimental annotation is removed.</b>
|
||||
+ * @see BlockPosition
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+public interface FinePosition extends Position {
|
||||
+
|
||||
+ @Override
|
||||
+ default int blockX() {
|
||||
+ return NumberConversions.floor(this.x());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default int blockY() {
|
||||
+ return NumberConversions.floor(this.y());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default int blockZ() {
|
||||
+ return NumberConversions.floor(this.z());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean isBlock() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean isFine() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default @NotNull BlockPosition toBlock() {
|
||||
+ return new BlockPositionImpl(this.blockX(), this.blockY(), this.blockZ());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default @NotNull FinePosition offset(int x, int y, int z) {
|
||||
+ return this.offset((double) x, y, z);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default @NotNull FinePosition offset(double x, double y, double z) {
|
||||
+ return x == 0.0 && y == 0.0 && z == 0.0 ? this : new FinePositionImpl(this.x() + x, this.y() + y, this.z() + z);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/math/FinePositionImpl.java b/src/main/java/io/papermc/paper/math/FinePositionImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..93476aaf8d21efb5a30b6d2cc2eeda8100fb72d0
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/math/FinePositionImpl.java
|
||||
@@ -0,0 +1,4 @@
|
||||
+package io.papermc.paper.math;
|
||||
+
|
||||
+record FinePositionImpl(double x, double y, double z) implements FinePosition {
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/math/Position.java b/src/main/java/io/papermc/paper/math/Position.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..300da713dcc303b340efad70efe57facf5422964
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/math/Position.java
|
||||
@@ -0,0 +1,184 @@
|
||||
+package io.papermc.paper.math;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.World;
|
||||
+import org.bukkit.util.Vector;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Common interface for {@link FinePosition} and {@link BlockPosition}.
|
||||
+ * <p>
|
||||
+ * <b>May see breaking changes until Experimental annotation is removed.</b>
|
||||
+ */
|
||||
+@ApiStatus.Experimental
|
||||
+public interface Position {
|
||||
+
|
||||
+ FinePosition FINE_ZERO = new FinePositionImpl(0, 0, 0);
|
||||
+ BlockPosition BLOCK_ZERO = new BlockPositionImpl(0, 0, 0);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the block x value for this position
|
||||
+ *
|
||||
+ * @return the block x value
|
||||
+ */
|
||||
+ int blockX();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the block x value for this position
|
||||
+ *
|
||||
+ * @return the block x value
|
||||
+ */
|
||||
+ int blockY();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the block x value for this position
|
||||
+ *
|
||||
+ * @return the block x value
|
||||
+ */
|
||||
+ int blockZ();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the x value for this position
|
||||
+ *
|
||||
+ * @return the x value
|
||||
+ */
|
||||
+ double x();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the y value for this position
|
||||
+ *
|
||||
+ * @return the y value
|
||||
+ */
|
||||
+ double y();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the z value for this position
|
||||
+ *
|
||||
+ * @return the z value
|
||||
+ */
|
||||
+ double z();
|
||||
+
|
||||
+ /**
|
||||
+ * Checks of this position represents a {@link BlockPosition}
|
||||
+ *
|
||||
+ * @return true if block
|
||||
+ */
|
||||
+ boolean isBlock();
|
||||
+
|
||||
+ /**
|
||||
+ * Checks if this position represents a {@link FinePosition}
|
||||
+ *
|
||||
+ * @return true if fine
|
||||
+ */
|
||||
+ boolean isFine();
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a position offset by the specified amounts.
|
||||
+ *
|
||||
+ * @param x x value to offset
|
||||
+ * @param y y value to offset
|
||||
+ * @param z z value to offset
|
||||
+ * @return the offset position
|
||||
+ */
|
||||
+ @NotNull Position offset(int x, int y, int z);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a position offset by the specified amounts.
|
||||
+ *
|
||||
+ * @param x x value to offset
|
||||
+ * @param y y value to offset
|
||||
+ * @param z z value to offset
|
||||
+ * @return the offset position
|
||||
+ */
|
||||
+ @NotNull FinePosition offset(double x, double y, double z);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a new position at the center of the block position this represents
|
||||
+ *
|
||||
+ * @return a new center position
|
||||
+ */
|
||||
+ @Contract(value = "-> new", pure = true)
|
||||
+ default @NotNull FinePosition toCenter() {
|
||||
+ return new FinePositionImpl(this.blockX() + 0.5, this.blockY() + 0.5, this.blockZ() + 0.5);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the block position of this position
|
||||
+ * or itself if it already is a block position
|
||||
+ *
|
||||
+ * @return the block position
|
||||
+ */
|
||||
+ @Contract(pure = true)
|
||||
+ @NotNull BlockPosition toBlock();
|
||||
+
|
||||
+ /**
|
||||
+ * Converts this position to a vector
|
||||
+ *
|
||||
+ * @return a new vector
|
||||
+ */
|
||||
+ @Contract(value = "-> new", pure = true)
|
||||
+ default @NotNull Vector toVector() {
|
||||
+ return new Vector(this.x(), this.y(), this.z());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new location object at this position with the specified world
|
||||
+ *
|
||||
+ * @param world the world for the location object
|
||||
+ * @return a new location
|
||||
+ */
|
||||
+ @Contract(value = "_ -> new", pure = true)
|
||||
+ default @NotNull Location toLocation(@NotNull World world) {
|
||||
+ return new Location(world, this.x(), this.y(), this.z());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a position at the coordinates
|
||||
+ *
|
||||
+ * @param x x coord
|
||||
+ * @param y y coord
|
||||
+ * @param z z coord
|
||||
+ * @return a position with those coords
|
||||
+ */
|
||||
+ @Contract(value = "_, _, _ -> new", pure = true)
|
||||
+ static @NotNull BlockPosition block(int x, int y, int z) {
|
||||
+ return new BlockPositionImpl(x, y, z);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a position from the location.
|
||||
+ *
|
||||
+ * @param location the location to copy the position of
|
||||
+ * @return a new position at that location
|
||||
+ */
|
||||
+ @Contract(value = "_ -> new", pure = true)
|
||||
+ static @NotNull BlockPosition block(@NotNull Location location) {
|
||||
+ return new BlockPositionImpl(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a position at the coordinates
|
||||
+ *
|
||||
+ * @param x x coord
|
||||
+ * @param y y coord
|
||||
+ * @param z z coord
|
||||
+ * @return a position with those coords
|
||||
+ */
|
||||
+ @Contract(value = "_, _, _ -> new", pure = true)
|
||||
+ static @NotNull FinePosition fine(double x, double y, double z) {
|
||||
+ return new FinePositionImpl(x, y, z);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a position from the location.
|
||||
+ *
|
||||
+ * @param location the location to copy the position of
|
||||
+ * @return a new position at that location
|
||||
+ */
|
||||
+ @Contract(value = "_ -> new", pure = true)
|
||||
+ static @NotNull FinePosition fine(@NotNull Location location) {
|
||||
+ return new FinePositionImpl(location.getX(), location.getY(), location.getZ());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index 7c4db051472fb6a6c6d24092dc6f75487356690a..3b99f359f556e6f2c341d55fa69b7462e69b6546 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* magnitude than 360 are valid, but may be normalized to any other equivalent
|
||||
* representation by the implementation.
|
||||
*/
|
||||
-public class Location implements Cloneable, ConfigurationSerializable {
|
||||
+public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition { // Paper
|
||||
private Reference<World> world;
|
||||
private double x;
|
||||
private double y;
|
||||
@@ -706,4 +706,26 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
}
|
||||
return pitch;
|
||||
}
|
||||
+
|
||||
+ // Paper - add Position
|
||||
+ @Override
|
||||
+ public double x() {
|
||||
+ return this.getX();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double y() {
|
||||
+ return this.getY();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double z() {
|
||||
+ return this.getZ();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Location toLocation(@NotNull World world) {
|
||||
+ return new Location(world, this.x(), this.y(), this.z(), this.getYaw(), this.getPitch());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,96 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Tue, 18 May 2021 14:42:26 -0700
|
||||
Subject: [PATCH] Add command line option to load extra plugin jars not in the
|
||||
plugins folder
|
||||
|
||||
ex: java -jar paperclip.jar nogui -add-plugin=/path/to/plugin.jar -add-plugin=/path/to/another/plugin_jar.jar
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 45f9ac35874c67c24718f6891b95df1ff4f0b93f..7717f5346aa784df4a0f6e43a5a74a66f279bc8a 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -78,6 +78,20 @@ public final class Bukkit {
|
||||
return server;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Returns the de facto plugins directory, generally used for storing plugin jars to be loaded,
|
||||
+ * as well as their {@link org.bukkit.plugin.Plugin#getDataFolder() data folders}.
|
||||
+ *
|
||||
+ * <p>Plugins should use {@link org.bukkit.plugin.Plugin#getDataFolder()} rather than traversing this
|
||||
+ * directory manually when determining the location in which to store their data and configuration files.</p>
|
||||
+ *
|
||||
+ * @return plugins directory
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static File getPluginsFolder() {
|
||||
+ return server.getPluginsFolder();
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Attempts to set the {@link Server} singleton.
|
||||
* <p>
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 087da3cd2cafd8255ed70e5e632b270a33e37eaf..0f990d33ab07249e4cf2d2269920b4cbeed27d39 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -63,6 +63,18 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface Server extends PluginMessageRecipient, net.kyori.adventure.audience.ForwardingAudience { // Paper
|
||||
|
||||
+ /**
|
||||
+ * Returns the de facto plugins directory, generally used for storing plugin jars to be loaded,
|
||||
+ * as well as their {@link org.bukkit.plugin.Plugin#getDataFolder() data folders}.
|
||||
+ *
|
||||
+ * <p>Plugins should use {@link org.bukkit.plugin.Plugin#getDataFolder()} rather than traversing this
|
||||
+ * directory manually when determining the location in which to store their data and configuration files.</p>
|
||||
+ *
|
||||
+ * @return plugins directory
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ File getPluginsFolder();
|
||||
+
|
||||
/**
|
||||
* Used for all administrative messages, such as an operator using a
|
||||
* command.
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index 63389474a2b3f0e283b42e7004aa6a94904a3d17..974ff7116b294473ec450757e8a9341540f43dcd 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -116,9 +116,22 @@ public final class SimplePluginManager implements PluginManager {
|
||||
@Override
|
||||
@NotNull
|
||||
public Plugin[] loadPlugins(@NotNull File directory) {
|
||||
+ // Paper start - extra jars
|
||||
+ return this.loadPlugins(directory, java.util.Collections.emptyList());
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public Plugin[] loadPlugins(final @NotNull File directory, final @NotNull List<File> extraPluginJars) {
|
||||
+ // Paper end
|
||||
if (true) {
|
||||
List<Plugin> pluginList = new ArrayList<>();
|
||||
java.util.Collections.addAll(pluginList, this.paperPluginManager.loadPlugins(directory));
|
||||
+ for (File file : extraPluginJars) {
|
||||
+ try {
|
||||
+ pluginList.add(this.paperPluginManager.loadPlugin(file));
|
||||
+ } catch (Exception e) {
|
||||
+ this.server.getLogger().log(Level.SEVERE, "Plugin loading error!", e);
|
||||
+ }
|
||||
+ }
|
||||
return pluginList.toArray(new Plugin[0]);
|
||||
}
|
||||
Preconditions.checkArgument(directory != null, "Directory cannot be null");
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
index de6b6188587fd254ab96cbc1f95fda2056d9cbe2..eaefbb00e9993d54906cc8cf35cf753c0d6c7707 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -93,7 +93,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
throw new InvalidPluginException(ex);
|
||||
}
|
||||
|
||||
- final File parentFile = file.getParentFile();
|
||||
+ final File parentFile = this.server.getPluginsFolder(); // Paper
|
||||
final File dataFolder = new File(parentFile, description.getName());
|
||||
@SuppressWarnings("deprecation")
|
||||
final File oldDataFolder = new File(parentFile, description.getRawName());
|
||||
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Mon, 29 Feb 2016 17:22:34 -0600
|
||||
Subject: [PATCH] Player affects spawning API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 1a54682f584479a5a548f6f1f2ffd5da5dc11c88..6b1a198f930a5a995e0cb6c279b455e1639a5039 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -2196,6 +2196,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
@Deprecated // Paper
|
||||
public String getLocale();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Get whether the player can affect mob spawning
|
||||
+ *
|
||||
+ * @return if the player can affect mob spawning
|
||||
+ */
|
||||
+ public boolean getAffectsSpawning();
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether the player can affect mob spawning
|
||||
+ *
|
||||
+ * @param affects Whether the player can affect mob spawning
|
||||
+ */
|
||||
+ public void setAffectsSpawning(boolean affects);
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Update the list of commands sent to the client.
|
||||
* <br>
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Feb 2016 17:24:57 -0600
|
||||
Subject: [PATCH] Add getTPS method
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 7717f5346aa784df4a0f6e43a5a74a66f279bc8a..fba3e617a8847a3e9282e6a1a389132b2ad5511c 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1964,6 +1964,17 @@ public final class Bukkit {
|
||||
return server.getEntity(uuid);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the current server TPS
|
||||
+ * @return current server TPS (1m, 5m, 15m in Paper-Server)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static double[] getTPS() {
|
||||
+ return server.getTPS();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get the advancement specified by this key.
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 0f990d33ab07249e4cf2d2269920b4cbeed27d39..c8cf66e64a3163c2bdf781f3ce52059546969b9b 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1672,6 +1672,16 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@Nullable
|
||||
Entity getEntity(@NotNull UUID uuid);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the current server TPS
|
||||
+ *
|
||||
+ * @return current server TPS (1m, 5m, 15m in Paper-Server)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public double[] getTPS();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get the advancement specified by this key.
|
||||
*
|
||||
@@ -1,200 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach@zachbr.io>
|
||||
Date: Mon, 27 May 2019 01:10:06 -0500
|
||||
Subject: [PATCH] Version Command 2.0
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a736d7bcdc5861a01b66ba36158db1c716339346
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
|
||||
@@ -0,0 +1,45 @@
|
||||
+package com.destroystokyo.paper.util;
|
||||
+
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.NamedTextColor;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface VersionFetcher {
|
||||
+ /**
|
||||
+ * Amount of time to cache results for in milliseconds
|
||||
+ * <p>
|
||||
+ * Negative values will never cache.
|
||||
+ *
|
||||
+ * @return cache time
|
||||
+ */
|
||||
+ long getCacheTime();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the version message to cache and show to command senders.
|
||||
+ *
|
||||
+ * <p>NOTE: This is run in a new thread separate from that of the command processing thread</p>
|
||||
+ *
|
||||
+ * @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()})
|
||||
+ * @return the message to show when requesting a version
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ Component getVersionMessage(@NotNull String serverVersion);
|
||||
+
|
||||
+ class DummyVersionFetcher implements VersionFetcher {
|
||||
+
|
||||
+ @Override
|
||||
+ public long getCacheTime() {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Component getVersionMessage(@NotNull String serverVersion) {
|
||||
+ Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!");
|
||||
+ Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()");
|
||||
+ new Throwable().printStackTrace();
|
||||
+ return Component.text("Unable to check for updates. No version provider set.", NamedTextColor.RED);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
index f68ef89f37057cf677a767026ab395f7a839a2f9..a6aa33b9574d0278e10927007a62290e1d102e73 100644
|
||||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
+++ b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@@ -119,5 +119,12 @@ public interface UnsafeValues {
|
||||
* @return name
|
||||
*/
|
||||
String getTimingsServerName();
|
||||
+
|
||||
+ /**
|
||||
+ * Called once by the version command on first use, then cached.
|
||||
+ */
|
||||
+ default com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
|
||||
+ return new com.destroystokyo.paper.util.VersionFetcher.DummyVersionFetcher();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
|
||||
index 04b4fb6859df0221f8f9f92c5a7ac2dda1073355..b437cf212a63aa96a9492db8d01d5d37061aee23 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
|
||||
@@ -24,8 +24,25 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.util.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
+// Paper start - version command 2.0
|
||||
+import com.destroystokyo.paper.util.VersionFetcher;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.NamedTextColor;
|
||||
+import net.kyori.adventure.text.event.ClickEvent;
|
||||
+import net.kyori.adventure.text.format.TextDecoration;
|
||||
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
+// Paper end - version command 2.0
|
||||
|
||||
public class VersionCommand extends BukkitCommand {
|
||||
+ private VersionFetcher versionFetcher; // Paper - version command 2.0
|
||||
+ private VersionFetcher getVersionFetcher() { // lazy load because unsafe isn't available at command registration
|
||||
+ if (versionFetcher == null) {
|
||||
+ versionFetcher = Bukkit.getUnsafe().getVersionFetcher();
|
||||
+ }
|
||||
+
|
||||
+ return versionFetcher;
|
||||
+ }
|
||||
+
|
||||
public VersionCommand(@NotNull String name) {
|
||||
super(name);
|
||||
|
||||
@@ -40,7 +57,7 @@ public class VersionCommand extends BukkitCommand {
|
||||
if (!testPermission(sender)) return true;
|
||||
|
||||
if (args.length == 0) {
|
||||
- sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")");
|
||||
+ //sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")"); // Paper - moved to setVersionMessage
|
||||
sendVersion(sender);
|
||||
} else {
|
||||
StringBuilder name = new StringBuilder();
|
||||
@@ -79,8 +96,17 @@ public class VersionCommand extends BukkitCommand {
|
||||
|
||||
private void describeToSender(@NotNull Plugin plugin, @NotNull CommandSender sender) {
|
||||
PluginDescriptionFile desc = plugin.getDescription();
|
||||
- sender.sendMessage(ChatColor.GREEN + desc.getName() + ChatColor.WHITE + " version " + ChatColor.GREEN + desc.getVersion());
|
||||
-
|
||||
+ // Paper start - version command 2.0
|
||||
+ sender.sendMessage(
|
||||
+ Component.text()
|
||||
+ .append(Component.text(desc.getName(), NamedTextColor.GREEN))
|
||||
+ .append(Component.text(" version "))
|
||||
+ .append(Component.text(desc.getVersion(), NamedTextColor.GREEN)
|
||||
+ .hoverEvent(Component.text("Click to copy to clipboard", NamedTextColor.WHITE))
|
||||
+ .clickEvent(ClickEvent.copyToClipboard(desc.getVersion()))
|
||||
+ )
|
||||
+ );
|
||||
+ // Paper end - version command 2.0
|
||||
if (desc.getDescription() != null) {
|
||||
sender.sendMessage(desc.getDescription());
|
||||
}
|
||||
@@ -146,14 +172,14 @@ public class VersionCommand extends BukkitCommand {
|
||||
|
||||
private final ReentrantLock versionLock = new ReentrantLock();
|
||||
private boolean hasVersion = false;
|
||||
- private String versionMessage = null;
|
||||
+ private Component versionMessage = null; // Paper
|
||||
private final Set<CommandSender> versionWaiters = new HashSet<CommandSender>();
|
||||
private boolean versionTaskStarted = false;
|
||||
private long lastCheck = 0;
|
||||
|
||||
private void sendVersion(@NotNull CommandSender sender) {
|
||||
if (hasVersion) {
|
||||
- if (System.currentTimeMillis() - lastCheck > 21600000) {
|
||||
+ if (System.currentTimeMillis() - lastCheck > getVersionFetcher().getCacheTime()) { // Paper - use version supplier
|
||||
lastCheck = System.currentTimeMillis();
|
||||
hasVersion = false;
|
||||
} else {
|
||||
@@ -168,7 +194,7 @@ public class VersionCommand extends BukkitCommand {
|
||||
return;
|
||||
}
|
||||
versionWaiters.add(sender);
|
||||
- sender.sendMessage("Checking version, please wait...");
|
||||
+ sender.sendMessage(Component.text("Checking version, please wait...", NamedTextColor.WHITE, TextDecoration.ITALIC)); // Paper
|
||||
if (!versionTaskStarted) {
|
||||
versionTaskStarted = true;
|
||||
new Thread(new Runnable() {
|
||||
@@ -186,6 +212,13 @@ public class VersionCommand extends BukkitCommand {
|
||||
|
||||
private void obtainVersion() {
|
||||
String version = Bukkit.getVersion();
|
||||
+ // Paper start
|
||||
+ if (version.startsWith("null")) { // running from ide?
|
||||
+ setVersionMessage(Component.text("Unknown version, custom build?", NamedTextColor.YELLOW));
|
||||
+ return;
|
||||
+ }
|
||||
+ setVersionMessage(getVersionFetcher().getVersionMessage(version));
|
||||
+ /*
|
||||
if (version == null) version = "Custom";
|
||||
String[] parts = version.substring(0, version.indexOf(' ')).split("-");
|
||||
if (parts.length == 4) {
|
||||
@@ -215,11 +248,24 @@ public class VersionCommand extends BukkitCommand {
|
||||
} else {
|
||||
setVersionMessage("Unknown version, custom build?");
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
- private void setVersionMessage(@NotNull String msg) {
|
||||
+ // Paper start
|
||||
+ private void setVersionMessage(final @NotNull Component msg) {
|
||||
lastCheck = System.currentTimeMillis();
|
||||
- versionMessage = msg;
|
||||
+ final Component message = Component.textOfChildren(
|
||||
+ Component.text("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")", NamedTextColor.WHITE),
|
||||
+ Component.newline(),
|
||||
+ msg
|
||||
+ );
|
||||
+ this.versionMessage = Component.text()
|
||||
+ .append(message)
|
||||
+ .hoverEvent(Component.text("Click to copy to clipboard", NamedTextColor.WHITE))
|
||||
+ .clickEvent(ClickEvent.copyToClipboard(PlainTextComponentSerializer.plainText().serialize(message)))
|
||||
+ .build();
|
||||
+ // Paper end
|
||||
versionLock.lock();
|
||||
try {
|
||||
hasVersion = true;
|
||||
@@ -1,66 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Mon, 29 Feb 2016 17:50:31 -0600
|
||||
Subject: [PATCH] Entity Origin API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
|
||||
index 598abaa82c634178043a29f6caa6ac5221659d06..70a32f89c16439c575d8928332cfed64d1d6ab7e 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -725,5 +725,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
default net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowEntity> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowEntity> op) {
|
||||
return net.kyori.adventure.text.event.HoverEvent.showEntity(op.apply(net.kyori.adventure.text.event.HoverEvent.ShowEntity.of(this.getType().getKey(), this.getUniqueId(), this.customName())));
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the location where this entity originates from.
|
||||
+ * <p>
|
||||
+ * This value can be null if the entity hasn't yet been added to the world.
|
||||
+ *
|
||||
+ * @return Location where entity originates or null if not yet added
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Location getOrigin();
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/FallingBlock.java b/src/main/java/org/bukkit/entity/FallingBlock.java
|
||||
index d96fd494b523491fcf1ac54d164351fd487f65d6..ae1ce2ee2deb82f3f4144ec54b3ba119b437c5e9 100644
|
||||
--- a/src/main/java/org/bukkit/entity/FallingBlock.java
|
||||
+++ b/src/main/java/org/bukkit/entity/FallingBlock.java
|
||||
@@ -126,4 +126,15 @@ public interface FallingBlock extends Entity {
|
||||
* @param damage the max damage to set. Must be >= 0
|
||||
*/
|
||||
void setMaxDamage(int damage);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the source block location of the FallingBlock
|
||||
+ *
|
||||
+ * @return the source block location the FallingBlock was spawned from
|
||||
+ * @deprecated replaced by {@link Entity#getOrigin()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default org.bukkit.Location getSourceLoc() {
|
||||
+ return this.getOrigin();
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/TNTPrimed.java b/src/main/java/org/bukkit/entity/TNTPrimed.java
|
||||
index a23cfdf66877f0a61eae700de084c76e6ee7b431..0813bd913c8fdb2001963ce3e82c07c2af105418 100644
|
||||
--- a/src/main/java/org/bukkit/entity/TNTPrimed.java
|
||||
+++ b/src/main/java/org/bukkit/entity/TNTPrimed.java
|
||||
@@ -53,4 +53,15 @@ public interface TNTPrimed extends Explosive {
|
||||
* @param source the source of this primed TNT
|
||||
*/
|
||||
public void setSource(@Nullable Entity source);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the source block location of the TNTPrimed
|
||||
+ *
|
||||
+ * @return the source block location the TNTPrimed was spawned from
|
||||
+ * @deprecated replaced by {@link Entity#getOrigin()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default org.bukkit.Location getSourceLoc() {
|
||||
+ return this.getOrigin();
|
||||
+ }
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Moore <rmsy@me.com>
|
||||
Date: Mon, 29 Feb 2016 18:02:25 -0600
|
||||
Subject: [PATCH] Add PlayerLocaleChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerLocaleChangeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerLocaleChangeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bb7baa91fd4ba763fd8ce216bc9043c5e2c4b7b7
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerLocaleChangeEvent.java
|
||||
@@ -0,0 +1,51 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+
|
||||
+/**
|
||||
+ * Called when the locale of the player is changed.
|
||||
+ *
|
||||
+ * @deprecated Replaced by {@link org.bukkit.event.player.PlayerLocaleChangeEvent} upstream
|
||||
+ */
|
||||
+@Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21")
|
||||
+public class PlayerLocaleChangeEvent extends PlayerEvent {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private final String oldLocale;
|
||||
+ private final String newLocale;
|
||||
+
|
||||
+ public PlayerLocaleChangeEvent(final Player player, final String oldLocale, final String newLocale) {
|
||||
+ super(player);
|
||||
+ this.oldLocale = oldLocale;
|
||||
+ this.newLocale = newLocale;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the locale the player switched from.
|
||||
+ *
|
||||
+ * @return player's old locale
|
||||
+ */
|
||||
+ public String getOldLocale() {
|
||||
+ return oldLocale;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the locale the player is changed to.
|
||||
+ *
|
||||
+ * @return player's new locale
|
||||
+ */
|
||||
+ public String getNewLocale() {
|
||||
+ return newLocale;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,159 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Mon, 29 Feb 2016 18:05:37 -0600
|
||||
Subject: [PATCH] Add view distance API
|
||||
|
||||
Add per player no-tick, tick, and send view distances.
|
||||
|
||||
Also add send/no-tick view distance to World.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 5357291ff0f2f20bd87ab9f6e57f6a4f6ff65226..887aa6217583d224d66f6d238ac269c23725d459 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -2662,6 +2662,62 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
int getSimulationDistance();
|
||||
// Spigot end
|
||||
|
||||
+ // Paper start - view distance api
|
||||
+ /**
|
||||
+ * Sets the view distance for this world.
|
||||
+ * @param viewDistance view distance in [2, 32]
|
||||
+ */
|
||||
+ void setViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the simulation distance for this world.
|
||||
+ * @param simulationDistance simulation distance in [2, 32]
|
||||
+ */
|
||||
+ void setSimulationDistance(int simulationDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the no-tick view distance for this world.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @return The no-tick view distance for this world.
|
||||
+ * @deprecated Use {@link #getViewDistance()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ int getNoTickViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the no-tick view distance for this world.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32]
|
||||
+ * @deprecated Use {@link #setViewDistance(int)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ void setNoTickViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the sending view distance for this world.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players in this world.
|
||||
+ * </p>
|
||||
+ * @return The sending view distance for this world.
|
||||
+ */
|
||||
+ int getSendViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the sending view distance for this world.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players in this world.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32] or -1
|
||||
+ */
|
||||
+ void setSendViewDistance(int viewDistance);
|
||||
+ // Paper end - view distance api
|
||||
+
|
||||
// Spigot start
|
||||
public class Spigot {
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 6b1a198f930a5a995e0cb6c279b455e1639a5039..f8e45f70fe23cf73c8677b5d24cefcd3aae5e24e 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -2210,6 +2210,78 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param affects Whether the player can affect mob spawning
|
||||
*/
|
||||
public void setAffectsSpawning(boolean affects);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the view distance for this player
|
||||
+ *
|
||||
+ * @return the player's view distance
|
||||
+ * @see org.bukkit.World#getViewDistance()
|
||||
+ */
|
||||
+ public int getViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the view distance for this player
|
||||
+ *
|
||||
+ * @param viewDistance the player's view distance
|
||||
+ * @see org.bukkit.World#setViewDistance(int)
|
||||
+ */
|
||||
+ public void setViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the simulation distance for this player
|
||||
+ *
|
||||
+ * @return the player's simulation distance
|
||||
+ */
|
||||
+ public int getSimulationDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the simulation distance for this player
|
||||
+ *
|
||||
+ * @param simulationDistance the player's new simulation distance
|
||||
+ */
|
||||
+ public void setSimulationDistance(int simulationDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the no-ticking view distance for this player.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @return The no-tick view distance for this player.
|
||||
+ * @deprecated Use {@link #getViewDistance()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public int getNoTickViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the no-ticking view distance for this player.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32] or -1
|
||||
+ * @deprecated Use {@link #setViewDistance(int)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setNoTickViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the sending view distance for this player.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players.
|
||||
+ * </p>
|
||||
+ * @return The sending view distance for this player.
|
||||
+ */
|
||||
+ public int getSendViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the sending view distance for this player.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32] or -1
|
||||
+ */
|
||||
+ public void setSendViewDistance(int viewDistance);
|
||||
// Paper end
|
||||
|
||||
/**
|
||||
@@ -1,98 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Mon, 29 Feb 2016 18:09:40 -0600
|
||||
Subject: [PATCH] Add BeaconEffectEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java b/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..978813b94a5eae0afccbd3b38b463091a46b56ac
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
|
||||
@@ -0,0 +1,86 @@
|
||||
+package com.destroystokyo.paper.event.block;
|
||||
+
|
||||
+import org.bukkit.block.Block;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.block.BlockEvent;
|
||||
+import org.bukkit.potion.PotionEffect;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a beacon effect is being applied to a player.
|
||||
+ */
|
||||
+public class BeaconEffectEvent extends BlockEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+ private PotionEffect effect;
|
||||
+ private Player player;
|
||||
+ private boolean primary;
|
||||
+
|
||||
+ public BeaconEffectEvent(@NotNull Block block, @NotNull PotionEffect effect, @NotNull Player player, boolean primary) {
|
||||
+ super(block);
|
||||
+ this.effect = effect;
|
||||
+ this.player = player;
|
||||
+ this.primary = primary;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancelled) {
|
||||
+ this.cancelled = cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the potion effect being applied.
|
||||
+ *
|
||||
+ * @return Potion effect
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PotionEffect getEffect() {
|
||||
+ return effect;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the potion effect that will be applied.
|
||||
+ *
|
||||
+ * @param effect Potion effect
|
||||
+ */
|
||||
+ public void setEffect(@NotNull PotionEffect effect) {
|
||||
+ this.effect = effect;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the player who the potion effect is being applied to.
|
||||
+ *
|
||||
+ * @return Affected player
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether the effect is a primary beacon effect.
|
||||
+ *
|
||||
+ * @return true if this event represents a primary effect
|
||||
+ */
|
||||
+ public boolean isPrimary() {
|
||||
+ return primary;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Anton <anxuiz.nx@gmail.com>
|
||||
Date: Mon, 29 Feb 2016 18:13:58 -0600
|
||||
Subject: [PATCH] Add PlayerInitialSpawnEvent
|
||||
|
||||
For modifying a player's initial spawn location as they join the server
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerInitialSpawnEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerInitialSpawnEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..febd384b43560d7d55c96bda5b0701a27fc9e18e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerInitialSpawnEvent.java
|
||||
@@ -0,0 +1,18 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.spigotmc.event.player.PlayerSpawnLocationEvent;
|
||||
+
|
||||
+/**
|
||||
+ * @deprecated Use {@link PlayerSpawnLocationEvent}, Duplicate API
|
||||
+ */
|
||||
+@Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21")
|
||||
+public class PlayerInitialSpawnEvent extends PlayerSpawnLocationEvent {
|
||||
+
|
||||
+ public PlayerInitialSpawnEvent(@NotNull Player who, @NotNull Location spawnLocation) {
|
||||
+ super(who, spawnLocation);
|
||||
+ }
|
||||
+}
|
||||
@@ -1,50 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Mon, 29 Feb 2016 19:48:59 -0600
|
||||
Subject: [PATCH] Expose server CommandMap
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index fba3e617a8847a3e9282e6a1a389132b2ad5511c..acb34296923fb27cfc28c130cf0b5405cfe340f6 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -2165,6 +2165,19 @@ public final class Bukkit {
|
||||
return server.getUnsafe();
|
||||
}
|
||||
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the active {@link org.bukkit.command.CommandMap}
|
||||
+ *
|
||||
+ * @return the active command map
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static org.bukkit.command.CommandMap getCommandMap() {
|
||||
+ return server.getCommandMap();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@NotNull
|
||||
public static Server.Spigot spigot() {
|
||||
return server.spigot();
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index c8cf66e64a3163c2bdf781f3ce52059546969b9b..5b3c34b01038849b1463870ccf657b11db82cd09 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1682,6 +1682,15 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
public double[] getTPS();
|
||||
// Paper end
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the active {@link org.bukkit.command.CommandMap}
|
||||
+ *
|
||||
+ * @return the active command map
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ org.bukkit.command.CommandMap getCommandMap();
|
||||
+
|
||||
/**
|
||||
* Get the advancement specified by this key.
|
||||
*
|
||||
@@ -1,124 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Mon, 29 Feb 2016 19:54:32 -0600
|
||||
Subject: [PATCH] Graduate bungeecord chat API from spigot subclasses
|
||||
|
||||
Change Javadoc to be accurate
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index b53e94d79862d66165bbcd2a79b82770398a7f3e..9417030074fccdd9113bf75eb8f17f74b9a9118b 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -410,6 +410,30 @@ public final class Bukkit {
|
||||
return server.broadcastMessage(message);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sends the component to all online players.
|
||||
+ *
|
||||
+ * @param component the component to send
|
||||
+ * @deprecated use {@code sendMessage} methods on {@link #getServer()} that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public static void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ server.broadcast(component);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to all online players.
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods on {@link #getServer()} that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public static void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ server.broadcast(components);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the name of the update folder. The update folder is used to safely
|
||||
* update plugins at the right moment on a plugin load.
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 124e88e512d24b6ff7ace3cf7d5a6adf4c2bb40d..ccc825a2ea43bb84a5a08dff00c4d8ec27e4e95a 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -345,6 +345,30 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@Deprecated // Paper
|
||||
public int broadcastMessage(@NotNull String message);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sends the component to all online players.
|
||||
+ *
|
||||
+ * @param component the component to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public default void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ spigot().broadcast(component);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to all online players.
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public default void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ spigot().broadcast(components);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the name of the update folder. The update folder is used to safely
|
||||
* update plugins at the right moment on a plugin load.
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index f8e45f70fe23cf73c8677b5d24cefcd3aae5e24e..f52e7d4e5b8399d04d77384f8fe5315086acd776 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -1041,6 +1041,42 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
*/
|
||||
public void sendMap(@NotNull MapView map);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sends the component to the player
|
||||
+ *
|
||||
+ * @param component the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Override
|
||||
+ @Deprecated
|
||||
+ public default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ spigot().sendMessage(component);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to the player
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Override
|
||||
+ @Deprecated
|
||||
+ public default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ spigot().sendMessage(components);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to the specified screen position of this player
|
||||
+ *
|
||||
+ * @param position the screen position
|
||||
+ * @param components the components to send
|
||||
+ */
|
||||
+ public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ spigot().sendMessage(position, components);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Send a hurt animation. This fakes incoming damage towards the player from
|
||||
* the given yaw relative to the player's direction.
|
||||
@@ -1,580 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Mon, 29 Feb 2016 20:24:35 -0600
|
||||
Subject: [PATCH] Add exception reporting event
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..306dbd975e9380c22dae0dad526725cc47a36f16
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java
|
||||
@@ -0,0 +1,42 @@
|
||||
+package com.destroystokyo.paper.event.server;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import com.destroystokyo.paper.exception.ServerException;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called whenever an exception is thrown in a recoverable section of the server.
|
||||
+ */
|
||||
+public class ServerExceptionEvent extends Event {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private ServerException exception;
|
||||
+
|
||||
+ public ServerExceptionEvent(@NotNull ServerException exception) {
|
||||
+ super(!Bukkit.isPrimaryThread());
|
||||
+ this.exception = Preconditions.checkNotNull(exception, "exception");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the wrapped exception that was thrown.
|
||||
+ *
|
||||
+ * @return Exception thrown
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ServerException getException() {
|
||||
+ return exception;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java b/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6fb39af0479a818f7f1465bcdfe505ab4ff7da1a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java
|
||||
@@ -0,0 +1,64 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.checkNotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a command throws an exception
|
||||
+ */
|
||||
+public class ServerCommandException extends ServerException {
|
||||
+
|
||||
+ private final Command command;
|
||||
+ private final CommandSender commandSender;
|
||||
+ private final String[] arguments;
|
||||
+
|
||||
+ public ServerCommandException(String message, Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause);
|
||||
+ this.commandSender = checkNotNull(commandSender, "commandSender");
|
||||
+ this.arguments = checkNotNull(arguments, "arguments");
|
||||
+ this.command = checkNotNull(command, "command");
|
||||
+ }
|
||||
+
|
||||
+ public ServerCommandException(Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(cause);
|
||||
+ this.commandSender = checkNotNull(commandSender, "commandSender");
|
||||
+ this.arguments = checkNotNull(arguments, "arguments");
|
||||
+ this.command = checkNotNull(command, "command");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerCommandException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ this.commandSender = checkNotNull(commandSender, "commandSender");
|
||||
+ this.arguments = checkNotNull(arguments, "arguments");
|
||||
+ this.command = checkNotNull(command, "command");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the command which threw the exception
|
||||
+ *
|
||||
+ * @return exception throwing command
|
||||
+ */
|
||||
+ public Command getCommand() {
|
||||
+ return command;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the command sender which executed the command request
|
||||
+ *
|
||||
+ * @return command sender of exception thrown command request
|
||||
+ */
|
||||
+ public CommandSender getCommandSender() {
|
||||
+ return commandSender;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the arguments which threw the exception for the command
|
||||
+ *
|
||||
+ * @return arguments of exception thrown command request
|
||||
+ */
|
||||
+ public String[] getArguments() {
|
||||
+ return arguments;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java b/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..410b24139535cd5d8439ad581c43c61b5757fbf6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java
|
||||
@@ -0,0 +1,52 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.Listener;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.*;
|
||||
+
|
||||
+/**
|
||||
+ * Exception thrown when a server event listener throws an exception
|
||||
+ */
|
||||
+public class ServerEventException extends ServerPluginException {
|
||||
+
|
||||
+ private final Listener listener;
|
||||
+ private final Event event;
|
||||
+
|
||||
+ public ServerEventException(String message, Throwable cause, Plugin responsiblePlugin, Listener listener, Event event) {
|
||||
+ super(message, cause, responsiblePlugin);
|
||||
+ this.listener = checkNotNull(listener, "listener");
|
||||
+ this.event = checkNotNull(event, "event");
|
||||
+ }
|
||||
+
|
||||
+ public ServerEventException(Throwable cause, Plugin responsiblePlugin, Listener listener, Event event) {
|
||||
+ super(cause, responsiblePlugin);
|
||||
+ this.listener = checkNotNull(listener, "listener");
|
||||
+ this.event = checkNotNull(event, "event");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerEventException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin, Listener listener, Event event) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
|
||||
+ this.listener = checkNotNull(listener, "listener");
|
||||
+ this.event = checkNotNull(event, "event");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the listener which threw the exception
|
||||
+ *
|
||||
+ * @return event listener
|
||||
+ */
|
||||
+ public Listener getListener() {
|
||||
+ return listener;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the event which caused the exception
|
||||
+ *
|
||||
+ * @return event
|
||||
+ */
|
||||
+ public Event getEvent() {
|
||||
+ return event;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerException.java b/src/main/java/com/destroystokyo/paper/exception/ServerException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c06ea3942447d4824b83ff839cb449fb818dede1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerException.java
|
||||
@@ -0,0 +1,23 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+/**
|
||||
+ * Wrapper exception for all exceptions that are thrown by the server.
|
||||
+ */
|
||||
+public class ServerException extends Exception {
|
||||
+
|
||||
+ public ServerException(String message) {
|
||||
+ super(message);
|
||||
+ }
|
||||
+
|
||||
+ public ServerException(String message, Throwable cause) {
|
||||
+ super(message, cause);
|
||||
+ }
|
||||
+
|
||||
+ public ServerException(Throwable cause) {
|
||||
+ super(cause);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java b/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2c3effca7c9d6c904cbe248d312b74e2cd360acf
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java
|
||||
@@ -0,0 +1,36 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import java.util.logging.Level;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when the internal server throws a recoverable exception.
|
||||
+ */
|
||||
+public class ServerInternalException extends ServerException {
|
||||
+
|
||||
+ public ServerInternalException(String message) {
|
||||
+ super(message);
|
||||
+ }
|
||||
+
|
||||
+ public ServerInternalException(String message, Throwable cause) {
|
||||
+ super(message, cause);
|
||||
+ }
|
||||
+
|
||||
+ public ServerInternalException(Throwable cause) {
|
||||
+ super(cause);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerInternalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ }
|
||||
+
|
||||
+ public static void reportInternalException(Throwable cause) {
|
||||
+ try {
|
||||
+ Bukkit.getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(cause)));
|
||||
+ ;
|
||||
+ } catch (Throwable t) {
|
||||
+ Bukkit.getLogger().log(Level.WARNING, "Exception posting ServerExceptionEvent", t); // Don't want to rethrow!
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f016ba3b1b62e554a9bacbb9635f2dbe441b3c4e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java
|
||||
@@ -0,0 +1,20 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown whenever there is an exception with any enabling or disabling of plugins.
|
||||
+ */
|
||||
+public class ServerPluginEnableDisableException extends ServerPluginException {
|
||||
+ public ServerPluginEnableDisableException(String message, Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(message, cause, responsiblePlugin);
|
||||
+ }
|
||||
+
|
||||
+ public ServerPluginEnableDisableException(Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(cause, responsiblePlugin);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerPluginEnableDisableException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..be3f92e3c6bcefe8b78da701b75121275001882e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java
|
||||
@@ -0,0 +1,36 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.checkNotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Wrapper exception for all cases to which a plugin can be immediately blamed for
|
||||
+ */
|
||||
+public class ServerPluginException extends ServerException {
|
||||
+ public ServerPluginException(String message, Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(message, cause);
|
||||
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
|
||||
+ }
|
||||
+
|
||||
+ public ServerPluginException(Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(cause);
|
||||
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerPluginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
|
||||
+ }
|
||||
+
|
||||
+ private final Plugin responsiblePlugin;
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the plugin which is directly responsible for the exception being thrown
|
||||
+ *
|
||||
+ * @return plugin which is responsible for the exception throw
|
||||
+ */
|
||||
+ public Plugin getResponsiblePlugin() {
|
||||
+ return responsiblePlugin;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2faef4cb358ec65e32a6aba6426f0dd7ddf90d2a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java
|
||||
@@ -0,0 +1,64 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.*;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when an incoming plugin message channel throws an exception
|
||||
+ */
|
||||
+public class ServerPluginMessageException extends ServerPluginException {
|
||||
+
|
||||
+ private final Player player;
|
||||
+ private final String channel;
|
||||
+ private final byte[] data;
|
||||
+
|
||||
+ public ServerPluginMessageException(String message, Throwable cause, Plugin responsiblePlugin, Player player, String channel, byte[] data) {
|
||||
+ super(message, cause, responsiblePlugin);
|
||||
+ this.player = checkNotNull(player, "player");
|
||||
+ this.channel = checkNotNull(channel, "channel");
|
||||
+ this.data = checkNotNull(data, "data");
|
||||
+ }
|
||||
+
|
||||
+ public ServerPluginMessageException(Throwable cause, Plugin responsiblePlugin, Player player, String channel, byte[] data) {
|
||||
+ super(cause, responsiblePlugin);
|
||||
+ this.player = checkNotNull(player, "player");
|
||||
+ this.channel = checkNotNull(channel, "channel");
|
||||
+ this.data = checkNotNull(data, "data");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerPluginMessageException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin, Player player, String channel, byte[] data) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
|
||||
+ this.player = checkNotNull(player, "player");
|
||||
+ this.channel = checkNotNull(channel, "channel");
|
||||
+ this.data = checkNotNull(data, "data");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the channel to which the error occurred from receiving data from
|
||||
+ *
|
||||
+ * @return exception channel
|
||||
+ */
|
||||
+ public String getChannel() {
|
||||
+ return channel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the data to which the error occurred from
|
||||
+ *
|
||||
+ * @return exception data
|
||||
+ */
|
||||
+ public byte[] getData() {
|
||||
+ return data;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the player which the plugin message causing the exception originated from
|
||||
+ *
|
||||
+ * @return exception player
|
||||
+ */
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java b/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2d0b2d4a9b3e5bdeec0e4ea7ab69858d86aa3715
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java
|
||||
@@ -0,0 +1,37 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.scheduler.BukkitTask;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.checkNotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a plugin's scheduler fails with an exception
|
||||
+ */
|
||||
+public class ServerSchedulerException extends ServerPluginException {
|
||||
+
|
||||
+ private final BukkitTask task;
|
||||
+
|
||||
+ public ServerSchedulerException(String message, Throwable cause, BukkitTask task) {
|
||||
+ super(message, cause, task.getOwner());
|
||||
+ this.task = checkNotNull(task, "task");
|
||||
+ }
|
||||
+
|
||||
+ public ServerSchedulerException(Throwable cause, BukkitTask task) {
|
||||
+ super(cause, task.getOwner());
|
||||
+ this.task = checkNotNull(task, "task");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerSchedulerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, BukkitTask task) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, task.getOwner());
|
||||
+ this.task = checkNotNull(task, "task");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the task which threw the exception
|
||||
+ *
|
||||
+ * @return exception throwing task
|
||||
+ */
|
||||
+ public BukkitTask getTask() {
|
||||
+ return task;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java b/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5582999fe94c7a3dac655044ccc6d078cd9521a1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java
|
||||
@@ -0,0 +1,22 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a tab-complete request throws an exception
|
||||
+ */
|
||||
+public class ServerTabCompleteException extends ServerCommandException {
|
||||
+
|
||||
+ public ServerTabCompleteException(String message, Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause, command, commandSender, arguments);
|
||||
+ }
|
||||
+
|
||||
+ public ServerTabCompleteException(Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(cause, command, commandSender, arguments);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerTabCompleteException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, command, commandSender, arguments);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
index 4205649948a9e2a72f64c3f007112245abac6d50..b3b32ce429edbf1ed040354dbe28ab86f0d24201 100644
|
||||
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
@@ -155,11 +155,14 @@ public class SimpleCommandMap implements CommandMap {
|
||||
target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length));
|
||||
} // target.timings.stopTiming(); // Spigot // Paper
|
||||
} catch (CommandException ex) {
|
||||
+ server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
|
||||
//target.timings.stopTiming(); // Spigot // Paper
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
//target.timings.stopTiming(); // Spigot // Paper
|
||||
- throw new CommandException("Unhandled exception executing '" + commandLine + "' in " + target, ex);
|
||||
+ String msg = "Unhandled exception executing '" + commandLine + "' in " + target;
|
||||
+ server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
|
||||
+ throw new CommandException(msg, ex);
|
||||
}
|
||||
|
||||
// return true as command was handled
|
||||
@@ -238,7 +241,9 @@ public class SimpleCommandMap implements CommandMap {
|
||||
} catch (CommandException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
- throw new CommandException("Unhandled exception executing tab-completer for '" + cmdLine + "' in " + target, ex);
|
||||
+ String msg = "Unhandled exception executing tab-completer for '" + cmdLine + "' in " + target;
|
||||
+ server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerTabCompleteException(msg, ex, target, sender, args))); // Paper
|
||||
+ throw new CommandException(msg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index 974ff7116b294473ec450757e8a9341540f43dcd..fc2dae69165776d08274e34a69962cc70445f411 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -515,7 +515,8 @@ public final class SimplePluginManager implements PluginManager {
|
||||
try {
|
||||
plugin.getPluginLoader().enablePlugin(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while enabling "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin);
|
||||
}
|
||||
|
||||
HandlerList.bakeAll();
|
||||
@@ -538,32 +539,37 @@ public final class SimplePluginManager implements PluginManager {
|
||||
try {
|
||||
plugin.getPluginLoader().disablePlugin(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while disabling "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
server.getScheduler().cancelTasks(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while cancelling tasks for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while cancelling tasks for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
server.getServicesManager().unregisterAll(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering services for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while unregistering services for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
HandlerList.unregisterAll(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering events for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while unregistering events for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
server.getMessenger().unregisterIncomingPluginChannel(plugin);
|
||||
server.getMessenger().unregisterOutgoingPluginChannel(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering plugin channels for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while unregistering plugin channels for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -576,6 +582,13 @@ public final class SimplePluginManager implements PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private void handlePluginException(String msg, Throwable ex, Plugin plugin) {
|
||||
+ server.getLogger().log(Level.SEVERE, msg, ex);
|
||||
+ callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerPluginEnableDisableException(msg, ex, plugin)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void clearPlugins() {
|
||||
if (true) {this.paperPluginManager.clearPlugins(); return;} // Paper
|
||||
@@ -641,7 +654,13 @@ public final class SimplePluginManager implements PluginManager {
|
||||
));
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName(), ex);
|
||||
+ // Paper start - error reporting
|
||||
+ String msg = "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName();
|
||||
+ server.getLogger().log(Level.SEVERE, msg, ex);
|
||||
+ if (!(event instanceof com.destroystokyo.paper.event.server.ServerExceptionEvent)) { // We don't want to cause an endless event loop
|
||||
+ callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerEventException(msg, ex, registration.getPlugin(), registration.getListener(), event)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Tue, 8 Mar 2016 13:05:59 -0800
|
||||
Subject: [PATCH] Add BaseComponent sendMessage methods to CommandSender
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/CommandSender.java b/src/main/java/org/bukkit/command/CommandSender.java
|
||||
index 0f2b85e4979c478fbcc20bd67446e6ac8c8696d7..5c8ae3e0a927f2f2924d719b03499d936cf4d951 100644
|
||||
--- a/src/main/java/org/bukkit/command/CommandSender.java
|
||||
+++ b/src/main/java/org/bukkit/command/CommandSender.java
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.UUID;
|
||||
+import net.kyori.adventure.audience.MessageType;
|
||||
+import net.kyori.adventure.identity.Identity;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -168,5 +171,33 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe
|
||||
default void sendPlainMessage(final @NotNull String message) {
|
||||
this.sendMessage(net.kyori.adventure.text.Component.text(message));
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the component to the sender
|
||||
+ *
|
||||
+ * <p>If this sender does not support sending full components then
|
||||
+ * the component will be sent as legacy text.</p>
|
||||
+ *
|
||||
+ * @param component the component to send
|
||||
+ * @deprecated use {@link #sendMessage(Identity, Component, MessageType)} instead
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ this.sendMessage(component.toLegacyText());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to the sender
|
||||
+ *
|
||||
+ * <p>If this sender does not support sending full components then
|
||||
+ * the components will be sent as legacy text.</p>
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@link #sendMessage(Identity, Component, MessageType)} instead
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ this.sendMessage(new net.md_5.bungee.api.chat.TextComponent(components).toLegacyText());
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Feb 2016 20:26:39 -0600
|
||||
Subject: [PATCH] Fix ServerListPingEvent flagging as Async
|
||||
|
||||
This event can sometimes fire Async, set the proper boolean
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/server/ServerEvent.java b/src/main/java/org/bukkit/event/server/ServerEvent.java
|
||||
index 46b119017a1e3dfcd9ae5fb91b4fe8c20b0d6b86..05167fb34e4c42edc67af6e6700a2a3cc0f92769 100644
|
||||
--- a/src/main/java/org/bukkit/event/server/ServerEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/server/ServerEvent.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.event.server;
|
||||
|
||||
+import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
/**
|
||||
@@ -8,7 +9,7 @@ import org.bukkit.event.Event;
|
||||
public abstract class ServerEvent extends Event {
|
||||
|
||||
public ServerEvent() {
|
||||
- super();
|
||||
+ super(!Bukkit.isPrimaryThread()); // Paper
|
||||
}
|
||||
|
||||
public ServerEvent(boolean isAsync) {
|
||||
@@ -1,569 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Mon, 29 Feb 2016 20:02:40 -0600
|
||||
Subject: [PATCH] Player Tab List and Title APIs
|
||||
|
||||
Co-authored-by: Fruxz <cedricspitzer@outlook.de>
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/Title.java b/src/main/java/com/destroystokyo/paper/Title.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9e90c3df567a65b48a0b9341f784eb902cb35d8c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/Title.java
|
||||
@@ -0,0 +1,420 @@
|
||||
+package com.destroystokyo.paper;
|
||||
+
|
||||
+import net.md_5.bungee.api.chat.BaseComponent;
|
||||
+import net.md_5.bungee.api.chat.TextComponent;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Arrays;
|
||||
+import java.util.Collection;
|
||||
+import java.util.List;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.checkArgument;
|
||||
+import static com.google.common.base.Preconditions.checkNotNull;
|
||||
+import static com.google.common.base.Preconditions.checkState;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a title to may be sent to a {@link Player}.
|
||||
+ *
|
||||
+ * <p>A title can be sent without subtitle text.</p>
|
||||
+ *
|
||||
+ * @deprecated use {@link net.kyori.adventure.title.Title}
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public final class Title {
|
||||
+
|
||||
+ /**
|
||||
+ * The default number of ticks for the title to fade in.
|
||||
+ */
|
||||
+ public static final int DEFAULT_FADE_IN = 20;
|
||||
+ /**
|
||||
+ * The default number of ticks for the title to stay.
|
||||
+ */
|
||||
+ public static final int DEFAULT_STAY = 200;
|
||||
+ /**
|
||||
+ * The default number of ticks for the title to fade out.
|
||||
+ */
|
||||
+ public static final int DEFAULT_FADE_OUT = 20;
|
||||
+
|
||||
+ private final BaseComponent[] title;
|
||||
+ private final BaseComponent[] subtitle;
|
||||
+ private final int fadeIn;
|
||||
+ private final int stay;
|
||||
+ private final int fadeOut;
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values and no subtitle.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent title) {
|
||||
+ this(title, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values and no subtitle.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent[] title) {
|
||||
+ this(title, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values and no subtitle.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ public Title(@NotNull String title) {
|
||||
+ this(title, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent title, @Nullable BaseComponent subtitle) {
|
||||
+ this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent[] title, @Nullable BaseComponent[] subtitle) {
|
||||
+ this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ */
|
||||
+ public Title(@NotNull String title, @Nullable String subtitle) {
|
||||
+ this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new title.
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ * @param fadeIn the number of ticks for the title to fade in
|
||||
+ * @param stay the number of ticks for the title to stay on screen
|
||||
+ * @param fadeOut the number of ticks for the title to fade out
|
||||
+ * @throws IllegalArgumentException if any of the times are negative
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent title, @Nullable BaseComponent subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
+ this(
|
||||
+ new BaseComponent[]{checkNotNull(title, "title")},
|
||||
+ subtitle == null ? null : new BaseComponent[]{subtitle},
|
||||
+ fadeIn,
|
||||
+ stay,
|
||||
+ fadeOut
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new title.
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ * @param fadeIn the number of ticks for the title to fade in
|
||||
+ * @param stay the number of ticks for the title to stay on screen
|
||||
+ * @param fadeOut the number of ticks for the title to fade out
|
||||
+ * @throws IllegalArgumentException if any of the times are negative
|
||||
+ */
|
||||
+ public Title(@Nullable BaseComponent[] title, @NotNull BaseComponent[] subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
+ checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn);
|
||||
+ checkArgument(stay >= 0, "Negative stay: %s", stay);
|
||||
+ checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut);
|
||||
+ this.title = checkNotNull(title, "title");
|
||||
+ this.subtitle = subtitle;
|
||||
+ this.fadeIn = fadeIn;
|
||||
+ this.stay = stay;
|
||||
+ this.fadeOut = fadeOut;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new title.
|
||||
+ *
|
||||
+ * <p>It is recommended to the {@link BaseComponent} constrctors.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ * @param fadeIn the number of ticks for the title to fade in
|
||||
+ * @param stay the number of ticks for the title to stay on screen
|
||||
+ * @param fadeOut the number of ticks for the title to fade out
|
||||
+ */
|
||||
+ public Title(@NotNull String title, @Nullable String subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
+ this(
|
||||
+ TextComponent.fromLegacyText(checkNotNull(title, "title")),
|
||||
+ subtitle == null ? null : TextComponent.fromLegacyText(subtitle),
|
||||
+ fadeIn,
|
||||
+ stay,
|
||||
+ fadeOut
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the text of this title
|
||||
+ *
|
||||
+ * @return the text
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public BaseComponent[] getTitle() {
|
||||
+ return this.title;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the text of this title's subtitle
|
||||
+ *
|
||||
+ * @return the text
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public BaseComponent[] getSubtitle() {
|
||||
+ return this.subtitle;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the number of ticks to fade in.
|
||||
+ *
|
||||
+ * <p>The returned value is never negative.</p>
|
||||
+ *
|
||||
+ * @return the number of ticks to fade in
|
||||
+ */
|
||||
+ public int getFadeIn() {
|
||||
+ return this.fadeIn;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the number of ticks to stay.
|
||||
+ *
|
||||
+ * <p>The returned value is never negative.</p>
|
||||
+ *
|
||||
+ * @return the number of ticks to stay
|
||||
+ */
|
||||
+ public int getStay() {
|
||||
+ return this.stay;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the number of ticks to fade out.
|
||||
+ *
|
||||
+ * <p>The returned value is never negative.</p>
|
||||
+ *
|
||||
+ * @return the number of ticks to fade out
|
||||
+ */
|
||||
+ public int getFadeOut() {
|
||||
+ return this.fadeOut;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to an player
|
||||
+ *
|
||||
+ * @param player the receiver of the title
|
||||
+ */
|
||||
+ public void send(@NotNull Player player) {
|
||||
+ player.sendTitle(this);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to the defined players
|
||||
+ *
|
||||
+ * @param players the receivers of the title
|
||||
+ */
|
||||
+ public void send(@NotNull Collection<? extends Player> players) {
|
||||
+ for (Player player : players) {
|
||||
+ player.sendTitle(this);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to the defined players
|
||||
+ *
|
||||
+ * @param players the receivers of the title
|
||||
+ */
|
||||
+ public void send(@NotNull Player[] players) {
|
||||
+ for (Player player : players) {
|
||||
+ player.sendTitle(this);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to all online players
|
||||
+ */
|
||||
+ public void broadcast() {
|
||||
+ send(Bukkit.getOnlinePlayers());
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static Builder builder() {
|
||||
+ return new Builder();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * A builder for creating titles
|
||||
+ */
|
||||
+ public static final class Builder {
|
||||
+
|
||||
+ private BaseComponent[] title;
|
||||
+ private BaseComponent[] subtitle;
|
||||
+ private int fadeIn = DEFAULT_FADE_IN;
|
||||
+ private int stay = DEFAULT_STAY;
|
||||
+ private int fadeOut = DEFAULT_FADE_OUT;
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the title to the given text.
|
||||
+ *
|
||||
+ * @param title the title text
|
||||
+ * @return this builder instance
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder title(@NotNull BaseComponent title) {
|
||||
+ return this.title(new BaseComponent[]{checkNotNull(title, "title")});
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the title to the given text.
|
||||
+ *
|
||||
+ * @param title the title text
|
||||
+ * @return this builder instance
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder title(@NotNull BaseComponent[] title) {
|
||||
+ this.title = checkNotNull(title, "title");
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the title to the given text.
|
||||
+ *
|
||||
+ * <p>It is recommended to the {@link BaseComponent} methods.</p>
|
||||
+ *
|
||||
+ * @param title the title text
|
||||
+ * @return this builder instance
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder title(@NotNull String title) {
|
||||
+ return this.title(TextComponent.fromLegacyText(checkNotNull(title, "title")));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the subtitle to the given text.
|
||||
+ *
|
||||
+ * @param subtitle the title text
|
||||
+ * @return this builder instance
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder subtitle(@Nullable BaseComponent subtitle) {
|
||||
+ return this.subtitle(subtitle == null ? null : new BaseComponent[]{subtitle});
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the subtitle to the given text.
|
||||
+ *
|
||||
+ * @param subtitle the title text
|
||||
+ * @return this builder instance
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder subtitle(@Nullable BaseComponent[] subtitle) {
|
||||
+ this.subtitle = subtitle;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the subtitle to the given text.
|
||||
+ *
|
||||
+ * <p>It is recommended to the {@link BaseComponent} methods.</p>
|
||||
+ *
|
||||
+ * @param subtitle the title text
|
||||
+ * @return this builder instance
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder subtitle(@Nullable String subtitle) {
|
||||
+ return this.subtitle(subtitle == null ? null : TextComponent.fromLegacyText(subtitle));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of ticks for the title to fade in
|
||||
+ *
|
||||
+ * @param fadeIn the number of ticks to fade in
|
||||
+ * @return this builder instance
|
||||
+ * @throws IllegalArgumentException if it is negative
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder fadeIn(int fadeIn) {
|
||||
+ checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn);
|
||||
+ this.fadeIn = fadeIn;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of ticks for the title to stay.
|
||||
+ *
|
||||
+ * @param stay the number of ticks to stay
|
||||
+ * @return this builder instance
|
||||
+ * @throws IllegalArgumentException if it is negative
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder stay(int stay) {
|
||||
+ checkArgument(stay >= 0, "Negative stay: %s", stay);
|
||||
+ this.stay = stay;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of ticks for the title to fade out.
|
||||
+ *
|
||||
+ * @param fadeOut the number of ticks to fade out
|
||||
+ * @return this builder instance
|
||||
+ * @throws IllegalArgumentException if it is negative
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder fadeOut(int fadeOut) {
|
||||
+ checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut);
|
||||
+ this.fadeOut = fadeOut;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title based on the values in the builder.
|
||||
+ *
|
||||
+ * @return a title from the values in this builder
|
||||
+ * @throws IllegalStateException if title isn't specified
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Title build() {
|
||||
+ checkState(title != null, "Title not specified");
|
||||
+ return new Title(this.title, this.subtitle, this.fadeIn, this.stay, this.fadeOut);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index f52e7d4e5b8399d04d77384f8fe5315086acd776..3650fb2b79368ad39278062f215d25cc99637cac 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -1075,6 +1075,131 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
spigot().sendMessage(position, components);
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Set the text displayed in the player list header and footer for this player
|
||||
+ *
|
||||
+ * @param header content for the top of the player list
|
||||
+ * @param footer content for the bottom of the player list
|
||||
+ * @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent[] header, @Nullable net.md_5.bungee.api.chat.BaseComponent[] footer);
|
||||
+
|
||||
+ /**
|
||||
+ * Set the text displayed in the player list header and footer for this player
|
||||
+ *
|
||||
+ * @param header content for the top of the player list
|
||||
+ * @param footer content for the bottom of the player list
|
||||
+ * @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent header, @Nullable net.md_5.bungee.api.chat.BaseComponent footer);
|
||||
+
|
||||
+ /**
|
||||
+ * Update the times for titles displayed to the player
|
||||
+ *
|
||||
+ * @param fadeInTicks ticks to fade-in
|
||||
+ * @param stayTicks ticks to stay visible
|
||||
+ * @param fadeOutTicks ticks to fade-out
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks);
|
||||
+
|
||||
+ /**
|
||||
+ * Update the subtitle of titles displayed to the player
|
||||
+ *
|
||||
+ * @param subtitle Subtitle to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent[] subtitle);
|
||||
+
|
||||
+ /**
|
||||
+ * Update the subtitle of titles displayed to the player
|
||||
+ *
|
||||
+ * @param subtitle Subtitle to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent subtitle);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title to the player, along with the last subtitle set, using the last set times
|
||||
+ *
|
||||
+ * @param title Title to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title to the player, along with the last subtitle set, using the last set times
|
||||
+ *
|
||||
+ * @param title Title to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title and subtitle to the player using the given times
|
||||
+ *
|
||||
+ * @param title big text
|
||||
+ * @param subtitle little text under it
|
||||
+ * @param fadeInTicks ticks to fade-in
|
||||
+ * @param stayTicks ticks to stay visible
|
||||
+ * @param fadeOutTicks ticks to fade-out
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title, @Nullable net.md_5.bungee.api.chat.BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title and subtitle to the player using the given times
|
||||
+ *
|
||||
+ * @param title big text
|
||||
+ * @param subtitle little text under it
|
||||
+ * @param fadeInTicks ticks to fade-in
|
||||
+ * @param stayTicks ticks to stay visible
|
||||
+ * @param fadeOutTicks ticks to fade-out
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title, @Nullable net.md_5.bungee.api.chat.BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the title to the player, overriding any previously displayed title.
|
||||
+ *
|
||||
+ * <p>This method overrides any previous title, use {@link #updateTitle(com.destroystokyo.paper.Title)} to change the existing one.</p>
|
||||
+ *
|
||||
+ * @param title the title to send
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ void sendTitle(@NotNull com.destroystokyo.paper.Title title);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the title to the player, overriding any previously displayed title.
|
||||
+ *
|
||||
+ * <p>This method doesn't override previous titles, but changes their values.</p>
|
||||
+ *
|
||||
+ * @param title the title to send
|
||||
+ * @throws NullPointerException if title is null
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ void updateTitle(@NotNull com.destroystokyo.paper.Title title);
|
||||
+
|
||||
+ /**
|
||||
+ * Hide any title that is currently visible to the player
|
||||
+ *
|
||||
+ * @deprecated use {@link #clearTitle()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void hideTitle();
|
||||
// Paper end
|
||||
|
||||
/**
|
||||
@@ -1,65 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: mrapple <tony@oc.tc>
|
||||
Date: Sun, 25 Nov 2012 13:47:27 -0600
|
||||
Subject: [PATCH] Add methods for working with arrows stuck in living entities
|
||||
|
||||
Upstream added methods for this so the original methods
|
||||
are now deprecated
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index 7c82644de3c438f45476ac02ce2c51c6fdbd543a..390bb294d09389877937ee2c6c3f346e65dfb178 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -215,12 +215,26 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
*/
|
||||
public int getArrowsInBody();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Set the amount of arrows in the entity's body.
|
||||
+ * <p>
|
||||
+ * Does not fire the {@link org.bukkit.event.entity.ArrowBodyCountChangeEvent}.
|
||||
+ *
|
||||
+ * @param count amount of arrows in entity's body
|
||||
+ */
|
||||
+ default void setArrowsInBody(final int count) {
|
||||
+ this.setArrowsInBody(count, false);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Set the amount of arrows in the entity's body.
|
||||
*
|
||||
* @param count amount of arrows in entity's body
|
||||
+ * @param fireEvent whether to fire the {@link org.bukkit.event.entity.ArrowBodyCountChangeEvent} event
|
||||
*/
|
||||
- public void setArrowsInBody(int count);
|
||||
+ void setArrowsInBody(int count, boolean fireEvent); // Paper
|
||||
|
||||
/**
|
||||
* Returns the living entity's current maximum no damage ticks.
|
||||
@@ -722,4 +736,24 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
* @return Whether the entity is invisible
|
||||
*/
|
||||
public boolean isInvisible();
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Get the number of arrows stuck in this entity
|
||||
+ * @return Number of arrows stuck
|
||||
+ * @deprecated use {@link #getArrowsInBody()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ int getArrowsStuck();
|
||||
+
|
||||
+ /**
|
||||
+ * Set the number of arrows stuck in this entity
|
||||
+ *
|
||||
+ * @param arrows Number of arrows to stick in this entity
|
||||
+ * @deprecated use {@link #setArrowsInBody(int, boolean)}. <b>This method previously fired {@link org.bukkit.event.entity.ArrowBodyCountChangeEvent} so if
|
||||
+ * you want to retain exact functionality, pass {@code true} for {@code fireEvent}.</b>
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ void setArrowsStuck(int arrows);
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sat, 4 Apr 2015 22:59:54 -0400
|
||||
Subject: [PATCH] Complete resource pack API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 3650fb2b79368ad39278062f215d25cc99637cac..967ea421aed7f9d4c8edd366c00cf3ceca723b2f 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -1655,7 +1655,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @throws IllegalArgumentException Thrown if the URL is null.
|
||||
* @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
* length restriction is an implementation specific arbitrary value.
|
||||
+ * @deprecated use {@link #setResourcePack(String, String)}
|
||||
*/
|
||||
+ @Deprecated // Paper
|
||||
public void setResourcePack(@NotNull String url);
|
||||
|
||||
/**
|
||||
@@ -2500,6 +2502,124 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
default net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowEntity> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowEntity> op) {
|
||||
return net.kyori.adventure.text.event.HoverEvent.showEntity(op.apply(net.kyori.adventure.text.event.HoverEvent.ShowEntity.of(this.getType().getKey(), this.getUniqueId(), this.displayName())));
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Request that the player's client download and switch resource packs.
|
||||
+ * <p>
|
||||
+ * The player's client will download the new resource pack asynchronously
|
||||
+ * in the background, and will automatically switch to it once the
|
||||
+ * download is complete. If the client has downloaded and cached the same
|
||||
+ * resource pack in the past, it will perform a quick timestamp check
|
||||
+ * over the network to determine if the resource pack has changed and
|
||||
+ * needs to be downloaded again. When this request is sent for the very
|
||||
+ * first time from a given server, the client will first display a
|
||||
+ * confirmation GUI to the player before proceeding with the download.
|
||||
+ * <p>
|
||||
+ * Notes:
|
||||
+ * <ul>
|
||||
+ * <li>Players can disable server resources on their client, in which
|
||||
+ * case this method will have no affect on them.
|
||||
+ * <li>There is no concept of resetting resource packs back to default
|
||||
+ * within Minecraft, so players will have to relog to do so.
|
||||
+ * </ul>
|
||||
+ *
|
||||
+ * @param url The URL from which the client will download the resource
|
||||
+ * pack. The string must contain only US-ASCII characters and should
|
||||
+ * be encoded as per RFC 1738.
|
||||
+ * @param hash A 40 character hexadecimal and lowercase SHA-1 digest of
|
||||
+ * the resource pack file.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is null.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
+ * length restriction is an implementation specific arbitrary value.
|
||||
+ */
|
||||
+ void setResourcePack(@NotNull String url, @NotNull String hash);
|
||||
+
|
||||
+ /**
|
||||
+ * Request that the player's client download and switch resource packs.
|
||||
+ * <p>
|
||||
+ * The player's client will download the new resource pack asynchronously
|
||||
+ * in the background, and will automatically switch to it once the
|
||||
+ * download is complete. If the client has downloaded and cached the same
|
||||
+ * resource pack in the past, it will perform a quick timestamp check
|
||||
+ * over the network to determine if the resource pack has changed and
|
||||
+ * needs to be downloaded again. When this request is sent for the very
|
||||
+ * first time from a given server, the client will first display a
|
||||
+ * confirmation GUI to the player before proceeding with the download.
|
||||
+ * <p>
|
||||
+ * Notes:
|
||||
+ * <ul>
|
||||
+ * <li>Players can disable server resources on their client, in which
|
||||
+ * case this method will have no affect on them.
|
||||
+ * <li>There is no concept of resetting resource packs back to default
|
||||
+ * within Minecraft, so players will have to relog to do so.
|
||||
+ * </ul>
|
||||
+ *
|
||||
+ * @param url The URL from which the client will download the resource
|
||||
+ * pack. The string must contain only US-ASCII characters and should
|
||||
+ * be encoded as per RFC 1738.
|
||||
+ * @param hash A 40 character hexadecimal and lowercase SHA-1 digest of
|
||||
+ * the resource pack file.
|
||||
+ * @param required Marks if the resource pack should be required by the client
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is null.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
+ * length restriction is an implementation specific arbitrary value.
|
||||
+ */
|
||||
+ void setResourcePack(@NotNull String url, @NotNull String hash, boolean required);
|
||||
+
|
||||
+ /**
|
||||
+ * Request that the player's client download and switch resource packs.
|
||||
+ * <p>
|
||||
+ * The player's client will download the new resource pack asynchronously
|
||||
+ * in the background, and will automatically switch to it once the
|
||||
+ * download is complete. If the client has downloaded and cached the same
|
||||
+ * resource pack in the past, it will perform a quick timestamp check
|
||||
+ * over the network to determine if the resource pack has changed and
|
||||
+ * needs to be downloaded again. When this request is sent for the very
|
||||
+ * first time from a given server, the client will first display a
|
||||
+ * confirmation GUI to the player before proceeding with the download.
|
||||
+ * <p>
|
||||
+ * Notes:
|
||||
+ * <ul>
|
||||
+ * <li>Players can disable server resources on their client, in which
|
||||
+ * case this method will have no affect on them.
|
||||
+ * <li>There is no concept of resetting resource packs back to default
|
||||
+ * within Minecraft, so players will have to relog to do so.
|
||||
+ * </ul>
|
||||
+ *
|
||||
+ * @param url The URL from which the client will download the resource
|
||||
+ * pack. The string must contain only US-ASCII characters and should
|
||||
+ * be encoded as per RFC 1738.
|
||||
+ * @param hash A 40 character hexadecimal and lowercase SHA-1 digest of
|
||||
+ * the resource pack file.
|
||||
+ * @param required Marks if the resource pack should be required by the client
|
||||
+ * @param resourcePackPrompt A Prompt to be displayed in the client request
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is null.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
+ * length restriction is an implementation specific arbitrary value.
|
||||
+ */
|
||||
+ void setResourcePack(@NotNull String url, @NotNull String hash, boolean required, @Nullable net.kyori.adventure.text.Component resourcePackPrompt);
|
||||
+ /**
|
||||
+ * @return the most recent resource pack status received from the player,
|
||||
+ * or null if no status has ever been received from this player.
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ org.bukkit.event.player.PlayerResourcePackStatusEvent.Status getResourcePackStatus();
|
||||
+
|
||||
+ /**
|
||||
+ * @return the most recent resource pack hash received from the player,
|
||||
+ * or null if no hash has ever been received from this player.
|
||||
+ *
|
||||
+ * @deprecated This is no longer sent from the client and will always be null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ @Deprecated
|
||||
+ String getResourcePackHash();
|
||||
+
|
||||
+ /**
|
||||
+ * @return true if the last resource pack status received from this player
|
||||
+ * was {@link org.bukkit.event.player.PlayerResourcePackStatusEvent.Status#SUCCESSFULLY_LOADED}
|
||||
+ */
|
||||
+ boolean hasResourcePack();
|
||||
// Paper end
|
||||
|
||||
// Spigot start
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java
|
||||
index b98195650d49d78ec35970ca0376b6289b861e4b..4c2102a11c3d682d98f0db4ccafa35231e66bcdd 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java
|
||||
@@ -11,13 +11,32 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PlayerResourcePackStatusEvent extends PlayerEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
+ @Deprecated
|
||||
+ private final String hash; // Paper
|
||||
private final Status status;
|
||||
|
||||
public PlayerResourcePackStatusEvent(@NotNull final Player who, @NotNull Status resourcePackStatus) {
|
||||
super(who);
|
||||
+ this.hash = null; // Paper
|
||||
this.status = resourcePackStatus;
|
||||
}
|
||||
|
||||
+ @Deprecated // Paper
|
||||
+ public PlayerResourcePackStatusEvent(final Player who, Status resourcePackStatus, String hash) {
|
||||
+ super(who);
|
||||
+ this.hash = hash; // Paper
|
||||
+ this.status = resourcePackStatus;
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ /**
|
||||
+ * @deprecated Hash does not seem to ever be set
|
||||
+ */
|
||||
+ public String getHash() {
|
||||
+ return this.hash;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the status of this pack.
|
||||
*
|
||||
@@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 19 May 2013 20:36:58 -0400
|
||||
Subject: [PATCH] Add a call helper to Event
|
||||
|
||||
Reduces diff in Server patches
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/Event.java b/src/main/java/org/bukkit/event/Event.java
|
||||
index 18d0636b749913bfdcea8eebc7d0840d192fb071..8ec56cd6b8e0f5c5dd8c7c88b4671e18dcf109d0 100644
|
||||
--- a/src/main/java/org/bukkit/event/Event.java
|
||||
+++ b/src/main/java/org/bukkit/event/Event.java
|
||||
@@ -35,6 +35,22 @@ public abstract class Event {
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Calls the event and tests if cancelled.
|
||||
+ *
|
||||
+ * @return false if event was cancelled, if cancellable. otherwise true.
|
||||
+ */
|
||||
+ public boolean callEvent() {
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(this);
|
||||
+ if (this instanceof Cancellable) {
|
||||
+ return !((Cancellable) this).isCancelled();
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Convenience method for providing a user-friendly identifier. By
|
||||
* default, it is the event's class's {@linkplain Class#getSimpleName()
|
||||
@@ -1,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 22 Jul 2015 18:50:41 -0400
|
||||
Subject: [PATCH] Add sender name to commands.yml replacement
|
||||
|
||||
This allows you to use $sender in commands.yml definitions to make
|
||||
commands that auto target self.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/FormattedCommandAlias.java b/src/main/java/org/bukkit/command/FormattedCommandAlias.java
|
||||
index a6ad94ef98a1df1d2842635d850bc990b0137849..9d4f553c04784cca63901a56a7aea62a5cae1d72 100644
|
||||
--- a/src/main/java/org/bukkit/command/FormattedCommandAlias.java
|
||||
+++ b/src/main/java/org/bukkit/command/FormattedCommandAlias.java
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
+import java.util.regex.Matcher; // Paper
|
||||
+import java.util.regex.Pattern; // Paper
|
||||
+
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -19,7 +22,7 @@ public class FormattedCommandAlias extends Command {
|
||||
ArrayList<String> commands = new ArrayList<String>();
|
||||
for (String formatString : formatStrings) {
|
||||
try {
|
||||
- commands.add(buildCommand(formatString, args));
|
||||
+ commands.add(buildCommand(sender, formatString, args)); // Paper
|
||||
} catch (Throwable throwable) {
|
||||
if (throwable instanceof IllegalArgumentException) {
|
||||
sender.sendMessage(throwable.getMessage());
|
||||
@@ -37,7 +40,10 @@ public class FormattedCommandAlias extends Command {
|
||||
return result;
|
||||
}
|
||||
|
||||
- private String buildCommand(@NotNull String formatString, @NotNull String[] args) {
|
||||
+ private String buildCommand(@NotNull CommandSender sender, @NotNull String formatString, @NotNull String[] args) { // Paper
|
||||
+ if (formatString.contains("$sender")) { // Paper
|
||||
+ formatString = formatString.replaceAll(Pattern.quote("$sender"), Matcher.quoteReplacement(sender.getName())); // Paper
|
||||
+ } // Paper
|
||||
int index = formatString.indexOf('$');
|
||||
while (index != -1) {
|
||||
int start = index;
|
||||
@@ -1,86 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William <admin@domnian.com>
|
||||
Date: Fri, 18 Mar 2016 03:28:07 -0400
|
||||
Subject: [PATCH] Add command to reload permissions.yml and require confirm to
|
||||
reload
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 88cbb61a855d77fe6840be48140261032c5a38b8..540c57e82247eaad2cae1ab0199caf2a6cabcab1 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -2200,6 +2200,13 @@ public final class Bukkit {
|
||||
public static org.bukkit.command.CommandMap getCommandMap() {
|
||||
return server.getCommandMap();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Reload the Permissions in permissions.yml
|
||||
+ */
|
||||
+ public static void reloadPermissions() {
|
||||
+ server.reloadPermissions();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 7edaadd0a99fd8bbe3c683a126efd29993ed596c..f3452f65e6b69e8a2f0942c7a6afb9837a6d88fd 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1943,4 +1943,6 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@NotNull
|
||||
Spigot spigot();
|
||||
// Spigot end
|
||||
+
|
||||
+ void reloadPermissions(); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
index 50cc311be7904cc8fc6070a21c8e4de3a489fd20..5fa9d648bc780e874f658597f1a24715bccac5cb 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
@@ -13,15 +13,35 @@ public class ReloadCommand extends BukkitCommand {
|
||||
public ReloadCommand(@NotNull String name) {
|
||||
super(name);
|
||||
this.description = "Reloads the server configuration and plugins";
|
||||
- this.usageMessage = "/reload";
|
||||
+ this.usageMessage = "/reload [permissions]"; // Paper
|
||||
this.setPermission("bukkit.command.reload");
|
||||
this.setAliases(Arrays.asList("rl"));
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) {
|
||||
+ public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) { // Paper
|
||||
if (!testPermission(sender)) return true;
|
||||
|
||||
+ // Paper start - Reload permissions.yml & require confirm
|
||||
+ boolean confirmed = System.getProperty("LetMeReload") != null;
|
||||
+ if (args.length == 1) {
|
||||
+ if (args[0].equalsIgnoreCase("permissions")) {
|
||||
+ Bukkit.getServer().reloadPermissions();
|
||||
+ Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Permissions successfully reloaded.", net.kyori.adventure.text.format.NamedTextColor.GREEN));
|
||||
+ return true;
|
||||
+ } else if ("confirm".equalsIgnoreCase(args[0])) {
|
||||
+ confirmed = true;
|
||||
+ } else {
|
||||
+ Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Usage: " + usageMessage, net.kyori.adventure.text.format.NamedTextColor.RED));
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!confirmed) {
|
||||
+ Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Are you sure you wish to reload your server? Doing so may cause bugs and memory leaks. It is recommended to restart instead of using /reload. To confirm, please type ", net.kyori.adventure.text.format.NamedTextColor.RED).append(net.kyori.adventure.text.Component.text("/reload confirm", net.kyori.adventure.text.format.NamedTextColor.YELLOW)));
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues when using some plugins.");
|
||||
Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
|
||||
Bukkit.reload();
|
||||
@@ -33,6 +53,6 @@ public class ReloadCommand extends BukkitCommand {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
|
||||
- return Collections.emptyList();
|
||||
+ return java.util.Collections.singletonList("permissions"); // Paper
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sun, 21 Jun 2015 15:05:21 -0400
|
||||
Subject: [PATCH] Custom replacement for eaten items
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java b/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
|
||||
index 5c054eb531e3caf17c179aff6a712fb8c33d8f77..6110d0417340710333b44312d82c7bd5165a8954 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
|
||||
@@ -24,6 +24,7 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable {
|
||||
private boolean isCancelled = false;
|
||||
private ItemStack item;
|
||||
private final EquipmentSlot hand;
|
||||
+ @Nullable private ItemStack replacement; // Paper
|
||||
|
||||
/**
|
||||
* @param player the player consuming
|
||||
@@ -82,6 +83,29 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable {
|
||||
return hand;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Return the custom item stack that will replace the consumed item, or null if no
|
||||
+ * custom replacement has been set (which means the default replacement will be used).
|
||||
+ *
|
||||
+ * @return The custom item stack that will replace the consumed item or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getReplacement() {
|
||||
+ return this.replacement;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set a custom item stack to replace the consumed item. Pass null to clear any custom
|
||||
+ * stack that has been set and use the default replacement.
|
||||
+ *
|
||||
+ * @param replacement Replacement item to set, null to clear any custom stack and use default
|
||||
+ */
|
||||
+ public void setReplacement(@Nullable ItemStack replacement) {
|
||||
+ this.replacement = replacement;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.isCancelled;
|
||||
@@ -1,79 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 20:26:34 -0400
|
||||
Subject: [PATCH] Entity AddTo/RemoveFrom World Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..07660202e41ee86f1b66bad3335cf6fe126e7f9c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java
|
||||
@@ -0,0 +1,32 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired any time an entity is being added to the world for any reason.
|
||||
+ *
|
||||
+ * Not to be confused with {@link org.bukkit.event.entity.CreatureSpawnEvent}
|
||||
+ * This will fire anytime a chunk is reloaded too.
|
||||
+ */
|
||||
+public class EntityAddToWorldEvent extends EntityEvent {
|
||||
+
|
||||
+ public EntityAddToWorldEvent(@NotNull Entity entity) {
|
||||
+ super(entity);
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e5dbbd660409bae0d3b96e83390511d3a423a52e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
|
||||
@@ -0,0 +1,29 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired any time an entity is being removed from a world for any reason
|
||||
+ */
|
||||
+public class EntityRemoveFromWorldEvent extends EntityEvent {
|
||||
+
|
||||
+ public EntityRemoveFromWorldEvent(@NotNull Entity entity) {
|
||||
+ super(entity);
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,95 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 21:15:34 -0400
|
||||
Subject: [PATCH] EntityPathfindEvent
|
||||
|
||||
Fires when an Entity decides to start moving to a location.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..63e46b2fb1b12b36fcb1e98b178cf29dd2e3d1b5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java
|
||||
@@ -0,0 +1,82 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an Entity decides to start moving towards a location.
|
||||
+ *
|
||||
+ * This event does not fire for the entities actual movement. Only when it
|
||||
+ * is choosing to start moving to a location.
|
||||
+ */
|
||||
+public class EntityPathfindEvent extends EntityEvent implements Cancellable {
|
||||
+ @Nullable private final Entity targetEntity;
|
||||
+ @NotNull private final Location loc;
|
||||
+
|
||||
+ public EntityPathfindEvent(@NotNull Entity entity, @NotNull Location loc, @Nullable Entity targetEntity) {
|
||||
+ super(entity);
|
||||
+ this.targetEntity = targetEntity;
|
||||
+ this.loc = loc;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The Entity that is pathfinding.
|
||||
+ * @return The Entity that is pathfinding.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Entity getEntity() {
|
||||
+ return entity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If the Entity is trying to pathfind to an entity, this is the entity in relation.
|
||||
+ *
|
||||
+ * Otherwise this will return null.
|
||||
+ *
|
||||
+ * @return The entity target or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity getTargetEntity() {
|
||||
+ return targetEntity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The Location of where the entity is about to move to.
|
||||
+ *
|
||||
+ * Note that if the target happened to of been an entity
|
||||
+ * @return Location of where the entity is trying to pathfind to.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location getLoc() {
|
||||
+ return loc;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,90 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: crast <contact@jamescrasta.com>
|
||||
Date: Sat, 1 Jun 2013 13:52:30 -0600
|
||||
Subject: [PATCH] Reduce thread synchronization in MetadataStoreBase
|
||||
|
||||
Use ConcurrentHashMap to allow thread-safe access methods and very
|
||||
limited synchronized portions to allow much higher concurrency in
|
||||
MetadataStore as well as far less locking, especially on reads
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
index 6886a7003fb76d07e0fa9c1c352c56480f08a0db..a0698522f01619c9d37474f4bd55a17de58fff89 100644
|
||||
--- a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
+++ b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
@@ -12,7 +12,7 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class MetadataStoreBase<T> {
|
||||
- private Map<String, Map<Plugin, MetadataValue>> metadataMap = new HashMap<String, Map<Plugin, MetadataValue>>();
|
||||
+ private Map<String, Map<Plugin, MetadataValue>> metadataMap = new java.util.concurrent.ConcurrentHashMap<String, Map<Plugin, MetadataValue>>(); // Paper
|
||||
|
||||
/**
|
||||
* Adds a metadata value to an object. Each metadata value is owned by a
|
||||
@@ -46,7 +46,9 @@ public abstract class MetadataStoreBase<T> {
|
||||
entry = new WeakHashMap<Plugin, MetadataValue>(1);
|
||||
metadataMap.put(key, entry);
|
||||
}
|
||||
- entry.put(owningPlugin, newMetadataValue);
|
||||
+ synchronized (entry) {
|
||||
+ entry.put(owningPlugin, newMetadataValue);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,10 +62,11 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @see MetadataStore#getMetadata(Object, String)
|
||||
*/
|
||||
@NotNull
|
||||
- public synchronized List<MetadataValue> getMetadata(@NotNull T subject, @NotNull String metadataKey) {
|
||||
+ public List<MetadataValue> getMetadata(@NotNull T subject, @NotNull String metadataKey) { // Paper
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
- if (metadataMap.containsKey(key)) {
|
||||
- Collection<MetadataValue> values = metadataMap.get(key).values();
|
||||
+ Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||
+ if (entry != null) {
|
||||
+ Collection<MetadataValue> values = entry.values();
|
||||
return Collections.unmodifiableList(new ArrayList<MetadataValue>(values));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
@@ -78,7 +81,7 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @param metadataKey the unique metadata key being queried.
|
||||
* @return the existence of the metadataKey within subject.
|
||||
*/
|
||||
- public synchronized boolean hasMetadata(@NotNull T subject, @NotNull String metadataKey) {
|
||||
+ public boolean hasMetadata(@NotNull T subject, @NotNull String metadataKey) { // Paper
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
return metadataMap.containsKey(key);
|
||||
}
|
||||
@@ -94,17 +97,18 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @see MetadataStore#removeMetadata(Object, String,
|
||||
* org.bukkit.plugin.Plugin)
|
||||
*/
|
||||
- public synchronized void removeMetadata(@NotNull T subject, @NotNull String metadataKey, @NotNull Plugin owningPlugin) {
|
||||
+ public void removeMetadata(@NotNull T subject, @NotNull String metadataKey, @NotNull Plugin owningPlugin) { // Paper
|
||||
Preconditions.checkArgument(owningPlugin != null, "Plugin cannot be null");
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
-
|
||||
- entry.remove(owningPlugin);
|
||||
- if (entry.isEmpty()) {
|
||||
- metadataMap.remove(key);
|
||||
+ synchronized (entry) {
|
||||
+ entry.remove(owningPlugin);
|
||||
+ if (entry.isEmpty()) {
|
||||
+ metadataMap.remove(key);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +121,7 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @throws IllegalArgumentException If plugin is null
|
||||
* @see MetadataStore#invalidateAll(org.bukkit.plugin.Plugin)
|
||||
*/
|
||||
- public synchronized void invalidateAll(@NotNull Plugin owningPlugin) {
|
||||
+ public void invalidateAll(@NotNull Plugin owningPlugin) { // Paper
|
||||
Preconditions.checkArgument(owningPlugin != null, "Plugin cannot be null");
|
||||
for (Map<Plugin, MetadataValue> values : metadataMap.values()) {
|
||||
if (values.containsKey(owningPlugin)) {
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 16 Jul 2013 21:26:50 -0400
|
||||
Subject: [PATCH] Add MetadataStoreBase.removeAll(Plugin)
|
||||
|
||||
So that on reload, metadata will be cleared
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
index a0698522f01619c9d37474f4bd55a17de58fff89..a298baaa7a126515bb2802dd311f8487f3e5533f 100644
|
||||
--- a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
+++ b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
@@ -5,6 +5,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
+import java.util.Iterator; // Paper
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
@@ -130,6 +131,26 @@ public abstract class MetadataStoreBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Removes all metadata in the metadata store that originates from the
|
||||
+ * given plugin.
|
||||
+ *
|
||||
+ * @param owningPlugin the plugin requesting the invalidation.
|
||||
+ * @throws IllegalArgumentException If plugin is null
|
||||
+ */
|
||||
+ public void removeAll(@NotNull Plugin owningPlugin) {
|
||||
+ Preconditions.checkNotNull(owningPlugin, "Plugin cannot be null");
|
||||
+ for (Iterator<Map<Plugin, MetadataValue>> iterator = metadataMap.values().iterator(); iterator.hasNext(); ) {
|
||||
+ Map<Plugin, MetadataValue> values = iterator.next();
|
||||
+ if (values.containsKey(owningPlugin)) {
|
||||
+ values.remove(owningPlugin);
|
||||
+ }
|
||||
+ if (values.isEmpty()) {
|
||||
+ iterator.remove();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Creates a unique name for the object receiving metadata by combining
|
||||
* unique data from the subject with a metadataKey.
|
||||
@@ -1,98 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sat, 2 Apr 2016 05:08:36 -0400
|
||||
Subject: [PATCH] Add PlayerUseUnknownEntityEvent
|
||||
|
||||
Adds the PlayerUseUnknownEntityEvent to be used by plugins dealing with
|
||||
virtual entities/entities that are not actually known to the server.
|
||||
|
||||
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a7228e248e3d8eb2e9f011dfe2c7dd9f3f48000f
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java
|
||||
@@ -0,0 +1,82 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.bukkit.inventory.EquipmentSlot;
|
||||
+import org.bukkit.util.Vector;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents an event that is called when a player right-clicks an unknown entity.
|
||||
+ * Useful for plugins dealing with virtual entities (entities that don't actually spawned on the server).
|
||||
+ * <br>
|
||||
+ * This event may be called multiple times per interaction with different interaction hands
|
||||
+ * and with or without the clicked position.
|
||||
+ */
|
||||
+public class PlayerUseUnknownEntityEvent extends PlayerEvent {
|
||||
+
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+ private final int entityId;
|
||||
+ private final boolean attack;
|
||||
+ private final @NotNull EquipmentSlot hand;
|
||||
+ private final @Nullable Vector clickedPosition;
|
||||
+
|
||||
+ public PlayerUseUnknownEntityEvent(@NotNull Player who, int entityId, boolean attack, @NotNull EquipmentSlot hand, @Nullable Vector clickedPosition) {
|
||||
+ super(who);
|
||||
+ this.entityId = entityId;
|
||||
+ this.attack = attack;
|
||||
+ this.hand = hand;
|
||||
+ this.clickedPosition = clickedPosition;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the entity id of the unknown entity that was interacted with.
|
||||
+ *
|
||||
+ * @return the entity id of the entity that was interacted with
|
||||
+ */
|
||||
+ public int getEntityId() {
|
||||
+ return this.entityId;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns whether the interaction was an attack.
|
||||
+ *
|
||||
+ * @return true if the player is attacking the entity, false if the player is interacting with the entity
|
||||
+ */
|
||||
+ public boolean isAttack() {
|
||||
+ return this.attack;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the hand used to perform this interaction.
|
||||
+ *
|
||||
+ * @return the hand used to interact
|
||||
+ */
|
||||
+ public @NotNull EquipmentSlot getHand() {
|
||||
+ return this.hand;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the position relative to the entity that was clicked, or null if not available.
|
||||
+ * See {@link org.bukkit.event.player.PlayerInteractAtEntityEvent} for more details.
|
||||
+ *
|
||||
+ * @return the position relative to the entity that was clicked, or null if not available
|
||||
+ * @see org.bukkit.event.player.PlayerInteractAtEntityEvent
|
||||
+ */
|
||||
+ public @Nullable Vector getClickedRelativePosition() {
|
||||
+ return this.clickedPosition != null ? this.clickedPosition.clone() : null;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,290 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 13 Apr 2016 20:20:18 -0700
|
||||
Subject: [PATCH] Add handshake event to allow plugins to handle client
|
||||
handshaking logic themselves
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..59ae7bc3a0a2079fe4b3a92d777aca682a58e4e3
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
|
||||
@@ -0,0 +1,277 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.NamedTextColor;
|
||||
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+/**
|
||||
+ * This event is fired during a player handshake.
|
||||
+ *
|
||||
+ * <p>If there are no listeners listening to this event, the logic default
|
||||
+ * to your server platform will be ran.</p>
|
||||
+ *
|
||||
+ * <p>WARNING: TAMPERING WITH THIS EVENT CAN BE DANGEROUS</p>
|
||||
+ */
|
||||
+public class PlayerHandshakeEvent extends Event implements Cancellable {
|
||||
+
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+ @NotNull private final String originalHandshake;
|
||||
+ @NotNull private final String originalSocketAddressHostname;
|
||||
+ private boolean cancelled;
|
||||
+ @Nullable private String serverHostname;
|
||||
+ @Nullable private String socketAddressHostname;
|
||||
+ @Nullable private UUID uniqueId;
|
||||
+ @Nullable private String propertiesJson;
|
||||
+ private boolean failed;
|
||||
+ private Component failMessage = Component.text("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!", NamedTextColor.YELLOW);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new {@link PlayerHandshakeEvent}.
|
||||
+ *
|
||||
+ * @param originalHandshake the original handshake string
|
||||
+ * @param cancelled if this event is enabled
|
||||
+ *
|
||||
+ * @deprecated in favour of {@link PlayerHandshakeEvent(String, String, boolean)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public PlayerHandshakeEvent(@NotNull String originalHandshake, boolean cancelled) {
|
||||
+ this(originalHandshake, "127.0.0.1", cancelled);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new {@link PlayerHandshakeEvent}.
|
||||
+ *
|
||||
+ * @param originalHandshake the original handshake string
|
||||
+ * @param originalSocketAddressHostname the original socket address hostname
|
||||
+ * @param cancelled if this event is enabled
|
||||
+ */
|
||||
+ public PlayerHandshakeEvent(@NotNull String originalHandshake, @NotNull String originalSocketAddressHostname, boolean cancelled) {
|
||||
+ super(true);
|
||||
+ this.originalHandshake = originalHandshake;
|
||||
+ this.originalSocketAddressHostname = originalSocketAddressHostname;
|
||||
+ this.cancelled = cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Determines if this event is cancelled.
|
||||
+ *
|
||||
+ * <p>When this event is cancelled, custom handshake logic will not
|
||||
+ * be processed.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if this event is cancelled, {@code false} otherwise
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if this event is cancelled.
|
||||
+ *
|
||||
+ * <p>When this event is cancelled, custom handshake logic will not
|
||||
+ * be processed.</p>
|
||||
+ *
|
||||
+ * @param cancelled {@code true} if this event is cancelled, {@code false} otherwise
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancelled) {
|
||||
+ this.cancelled = cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the original handshake string.
|
||||
+ *
|
||||
+ * @return the original handshake string
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getOriginalHandshake() {
|
||||
+ return this.originalHandshake;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the original socket address hostname.
|
||||
+ *
|
||||
+ * <p>This does not include the port.</p>
|
||||
+ * <p>In cases where this event is manually fired and the plugin wasn't updated yet, the default is {@code "127.0.0.1"}.</p>
|
||||
+ *
|
||||
+ * @return the original socket address hostname
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getOriginalSocketAddressHostname() {
|
||||
+ return this.originalSocketAddressHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the server hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @return the server hostname string
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getServerHostname() {
|
||||
+ return this.serverHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the server hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @param serverHostname the server hostname string
|
||||
+ */
|
||||
+ public void setServerHostname(@NotNull String serverHostname) {
|
||||
+ this.serverHostname = serverHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the socket address hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @return the socket address hostname string
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getSocketAddressHostname() {
|
||||
+ return this.socketAddressHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the socket address hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @param socketAddressHostname the socket address hostname string
|
||||
+ */
|
||||
+ public void setSocketAddressHostname(@NotNull String socketAddressHostname) {
|
||||
+ this.socketAddressHostname = socketAddressHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the unique id.
|
||||
+ *
|
||||
+ * @return the unique id
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public UUID getUniqueId() {
|
||||
+ return this.uniqueId;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the unique id.
|
||||
+ *
|
||||
+ * @param uniqueId the unique id
|
||||
+ */
|
||||
+ public void setUniqueId(@NotNull UUID uniqueId) {
|
||||
+ this.uniqueId = uniqueId;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the profile properties.
|
||||
+ *
|
||||
+ * <p>This should be a valid JSON string.</p>
|
||||
+ *
|
||||
+ * @return the profile properties, as JSON
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getPropertiesJson() {
|
||||
+ return this.propertiesJson;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Determines if authentication failed.
|
||||
+ *
|
||||
+ * <p>When {@code true}, the client connecting will be disconnected
|
||||
+ * with the {@link #getFailMessage() fail message}.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if authentication failed, {@code false} otherwise
|
||||
+ */
|
||||
+ public boolean isFailed() {
|
||||
+ return this.failed;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if authentication failed and the client should be disconnected.
|
||||
+ *
|
||||
+ * <p>When {@code true}, the client connecting will be disconnected
|
||||
+ * with the {@link #getFailMessage() fail message}.</p>
|
||||
+ *
|
||||
+ * @param failed {@code true} if authentication failed, {@code false} otherwise
|
||||
+ */
|
||||
+ public void setFailed(boolean failed) {
|
||||
+ this.failed = failed;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the profile properties.
|
||||
+ *
|
||||
+ * <p>This should be a valid JSON string.</p>
|
||||
+ *
|
||||
+ * @param propertiesJson the profile properties, as JSON
|
||||
+ */
|
||||
+ public void setPropertiesJson(@NotNull String propertiesJson) {
|
||||
+ this.propertiesJson = propertiesJson;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @return the message to display to the client
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Component failMessage() {
|
||||
+ return this.failMessage;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @param failMessage the message to display to the client
|
||||
+ */
|
||||
+ public void failMessage(@NotNull Component failMessage) {
|
||||
+ this.failMessage = failMessage;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @return the message to display to the client
|
||||
+ * @deprecated use {@link #failMessage()}
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Deprecated
|
||||
+ public String getFailMessage() {
|
||||
+ return LegacyComponentSerializer.legacySection().serialize(this.failMessage());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @param failMessage the message to display to the client
|
||||
+ * @deprecated use {@link #failMessage(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setFailMessage(@NotNull String failMessage) {
|
||||
+ Preconditions.checkArgument(failMessage != null && !failMessage.isEmpty(), "fail message cannot be null or empty");
|
||||
+ this.failMessage(LegacyComponentSerializer.legacySection().deserialize(failMessage));
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Fri, 4 Mar 2016 03:13:18 -0500
|
||||
Subject: [PATCH] Arrow pickup rule API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/AbstractArrow.java b/src/main/java/org/bukkit/entity/AbstractArrow.java
|
||||
index 5b50a4e10e8ace8cc53ad3c8d7c3185f88d5c8db..e8e56e89e32d84af0639fe2e9b0eeabd747b6007 100644
|
||||
--- a/src/main/java/org/bukkit/entity/AbstractArrow.java
|
||||
+++ b/src/main/java/org/bukkit/entity/AbstractArrow.java
|
||||
@@ -141,4 +141,38 @@ public interface AbstractArrow extends Projectile {
|
||||
*/
|
||||
CREATIVE_ONLY
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the {@link PickupRule} for this arrow.
|
||||
+ *
|
||||
+ * <p>This is generally {@link PickupRule#ALLOWED} only if the arrow was
|
||||
+ * <b>not</b> fired from a bow with the infinity enchantment.</p>
|
||||
+ *
|
||||
+ * @return The pickup rule
|
||||
+ * @deprecated Use {@link Arrow#getPickupStatus()} as an upstream compatible replacement for this function
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default PickupRule getPickupRule() {
|
||||
+ return PickupRule.valueOf(this.getPickupStatus().name());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the rule for which players can pickup this arrow as an item.
|
||||
+ *
|
||||
+ * @param rule The pickup rule
|
||||
+ * @deprecated Use {@link Arrow#setPickupStatus(PickupStatus)} with {@link PickupStatus} as an upstream compatible replacement for this function
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default void setPickupRule(PickupRule rule) {
|
||||
+ this.setPickupStatus(PickupStatus.valueOf(rule.name()));
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ enum PickupRule {
|
||||
+ DISALLOWED,
|
||||
+ ALLOWED,
|
||||
+ CREATIVE_ONLY;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Fri, 22 Apr 2016 01:43:11 -0500
|
||||
Subject: [PATCH] EntityRegainHealthEvent isFastRegen API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java b/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java
|
||||
index 8feb6698f9630f099be99e52d1149cd6bc615197..d51d2ec1d04d9ea8a25a70d0d856f2355ebfcb4a 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java
|
||||
@@ -13,12 +13,31 @@ public class EntityRegainHealthEvent extends EntityEvent implements Cancellable
|
||||
private boolean cancelled;
|
||||
private double amount;
|
||||
private final RegainReason regainReason;
|
||||
+ private final boolean isFastRegen; // Paper
|
||||
|
||||
public EntityRegainHealthEvent(@NotNull final Entity entity, final double amount, @NotNull final RegainReason regainReason) {
|
||||
+ // Paper start - Forward
|
||||
+ this(entity, amount, regainReason, false);
|
||||
+ }
|
||||
+
|
||||
+ public EntityRegainHealthEvent(@NotNull final Entity entity, final double amount, @NotNull final RegainReason regainReason, boolean isFastRegen) {
|
||||
+ // Paper end
|
||||
super(entity);
|
||||
this.amount = amount;
|
||||
this.regainReason = regainReason;
|
||||
+ this.isFastRegen = isFastRegen; // Paper
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Add getter for isFastRegen
|
||||
+ /**
|
||||
+ * Is this event a result of the fast regeneration mechanic
|
||||
+ *
|
||||
+ * @return Whether the event is the result of a fast regeneration mechanic
|
||||
+ */
|
||||
+ public boolean isFastRegen() {
|
||||
+ return isFastRegen;
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Gets the amount of regained health
|
||||
@@ -1,422 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 1 May 2016 15:19:49 -0400
|
||||
Subject: [PATCH] LootTable API
|
||||
|
||||
Provides API to control what Loot Table an object uses.
|
||||
|
||||
Also provides an Event to control if a lootable inventory should
|
||||
auto replenish for a player.
|
||||
|
||||
Provides methods to determine players looted state for an object
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..92d7b853a2ccaae5afa8ac141bead840942944ef
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.block.Block;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Represents an Inventory that can generate loot, such as Chests inside of Fortresses and Mineshafts
|
||||
+ */
|
||||
+public interface LootableBlockInventory extends LootableInventory {
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the block that is lootable
|
||||
+ * @return The Block
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ Block getBlock();
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b387894fe8001edb41ad2ad2b70ebabe065b682e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Represents an Inventory that can generate loot, such as Minecarts inside of Mineshafts
|
||||
+ */
|
||||
+public interface LootableEntityInventory extends LootableInventory {
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the entity that is lootable
|
||||
+ * @return The Entity
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ Entity getEntity();
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2b01a50b6e18856f4c9e28340a7a111cae646a0a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
|
||||
@@ -0,0 +1,125 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.loot.Lootable;
|
||||
+
|
||||
+import java.util.UUID;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents an Inventory that contains a Loot Table associated to it that will
|
||||
+ * automatically fill on first open.
|
||||
+ *
|
||||
+ * A new feature and API is provided to support automatically refreshing the contents
|
||||
+ * of the inventory based on that Loot Table after a configurable amount of time has passed.
|
||||
+ *
|
||||
+ * The behavior of how the Inventory is filled based on the loot table may vary based
|
||||
+ * on Minecraft versions and the Loot Table feature.
|
||||
+ */
|
||||
+public interface LootableInventory extends Lootable {
|
||||
+
|
||||
+ /**
|
||||
+ * Server owners have to enable whether or not an object in a world should refill
|
||||
+ *
|
||||
+ * @return If the world this inventory is currently in has Replenishable Lootables enabled
|
||||
+ */
|
||||
+ boolean isRefillEnabled();
|
||||
+
|
||||
+ /**
|
||||
+ * Whether or not this object has ever been filled
|
||||
+ * @return Has ever been filled
|
||||
+ */
|
||||
+ boolean hasBeenFilled();
|
||||
+
|
||||
+ /**
|
||||
+ * Has this player ever looted this block
|
||||
+ * @param player The player to check
|
||||
+ * @return Whether or not this player has looted this block
|
||||
+ */
|
||||
+ default boolean hasPlayerLooted(@NotNull Player player) {
|
||||
+ return hasPlayerLooted(player.getUniqueId());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Checks if this player can loot this block. Takes into account the "restrict player reloot" settings
|
||||
+ *
|
||||
+ * @param player the player to check
|
||||
+ *
|
||||
+ * @return Whether this player can loot this block
|
||||
+ */
|
||||
+ boolean canPlayerLoot(@NotNull UUID player);
|
||||
+
|
||||
+ /**
|
||||
+ * Has this player ever looted this block
|
||||
+ * @param player The player to check
|
||||
+ * @return Whether or not this player has looted this block
|
||||
+ */
|
||||
+ boolean hasPlayerLooted(@NotNull UUID player);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp, in milliseconds, of when the player last looted this object
|
||||
+ *
|
||||
+ * @param player The player to check
|
||||
+ * @return Timestamp last looted, or null if player has not looted this object
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ default Long getLastLooted(@NotNull Player player) {
|
||||
+ return getLastLooted(player.getUniqueId());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp, in milliseconds, of when the player last looted this object
|
||||
+ *
|
||||
+ * @param player The player to check
|
||||
+ * @return Timestamp last looted, or null if player has not looted this object
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Long getLastLooted(@NotNull UUID player);
|
||||
+
|
||||
+ /**
|
||||
+ * Change the state of whether or not a player has looted this block
|
||||
+ * @param player The player to change state for
|
||||
+ * @param looted true to add player to looted list, false to remove
|
||||
+ * @return The previous state of whether the player had looted this or not
|
||||
+ */
|
||||
+ default boolean setHasPlayerLooted(@NotNull Player player, boolean looted) {
|
||||
+ return setHasPlayerLooted(player.getUniqueId(), looted);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Change the state of whether or not a player has looted this block
|
||||
+ * @param player The player to change state for
|
||||
+ * @param looted true to add player to looted list, false to remove
|
||||
+ * @return The previous state of whether the player had looted this or not
|
||||
+ */
|
||||
+ boolean setHasPlayerLooted(@NotNull UUID player, boolean looted);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns Whether or not this object has been filled and now has a pending refill
|
||||
+ * @return Has pending refill
|
||||
+ */
|
||||
+ boolean hasPendingRefill();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp in milliseconds that the Lootable object was last refilled
|
||||
+ *
|
||||
+ * @return -1 if it was never refilled, or timestamp in milliseconds
|
||||
+ */
|
||||
+ long getLastFilled();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp in milliseconds that the Lootable object will refill
|
||||
+ *
|
||||
+ * @return -1 if it is not scheduled for refill, or timestamp in milliseconds
|
||||
+ */
|
||||
+ long getNextRefill();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the timestamp in milliseconds of the next refill for this object
|
||||
+ *
|
||||
+ * @param refillAt timestamp in milliseconds. -1 to clear next refill
|
||||
+ * @return The previous scheduled time to refill, or -1 if was not scheduled
|
||||
+ */
|
||||
+ long setNextRefill(long refillAt);
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fd184f13f5e8ee5cf829fff4f44696e1f760430b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java
|
||||
@@ -0,0 +1,45 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class LootableInventoryReplenishEvent extends PlayerEvent implements Cancellable {
|
||||
+ @NotNull private final LootableInventory inventory;
|
||||
+
|
||||
+ public LootableInventoryReplenishEvent(@NotNull Player player, @NotNull LootableInventory inventory) {
|
||||
+ super(player);
|
||||
+ this.inventory = inventory;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public LootableInventory getInventory() {
|
||||
+ return inventory;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/block/Chest.java b/src/main/java/org/bukkit/block/Chest.java
|
||||
index b451191312e4fb19f2131c2d0a0c0337953f6c7c..db6affbc78106b2d93b41953b624a0bca0ca1d72 100644
|
||||
--- a/src/main/java/org/bukkit/block/Chest.java
|
||||
+++ b/src/main/java/org/bukkit/block/Chest.java
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory; // Paper
|
||||
+import org.bukkit.Nameable; // Paper
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -7,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Represents a captured state of a chest.
|
||||
*/
|
||||
-public interface Chest extends Container, Lootable, Lidded {
|
||||
+public interface Chest extends Container, LootableBlockInventory, Lidded { // Paper
|
||||
|
||||
/**
|
||||
* Gets the inventory of the chest block represented by this block state.
|
||||
diff --git a/src/main/java/org/bukkit/block/Dispenser.java b/src/main/java/org/bukkit/block/Dispenser.java
|
||||
index 74cd194c9a98245dc52e7e352d7d6c046e1e5cf3..07af1a3f011d4b96275f919d302ac367198e923e 100644
|
||||
--- a/src/main/java/org/bukkit/block/Dispenser.java
|
||||
+++ b/src/main/java/org/bukkit/block/Dispenser.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.Nameable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.bukkit.projectiles.BlockProjectileSource;
|
||||
@@ -8,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a captured state of a dispenser.
|
||||
*/
|
||||
-public interface Dispenser extends Container, Nameable, Lootable {
|
||||
+public interface Dispenser extends Container, Nameable, LootableBlockInventory { // Paper
|
||||
|
||||
/**
|
||||
* Gets the BlockProjectileSource object for the dispenser.
|
||||
diff --git a/src/main/java/org/bukkit/block/Dropper.java b/src/main/java/org/bukkit/block/Dropper.java
|
||||
index 424392fb5ed4628199b0e73689522aa3c90740cb..c76202321e29ad67597ca3017eb8d9baf6787383 100644
|
||||
--- a/src/main/java/org/bukkit/block/Dropper.java
|
||||
+++ b/src/main/java/org/bukkit/block/Dropper.java
|
||||
@@ -1,11 +1,12 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a dropper.
|
||||
*/
|
||||
-public interface Dropper extends Container, Lootable {
|
||||
+public interface Dropper extends Container, LootableBlockInventory { // Paper
|
||||
|
||||
/**
|
||||
* Tries to drop a randomly selected item from the dropper's inventory,
|
||||
diff --git a/src/main/java/org/bukkit/block/Hopper.java b/src/main/java/org/bukkit/block/Hopper.java
|
||||
index 58e493099810fb8d4705ecd49b4a5e1e1949b87b..7ade312f180b7e30871d3a3240c76325cc369c26 100644
|
||||
--- a/src/main/java/org/bukkit/block/Hopper.java
|
||||
+++ b/src/main/java/org/bukkit/block/Hopper.java
|
||||
@@ -1,8 +1,9 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a hopper.
|
||||
*/
|
||||
-public interface Hopper extends Container, Lootable { }
|
||||
+public interface Hopper extends Container, LootableBlockInventory { } // Paper
|
||||
diff --git a/src/main/java/org/bukkit/block/ShulkerBox.java b/src/main/java/org/bukkit/block/ShulkerBox.java
|
||||
index 387b2892886e1ccb2bd928e5111fb9bd41d777ab..5dc5318b0a451937228a8a059dfec1cd9de389a6 100644
|
||||
--- a/src/main/java/org/bukkit/block/ShulkerBox.java
|
||||
+++ b/src/main/java/org/bukkit/block/ShulkerBox.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a captured state of a ShulkerBox.
|
||||
*/
|
||||
-public interface ShulkerBox extends Container, Lootable, Lidded {
|
||||
+public interface ShulkerBox extends Container, LootableBlockInventory, Lidded { // Paper
|
||||
|
||||
/**
|
||||
* Get the {@link DyeColor} corresponding to this ShulkerBox
|
||||
diff --git a/src/main/java/org/bukkit/entity/ChestBoat.java b/src/main/java/org/bukkit/entity/ChestBoat.java
|
||||
index 5b5c3be107fdaa6c55ceb1bca2c223ebc6ab7f43..4ebe1033c55dbd58d0794809435c935236fabcc2 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ChestBoat.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ChestBoat.java
|
||||
@@ -6,5 +6,5 @@ import org.bukkit.loot.Lootable;
|
||||
/**
|
||||
* A {@link Boat} with a chest.
|
||||
*/
|
||||
-public interface ChestBoat extends Boat, InventoryHolder, Lootable {
|
||||
+public interface ChestBoat extends Boat, InventoryHolder, com.destroystokyo.paper.loottable.LootableEntityInventory { // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java b/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
|
||||
index 937b99f8734d71b2ad33af142afbc251b81d9745..db69687a7ad4b18d17ab1677cae5d8dd4dcd3678 100644
|
||||
--- a/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
|
||||
+++ b/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.entity.minecart;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableEntityInventory;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.loot.Lootable;
|
||||
@@ -7,7 +8,7 @@ import org.bukkit.loot.Lootable;
|
||||
/**
|
||||
* Represents a Minecart with a Hopper inside it
|
||||
*/
|
||||
-public interface HopperMinecart extends Minecart, InventoryHolder, Lootable {
|
||||
+public interface HopperMinecart extends Minecart, InventoryHolder, LootableEntityInventory {
|
||||
|
||||
/**
|
||||
* Checks whether or not this Minecart will pick up
|
||||
diff --git a/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java b/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java
|
||||
index 9ea403e6fd8e960d017660e0aec118abeda2c42b..238d118f7788b13cd86b7e9ea3a0fc38e2e09715 100644
|
||||
--- a/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java
|
||||
+++ b/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.entity.minecart;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableEntityInventory;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.loot.Lootable;
|
||||
@@ -9,5 +10,5 @@ import org.bukkit.loot.Lootable;
|
||||
* minecarts} have their own inventory that can be accessed using methods
|
||||
* from the {@link InventoryHolder} interface.
|
||||
*/
|
||||
-public interface StorageMinecart extends Minecart, InventoryHolder, Lootable {
|
||||
+public interface StorageMinecart extends Minecart, InventoryHolder, LootableEntityInventory { // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/loot/Lootable.java b/src/main/java/org/bukkit/loot/Lootable.java
|
||||
index 24a3d989db3bc67e7afe8459a3d4bb132f448ea7..901db852498e0658c79a57582508dab29bf0a798 100644
|
||||
--- a/src/main/java/org/bukkit/loot/Lootable.java
|
||||
+++ b/src/main/java/org/bukkit/loot/Lootable.java
|
||||
@@ -36,6 +36,34 @@ public interface Lootable {
|
||||
@Nullable
|
||||
LootTable getLootTable();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Set the loot table and seed for a container or entity at the same time.
|
||||
+ *
|
||||
+ * @param table the Loot Table this {@link org.bukkit.block.Container} or {@link org.bukkit.entity.Mob} will have.
|
||||
+ * @param seed the seed to used to generate loot. Default is 0.
|
||||
+ */
|
||||
+ default void setLootTable(@Nullable LootTable table, long seed) {
|
||||
+ setLootTable(table);
|
||||
+ setSeed(seed);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns whether or not this object has a Loot Table
|
||||
+ * @return Has a loot table
|
||||
+ */
|
||||
+ default boolean hasLootTable() {
|
||||
+ return getLootTable() != null;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Clears the associated Loot Table to this object
|
||||
+ */
|
||||
+ default void clearLootTable() {
|
||||
+ setLootTable(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Set the seed used when this Loot Table generates loot.
|
||||
*
|
||||
@@ -1,122 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AlphaBlend <whizkid3000@hotmail.com>
|
||||
Date: Sun, 16 Oct 2016 23:19:34 -0700
|
||||
Subject: [PATCH] Add EntityZapEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1c5fa066c9e5e1b1a06df30842a4c7acc4742df8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java
|
||||
@@ -0,0 +1,64 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.LightningStrike;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityTransformEvent;
|
||||
+
|
||||
+import java.util.Collections;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when lightning strikes an entity
|
||||
+ */
|
||||
+public class EntityZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+ @NotNull private final LightningStrike bolt;
|
||||
+
|
||||
+ public EntityZapEvent(@NotNull final Entity entity, @NotNull final LightningStrike bolt, @NotNull final Entity replacementEntity) {
|
||||
+ super(entity, Collections.singletonList(replacementEntity), TransformReason.LIGHTNING);
|
||||
+ Preconditions.checkNotNull(bolt);
|
||||
+ Preconditions.checkNotNull(replacementEntity);
|
||||
+ this.bolt = bolt;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the lightning bolt that is striking the entity.
|
||||
+ * @return The lightning bolt responsible for this event
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public LightningStrike getBolt() {
|
||||
+ return bolt;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the entity that will replace the struck entity.
|
||||
+ * @return The entity that will replace the struck entity
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Entity getReplacementEntity() {
|
||||
+ return getTransformedEntity();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/PigZapEvent.java b/src/main/java/org/bukkit/event/entity/PigZapEvent.java
|
||||
index 0e0ed93b568fd2c0d8f6e359c31dc29cb0fa71c2..d3949edfc736b3d67a627ef378748b374769e183 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/PigZapEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/PigZapEvent.java
|
||||
@@ -2,6 +2,7 @@ package org.bukkit.event.entity;
|
||||
|
||||
import java.util.Collections;
|
||||
import org.bukkit.entity.Entity;
|
||||
+import com.destroystokyo.paper.event.entity.EntityZapEvent;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.entity.PigZombie;
|
||||
@@ -12,14 +13,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Stores data for pigs being zapped
|
||||
*/
|
||||
-public class PigZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
- private static final HandlerList handlers = new HandlerList();
|
||||
+public class PigZapEvent extends EntityZapEvent implements Cancellable {
|
||||
+ //private static final HandlerList handlers = new HandlerList();
|
||||
private boolean canceled;
|
||||
private final PigZombie pigzombie;
|
||||
private final LightningStrike bolt;
|
||||
|
||||
public PigZapEvent(@NotNull final Pig pig, @NotNull final LightningStrike bolt, @NotNull final PigZombie pigzombie) {
|
||||
- super(pig, Collections.singletonList((Entity) pigzombie), TransformReason.LIGHTNING);
|
||||
+ super(pig, bolt, pigzombie);
|
||||
this.bolt = bolt;
|
||||
this.pigzombie = pigzombie;
|
||||
}
|
||||
@@ -63,6 +64,8 @@ public class PigZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
return pigzombie;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /*
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
@@ -73,4 +76,6 @@ public class PigZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: vemacs <d@nkmem.es>
|
||||
Date: Wed, 23 Nov 2016 12:53:43 -0500
|
||||
Subject: [PATCH] Misc Utils
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/utils/CachedSizeConcurrentLinkedQueue.java b/src/main/java/com/destroystokyo/paper/utils/CachedSizeConcurrentLinkedQueue.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5bb677ce585b856b3d3e589e29786a29619c56a7
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/utils/CachedSizeConcurrentLinkedQueue.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package com.destroystokyo.paper.utils;
|
||||
+
|
||||
+import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
+import java.util.concurrent.atomic.LongAdder;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public class CachedSizeConcurrentLinkedQueue<E> extends ConcurrentLinkedQueue<E> {
|
||||
+ private final LongAdder cachedSize = new LongAdder();
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean add(@NotNull E e) {
|
||||
+ boolean result = super.add(e);
|
||||
+ if (result) {
|
||||
+ cachedSize.increment();
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public E poll() {
|
||||
+ E result = super.poll();
|
||||
+ if (result != null) {
|
||||
+ cachedSize.decrement();
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int size() {
|
||||
+ return cachedSize.intValue();
|
||||
+ }
|
||||
+}
|
||||
@@ -1,108 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Mon, 28 Nov 2016 10:16:39 -0500
|
||||
Subject: [PATCH] Allow Reloading of Command Aliases
|
||||
|
||||
Reload the aliases stored in commands.yml
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 540c57e82247eaad2cae1ab0199caf2a6cabcab1..abbafce790d30bab81b40c6c973d21f09d3d24ef 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -2207,6 +2207,15 @@ public final class Bukkit {
|
||||
public static void reloadPermissions() {
|
||||
server.reloadPermissions();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Reload the Command Aliases in commands.yml
|
||||
+ *
|
||||
+ * @return Whether the reload was successful
|
||||
+ */
|
||||
+ public static boolean reloadCommandAliases() {
|
||||
+ return server.reloadCommandAliases();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index f3452f65e6b69e8a2f0942c7a6afb9837a6d88fd..925e3e32bf971efc08fd39d1e10d83bb0c6e8634 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1945,4 +1945,6 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
// Spigot end
|
||||
|
||||
void reloadPermissions(); // Paper
|
||||
+
|
||||
+ boolean reloadCommandAliases(); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/CommandMap.java b/src/main/java/org/bukkit/command/CommandMap.java
|
||||
index bd2c7a6964722412148fae39e1b4951fc0002b9b..864c263bbd4dd6dd7c37a74b39b1a40a884d0731 100644
|
||||
--- a/src/main/java/org/bukkit/command/CommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/CommandMap.java
|
||||
@@ -128,4 +128,14 @@ public interface CommandMap {
|
||||
*/
|
||||
@Nullable
|
||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String cmdLine, @Nullable Location location) throws IllegalArgumentException;
|
||||
+
|
||||
+ // Paper start - Expose Known Commands
|
||||
+ /**
|
||||
+ * Return a Map of known commands
|
||||
+ *
|
||||
+ * @return known commands
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public java.util.Map<String, Command> getKnownCommands();
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
index b3b32ce429edbf1ed040354dbe28ab86f0d24201..1424060c0a162020d4a680e0a592224561067b16 100644
|
||||
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
@@ -293,4 +293,11 @@ public class SimpleCommandMap implements CommandMap {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - Expose Known Commands
|
||||
+ @NotNull
|
||||
+ public Map<String, Command> getKnownCommands() {
|
||||
+ return knownCommands;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
index 5fa9d648bc780e874f658597f1a24715bccac5cb..3ec32b46264cfff857b50129b5e0fa5584943ec6 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
@@ -13,7 +13,7 @@ public class ReloadCommand extends BukkitCommand {
|
||||
public ReloadCommand(@NotNull String name) {
|
||||
super(name);
|
||||
this.description = "Reloads the server configuration and plugins";
|
||||
- this.usageMessage = "/reload [permissions]"; // Paper
|
||||
+ this.usageMessage = "/reload [permissions|commands|confirm]"; // Paper
|
||||
this.setPermission("bukkit.command.reload");
|
||||
this.setAliases(Arrays.asList("rl"));
|
||||
}
|
||||
@@ -29,6 +29,13 @@ public class ReloadCommand extends BukkitCommand {
|
||||
Bukkit.getServer().reloadPermissions();
|
||||
Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Permissions successfully reloaded.", net.kyori.adventure.text.format.NamedTextColor.GREEN));
|
||||
return true;
|
||||
+ } else if ("commands".equalsIgnoreCase(args[0])) {
|
||||
+ if (Bukkit.getServer().reloadCommandAliases()) {
|
||||
+ Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("Command aliases successfully reloaded.", net.kyori.adventure.text.format.NamedTextColor.GREEN));
|
||||
+ } else {
|
||||
+ Command.broadcastCommandMessage(sender, net.kyori.adventure.text.Component.text("An error occurred while trying to reload command aliases.", net.kyori.adventure.text.format.NamedTextColor.RED));
|
||||
+ }
|
||||
+ return true;
|
||||
} else if ("confirm".equalsIgnoreCase(args[0])) {
|
||||
confirmed = true;
|
||||
} else {
|
||||
@@ -53,6 +60,6 @@ public class ReloadCommand extends BukkitCommand {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
|
||||
- return java.util.Collections.singletonList("permissions"); // Paper
|
||||
+ return com.google.common.collect.Lists.newArrayList("permissions", "commands"); // Paper
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AlphaBlend <whizkid3000@hotmail.com>
|
||||
Date: Thu, 8 Sep 2016 08:47:08 -0700
|
||||
Subject: [PATCH] Add source to PlayerExpChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java b/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java
|
||||
index c99c9281e98e4b510dddb711b8785bcd56b3b92f..7c340f539c31a431d7d9204a8135e0bfc31863a8 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java
|
||||
@@ -1,21 +1,43 @@
|
||||
package org.bukkit.event.player;
|
||||
|
||||
+import org.bukkit.entity.Entity; // Paper
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+import org.jetbrains.annotations.Nullable; // Paper
|
||||
+
|
||||
/**
|
||||
* Called when a players experience changes naturally
|
||||
*/
|
||||
public class PlayerExpChangeEvent extends PlayerEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
+ // Paper start
|
||||
+ @Nullable
|
||||
+ private final Entity source;
|
||||
private int exp;
|
||||
|
||||
public PlayerExpChangeEvent(@NotNull final Player player, final int expAmount) {
|
||||
+ this(player, null, expAmount);
|
||||
+ }
|
||||
+
|
||||
+ public PlayerExpChangeEvent(@NotNull final Player player, @Nullable final Entity sourceEntity, final int expAmount) {
|
||||
super(player);
|
||||
+ source = sourceEntity;
|
||||
exp = expAmount;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Get the source that provided the experience.
|
||||
+ *
|
||||
+ * @return The source of the experience
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity getSource() {
|
||||
+ return source;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get the amount of experience the player will receive
|
||||
*
|
||||
@@ -1,82 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Fri, 16 Dec 2016 21:25:39 -0600
|
||||
Subject: [PATCH] Add ProjectileCollideEvent
|
||||
|
||||
Now deprecated and replaced with ProjectileHitEvent
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/ProjectileCollideEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/ProjectileCollideEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6ae2bc3d952d34f298220738856024e0b6594199
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/ProjectileCollideEvent.java
|
||||
@@ -0,0 +1,69 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.Projectile;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a projectile collides with an entity
|
||||
+ * <p>
|
||||
+ * This event is called <b>before</b> {@link org.bukkit.event.entity.EntityDamageByEntityEvent}, and cancelling it will allow the projectile to continue flying
|
||||
+ * @deprecated Deprecated, use {@link org.bukkit.event.entity.ProjectileHitEvent} and check if there is a hit entity
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public class ProjectileCollideEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final Entity collidedWith;
|
||||
+
|
||||
+ /**
|
||||
+ * Get the entity the projectile collided with
|
||||
+ *
|
||||
+ * @return the entity collided with
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Entity getCollidedWith() {
|
||||
+ return collidedWith;
|
||||
+ }
|
||||
+
|
||||
+ public ProjectileCollideEvent(@NotNull Projectile what, @NotNull Entity collidedWith) {
|
||||
+ super(what);
|
||||
+ this.collidedWith = collidedWith;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the projectile that collided
|
||||
+ *
|
||||
+ * @return the projectile that collided
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Projectile getEntity() {
|
||||
+ return (Projectile) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlerList = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlerList;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlerList;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,62 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 20 Dec 2016 15:55:55 -0500
|
||||
Subject: [PATCH] Add String based Action Bar API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 967ea421aed7f9d4c8edd366c00cf3ceca723b2f..87b67723cb9dcead110eb88dd741d3348eb9ec1b 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -1042,6 +1042,39 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
public void sendMap(@NotNull MapView map);
|
||||
|
||||
// Paper start
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an Action Bar message to the client.
|
||||
+ *
|
||||
+ * Use Section symbols for legacy color codes to send formatting.
|
||||
+ *
|
||||
+ * @param message The message to send
|
||||
+ * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(@NotNull String message);
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an Action Bar message to the client.
|
||||
+ *
|
||||
+ * Use supplied alternative character to the section symbol to represent legacy color codes.
|
||||
+ *
|
||||
+ * @param alternateChar Alternate symbol such as '&'
|
||||
+ * @param message The message to send
|
||||
+ * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(char alternateChar, @NotNull String message);
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an Action Bar message to the client.
|
||||
+ *
|
||||
+ * @param message The components to send
|
||||
+ * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(@NotNull net.md_5.bungee.api.chat.BaseComponent... message);
|
||||
+
|
||||
/**
|
||||
* Sends the component to the player
|
||||
*
|
||||
@@ -1069,9 +1102,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
/**
|
||||
* Sends an array of components as a single message to the specified screen position of this player
|
||||
*
|
||||
+ * @deprecated This is unlikely the API you want to use. See {@link #sendActionBar(String)} for a more proper Action Bar API. This deprecated API may send unsafe items to the client.
|
||||
* @param position the screen position
|
||||
* @param components the components to send
|
||||
*/
|
||||
+ @Deprecated
|
||||
public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
spigot().sendMessage(position, components);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 21 Dec 2016 11:47:25 -0600
|
||||
Subject: [PATCH] Add API methods to control if armour stands can move
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/ArmorStand.java b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
index dc604d6ab9dcf67fa0791539d18c2f890a814ed8..91fc11dda99de506be83d40df8929bf7cd8e8d85 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
@@ -344,4 +344,21 @@ public interface ArmorStand extends LivingEntity {
|
||||
*/
|
||||
ADDING;
|
||||
}
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Tests if this armor stand can move.
|
||||
+ *
|
||||
+ * <p>The default value is {@code true}.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if this armour stand can move, {@code false} otherwise
|
||||
+ */
|
||||
+ boolean canMove();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if this armor stand can move.
|
||||
+ *
|
||||
+ * @param move {@code true} if this armour stand can move, {@code false} otherwise
|
||||
+ */
|
||||
+ void setCanMove(boolean move);
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 4 Dec 2016 01:19:14 -0500
|
||||
Subject: [PATCH] IllegalPacketEvent
|
||||
|
||||
Fire an event when an illegal packet is received to let plugins handle it
|
||||
|
||||
Lets plugins change the kick message and if it should kick or not.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java b/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8d8e9b16f2a6707d2af7567c7682dfc5db51a737
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java
|
||||
@@ -0,0 +1,74 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * @deprecated Not used
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public class IllegalPacketEvent extends PlayerEvent {
|
||||
+ @Nullable private final String type;
|
||||
+ @Nullable private final String ex;
|
||||
+ @Nullable private String kickMessage;
|
||||
+ private boolean shouldKick = true;
|
||||
+
|
||||
+ public IllegalPacketEvent(@NotNull Player player, @Nullable String type, @Nullable String kickMessage, @NotNull Exception e) {
|
||||
+ super(player);
|
||||
+ this.type = type;
|
||||
+ this.kickMessage = kickMessage;
|
||||
+ this.ex = e.getMessage();
|
||||
+ }
|
||||
+
|
||||
+ public boolean isShouldKick() {
|
||||
+ return shouldKick;
|
||||
+ }
|
||||
+
|
||||
+ public void setShouldKick(boolean shouldKick) {
|
||||
+ this.shouldKick = shouldKick;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public String getKickMessage() {
|
||||
+ return kickMessage;
|
||||
+ }
|
||||
+
|
||||
+ public void setKickMessage(@Nullable String kickMessage) {
|
||||
+ this.kickMessage = kickMessage;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public String getType() {
|
||||
+ return type;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public String getExceptionMessage() {
|
||||
+ return ex;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public static void process(@NotNull Player player, @Nullable String type, @Nullable String kickMessage, @NotNull Exception exception) {
|
||||
+ IllegalPacketEvent event = new IllegalPacketEvent(player, type, kickMessage, exception);
|
||||
+ event.callEvent();
|
||||
+ if (event.shouldKick) {
|
||||
+ player.kickPlayer(kickMessage);
|
||||
+ }
|
||||
+ Bukkit.getLogger().severe(player.getName() + "/" + type + ": " + exception.getMessage());
|
||||
+ }
|
||||
+}
|
||||
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 28 Dec 2016 01:18:55 -0500
|
||||
Subject: [PATCH] Fireworks API's
|
||||
|
||||
Get the Entity being boosted
|
||||
Get the firework launcher
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Firework.java b/src/main/java/org/bukkit/entity/Firework.java
|
||||
index e750b34d7d067a5f2f5587853274b6f479cc4fd6..0d31aa0b22cf1e849572294e2cfe38b48c9210af 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Firework.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Firework.java
|
||||
@@ -111,4 +111,20 @@ public interface Firework extends Projectile {
|
||||
* @param shotAtAngle the new shotAtAngle
|
||||
*/
|
||||
void setShotAtAngle(boolean shotAtAngle);
|
||||
+
|
||||
+ // Paper start
|
||||
+ @org.jetbrains.annotations.Nullable
|
||||
+ public java.util.UUID getSpawningEntity();
|
||||
+ /**
|
||||
+ * If this firework is boosting an entity, return it
|
||||
+ * @deprecated use {@link #getAttachedTo()}
|
||||
+ * @see #setAttachedTo(LivingEntity)
|
||||
+ * @return The entity being boosted
|
||||
+ */
|
||||
+ @org.jetbrains.annotations.Nullable
|
||||
+ @Deprecated
|
||||
+ default LivingEntity getBoostedEntity() {
|
||||
+ return getAttachedTo();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 31 Dec 2016 20:29:33 -0500
|
||||
Subject: [PATCH] PlayerTeleportEndGatewayEvent
|
||||
|
||||
Allows you to access the Gateway being used in a teleport event
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b64ab6eecd8bc4ca9c109b9d83c82861d6260793
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java
|
||||
@@ -0,0 +1,29 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.block.EndGateway;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when a teleport is triggered for an End Gateway
|
||||
+ */
|
||||
+public class PlayerTeleportEndGatewayEvent extends PlayerTeleportEvent {
|
||||
+ @NotNull private final EndGateway gateway;
|
||||
+
|
||||
+ public PlayerTeleportEndGatewayEvent(@NotNull Player player, @NotNull Location from, @NotNull Location to, @NotNull EndGateway gateway) {
|
||||
+ super(player, from, to, PlayerTeleportEvent.TeleportCause.END_GATEWAY);
|
||||
+ this.gateway = gateway;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The gateway triggering the teleport
|
||||
+ *
|
||||
+ * @return EndGateway used
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public EndGateway getGateway() {
|
||||
+ return gateway;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 7 Jan 2017 15:23:03 -0500
|
||||
Subject: [PATCH] Provide E/TE/Chunk count stat methods
|
||||
|
||||
Provides counts without the ineffeciency of using .getEntities().size()
|
||||
which creates copy of the collections.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 887aa6217583d224d66f6d238ac269c23725d459..4ef6bbfa753da439ac57bd8d70dd114d73665c8d 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -46,6 +46,33 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient, Metadatable, PersistentDataHolder, Keyed, net.kyori.adventure.audience.ForwardingAudience { // Paper
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * @return The amount of Entities in this world
|
||||
+ */
|
||||
+ int getEntityCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Tile Entities in this world
|
||||
+ */
|
||||
+ int getTileEntityCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Tickable Tile Entities in this world
|
||||
+ */
|
||||
+ int getTickableTileEntityCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Chunks in this world
|
||||
+ */
|
||||
+ int getChunkCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Players in this world
|
||||
+ */
|
||||
+ int getPlayerCount();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the {@link Block} at the given coordinates
|
||||
*
|
||||
@@ -1,122 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 16:28:32 -0500
|
||||
Subject: [PATCH] ExperienceOrbs API for Reason/Source/Triggering player
|
||||
|
||||
Adds lots of information about why this orb exists.
|
||||
|
||||
Replaces isFromBottle() with logic that persists entity reloads too.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/ExperienceOrb.java b/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||
index c286edfd827e185a76e44c44faace19a80325d7a..dec70bbfaf73a9d525b2c45682b804c684e1645b 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable; // Paper
|
||||
+
|
||||
/**
|
||||
* Represents an Experience Orb.
|
||||
*/
|
||||
@@ -18,4 +21,99 @@ public interface ExperienceOrb extends Entity {
|
||||
* @param value Amount of experience
|
||||
*/
|
||||
public void setExperience(int value);
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Check if this orb was spawned from a {@link ThrownExpBottle}
|
||||
+ *
|
||||
+ * @return if orb was spawned from a bottle
|
||||
+ * @deprecated Use getSpawnReason() == EXP_BOTTLE
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default boolean isFromBottle() {
|
||||
+ return getSpawnReason() == SpawnReason.EXP_BOTTLE;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Reasons for why this Experience Orb was spawned
|
||||
+ */
|
||||
+ enum SpawnReason {
|
||||
+ /**
|
||||
+ * Spawned by a player dying
|
||||
+ */
|
||||
+ PLAYER_DEATH,
|
||||
+ /**
|
||||
+ * Spawned by an entity dying after being damaged by a player
|
||||
+ */
|
||||
+ ENTITY_DEATH,
|
||||
+ /**
|
||||
+ * Spawned by player using a furnace
|
||||
+ */
|
||||
+ FURNACE,
|
||||
+ /**
|
||||
+ * Spawned by player breeding animals
|
||||
+ */
|
||||
+ BREED,
|
||||
+ /**
|
||||
+ * Spawned by player trading with a villager
|
||||
+ */
|
||||
+ VILLAGER_TRADE,
|
||||
+ /**
|
||||
+ * Spawned by player fishing
|
||||
+ */
|
||||
+ FISHING,
|
||||
+ /**
|
||||
+ * Spawned by player breaking a block that gives experience points such as Diamond Ore
|
||||
+ */
|
||||
+ BLOCK_BREAK,
|
||||
+ /**
|
||||
+ * Spawned by Bukkit API
|
||||
+ */
|
||||
+ CUSTOM,
|
||||
+ /**
|
||||
+ * Spawned by a player throwing an experience points bottle
|
||||
+ */
|
||||
+ EXP_BOTTLE,
|
||||
+ /**
|
||||
+ * Spawned by a player using a grindstone
|
||||
+ */
|
||||
+ GRINDSTONE,
|
||||
+ /**
|
||||
+ * We do not know why it was spawned
|
||||
+ */
|
||||
+ UNKNOWN
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If this experience orb was triggered to be spawned by
|
||||
+ * an entity such as a player, due to events such as killing entity,
|
||||
+ * breaking blocks, smelting in a furnace, etc, this will return the UUID
|
||||
+ * of the entity that triggered this orb to drop.
|
||||
+ *
|
||||
+ * In the case of an entity being killed, this will be the killers UUID.
|
||||
+ *
|
||||
+ * @return UUID of the player that triggered this orb to drop, or null if unknown/no triggering entity
|
||||
+ */
|
||||
+ @Nullable java.util.UUID getTriggerEntityId();
|
||||
+
|
||||
+ /**
|
||||
+ * If this experience orb was spawned in relation to another
|
||||
+ * entity, such as a player or other living entity death, or breeding,
|
||||
+ * return the source entity UUID.
|
||||
+ *
|
||||
+ * In the case of breeding, this will be the new baby entities UUID.
|
||||
+ * In the case of an entity being killed, this will be the dead entities UUID.
|
||||
+ *
|
||||
+ * @return The UUID of the entity that sourced this experience orb
|
||||
+ */
|
||||
+ @Nullable java.util.UUID getSourceEntityId();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the reason that this experience orb was spawned. For any case that we
|
||||
+ * do not know, such as orbs spawned before this API was added, UNKNOWN is returned.
|
||||
+ * @return The reason for this orb being spawned.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ SpawnReason getSpawnReason();
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sat, 21 Jan 2017 17:03:10 -0600
|
||||
Subject: [PATCH] Expose WorldBorder#isInBounds(Location) check
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/WorldBorder.java b/src/main/java/org/bukkit/WorldBorder.java
|
||||
index b1c08a7fc5856bcc29ee64d0a87b95a8ac940ddc..3ab5700b0b13fbfbf7c5b0b2c4a90bcc1e0a2d9c 100644
|
||||
--- a/src/main/java/org/bukkit/WorldBorder.java
|
||||
+++ b/src/main/java/org/bukkit/WorldBorder.java
|
||||
@@ -162,4 +162,18 @@ public interface WorldBorder {
|
||||
* @return The absolute maximum center coordinate of the WorldBorder
|
||||
*/
|
||||
public double getMaxCenterCoordinate();
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Checks if the location is within the boundaries of this border.
|
||||
+ *
|
||||
+ * @param location specific location to check
|
||||
+ * @return true if the location is within the bounds of this border, false otherwise.
|
||||
+ * @deprecated use {@link #isInside(Location)} for an upstream compatible replacement
|
||||
+ */
|
||||
+ @Deprecated(forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.21")
|
||||
+ public default boolean isInBounds(@NotNull Location location) {
|
||||
+ return this.isInside(location);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Fri, 9 Jun 2017 07:24:24 -0700
|
||||
Subject: [PATCH] Add configuration option to prevent player names from being
|
||||
suggested
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index abbafce790d30bab81b40c6c973d21f09d3d24ef..4665d42f167d587ec3edaf6432eef0a5a883401f 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -2216,6 +2216,16 @@ public final class Bukkit {
|
||||
public static boolean reloadCommandAliases() {
|
||||
return server.reloadCommandAliases();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Checks if player names should be suggested when a command returns {@code null} as
|
||||
+ * their tab completion result.
|
||||
+ *
|
||||
+ * @return true if player names should be suggested
|
||||
+ */
|
||||
+ public static boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||
+ return server.suggestPlayerNamesWhenNullTabCompletions();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 925e3e32bf971efc08fd39d1e10d83bb0c6e8634..7b95c1049ec365b8a1c20e5e18f6a79d4042fa38 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1947,4 +1947,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
void reloadPermissions(); // Paper
|
||||
|
||||
boolean reloadCommandAliases(); // Paper
|
||||
+
|
||||
+ // Paper start - allow preventing player name suggestions by default
|
||||
+ /**
|
||||
+ * Checks if player names should be suggested when a command returns {@code null} as
|
||||
+ * their tab completion result.
|
||||
+ *
|
||||
+ * @return true if player names should be suggested
|
||||
+ */
|
||||
+ boolean suggestPlayerNamesWhenNullTabCompletions();
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
|
||||
index 5cfd88eec9bf02e83d77b6fce1a5c14b7687f48b..1c6205cc667bbec8f6aca479f13b3e9cfcd63ab2 100644
|
||||
--- a/src/main/java/org/bukkit/command/Command.java
|
||||
+++ b/src/main/java/org/bukkit/command/Command.java
|
||||
@@ -99,7 +99,7 @@ public abstract class Command {
|
||||
Preconditions.checkArgument(args != null, "Arguments cannot be null");
|
||||
Preconditions.checkArgument(alias != null, "Alias cannot be null");
|
||||
|
||||
- if (args.length == 0) {
|
||||
+ if (args.length == 0 || !sender.getServer().suggestPlayerNamesWhenNullTabCompletions()) { // Paper - allow preventing player name suggestions by default) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 5 May 2017 03:57:08 -0500
|
||||
Subject: [PATCH] Item#canEntityPickup
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Item.java b/src/main/java/org/bukkit/entity/Item.java
|
||||
index 65dd4554c6cc0801fcbc0ef6809b794dcebd1124..ab06c640cef1309ab44b0fae8d95df48cdc869a7 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Item.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Item.java
|
||||
@@ -89,4 +89,20 @@ public interface Item extends Entity {
|
||||
*/
|
||||
@Nullable
|
||||
public UUID getThrower();
|
||||
+
|
||||
+ // Paper Start
|
||||
+ /**
|
||||
+ * Gets if non-player entities can pick this Item up
|
||||
+ *
|
||||
+ * @return True if non-player entities can pickup
|
||||
+ */
|
||||
+ public boolean canMobPickup();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if non-player entities can pick this Item up
|
||||
+ *
|
||||
+ * @param canMobPickup True to allow non-player entity pickup
|
||||
+ */
|
||||
+ public void setCanMobPickup(boolean canMobPickup);
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 11 Jun 2017 16:30:37 -0500
|
||||
Subject: [PATCH] PlayerAttemptPickupItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java b/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0788153a9641e75da565d2e6eee37eeee1cbc61e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java
|
||||
@@ -0,0 +1,90 @@
|
||||
+package org.bukkit.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Item;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a player attempts to pick an item up from the ground
|
||||
+ */
|
||||
+public class PlayerAttemptPickupItemEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private final Item item;
|
||||
+ private final int remaining;
|
||||
+ private boolean flyAtPlayer = true;
|
||||
+ private boolean isCancelled = false;
|
||||
+
|
||||
+ @Deprecated // Remove in 1.13 // Remove in 1.14?
|
||||
+ public PlayerAttemptPickupItemEvent(@NotNull final Player player, @NotNull final Item item) {
|
||||
+ this(player, item, 0);
|
||||
+ }
|
||||
+
|
||||
+ public PlayerAttemptPickupItemEvent(@NotNull final Player player, @NotNull final Item item, final int remaining) {
|
||||
+ super(player);
|
||||
+ this.item = item;
|
||||
+ this.remaining = remaining;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the Item attempted by the player.
|
||||
+ *
|
||||
+ * @return Item
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Item getItem() {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the amount that will remain on the ground, if any
|
||||
+ *
|
||||
+ * @return amount that will remain on the ground
|
||||
+ */
|
||||
+ public int getRemaining() {
|
||||
+ return remaining;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set if the item will fly at the player
|
||||
+ * <p>Cancelling the event will set this value to false.</p>
|
||||
+ *
|
||||
+ * @param flyAtPlayer True for item to fly at player
|
||||
+ */
|
||||
+ public void setFlyAtPlayer(boolean flyAtPlayer) {
|
||||
+ this.flyAtPlayer = flyAtPlayer;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets if the item will fly at the player
|
||||
+ *
|
||||
+ * @return True if the item will fly at the player
|
||||
+ */
|
||||
+ public boolean getFlyAtPlayer() {
|
||||
+ return this.flyAtPlayer;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.isCancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.isCancelled = cancel;
|
||||
+ this.flyAtPlayer = !cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
@@ -1,122 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sweepyoface <github@sweepy.pw>
|
||||
Date: Sat, 17 Jun 2017 18:48:06 -0400
|
||||
Subject: [PATCH] Add UnknownCommandEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java b/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e4f8a0d14ae66468bbb0a5d6bf9c1ee417dc866c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java
|
||||
@@ -0,0 +1,110 @@
|
||||
+package org.bukkit.event.command;
|
||||
+
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a player executes a command that is not defined
|
||||
+ */
|
||||
+public class UnknownCommandEvent extends Event {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private CommandSender sender;
|
||||
+ @NotNull private String commandLine;
|
||||
+ @Nullable private Component message;
|
||||
+
|
||||
+ public UnknownCommandEvent(@NotNull final CommandSender sender, @NotNull final String commandLine, @Nullable final Component message) {
|
||||
+ super(false);
|
||||
+ this.sender = sender;
|
||||
+ this.commandLine = commandLine;
|
||||
+ this.message = message;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the CommandSender or ConsoleCommandSender
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Sender of the command
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public CommandSender getSender() {
|
||||
+ return sender;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the command that was send
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Command sent
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getCommandLine() {
|
||||
+ return commandLine;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets message that will be returned
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Unknown command message
|
||||
+ * @deprecated use {@link #message()}
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ @Deprecated
|
||||
+ public String getMessage() {
|
||||
+ return this.message == null ? null : LegacyComponentSerializer.legacySection().serialize(this.message);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets message that will be returned
|
||||
+ * <p>
|
||||
+ * Set to null to avoid any message being sent
|
||||
+ *
|
||||
+ * @param message the message to be returned, or null
|
||||
+ * @deprecated use {@link #message(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setMessage(@Nullable String message) {
|
||||
+ this.message(message == null ? null : LegacyComponentSerializer.legacySection().deserialize(message));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets message that will be returned
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Unknown command message
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ @Contract(pure = true)
|
||||
+ public Component message() {
|
||||
+ return this.message;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets message that will be returned
|
||||
+ * <p>
|
||||
+ * Set to null to avoid any message being sent
|
||||
+ *
|
||||
+ * @param message the message to be returned, or null
|
||||
+ */
|
||||
+ public void message(@Nullable Component message) {
|
||||
+ this.message = message;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
@@ -1,502 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 15 Jan 2018 21:46:46 -0500
|
||||
Subject: [PATCH] Basic PlayerProfile API
|
||||
|
||||
Provides basic elements of a PlayerProfile to be used by future API/events
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b76f13a0266806544bde13952476d4867caaf25b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java
|
||||
@@ -0,0 +1,231 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import java.util.Set;
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import org.bukkit.profile.PlayerTextures;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a players profile for the game, such as UUID, Name, and textures.
|
||||
+ */
|
||||
+public interface PlayerProfile extends org.bukkit.profile.PlayerProfile {
|
||||
+
|
||||
+ /**
|
||||
+ * @return The players name, if set
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ String getName();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets this profiles Name
|
||||
+ *
|
||||
+ * @param name The new Name
|
||||
+ * @return The previous Name
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ String setName(@Nullable String name);
|
||||
+
|
||||
+ /**
|
||||
+ * @return The players unique identifier, if set
|
||||
+ */
|
||||
+ @Nullable UUID getId();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets this profiles UUID
|
||||
+ *
|
||||
+ * @param uuid The new UUID
|
||||
+ * @return The previous UUID
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ UUID setId(@Nullable UUID uuid);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the {@link PlayerTextures} of this profile.
|
||||
+ * This will build a snapshot of the current texture data once
|
||||
+ * requested inside PlayerTextures.
|
||||
+ *
|
||||
+ * @return the textures, not <code>null</code>
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ PlayerTextures getTextures();
|
||||
+
|
||||
+ /**
|
||||
+ * Copies the given textures.
|
||||
+ *
|
||||
+ * @param textures the textures to copy, or <code>null</code> to clear the
|
||||
+ * textures
|
||||
+ */
|
||||
+ void setTextures(@Nullable PlayerTextures textures);
|
||||
+
|
||||
+ /**
|
||||
+ * @return A Mutable set of this players properties, such as textures.
|
||||
+ * Values specified here are subject to implementation details.
|
||||
+ */
|
||||
+ @NotNull Set<ProfileProperty> getProperties();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if the Profile has the specified property
|
||||
+ * @param property Property name to check
|
||||
+ * @return If the property is set
|
||||
+ */
|
||||
+ boolean hasProperty(@Nullable String property);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets a property. If the property already exists, the previous one will be replaced
|
||||
+ * @param property Property to set.
|
||||
+ */
|
||||
+ void setProperty(@NotNull ProfileProperty property);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets multiple properties. If any of the set properties already exist, it will be replaced
|
||||
+ * @param properties The properties to set
|
||||
+ */
|
||||
+ void setProperties(@NotNull Collection<ProfileProperty> properties);
|
||||
+
|
||||
+ /**
|
||||
+ * Removes a specific property from this profile
|
||||
+ * @param property The property to remove
|
||||
+ * @return If a property was removed
|
||||
+ */
|
||||
+ boolean removeProperty(@Nullable String property);
|
||||
+
|
||||
+ /**
|
||||
+ * Removes a specific property from this profile
|
||||
+ * @param property The property to remove
|
||||
+ * @return If a property was removed
|
||||
+ */
|
||||
+ default boolean removeProperty(@NotNull ProfileProperty property) {
|
||||
+ return removeProperty(property.getName());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Removes all properties in the collection
|
||||
+ * @param properties The properties to remove
|
||||
+ * @return If any property was removed
|
||||
+ */
|
||||
+ default boolean removeProperties(@NotNull Collection<ProfileProperty> properties) {
|
||||
+ boolean removed = false;
|
||||
+ for (ProfileProperty property : properties) {
|
||||
+ if (removeProperty(property)) {
|
||||
+ removed = true;
|
||||
+ }
|
||||
+ }
|
||||
+ return removed;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Clears all properties on this profile
|
||||
+ */
|
||||
+ void clearProperties();
|
||||
+
|
||||
+ /**
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean isComplete();
|
||||
+
|
||||
+ /**
|
||||
+ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls
|
||||
+ * Does not account for textures.
|
||||
+ *
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean completeFromCache();
|
||||
+
|
||||
+ /**
|
||||
+ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls
|
||||
+ * Does not account for textures.
|
||||
+ *
|
||||
+ * @param onlineMode Treat this as online mode or not
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean completeFromCache(boolean onlineMode);
|
||||
+
|
||||
+ /**
|
||||
+ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls
|
||||
+ * Does not account for textures.
|
||||
+ *
|
||||
+ * @param lookupUUID If only name is supplied, should we do a UUID lookup
|
||||
+ * @param onlineMode Treat this as online mode or not
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean completeFromCache(boolean lookupUUID, boolean onlineMode);
|
||||
+
|
||||
+ /**
|
||||
+ * If this profile is not complete, then make the API call to complete it.
|
||||
+ * This is a blocking operation and should be done asynchronously.
|
||||
+ *
|
||||
+ * This will also complete textures. If you do not want to load textures, use {{@link #complete(boolean)}}
|
||||
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
|
||||
+ */
|
||||
+ default boolean complete() {
|
||||
+ return complete(true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If this profile is not complete, then make the API call to complete it.
|
||||
+ * This is a blocking operation and should be done asynchronously.
|
||||
+ *
|
||||
+ * Optionally will also fill textures.
|
||||
+ *
|
||||
+ * Online mode will be automatically determined
|
||||
+ * @param textures controls if we should fill the profile with texture properties
|
||||
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
|
||||
+ */
|
||||
+ boolean complete(boolean textures);
|
||||
+
|
||||
+ /**
|
||||
+ * If this profile is not complete, then make the API call to complete it.
|
||||
+ * This is a blocking operation and should be done asynchronously.
|
||||
+ *
|
||||
+ * Optionally will also fill textures.
|
||||
+ * @param textures controls if we should fill the profile with texture properties
|
||||
+ * @param onlineMode Treat this server as online mode or not
|
||||
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
|
||||
+ */
|
||||
+ boolean complete(boolean textures, boolean onlineMode);
|
||||
+
|
||||
+ /**
|
||||
+ * Produces an updated player profile based on this profile.
|
||||
+ * <p>
|
||||
+ * This tries to produce a completed profile by filling in missing
|
||||
+ * properties (name, unique id, textures, etc.), and updates existing
|
||||
+ * properties (e.g. name, textures, etc.) to their official and up-to-date
|
||||
+ * values. This operation does not alter the current profile, but produces a
|
||||
+ * new updated {@link PlayerProfile}.
|
||||
+ * <p>
|
||||
+ * If no player exists for the unique id or name of this profile, this
|
||||
+ * operation yields a profile that is equal to the current profile, which
|
||||
+ * might not be complete.
|
||||
+ * <p>
|
||||
+ * This is an asynchronous operation: Updating the profile can result in an
|
||||
+ * outgoing connection in another thread in order to fetch the latest
|
||||
+ * profile properties. The returned {@link CompletableFuture} will be
|
||||
+ * completed once the updated profile is available. In order to not block
|
||||
+ * the server's main thread, you should not wait for the result of the
|
||||
+ * returned CompletableFuture on the server's main thread. Instead, if you
|
||||
+ * want to do something with the updated player profile on the server's main
|
||||
+ * thread once it is available, you could do something like this:
|
||||
+ * <pre>
|
||||
+ * profile.update().thenAcceptAsync(updatedProfile -> {
|
||||
+ * // Do something with the updated profile:
|
||||
+ * // ...
|
||||
+ * }, runnable -> Bukkit.getScheduler().runTask(plugin, runnable));
|
||||
+ * </pre>
|
||||
+ */
|
||||
+ @Override
|
||||
+ @NotNull CompletableFuture<PlayerProfile> update();
|
||||
+
|
||||
+ /**
|
||||
+ * Whether this Profile has textures associated to it
|
||||
+ * @return If it has a textures property
|
||||
+ */
|
||||
+ default boolean hasTextures() {
|
||||
+ return hasProperty("textures");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7b3b6ef533d32169fbeca389bd61cfc6b0e0faee
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
|
||||
@@ -0,0 +1,72 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+
|
||||
+import java.util.Objects;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a property on a {@link PlayerProfile}
|
||||
+ */
|
||||
+public class ProfileProperty {
|
||||
+ private final String name;
|
||||
+ private final String value;
|
||||
+ private final String signature;
|
||||
+
|
||||
+ public ProfileProperty(@NotNull String name, @NotNull String value) {
|
||||
+ this(name, value, null);
|
||||
+ }
|
||||
+
|
||||
+ public ProfileProperty(@NotNull String name, @NotNull String value, @Nullable String signature) {
|
||||
+ this.name = Preconditions.checkNotNull(name, "ProfileProperty name can not be null");
|
||||
+ this.value = Preconditions.checkNotNull(value, "ProfileProperty value can not be null");
|
||||
+ this.signature = signature;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The property name, ie "textures"
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getName() {
|
||||
+ return name;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The property value, likely to be base64 encoded
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getValue() {
|
||||
+ return value;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return A signature from Mojang for signed properties
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getSignature() {
|
||||
+ return signature;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return If this property has a signature or not
|
||||
+ */
|
||||
+ public boolean isSigned() {
|
||||
+ return this.signature != null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(Object o) {
|
||||
+ if (this == o) return true;
|
||||
+ if (o == null || getClass() != o.getClass()) return false;
|
||||
+ ProfileProperty that = (ProfileProperty) o;
|
||||
+ return Objects.equals(name, that.name) &&
|
||||
+ Objects.equals(value, that.value) &&
|
||||
+ Objects.equals(signature, that.signature);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ return Objects.hash(name);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index ae017e210a54e78ecd14117ac939e1bb3da4497a..047676a7ea94bf26c8dd0552c72760bcc264218f 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -2228,6 +2228,83 @@ public final class Bukkit {
|
||||
public static boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||
return server.suggestPlayerNamesWhenNullTabCompletions();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified uuid, with name as null.
|
||||
+ *
|
||||
+ * If a player with the passed uuid exists on the server at the time of creation, the returned player profile will
|
||||
+ * be populated with the properties of said player (including their uuid and name).
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull UUID uuid) {
|
||||
+ return server.createProfile(uuid);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name, with UUID as null.
|
||||
+ *
|
||||
+ * If a player with the passed name exists on the server at the time of creation, the returned player profile will
|
||||
+ * be populated with the properties of said player (including their uuid and name).
|
||||
+ * <p>
|
||||
+ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile("JEB_")} will
|
||||
+ * yield a profile with the name 'jeb_', their uuid and their textures.
|
||||
+ * To bypass this pre-population on a case-insensitive name match, see {@link #createProfileExact(UUID, String)}.
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull String name) {
|
||||
+ return server.createProfile(name);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name/uuid
|
||||
+ *
|
||||
+ * Both UUID and Name can not be null at same time. One must be supplied.
|
||||
+ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player
|
||||
+ * profile will be populated with the properties of said player (including their uuid and name).
|
||||
+ * <p>
|
||||
+ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile(null, "JEB_")} will
|
||||
+ * yield a profile with the name 'jeb_', their uuid and their textures.
|
||||
+ * To bypass this pre-population on an case-insensitive name match, see {@link #createProfileExact(UUID, String)}.
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * The name comparison will compare the {@link String#toLowerCase()} version of both the passed name parameter and
|
||||
+ * a players name to honour the case-insensitive nature of a mojang profile lookup.
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) {
|
||||
+ return server.createProfile(uuid, name);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates an exact PlayerProfile for the specified name/uuid
|
||||
+ *
|
||||
+ * Both UUID and Name can not be null at same time. One must be supplied.
|
||||
+ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player
|
||||
+ * profile will be populated with the properties of said player.
|
||||
+ * <p>
|
||||
+ * Compared to {@link #createProfile(UUID, String)}, this method will never mutate the passed uuid or name.
|
||||
+ * If a player with either the same uuid or a matching name (case-insensitive) is found on the server, their
|
||||
+ * properties, such as textures, will be pre-populated in the profile, however the passed uuid and name stay intact.
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static com.destroystokyo.paper.profile.PlayerProfile createProfileExact(@Nullable UUID uuid, @Nullable String name) {
|
||||
+ return server.createProfileExact(uuid, name);
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index e1211bb9c3186ffb1c5c7b858b8bab50bf87df9f..94192cfe9bb15c0083cf28761bc3f0f6bb19aa8d 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1955,5 +1955,74 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @return true if player names should be suggested
|
||||
*/
|
||||
boolean suggestPlayerNamesWhenNullTabCompletions();
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified uuid, with name as null.
|
||||
+ *
|
||||
+ * If a player with the passed uuid exists on the server at the time of creation, the returned player profile will
|
||||
+ * be populated with the properties of said player (including their uuid and name).
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull UUID uuid);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name, with UUID as null.
|
||||
+ *
|
||||
+ * If a player with the passed name exists on the server at the time of creation, the returned player profile will
|
||||
+ * be populated with the properties of said player (including their uuid and name).
|
||||
+ * <p>
|
||||
+ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile("JEB_")} will
|
||||
+ * yield a profile with the name 'jeb_', their uuid and their textures.
|
||||
+ * To bypass this pre-population on a case-insensitive name match, see {@link #createProfileExact(UUID, String)}.
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull String name);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name/uuid
|
||||
+ *
|
||||
+ * Both UUID and Name can not be null at same time. One must be supplied.
|
||||
+ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player
|
||||
+ * profile will be populated with the properties of said player (including their uuid and name).
|
||||
+ * <p>
|
||||
+ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile(null, "JEB_")} will
|
||||
+ * yield a profile with the name 'jeb_', their uuid and their textures.
|
||||
+ * To bypass this pre-population on an case-insensitive name match, see {@link #createProfileExact(UUID, String)}.
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * The name comparison will compare the {@link String#toLowerCase()} version of both the passed name parameter and
|
||||
+ * a players name to honour the case-insensitive nature of a mojang profile lookup.
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates an exact PlayerProfile for the specified name/uuid
|
||||
+ *
|
||||
+ * Both UUID and Name can not be null at same time. One must be supplied.
|
||||
+ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player
|
||||
+ * profile will be populated with the properties of said player.
|
||||
+ * <p>
|
||||
+ * Compared to {@link #createProfile(UUID, String)}, this method will never mutate the passed uuid or name.
|
||||
+ * If a player with either the same uuid or a matching name (case-insensitive) is found on the server, their
|
||||
+ * properties, such as textures, will be pre-populated in the profile, however the passed uuid and name stay intact.
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile createProfileExact(@Nullable UUID uuid, @Nullable String name);
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/profile/PlayerProfile.java b/src/main/java/org/bukkit/profile/PlayerProfile.java
|
||||
index 16ae1282f3178e8873483a25a5d5cce16b2c21a9..fc46add38bf59dc1a04ea566fd230dcd8ae2708c 100644
|
||||
--- a/src/main/java/org/bukkit/profile/PlayerProfile.java
|
||||
+++ b/src/main/java/org/bukkit/profile/PlayerProfile.java
|
||||
@@ -93,7 +93,7 @@ public interface PlayerProfile extends Cloneable, ConfigurationSerializable {
|
||||
* PlayerProfile once it is available
|
||||
*/
|
||||
@NotNull
|
||||
- CompletableFuture<PlayerProfile> update();
|
||||
+ CompletableFuture<? extends PlayerProfile> update(); // Paper
|
||||
|
||||
@NotNull
|
||||
PlayerProfile clone();
|
||||
Loaded 100 of 3160 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user