Compare commits
206 Commits
patch-tabc
...
cf36174de7
Author | SHA1 | Date | |
---|---|---|---|
cf36174de7 | |||
b7f0cc4217 | |||
a0f6d000ec | |||
ca3323c00f | |||
f52180c385 | |||
949cde9e2b | |||
![]() |
497c6879e0 | ||
![]() |
7b27dfaf5e | ||
![]() |
f9b75c4a3a | ||
![]() |
0509303fd3 | ||
![]() |
f486a251f3 | ||
![]() |
5a1e342e0d | ||
![]() |
d9bbdc3281 | ||
![]() |
cfe00fa47c | ||
![]() |
d68ebd1eaf | ||
![]() |
a7cd79eb41 | ||
![]() |
9e83ee6f0c | ||
![]() |
7c81d91740 | ||
![]() |
5b126b7f4d | ||
![]() |
9fe7d21f4b | ||
![]() |
94ea0271ba | ||
![]() |
3af672d2f2 | ||
![]() |
0dd7b98428 | ||
![]() |
a793692a2c | ||
![]() |
23fb838227 | ||
![]() |
2d6d89d668 | ||
![]() |
0199cb90ff | ||
![]() |
958cef5084 | ||
![]() |
9f5ace9025 | ||
![]() |
3a6e2631bf | ||
![]() |
c7adcf9fdf | ||
![]() |
da3616e636 | ||
![]() |
b371fe67a5 | ||
![]() |
6324c7d527 | ||
![]() |
6263fe283b | ||
![]() |
9a7617f9b8 | ||
![]() |
9a71358dfa | ||
![]() |
a96a2e80a1 | ||
![]() |
68200133b6 | ||
![]() |
188d502c59 | ||
![]() |
84ac683c1d | ||
![]() |
b418c94215 | ||
![]() |
38e593a698 | ||
![]() |
38028e8e90 | ||
![]() |
3db27052a1 | ||
![]() |
e24f9223df | ||
![]() |
9e5ed82c99 | ||
![]() |
606fa278c4 | ||
![]() |
7dd549ff1e | ||
![]() |
3c12b04c98 | ||
![]() |
5545850f9d | ||
![]() |
2f909b44d7 | ||
![]() |
ff155ebbb4 | ||
![]() |
a0a4fa0e56 | ||
![]() |
1b76a26691 | ||
![]() |
bd7bd2739a | ||
![]() |
a7ad407f4b | ||
![]() |
931ff0fde6 | ||
![]() |
dfd847f705 | ||
![]() |
a1fee720b9 | ||
![]() |
963854f8d5 | ||
![]() |
2ef5e7004b | ||
![]() |
2e6f0dd442 | ||
![]() |
7790783949 | ||
![]() |
f4534c8273 | ||
![]() |
76673f02a4 | ||
![]() |
b47ae0944c | ||
![]() |
f9712cbc7c | ||
![]() |
1b6d845530 | ||
![]() |
19424aba9d | ||
![]() |
71ac9b34fa | ||
![]() |
7651d4a249 | ||
![]() |
f8e0bccdf0 | ||
![]() |
a5b6eb6afa | ||
![]() |
41471da9db | ||
![]() |
e71767688d | ||
![]() |
5467e3a842 | ||
![]() |
511017ab35 | ||
![]() |
c3e8cfac79 | ||
![]() |
bf2b3c68f8 | ||
![]() |
68e74a8c03 | ||
![]() |
5b4a540440 | ||
![]() |
88da5c05c7 | ||
![]() |
2d369e8945 | ||
![]() |
02548c4b9b | ||
![]() |
71990e3ccc | ||
![]() |
5e7dcc48b9 | ||
![]() |
5cdba87b87 | ||
![]() |
696315615d | ||
![]() |
dd3f820040 | ||
![]() |
78ca16dfe3 | ||
![]() |
adc32d5a5c | ||
![]() |
12e4514813 | ||
![]() |
587fb37bdf | ||
![]() |
d221e52929 | ||
![]() |
e151a6cf92 | ||
![]() |
9ced5ce131 | ||
![]() |
c8e876bfe2 | ||
![]() |
2a716bbc7f | ||
![]() |
00590b6c0d | ||
![]() |
2ff4be7846 | ||
![]() |
ff5727c5ef | ||
![]() |
e46bc343e4 | ||
![]() |
5972fd2353 | ||
![]() |
8c0e4b1d33 | ||
![]() |
a737a754d1 | ||
![]() |
fc8685a042 | ||
![]() |
cc4765b4fe | ||
![]() |
eccdf87f22 | ||
![]() |
862bb2ac72 | ||
![]() |
34d416a4e8 | ||
![]() |
410f64bc9f | ||
![]() |
978e68fc74 | ||
![]() |
a17d8f8a66 | ||
![]() |
7e47490e70 | ||
![]() |
f4f94d3b56 | ||
![]() |
eae9d45c8a | ||
![]() |
d2d157c1fe | ||
![]() |
9c95d4ba43 | ||
![]() |
6cbd7404f4 | ||
![]() |
ad8a8ef5a9 | ||
![]() |
e6766a1ee2 | ||
![]() |
b4ccdaa51c | ||
![]() |
3a11656909 | ||
![]() |
2479fab632 | ||
![]() |
51eb1ac623 | ||
![]() |
879f37f046 | ||
![]() |
f2aadd6014 | ||
![]() |
1ad81504ca | ||
![]() |
425ee4e142 | ||
![]() |
42d8300bb7 | ||
![]() |
a9d75c5255 | ||
![]() |
98afd548d1 | ||
![]() |
7fc256dba7 | ||
![]() |
21b23624ad | ||
![]() |
1ace5c0c8b | ||
![]() |
bee99beab1 | ||
![]() |
8b363d3d1f | ||
![]() |
c7b0c3cd48 | ||
![]() |
c0c9b28582 | ||
![]() |
c3fffbc919 | ||
![]() |
6613aaea95 | ||
![]() |
53ce6b93a2 | ||
![]() |
d8e293842f | ||
![]() |
5cf869df1a | ||
![]() |
f26f7d8809 | ||
![]() |
c5a90475af | ||
![]() |
3008d7ef2f | ||
![]() |
1823f86dbb | ||
![]() |
06bf088d27 | ||
![]() |
9953698a7c | ||
![]() |
bda1605627 | ||
![]() |
2e0e88db0d | ||
![]() |
96482cc0cf | ||
![]() |
a283aaf724 | ||
![]() |
5db276eb52 | ||
![]() |
c866619f56 | ||
![]() |
b9da505efe | ||
![]() |
061a7c67bd | ||
![]() |
6f7331e852 | ||
![]() |
1b489bcc11 | ||
![]() |
da27924a49 | ||
![]() |
15b39887c5 | ||
![]() |
f9583a7652 | ||
![]() |
cb738188de | ||
![]() |
a8b2f5268d | ||
![]() |
ad50fc9ad3 | ||
![]() |
a25c2b325b | ||
![]() |
c57bf61114 | ||
![]() |
b7935d4b14 | ||
![]() |
00982f3620 | ||
![]() |
088b2045d0 | ||
![]() |
633ff1cfc8 | ||
![]() |
6cda6b6c10 | ||
![]() |
90573625f1 | ||
![]() |
d49e97c423 | ||
![]() |
39a80e414e | ||
![]() |
ab9153ddc3 | ||
![]() |
7ec1f487c1 | ||
![]() |
c96628b72e | ||
![]() |
e5ded9a2fb | ||
![]() |
5823f47467 | ||
![]() |
a0b7f09252 | ||
![]() |
b60a30c705 | ||
![]() |
4fc1a9e770 | ||
![]() |
f0908b663f | ||
![]() |
5fa596fee9 | ||
![]() |
ada1b95ffc | ||
![]() |
72b3bdf676 | ||
![]() |
71d1246374 | ||
![]() |
ac371bb596 | ||
![]() |
830ee8f27d | ||
![]() |
425dd45109 | ||
![]() |
6a039de8db | ||
![]() |
8d783aa172 | ||
![]() |
a4e5f5005b | ||
![]() |
a7c6edeb63 | ||
![]() |
4f23b49fef | ||
![]() |
cfcc8b1a6f | ||
![]() |
ebec582ce2 | ||
![]() |
3d701fbe0e | ||
![]() |
e95da11115 | ||
![]() |
9f6a798ea6 | ||
![]() |
36c8df4d2f | ||
![]() |
baf2f60850 | ||
![]() |
9ac39005f8 |
63
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
63
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
name: Bug inside BungeeCord
|
||||||
|
description: Create a bug report about a problem inside BungeeCord.
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
#### Report a bug inside bungeecord
|
||||||
|
Issues happening with forks of BungeeCord should **not** be reported here.
|
||||||
|
- type: input
|
||||||
|
id: bungee-version
|
||||||
|
attributes:
|
||||||
|
label: Bungeecord version
|
||||||
|
description: The output of the /bungee command (or just the bungee build number) (execute in bungeecord console for easy text copy)
|
||||||
|
placeholder: e.g. git:BungeeCord-Bootstrap:1.xx-SNAPSHOT:xxxxxxx:xxxx
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: server-version
|
||||||
|
attributes:
|
||||||
|
label: Server version
|
||||||
|
description: The output of the /version command (execute in server console for easy text copy)
|
||||||
|
placeholder: "e.g. git-Spigot-xxxxxxx-xxxxxxx (MC: 1.x.x)"
|
||||||
|
- type: input
|
||||||
|
id: client-version
|
||||||
|
attributes:
|
||||||
|
label: Client version
|
||||||
|
description: Minecraft Client Version
|
||||||
|
placeholder: e.g. 1.18.2
|
||||||
|
- type: textarea
|
||||||
|
id: bungee-plugins
|
||||||
|
attributes:
|
||||||
|
label: Bungeecord plugins
|
||||||
|
description: Please list all BungeeCord plugins you are using.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: the-bug
|
||||||
|
attributes:
|
||||||
|
label: The bug
|
||||||
|
description: Please describe the bug. Include **details** you find neccessary. If you just have a question, please ask it in [SpigotMC Forums](https://www.spigotmc.org) and not here.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Log output (links)
|
||||||
|
description: Please put your log output inbetween three backticks (```` ``` ````). Upload your log files to [gist.github.com](https://gist.github.com) and put them in here.
|
||||||
|
placeholder: |
|
||||||
|
```
|
||||||
|
log output
|
||||||
|
```
|
||||||
|
- type: checkboxes
|
||||||
|
id: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Checking
|
||||||
|
options:
|
||||||
|
- label: I am using BungeeCord and **not a fork**. Issues with forks should not be reported here.
|
||||||
|
required: true
|
||||||
|
- label: I think this is **not** an issue with a bungeecord plugin.
|
||||||
|
required: true
|
||||||
|
- label: I have not read these checkboxes and therefore I just ticked them all.
|
||||||
|
- label: This is not a question or plugin creation help request.
|
||||||
|
required: true
|
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Configuration help
|
||||||
|
url: https://www.spigotmc.org/forums/bungeecord-help.70/create-thread
|
||||||
|
about: Help for configuring bungeecord will only be answered in spigotmc.org forums.
|
||||||
|
- name: I have a problem with a bungee plugin
|
||||||
|
url: https://www.spigotmc.org/forums/bungeecord-plugin-help.71/create-thread
|
||||||
|
about: Help about plugins can be recieved in spigotmc.org forums.
|
||||||
|
- name: Questions and discussions
|
||||||
|
url: https://www.spigotmc.org/forums/bungeecord-discussion.21/create-thread
|
||||||
|
about: spigotmc.org forums are the best place to ask your questions regarding bungeecord.
|
||||||
|
- name: Plugin creation help
|
||||||
|
url: https://www.spigotmc.org/forums/bungeecord-plugin-development.23/create-thread
|
||||||
|
about: Plugin creation help for bungee plugins can be recieved in spigotmc.org forums.
|
36
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
36
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
name: Feature request
|
||||||
|
description: Suggest a feature which bungeecord should include.
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: the-feature
|
||||||
|
attributes:
|
||||||
|
label: Feature description
|
||||||
|
description: Please describe your feature or improvement. Please include **details**.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: goal
|
||||||
|
attributes:
|
||||||
|
label: Goal of the feature
|
||||||
|
description: What is the goal of your feature?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Unfitting alternatives
|
||||||
|
description: What alternatives have you considered and why are they not sufficient for your use case?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: checkboxes
|
||||||
|
id: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Checking
|
||||||
|
options:
|
||||||
|
- label: This is not a question or plugin creation help request.
|
||||||
|
required: true
|
||||||
|
- label: This is a **feature or improvement request**.
|
||||||
|
required: true
|
||||||
|
- label: I have not read these checkboxes and therefore I just ticked them all.
|
||||||
|
- label: I did not use this form to report a bug.
|
||||||
|
required: true
|
28
.github/dependabot.yml
vendored
Normal file
28
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "maven"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
open-pull-requests-limit: 50
|
||||||
|
ignore:
|
||||||
|
# Synchronised with Minecraft
|
||||||
|
- dependency-name: "com.google.code.gson:gson"
|
||||||
|
# 9.x has performance issues (see, eg, checkstyle/checkstyle#10934) and 10.x is incompatible
|
||||||
|
- dependency-name: "com.puppycrawl.tools:checkstyle"
|
||||||
|
# Newer versions have issues, see #1909 and #2050
|
||||||
|
- dependency-name: "jline:jline"
|
||||||
|
# Later versions of these Maven dependencies are incompatible and require careful management - see SPIGOT-7400
|
||||||
|
- dependency-name: "org.apache.maven.resolver:maven-resolver-connector-basic"
|
||||||
|
- dependency-name: "org.apache.maven.resolver:maven-resolver-transport-http"
|
||||||
|
- dependency-name: "org.apache.maven:maven-resolver-provider"
|
||||||
|
# Used with maven-resolver dependencies; 2.0 update breaks other providers
|
||||||
|
- dependency-name: "org.slf4j:slf4j-api"
|
||||||
|
update-types: ["version-update:semver-major"]
|
||||||
|
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
open-pull-requests-limit: 50
|
10
.github/workflows/maven.yml
vendored
10
.github/workflows/maven.yml
vendored
@@ -4,18 +4,20 @@ on: [push, pull_request]
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
java: [8, 11]
|
java: [8, 11, 17, 21]
|
||||||
|
|
||||||
name: Java ${{ matrix.java }}
|
name: Java ${{ matrix.java }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
|
distribution: zulu
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
- run: java -version && mvn --version
|
- run: java -version && mvn --version
|
||||||
- run: mvn --activate-profiles dist --no-transfer-progress package
|
- run: mvn --activate-profiles dist --no-transfer-progress package
|
||||||
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[submodule "native/mbedtls"]
|
||||||
|
path = native/mbedtls
|
||||||
|
url = https://github.com/ARMmbed/mbedtls.git
|
||||||
|
[submodule "native/zlib"]
|
||||||
|
path = native/zlib
|
||||||
|
url = https://github.com/cloudflare/zlib.git
|
@@ -23,4 +23,4 @@ Binaries
|
|||||||
--------
|
--------
|
||||||
Precompiled binaries are available for end users on [Jenkins](https://www.spigotmc.org/go/bungeecord-dl).
|
Precompiled binaries are available for end users on [Jenkins](https://www.spigotmc.org/go/bungeecord-dl).
|
||||||
|
|
||||||
(c) 2012-2020 SpigotMC Pty. Ltd.
|
(c) 2012-2023 SpigotMC Pty. Ltd.
|
||||||
|
39
api/pom.xml
39
api/pom.xml
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-api</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-API</name>
|
<name>BungeeCord-API</name>
|
||||||
@@ -20,25 +19,25 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-config</artifactId>
|
<artifactId>bungeecord-config</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-event</artifactId>
|
<artifactId>bungeecord-event</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
@@ -46,13 +45,33 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-transport-native-unix-common</artifactId>
|
<artifactId>netty-transport-native-unix-common</artifactId>
|
||||||
<version>${netty.version}</version>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-resolver-provider</artifactId>
|
||||||
|
<version>3.8.5</version>
|
||||||
|
<!-- not part of the API proper -->
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven.resolver</groupId>
|
||||||
|
<artifactId>maven-resolver-connector-basic</artifactId>
|
||||||
|
<version>1.7.3</version>
|
||||||
|
<!-- not part of the API proper -->
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven.resolver</groupId>
|
||||||
|
<artifactId>maven-resolver-transport-http</artifactId>
|
||||||
|
<version>1.7.3</version>
|
||||||
|
<!-- not part of the API proper -->
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.26</version>
|
<version>2.2</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@@ -7,6 +7,7 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,6 +69,17 @@ public class Util
|
|||||||
return String.format( "0x%02X", i );
|
return String.format( "0x%02X", i );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats an char as a unicode value.
|
||||||
|
*
|
||||||
|
* @param c the character to format
|
||||||
|
* @return the unicode representation of the character
|
||||||
|
*/
|
||||||
|
public static String unicode(char c)
|
||||||
|
{
|
||||||
|
return "\\u" + String.format( "%04x", (int) c ).toUpperCase( Locale.ROOT );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a pretty one line version of a {@link Throwable}. Useful for
|
* Constructs a pretty one line version of a {@link Throwable}. Useful for
|
||||||
* debugging.
|
* debugging.
|
||||||
@@ -76,11 +88,24 @@ public class Util
|
|||||||
* @return a string representing information about the {@link Throwable}
|
* @return a string representing information about the {@link Throwable}
|
||||||
*/
|
*/
|
||||||
public static String exception(Throwable t)
|
public static String exception(Throwable t)
|
||||||
|
{
|
||||||
|
return exception( t, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a pretty one line version of a {@link Throwable}. Useful for
|
||||||
|
* debugging.
|
||||||
|
*
|
||||||
|
* @param t the {@link Throwable} to format.
|
||||||
|
* @param includeLineNumbers whether to include line numbers
|
||||||
|
* @return a string representing information about the {@link Throwable}
|
||||||
|
*/
|
||||||
|
public static String exception(Throwable t, boolean includeLineNumbers)
|
||||||
{
|
{
|
||||||
// TODO: We should use clear manually written exceptions
|
// TODO: We should use clear manually written exceptions
|
||||||
StackTraceElement[] trace = t.getStackTrace();
|
StackTraceElement[] trace = t.getStackTrace();
|
||||||
return t.getClass().getSimpleName() + " : " + t.getMessage()
|
return t.getClass().getSimpleName() + " : " + t.getMessage()
|
||||||
+ ( ( trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" );
|
+ ( ( includeLineNumbers && trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String csv(Iterable<?> objects)
|
public static String csv(Iterable<?> objects)
|
||||||
@@ -88,6 +113,16 @@ public class Util
|
|||||||
return format( objects, ", " );
|
return format( objects, ", " );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string of objects, each separated by a separator.
|
||||||
|
*
|
||||||
|
* @param objects the objects to join
|
||||||
|
* @param separators the separator
|
||||||
|
* @return joined string
|
||||||
|
* @see String#join(java.lang.CharSequence, java.lang.Iterable)
|
||||||
|
* @deprecated use {@link String} join methods
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String format(Iterable<?> objects, String separators)
|
public static String format(Iterable<?> objects, String separators)
|
||||||
{
|
{
|
||||||
return Joiner.on( separators ).join( objects );
|
return Joiner.on( separators ).join( objects );
|
||||||
|
@@ -28,18 +28,13 @@ public abstract class AbstractReconnectHandler implements ReconnectHandler
|
|||||||
|
|
||||||
public static ServerInfo getForcedHost(PendingConnection con)
|
public static ServerInfo getForcedHost(PendingConnection con)
|
||||||
{
|
{
|
||||||
if ( con.getVirtualHost() == null )
|
String forced = ( con.getVirtualHost() == null ) ? null : con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() );
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String forced = con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() );
|
|
||||||
|
|
||||||
if ( forced == null && con.getListener().isForceDefault() )
|
if ( forced == null && con.getListener().isForceDefault() )
|
||||||
{
|
{
|
||||||
forced = con.getListener().getDefaultServer();
|
forced = con.getListener().getDefaultServer();
|
||||||
}
|
}
|
||||||
return ProxyServer.getInstance().getServerInfo( forced );
|
return ( forced == null ) ? null : ProxyServer.getInstance().getServerInfo( forced );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ServerInfo getStoredServer(ProxiedPlayer player);
|
protected abstract ServerInfo getStoredServer(ProxiedPlayer player);
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
package net.md_5.bungee.api;
|
package net.md_5.bungee.api;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.io.BaseEncoding;
|
import com.google.common.io.BaseEncoding;
|
||||||
import com.google.gson.TypeAdapter;
|
import com.google.gson.TypeAdapter;
|
||||||
import com.google.gson.internal.bind.TypeAdapters;
|
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -26,13 +27,26 @@ public class Favicon
|
|||||||
@Override
|
@Override
|
||||||
public void write(JsonWriter out, Favicon value) throws IOException
|
public void write(JsonWriter out, Favicon value) throws IOException
|
||||||
{
|
{
|
||||||
TypeAdapters.STRING.write( out, value == null ? null : value.getEncoded() );
|
if ( value == null )
|
||||||
|
{
|
||||||
|
out.nullValue();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
out.value( value.getEncoded() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Favicon read(JsonReader in) throws IOException
|
public Favicon read(JsonReader in) throws IOException
|
||||||
{
|
{
|
||||||
String enc = TypeAdapters.STRING.read( in );
|
JsonToken peek = in.peek();
|
||||||
|
if ( peek == JsonToken.NULL )
|
||||||
|
{
|
||||||
|
in.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String enc = in.nextString();
|
||||||
return enc == null ? null : create( enc );
|
return enc == null ? null : create( enc );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -59,6 +73,7 @@ public class Favicon
|
|||||||
*/
|
*/
|
||||||
public static Favicon create(BufferedImage image)
|
public static Favicon create(BufferedImage image)
|
||||||
{
|
{
|
||||||
|
Preconditions.checkArgument( image != null, "image is null" );
|
||||||
// check size
|
// check size
|
||||||
if ( image.getWidth() != 64 || image.getHeight() != 64 )
|
if ( image.getWidth() != 64 || image.getHeight() != 64 )
|
||||||
{
|
{
|
||||||
|
@@ -15,7 +15,7 @@ import net.md_5.bungee.api.event.ServerConnectEvent;
|
|||||||
import net.md_5.bungee.api.score.Scoreboard;
|
import net.md_5.bungee.api.score.Scoreboard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a player who's connection is being connected to somewhere else,
|
* Represents a player whose connection is being connected to somewhere else,
|
||||||
* whether it be a remote or embedded server.
|
* whether it be a remote or embedded server.
|
||||||
*/
|
*/
|
||||||
public interface ProxiedPlayer extends Connection, CommandSender
|
public interface ProxiedPlayer extends Connection, CommandSender
|
||||||
@@ -57,8 +57,7 @@ public interface ProxiedPlayer extends Connection, CommandSender
|
|||||||
String getDisplayName();
|
String getDisplayName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets this players display name to be used as their nametag and tab list
|
* Sets this player's display name to be used by proxy commands and plugins.
|
||||||
* name.
|
|
||||||
*
|
*
|
||||||
* @param name the name to set
|
* @param name the name to set
|
||||||
*/
|
*/
|
||||||
|
@@ -1,40 +0,0 @@
|
|||||||
package net.md_5.bungee.api.event;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event called when an 1.13+ player uses tab completion.
|
|
||||||
* This event is fired after {@link TabCompleteEvent}.
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class BrigadierSuggestionsEvent extends TargetedEvent implements Cancellable
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancelled state.
|
|
||||||
*/
|
|
||||||
private boolean cancelled;
|
|
||||||
/**
|
|
||||||
* The message the player has already entered.
|
|
||||||
*/
|
|
||||||
private final String cursor;
|
|
||||||
/**
|
|
||||||
* The suggestions that will be sent to the client. If this list is empty,
|
|
||||||
* the request will be forwarded to the server.
|
|
||||||
*/
|
|
||||||
private Suggestions suggestions;
|
|
||||||
|
|
||||||
public BrigadierSuggestionsEvent(Connection sender, Connection receiver, String cursor, Suggestions suggestions)
|
|
||||||
{
|
|
||||||
super( sender, receiver );
|
|
||||||
this.cursor = cursor;
|
|
||||||
this.suggestions = suggestions;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,157 @@
|
|||||||
|
package net.md_5.bungee.api.event;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
|
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||||
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
|
import com.mojang.brigadier.tree.RootCommandNode;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.Connection;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import net.md_5.bungee.api.plugin.PluginManager;
|
||||||
|
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called when a downstream server (on 1.13+) sends the command structure
|
||||||
|
* to a player, but before BungeeCord adds the dummy command nodes of
|
||||||
|
* registered commands.
|
||||||
|
* <p>
|
||||||
|
* BungeeCord will not overwrite the modifications made by the listeners.
|
||||||
|
*
|
||||||
|
* <h2>Usage example</h2>
|
||||||
|
* Here is a usage example of this event, to declare a command structure.
|
||||||
|
* This illustrates the commands /server and /send of Bungee.
|
||||||
|
* <pre>
|
||||||
|
* event.getRoot().addChild( LiteralArgumentBuilder.<CommandSender>literal( "server" )
|
||||||
|
* .requires( sender -> sender.hasPermission( "bungeecord.command.server" ) )
|
||||||
|
* .executes( a -> 0 )
|
||||||
|
* .then( RequiredArgumentBuilder.argument( "serverName", StringArgumentType.greedyString() )
|
||||||
|
* .suggests( SuggestionRegistry.ASK_SERVER )
|
||||||
|
* )
|
||||||
|
* .build()
|
||||||
|
* );
|
||||||
|
* event.getRoot().addChild( LiteralArgumentBuilder.<CommandSender>literal( "send" )
|
||||||
|
* .requires( sender -> sender.hasPermission( "bungeecord.command.send" ) )
|
||||||
|
* .then( RequiredArgumentBuilder.argument( "playerName", StringArgumentType.word() )
|
||||||
|
* .suggests( SuggestionRegistry.ASK_SERVER )
|
||||||
|
* .then( RequiredArgumentBuilder.argument( "serverName", StringArgumentType.greedyString() )
|
||||||
|
* .suggests( SuggestionRegistry.ASK_SERVER )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* .build()
|
||||||
|
* );
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h2>Flag a {@link CommandNode} as executable or not</h2>
|
||||||
|
* The implementation of a {@link com.mojang.brigadier.Command Command} used in
|
||||||
|
* {@link ArgumentBuilder#executes(com.mojang.brigadier.Command)} will never be
|
||||||
|
* executed. This will only tell to the client if the current node is
|
||||||
|
* executable or not.
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* {@code builder.executes(null)} (default) to mark the node as not
|
||||||
|
* executable.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* {@code builder.executes(a -> 0)}, or any non null argument, to mark
|
||||||
|
* the node as executable (the child arguments are displayed as
|
||||||
|
* optional).
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <h2>{@link CommandNode}’s suggestions management</h2>
|
||||||
|
* The implementation of a SuggestionProvider used in
|
||||||
|
* {@link RequiredArgumentBuilder#suggests(SuggestionProvider)} will never be
|
||||||
|
* executed. This will only tell to the client how to deal with the
|
||||||
|
* auto-completion of the argument.
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* {@code builder.suggests(null)} (default) to disable auto-completion
|
||||||
|
* for this argument.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* {@code builder.suggests(SuggestionRegistry.ALL_RECIPES)} to suggest
|
||||||
|
* Minecraft’s recipes.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* {@code builder.suggests(SuggestionRegistry.AVAILABLE_SOUNDS)} to
|
||||||
|
* suggest Minecraft’s default sound identifiers.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* {@code builder.suggests(SuggestionRegistry.SUMMONABLE_ENTITIES)} to
|
||||||
|
* suggest Minecraft’s default summonable entities identifiers.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* {@code builder.suggests(SuggestionRegistry.ASK_SERVER)}, or any
|
||||||
|
* other non null argument, to make the Minecraft client ask
|
||||||
|
* auto-completion to the server. Any specified implementation of
|
||||||
|
* {@link SuggestionProvider} will never be executed.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <h2>Argument types</h2>
|
||||||
|
* When building a new argument command node using
|
||||||
|
* {@link RequiredArgumentBuilder#argument(String, ArgumentType)}, you have to
|
||||||
|
* specify an {@link ArgumentType}. You can use all subclasses of
|
||||||
|
* {@link ArgumentType} provided with brigadier (for instance,
|
||||||
|
* {@link StringArgumentType} or {@link IntegerArgumentType}), or call any
|
||||||
|
* {@code ArgumentRegistry.minecraft*()} methods to use a {@code minecraft:*}
|
||||||
|
* argument type.
|
||||||
|
*
|
||||||
|
* <h2>Limitations with brigadier API</h2>
|
||||||
|
* This event is only used for the client to show command syntax, suggest
|
||||||
|
* sub-commands and color the arguments in the chat box. The command execution
|
||||||
|
* needs to be implemented using {@link PluginManager#registerCommand(Plugin,
|
||||||
|
* Command)} and the server-side tab-completion using {@link TabCompleteEvent}
|
||||||
|
* or {@link TabExecutor}.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class CommandsDeclareEvent extends TargetedEvent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Wether or not the command tree is modified by this event.
|
||||||
|
*
|
||||||
|
* If this value is set to true, BungeeCord will ensure that the
|
||||||
|
* modifications made in the command tree, will be sent to the player.
|
||||||
|
* If this is false, the modifications may not be taken into account.
|
||||||
|
*
|
||||||
|
* When calling {@link #getRoot()}, this value is automatically set
|
||||||
|
* to true.
|
||||||
|
*/
|
||||||
|
@Setter(value = AccessLevel.NONE)
|
||||||
|
private boolean modified = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root command node of the command structure that will be send to the
|
||||||
|
* player.
|
||||||
|
*/
|
||||||
|
private final RootCommandNode<CommandSender> root;
|
||||||
|
|
||||||
|
public CommandsDeclareEvent(Connection sender, Connection receiver, RootCommandNode<CommandSender> root)
|
||||||
|
{
|
||||||
|
super( sender, receiver );
|
||||||
|
this.root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root command node of the command structure that will be send to the
|
||||||
|
* player.
|
||||||
|
* @return The root command node
|
||||||
|
*/
|
||||||
|
public RootCommandNode<CommandSender> getRoot()
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
}
|
@@ -8,7 +8,7 @@ import net.md_5.bungee.api.ServerPing;
|
|||||||
import net.md_5.bungee.api.connection.PendingConnection;
|
import net.md_5.bungee.api.connection.PendingConnection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the proxy is pinged with packet 0xFE from the server list.
|
* Called when the proxy is queried for status from the server list.
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ToString(callSuper = false)
|
@ToString(callSuper = false)
|
||||||
|
@@ -9,6 +9,13 @@ import net.md_5.bungee.api.config.ServerInfo;
|
|||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the player is disconnected from a server, for example during
|
||||||
|
* server switching.
|
||||||
|
*
|
||||||
|
* If the player is kicked from a server, {@link ServerKickEvent} will be called
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ToString(callSuper = false)
|
@ToString(callSuper = false)
|
||||||
|
@@ -9,9 +9,9 @@ import net.md_5.bungee.api.plugin.Cancellable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Event called when a player uses tab completion.
|
* Event called when a player uses tab completion.
|
||||||
* For 1.13+ clients, you can also use {@link BrigadierSuggestionsEvent} for
|
* @deprecated please use {@link TabCompleteRequestEvent} to support 1.13+ suggestions.
|
||||||
* more control of the suggestions.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Data
|
@Data
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@@ -0,0 +1,85 @@
|
|||||||
|
package net.md_5.bungee.api.event;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.mojang.brigadier.context.StringRange;
|
||||||
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
import net.md_5.bungee.api.connection.Connection;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called when a player uses tab completion.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class TabCompleteRequestEvent extends TargetedEvent implements Cancellable
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancelled state.
|
||||||
|
*/
|
||||||
|
private boolean cancelled;
|
||||||
|
/**
|
||||||
|
* The message the player has already entered.
|
||||||
|
*/
|
||||||
|
private final String cursor;
|
||||||
|
/**
|
||||||
|
* Range corresponding to the last word of {@link #getCursor()}.
|
||||||
|
* If you want your suggestions to be compatible with 1.12 and older
|
||||||
|
* clients, you need to {@link #setSuggestions(Suggestions)} with
|
||||||
|
* a range equals to this one.
|
||||||
|
* For 1.13 and newer clients, any other range that cover any part of
|
||||||
|
* {@link #getCursor()} is fine.<br>
|
||||||
|
* To check if the client supports custom ranges, use
|
||||||
|
* {@link #supportsCustomRange()}.
|
||||||
|
*/
|
||||||
|
private final StringRange legacyCompatibleRange;
|
||||||
|
/**
|
||||||
|
* The suggestions that will be sent to the client. If this list is empty,
|
||||||
|
* the request will be forwarded to the server.
|
||||||
|
*/
|
||||||
|
private Suggestions suggestions;
|
||||||
|
|
||||||
|
public TabCompleteRequestEvent(Connection sender, Connection receiver, String cursor, StringRange legacyCompatibleRange, Suggestions suggestions)
|
||||||
|
{
|
||||||
|
super( sender, receiver );
|
||||||
|
this.cursor = cursor;
|
||||||
|
this.legacyCompatibleRange = legacyCompatibleRange;
|
||||||
|
this.suggestions = suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the suggestions that will be sent to the client.
|
||||||
|
* If this list is empty, the request will be forwarded to the server.
|
||||||
|
* @param suggestions the new Suggestions. Cannot be null.
|
||||||
|
* @throws IllegalArgumentException if the client is on 1.12 or lower and
|
||||||
|
* {@code suggestions.getRange()} is not equals to {@link #legacyCompatibleRange}.
|
||||||
|
*/
|
||||||
|
public void setSuggestions(Suggestions suggestions)
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull( suggestions );
|
||||||
|
Preconditions.checkArgument( supportsCustomRange() || legacyCompatibleRange.equals( suggestions.getRange() ),
|
||||||
|
"Clients on 1.12 or lower versions don't support the provided range for tab-completion: " + suggestions.getRange()
|
||||||
|
+ ". Please use TabCompleteRequestEvent.getLegacyCompatibleRange() for legacy clients." );
|
||||||
|
this.suggestions = suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenient method to tell if the client supports custom range for
|
||||||
|
* suggestions.
|
||||||
|
* If the client is on 1.13 or above, this methods returns true, and any
|
||||||
|
* range can be used for {@link #setSuggestions(Suggestions)}. Otherwise,
|
||||||
|
* it returns false and the defined range must be equals to
|
||||||
|
* {@link #legacyCompatibleRange}.
|
||||||
|
* @return true if the client is on 1.13 or newer version, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean supportsCustomRange()
|
||||||
|
{
|
||||||
|
return ( (ProxiedPlayer) getSender() ).getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13;
|
||||||
|
}
|
||||||
|
}
|
123
api/src/main/java/net/md_5/bungee/api/plugin/LibraryLoader.java
Normal file
123
api/src/main/java/net/md_5/bungee/api/plugin/LibraryLoader.java
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package net.md_5.bungee.api.plugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
|
||||||
|
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||||
|
import org.eclipse.aether.RepositorySystem;
|
||||||
|
import org.eclipse.aether.artifact.Artifact;
|
||||||
|
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||||
|
import org.eclipse.aether.collection.CollectRequest;
|
||||||
|
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
|
||||||
|
import org.eclipse.aether.graph.Dependency;
|
||||||
|
import org.eclipse.aether.impl.DefaultServiceLocator;
|
||||||
|
import org.eclipse.aether.repository.LocalRepository;
|
||||||
|
import org.eclipse.aether.repository.RemoteRepository;
|
||||||
|
import org.eclipse.aether.repository.RepositoryPolicy;
|
||||||
|
import org.eclipse.aether.resolution.ArtifactResult;
|
||||||
|
import org.eclipse.aether.resolution.DependencyRequest;
|
||||||
|
import org.eclipse.aether.resolution.DependencyResolutionException;
|
||||||
|
import org.eclipse.aether.resolution.DependencyResult;
|
||||||
|
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
|
||||||
|
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
|
||||||
|
import org.eclipse.aether.transfer.AbstractTransferListener;
|
||||||
|
import org.eclipse.aether.transfer.TransferCancelledException;
|
||||||
|
import org.eclipse.aether.transfer.TransferEvent;
|
||||||
|
import org.eclipse.aether.transport.http.HttpTransporterFactory;
|
||||||
|
|
||||||
|
class LibraryLoader
|
||||||
|
{
|
||||||
|
|
||||||
|
private final Logger logger;
|
||||||
|
private final RepositorySystem repository;
|
||||||
|
private final DefaultRepositorySystemSession session;
|
||||||
|
private final List<RemoteRepository> repositories;
|
||||||
|
|
||||||
|
public LibraryLoader(Logger logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
|
||||||
|
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
|
||||||
|
locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
|
||||||
|
locator.addService( TransporterFactory.class, HttpTransporterFactory.class );
|
||||||
|
|
||||||
|
this.repository = locator.getService( RepositorySystem.class );
|
||||||
|
this.session = MavenRepositorySystemUtils.newSession();
|
||||||
|
|
||||||
|
session.setChecksumPolicy( RepositoryPolicy.CHECKSUM_POLICY_FAIL );
|
||||||
|
session.setLocalRepositoryManager( repository.newLocalRepositoryManager( session, new LocalRepository( "libraries" ) ) );
|
||||||
|
session.setTransferListener( new AbstractTransferListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void transferStarted(TransferEvent event) throws TransferCancelledException
|
||||||
|
{
|
||||||
|
logger.log( Level.INFO, "Downloading {0}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
session.setReadOnly();
|
||||||
|
|
||||||
|
this.repositories = repository.newResolutionRepositories( session, Arrays.asList( new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2" ).build() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassLoader createLoader(PluginDescription desc)
|
||||||
|
{
|
||||||
|
if ( desc.getLibraries().isEmpty() )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
logger.log( Level.INFO, "[{0}] Loading {1} libraries... please wait", new Object[]
|
||||||
|
{
|
||||||
|
desc.getName(), desc.getLibraries().size()
|
||||||
|
} );
|
||||||
|
|
||||||
|
List<Dependency> dependencies = new ArrayList<>();
|
||||||
|
for ( String library : desc.getLibraries() )
|
||||||
|
{
|
||||||
|
Artifact artifact = new DefaultArtifact( library );
|
||||||
|
Dependency dependency = new Dependency( artifact, null );
|
||||||
|
|
||||||
|
dependencies.add( dependency );
|
||||||
|
}
|
||||||
|
|
||||||
|
DependencyResult result;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = repository.resolveDependencies( session, new DependencyRequest( new CollectRequest( (Dependency) null, dependencies, repositories ), null ) );
|
||||||
|
} catch ( DependencyResolutionException ex )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( "Error resolving libraries", ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
List<URL> jarFiles = new ArrayList<>();
|
||||||
|
for ( ArtifactResult artifact : result.getArtifactResults() )
|
||||||
|
{
|
||||||
|
File file = artifact.getArtifact().getFile();
|
||||||
|
|
||||||
|
URL url;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
url = file.toURI().toURL();
|
||||||
|
} catch ( MalformedURLException ex )
|
||||||
|
{
|
||||||
|
throw new AssertionError( ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
jarFiles.add( url );
|
||||||
|
logger.log( Level.INFO, "[{0}] Loaded library {1}", new Object[]
|
||||||
|
{
|
||||||
|
desc.getName(), file
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
URLClassLoader loader = new URLClassLoader( jarFiles.toArray( new URL[ 0 ] ) );
|
||||||
|
|
||||||
|
return loader;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,12 +1,23 @@
|
|||||||
package net.md_5.bungee.api.plugin;
|
package net.md_5.bungee.api.plugin;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.security.CodeSigner;
|
||||||
|
import java.security.CodeSource;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
import lombok.ToString;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
|
@ToString(of = "desc")
|
||||||
final class PluginClassloader extends URLClassLoader
|
final class PluginClassloader extends URLClassLoader
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -14,6 +25,10 @@ final class PluginClassloader extends URLClassLoader
|
|||||||
//
|
//
|
||||||
private final ProxyServer proxy;
|
private final ProxyServer proxy;
|
||||||
private final PluginDescription desc;
|
private final PluginDescription desc;
|
||||||
|
private final JarFile jar;
|
||||||
|
private final Manifest manifest;
|
||||||
|
private final URL url;
|
||||||
|
private final ClassLoader libraryLoader;
|
||||||
//
|
//
|
||||||
private Plugin plugin;
|
private Plugin plugin;
|
||||||
|
|
||||||
@@ -22,11 +37,18 @@ final class PluginClassloader extends URLClassLoader
|
|||||||
ClassLoader.registerAsParallelCapable();
|
ClassLoader.registerAsParallelCapable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginClassloader(ProxyServer proxy, PluginDescription desc, URL[] urls)
|
public PluginClassloader(ProxyServer proxy, PluginDescription desc, File file, ClassLoader libraryLoader) throws IOException
|
||||||
{
|
{
|
||||||
super( urls );
|
super( new URL[]
|
||||||
|
{
|
||||||
|
file.toURI().toURL()
|
||||||
|
} );
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
this.desc = desc;
|
this.desc = desc;
|
||||||
|
this.jar = new JarFile( file );
|
||||||
|
this.manifest = jar.getManifest();
|
||||||
|
this.url = file.toURI().toURL();
|
||||||
|
this.libraryLoader = libraryLoader;
|
||||||
|
|
||||||
allLoaders.add( this );
|
allLoaders.add( this );
|
||||||
}
|
}
|
||||||
@@ -34,17 +56,34 @@ final class PluginClassloader extends URLClassLoader
|
|||||||
@Override
|
@Override
|
||||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
|
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
|
||||||
{
|
{
|
||||||
return loadClass0( name, resolve, true );
|
return loadClass0( name, resolve, true, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> loadClass0(String name, boolean resolve, boolean checkOther) throws ClassNotFoundException
|
private Class<?> loadClass0(String name, boolean resolve, boolean checkOther, boolean checkLibraries) throws ClassNotFoundException
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return super.loadClass( name, resolve );
|
Class<?> result = super.loadClass( name, resolve );
|
||||||
|
|
||||||
|
// SPIGOT-6749: Library classes will appear in the above, but we don't want to return them to other plugins
|
||||||
|
if ( checkOther || result.getClassLoader() == this )
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
} catch ( ClassNotFoundException ex )
|
} catch ( ClassNotFoundException ex )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( checkLibraries && libraryLoader != null )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return libraryLoader.loadClass( name );
|
||||||
|
} catch ( ClassNotFoundException ex )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( checkOther )
|
if ( checkOther )
|
||||||
{
|
{
|
||||||
for ( PluginClassloader loader : allLoaders )
|
for ( PluginClassloader loader : allLoaders )
|
||||||
@@ -53,16 +92,81 @@ final class PluginClassloader extends URLClassLoader
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return loader.loadClass0( name, resolve, false );
|
return loader.loadClass0( name, resolve, false, proxy.getPluginManager().isTransitiveDepend( desc, loader.desc ) );
|
||||||
} catch ( ClassNotFoundException ex )
|
} catch ( ClassNotFoundException ex )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ClassNotFoundException( name );
|
throw new ClassNotFoundException( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
String path = name.replace( '.', '/' ).concat( ".class" );
|
||||||
|
JarEntry entry = jar.getJarEntry( path );
|
||||||
|
|
||||||
|
if ( entry != null )
|
||||||
|
{
|
||||||
|
byte[] classBytes;
|
||||||
|
|
||||||
|
try ( InputStream is = jar.getInputStream( entry ) )
|
||||||
|
{
|
||||||
|
classBytes = ByteStreams.toByteArray( is );
|
||||||
|
} catch ( IOException ex )
|
||||||
|
{
|
||||||
|
throw new ClassNotFoundException( name, ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
int dot = name.lastIndexOf( '.' );
|
||||||
|
if ( dot != -1 )
|
||||||
|
{
|
||||||
|
String pkgName = name.substring( 0, dot );
|
||||||
|
if ( getPackage( pkgName ) == null )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( manifest != null )
|
||||||
|
{
|
||||||
|
definePackage( pkgName, manifest, url );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
definePackage( pkgName, null, null, null, null, null, null, null );
|
||||||
|
}
|
||||||
|
} catch ( IllegalArgumentException ex )
|
||||||
|
{
|
||||||
|
if ( getPackage( pkgName ) == null )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Cannot find package " + pkgName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeSigner[] signers = entry.getCodeSigners();
|
||||||
|
CodeSource source = new CodeSource( url, signers );
|
||||||
|
|
||||||
|
return defineClass( name, classBytes, 0, classBytes.length, source );
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.findClass( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
super.close();
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
jar.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init(Plugin plugin)
|
void init(Plugin plugin)
|
||||||
{
|
{
|
||||||
Preconditions.checkArgument( plugin != null, "plugin" );
|
Preconditions.checkArgument( plugin != null, "plugin" );
|
||||||
|
@@ -2,6 +2,8 @@ package net.md_5.bungee.api.plugin;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -48,4 +50,8 @@ public class PluginDescription
|
|||||||
* Optional description.
|
* Optional description.
|
||||||
*/
|
*/
|
||||||
private String description = null;
|
private String description = null;
|
||||||
|
/**
|
||||||
|
* Optional libraries.
|
||||||
|
*/
|
||||||
|
private List<String> libraries = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
@@ -4,10 +4,12 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
import com.google.common.graph.GraphBuilder;
|
||||||
|
import com.google.common.graph.Graphs;
|
||||||
|
import com.google.common.graph.MutableGraph;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -31,6 +33,7 @@ import net.md_5.bungee.api.ProxyServer;
|
|||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.event.EventBus;
|
import net.md_5.bungee.event.EventBus;
|
||||||
import net.md_5.bungee.event.EventHandler;
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
import org.yaml.snakeyaml.LoaderOptions;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
import org.yaml.snakeyaml.constructor.Constructor;
|
import org.yaml.snakeyaml.constructor.Constructor;
|
||||||
import org.yaml.snakeyaml.introspector.PropertyUtils;
|
import org.yaml.snakeyaml.introspector.PropertyUtils;
|
||||||
@@ -49,6 +52,8 @@ public final class PluginManager
|
|||||||
private final Yaml yaml;
|
private final Yaml yaml;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final Map<String, Plugin> plugins = new LinkedHashMap<>();
|
private final Map<String, Plugin> plugins = new LinkedHashMap<>();
|
||||||
|
private final MutableGraph<String> dependencyGraph = GraphBuilder.directed().build();
|
||||||
|
private final LibraryLoader libraryLoader;
|
||||||
private final Map<String, Command> commandMap = new HashMap<>();
|
private final Map<String, Command> commandMap = new HashMap<>();
|
||||||
private Map<String, PluginDescription> toLoad = new HashMap<>();
|
private Map<String, PluginDescription> toLoad = new HashMap<>();
|
||||||
private final Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create();
|
private final Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create();
|
||||||
@@ -60,13 +65,24 @@ public final class PluginManager
|
|||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
|
|
||||||
// Ignore unknown entries in the plugin descriptions
|
// Ignore unknown entries in the plugin descriptions
|
||||||
Constructor yamlConstructor = new Constructor();
|
Constructor yamlConstructor = new Constructor( new LoaderOptions() );
|
||||||
PropertyUtils propertyUtils = yamlConstructor.getPropertyUtils();
|
PropertyUtils propertyUtils = yamlConstructor.getPropertyUtils();
|
||||||
propertyUtils.setSkipMissingProperties( true );
|
propertyUtils.setSkipMissingProperties( true );
|
||||||
yamlConstructor.setPropertyUtils( propertyUtils );
|
yamlConstructor.setPropertyUtils( propertyUtils );
|
||||||
yaml = new Yaml( yamlConstructor );
|
yaml = new Yaml( yamlConstructor );
|
||||||
|
|
||||||
eventBus = new EventBus( proxy.getLogger() );
|
eventBus = new EventBus( proxy.getLogger() );
|
||||||
|
|
||||||
|
LibraryLoader libraryLoader = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
libraryLoader = new LibraryLoader( proxy.getLogger() );
|
||||||
|
} catch ( NoClassDefFoundError ex )
|
||||||
|
{
|
||||||
|
// Provided depends were not added back
|
||||||
|
proxy.getLogger().warning( "Could not initialize LibraryLoader (missing dependencies?)" );
|
||||||
|
}
|
||||||
|
this.libraryLoader = libraryLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,6 +325,7 @@ public final class PluginManager
|
|||||||
status = false;
|
status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencyGraph.putEdge( plugin.getName(), dependName );
|
||||||
if ( !status )
|
if ( !status )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -320,10 +337,7 @@ public final class PluginManager
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
URLClassLoader loader = new PluginClassloader( proxy, plugin, new URL[]
|
URLClassLoader loader = new PluginClassloader( proxy, plugin, plugin.getFile(), ( libraryLoader != null ) ? libraryLoader.createLoader( plugin ) : null );
|
||||||
{
|
|
||||||
plugin.getFile().toURI().toURL()
|
|
||||||
} );
|
|
||||||
Class<?> main = loader.loadClass( plugin.getMain() );
|
Class<?> main = loader.loadClass( plugin.getMain() );
|
||||||
Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance();
|
Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
@@ -335,7 +349,7 @@ public final class PluginManager
|
|||||||
} );
|
} );
|
||||||
} catch ( Throwable t )
|
} catch ( Throwable t )
|
||||||
{
|
{
|
||||||
proxy.getLogger().log( Level.WARNING, "Error enabling plugin " + plugin.getName(), t );
|
proxy.getLogger().log( Level.WARNING, "Error loading plugin " + plugin.getName(), t );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,4 +477,19 @@ public final class PluginManager
|
|||||||
{
|
{
|
||||||
return Collections.unmodifiableCollection( commandMap.entrySet() );
|
return Collections.unmodifiableCollection( commandMap.entrySet() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isTransitiveDepend(PluginDescription plugin, PluginDescription depend)
|
||||||
|
{
|
||||||
|
Preconditions.checkArgument( plugin != null, "plugin" );
|
||||||
|
Preconditions.checkArgument( depend != null, "depend" );
|
||||||
|
|
||||||
|
if ( dependencyGraph.nodes().contains( plugin.getName() ) )
|
||||||
|
{
|
||||||
|
if ( Graphs.reachableNodes( dependencyGraph, plugin.getName() ).contains( depend.getName() ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
package net.md_5.bungee.api;
|
package net.md_5.bungee.api;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
import net.md_5.bungee.api.event.ServerConnectEvent;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class ServerConnectRequestTest
|
public class ServerConnectRequestTest
|
||||||
{
|
{
|
||||||
@@ -78,15 +79,15 @@ public class ServerConnectRequestTest
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Test(expected = NullPointerException.class)
|
@Test
|
||||||
public void testNullTarget()
|
public void testNullTarget()
|
||||||
{
|
{
|
||||||
ServerConnectRequest.builder().target( null ).reason( ServerConnectEvent.Reason.JOIN_PROXY ).build();
|
assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( null ).reason( ServerConnectEvent.Reason.JOIN_PROXY ).build() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = NullPointerException.class)
|
@Test
|
||||||
public void testNullReason()
|
public void testNullReason()
|
||||||
{
|
{
|
||||||
ServerConnectRequest.builder().target( DUMMY_INFO ).reason( null ).build();
|
assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( DUMMY_INFO ).reason( null ).build() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,63 +1,38 @@
|
|||||||
package net.md_5.bungee.util;
|
package net.md_5.bungee.util;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import io.netty.channel.unix.DomainSocketAddress;
|
import io.netty.channel.unix.DomainSocketAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.Arrays;
|
import java.util.stream.Stream;
|
||||||
import java.util.Collection;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.md_5.bungee.Util;
|
import net.md_5.bungee.Util;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class AddressParseTest
|
public class AddressParseTest
|
||||||
{
|
{
|
||||||
|
|
||||||
@Parameters
|
public static Stream<Arguments> data()
|
||||||
public static Collection<Object[]> data()
|
|
||||||
{
|
{
|
||||||
return Arrays.asList( new Object[][]
|
return Stream.of(
|
||||||
{
|
Arguments.of( "127.0.0.1", "127.0.0.1", Util.DEFAULT_PORT ),
|
||||||
{
|
Arguments.of( "127.0.0.1:1337", "127.0.0.1", 1337 ),
|
||||||
"127.0.0.1", "127.0.0.1", Util.DEFAULT_PORT
|
Arguments.of( "[::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT ),
|
||||||
},
|
Arguments.of( "[0:0:0:0::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT ),
|
||||||
{
|
Arguments.of( "[0:0:0:0:0:0:0:1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT ),
|
||||||
"127.0.0.1:1337", "127.0.0.1", 1337
|
Arguments.of( "[::1]:1337", "0:0:0:0:0:0:0:1", 1337 ),
|
||||||
},
|
Arguments.of( "[0:0:0:0::1]:1337", "0:0:0:0:0:0:0:1", 1337 ),
|
||||||
{
|
Arguments.of( "[0:0:0:0:0:0:0:1]:1337", "0:0:0:0:0:0:0:1", 1337 ),
|
||||||
"[::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT
|
Arguments.of( "unix:///var/run/bungee.sock", "/var/run/bungee.sock", -1 )
|
||||||
},
|
);
|
||||||
{
|
|
||||||
"[0:0:0:0::1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"[0:0:0:0:0:0:0:1]", "0:0:0:0:0:0:0:1", Util.DEFAULT_PORT
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"[::1]:1337", "0:0:0:0:0:0:0:1", 1337
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"[0:0:0:0::1]:1337", "0:0:0:0:0:0:0:1", 1337
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"[0:0:0:0:0:0:0:1]:1337", "0:0:0:0:0:0:0:1", 1337
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unix:///var/run/bungee.sock", "/var/run/bungee.sock", -1
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
private final String line;
|
|
||||||
private final String host;
|
|
||||||
private final int port;
|
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void test()
|
@MethodSource("data")
|
||||||
|
public void test(String line, String host, int port)
|
||||||
{
|
{
|
||||||
SocketAddress parsed = Util.getAddr( line );
|
SocketAddress parsed = Util.getAddr( line );
|
||||||
|
|
||||||
@@ -65,14 +40,14 @@ public class AddressParseTest
|
|||||||
{
|
{
|
||||||
InetSocketAddress tcp = (InetSocketAddress) parsed;
|
InetSocketAddress tcp = (InetSocketAddress) parsed;
|
||||||
|
|
||||||
Assert.assertEquals( host, tcp.getHostString() );
|
assertEquals( host, tcp.getHostString() );
|
||||||
Assert.assertEquals( port, tcp.getPort() );
|
assertEquals( port, tcp.getPort() );
|
||||||
} else if ( parsed instanceof DomainSocketAddress )
|
} else if ( parsed instanceof DomainSocketAddress )
|
||||||
{
|
{
|
||||||
DomainSocketAddress unix = (DomainSocketAddress) parsed;
|
DomainSocketAddress unix = (DomainSocketAddress) parsed;
|
||||||
|
|
||||||
Assert.assertEquals( host, unix.path() );
|
assertEquals( host, unix.path() );
|
||||||
Assert.assertEquals( -1, port );
|
assertEquals( -1, port );
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
throw new AssertionError( "Unknown socket " + parsed );
|
throw new AssertionError( "Unknown socket " + parsed );
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package net.md_5.bungee.util;
|
package net.md_5.bungee.util;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class CaseInsensitiveTest
|
public class CaseInsensitiveTest
|
||||||
{
|
{
|
||||||
@@ -13,12 +13,12 @@ public class CaseInsensitiveTest
|
|||||||
CaseInsensitiveMap<Object> map = new CaseInsensitiveMap<>();
|
CaseInsensitiveMap<Object> map = new CaseInsensitiveMap<>();
|
||||||
|
|
||||||
map.put( "FOO", obj );
|
map.put( "FOO", obj );
|
||||||
Assert.assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive
|
assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive
|
||||||
Assert.assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved
|
assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved
|
||||||
|
|
||||||
// Assert that remove is case insensitive
|
// Assert that remove is case insensitive
|
||||||
map.remove( "FoO" );
|
map.remove( "FoO" );
|
||||||
Assert.assertFalse( map.contains( "foo" ) );
|
assertFalse( map.contains( "foo" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -27,8 +27,8 @@ public class CaseInsensitiveTest
|
|||||||
CaseInsensitiveSet set = new CaseInsensitiveSet();
|
CaseInsensitiveSet set = new CaseInsensitiveSet();
|
||||||
|
|
||||||
set.add( "FOO" );
|
set.add( "FOO" );
|
||||||
Assert.assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive
|
assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive
|
||||||
set.remove( "FoO" );
|
set.remove( "FoO" );
|
||||||
Assert.assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive
|
assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package net.md_5.bungee.util;
|
package net.md_5.bungee.util;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import net.md_5.bungee.Util;
|
import net.md_5.bungee.Util;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class UUIDTest
|
public class UUIDTest
|
||||||
{
|
{
|
||||||
@@ -13,7 +13,7 @@ public class UUIDTest
|
|||||||
{
|
{
|
||||||
UUID uuid = UUID.fromString( "af74a02d-19cb-445b-b07f-6866a861f783" );
|
UUID uuid = UUID.fromString( "af74a02d-19cb-445b-b07f-6866a861f783" );
|
||||||
UUID uuid1 = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" );
|
UUID uuid1 = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" );
|
||||||
Assert.assertEquals( uuid, uuid1 );
|
assertEquals( uuid, uuid1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -23,7 +23,7 @@ public class UUIDTest
|
|||||||
{
|
{
|
||||||
UUID expected = UUID.randomUUID();
|
UUID expected = UUID.randomUUID();
|
||||||
UUID actual = Util.getUUID( expected.toString().replace( "-", "" ) );
|
UUID actual = Util.getUUID( expected.toString().replace( "-", "" ) );
|
||||||
Assert.assertEquals( "Could not parse UUID " + expected, expected, actual );
|
assertEquals( expected, actual, "Could not parse UUID " + expected );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-bootstrap</artifactId>
|
<artifactId>bungeecord-bootstrap</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Bootstrap</name>
|
<name>BungeeCord-Bootstrap</name>
|
||||||
@@ -21,14 +20,12 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||||
<maven.compiler.source>1.6</maven.compiler.source>
|
|
||||||
<maven.compiler.target>1.6</maven.compiler.target>
|
|
||||||
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
|
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-proxy</artifactId>
|
<artifactId>bungeecord-proxy</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
@@ -41,7 +38,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.3.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifestEntries>
|
<manifestEntries>
|
||||||
@@ -55,7 +52,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.2.3</version>
|
<version>3.5.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -79,4 +76,34 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>jdk-9-release</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[9,)</jdk>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.release>6</maven.compiler.release>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>jdk-12-release</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[12,)</jdk>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.release>7</maven.compiler.release>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>jdk-20-release</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[20,)</jdk>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.release>8</maven.compiler.release>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Chat</name>
|
<name>BungeeCord-Chat</name>
|
||||||
@@ -22,7 +21,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.8.0</version>
|
<version>2.10.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@@ -300,7 +300,7 @@ public final class ChatColor
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static ChatColor[] values()
|
public static ChatColor[] values()
|
||||||
{
|
{
|
||||||
return BY_CHAR.values().toArray( new ChatColor[ BY_CHAR.values().size() ] );
|
return BY_CHAR.values().toArray( new ChatColor[ 0 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -78,6 +78,12 @@ public abstract class BaseComponent
|
|||||||
@Getter
|
@Getter
|
||||||
private HoverEvent hoverEvent;
|
private HoverEvent hoverEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this component rejects previous formatting
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private transient boolean reset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*
|
*
|
||||||
|
@@ -57,7 +57,7 @@ public final class ComponentBuilder
|
|||||||
*/
|
*/
|
||||||
public ComponentBuilder(ComponentBuilder original)
|
public ComponentBuilder(ComponentBuilder original)
|
||||||
{
|
{
|
||||||
this( original.parts.toArray( new BaseComponent[ original.parts.size() ] ) );
|
this( original.parts.toArray( new BaseComponent[ 0 ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,7 +161,7 @@ public final class ComponentBuilder
|
|||||||
previous = dummy;
|
previous = dummy;
|
||||||
dummy = null;
|
dummy = null;
|
||||||
}
|
}
|
||||||
if ( previous != null )
|
if ( previous != null && !component.isReset() )
|
||||||
{
|
{
|
||||||
component.copyFormatting( previous, retention, false );
|
component.copyFormatting( previous, retention, false );
|
||||||
}
|
}
|
||||||
@@ -454,9 +454,32 @@ public final class ComponentBuilder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the component built by this builder. If this builder is
|
||||||
|
* empty, an empty text component will be returned.
|
||||||
|
*
|
||||||
|
* @return the component
|
||||||
|
*/
|
||||||
|
public BaseComponent build()
|
||||||
|
{
|
||||||
|
TextComponent base = new TextComponent();
|
||||||
|
if ( !parts.isEmpty() )
|
||||||
|
{
|
||||||
|
List<BaseComponent> cloned = new ArrayList<>( parts );
|
||||||
|
cloned.replaceAll( BaseComponent::duplicate );
|
||||||
|
base.setExtra( cloned );
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the components needed to display the message created by this
|
* Returns the components needed to display the message created by this
|
||||||
* builder.git
|
* builder.git
|
||||||
|
* <p>
|
||||||
|
* <strong>NOTE:</strong> {@link #build()} is preferred as it will
|
||||||
|
* consolidate all components into a single BaseComponent with extra
|
||||||
|
* contents as opposed to an array of components which is non-standard
|
||||||
|
* and may result in unexpected behavior.
|
||||||
*
|
*
|
||||||
* @return the created components
|
* @return the created components
|
||||||
*/
|
*/
|
||||||
|
@@ -44,7 +44,7 @@ public final class TextComponent extends BaseComponent
|
|||||||
*/
|
*/
|
||||||
public static BaseComponent[] fromLegacyText(String message, ChatColor defaultColor)
|
public static BaseComponent[] fromLegacyText(String message, ChatColor defaultColor)
|
||||||
{
|
{
|
||||||
ArrayList<BaseComponent> components = new ArrayList<BaseComponent>();
|
ArrayList<BaseComponent> components = new ArrayList<>();
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
TextComponent component = new TextComponent();
|
TextComponent component = new TextComponent();
|
||||||
Matcher matcher = url.matcher( message );
|
Matcher matcher = url.matcher( message );
|
||||||
@@ -111,15 +111,15 @@ public final class TextComponent extends BaseComponent
|
|||||||
} else if ( format == ChatColor.MAGIC )
|
} else if ( format == ChatColor.MAGIC )
|
||||||
{
|
{
|
||||||
component.setObfuscated( true );
|
component.setObfuscated( true );
|
||||||
} else if ( format == ChatColor.RESET )
|
|
||||||
{
|
|
||||||
format = defaultColor;
|
|
||||||
component = new TextComponent();
|
|
||||||
component.setColor( format );
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
if ( format == ChatColor.RESET )
|
||||||
|
{
|
||||||
|
format = defaultColor;
|
||||||
|
}
|
||||||
component = new TextComponent();
|
component = new TextComponent();
|
||||||
component.setColor( format );
|
component.setColor( format );
|
||||||
|
component.setReset( true );
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ public final class TextComponent extends BaseComponent
|
|||||||
component.setText( builder.toString() );
|
component.setText( builder.toString() );
|
||||||
components.add( component );
|
components.add( component );
|
||||||
|
|
||||||
return components.toArray( new BaseComponent[ components.size() ] );
|
return components.toArray( new BaseComponent[ 0 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,6 +230,6 @@ public final class TextComponent extends BaseComponent
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format( "TextComponent{text=%s, %s}", text, super.toString() );
|
return "TextComponent{text=" + text + ", " + super.toString() + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,10 @@ public final class TranslatableComponent extends BaseComponent
|
|||||||
* The components to substitute into the translation
|
* The components to substitute into the translation
|
||||||
*/
|
*/
|
||||||
private List<BaseComponent> with;
|
private List<BaseComponent> with;
|
||||||
|
/**
|
||||||
|
* The fallback, if the translation is not found
|
||||||
|
*/
|
||||||
|
private String fallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a translatable component from the original to clone it.
|
* Creates a translatable component from the original to clone it.
|
||||||
@@ -153,6 +157,11 @@ public final class TranslatableComponent extends BaseComponent
|
|||||||
{
|
{
|
||||||
String trans = TranslationRegistry.INSTANCE.translate( translate );
|
String trans = TranslationRegistry.INSTANCE.translate( translate );
|
||||||
|
|
||||||
|
if ( trans.equals( translate ) && fallback != null )
|
||||||
|
{
|
||||||
|
trans = fallback;
|
||||||
|
}
|
||||||
|
|
||||||
Matcher matcher = format.matcher( trans );
|
Matcher matcher = format.matcher( trans );
|
||||||
int position = 0;
|
int position = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@@ -23,6 +23,12 @@ public class Text extends Content
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Text(BaseComponent value)
|
||||||
|
{
|
||||||
|
// For legacy serialization reasons, this has to be an array of components
|
||||||
|
this( new BaseComponent[]{value} );
|
||||||
|
}
|
||||||
|
|
||||||
public Text(String value)
|
public Text(String value)
|
||||||
{
|
{
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
@@ -22,14 +22,6 @@ public class BaseComponentSerializer
|
|||||||
|
|
||||||
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context)
|
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context)
|
||||||
{
|
{
|
||||||
if ( object.has( "color" ) )
|
|
||||||
{
|
|
||||||
component.setColor( ChatColor.of( object.get( "color" ).getAsString() ) );
|
|
||||||
}
|
|
||||||
if ( object.has( "font" ) )
|
|
||||||
{
|
|
||||||
component.setFont( object.get( "font" ).getAsString() );
|
|
||||||
}
|
|
||||||
if ( object.has( "bold" ) )
|
if ( object.has( "bold" ) )
|
||||||
{
|
{
|
||||||
component.setBold( object.get( "bold" ).getAsBoolean() );
|
component.setBold( object.get( "bold" ).getAsBoolean() );
|
||||||
@@ -50,14 +42,14 @@ public class BaseComponentSerializer
|
|||||||
{
|
{
|
||||||
component.setObfuscated( object.get( "obfuscated" ).getAsBoolean() );
|
component.setObfuscated( object.get( "obfuscated" ).getAsBoolean() );
|
||||||
}
|
}
|
||||||
|
if ( object.has( "color" ) )
|
||||||
|
{
|
||||||
|
component.setColor( ChatColor.of( object.get( "color" ).getAsString() ) );
|
||||||
|
}
|
||||||
if ( object.has( "insertion" ) )
|
if ( object.has( "insertion" ) )
|
||||||
{
|
{
|
||||||
component.setInsertion( object.get( "insertion" ).getAsString() );
|
component.setInsertion( object.get( "insertion" ).getAsString() );
|
||||||
}
|
}
|
||||||
if ( object.has( "extra" ) )
|
|
||||||
{
|
|
||||||
component.setExtra( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "extra" ), BaseComponent[].class ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//Events
|
//Events
|
||||||
if ( object.has( "clickEvent" ) )
|
if ( object.has( "clickEvent" ) )
|
||||||
@@ -93,7 +85,7 @@ public class BaseComponentSerializer
|
|||||||
{
|
{
|
||||||
components = new BaseComponent[]
|
components = new BaseComponent[]
|
||||||
{
|
{
|
||||||
context.deserialize( contents, BaseComponent.class )
|
context.deserialize( contents, BaseComponent.class )
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
hoverEvent = new HoverEvent( action, components );
|
hoverEvent = new HoverEvent( action, components );
|
||||||
@@ -121,6 +113,15 @@ public class BaseComponentSerializer
|
|||||||
component.setHoverEvent( hoverEvent );
|
component.setHoverEvent( hoverEvent );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( object.has( "font" ) )
|
||||||
|
{
|
||||||
|
component.setFont( object.get( "font" ).getAsString() );
|
||||||
|
}
|
||||||
|
if ( object.has( "extra" ) )
|
||||||
|
{
|
||||||
|
component.setExtra( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "extra" ), BaseComponent[].class ) ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context)
|
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context)
|
||||||
@@ -135,14 +136,6 @@ public class BaseComponentSerializer
|
|||||||
{
|
{
|
||||||
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
|
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
|
||||||
ComponentSerializer.serializedComponents.get().add( component );
|
ComponentSerializer.serializedComponents.get().add( component );
|
||||||
if ( component.getColorRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "color", component.getColorRaw().getName() );
|
|
||||||
}
|
|
||||||
if ( component.getFontRaw() != null )
|
|
||||||
{
|
|
||||||
object.addProperty( "font", component.getFontRaw() );
|
|
||||||
}
|
|
||||||
if ( component.isBoldRaw() != null )
|
if ( component.isBoldRaw() != null )
|
||||||
{
|
{
|
||||||
object.addProperty( "bold", component.isBoldRaw() );
|
object.addProperty( "bold", component.isBoldRaw() );
|
||||||
@@ -163,16 +156,15 @@ public class BaseComponentSerializer
|
|||||||
{
|
{
|
||||||
object.addProperty( "obfuscated", component.isObfuscatedRaw() );
|
object.addProperty( "obfuscated", component.isObfuscatedRaw() );
|
||||||
}
|
}
|
||||||
|
if ( component.getColorRaw() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "color", component.getColorRaw().getName() );
|
||||||
|
}
|
||||||
if ( component.getInsertion() != null )
|
if ( component.getInsertion() != null )
|
||||||
{
|
{
|
||||||
object.addProperty( "insertion", component.getInsertion() );
|
object.addProperty( "insertion", component.getInsertion() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( component.getExtra() != null )
|
|
||||||
{
|
|
||||||
object.add( "extra", context.serialize( component.getExtra() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//Events
|
//Events
|
||||||
if ( component.getClickEvent() != null )
|
if ( component.getClickEvent() != null )
|
||||||
{
|
{
|
||||||
@@ -195,6 +187,15 @@ public class BaseComponentSerializer
|
|||||||
}
|
}
|
||||||
object.add( "hoverEvent", hoverEvent );
|
object.add( "hoverEvent", hoverEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( component.getFontRaw() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "font", component.getFontRaw() );
|
||||||
|
}
|
||||||
|
if ( component.getExtra() != null )
|
||||||
|
{
|
||||||
|
object.add( "extra", context.serialize( component.getExtra() ) );
|
||||||
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
ComponentSerializer.serializedComponents.get().remove( component );
|
ComponentSerializer.serializedComponents.get().remove( component );
|
||||||
|
@@ -27,7 +27,6 @@ import net.md_5.bungee.api.chat.hover.content.TextSerializer;
|
|||||||
public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final JsonParser JSON_PARSER = new JsonParser();
|
|
||||||
private static final Gson gson = new GsonBuilder().
|
private static final Gson gson = new GsonBuilder().
|
||||||
registerTypeAdapter( BaseComponent.class, new ComponentSerializer() ).
|
registerTypeAdapter( BaseComponent.class, new ComponentSerializer() ).
|
||||||
registerTypeAdapter( TextComponent.class, new TextComponentSerializer() ).
|
registerTypeAdapter( TextComponent.class, new TextComponentSerializer() ).
|
||||||
@@ -43,9 +42,25 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
|||||||
|
|
||||||
public static final ThreadLocal<Set<BaseComponent>> serializedComponents = new ThreadLocal<Set<BaseComponent>>();
|
public static final ThreadLocal<Set<BaseComponent>> serializedComponents = new ThreadLocal<Set<BaseComponent>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a JSON-compliant String as an array of base components. The input
|
||||||
|
* can be one of either an array of components, or a single component object.
|
||||||
|
* If the input is an array, each component will be parsed individually and
|
||||||
|
* returned in the order that they were parsed. If the input is a single
|
||||||
|
* component object, a single-valued array with the component will be returned.
|
||||||
|
* <p>
|
||||||
|
* <strong>NOTE:</strong> {@link #deserialize(String)} is preferred as it will
|
||||||
|
* parse only one component as opposed to an array of components which is non-
|
||||||
|
* standard behavior. This method is still appropriate for parsing multiple
|
||||||
|
* components at once, although such use case is rarely (if at all) exhibited
|
||||||
|
* in vanilla Minecraft.
|
||||||
|
*
|
||||||
|
* @param json the component json to parse
|
||||||
|
* @return an array of all parsed components
|
||||||
|
*/
|
||||||
public static BaseComponent[] parse(String json)
|
public static BaseComponent[] parse(String json)
|
||||||
{
|
{
|
||||||
JsonElement jsonElement = JSON_PARSER.parse( json );
|
JsonElement jsonElement = JsonParser.parseString( json );
|
||||||
|
|
||||||
if ( jsonElement.isJsonArray() )
|
if ( jsonElement.isJsonArray() )
|
||||||
{
|
{
|
||||||
@@ -59,6 +74,26 @@ public class ComponentSerializer implements JsonDeserializer<BaseComponent>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize a JSON-compliant String as a single component. The input is
|
||||||
|
* expected to be a JSON object that represents only one component.
|
||||||
|
*
|
||||||
|
* @param json the component json to parse
|
||||||
|
* @return the deserialized component
|
||||||
|
* @throws IllegalArgumentException if anything other than a JSON object is
|
||||||
|
* passed as input
|
||||||
|
*/
|
||||||
|
public static BaseComponent deserialize(String json)
|
||||||
|
{
|
||||||
|
JsonElement jsonElement = JsonParser.parseString( json );
|
||||||
|
if ( !jsonElement.isJsonObject() )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( "Malformatted JSON. Expected object, got array for input \"" + json + "\"." );
|
||||||
|
}
|
||||||
|
|
||||||
|
return gson.fromJson( jsonElement, BaseComponent.class );
|
||||||
|
}
|
||||||
|
|
||||||
public static String toString(Object object)
|
public static String toString(Object object)
|
||||||
{
|
{
|
||||||
return gson.toJson( object );
|
return gson.toJson( object );
|
||||||
|
@@ -8,8 +8,6 @@ import com.google.gson.JsonParseException;
|
|||||||
import com.google.gson.JsonSerializationContext;
|
import com.google.gson.JsonSerializationContext;
|
||||||
import com.google.gson.JsonSerializer;
|
import com.google.gson.JsonSerializer;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.List;
|
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
|
||||||
public class TextComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TextComponent>, JsonDeserializer<TextComponent>
|
public class TextComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TextComponent>, JsonDeserializer<TextComponent>
|
||||||
@@ -32,13 +30,9 @@ public class TextComponentSerializer extends BaseComponentSerializer implements
|
|||||||
@Override
|
@Override
|
||||||
public JsonElement serialize(TextComponent src, Type typeOfSrc, JsonSerializationContext context)
|
public JsonElement serialize(TextComponent src, Type typeOfSrc, JsonSerializationContext context)
|
||||||
{
|
{
|
||||||
List<BaseComponent> extra = src.getExtra();
|
|
||||||
JsonObject object = new JsonObject();
|
JsonObject object = new JsonObject();
|
||||||
|
serialize( object, src, context );
|
||||||
object.addProperty( "text", src.getText() );
|
object.addProperty( "text", src.getText() );
|
||||||
if ( src.hasFormatting() || ( extra != null && !extra.isEmpty() ) )
|
|
||||||
{
|
|
||||||
serialize( object, src, context );
|
|
||||||
}
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,11 @@ public class TranslatableComponentSerializer extends BaseComponentSerializer imp
|
|||||||
component.setTranslate( object.get( "translate" ).getAsString() );
|
component.setTranslate( object.get( "translate" ).getAsString() );
|
||||||
if ( object.has( "with" ) )
|
if ( object.has( "with" ) )
|
||||||
{
|
{
|
||||||
component.setWith( Arrays.asList( context.<BaseComponent[]>deserialize( object.get( "with" ), BaseComponent[].class ) ) );
|
component.setWith( Arrays.asList( context.deserialize( object.get( "with" ), BaseComponent[].class ) ) );
|
||||||
|
}
|
||||||
|
if ( object.has( "fallback" ) )
|
||||||
|
{
|
||||||
|
component.setFallback( object.get( "fallback" ).getAsString() );
|
||||||
}
|
}
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
@@ -43,6 +47,10 @@ public class TranslatableComponentSerializer extends BaseComponentSerializer imp
|
|||||||
{
|
{
|
||||||
object.add( "with", context.serialize( src.getWith() ) );
|
object.add( "with", context.serialize( src.getWith() ) );
|
||||||
}
|
}
|
||||||
|
if ( src.getFallback() != null )
|
||||||
|
{
|
||||||
|
object.addProperty( "fallback", src.getFallback() );
|
||||||
|
}
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,17 @@
|
|||||||
package net.md_5.bungee.api.chat;
|
package net.md_5.bungee.api.chat;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.ObjIntConsumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.chat.hover.content.Item;
|
import net.md_5.bungee.api.chat.hover.content.Item;
|
||||||
import net.md_5.bungee.api.chat.hover.content.Text;
|
import net.md_5.bungee.api.chat.hover.content.Text;
|
||||||
import net.md_5.bungee.chat.ComponentSerializer;
|
import net.md_5.bungee.chat.ComponentSerializer;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ComponentsTest
|
public class ComponentsTest
|
||||||
{
|
{
|
||||||
@@ -15,13 +20,27 @@ public class ComponentsTest
|
|||||||
{
|
{
|
||||||
String json = ComponentSerializer.toString( components );
|
String json = ComponentSerializer.toString( components );
|
||||||
BaseComponent[] parsed = ComponentSerializer.parse( json );
|
BaseComponent[] parsed = ComponentSerializer.parse( json );
|
||||||
Assert.assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( components ) );
|
assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( components ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void testDissembleReassemble(String json)
|
public static void testDissembleReassemble(BaseComponent component)
|
||||||
{
|
{
|
||||||
|
String json = ComponentSerializer.toString( component );
|
||||||
BaseComponent[] parsed = ComponentSerializer.parse( json );
|
BaseComponent[] parsed = ComponentSerializer.parse( json );
|
||||||
Assert.assertEquals( json, ComponentSerializer.toString( parsed ) );
|
assertEquals( TextComponent.toLegacyText( parsed ), TextComponent.toLegacyText( component ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void testAssembleDissemble(String json, boolean modern)
|
||||||
|
{
|
||||||
|
if ( modern )
|
||||||
|
{
|
||||||
|
BaseComponent deserialized = ComponentSerializer.deserialize( json );
|
||||||
|
assertEquals( json, ComponentSerializer.toString( deserialized ) );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
BaseComponent[] parsed = ComponentSerializer.parse( json );
|
||||||
|
assertEquals( json, ComponentSerializer.toString( parsed ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -41,14 +60,16 @@ public class ComponentsTest
|
|||||||
{
|
{
|
||||||
textComponent
|
textComponent
|
||||||
} );
|
} );
|
||||||
json = "{\"text\":\"Test\",\"hoverEvent\":{\"action\":\"show_item\",\"value\":[{\"text\":\"{id:\\\"minecraft:netherrack\\\",Count:47b}\"}]}}";
|
testDissembleReassemble( textComponent );
|
||||||
testDissembleReassemble( json );
|
json = "{\"hoverEvent\":{\"action\":\"show_item\",\"value\":[{\"text\":\"{id:\\\"minecraft:netherrack\\\",Count:47b}\"}]},\"text\":\"Test\"}";
|
||||||
|
testAssembleDissemble( json, false );
|
||||||
|
testAssembleDissemble( json, true );
|
||||||
//////////
|
//////////
|
||||||
String hoverVal = "{\"text\":\"{id:\\\"minecraft:dirt\\\",Count:1b}\"}";
|
String hoverVal = "{\"text\":\"{id:\\\"minecraft:dirt\\\",Count:1b}\"}";
|
||||||
json = "{\"extra\":[{\"text\":\"[\"},{\"extra\":[{\"translate\":\"block.minecraft.dirt\"}],\"text\":\"\"},{\"text\":\"]\"}],\"hoverEvent\":{\"action\":\"show_item\",\"value\":[" + hoverVal + "]},\"text\":\"\"}";
|
json = "{\"extra\":[{\"text\":\"[\"},{\"extra\":[{\"translate\":\"block.minecraft.dirt\"}],\"text\":\"\"},{\"text\":\"]\"}],\"hoverEvent\":{\"action\":\"show_item\",\"value\":[" + hoverVal + "]},\"text\":\"\"}";
|
||||||
components = ComponentSerializer.parse( json );
|
components = ComponentSerializer.parse( json );
|
||||||
Text contentText = ( (Text) components[0].getHoverEvent().getContents().get( 0 ) );
|
Text contentText = ( (Text) components[0].getHoverEvent().getContents().get( 0 ) );
|
||||||
Assert.assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) );
|
assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) );
|
||||||
testDissembleReassemble( components );
|
testDissembleReassemble( components );
|
||||||
//////////
|
//////////
|
||||||
TextComponent component1 = new TextComponent( "HoverableText" );
|
TextComponent component1 = new TextComponent( "HoverableText" );
|
||||||
@@ -59,25 +80,44 @@ public class ComponentsTest
|
|||||||
json = ComponentSerializer.toString( component1 );
|
json = ComponentSerializer.toString( component1 );
|
||||||
components = ComponentSerializer.parse( json );
|
components = ComponentSerializer.parse( json );
|
||||||
Item parsedContentItem = ( (Item) components[0].getHoverEvent().getContents().get( 0 ) );
|
Item parsedContentItem = ( (Item) components[0].getHoverEvent().getContents().get( 0 ) );
|
||||||
Assert.assertEquals( contentItem, parsedContentItem );
|
assertEquals( contentItem, parsedContentItem );
|
||||||
Assert.assertEquals( contentItem.getCount(), parsedContentItem.getCount() );
|
assertEquals( contentItem.getCount(), parsedContentItem.getCount() );
|
||||||
Assert.assertEquals( contentItem.getId(), parsedContentItem.getId() );
|
assertEquals( contentItem.getId(), parsedContentItem.getId() );
|
||||||
Assert.assertEquals( nbt, parsedContentItem.getTag().getNbt() );
|
assertEquals( nbt, parsedContentItem.getTag().getNbt() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyComponentBuilder()
|
public void testEmptyComponentBuilderCreate()
|
||||||
|
{
|
||||||
|
this.testEmptyComponentBuilder(
|
||||||
|
ComponentBuilder::create,
|
||||||
|
(components) -> assertEquals( components.length, 0 ),
|
||||||
|
(components, size) -> assertEquals( size, components.length )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyComponentBuilderBuild()
|
||||||
|
{
|
||||||
|
this.testEmptyComponentBuilder(
|
||||||
|
ComponentBuilder::build,
|
||||||
|
(component) -> assertNull( component.getExtra() ),
|
||||||
|
(component, size) -> assertEquals( component.getExtra().size(), size )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void testEmptyComponentBuilder(Function<ComponentBuilder, T> componentBuilder, Consumer<T> emptyAssertion, ObjIntConsumer<T> sizedAssertion)
|
||||||
{
|
{
|
||||||
ComponentBuilder builder = new ComponentBuilder();
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
|
|
||||||
BaseComponent[] parts = builder.create();
|
T component = componentBuilder.apply( builder );
|
||||||
Assert.assertEquals( parts.length, 0 );
|
emptyAssertion.accept( component );
|
||||||
|
|
||||||
for ( int i = 0; i < 3; i++ )
|
for ( int i = 0; i < 3; i++ )
|
||||||
{
|
{
|
||||||
builder.append( "part:" + i );
|
builder.append( "part:" + i );
|
||||||
parts = builder.create();
|
component = componentBuilder.apply( builder );
|
||||||
Assert.assertEquals( parts.length, i + 1 );
|
sizedAssertion.accept( component, i + 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,23 +125,23 @@ public class ComponentsTest
|
|||||||
public void testDummyRetaining()
|
public void testDummyRetaining()
|
||||||
{
|
{
|
||||||
ComponentBuilder builder = new ComponentBuilder();
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
Assert.assertNotNull( builder.getCurrentComponent() );
|
assertNotNull( builder.getCurrentComponent() );
|
||||||
builder.color( ChatColor.GREEN );
|
builder.color( ChatColor.GREEN );
|
||||||
builder.append( "test ", ComponentBuilder.FormatRetention.ALL );
|
builder.append( "test ", ComponentBuilder.FormatRetention.ALL );
|
||||||
Assert.assertEquals( builder.getCurrentComponent().getColor(), ChatColor.GREEN );
|
assertEquals( builder.getCurrentComponent().getColor(), ChatColor.GREEN );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IndexOutOfBoundsException.class)
|
@Test
|
||||||
public void testComponentGettingExceptions()
|
public void testComponentGettingExceptions()
|
||||||
{
|
{
|
||||||
ComponentBuilder builder = new ComponentBuilder();
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
builder.getComponent( -1 );
|
assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( -1 ) );
|
||||||
builder.getComponent( 0 );
|
assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 0 ) );
|
||||||
builder.getComponent( 1 );
|
assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 1 ) );
|
||||||
BaseComponent component = new TextComponent( "Hello" );
|
BaseComponent component = new TextComponent( "Hello" );
|
||||||
builder.append( component );
|
builder.append( component );
|
||||||
Assert.assertEquals( builder.getComponent( 0 ), component );
|
assertEquals( builder.getComponent( 0 ), component );
|
||||||
builder.getComponent( 1 );
|
assertThrows( IndexOutOfBoundsException.class, () -> builder.getComponent( 1 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -110,33 +150,33 @@ public class ComponentsTest
|
|||||||
ComponentBuilder builder = new ComponentBuilder();
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
TextComponent apple = new TextComponent( "apple" );
|
TextComponent apple = new TextComponent( "apple" );
|
||||||
builder.append( apple );
|
builder.append( apple );
|
||||||
Assert.assertEquals( builder.getCurrentComponent(), apple );
|
assertEquals( builder.getCurrentComponent(), apple );
|
||||||
Assert.assertEquals( builder.getComponent( 0 ), apple );
|
assertEquals( builder.getComponent( 0 ), apple );
|
||||||
|
|
||||||
TextComponent mango = new TextComponent( "mango" );
|
TextComponent mango = new TextComponent( "mango" );
|
||||||
TextComponent orange = new TextComponent( "orange" );
|
TextComponent orange = new TextComponent( "orange" );
|
||||||
builder.append( mango );
|
builder.append( mango );
|
||||||
builder.append( orange );
|
builder.append( orange );
|
||||||
builder.removeComponent( 1 ); // Removing mango
|
builder.removeComponent( 1 ); // Removing mango
|
||||||
Assert.assertEquals( builder.getComponent( 0 ), apple );
|
assertEquals( builder.getComponent( 0 ), apple );
|
||||||
Assert.assertEquals( builder.getComponent( 1 ), orange );
|
assertEquals( builder.getComponent( 1 ), orange );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testToLegacyFromLegacy()
|
public void testToLegacyFromLegacy()
|
||||||
{
|
{
|
||||||
String text = "§a§lHello §f§kworld§7!";
|
String text = "§a§lHello §f§kworld§7!";
|
||||||
Assert.assertEquals( text, TextComponent.toLegacyText( TextComponent.fromLegacyText( text ) ) );
|
assertEquals( text, TextComponent.toLegacyText( TextComponent.fromLegacyText( text ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IndexOutOfBoundsException.class)
|
@Test
|
||||||
public void testComponentBuilderCursorInvalidPos()
|
public void testComponentBuilderCursorInvalidPos()
|
||||||
{
|
{
|
||||||
ComponentBuilder builder = new ComponentBuilder();
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
builder.append( new TextComponent( "Apple, " ) );
|
builder.append( new TextComponent( "Apple, " ) );
|
||||||
builder.append( new TextComponent( "Orange, " ) );
|
builder.append( new TextComponent( "Orange, " ) );
|
||||||
builder.setCursor( -1 );
|
assertThrows( IndexOutOfBoundsException.class, () -> builder.setCursor( -1 ) );
|
||||||
builder.setCursor( 2 );
|
assertThrows( IndexOutOfBoundsException.class, () -> builder.setCursor( 2 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -144,24 +184,24 @@ public class ComponentsTest
|
|||||||
{
|
{
|
||||||
TextComponent t1, t2, t3;
|
TextComponent t1, t2, t3;
|
||||||
ComponentBuilder builder = new ComponentBuilder();
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
Assert.assertEquals( builder.getCursor(), -1 );
|
assertEquals( builder.getCursor(), -1 );
|
||||||
builder.append( t1 = new TextComponent( "Apple, " ) );
|
builder.append( t1 = new TextComponent( "Apple, " ) );
|
||||||
Assert.assertEquals( builder.getCursor(), 0 );
|
assertEquals( builder.getCursor(), 0 );
|
||||||
builder.append( t2 = new TextComponent( "Orange, " ) );
|
builder.append( t2 = new TextComponent( "Orange, " ) );
|
||||||
builder.append( t3 = new TextComponent( "Mango, " ) );
|
builder.append( t3 = new TextComponent( "Mango, " ) );
|
||||||
Assert.assertEquals( builder.getCursor(), 2 );
|
assertEquals( builder.getCursor(), 2 );
|
||||||
|
|
||||||
builder.setCursor( 0 );
|
builder.setCursor( 0 );
|
||||||
Assert.assertEquals( builder.getCurrentComponent(), t1 );
|
assertEquals( builder.getCurrentComponent(), t1 );
|
||||||
|
|
||||||
// Test that appending new components updates the position to the new list size
|
// Test that appending new components updates the position to the new list size
|
||||||
// after having previously set it to 0 (first component)
|
// after having previously set it to 0 (first component)
|
||||||
builder.append( new TextComponent( "and Grapefruit" ) );
|
builder.append( new TextComponent( "and Grapefruit" ) );
|
||||||
Assert.assertEquals( builder.getCursor(), 3 );
|
assertEquals( builder.getCursor(), 3 );
|
||||||
|
|
||||||
builder.setCursor( 0 );
|
builder.setCursor( 0 );
|
||||||
builder.resetCursor();
|
builder.resetCursor();
|
||||||
Assert.assertEquals( builder.getCursor(), 3 );
|
assertEquals( builder.getCursor(), 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -170,7 +210,7 @@ public class ComponentsTest
|
|||||||
String text = "§a§lHello §r§kworld§7!";
|
String text = "§a§lHello §r§kworld§7!";
|
||||||
BaseComponent[] components = TextComponent.fromLegacyText( text );
|
BaseComponent[] components = TextComponent.fromLegacyText( text );
|
||||||
BaseComponent[] builderComponents = new ComponentBuilder().append( components ).create();
|
BaseComponent[] builderComponents = new ComponentBuilder().append( components ).create();
|
||||||
Assert.assertArrayEquals( components, builderComponents );
|
assertArrayEquals( components, builderComponents );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -192,7 +232,7 @@ public class ComponentsTest
|
|||||||
component.setHoverEvent( event );
|
component.setHoverEvent( event );
|
||||||
String serialised = ComponentSerializer.toString( component );
|
String serialised = ComponentSerializer.toString( component );
|
||||||
BaseComponent[] deserialised = ComponentSerializer.parse( serialised );
|
BaseComponent[] deserialised = ComponentSerializer.parse( serialised );
|
||||||
Assert.assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) );
|
assertEquals( TextComponent.toLegacyText( deserialised ), TextComponent.toLegacyText( component ) );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -207,13 +247,13 @@ public class ComponentsTest
|
|||||||
);
|
);
|
||||||
TextComponent component = new TextComponent( "test" );
|
TextComponent component = new TextComponent( "test" );
|
||||||
component.setHoverEvent( hoverEvent );
|
component.setHoverEvent( hoverEvent );
|
||||||
Assert.assertEquals( component.getHoverEvent().getContents().size(), 1 );
|
assertEquals( component.getHoverEvent().getContents().size(), 1 );
|
||||||
Assert.assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof Text );
|
assertTrue( component.getHoverEvent().getContents().get( 0 ) instanceof Text );
|
||||||
Assert.assertEquals( ( (Text) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement );
|
assertEquals( ( (Text) component.getHoverEvent().getContents().get( 0 ) ).getValue(), advancement );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHoverEventContents()
|
public void testHoverEventContentsCreate()
|
||||||
{
|
{
|
||||||
// First do the text using the newer contents system
|
// First do the text using the newer contents system
|
||||||
HoverEvent hoverEvent = new HoverEvent(
|
HoverEvent hoverEvent = new HoverEvent(
|
||||||
@@ -222,21 +262,53 @@ public class ComponentsTest
|
|||||||
new Text( new ComponentBuilder( "Second" ).create() )
|
new Text( new ComponentBuilder( "Second" ).create() )
|
||||||
);
|
);
|
||||||
|
|
||||||
TextComponent component = new TextComponent( "Sample text" );
|
this.testHoverEventContents(
|
||||||
component.setHoverEvent( hoverEvent );
|
hoverEvent,
|
||||||
Assert.assertEquals( hoverEvent.getContents().size(), 2 );
|
ComponentSerializer::parse,
|
||||||
Assert.assertFalse( hoverEvent.isLegacy() );
|
(components) -> components[0].getHoverEvent(),
|
||||||
String serialized = ComponentSerializer.toString( component );
|
ComponentsTest::testDissembleReassemble // BaseComponent
|
||||||
BaseComponent[] deserialized = ComponentSerializer.parse( serialized );
|
);
|
||||||
Assert.assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() );
|
|
||||||
|
|
||||||
// check the test still works with the value method
|
// check the test still works with the value method
|
||||||
hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Sample text" ).create() );
|
hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Sample text" ).create() );
|
||||||
Assert.assertEquals( hoverEvent.getContents().size(), 1 );
|
TextComponent component = new TextComponent( "Sample text" );
|
||||||
Assert.assertTrue( hoverEvent.isLegacy() );
|
component.setHoverEvent( hoverEvent );
|
||||||
serialized = ComponentSerializer.toString( component );
|
|
||||||
deserialized = ComponentSerializer.parse( serialized );
|
assertEquals( hoverEvent.getContents().size(), 1 );
|
||||||
Assert.assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() );
|
assertTrue( hoverEvent.isLegacy() );
|
||||||
|
String serialized = ComponentSerializer.toString( component );
|
||||||
|
BaseComponent[] deserialized = ComponentSerializer.parse( serialized );
|
||||||
|
assertEquals( component.getHoverEvent(), deserialized[0].getHoverEvent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHoverEventContentsBuild()
|
||||||
|
{
|
||||||
|
// First do the text using the newer contents system
|
||||||
|
HoverEvent hoverEvent = new HoverEvent(
|
||||||
|
HoverEvent.Action.SHOW_TEXT,
|
||||||
|
new Text( new ComponentBuilder( "First" ).build() ),
|
||||||
|
new Text( new ComponentBuilder( "Second" ).build() )
|
||||||
|
);
|
||||||
|
|
||||||
|
this.testHoverEventContents(
|
||||||
|
hoverEvent,
|
||||||
|
ComponentSerializer::deserialize,
|
||||||
|
BaseComponent::getHoverEvent,
|
||||||
|
ComponentsTest::testDissembleReassemble // BaseComponent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void testHoverEventContents(HoverEvent hoverEvent, Function<String, T> deserializer, Function<T, HoverEvent> hoverEventGetter, Consumer<T> dissembleReassembleTest)
|
||||||
|
{
|
||||||
|
TextComponent component = new TextComponent( "Sample text" );
|
||||||
|
component.setHoverEvent( hoverEvent );
|
||||||
|
assertEquals( hoverEvent.getContents().size(), 2 );
|
||||||
|
assertFalse( hoverEvent.isLegacy() );
|
||||||
|
|
||||||
|
String serialized = ComponentSerializer.toString( component );
|
||||||
|
T deserialized = deserializer.apply( serialized );
|
||||||
|
assertEquals( component.getHoverEvent(), hoverEventGetter.apply( deserialized ) );
|
||||||
|
|
||||||
// Test single content:
|
// Test single content:
|
||||||
String json = "{\"italic\":true,\"color\":\"gray\",\"translate\":\"chat.type.admin\",\"with\":[{\"text\":\"@\"}"
|
String json = "{\"italic\":true,\"color\":\"gray\",\"translate\":\"chat.type.admin\",\"with\":[{\"text\":\"@\"}"
|
||||||
@@ -248,37 +320,76 @@ public class ComponentsTest
|
|||||||
+ "\"/tell Name \"},\"hoverEvent\":{\"action\":\"show_entity\",\"contents\":"
|
+ "\"/tell Name \"},\"hoverEvent\":{\"action\":\"show_entity\",\"contents\":"
|
||||||
+ "{\"type\":\"minecraft:player\",\"id\":\"00000000-0000-0000-0000-00000000000000\",\"name\":"
|
+ "{\"type\":\"minecraft:player\",\"id\":\"00000000-0000-0000-0000-00000000000000\",\"name\":"
|
||||||
+ "{\"text\":\"Name\"}}},\"text\":\"Name\"}]}]}";
|
+ "{\"text\":\"Name\"}}},\"text\":\"Name\"}]}]}";
|
||||||
testDissembleReassemble( ComponentSerializer.parse( json ) );
|
dissembleReassembleTest.accept( deserializer.apply( json ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFormatRetentionCopyFormatting()
|
public void testFormatRetentionCopyFormattingCreate()
|
||||||
|
{
|
||||||
|
this.testFormatRetentionCopyFormatting( () -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Test" ).create() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormatRetentionCopyFormattingBuild()
|
||||||
|
{
|
||||||
|
this.testFormatRetentionCopyFormatting( () -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new Text( new ComponentBuilder( "Test" ).build() ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testFormatRetentionCopyFormatting(Supplier<HoverEvent> hoverEventSupplier)
|
||||||
{
|
{
|
||||||
TextComponent first = new TextComponent( "Hello" );
|
TextComponent first = new TextComponent( "Hello" );
|
||||||
first.setBold( true );
|
first.setBold( true );
|
||||||
first.setColor( ChatColor.RED );
|
first.setColor( ChatColor.RED );
|
||||||
first.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "test" ) );
|
first.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "test" ) );
|
||||||
first.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Test" ).create() ) );
|
first.setHoverEvent( hoverEventSupplier.get() );
|
||||||
|
|
||||||
TextComponent second = new TextComponent( " world" );
|
TextComponent second = new TextComponent( " world" );
|
||||||
second.copyFormatting( first, ComponentBuilder.FormatRetention.ALL, true );
|
second.copyFormatting( first, ComponentBuilder.FormatRetention.ALL, true );
|
||||||
Assert.assertEquals( first.isBold(), second.isBold() );
|
assertEquals( first.isBold(), second.isBold() );
|
||||||
Assert.assertEquals( first.getColor(), second.getColor() );
|
assertEquals( first.getColor(), second.getColor() );
|
||||||
Assert.assertEquals( first.getClickEvent(), second.getClickEvent() );
|
assertEquals( first.getClickEvent(), second.getClickEvent() );
|
||||||
Assert.assertEquals( first.getHoverEvent(), second.getHoverEvent() );
|
assertEquals( first.getHoverEvent(), second.getHoverEvent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderClone()
|
public void testBuilderCloneCreate()
|
||||||
|
{
|
||||||
|
this.testBuilderClone( (builder) -> TextComponent.toLegacyText( builder.create() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderCloneBuild()
|
||||||
|
{
|
||||||
|
this.testBuilderClone( (builder) -> TextComponent.toLegacyText( builder.build() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testBuilderClone(Function<ComponentBuilder, String> legacyTextFunction)
|
||||||
{
|
{
|
||||||
ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.RED ).append( "world" ).color( ChatColor.DARK_RED );
|
ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.RED ).append( "world" ).color( ChatColor.DARK_RED );
|
||||||
ComponentBuilder cloned = new ComponentBuilder( builder );
|
ComponentBuilder cloned = new ComponentBuilder( builder );
|
||||||
|
|
||||||
Assert.assertEquals( TextComponent.toLegacyText( builder.create() ), TextComponent.toLegacyText( cloned.create() ) );
|
assertEquals( legacyTextFunction.apply( builder ), legacyTextFunction.apply( cloned ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderAppendMixedComponents()
|
public void testBuilderAppendCreateMixedComponents()
|
||||||
|
{
|
||||||
|
this.testBuilderAppendMixedComponents(
|
||||||
|
ComponentBuilder::create,
|
||||||
|
(components, index) -> components[index]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderAppendBuildMixedComponents()
|
||||||
|
{
|
||||||
|
this.testBuilderAppendMixedComponents(
|
||||||
|
ComponentBuilder::build,
|
||||||
|
(component, index) -> component.getExtra().get( index )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void testBuilderAppendMixedComponents(Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter)
|
||||||
{
|
{
|
||||||
ComponentBuilder builder = new ComponentBuilder( "Hello " );
|
ComponentBuilder builder = new ComponentBuilder( "Hello " );
|
||||||
TextComponent textComponent = new TextComponent( "world " );
|
TextComponent textComponent = new TextComponent( "world " );
|
||||||
@@ -291,11 +402,11 @@ public class ComponentsTest
|
|||||||
} );
|
} );
|
||||||
ScoreComponent scoreComponent = new ScoreComponent( "myscore", "myobjective" );
|
ScoreComponent scoreComponent = new ScoreComponent( "myscore", "myobjective" );
|
||||||
builder.append( scoreComponent ); // non array based BaseComponent append
|
builder.append( scoreComponent ); // non array based BaseComponent append
|
||||||
BaseComponent[] components = builder.create();
|
T component = componentBuilder.apply( builder );
|
||||||
Assert.assertEquals( "Hello ", components[0].toPlainText() );
|
assertEquals( "Hello ", extraGetter.apply( component, 0 ).toPlainText() );
|
||||||
Assert.assertEquals( textComponent.toPlainText(), components[1].toPlainText() );
|
assertEquals( textComponent.toPlainText(), extraGetter.apply( component, 1 ).toPlainText() );
|
||||||
Assert.assertEquals( translatableComponent.toPlainText(), components[2].toPlainText() );
|
assertEquals( translatableComponent.toPlainText(), extraGetter.apply( component, 2 ).toPlainText() );
|
||||||
Assert.assertEquals( scoreComponent.toPlainText(), components[3].toPlainText() );
|
assertEquals( scoreComponent.toPlainText(), extraGetter.apply( component, 3 ).toPlainText() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -305,36 +416,84 @@ public class ComponentsTest
|
|||||||
String text = ComponentSerializer.toString( component );
|
String text = ComponentSerializer.toString( component );
|
||||||
BaseComponent[] reparsed = ComponentSerializer.parse( text );
|
BaseComponent[] reparsed = ComponentSerializer.parse( text );
|
||||||
|
|
||||||
Assert.assertArrayEquals( component, reparsed );
|
assertArrayEquals( component, reparsed );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderAppend()
|
public void testBuilderAppendCreate()
|
||||||
|
{
|
||||||
|
this.testBuilderAppend(
|
||||||
|
() -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Hello world" ).create() ),
|
||||||
|
ComponentBuilder::create,
|
||||||
|
(components, index) -> components[index],
|
||||||
|
BaseComponent::toPlainText,
|
||||||
|
ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!",
|
||||||
|
BaseComponent::toLegacyText
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderAppendBuild()
|
||||||
|
{
|
||||||
|
this.testBuilderAppend(
|
||||||
|
() -> new HoverEvent( HoverEvent.Action.SHOW_TEXT, new Text( new ComponentBuilder( "Hello world" ).build() ) ),
|
||||||
|
ComponentBuilder::build,
|
||||||
|
(component, index) -> component.getExtra().get( index ),
|
||||||
|
(component) -> BaseComponent.toPlainText( component ),
|
||||||
|
// An extra format code is appended to the beginning because there is an empty TextComponent at the start of every component
|
||||||
|
ChatColor.WHITE.toString() + ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!",
|
||||||
|
(component) -> BaseComponent.toLegacyText( component )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void testBuilderAppend(Supplier<HoverEvent> hoverEventSupplier, Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter, Function<T, String> toPlainTextFunction, String expectedLegacyText, Function<T, String> toLegacyTextFunction)
|
||||||
{
|
{
|
||||||
ClickEvent clickEvent = new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/help " );
|
ClickEvent clickEvent = new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/help " );
|
||||||
HoverEvent hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Hello world" ).create() );
|
HoverEvent hoverEvent = hoverEventSupplier.get();
|
||||||
|
|
||||||
ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW );
|
ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW );
|
||||||
builder.append( new ComponentBuilder( "world!" ).color( ChatColor.GREEN ).event( hoverEvent ).event( clickEvent ).create() );
|
builder.append( new ComponentBuilder( "world!" ).color( ChatColor.GREEN ).event( hoverEvent ).event( clickEvent ).create() ); // Intentionally using create() to append multiple individual components
|
||||||
|
|
||||||
BaseComponent[] components = builder.create();
|
T component = componentBuilder.apply( builder );
|
||||||
|
|
||||||
Assert.assertEquals( components[1].getHoverEvent(), hoverEvent );
|
assertEquals( extraGetter.apply( component, 1 ).getHoverEvent(), hoverEvent );
|
||||||
Assert.assertEquals( components[1].getClickEvent(), clickEvent );
|
assertEquals( extraGetter.apply( component, 1 ).getClickEvent(), clickEvent );
|
||||||
Assert.assertEquals( "Hello world!", BaseComponent.toPlainText( components ) );
|
assertEquals( "Hello world!", toPlainTextFunction.apply( component ) );
|
||||||
Assert.assertEquals( ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!", BaseComponent.toLegacyText( components ) );
|
assertEquals( expectedLegacyText, toLegacyTextFunction.apply( component ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderAppendLegacy()
|
public void testBuilderAppendLegacyCreate()
|
||||||
|
{
|
||||||
|
this.testBuilderAppendLegacy(
|
||||||
|
ComponentBuilder::create,
|
||||||
|
BaseComponent::toPlainText,
|
||||||
|
ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!",
|
||||||
|
BaseComponent::toLegacyText
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderAppendLegacyBuild()
|
||||||
|
{
|
||||||
|
this.testBuilderAppendLegacy(
|
||||||
|
ComponentBuilder::build,
|
||||||
|
(component) -> BaseComponent.toPlainText( component ),
|
||||||
|
// An extra format code is appended to the beginning because there is an empty TextComponent at the start of every component
|
||||||
|
ChatColor.WHITE.toString() + ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!",
|
||||||
|
(component) -> BaseComponent.toLegacyText( component )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void testBuilderAppendLegacy(Function<ComponentBuilder, T> componentBuilder, Function<T, String> toPlainTextFunction, String expectedLegacyString, Function<T, String> toLegacyTextFunction)
|
||||||
{
|
{
|
||||||
ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW );
|
ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW );
|
||||||
builder.appendLegacy( "§aworld!" );
|
builder.appendLegacy( "§aworld!" );
|
||||||
|
|
||||||
BaseComponent[] components = builder.create();
|
T component = componentBuilder.apply( builder );
|
||||||
|
|
||||||
Assert.assertEquals( "Hello world!", BaseComponent.toPlainText( components ) );
|
assertEquals( "Hello world!", toPlainTextFunction.apply( component ) );
|
||||||
Assert.assertEquals( ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!", BaseComponent.toLegacyText( components ) );
|
assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -343,8 +502,8 @@ public class ComponentsTest
|
|||||||
TextComponent textComponent = new TextComponent( "Hello world" );
|
TextComponent textComponent = new TextComponent( "Hello world" );
|
||||||
textComponent.setColor( ChatColor.RED );
|
textComponent.setColor( ChatColor.RED );
|
||||||
|
|
||||||
Assert.assertEquals( "Hello world", textComponent.toPlainText() );
|
assertEquals( "Hello world", textComponent.toPlainText() );
|
||||||
Assert.assertEquals( ChatColor.RED + "Hello world", textComponent.toLegacyText() );
|
assertEquals( ChatColor.RED + "Hello world", textComponent.toLegacyText() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -352,25 +511,25 @@ public class ComponentsTest
|
|||||||
{
|
{
|
||||||
BaseComponent[] test1 = TextComponent.fromLegacyText( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold" );
|
BaseComponent[] test1 = TextComponent.fromLegacyText( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold" );
|
||||||
|
|
||||||
Assert.assertEquals( "Aqua RedBold", BaseComponent.toPlainText( test1 ) );
|
assertEquals( "Aqua RedBold", BaseComponent.toPlainText( test1 ) );
|
||||||
Assert.assertEquals( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold", BaseComponent.toLegacyText( test1 ) );
|
assertEquals( ChatColor.AQUA + "Aqua " + ChatColor.RED + ChatColor.BOLD + "RedBold", BaseComponent.toLegacyText( test1 ) );
|
||||||
|
|
||||||
BaseComponent[] test2 = TextComponent.fromLegacyText( "Text http://spigotmc.org " + ChatColor.GREEN + "google.com/test" );
|
BaseComponent[] test2 = TextComponent.fromLegacyText( "Text http://spigotmc.org " + ChatColor.GREEN + "google.com/test" );
|
||||||
|
|
||||||
Assert.assertEquals( "Text http://spigotmc.org google.com/test", BaseComponent.toPlainText( test2 ) );
|
assertEquals( "Text http://spigotmc.org google.com/test", BaseComponent.toPlainText( test2 ) );
|
||||||
//The extra ChatColor instances are sometimes inserted when not needed but it doesn't change the result
|
//The extra ChatColor instances are sometimes inserted when not needed but it doesn't change the result
|
||||||
Assert.assertEquals( ChatColor.WHITE + "Text " + ChatColor.WHITE + "http://spigotmc.org" + ChatColor.WHITE
|
assertEquals( ChatColor.WHITE + "Text " + ChatColor.WHITE + "http://spigotmc.org" + ChatColor.WHITE
|
||||||
+ " " + ChatColor.GREEN + "google.com/test" + ChatColor.GREEN, BaseComponent.toLegacyText( test2 ) );
|
+ " " + ChatColor.GREEN + "google.com/test" + ChatColor.GREEN, BaseComponent.toLegacyText( test2 ) );
|
||||||
|
|
||||||
ClickEvent url1 = test2[1].getClickEvent();
|
ClickEvent url1 = test2[1].getClickEvent();
|
||||||
Assert.assertNotNull( url1 );
|
assertNotNull( url1 );
|
||||||
Assert.assertTrue( url1.getAction() == ClickEvent.Action.OPEN_URL );
|
assertTrue( url1.getAction() == ClickEvent.Action.OPEN_URL );
|
||||||
Assert.assertEquals( "http://spigotmc.org", url1.getValue() );
|
assertEquals( "http://spigotmc.org", url1.getValue() );
|
||||||
|
|
||||||
ClickEvent url2 = test2[3].getClickEvent();
|
ClickEvent url2 = test2[3].getClickEvent();
|
||||||
Assert.assertNotNull( url2 );
|
assertNotNull( url2 );
|
||||||
Assert.assertTrue( url2.getAction() == ClickEvent.Action.OPEN_URL );
|
assertTrue( url2.getAction() == ClickEvent.Action.OPEN_URL );
|
||||||
Assert.assertEquals( "http://google.com/test", url2.getValue() );
|
assertEquals( "http://google.com/test", url2.getValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -382,83 +541,140 @@ public class ComponentsTest
|
|||||||
item, "5",
|
item, "5",
|
||||||
"thinkofdeath" );
|
"thinkofdeath" );
|
||||||
|
|
||||||
Assert.assertEquals( "Given Golden Sword * 5 to thinkofdeath", translatableComponent.toPlainText() );
|
assertEquals( "Given Golden Sword * 5 to thinkofdeath", translatableComponent.toPlainText() );
|
||||||
Assert.assertEquals( ChatColor.WHITE + "Given " + ChatColor.AQUA + "Golden Sword" + ChatColor.WHITE
|
assertEquals( ChatColor.WHITE + "Given " + ChatColor.AQUA + "Golden Sword" + ChatColor.WHITE
|
||||||
+ " * " + ChatColor.WHITE + "5" + ChatColor.WHITE + " to " + ChatColor.WHITE + "thinkofdeath",
|
+ " * " + ChatColor.WHITE + "5" + ChatColor.WHITE + " to " + ChatColor.WHITE + "thinkofdeath",
|
||||||
translatableComponent.toLegacyText() );
|
translatableComponent.toLegacyText() );
|
||||||
|
|
||||||
TranslatableComponent positional = new TranslatableComponent( "book.pageIndicator", "5", "50" );
|
TranslatableComponent positional = new TranslatableComponent( "book.pageIndicator", "5", "50" );
|
||||||
|
|
||||||
Assert.assertEquals( "Page 5 of 50", positional.toPlainText() );
|
assertEquals( "Page 5 of 50", positional.toPlainText() );
|
||||||
Assert.assertEquals( ChatColor.WHITE + "Page " + ChatColor.WHITE + "5" + ChatColor.WHITE + " of " + ChatColor.WHITE + "50", positional.toLegacyText() );
|
assertEquals( ChatColor.WHITE + "Page " + ChatColor.WHITE + "5" + ChatColor.WHITE + " of " + ChatColor.WHITE + "50", positional.toLegacyText() );
|
||||||
|
|
||||||
TranslatableComponent one_four_two = new TranslatableComponent( "filled_map.buried_treasure" );
|
TranslatableComponent one_four_two = new TranslatableComponent( "filled_map.buried_treasure" );
|
||||||
Assert.assertEquals( "Buried Treasure Map", one_four_two.toPlainText() );
|
assertEquals( "Buried Treasure Map", one_four_two.toPlainText() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilder()
|
public void testBuilderCreate()
|
||||||
{
|
{
|
||||||
BaseComponent[] components = new ComponentBuilder( "Hello " ).color( ChatColor.RED ).
|
this.testBuilder(
|
||||||
|
ComponentBuilder::create,
|
||||||
|
BaseComponent::toPlainText,
|
||||||
|
ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD
|
||||||
|
+ "World" + ChatColor.YELLOW + ChatColor.BOLD + "!",
|
||||||
|
BaseComponent::toLegacyText
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderBuild()
|
||||||
|
{
|
||||||
|
this.testBuilder(
|
||||||
|
ComponentBuilder::build,
|
||||||
|
(component) -> BaseComponent.toPlainText( component ),
|
||||||
|
// An extra format code is appended to the beginning because there is an empty TextComponent at the start of every component
|
||||||
|
ChatColor.WHITE.toString() + ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD
|
||||||
|
+ "World" + ChatColor.YELLOW + ChatColor.BOLD + "!",
|
||||||
|
(component) -> BaseComponent.toLegacyText( component )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void testBuilder(Function<ComponentBuilder, T> componentBuilder, Function<T, String> toPlainTextFunction, String expectedLegacyString, Function<T, String> toLegacyTextFunction)
|
||||||
|
{
|
||||||
|
T component = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED ).
|
||||||
append( "World" ).bold( true ).color( ChatColor.BLUE ).
|
append( "World" ).bold( true ).color( ChatColor.BLUE ).
|
||||||
append( "!" ).color( ChatColor.YELLOW ).create();
|
append( "!" ).color( ChatColor.YELLOW ) );
|
||||||
|
|
||||||
Assert.assertEquals( "Hello World!", BaseComponent.toPlainText( components ) );
|
assertEquals( "Hello World!", toPlainTextFunction.apply( component ) );
|
||||||
Assert.assertEquals( ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD
|
assertEquals( expectedLegacyString, toLegacyTextFunction.apply( component ) );
|
||||||
+ "World" + ChatColor.YELLOW + ChatColor.BOLD + "!", BaseComponent.toLegacyText( components ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderReset()
|
public void testBuilderCreateReset()
|
||||||
{
|
{
|
||||||
BaseComponent[] components = new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
this.testBuilderReset(
|
||||||
.append( "World" ).reset().create();
|
ComponentBuilder::create,
|
||||||
|
(components, index) -> components[index]
|
||||||
Assert.assertEquals( components[0].getColor(), ChatColor.RED );
|
);
|
||||||
Assert.assertEquals( components[1].getColor(), ChatColor.WHITE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderFormatRetention()
|
public void testBuilderBuildReset()
|
||||||
{
|
{
|
||||||
BaseComponent[] noneRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
this.testBuilderReset(
|
||||||
.append( "World", ComponentBuilder.FormatRetention.NONE ).create();
|
ComponentBuilder::build,
|
||||||
|
(component, index) -> component.getExtra().get( index )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Assert.assertEquals( noneRetention[0].getColor(), ChatColor.RED );
|
private <T> void testBuilderReset(Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter)
|
||||||
Assert.assertEquals( noneRetention[1].getColor(), ChatColor.WHITE );
|
{
|
||||||
|
T component = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
||||||
|
.append( "World" ).reset() );
|
||||||
|
|
||||||
HoverEvent testEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "test" ).create() );
|
assertEquals( ChatColor.RED, extraGetter.apply( component, 0 ).getColor() );
|
||||||
|
assertEquals( ChatColor.WHITE, extraGetter.apply( component, 1 ).getColor() );
|
||||||
|
}
|
||||||
|
|
||||||
BaseComponent[] formattingRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
@Test
|
||||||
.event( testEvent ).append( "World", ComponentBuilder.FormatRetention.FORMATTING ).create();
|
public void testBuilderCreateFormatRetention()
|
||||||
|
{
|
||||||
|
this.testBuilderFormatRetention(
|
||||||
|
ComponentBuilder::create,
|
||||||
|
(components, index) -> components[index]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Assert.assertEquals( formattingRetention[0].getColor(), ChatColor.RED );
|
@Test
|
||||||
Assert.assertEquals( formattingRetention[0].getHoverEvent(), testEvent );
|
public void testBuilderBuildFormatRetention()
|
||||||
Assert.assertEquals( formattingRetention[1].getColor(), ChatColor.RED );
|
{
|
||||||
Assert.assertNull( formattingRetention[1].getHoverEvent() );
|
this.testBuilderFormatRetention(
|
||||||
|
ComponentBuilder::build,
|
||||||
|
(component, index) -> component.getExtra().get( index )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void testBuilderFormatRetention(Function<ComponentBuilder, T> componentBuilder, BiFunction<T, Integer, BaseComponent> extraGetter)
|
||||||
|
{
|
||||||
|
T noneRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
||||||
|
.append( "World", ComponentBuilder.FormatRetention.NONE ) );
|
||||||
|
|
||||||
|
assertEquals( ChatColor.RED, extraGetter.apply( noneRetention, 0 ).getColor() );
|
||||||
|
assertEquals( ChatColor.WHITE, extraGetter.apply( noneRetention, 1 ).getColor() );
|
||||||
|
|
||||||
|
HoverEvent testEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new Text( new ComponentBuilder( "test" ).build() ) );
|
||||||
|
|
||||||
|
T formattingRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
||||||
|
.event( testEvent ).append( "World", ComponentBuilder.FormatRetention.FORMATTING ) );
|
||||||
|
|
||||||
|
assertEquals( ChatColor.RED, extraGetter.apply( formattingRetention, 0 ).getColor() );
|
||||||
|
assertEquals( testEvent, extraGetter.apply( formattingRetention, 0 ).getHoverEvent() );
|
||||||
|
assertEquals( ChatColor.RED, extraGetter.apply( formattingRetention, 1 ).getColor() );
|
||||||
|
assertNull( extraGetter.apply( formattingRetention, 1 ).getHoverEvent() );
|
||||||
|
|
||||||
ClickEvent testClickEvent = new ClickEvent( ClickEvent.Action.OPEN_URL, "http://www.example.com" );
|
ClickEvent testClickEvent = new ClickEvent( ClickEvent.Action.OPEN_URL, "http://www.example.com" );
|
||||||
|
|
||||||
BaseComponent[] eventRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
T eventRetention = componentBuilder.apply( new ComponentBuilder( "Hello " ).color( ChatColor.RED )
|
||||||
.event( testEvent ).event( testClickEvent ).append( "World", ComponentBuilder.FormatRetention.EVENTS ).create();
|
.event( testEvent ).event( testClickEvent ).append( "World", ComponentBuilder.FormatRetention.EVENTS ) );
|
||||||
|
|
||||||
Assert.assertEquals( eventRetention[0].getColor(), ChatColor.RED );
|
assertEquals( ChatColor.RED, extraGetter.apply( eventRetention, 0 ).getColor() );
|
||||||
Assert.assertEquals( eventRetention[0].getHoverEvent(), testEvent );
|
assertEquals( testEvent, extraGetter.apply( eventRetention, 0 ).getHoverEvent() );
|
||||||
Assert.assertEquals( eventRetention[0].getClickEvent(), testClickEvent );
|
assertEquals( testClickEvent, extraGetter.apply( eventRetention, 0 ).getClickEvent() );
|
||||||
Assert.assertEquals( eventRetention[1].getColor(), ChatColor.WHITE );
|
assertEquals( ChatColor.WHITE, extraGetter.apply( eventRetention, 1 ).getColor() );
|
||||||
Assert.assertEquals( eventRetention[1].getHoverEvent(), testEvent );
|
assertEquals( testEvent, extraGetter.apply( eventRetention, 1 ).getHoverEvent() );
|
||||||
Assert.assertEquals( eventRetention[1].getClickEvent(), testClickEvent );
|
assertEquals( testClickEvent, extraGetter.apply( eventRetention, 1 ).getClickEvent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testLoopSimple()
|
public void testLoopSimple()
|
||||||
{
|
{
|
||||||
TextComponent component = new TextComponent( "Testing" );
|
TextComponent component = new TextComponent( "Testing" );
|
||||||
component.addExtra( component );
|
component.addExtra( component );
|
||||||
ComponentSerializer.toString( component );
|
assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( component ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testLoopComplex()
|
public void testLoopComplex()
|
||||||
{
|
{
|
||||||
TextComponent a = new TextComponent( "A" );
|
TextComponent a = new TextComponent( "A" );
|
||||||
@@ -469,7 +685,7 @@ public class ComponentsTest
|
|||||||
a.addExtra( b );
|
a.addExtra( b );
|
||||||
b.addExtra( c );
|
b.addExtra( c );
|
||||||
c.addExtra( a );
|
c.addExtra( a );
|
||||||
ComponentSerializer.toString( a );
|
assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( a ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -483,7 +699,7 @@ public class ComponentsTest
|
|||||||
ComponentSerializer.toString( a );
|
ComponentSerializer.toString( a );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testRepeatedError()
|
public void testRepeatedError()
|
||||||
{
|
{
|
||||||
TextComponent a = new TextComponent( "A" );
|
TextComponent a = new TextComponent( "A" );
|
||||||
@@ -495,7 +711,7 @@ public class ComponentsTest
|
|||||||
a.addExtra( c );
|
a.addExtra( c );
|
||||||
c.addExtra( a );
|
c.addExtra( a );
|
||||||
a.addExtra( b );
|
a.addExtra( b );
|
||||||
ComponentSerializer.toString( a );
|
assertThrows( IllegalArgumentException.class, () -> ComponentSerializer.toString( a ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -520,7 +736,7 @@ public class ComponentsTest
|
|||||||
String emptyLegacyText = fromAndToLegacyText( "" );
|
String emptyLegacyText = fromAndToLegacyText( "" );
|
||||||
|
|
||||||
// all invalid color codes and the trailing '§' should be ignored
|
// all invalid color codes and the trailing '§' should be ignored
|
||||||
Assert.assertEquals( emptyLegacyText, invalidColorCodesLegacyText );
|
assertEquals( emptyLegacyText, invalidColorCodesLegacyText );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -529,12 +745,12 @@ public class ComponentsTest
|
|||||||
String text = "§a";
|
String text = "§a";
|
||||||
|
|
||||||
BaseComponent[] converted = TextComponent.fromLegacyText( text );
|
BaseComponent[] converted = TextComponent.fromLegacyText( text );
|
||||||
Assert.assertEquals( ChatColor.GREEN, converted[0].getColor() );
|
assertEquals( ChatColor.GREEN, converted[0].getColor() );
|
||||||
|
|
||||||
String roundtripLegacyText = BaseComponent.toLegacyText( converted );
|
String roundtripLegacyText = BaseComponent.toLegacyText( converted );
|
||||||
|
|
||||||
// color code should not be lost during conversion
|
// color code should not be lost during conversion
|
||||||
Assert.assertEquals( text, roundtripLegacyText );
|
assertEquals( text, roundtripLegacyText );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -546,7 +762,7 @@ public class ComponentsTest
|
|||||||
TextComponent second = new TextComponent( "Hello, " );
|
TextComponent second = new TextComponent( "Hello, " );
|
||||||
second.addExtra( new TextComponent( "World!" ) );
|
second.addExtra( new TextComponent( "World!" ) );
|
||||||
|
|
||||||
Assert.assertEquals( first, second );
|
assertEquals( first, second );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -558,7 +774,7 @@ public class ComponentsTest
|
|||||||
TextComponent second = new TextComponent( "Hello, " );
|
TextComponent second = new TextComponent( "Hello, " );
|
||||||
second.addExtra( new TextComponent( "World!" ) );
|
second.addExtra( new TextComponent( "World!" ) );
|
||||||
|
|
||||||
Assert.assertNotEquals( first, second );
|
assertNotEquals( first, second );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -569,10 +785,57 @@ public class ComponentsTest
|
|||||||
|
|
||||||
BaseComponent[] reColored = TextComponent.fromLegacyText( legacy );
|
BaseComponent[] reColored = TextComponent.fromLegacyText( legacy );
|
||||||
|
|
||||||
Assert.assertArrayEquals( hexColored, reColored );
|
assertArrayEquals( hexColored, reColored );
|
||||||
}
|
}
|
||||||
|
|
||||||
private String fromAndToLegacyText(String legacyText)
|
@Test
|
||||||
|
public void testLegacyResetInBuilderCreate()
|
||||||
|
{
|
||||||
|
this.testLegacyResetInBuilder(
|
||||||
|
ComponentBuilder::create,
|
||||||
|
ComponentSerializer::toString
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLegacyResetInBuilderBuild()
|
||||||
|
{
|
||||||
|
this.testLegacyResetInBuilder(
|
||||||
|
ComponentBuilder::build,
|
||||||
|
ComponentSerializer::toString
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In legacy chat, colors and reset both reset all formatting.
|
||||||
|
* Make sure it works in combination with ComponentBuilder.
|
||||||
|
*/
|
||||||
|
private <T> void testLegacyResetInBuilder(Function<ComponentBuilder, T> componentBuilder, Function<T, String> componentSerializer)
|
||||||
|
{
|
||||||
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
|
BaseComponent[] a = TextComponent.fromLegacyText( "§4§n44444§rdd§6§l6666" );
|
||||||
|
|
||||||
|
String expected = "{\"extra\":[{\"underlined\":true,\"color\":\"dark_red\",\"text\":\"44444\"},{\"color\":"
|
||||||
|
+ "\"white\",\"text\":\"dd\"},{\"bold\":true,\"color\":\"gold\",\"text\":\"6666\"}],\"text\":\"\"}";
|
||||||
|
assertEquals( expected, ComponentSerializer.toString( a ) );
|
||||||
|
|
||||||
|
builder.append( a );
|
||||||
|
|
||||||
|
String test1 = componentSerializer.apply( componentBuilder.apply( builder ) );
|
||||||
|
assertEquals( expected, test1 );
|
||||||
|
|
||||||
|
BaseComponent[] b = TextComponent.fromLegacyText( "§rrrrr" );
|
||||||
|
builder.append( b );
|
||||||
|
|
||||||
|
String test2 = componentSerializer.apply( componentBuilder.apply( builder ) );
|
||||||
|
assertEquals(
|
||||||
|
"{\"extra\":[{\"underlined\":true,\"color\":\"dark_red\",\"text\":\"44444\"},"
|
||||||
|
+ "{\"color\":\"white\",\"text\":\"dd\"},{\"bold\":true,\"color\":\"gold\",\"text\":\"6666\"},"
|
||||||
|
+ "{\"color\":\"white\",\"text\":\"rrrr\"}],\"text\":\"\"}",
|
||||||
|
test2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String fromAndToLegacyText(String legacyText)
|
||||||
{
|
{
|
||||||
return BaseComponent.toLegacyText( TextComponent.fromLegacyText( legacyText ) );
|
return BaseComponent.toLegacyText( TextComponent.fromLegacyText( legacyText ) );
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package net.md_5.bungee.api.chat;
|
package net.md_5.bungee.api.chat;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import net.md_5.bungee.chat.ComponentSerializer;
|
import net.md_5.bungee.chat.ComponentSerializer;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class TranslatableComponentTest
|
public class TranslatableComponentTest
|
||||||
{
|
{
|
||||||
@@ -11,8 +11,8 @@ public class TranslatableComponentTest
|
|||||||
public void testMissingPlaceholdersAdded()
|
public void testMissingPlaceholdersAdded()
|
||||||
{
|
{
|
||||||
TranslatableComponent testComponent = new TranslatableComponent( "Test string with %s placeholders: %s", 2, "aoeu" );
|
TranslatableComponent testComponent = new TranslatableComponent( "Test string with %s placeholders: %s", 2, "aoeu" );
|
||||||
Assert.assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() );
|
assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() );
|
||||||
Assert.assertEquals( "§fTest string with §f2§f placeholders: §faoeu", testComponent.toLegacyText() );
|
assertEquals( "§fTest string with §f2§f placeholders: §faoeu", testComponent.toLegacyText() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -22,7 +22,7 @@ public class TranslatableComponentTest
|
|||||||
String jsonString = ComponentSerializer.toString( testComponent );
|
String jsonString = ComponentSerializer.toString( testComponent );
|
||||||
BaseComponent[] baseComponents = ComponentSerializer.parse( jsonString );
|
BaseComponent[] baseComponents = ComponentSerializer.parse( jsonString );
|
||||||
|
|
||||||
Assert.assertEquals( "Test string with a placeholder", TextComponent.toPlainText( baseComponents ) );
|
assertEquals( "Test string with a placeholder", TextComponent.toPlainText( baseComponents ) );
|
||||||
Assert.assertEquals( "§fTest string with §fa§f placeholder", TextComponent.toLegacyText( baseComponents ) );
|
assertEquals( "§fTest string with §fa§f placeholder", TextComponent.toLegacyText( baseComponents ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,9 +33,9 @@
|
|||||||
|
|
||||||
<!-- See http://checkstyle.sourceforge.net/config_filters.html -->
|
<!-- See http://checkstyle.sourceforge.net/config_filters.html -->
|
||||||
<module name="SuppressionCommentFilter"/>
|
<module name="SuppressionCommentFilter"/>
|
||||||
|
<module name="SuppressWarningsHolder"/>
|
||||||
|
|
||||||
<!-- See http://checkstyle.sourceforge.net/config_imports.html -->
|
<!-- See http://checkstyle.sourceforge.net/config_imports.html -->
|
||||||
<module name="AvoidStarImport"/>
|
|
||||||
<module name="ImportOrder">
|
<module name="ImportOrder">
|
||||||
<property name="option" value="above"/>
|
<property name="option" value="above"/>
|
||||||
<property name="ordered" value="true"/>
|
<property name="ordered" value="true"/>
|
||||||
@@ -54,11 +54,11 @@
|
|||||||
<module name="OperatorWrap"/>
|
<module name="OperatorWrap"/>
|
||||||
<module name="ParenPad">
|
<module name="ParenPad">
|
||||||
<property name="option" value="nospace"/>
|
<property name="option" value="nospace"/>
|
||||||
<property name="tokens" value="ANNOTATION, CTOR_DEF, METHOD_DEF"/>
|
<property name="tokens" value="ANNOTATION, CTOR_DEF, METHOD_DEF, LAMBDA"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="ParenPad">
|
<module name="ParenPad">
|
||||||
<property name="option" value="space"/>
|
<property name="option" value="space"/>
|
||||||
<property name="tokens" value="ANNOTATION_FIELD_DEF, CTOR_CALL, DOT, ENUM_CONSTANT_DEF, EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA"/>
|
<property name="tokens" value="ANNOTATION_FIELD_DEF, CTOR_CALL, DOT, ENUM_CONSTANT_DEF, EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, RECORD_DEF"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="SingleSpaceSeparator"/>
|
<module name="SingleSpaceSeparator"/>
|
||||||
<module name="TypecastParenPad"/>
|
<module name="TypecastParenPad"/>
|
||||||
@@ -84,4 +84,6 @@
|
|||||||
<module name="Indentation"/>
|
<module name="Indentation"/>
|
||||||
<module name="UpperEll"/>
|
<module name="UpperEll"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
<module name="SuppressWarningsFilter"/>
|
||||||
</module>
|
</module>
|
||||||
|
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-config</artifactId>
|
<artifactId>bungeecord-config</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Config</name>
|
<name>BungeeCord-Config</name>
|
||||||
@@ -22,14 +21,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.8.0</version>
|
<version>2.10.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.26</version>
|
<version>2.2</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@@ -14,6 +14,7 @@ import java.util.Map;
|
|||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
|
import org.yaml.snakeyaml.LoaderOptions;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
import org.yaml.snakeyaml.constructor.Constructor;
|
import org.yaml.snakeyaml.constructor.Constructor;
|
||||||
import org.yaml.snakeyaml.nodes.Node;
|
import org.yaml.snakeyaml.nodes.Node;
|
||||||
@@ -29,7 +30,10 @@ public class YamlConfiguration extends ConfigurationProvider
|
|||||||
@Override
|
@Override
|
||||||
protected Yaml initialValue()
|
protected Yaml initialValue()
|
||||||
{
|
{
|
||||||
Representer representer = new Representer()
|
DumperOptions options = new DumperOptions();
|
||||||
|
options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK );
|
||||||
|
|
||||||
|
Representer representer = new Representer( options )
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
representers.put( Configuration.class, new Represent()
|
representers.put( Configuration.class, new Represent()
|
||||||
@@ -43,10 +47,7 @@ public class YamlConfiguration extends ConfigurationProvider
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DumperOptions options = new DumperOptions();
|
return new Yaml( new Constructor( new LoaderOptions() ), representer, options );
|
||||||
options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK );
|
|
||||||
|
|
||||||
return new Yaml( new Constructor(), representer, options );
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,148 +1,138 @@
|
|||||||
package net.md_5.bungee.config;
|
package net.md_5.bungee.config;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class CompoundConfigurationTest
|
public class CompoundConfigurationTest
|
||||||
{
|
{
|
||||||
|
|
||||||
@Parameters(name = "{0}")
|
public static Stream<Arguments> data()
|
||||||
public static Iterable<Object[]> data()
|
|
||||||
{
|
{
|
||||||
// CHECKSTYLE:OFF
|
return Stream.of(
|
||||||
return Arrays.asList( new Object[][]
|
Arguments.of(
|
||||||
{
|
// provider
|
||||||
{
|
YamlConfiguration.class,
|
||||||
// provider
|
// testDocument
|
||||||
YamlConfiguration.class,
|
""
|
||||||
// testDocument
|
+ "receipt: Oz-Ware Purchase Invoice\n"
|
||||||
""
|
+ "date: 2012-08-06\n"
|
||||||
+ "receipt: Oz-Ware Purchase Invoice\n"
|
+ "customer:\n"
|
||||||
+ "date: 2012-08-06\n"
|
+ " given: Dorothy\n"
|
||||||
+ "customer:\n"
|
+ " family: Gale\n"
|
||||||
+ " given: Dorothy\n"
|
+ "\n"
|
||||||
+ " family: Gale\n"
|
+ "items:\n"
|
||||||
+ "\n"
|
+ " - part_no: A4786\n"
|
||||||
+ "items:\n"
|
+ " descrip: Water Bucket (Filled)\n"
|
||||||
+ " - part_no: A4786\n"
|
+ " price: 1.47\n"
|
||||||
+ " descrip: Water Bucket (Filled)\n"
|
+ " quantity: 4\n"
|
||||||
+ " price: 1.47\n"
|
+ "\n"
|
||||||
+ " quantity: 4\n"
|
+ " - part_no: E1628\n"
|
||||||
+ "\n"
|
+ " descrip: High Heeled \"Ruby\" Slippers\n"
|
||||||
+ " - part_no: E1628\n"
|
+ " size: 8\n"
|
||||||
+ " descrip: High Heeled \"Ruby\" Slippers\n"
|
+ " price: 100.27\n"
|
||||||
+ " size: 8\n"
|
+ " quantity: 1\n"
|
||||||
+ " price: 100.27\n"
|
+ "\n"
|
||||||
+ " quantity: 1\n"
|
+ "bill-to: &id001\n"
|
||||||
+ "\n"
|
+ " street: |\n"
|
||||||
+ "bill-to: &id001\n"
|
+ " 123 Tornado Alley\n"
|
||||||
+ " street: |\n"
|
+ " Suite 16\n"
|
||||||
+ " 123 Tornado Alley\n"
|
+ " city: East Centerville\n"
|
||||||
+ " Suite 16\n"
|
+ " state: KS\n"
|
||||||
+ " city: East Centerville\n"
|
+ "\n"
|
||||||
+ " state: KS\n"
|
+ "ship-to: *id001\n"
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ "ship-to: *id001\n"
|
+ "specialDelivery: >\n"
|
||||||
+ "\n"
|
+ " Follow the Yellow Brick\n"
|
||||||
+ "specialDelivery: >\n"
|
+ " Road to the Emerald City.\n"
|
||||||
+ " Follow the Yellow Brick\n"
|
+ " Pay no attention to the\n"
|
||||||
+ " Road to the Emerald City.\n"
|
+ " man behind the curtain.",
|
||||||
+ " Pay no attention to the\n"
|
// numberTest
|
||||||
+ " man behind the curtain.",
|
""
|
||||||
// numberTest
|
+ "someKey:\n"
|
||||||
""
|
+ " 1: 1\n"
|
||||||
+ "someKey:\n"
|
+ " 2: 2\n"
|
||||||
+ " 1: 1\n"
|
+ " 3: 3\n"
|
||||||
+ " 2: 2\n"
|
+ " 4: 4",
|
||||||
+ " 3: 3\n"
|
// nullTest
|
||||||
+ " 4: 4",
|
""
|
||||||
// nullTest
|
+ "null:\n"
|
||||||
""
|
+ " null: object\n"
|
||||||
+ "null:\n"
|
+ " object: null\n"
|
||||||
+ " null: object\n"
|
),
|
||||||
+ " object: null\n"
|
Arguments.of(
|
||||||
},
|
// provider
|
||||||
{
|
JsonConfiguration.class,
|
||||||
// provider
|
// testDocument
|
||||||
JsonConfiguration.class,
|
""
|
||||||
// testDocument
|
+ "{\n"
|
||||||
""
|
+ " \"customer\": {\n"
|
||||||
+ "{\n"
|
+ " \"given\": \"Dorothy\", \n"
|
||||||
+ " \"customer\": {\n"
|
+ " \"family\": \"Gale\"\n"
|
||||||
+ " \"given\": \"Dorothy\", \n"
|
+ " }, \n"
|
||||||
+ " \"family\": \"Gale\"\n"
|
+ " \"ship-to\": {\n"
|
||||||
+ " }, \n"
|
+ " \"city\": \"East Centerville\", \n"
|
||||||
+ " \"ship-to\": {\n"
|
+ " \"state\": \"KS\", \n"
|
||||||
+ " \"city\": \"East Centerville\", \n"
|
+ " \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n"
|
||||||
+ " \"state\": \"KS\", \n"
|
+ " }, \n"
|
||||||
+ " \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n"
|
+ " \"bill-to\": {\n"
|
||||||
+ " }, \n"
|
+ " \"city\": \"East Centerville\", \n"
|
||||||
+ " \"bill-to\": {\n"
|
+ " \"state\": \"KS\", \n"
|
||||||
+ " \"city\": \"East Centerville\", \n"
|
+ " \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n"
|
||||||
+ " \"state\": \"KS\", \n"
|
+ " }, \n"
|
||||||
+ " \"street\": \"123 Tornado Alley\\nSuite 16\\n\"\n"
|
+ " \"date\": \"2012-08-06\", \n"
|
||||||
+ " }, \n"
|
+ " \"items\": [\n"
|
||||||
+ " \"date\": \"2012-08-06\", \n"
|
+ " {\n"
|
||||||
+ " \"items\": [\n"
|
+ " \"part_no\": \"A4786\", \n"
|
||||||
+ " {\n"
|
+ " \"price\": 1.47, \n"
|
||||||
+ " \"part_no\": \"A4786\", \n"
|
+ " \"descrip\": \"Water Bucket (Filled)\", \n"
|
||||||
+ " \"price\": 1.47, \n"
|
+ " \"quantity\": 4\n"
|
||||||
+ " \"descrip\": \"Water Bucket (Filled)\", \n"
|
+ " }, \n"
|
||||||
+ " \"quantity\": 4\n"
|
+ " {\n"
|
||||||
+ " }, \n"
|
+ " \"part_no\": \"E1628\", \n"
|
||||||
+ " {\n"
|
+ " \"descrip\": \"High Heeled \\\"Ruby\\\" Slippers\", \n"
|
||||||
+ " \"part_no\": \"E1628\", \n"
|
+ " \"price\": 100.27, \n"
|
||||||
+ " \"descrip\": \"High Heeled \\\"Ruby\\\" Slippers\", \n"
|
+ " \"quantity\": 1, \n"
|
||||||
+ " \"price\": 100.27, \n"
|
+ " \"size\": 8\n"
|
||||||
+ " \"quantity\": 1, \n"
|
+ " }\n"
|
||||||
+ " \"size\": 8\n"
|
+ " ], \n"
|
||||||
+ " }\n"
|
+ " \"receipt\": \"Oz-Ware Purchase Invoice\", \n"
|
||||||
+ " ], \n"
|
+ " \"specialDelivery\": \"Follow the Yellow Brick Road to the Emerald City. Pay no attention to the man behind the curtain.\"\n"
|
||||||
+ " \"receipt\": \"Oz-Ware Purchase Invoice\", \n"
|
+ "}",
|
||||||
+ " \"specialDelivery\": \"Follow the Yellow Brick Road to the Emerald City. Pay no attention to the man behind the curtain.\"\n"
|
// numberTest
|
||||||
+ "}",
|
""
|
||||||
// numberTest
|
+ "{\n"
|
||||||
""
|
+ " \"someKey\": {\n"
|
||||||
+ "{\n"
|
+ " \"1\": 1, \n"
|
||||||
+ " \"someKey\": {\n"
|
+ " \"2\": 2, \n"
|
||||||
+ " \"1\": 1, \n"
|
+ " \"3\": 3, \n"
|
||||||
+ " \"2\": 2, \n"
|
+ " \"4\": 4\n"
|
||||||
+ " \"3\": 3, \n"
|
+ " }\n"
|
||||||
+ " \"4\": 4\n"
|
+ "}",
|
||||||
+ " }\n"
|
// nullTest
|
||||||
+ "}",
|
""
|
||||||
// nullTest
|
+ "{\n"
|
||||||
""
|
+ " \"null\": {\n"
|
||||||
+ "{\n"
|
+ " \"null\": \"object\", \n"
|
||||||
+ " \"null\": {\n"
|
+ " \"object\": null\n"
|
||||||
+ " \"null\": \"object\", \n"
|
+ " }\n"
|
||||||
+ " \"object\": null\n"
|
+ "}"
|
||||||
+ " }\n"
|
)
|
||||||
+ "}"
|
);
|
||||||
}
|
|
||||||
} );
|
|
||||||
// CHECKSTYLE:ON
|
|
||||||
}
|
}
|
||||||
//
|
|
||||||
private final Class<? extends ConfigurationProvider> provider;
|
|
||||||
private final String testDocument;
|
|
||||||
private final String numberTest;
|
|
||||||
private final String nullTest;
|
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testConfig() throws Exception
|
@MethodSource("data")
|
||||||
|
public void testConfig(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest) throws Exception
|
||||||
{
|
{
|
||||||
Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument );
|
Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument );
|
||||||
testSection( conf );
|
testSection( conf );
|
||||||
@@ -151,7 +141,7 @@ public class CompoundConfigurationTest
|
|||||||
ConfigurationProvider.getProvider( provider ).save( conf, sw );
|
ConfigurationProvider.getProvider( provider ).save( conf, sw );
|
||||||
|
|
||||||
// Check nulls were saved, see #1094
|
// Check nulls were saved, see #1094
|
||||||
Assert.assertFalse( "Config contains null", sw.toString().contains( "null" ) );
|
assertFalse( sw.toString().contains( "null" ), "Config contains null" );
|
||||||
|
|
||||||
conf = ConfigurationProvider.getProvider( provider ).load( new StringReader( sw.toString() ) );
|
conf = ConfigurationProvider.getProvider( provider ).load( new StringReader( sw.toString() ) );
|
||||||
conf.set( "receipt", "Oz-Ware Purchase Invoice" ); // Add it back
|
conf.set( "receipt", "Oz-Ware Purchase Invoice" ); // Add it back
|
||||||
@@ -160,37 +150,38 @@ public class CompoundConfigurationTest
|
|||||||
|
|
||||||
private void testSection(Configuration conf)
|
private void testSection(Configuration conf)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( "receipt", "Oz-Ware Purchase Invoice", conf.getString( "receipt" ) );
|
assertEquals( "Oz-Ware Purchase Invoice", conf.getString( "receipt" ), "receipt" );
|
||||||
// Assert.assertEquals( "date", "2012-08-06", conf.get( "date" ).toString() );
|
// assertEquals( "2012-08-06", conf.get( "date" ).toString(), "date" );
|
||||||
|
|
||||||
Configuration customer = conf.getSection( "customer" );
|
Configuration customer = conf.getSection( "customer" );
|
||||||
Assert.assertEquals( "customer.given", "Dorothy", customer.getString( "given" ) );
|
assertEquals( "Dorothy", customer.getString( "given" ), "customer.given" );
|
||||||
Assert.assertEquals( "customer.given", "Dorothy", conf.getString( "customer.given" ) );
|
assertEquals( "Dorothy", conf.getString( "customer.given" ), "customer.given" );
|
||||||
|
|
||||||
List items = conf.getList( "items" );
|
List items = conf.getList( "items" );
|
||||||
Map item = (Map) items.get( 0 );
|
Map item = (Map) items.get( 0 );
|
||||||
Assert.assertEquals( "items[0].part_no", "A4786", item.get( "part_no" ) );
|
assertEquals( "A4786", item.get( "part_no" ), "items[0].part_no" );
|
||||||
|
|
||||||
conf.set( "receipt", null );
|
conf.set( "receipt", null );
|
||||||
Assert.assertEquals( null, conf.get( "receipt" ) );
|
assertEquals( null, conf.get( "receipt" ) );
|
||||||
Assert.assertEquals( "foo", conf.get( "receipt", "foo" ) );
|
assertEquals( "foo", conf.get( "receipt", "foo" ) );
|
||||||
|
|
||||||
Configuration newSection = conf.getSection( "new.section" );
|
Configuration newSection = conf.getSection( "new.section" );
|
||||||
newSection.set( "value", "foo" );
|
newSection.set( "value", "foo" );
|
||||||
Assert.assertEquals( "foo", conf.get( "new.section.value" ) );
|
assertEquals( "foo", conf.get( "new.section.value" ) );
|
||||||
|
|
||||||
conf.set( "other.new.section", "bar" );
|
conf.set( "other.new.section", "bar" );
|
||||||
Assert.assertEquals( "bar", conf.get( "other.new.section" ) );
|
assertEquals( "bar", conf.get( "other.new.section" ) );
|
||||||
|
|
||||||
Assert.assertTrue( conf.contains( "customer.given" ) );
|
assertTrue( conf.contains( "customer.given" ) );
|
||||||
Assert.assertTrue( customer.contains( "given" ) );
|
assertTrue( customer.contains( "given" ) );
|
||||||
|
|
||||||
Assert.assertFalse( conf.contains( "customer.foo" ) );
|
assertFalse( conf.contains( "customer.foo" ) );
|
||||||
Assert.assertFalse( customer.contains( "foo" ) );
|
assertFalse( customer.contains( "foo" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testNumberedKeys()
|
@MethodSource("data")
|
||||||
|
public void testNumberedKeys(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest)
|
||||||
{
|
{
|
||||||
Configuration conf = ConfigurationProvider.getProvider( provider ).load( numberTest );
|
Configuration conf = ConfigurationProvider.getProvider( provider ).load( numberTest );
|
||||||
|
|
||||||
@@ -201,29 +192,31 @@ public class CompoundConfigurationTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testNull()
|
@MethodSource("data")
|
||||||
|
public void testNull(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest)
|
||||||
{
|
{
|
||||||
Configuration conf = ConfigurationProvider.getProvider( provider ).load( nullTest );
|
Configuration conf = ConfigurationProvider.getProvider( provider ).load( nullTest );
|
||||||
|
|
||||||
Assert.assertEquals( "object", conf.get( "null.null" ) );
|
assertEquals( "object", conf.get( "null.null" ) );
|
||||||
Assert.assertEquals( "object", conf.getSection( "null" ).get( "null" ) );
|
assertEquals( "object", conf.getSection( "null" ).get( "null" ) );
|
||||||
|
|
||||||
Assert.assertEquals( null, conf.get( "null.object" ) );
|
assertEquals( null, conf.get( "null.object" ) );
|
||||||
Assert.assertEquals( "", conf.getString( "null.object" ) );
|
assertEquals( "", conf.getString( "null.object" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testMapAddition()
|
@MethodSource("data")
|
||||||
|
public void testMapAddition(Class<? extends ConfigurationProvider> provider, String testDocument, String numberTest, String nullTest)
|
||||||
{
|
{
|
||||||
Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument );
|
Configuration conf = ConfigurationProvider.getProvider( provider ).load( testDocument );
|
||||||
|
|
||||||
conf.set( "addition", Collections.singletonMap( "foo", "bar" ) );
|
conf.set( "addition", Collections.singletonMap( "foo", "bar" ) );
|
||||||
|
|
||||||
// Order matters
|
// Order matters
|
||||||
Assert.assertEquals( "bar", conf.getSection( "addition" ).getString( "foo" ) );
|
assertEquals( "bar", conf.getSection( "addition" ).getString( "foo" ) );
|
||||||
Assert.assertEquals( "bar", conf.getString( "addition.foo" ) );
|
assertEquals( "bar", conf.getString( "addition.foo" ) );
|
||||||
|
|
||||||
Assert.assertTrue( conf.get( "addition" ) instanceof Configuration );
|
assertTrue( conf.get( "addition" ) instanceof Configuration );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package net.md_5.bungee.config;
|
package net.md_5.bungee.config;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class DefaultConfigurationTest
|
public class DefaultConfigurationTest
|
||||||
{
|
{
|
||||||
@@ -16,8 +16,8 @@ public class DefaultConfigurationTest
|
|||||||
|
|
||||||
Configuration actualConfig = new Configuration( defaultConfig );
|
Configuration actualConfig = new Configuration( defaultConfig );
|
||||||
|
|
||||||
Assert.assertEquals( 10, actualConfig.getInt( "setting" ) );
|
assertEquals( 10, actualConfig.getInt( "setting" ) );
|
||||||
Assert.assertEquals( 11, actualConfig.getInt( "nested.setting" ) );
|
assertEquals( 11, actualConfig.getInt( "nested.setting" ) );
|
||||||
Assert.assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) );
|
assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-event</artifactId>
|
<artifactId>bungeecord-event</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Event</name>
|
<name>BungeeCord-Event</name>
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package net.md_5.bungee.event;
|
package net.md_5.bungee.event;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
@@ -41,6 +42,8 @@ public class EventBus
|
|||||||
{
|
{
|
||||||
for ( EventHandlerMethod method : handlers )
|
for ( EventHandlerMethod method : handlers )
|
||||||
{
|
{
|
||||||
|
long start = System.nanoTime();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
method.invoke( event );
|
method.invoke( event );
|
||||||
@@ -54,6 +57,15 @@ public class EventBus
|
|||||||
{
|
{
|
||||||
logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() ), ex.getCause() );
|
logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() ), ex.getCause() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long elapsed = System.nanoTime() - start;
|
||||||
|
if ( elapsed > 50000000 )
|
||||||
|
{
|
||||||
|
logger.log( Level.WARNING, "Plugin listener {0} took {1}ms to process event {2}!", new Object[]
|
||||||
|
{
|
||||||
|
method.getListener().getClass().getName(), elapsed / 1000000, event
|
||||||
|
} );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +73,8 @@ public class EventBus
|
|||||||
private Map<Class<?>, Map<Byte, Set<Method>>> findHandlers(Object listener)
|
private Map<Class<?>, Map<Byte, Set<Method>>> findHandlers(Object listener)
|
||||||
{
|
{
|
||||||
Map<Class<?>, Map<Byte, Set<Method>>> handler = new HashMap<>();
|
Map<Class<?>, Map<Byte, Set<Method>>> handler = new HashMap<>();
|
||||||
for ( Method m : listener.getClass().getDeclaredMethods() )
|
Set<Method> methods = ImmutableSet.<Method>builder().add( listener.getClass().getMethods() ).add( listener.getClass().getDeclaredMethods() ).build();
|
||||||
|
for ( final Method m : methods )
|
||||||
{
|
{
|
||||||
EventHandler annotation = m.getAnnotation( EventHandler.class );
|
EventHandler annotation = m.getAnnotation( EventHandler.class );
|
||||||
if ( annotation != null )
|
if ( annotation != null )
|
||||||
@@ -75,18 +88,8 @@ public class EventBus
|
|||||||
} );
|
} );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Map<Byte, Set<Method>> prioritiesMap = handler.get( params[0] );
|
Map<Byte, Set<Method>> prioritiesMap = handler.computeIfAbsent( params[0], k -> new HashMap<>() );
|
||||||
if ( prioritiesMap == null )
|
Set<Method> priority = prioritiesMap.computeIfAbsent( annotation.priority(), k -> new HashSet<>() );
|
||||||
{
|
|
||||||
prioritiesMap = new HashMap<>();
|
|
||||||
handler.put( params[0], prioritiesMap );
|
|
||||||
}
|
|
||||||
Set<Method> priority = prioritiesMap.get( annotation.priority() );
|
|
||||||
if ( priority == null )
|
|
||||||
{
|
|
||||||
priority = new HashSet<>();
|
|
||||||
prioritiesMap.put( annotation.priority(), priority );
|
|
||||||
}
|
|
||||||
priority.add( m );
|
priority.add( m );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,22 +104,11 @@ public class EventBus
|
|||||||
{
|
{
|
||||||
for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() )
|
for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() )
|
||||||
{
|
{
|
||||||
Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.get( e.getKey() );
|
Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.computeIfAbsent( e.getKey(), k -> new HashMap<>() );
|
||||||
if ( prioritiesMap == null )
|
|
||||||
{
|
|
||||||
prioritiesMap = new HashMap<>();
|
|
||||||
byListenerAndPriority.put( e.getKey(), prioritiesMap );
|
|
||||||
}
|
|
||||||
for ( Map.Entry<Byte, Set<Method>> entry : e.getValue().entrySet() )
|
for ( Map.Entry<Byte, Set<Method>> entry : e.getValue().entrySet() )
|
||||||
{
|
{
|
||||||
Map<Object, Method[]> currentPriorityMap = prioritiesMap.get( entry.getKey() );
|
Map<Object, Method[]> currentPriorityMap = prioritiesMap.computeIfAbsent( entry.getKey(), k -> new HashMap<>() );
|
||||||
if ( currentPriorityMap == null )
|
currentPriorityMap.put( listener, entry.getValue().toArray( new Method[ 0 ] ) );
|
||||||
{
|
|
||||||
currentPriorityMap = new HashMap<>();
|
|
||||||
prioritiesMap.put( entry.getKey(), currentPriorityMap );
|
|
||||||
}
|
|
||||||
Method[] baked = new Method[ entry.getValue().size() ];
|
|
||||||
currentPriorityMap.put( listener, entry.getValue().toArray( baked ) );
|
|
||||||
}
|
}
|
||||||
bakeHandlers( e.getKey() );
|
bakeHandlers( e.getKey() );
|
||||||
}
|
}
|
||||||
@@ -194,7 +186,7 @@ public class EventBus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ( value++ < Byte.MAX_VALUE );
|
} while ( value++ < Byte.MAX_VALUE );
|
||||||
byEventBaked.put( eventClass, handlersList.toArray( new EventHandlerMethod[ handlersList.size() ] ) );
|
byEventBaked.put( eventClass, handlersList.toArray( new EventHandlerMethod[ 0 ] ) );
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
byEventBaked.remove( eventClass );
|
byEventBaked.remove( eventClass );
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package net.md_5.bungee.event;
|
package net.md_5.bungee.event;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class EventBusTest
|
public class EventBusTest
|
||||||
{
|
{
|
||||||
@@ -15,14 +15,14 @@ public class EventBusTest
|
|||||||
{
|
{
|
||||||
bus.register( this );
|
bus.register( this );
|
||||||
bus.post( new FirstEvent() );
|
bus.post( new FirstEvent() );
|
||||||
Assert.assertEquals( 0, latch.getCount() );
|
assertEquals( 0, latch.getCount() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void firstListener(FirstEvent event)
|
public void firstListener(FirstEvent event)
|
||||||
{
|
{
|
||||||
bus.post( new SecondEvent() );
|
bus.post( new SecondEvent() );
|
||||||
Assert.assertEquals( 1, latch.getCount() );
|
assertEquals( 1, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package net.md_5.bungee.event;
|
package net.md_5.bungee.event;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class EventPriorityTest
|
public class EventPriorityTest
|
||||||
{
|
{
|
||||||
@@ -16,41 +16,41 @@ public class EventPriorityTest
|
|||||||
bus.register( this );
|
bus.register( this );
|
||||||
bus.register( new EventPriorityListenerPartner() );
|
bus.register( new EventPriorityListenerPartner() );
|
||||||
bus.post( new PriorityTestEvent() );
|
bus.post( new PriorityTestEvent() );
|
||||||
Assert.assertEquals( 0, latch.getCount() );
|
assertEquals( 0, latch.getCount() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = Byte.MIN_VALUE)
|
@EventHandler(priority = Byte.MIN_VALUE)
|
||||||
public void onMinPriority(PriorityTestEvent event)
|
public void onMinPriority(PriorityTestEvent event)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( 7, latch.getCount() );
|
assertEquals( 7, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onLowestPriority(PriorityTestEvent event)
|
public void onLowestPriority(PriorityTestEvent event)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( 6, latch.getCount() );
|
assertEquals( 6, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onNormalPriority(PriorityTestEvent event)
|
public void onNormalPriority(PriorityTestEvent event)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( 4, latch.getCount() );
|
assertEquals( 4, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void onHighestPriority(PriorityTestEvent event)
|
public void onHighestPriority(PriorityTestEvent event)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( 2, latch.getCount() );
|
assertEquals( 2, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = Byte.MAX_VALUE)
|
@EventHandler(priority = Byte.MAX_VALUE)
|
||||||
public void onMaxPriority(PriorityTestEvent event)
|
public void onMaxPriority(PriorityTestEvent event)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( 1, latch.getCount() );
|
assertEquals( 1, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,14 +64,14 @@ public class EventPriorityTest
|
|||||||
@EventHandler(priority = EventPriority.HIGH)
|
@EventHandler(priority = EventPriority.HIGH)
|
||||||
public void onHighPriority(PriorityTestEvent event)
|
public void onHighPriority(PriorityTestEvent event)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( 3, latch.getCount() );
|
assertEquals( 3, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
public void onLowPriority(PriorityTestEvent event)
|
public void onLowPriority(PriorityTestEvent event)
|
||||||
{
|
{
|
||||||
Assert.assertEquals( 5, latch.getCount() );
|
assertEquals( 5, latch.getCount() );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
event/src/test/java/net/md_5/bungee/event/SubclassTest.java
Normal file
26
event/src/test/java/net/md_5/bungee/event/SubclassTest.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package net.md_5.bungee.event;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class SubclassTest extends EventBusTest
|
||||||
|
{
|
||||||
|
|
||||||
|
private final CountDownLatch latch = new CountDownLatch( 1 );
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
public void testNestedEvents()
|
||||||
|
{
|
||||||
|
super.testNestedEvents();
|
||||||
|
assertEquals( 0, latch.getCount() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
protected void extraListener(FirstEvent event)
|
||||||
|
{
|
||||||
|
assertEquals( 1, latch.getCount() );
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
package net.md_5.bungee.event;
|
package net.md_5.bungee.event;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class UnregisteringListenerTest
|
public class UnregisteringListenerTest
|
||||||
{
|
{
|
||||||
@@ -19,7 +19,7 @@ public class UnregisteringListenerTest
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEvent(TestEvent evt)
|
public void onEvent(TestEvent evt)
|
||||||
{
|
{
|
||||||
Assert.fail( "Event listener wasn't unregistered" );
|
fail( "Event listener wasn't unregistered" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestEvent
|
public static class TestEvent
|
||||||
|
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-log</artifactId>
|
<artifactId>bungeecord-log</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Log</name>
|
<name>BungeeCord-Log</name>
|
||||||
@@ -26,7 +25,7 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
|
@@ -13,19 +13,23 @@ public class BungeeLogger extends Logger
|
|||||||
|
|
||||||
private final LogDispatcher dispatcher = new LogDispatcher( this );
|
private final LogDispatcher dispatcher = new LogDispatcher( this );
|
||||||
|
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
@SuppressWarnings(
|
@SuppressWarnings(
|
||||||
{
|
{
|
||||||
"CallToPrintStackTrace", "CallToThreadStartDuringObjectConstruction"
|
"CallToPrintStackTrace", "CallToThreadStartDuringObjectConstruction"
|
||||||
})
|
})
|
||||||
|
// CHECKSTYLE:ON
|
||||||
@SuppressFBWarnings("SC_START_IN_CTOR")
|
@SuppressFBWarnings("SC_START_IN_CTOR")
|
||||||
public BungeeLogger(String loggerName, String filePattern, ConsoleReader reader)
|
public BungeeLogger(String loggerName, String filePattern, ConsoleReader reader)
|
||||||
{
|
{
|
||||||
super( loggerName, null );
|
super( loggerName, null );
|
||||||
setLevel( Level.ALL );
|
setLevel( Level.ALL );
|
||||||
|
setUseParentHandlers( false );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FileHandler fileHandler = new FileHandler( filePattern, 1 << 24, 8, true );
|
FileHandler fileHandler = new FileHandler( filePattern, 1 << 24, 8, true );
|
||||||
|
fileHandler.setLevel( Level.parse( System.getProperty( "net.md_5.bungee.file-log-level", "INFO" ) ) );
|
||||||
fileHandler.setFormatter( new ConciseFormatter( false ) );
|
fileHandler.setFormatter( new ConciseFormatter( false ) );
|
||||||
addHandler( fileHandler );
|
addHandler( fileHandler );
|
||||||
|
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
package net.md_5.bungee.log;
|
||||||
|
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
import java.util.logging.LogRecord;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class LoggingForwardHandler extends Handler
|
||||||
|
{
|
||||||
|
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publish(LogRecord record)
|
||||||
|
{
|
||||||
|
logger.log( record );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws SecurityException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -1,20 +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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module-cmd-alert</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>cmd_alert</name>
|
|
||||||
<description>Provides the alert and alertraw commands</description>
|
|
||||||
</project>
|
|
@@ -1,46 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.alert;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
|
||||||
|
|
||||||
public class CommandAlert extends Command
|
|
||||||
{
|
|
||||||
|
|
||||||
public CommandAlert()
|
|
||||||
{
|
|
||||||
super( "alert", "bungeecord.command.alert" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
if ( args.length == 0 )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "message_needed" ) );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
if ( args[0].startsWith( "&h" ) )
|
|
||||||
{
|
|
||||||
// Remove &h
|
|
||||||
args[0] = args[0].substring( 2, args[0].length() );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
builder.append( ProxyServer.getInstance().getTranslation( "alert" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( String s : args )
|
|
||||||
{
|
|
||||||
builder.append( ChatColor.translateAlternateColorCodes( '&', s ) );
|
|
||||||
builder.append( " " );
|
|
||||||
}
|
|
||||||
|
|
||||||
String message = builder.substring( 0, builder.length() - 1 );
|
|
||||||
|
|
||||||
ProxyServer.getInstance().broadcast( TextComponent.fromLegacyText( message ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,56 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.alert;
|
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
|
||||||
import net.md_5.bungee.api.chat.HoverEvent;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
|
||||||
import net.md_5.bungee.chat.ComponentSerializer;
|
|
||||||
|
|
||||||
public class CommandAlertRaw extends Command
|
|
||||||
{
|
|
||||||
|
|
||||||
public CommandAlertRaw()
|
|
||||||
{
|
|
||||||
super( "alertraw", "bungeecord.command.alert" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
if ( args.length == 0 )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "message_needed" ) );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
String message = Joiner.on( ' ' ).join( args );
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProxyServer.getInstance().broadcast( ComponentSerializer.parse( message ) );
|
|
||||||
} catch ( Exception e )
|
|
||||||
{
|
|
||||||
Throwable error = e;
|
|
||||||
while ( error.getCause() != null )
|
|
||||||
{
|
|
||||||
error = error.getCause();
|
|
||||||
}
|
|
||||||
if ( sender instanceof ProxiedPlayer )
|
|
||||||
{
|
|
||||||
sender.sendMessage( new ComponentBuilder( ProxyServer.getInstance().getTranslation( "error_occurred_player" ) )
|
|
||||||
.event( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( error.getMessage() )
|
|
||||||
.color( ChatColor.RED )
|
|
||||||
.create() ) )
|
|
||||||
.create()
|
|
||||||
);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "error_occurred_console", error.getMessage() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.alert;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PluginAlert extends Plugin
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
getProxy().getPluginManager().registerCommand( this, new CommandAlert() );
|
|
||||||
getProxy().getPluginManager().registerCommand( this, new CommandAlertRaw() );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: net.md_5.bungee.module.cmd.alert.PluginAlert
|
|
||||||
version: ${describe}
|
|
||||||
description: ${project.description}
|
|
||||||
author: ${module.author}
|
|
@@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project-shared-configuration>
|
|
||||||
<!--
|
|
||||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
|
||||||
The configuration is intended to be shared among all the users of project and
|
|
||||||
therefore it is assumed to be part of version control checkout.
|
|
||||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
|
||||||
-->
|
|
||||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
|
||||||
<!--
|
|
||||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
|
||||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
|
||||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
|
||||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
|
||||||
-->
|
|
||||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
|
||||||
</properties>
|
|
||||||
</project-shared-configuration>
|
|
@@ -1,20 +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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module-cmd-find</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>cmd_find</name>
|
|
||||||
<description>Provides the find command</description>
|
|
||||||
</project>
|
|
@@ -1,34 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.find;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.command.PlayerCommand;
|
|
||||||
|
|
||||||
public class CommandFind extends PlayerCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
public CommandFind()
|
|
||||||
{
|
|
||||||
super( "find", "bungeecord.command.find" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
if ( args.length != 1 )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "username_needed" ) );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] );
|
|
||||||
if ( player == null || player.getServer() == null )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_online_at", player.getName(), player.getServer().getInfo().getName() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.find;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PluginFind extends Plugin
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
getProxy().getPluginManager().registerCommand( this, new CommandFind() );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: net.md_5.bungee.module.cmd.find.PluginFind
|
|
||||||
version: ${describe}
|
|
||||||
description: ${project.description}
|
|
||||||
author: ${module.author}
|
|
@@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project-shared-configuration>
|
|
||||||
<!--
|
|
||||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
|
||||||
The configuration is intended to be shared among all the users of project and
|
|
||||||
therefore it is assumed to be part of version control checkout.
|
|
||||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
|
||||||
-->
|
|
||||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
|
||||||
<!--
|
|
||||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
|
||||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
|
||||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
|
||||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
|
||||||
-->
|
|
||||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
|
||||||
</properties>
|
|
||||||
</project-shared-configuration>
|
|
@@ -1,20 +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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module-cmd-list</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>cmd_list</name>
|
|
||||||
<description>Provides the glist command</description>
|
|
||||||
</project>
|
|
@@ -1,47 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.list;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import net.md_5.bungee.Util;
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Command to list all players connected to the proxy.
|
|
||||||
*/
|
|
||||||
public class CommandList extends Command
|
|
||||||
{
|
|
||||||
|
|
||||||
public CommandList()
|
|
||||||
{
|
|
||||||
super( "glist", "bungeecord.command.list" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
for ( ServerInfo server : ProxyServer.getInstance().getServers().values() )
|
|
||||||
{
|
|
||||||
if ( !server.canAccess( sender ) )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> players = new ArrayList<>();
|
|
||||||
for ( ProxiedPlayer player : server.getPlayers() )
|
|
||||||
{
|
|
||||||
players.add( player.getDisplayName() );
|
|
||||||
}
|
|
||||||
Collections.sort( players, String.CASE_INSENSITIVE_ORDER );
|
|
||||||
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_list", server.getName(), server.getPlayers().size(), Util.format( players, ChatColor.RESET + ", " ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "total_players", ProxyServer.getInstance().getOnlineCount() ) );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.list;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PluginList extends Plugin
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
getProxy().getPluginManager().registerCommand( this, new CommandList() );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: net.md_5.bungee.module.cmd.list.PluginList
|
|
||||||
version: ${describe}
|
|
||||||
description: ${project.description}
|
|
||||||
author: ${module.author}
|
|
@@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project-shared-configuration>
|
|
||||||
<!--
|
|
||||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
|
||||||
The configuration is intended to be shared among all the users of project and
|
|
||||||
therefore it is assumed to be part of version control checkout.
|
|
||||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
|
||||||
-->
|
|
||||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
|
||||||
<!--
|
|
||||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
|
||||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
|
||||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
|
||||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
|
||||||
-->
|
|
||||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
|
||||||
</properties>
|
|
||||||
</project-shared-configuration>
|
|
@@ -1,20 +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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module-cmd-send</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>cmd_send</name>
|
|
||||||
<description>Provides the gsend command</description>
|
|
||||||
</project>
|
|
@@ -1,200 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.send;
|
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import net.md_5.bungee.api.Callback;
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.ServerConnectRequest;
|
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
|
||||||
import net.md_5.bungee.api.chat.HoverEvent;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
|
||||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
|
||||||
|
|
||||||
public class CommandSend extends Command implements TabExecutor
|
|
||||||
{
|
|
||||||
|
|
||||||
protected static class SendCallback
|
|
||||||
{
|
|
||||||
|
|
||||||
private final Map<ServerConnectRequest.Result, List<String>> results = new HashMap<>();
|
|
||||||
private final CommandSender sender;
|
|
||||||
private int count = 0;
|
|
||||||
|
|
||||||
public SendCallback(CommandSender sender)
|
|
||||||
{
|
|
||||||
this.sender = sender;
|
|
||||||
for ( ServerConnectRequest.Result result : ServerConnectRequest.Result.values() )
|
|
||||||
{
|
|
||||||
results.put( result, new ArrayList<String>() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void lastEntryDone()
|
|
||||||
{
|
|
||||||
sender.sendMessage( ChatColor.GREEN.toString() + ChatColor.BOLD + "Send Results:" );
|
|
||||||
for ( Map.Entry<ServerConnectRequest.Result, List<String>> entry : results.entrySet() )
|
|
||||||
{
|
|
||||||
ComponentBuilder builder = new ComponentBuilder( "" );
|
|
||||||
if ( !entry.getValue().isEmpty() )
|
|
||||||
{
|
|
||||||
builder.event( new HoverEvent( HoverEvent.Action.SHOW_TEXT,
|
|
||||||
new ComponentBuilder( Joiner.on( ", " ).join( entry.getValue() ) ).color( ChatColor.YELLOW ).create() ) );
|
|
||||||
}
|
|
||||||
builder.append( entry.getKey().name() + ": " ).color( ChatColor.GREEN );
|
|
||||||
builder.append( "" + entry.getValue().size() ).bold( true );
|
|
||||||
sender.sendMessage( builder.create() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Entry implements Callback<ServerConnectRequest.Result>
|
|
||||||
{
|
|
||||||
|
|
||||||
private final SendCallback callback;
|
|
||||||
private final ProxiedPlayer player;
|
|
||||||
private final ServerInfo target;
|
|
||||||
|
|
||||||
public Entry(SendCallback callback, ProxiedPlayer player, ServerInfo target)
|
|
||||||
{
|
|
||||||
this.callback = callback;
|
|
||||||
this.player = player;
|
|
||||||
this.target = target;
|
|
||||||
this.callback.count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void done(ServerConnectRequest.Result result, Throwable error)
|
|
||||||
{
|
|
||||||
callback.results.get( result ).add( player.getName() );
|
|
||||||
if ( result == ServerConnectRequest.Result.SUCCESS )
|
|
||||||
{
|
|
||||||
player.sendMessage( ProxyServer.getInstance().getTranslation( "you_got_summoned", target.getName(), callback.sender.getName() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( --callback.count == 0 )
|
|
||||||
{
|
|
||||||
callback.lastEntryDone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandSend()
|
|
||||||
{
|
|
||||||
super( "send", "bungeecord.command.send" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
if ( args.length != 2 )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "send_cmd_usage" ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ServerInfo server = ProxyServer.getInstance().getServerInfo( args[1] );
|
|
||||||
if ( server == null )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "no_server" ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ProxiedPlayer> targets;
|
|
||||||
if ( args[0].equalsIgnoreCase( "all" ) )
|
|
||||||
{
|
|
||||||
targets = new ArrayList<>( ProxyServer.getInstance().getPlayers() );
|
|
||||||
} else if ( args[0].equalsIgnoreCase( "current" ) )
|
|
||||||
{
|
|
||||||
if ( !( sender instanceof ProxiedPlayer ) )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "player_only" ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
|
||||||
targets = new ArrayList<>( player.getServer().getInfo().getPlayers() );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// If we use a server name, send the entire server. This takes priority over players.
|
|
||||||
ServerInfo serverTarget = ProxyServer.getInstance().getServerInfo( args[0] );
|
|
||||||
if ( serverTarget != null )
|
|
||||||
{
|
|
||||||
targets = new ArrayList<>( serverTarget.getPlayers() );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] );
|
|
||||||
if ( player == null )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
targets = Collections.singletonList( player );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final SendCallback callback = new SendCallback( sender );
|
|
||||||
for ( ProxiedPlayer player : targets )
|
|
||||||
{
|
|
||||||
ServerConnectRequest request = ServerConnectRequest.builder()
|
|
||||||
.target( server )
|
|
||||||
.reason( ServerConnectEvent.Reason.COMMAND )
|
|
||||||
.callback( new SendCallback.Entry( callback, player, server ) )
|
|
||||||
.build();
|
|
||||||
player.connect( request );
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.sendMessage( ChatColor.DARK_GREEN + "Attempting to send " + targets.size() + " players to " + server.getName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
if ( args.length > 2 || args.length == 0 )
|
|
||||||
{
|
|
||||||
return ImmutableSet.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> matches = new HashSet<>();
|
|
||||||
if ( args.length == 1 )
|
|
||||||
{
|
|
||||||
String search = args[0].toLowerCase( Locale.ROOT );
|
|
||||||
for ( ProxiedPlayer player : ProxyServer.getInstance().getPlayers() )
|
|
||||||
{
|
|
||||||
if ( player.getName().toLowerCase( Locale.ROOT ).startsWith( search ) )
|
|
||||||
{
|
|
||||||
matches.add( player.getName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( "all".startsWith( search ) )
|
|
||||||
{
|
|
||||||
matches.add( "all" );
|
|
||||||
}
|
|
||||||
if ( "current".startsWith( search ) )
|
|
||||||
{
|
|
||||||
matches.add( "current" );
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
String search = args[1].toLowerCase( Locale.ROOT );
|
|
||||||
for ( String server : ProxyServer.getInstance().getServers().keySet() )
|
|
||||||
{
|
|
||||||
if ( server.toLowerCase( Locale.ROOT ).startsWith( search ) )
|
|
||||||
{
|
|
||||||
matches.add( server );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.send;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PluginSend extends Plugin
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
getProxy().getPluginManager().registerCommand( this, new CommandSend() );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: net.md_5.bungee.module.cmd.send.PluginSend
|
|
||||||
version: ${describe}
|
|
||||||
description: ${project.description}
|
|
||||||
author: ${module.author}
|
|
@@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project-shared-configuration>
|
|
||||||
<!--
|
|
||||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
|
||||||
The configuration is intended to be shared among all the users of project and
|
|
||||||
therefore it is assumed to be part of version control checkout.
|
|
||||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
|
||||||
-->
|
|
||||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
|
||||||
<!--
|
|
||||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
|
||||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
|
||||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
|
||||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
|
||||||
-->
|
|
||||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
|
||||||
</properties>
|
|
||||||
</project-shared-configuration>
|
|
@@ -1,20 +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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module-cmd-server</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>cmd_server</name>
|
|
||||||
<description>Provides the server command</description>
|
|
||||||
</project>
|
|
@@ -1,104 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.server;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
|
||||||
import net.md_5.bungee.api.chat.HoverEvent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
|
||||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Command to list and switch a player between available servers.
|
|
||||||
*/
|
|
||||||
public class CommandServer extends Command implements TabExecutor
|
|
||||||
{
|
|
||||||
|
|
||||||
public CommandServer()
|
|
||||||
{
|
|
||||||
super( "server", "bungeecord.command.server" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args)
|
|
||||||
{
|
|
||||||
Map<String, ServerInfo> servers = ProxyServer.getInstance().getServers();
|
|
||||||
if ( args.length == 0 )
|
|
||||||
{
|
|
||||||
if ( sender instanceof ProxiedPlayer )
|
|
||||||
{
|
|
||||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "current_server", ( (ProxiedPlayer) sender ).getServer().getInfo().getName() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
ComponentBuilder serverList = new ComponentBuilder().appendLegacy( ProxyServer.getInstance().getTranslation( "server_list" ) );
|
|
||||||
boolean first = true;
|
|
||||||
for ( ServerInfo server : servers.values() )
|
|
||||||
{
|
|
||||||
if ( server.canAccess( sender ) )
|
|
||||||
{
|
|
||||||
TextComponent serverTextComponent = new TextComponent( first ? server.getName() : ", " + server.getName() );
|
|
||||||
int count = server.getPlayers().size();
|
|
||||||
serverTextComponent.setHoverEvent( new HoverEvent(
|
|
||||||
HoverEvent.Action.SHOW_TEXT,
|
|
||||||
new ComponentBuilder( count + ( count == 1 ? " player" : " players" ) + "\n" ).appendLegacy( ProxyServer.getInstance().getTranslation( "click_to_connect" ) ).create() )
|
|
||||||
);
|
|
||||||
serverTextComponent.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/server " + server.getName() ) );
|
|
||||||
serverList.append( serverTextComponent );
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sender.sendMessage( serverList.create() );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
if ( !( sender instanceof ProxiedPlayer ) )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
|
||||||
|
|
||||||
ServerInfo server = servers.get( args[0] );
|
|
||||||
if ( server == null )
|
|
||||||
{
|
|
||||||
player.sendMessage( ProxyServer.getInstance().getTranslation( "no_server" ) );
|
|
||||||
} else if ( !server.canAccess( player ) )
|
|
||||||
{
|
|
||||||
player.sendMessage( ProxyServer.getInstance().getTranslation( "no_server_permission" ) );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
player.connect( server, ServerConnectEvent.Reason.COMMAND );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<String> onTabComplete(final CommandSender sender, final String[] args)
|
|
||||||
{
|
|
||||||
return ( args.length > 1 ) ? Collections.EMPTY_LIST : Iterables.transform( Iterables.filter( ProxyServer.getInstance().getServers().values(), new Predicate<ServerInfo>()
|
|
||||||
{
|
|
||||||
private final String lower = ( args.length == 0 ) ? "" : args[0].toLowerCase( Locale.ROOT );
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(ServerInfo input)
|
|
||||||
{
|
|
||||||
return input.getName().toLowerCase( Locale.ROOT ).startsWith( lower ) && input.canAccess( sender );
|
|
||||||
}
|
|
||||||
} ), new Function<ServerInfo, String>()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public String apply(ServerInfo input)
|
|
||||||
{
|
|
||||||
return input.getName();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
package net.md_5.bungee.module.cmd.server;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PluginServer extends Plugin
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
getProxy().getPluginManager().registerCommand( this, new CommandServer() );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: net.md_5.bungee.module.cmd.server.PluginServer
|
|
||||||
version: ${describe}
|
|
||||||
description: ${project.description}
|
|
||||||
author: ${module.author}
|
|
@@ -1,54 +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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
|
|
||||||
<name>BungeeCord Modules</name>
|
|
||||||
<description>Parent project for all BungeeCord modules.</description>
|
|
||||||
|
|
||||||
<modules>
|
|
||||||
<module>cmd-alert</module>
|
|
||||||
<module>cmd-find</module>
|
|
||||||
<module>cmd-list</module>
|
|
||||||
<module>cmd-send</module>
|
|
||||||
<module>cmd-server</module>
|
|
||||||
<module>reconnect-yaml</module>
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<module.author>SpigotMC</module.author>
|
|
||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
|
||||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-api</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>${project.name}</finalName>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<filtering>true</filtering>
|
|
||||||
<directory>${basedir}/src/main/resources</directory>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
@@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project-shared-configuration>
|
|
||||||
<!--
|
|
||||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
|
||||||
The configuration is intended to be shared among all the users of project and
|
|
||||||
therefore it is assumed to be part of version control checkout.
|
|
||||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
|
||||||
-->
|
|
||||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
|
||||||
<!--
|
|
||||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
|
||||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
|
||||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
|
||||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
|
||||||
-->
|
|
||||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
|
||||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
|
||||||
</properties>
|
|
||||||
</project-shared-configuration>
|
|
@@ -1,20 +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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-module-reconnect-yaml</artifactId>
|
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>reconnect_yaml</name>
|
|
||||||
<description>Provides reconnect location functionality in locations.yml</description>
|
|
||||||
</project>
|
|
@@ -1,22 +0,0 @@
|
|||||||
package net.md_5.bungee.module.reconnect.yaml;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.config.ListenerInfo;
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PluginYaml extends Plugin
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
// TODO: Abstract this for other reconnect modules
|
|
||||||
for ( ListenerInfo info : getProxy().getConfig().getListeners() )
|
|
||||||
{
|
|
||||||
if ( !info.isForceDefault() && getProxy().getReconnectHandler() == null )
|
|
||||||
{
|
|
||||||
getProxy().setReconnectHandler( new YamlReconnectHandler() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,115 +0,0 @@
|
|||||||
package net.md_5.bungee.module.reconnect.yaml;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import net.md_5.bungee.api.AbstractReconnectHandler;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.util.CaseInsensitiveMap;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
public class YamlReconnectHandler extends AbstractReconnectHandler
|
|
||||||
{
|
|
||||||
|
|
||||||
private final Yaml yaml = new Yaml();
|
|
||||||
private final File file = new File( "locations.yml" );
|
|
||||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
|
||||||
/*========================================================================*/
|
|
||||||
private CaseInsensitiveMap<String> data;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public YamlReconnectHandler()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
file.createNewFile();
|
|
||||||
try ( FileReader rd = new FileReader( file ) )
|
|
||||||
{
|
|
||||||
Map map = yaml.loadAs( rd, Map.class );
|
|
||||||
if ( map != null )
|
|
||||||
{
|
|
||||||
data = new CaseInsensitiveMap<>( map );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch ( Exception ex )
|
|
||||||
{
|
|
||||||
file.renameTo( new File( "locations.yml.old" ) );
|
|
||||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load reconnect locations, resetting them" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( data == null )
|
|
||||||
{
|
|
||||||
data = new CaseInsensitiveMap<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ServerInfo getStoredServer(ProxiedPlayer player)
|
|
||||||
{
|
|
||||||
ServerInfo server = null;
|
|
||||||
lock.readLock().lock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
server = ProxyServer.getInstance().getServerInfo( data.get( key( player ) ) );
|
|
||||||
} finally
|
|
||||||
{
|
|
||||||
lock.readLock().unlock();
|
|
||||||
}
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setServer(ProxiedPlayer player)
|
|
||||||
{
|
|
||||||
lock.writeLock().lock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
data.put( key( player ), ( player.getReconnectServer() != null ) ? player.getReconnectServer().getName() : player.getServer().getInfo().getName() );
|
|
||||||
} finally
|
|
||||||
{
|
|
||||||
lock.writeLock().unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String key(ProxiedPlayer player)
|
|
||||||
{
|
|
||||||
InetSocketAddress host = player.getPendingConnection().getVirtualHost();
|
|
||||||
return player.getName() + ";" + host.getHostString() + ":" + host.getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save()
|
|
||||||
{
|
|
||||||
Map<String, String> copy = new HashMap<>();
|
|
||||||
lock.readLock().lock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
copy.putAll( data );
|
|
||||||
} finally
|
|
||||||
{
|
|
||||||
lock.readLock().unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
try ( FileWriter wr = new FileWriter( file ) )
|
|
||||||
{
|
|
||||||
yaml.dump( copy, wr );
|
|
||||||
} catch ( IOException ex )
|
|
||||||
{
|
|
||||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not save reconnect locations", ex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: net.md_5.bungee.module.reconnect.yaml.PluginYaml
|
|
||||||
version: ${describe}
|
|
||||||
description: ${project.description}
|
|
||||||
author: ${module.author}
|
|
@@ -1,6 +1,14 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
CXX="g++ -shared -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/"
|
set -eu
|
||||||
|
|
||||||
$CXX src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so -lcrypto
|
echo "Compiling mbedtls"
|
||||||
$CXX src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so -lz
|
(cd mbedtls && make no_test)
|
||||||
|
|
||||||
|
echo "Compiling zlib"
|
||||||
|
(cd zlib && CFLAGS=-fPIC ./configure --static && make)
|
||||||
|
|
||||||
|
CXX="g++ -shared -fPIC -Wl,--wrap=memcpy -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/"
|
||||||
|
|
||||||
|
$CXX -Imbedtls/include src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so mbedtls/library/libmbedcrypto.a
|
||||||
|
$CXX -Izlib src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so zlib/libz.a
|
||||||
|
1
native/mbedtls
Submodule
1
native/mbedtls
Submodule
Submodule native/mbedtls added at 8c89224991
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-native</artifactId>
|
<artifactId>bungeecord-native</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Native</name>
|
<name>BungeeCord-Native</name>
|
||||||
@@ -22,7 +21,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-transport</artifactId>
|
<artifactId>netty-transport</artifactId>
|
||||||
<version>${netty.version}</version>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@@ -1,12 +1,15 @@
|
|||||||
// Support for CentOS 6
|
|
||||||
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <mbedtls/aes.h>
|
#include <mbedtls/aes.h>
|
||||||
#include "net_md_5_bungee_jni_cipher_NativeCipherImpl.h"
|
#include "net_md_5_bungee_jni_cipher_NativeCipherImpl.h"
|
||||||
|
|
||||||
|
// Support for CentOS 6
|
||||||
|
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
|
||||||
|
extern "C" void *__wrap_memcpy(void *dest, const void *src, size_t n) {
|
||||||
|
return memcpy(dest, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
|
|
||||||
struct crypto_context {
|
struct crypto_context {
|
||||||
|
@@ -1,7 +1,15 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h"
|
#include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h"
|
||||||
|
|
||||||
|
// Support for CentOS 6
|
||||||
|
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
|
||||||
|
extern "C" void *__wrap_memcpy(void *dest, const void *src, size_t n) {
|
||||||
|
return memcpy(dest, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
|
|
||||||
static jfieldID consumedID;
|
static jfieldID consumedID;
|
||||||
|
@@ -6,18 +6,19 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import net.md_5.bungee.jni.cipher.BungeeCipher;
|
import net.md_5.bungee.jni.cipher.BungeeCipher;
|
||||||
|
|
||||||
public final class NativeCode<T>
|
public final class NativeCode<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Class<? extends T> javaImpl;
|
private final Supplier<? extends T> javaImpl;
|
||||||
private final Class<? extends T> nativeImpl;
|
private final Supplier<? extends T> nativeImpl;
|
||||||
//
|
//
|
||||||
private boolean loaded;
|
private boolean loaded;
|
||||||
|
|
||||||
public NativeCode(String name, Class<? extends T> javaImpl, Class<? extends T> nativeImpl)
|
public NativeCode(String name, Supplier<? extends T> javaImpl, Supplier<? extends T> nativeImpl)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.javaImpl = javaImpl;
|
this.javaImpl = javaImpl;
|
||||||
@@ -26,13 +27,7 @@ public final class NativeCode<T>
|
|||||||
|
|
||||||
public T newInstance()
|
public T newInstance()
|
||||||
{
|
{
|
||||||
try
|
return ( loaded ) ? nativeImpl.get() : javaImpl.get();
|
||||||
{
|
|
||||||
return ( loaded ) ? nativeImpl.getDeclaredConstructor().newInstance() : javaImpl.getDeclaredConstructor().newInstance();
|
|
||||||
} catch ( ReflectiveOperationException ex )
|
|
||||||
{
|
|
||||||
throw new RuntimeException( "Error getting instance", ex );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean load()
|
public boolean load()
|
||||||
|
@@ -25,9 +25,15 @@ public class JavaCipher implements BungeeCipher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaCipher() throws GeneralSecurityException
|
public JavaCipher()
|
||||||
{
|
{
|
||||||
this.cipher = Cipher.getInstance( "AES/CFB8/NoPadding" );
|
try
|
||||||
|
{
|
||||||
|
this.cipher = Cipher.getInstance( "AES/CFB8/NoPadding" );
|
||||||
|
} catch ( GeneralSecurityException ex )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( ex );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,6 @@
|
|||||||
package net.md_5.bungee;
|
package net.md_5.bungee;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -9,12 +10,11 @@ import net.md_5.bungee.jni.NativeCode;
|
|||||||
import net.md_5.bungee.jni.cipher.BungeeCipher;
|
import net.md_5.bungee.jni.cipher.BungeeCipher;
|
||||||
import net.md_5.bungee.jni.cipher.JavaCipher;
|
import net.md_5.bungee.jni.cipher.JavaCipher;
|
||||||
import net.md_5.bungee.jni.cipher.NativeCipher;
|
import net.md_5.bungee.jni.cipher.NativeCipher;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.runners.MethodSorters;
|
|
||||||
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@TestMethodOrder(MethodOrderer.MethodName.class)
|
||||||
public class NativeCipherTest
|
public class NativeCipherTest
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ public class NativeCipherTest
|
|||||||
private final SecretKey secret = new SecretKeySpec( new byte[ 16 ], "AES" );
|
private final SecretKey secret = new SecretKeySpec( new byte[ 16 ], "AES" );
|
||||||
private static final int BENCHMARK_COUNT = 4096;
|
private static final int BENCHMARK_COUNT = 4096;
|
||||||
//
|
//
|
||||||
private static final NativeCode<BungeeCipher> factory = new NativeCode<>( "native-cipher", JavaCipher.class, NativeCipher.class );
|
private static final NativeCode<BungeeCipher> factory = new NativeCode<>( "native-cipher", JavaCipher::new, NativeCipher::new );
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNative() throws Exception
|
public void testNative() throws Exception
|
||||||
@@ -34,7 +34,7 @@ public class NativeCipherTest
|
|||||||
if ( NativeCode.isSupported() )
|
if ( NativeCode.isSupported() )
|
||||||
{
|
{
|
||||||
boolean loaded = factory.load();
|
boolean loaded = factory.load();
|
||||||
Assert.assertTrue( "Native cipher failed to load!", loaded );
|
assertTrue( loaded, "Native cipher failed to load!" );
|
||||||
|
|
||||||
NativeCipher cipher = new NativeCipher();
|
NativeCipher cipher = new NativeCipher();
|
||||||
System.out.println( "Testing native cipher..." );
|
System.out.println( "Testing native cipher..." );
|
||||||
@@ -48,7 +48,7 @@ public class NativeCipherTest
|
|||||||
if ( NativeCode.isSupported() )
|
if ( NativeCode.isSupported() )
|
||||||
{
|
{
|
||||||
boolean loaded = factory.load();
|
boolean loaded = factory.load();
|
||||||
Assert.assertTrue( "Native cipher failed to load!", loaded );
|
assertTrue( loaded, "Native cipher failed to load!" );
|
||||||
|
|
||||||
NativeCipher cipher = new NativeCipher();
|
NativeCipher cipher = new NativeCipher();
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ public class NativeCipherTest
|
|||||||
// Encrypt
|
// Encrypt
|
||||||
cipher.init( true, secret );
|
cipher.init( true, secret );
|
||||||
cipher.cipher( nativePlain, out );
|
cipher.cipher( nativePlain, out );
|
||||||
Assert.assertEquals( nativeCiphered, out );
|
assertEquals( nativeCiphered, out );
|
||||||
|
|
||||||
out.clear();
|
out.clear();
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ public class NativeCipherTest
|
|||||||
cipher.init( false, secret );
|
cipher.init( false, secret );
|
||||||
cipher.cipher( nativeCiphered, out );
|
cipher.cipher( nativeCiphered, out );
|
||||||
nativePlain.resetReaderIndex();
|
nativePlain.resetReaderIndex();
|
||||||
Assert.assertEquals( nativePlain, out );
|
assertEquals( nativePlain, out );
|
||||||
|
|
||||||
System.out.println( "This cipher works correctly!" );
|
System.out.println( "This cipher works correctly!" );
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package net.md_5.bungee;
|
package net.md_5.bungee;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -9,20 +10,19 @@ import net.md_5.bungee.jni.NativeCode;
|
|||||||
import net.md_5.bungee.jni.zlib.BungeeZlib;
|
import net.md_5.bungee.jni.zlib.BungeeZlib;
|
||||||
import net.md_5.bungee.jni.zlib.JavaZlib;
|
import net.md_5.bungee.jni.zlib.JavaZlib;
|
||||||
import net.md_5.bungee.jni.zlib.NativeZlib;
|
import net.md_5.bungee.jni.zlib.NativeZlib;
|
||||||
import org.junit.Assert;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class NativeZlibTest
|
public class NativeZlibTest
|
||||||
{
|
{
|
||||||
|
|
||||||
private final NativeCode<BungeeZlib> factory = new NativeCode<>( "native-compress", JavaZlib.class, NativeZlib.class );
|
private final NativeCode<BungeeZlib> factory = new NativeCode<>( "native-compress", JavaZlib::new, NativeZlib::new );
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doTest() throws DataFormatException
|
public void doTest() throws DataFormatException
|
||||||
{
|
{
|
||||||
if ( NativeCode.isSupported() )
|
if ( NativeCode.isSupported() )
|
||||||
{
|
{
|
||||||
Assert.assertTrue( "Native code failed to load!", factory.load() );
|
assertTrue( factory.load(), "Native code failed to load!" );
|
||||||
test( factory.newInstance() );
|
test( factory.newInstance() );
|
||||||
}
|
}
|
||||||
test( new JavaZlib() );
|
test( new JavaZlib() );
|
||||||
@@ -64,6 +64,6 @@ public class NativeZlibTest
|
|||||||
long elapsed = System.currentTimeMillis() - start;
|
long elapsed = System.currentTimeMillis() - start;
|
||||||
System.out.println( "Took: " + elapsed + "ms" );
|
System.out.println( "Took: " + elapsed + "ms" );
|
||||||
|
|
||||||
Assert.assertTrue( "Results do not match", Arrays.equals( dataBuf, check ) );
|
assertTrue( Arrays.equals( dataBuf, check ), "Results do not match" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
native/zlib
Submodule
1
native/zlib
Submodule
Submodule native/zlib added at 4e4e4c4fbd
139
pom.xml
139
pom.xml
@@ -3,9 +3,9 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Parent</name>
|
<name>BungeeCord-Parent</name>
|
||||||
@@ -37,10 +37,10 @@
|
|||||||
<module>config</module>
|
<module>config</module>
|
||||||
<module>event</module>
|
<module>event</module>
|
||||||
<module>log</module>
|
<module>log</module>
|
||||||
<module>module</module>
|
|
||||||
<module>protocol</module>
|
<module>protocol</module>
|
||||||
<module>proxy</module>
|
<module>proxy</module>
|
||||||
<module>query</module>
|
<module>query</module>
|
||||||
|
<module>slf4j</module>
|
||||||
<module>native</module>
|
<module>native</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
@@ -71,23 +71,34 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<build.number>unknown</build.number>
|
<build.number>unknown</build.number>
|
||||||
<netty.version>4.1.53.Final</netty.version>
|
<lombok.version>1.18.30</lombok.version>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-bom</artifactId>
|
||||||
|
<version>4.1.97.Final</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<version>4.13.1</version>
|
<version>5.10.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>21.0</version>
|
<version>32.1.2-jre</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -99,19 +110,28 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.10</version>
|
<version>${lombok.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>scriptus</artifactId>
|
<artifactId>scriptus</artifactId>
|
||||||
<version>0.4.1</version>
|
<version>0.5.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<format>git:${project.name}:${project.version}:%s:${build.number}</format>
|
<format>git:${project.name}-Pandacube:${project.version}:%s:${build.number}</format>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
@@ -122,10 +142,15 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
<version>3.1.1</version>
|
<version>3.3.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>process-classes</phase>
|
<phase>process-classes</phase>
|
||||||
@@ -143,14 +168,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.puppycrawl.tools</groupId>
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
<artifactId>checkstyle</artifactId>
|
<artifactId>checkstyle</artifactId>
|
||||||
<version>8.36.2</version>
|
<version>8.45.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||||
<version>1.19</version>
|
<version>1.23</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>process-classes</phase>
|
<phase>process-classes</phase>
|
||||||
@@ -167,10 +192,82 @@
|
|||||||
</signature>
|
</signature>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
<version>3.4.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>enforce</id>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<dependencyConvergence>
|
||||||
|
<excludes>
|
||||||
|
<!-- org.apache.maven:maven-resolver-provider is inconsistent -->
|
||||||
|
<exclude>org.apache.commons:commons-lang3</exclude>
|
||||||
|
<!-- org.apache.maven:maven-resolver-transport-http is inconsistent -->
|
||||||
|
<exclude>org.apache.httpcomponents:httpcore</exclude>
|
||||||
|
</excludes>
|
||||||
|
</dependencyConvergence>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<!--<goal>enforce</goal>--> <!-- Disabled until maven-resolver is upgraded again. -->
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>jdk-9-release</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[9,)</jdk>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.release>8</maven.compiler.release>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>jdk-9-javadoc</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[9,)</jdk>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<additionalOptions>-html5</additionalOptions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>jdk-15-javadoc</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[15,)</jdk>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<doclint>none</doclint>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>dist</id>
|
<id>dist</id>
|
||||||
<build>
|
<build>
|
||||||
@@ -178,7 +275,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>3.3.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -191,7 +288,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok-maven-plugin</artifactId>
|
<artifactId>lombok-maven-plugin</artifactId>
|
||||||
<version>1.18.10.0</version>
|
<version>1.18.20.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -205,11 +302,17 @@
|
|||||||
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
|
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
|
||||||
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
|
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<!-- Execute Javadoc once normally to catch any warnings -->
|
<!-- Execute Javadoc once normally to catch any warnings -->
|
||||||
<execution>
|
<execution>
|
||||||
@@ -247,7 +350,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-gpg-plugin</artifactId>
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
<version>1.6</version>
|
<version>3.1.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>verify</phase>
|
<phase>verify</phase>
|
||||||
|
@@ -4,15 +4,14 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-parent</artifactId>
|
<artifactId>bungeecord-parent</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>net.md-5</groupId>
|
|
||||||
<artifactId>bungeecord-protocol</artifactId>
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
<version>1.16-R0.4-SNAPSHOT</version>
|
<version>1.20-R0.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>BungeeCord-Protocol</name>
|
<name>BungeeCord-Protocol</name>
|
||||||
@@ -41,7 +40,7 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>fr.pandacube.bungeecord</groupId>
|
||||||
<artifactId>bungeecord-chat</artifactId>
|
<artifactId>bungeecord-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
@@ -49,7 +48,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-codec</artifactId>
|
<artifactId>netty-codec</artifactId>
|
||||||
<version>${netty.version}</version>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -2,12 +2,16 @@ package net.md_5.bungee.protocol;
|
|||||||
|
|
||||||
import net.md_5.bungee.protocol.packet.BossBar;
|
import net.md_5.bungee.protocol.packet.BossBar;
|
||||||
import net.md_5.bungee.protocol.packet.Chat;
|
import net.md_5.bungee.protocol.packet.Chat;
|
||||||
|
import net.md_5.bungee.protocol.packet.ClearTitles;
|
||||||
|
import net.md_5.bungee.protocol.packet.ClientChat;
|
||||||
|
import net.md_5.bungee.protocol.packet.ClientCommand;
|
||||||
import net.md_5.bungee.protocol.packet.ClientSettings;
|
import net.md_5.bungee.protocol.packet.ClientSettings;
|
||||||
import net.md_5.bungee.protocol.packet.ClientStatus;
|
import net.md_5.bungee.protocol.packet.ClientStatus;
|
||||||
import net.md_5.bungee.protocol.packet.Commands;
|
import net.md_5.bungee.protocol.packet.Commands;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
||||||
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
import net.md_5.bungee.protocol.packet.EncryptionResponse;
|
||||||
import net.md_5.bungee.protocol.packet.EntityStatus;
|
import net.md_5.bungee.protocol.packet.EntityStatus;
|
||||||
|
import net.md_5.bungee.protocol.packet.FinishConfiguration;
|
||||||
import net.md_5.bungee.protocol.packet.GameState;
|
import net.md_5.bungee.protocol.packet.GameState;
|
||||||
import net.md_5.bungee.protocol.packet.Handshake;
|
import net.md_5.bungee.protocol.packet.Handshake;
|
||||||
import net.md_5.bungee.protocol.packet.KeepAlive;
|
import net.md_5.bungee.protocol.packet.KeepAlive;
|
||||||
@@ -15,6 +19,7 @@ import net.md_5.bungee.protocol.packet.Kick;
|
|||||||
import net.md_5.bungee.protocol.packet.LegacyHandshake;
|
import net.md_5.bungee.protocol.packet.LegacyHandshake;
|
||||||
import net.md_5.bungee.protocol.packet.LegacyPing;
|
import net.md_5.bungee.protocol.packet.LegacyPing;
|
||||||
import net.md_5.bungee.protocol.packet.Login;
|
import net.md_5.bungee.protocol.packet.Login;
|
||||||
|
import net.md_5.bungee.protocol.packet.LoginAcknowledged;
|
||||||
import net.md_5.bungee.protocol.packet.LoginPayloadRequest;
|
import net.md_5.bungee.protocol.packet.LoginPayloadRequest;
|
||||||
import net.md_5.bungee.protocol.packet.LoginPayloadResponse;
|
import net.md_5.bungee.protocol.packet.LoginPayloadResponse;
|
||||||
import net.md_5.bungee.protocol.packet.LoginRequest;
|
import net.md_5.bungee.protocol.packet.LoginRequest;
|
||||||
@@ -22,18 +27,25 @@ import net.md_5.bungee.protocol.packet.LoginSuccess;
|
|||||||
import net.md_5.bungee.protocol.packet.PingPacket;
|
import net.md_5.bungee.protocol.packet.PingPacket;
|
||||||
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
||||||
import net.md_5.bungee.protocol.packet.PlayerListItem;
|
import net.md_5.bungee.protocol.packet.PlayerListItem;
|
||||||
|
import net.md_5.bungee.protocol.packet.PlayerListItemRemove;
|
||||||
|
import net.md_5.bungee.protocol.packet.PlayerListItemUpdate;
|
||||||
import net.md_5.bungee.protocol.packet.PluginMessage;
|
import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||||
import net.md_5.bungee.protocol.packet.Respawn;
|
import net.md_5.bungee.protocol.packet.Respawn;
|
||||||
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
|
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
|
||||||
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
|
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
|
||||||
import net.md_5.bungee.protocol.packet.ScoreboardScore;
|
import net.md_5.bungee.protocol.packet.ScoreboardScore;
|
||||||
|
import net.md_5.bungee.protocol.packet.ServerData;
|
||||||
import net.md_5.bungee.protocol.packet.SetCompression;
|
import net.md_5.bungee.protocol.packet.SetCompression;
|
||||||
|
import net.md_5.bungee.protocol.packet.StartConfiguration;
|
||||||
import net.md_5.bungee.protocol.packet.StatusRequest;
|
import net.md_5.bungee.protocol.packet.StatusRequest;
|
||||||
import net.md_5.bungee.protocol.packet.StatusResponse;
|
import net.md_5.bungee.protocol.packet.StatusResponse;
|
||||||
|
import net.md_5.bungee.protocol.packet.Subtitle;
|
||||||
|
import net.md_5.bungee.protocol.packet.SystemChat;
|
||||||
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
|
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
|
||||||
import net.md_5.bungee.protocol.packet.TabCompleteResponse;
|
import net.md_5.bungee.protocol.packet.TabCompleteResponse;
|
||||||
import net.md_5.bungee.protocol.packet.Team;
|
import net.md_5.bungee.protocol.packet.Team;
|
||||||
import net.md_5.bungee.protocol.packet.Title;
|
import net.md_5.bungee.protocol.packet.Title;
|
||||||
|
import net.md_5.bungee.protocol.packet.TitleTimes;
|
||||||
import net.md_5.bungee.protocol.packet.ViewDistance;
|
import net.md_5.bungee.protocol.packet.ViewDistance;
|
||||||
|
|
||||||
public abstract class AbstractPacketHandler
|
public abstract class AbstractPacketHandler
|
||||||
@@ -75,6 +87,18 @@ public abstract class AbstractPacketHandler
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handle(ClientChat chat) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(SystemChat chat) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(ClientCommand command) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public void handle(Respawn respawn) throws Exception
|
public void handle(Respawn respawn) throws Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -95,6 +119,14 @@ public abstract class AbstractPacketHandler
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handle(PlayerListItemRemove playerListItem) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(PlayerListItemUpdate playerListItem) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public void handle(PlayerListHeaderFooter playerListHeaderFooter) throws Exception
|
public void handle(PlayerListHeaderFooter playerListHeaderFooter) throws Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -127,6 +159,18 @@ public abstract class AbstractPacketHandler
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handle(Subtitle title) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(TitleTimes title) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(ClearTitles title) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public void handle(PluginMessage pluginMessage) throws Exception
|
public void handle(PluginMessage pluginMessage) throws Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -178,4 +222,20 @@ public abstract class AbstractPacketHandler
|
|||||||
public void handle(GameState gameState) throws Exception
|
public void handle(GameState gameState) throws Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handle(ServerData serverData) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(LoginAcknowledged loginAcknowledged) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(StartConfiguration startConfiguration) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(FinishConfiguration finishConfiguration) throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user