Compare commits

...

1607 Commits

Author SHA1 Message Date
93cbdab1f6 new event TabCompleteRequestEvent and deprecate TabCompleteEvent 2024-12-11 22:33:44 +01:00
46c233d032 Add CommandsDeclareEvent to declare commands with brigadier API 2024-12-11 22:33:43 +01:00
89053d2254 Server branding now includes the backend server name 2024-12-11 22:33:43 +01:00
5932730744 Multi-session with same Minecraft account with specific permission
Players with permission bungeecord.multiple_connect can have multiple connections with the same Minecraft account.
The UUID and player name is altered to avoid collision with other player:
UUID : xxxxxxxx-xxxx-VIxx-xxxx-xxxxxxxxxxxx
- The UUID version (V above) is now the provided version + 8 (for online player, it is 4, so it becomes C).
- The I digit will follow the index of the duplicated player : first duplicated player is 1, second one is 2.
- The name of the player will be the real player name, followed by the character "." (dot) followed by the duplication index.

Bedrock accounts connected using the Floodgate plugin will not be able to connect multiple times due to the risk of xUID collision.
2024-12-11 22:33:43 +01:00
3d89980065 Change projet configuration and POM for Pandacube 2024-12-11 22:33:43 +01:00
21880c668a Remove modules and startup delay
We don’t need them for Pandacube
2024-12-11 22:33:40 +01:00
Outfluencer
7340f1a035
#3765: Fix forgotten boolean write 2024-12-08 07:50:03 +11:00
md_5
8a80435e64
Minecraft 1.21.4 support 2024-12-04 03:20:00 +11:00
md_5
20a71b06a9
Minecraft 1.21.4-rc3 support 2024-11-30 10:11:33 +11:00
md_5
b376f61578
Minecraft 1.21.4-pre2 support 2024-11-26 20:38:03 +11:00
md_5
373dab05ad
Minecraft 1.21.4-pre1 support 2024-11-23 12:27:38 +11:00
Outfluencer
f6b40b1186
#3758: Handle LoginPayloadResponse in UpstreamBridge 2024-11-19 20:20:17 +11:00
Outfluencer
81b118a8ba
#3759: Remove unnecessary protocol version check for UnsignedClientCommand 2024-11-17 11:44:17 +11:00
BoomEaro
7a42f12716
#3760: Fix possible NPE when trying to get encoder/decoder protocol 2024-11-17 11:43:31 +11:00
md_5
4886c4be01
Minecraft 1.21.2 support 2024-10-23 02:15:00 +11:00
md_5
7338d0f444
Minecraft 1.21.2-rc2 support 2024-10-22 07:32:49 +11:00
Outfluencer
8212e10c7c
#3756, #3757: Queue PlayerListItemRemove packets for disconnecting players 2024-10-21 21:05:01 +11:00
md_5
2593130b3e
Minecraft 1.21.2-rc1 support 2024-10-19 08:56:06 +11:00
md_5
6ea49962c5
Minecraft 1.21.2-pre3 support 2024-10-13 09:53:59 +11:00
Outfluencer
672db9fe47
#3753, #3754: Don't disconnect during login if the player is on a server 2024-10-13 09:38:59 +11:00
Outfluencer
2bacf6572b
#3743: Fix infinite encrypting screen on miss configured ip-forwarding 2024-10-06 19:03:45 +11:00
Valentine
9813e46e66
#3746, #3666: Fix potential race conditions when connecting to multiple servers at the same time 2024-10-06 18:55:12 +11:00
Valentine
01a5f36012
#3751: Fix potential overriding of cipher by other libraries 2024-09-29 19:44:15 +10:00
md_5
f0a30c43cd
Minecraft 24w39a support 2024-09-28 08:51:09 +10:00
Outfluencer
acb85e30fa
#3742: Add more checks to InitialHandler 2024-09-21 09:05:50 +10:00
Outfluencer
9437cedc48
#3748: Minecraft 24w38a support 2024-09-21 09:02:28 +10:00
Outfluencer
a89cf5f36d
#3736: Add simple login payload API 2024-09-09 21:06:48 +10:00
Outfluencer
b309e4ac50
#3737: Use composite buffers where possible 2024-09-09 21:01:19 +10:00
md_5
477ea5983c
Remove unused field 2024-09-08 13:15:40 +10:00
Outfluencer
eca6090f1e
#3739: Support aarch64 natives 2024-09-08 09:15:02 +10:00
md_5
8f8c270f3b
Minecraft 24w36a support 2024-09-07 09:13:23 +10:00
md_5
84ac7ab944
Minecraft 24w35a support 2024-09-02 21:06:47 +10:00
Outfluencer
5fbcc6b119
#3732: Fix protocol state issue 2024-08-26 20:06:34 +10:00
Janmm14
79f85a2ce2
#3662: Add deprecation warning to ComponentSerializer.toString(Object)
It taking all objects is error-prone, deprecate it and create overloads
for used acceptable types.
2024-08-25 09:28:49 +10:00
Outfluencer
d32eedd333
#3727: 24w34a snapshot support 2024-08-25 09:15:03 +10:00
Outfluencer
e1d4b6adc7
#3731: Update cookie handling with vanilla limits and don't allow unrequested cookies 2024-08-25 09:10:00 +10:00
Outfluencer
534148763f
#3721: Improve same uuid and name checks
We didn't return so the login event was fired for a disconnected player
2024-08-22 19:25:45 +10:00
lax1dude
cd56fb32c2
#3722: Disable GZIP in native compress library (no longer requires PCLMUL) 2024-08-09 19:07:38 +10:00
lax1dude
6b612302e1
#3718, #3717: Add check for SSE 4.2 and PCLMUL support to native zlib 2024-08-08 18:19:20 +10:00
lax1dude
e49759025f
#3716, #3707: Fix native-cipher segfault when using musl libc 2024-08-08 18:19:20 +10:00
Outfluencer
c310e3339f
#3720: Replace some println calls with proxy logger 2024-08-07 19:57:09 +10:00
Nick
b64615e298
#3715: Fix maximum length for command packets 2024-07-28 21:07:49 +10:00
Raraph84
45d2f44003
#3713: Add default admin permissions for /find and /send 2024-07-28 21:04:41 +10:00
Raraph84
a57adcce00
#3711, #3712: Don't try to reconnect player when it disconnects manually
* Set server obsolete when disconnected by the proxy
2024-07-28 21:02:31 +10:00
lax1dude
8b195d1d21
#3693: Compile natives as C instead of C++, check malloc/calloc return values for null 2024-06-25 07:01:10 +10:00
Outfluencer
cda4537fba
#3695, #3696: Connect player to fallback if backend disconnects silently 2024-06-23 08:47:05 +10:00
dependabot[bot]
df413f62db
#3677: Bump com.mysql:mysql-connector-j from 8.3.0 to 8.4.0
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.3.0 to 8.4.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.3.0...8.4.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-23 08:22:54 +10:00
md_5
8a88ce464e
Minecraft 1.21 support 2024-06-14 01:05:00 +10:00
Outfluencer
006a14a75c
#3689, #3690: Don't immediately close HAProxy health check 2024-06-13 21:07:08 +10:00
md_5
07df657f3c
Minecraft 1.21-rc1 support 2024-06-11 07:00:30 +10:00
md_5
b8b373a53e
Minecraft 1.21-pre4 support 2024-06-08 10:31:45 +10:00
md_5
e7e0b97cff
Minecraft 1.21-pre2 support 2024-06-02 09:41:02 +10:00
dependabot[bot]
52ab21b1ff
#3682: Bump io.netty:netty-bom from 4.1.109.Final to 4.1.110.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.109.Final to 4.1.110.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.109.Final...netty-4.1.110.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-27 06:59:21 +10:00
md_5
8e8a635361
Minecraft 24w21b support 2024-05-27 06:57:51 +10:00
Janmm14
18eae8a1a6
#3664: Improve chat test code quality 2024-05-05 10:48:01 +10:00
Outfluencer
6e1751733f
#3608, #3676: Close connection if HAProxy 2.0 message is a health check 2024-04-29 06:56:18 +10:00
DerFrZocker
6335af840b
SPIGOT-7638: Library loader does not seem to resolve every dependency 2024-04-27 09:25:29 +10:00
Janmm14
336333acb1
#3665: Small improvements to TranslatableComponent
* Make TranslatableComponent format Pattern static
* Fix TranslatableComponent copy constructor not copying fallback
2024-04-25 07:58:27 +10:00
dependabot[bot]
d110f6629b
#3669: Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.5.3
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.2 to 3.5.3.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.2...maven-shade-plugin-3.5.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-25 07:57:50 +10:00
md_5
6f70b15e2e
Minecraft 1.20.5 support 2024-04-24 01:15:00 +10:00
dependabot[bot]
b30499e2b6
#3667: Bump org.apache.maven.plugins:maven-jar-plugin from 3.4.0 to 3.4.1
Bumps [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/apache/maven-jar-plugin/releases)
- [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.4.0...maven-jar-plugin-3.4.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-jar-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 08:19:33 +10:00
md_5
5079181c28
Minecraft 1.20.5-rc3 support 2024-04-23 06:16:02 +10:00
md_5
ee02d98cb2
Minecraft 1.20.5-rc2 support 2024-04-20 08:53:11 +10:00
Outfluencer
c7ff3b8a14
#3654: Update year in README.md 2024-04-20 08:46:24 +10:00
Outfluencer
de60af0d7b
#3659: Cleanup command packets for 1.20.5 2024-04-20 08:45:46 +10:00
dependabot[bot]
a9218a7aa7
#3660: Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.3 to 3.2.4
Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.2.3 to 3.2.4.
- [Release notes](https://github.com/apache/maven-gpg-plugin/releases)
- [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.3...maven-gpg-plugin-3.2.4)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-gpg-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-20 08:44:38 +10:00
Outfluencer
67c65e0464
#3658: Minecraft 1.20.5-rc1 support 2024-04-19 06:58:16 +10:00
Outfluencer
1be25b6c74
#3656: Improve online mode support where IP forwarding is disabled 2024-04-17 21:05:26 +10:00
md_5
8525b44961
Minecraft 1.20.5-pre3 support 2024-04-17 07:55:07 +10:00
Jared Tiala
1fca510a08
#3655: Fix 1.20.5-pre1 view distance packet ID 2024-04-17 06:38:26 +10:00
dependabot[bot]
3384185285
#3652: Bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.0
Bumps [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-jar-plugin/releases)
- [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.3.0...maven-jar-plugin-3.4.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-jar-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-16 21:33:01 +10:00
dependabot[bot]
3075d2c19d
#3651: Bump io.netty:netty-bom from 4.1.108.Final to 4.1.109.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.108.Final to 4.1.109.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.108.Final...netty-4.1.109.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-16 21:32:48 +10:00
md_5
bc528d5d98
Update native libraries 2024-04-14 09:15:51 +10:00
Outfluencer
25cf8d682b
#3617: Don't go further if connection is disconnected during handshake event
Also replace all isClosed with isClosing as it is more accurate for
disconnect calls in events.
2024-04-13 17:22:31 +10:00
ignPurple
17e23d5c3f
#3628: Convert PostLoginEvent to AsyncEvent and expose target server 2024-04-13 17:10:24 +10:00
dependabot[bot]
d6c5197cb9
#3599: Bump com.mysql:mysql-connector-j from 8.2.0 to 8.3.0
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.2.0 to 8.3.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.2.0...8.3.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-13 15:52:04 +10:00
dependabot[bot]
dd96f0f878
#3647: Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.2 to 3.2.3
Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.2.2 to 3.2.3.
- [Release notes](https://github.com/apache/maven-gpg-plugin/releases)
- [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.2...maven-gpg-plugin-3.2.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-gpg-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-13 15:49:42 +10:00
md_5
8a9501ffe4
Minecraft 1.20.5-pre1 support 2024-04-13 10:50:38 +10:00
Outfluencer
5e25c63c5a
#3646: Add experimental io_uring support 2024-04-09 21:39:06 +10:00
dependabot[bot]
bd963501ec
#3644: Bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1
Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.3.0 to 3.3.1.
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.3.0...maven-source-plugin-3.3.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-source-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-09 21:22:35 +10:00
md_5
da795a7094
Minecraft 24w14a support 2024-04-07 08:18:48 +10:00
md_5
84d0ea73fa
Minor formatting fixes 2024-03-31 10:09:20 +11:00
Outfluencer
0851e39197
#3614: Make glist command output hover and clickable 2024-03-31 10:09:16 +11:00
md_5
86e6fdf8a2
Fix lombok induced JavaDoc error 2024-03-31 10:02:23 +11:00
md_5
6ab0f5eba7
#3621: Warn about use of valid chat colors and add test 2024-03-31 09:53:03 +11:00
Rothes
f224787222
#3621: Only serialize valid chat colors to "color" component 2024-03-31 09:51:04 +11:00
Janmm14
82684c7b6b
#3634: Improve chat test code style.
Stop use of subclass for static method call.
Make test helper methods static.
2024-03-31 09:38:18 +11:00
Janmm14
c2f73d32b8
#3634: Micro-optimize chat deserialization 2024-03-31 09:38:17 +11:00
md_5
e642b9dde1
Minecraft 24w13a support 2024-03-29 15:03:59 +11:00
dependabot[bot]
db623d10c5
#3640: Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.1 to 3.2.2
Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/apache/maven-gpg-plugin/releases)
- [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.1...maven-gpg-plugin-3.2.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-gpg-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-27 08:22:21 +11:00
dependabot[bot]
61bb9f5b93
#3637: Bump org.projectlombok:lombok from 1.18.30 to 1.18.32
Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.30 to 1.18.32.
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.30...v1.18.32)

---
updated-dependencies:
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 15:58:33 +11:00
dependabot[bot]
9551b45328
#3639: Bump io.netty:netty-bom from 4.1.107.Final to 4.1.108.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.107.Final to 4.1.108.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.107.Final...netty-4.1.108.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 15:58:14 +11:00
dependabot[bot]
dc680b87eb
#3636: Bump org.apache.maven.plugins:maven-gpg-plugin from 3.1.0 to 3.2.1
Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.1.0 to 3.2.1.
- [Release notes](https://github.com/apache/maven-gpg-plugin/releases)
- [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.1.0...maven-gpg-plugin-3.2.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-gpg-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 15:57:59 +11:00
dependabot[bot]
156eda78c6
#3635: Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.12.1 to 3.13.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.12.1...maven-compiler-plugin-3.13.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 15:57:46 +11:00
md_5
31be68af51
Minecraft 24w12a support 2024-03-23 15:57:06 +11:00
Outfluencer
ffa011c7b1
#3622: Revert "#3256: Allow - and . in online mode as some accounts still have these…"
This reverts commit f4f94d3b56.
2024-03-11 14:24:02 +11:00
dependabot[bot]
22536c11bd
#3618: Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.1 to 3.5.2
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.1...maven-shade-plugin-3.5.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 14:22:44 +11:00
Janmm14
2394e204fa
#3629: Fix scoreboard team data reading 2024-03-11 14:22:19 +11:00
md_5
1b88a84710
Minecraft 24w10a support 2024-03-07 20:31:26 +11:00
md_5
7606d4437b
Minecraft 24w07a support 2024-02-27 21:36:16 +11:00
dependabot[bot]
3e9a7e45c4
#3616: Bump io.netty:netty-bom from 4.1.106.Final to 4.1.107.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.106.Final to 4.1.107.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.106.Final...netty-4.1.107.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-17 13:41:16 +11:00
dependabot[bot]
f6c5332c1a
#3613: Bump org.junit.jupiter:junit-jupiter from 5.10.1 to 5.10.2
Bumps [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit5) from 5.10.1 to 5.10.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.10.1...r5.10.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-17 13:41:00 +11:00
md_5
d0fa62d424
Minecraft 24w06a support 2024-02-10 12:26:38 +11:00
md_5
464ed0184c
Improve cookie support during login 2024-02-10 12:26:26 +11:00
md_5
eda268b481
Fix 24w05b spectate packet ID 2024-02-06 07:03:49 +11:00
md_5
3e1007527c
#3612: Error when disconnecting player on PostLoginEvent 2024-02-04 11:47:30 +11:00
md_5
b52b14696c
Add PendingConnection#isTransferred API method 2024-02-04 11:35:20 +11:00
md_5
94d5b0d03c
Minecraft 24w05b support 2024-02-03 15:34:08 +11:00
Diogo Correia
c3f228f626
#3610, 3611: inverted isEmpty method on ComponentStyle 2024-02-02 11:16:46 +11:00
Outfluencer
02c5c1ee76
#3602: Minecraft 24w04a support 2024-01-30 07:25:22 +11:00
md_5
c69acf728c
Add JetBrains java-annotations 2024-01-29 20:29:58 +11:00
md_5
a1cd694363
Bump version to 1.20-R0.3-SNAPSHOT 2024-01-20 08:41:57 +11:00
md_5
3e2bc8e2d7
Release 1.20-R0.2 2024-01-20 08:37:37 +11:00
dependabot[bot]
ad7163d2d6
#3600: Bump io.netty:netty-bom from 4.1.104.Final to 4.1.106.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.104.Final to 4.1.106.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.104.Final...netty-4.1.106.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-20 08:34:51 +11:00
Valentine
19918c694f
#3594: Fix missing ComponentStyleSerializer 2024-01-09 16:09:55 +11:00
md_5
21c8f2815a
Decode ComponentStyle over network as appropriate 2024-01-06 16:35:33 +11:00
Parker Hawke
737d545fb6
#3569: Separate component styling into a ComponentStyle class 2024-01-06 16:35:30 +11:00
dependabot[bot]
b23a51825e
#3588: Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.11.0 to 3.12.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.11.0...maven-compiler-plugin-3.12.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-26 08:47:34 +11:00
md_5
708c5b6254
#3585: Fix mistake converting certain NBT to JSON in previous commit 2023-12-22 22:06:23 +11:00
md_5
f5af11193c
#3584: Handle conversion of mixed NBT lists to json 2023-12-22 18:01:30 +11:00
md_5
b711e4033f
#3578: bungeecord-chat does not support array format UUIDs 2023-12-19 19:54:03 +11:00
Outfluencer
3deaaadc3a
#3574: "VarInt too big" should be an OverflowPacketException 2023-12-16 11:29:03 +11:00
dependabot[bot]
51b9a6b0b8
#3577: Bump io.netty:netty-bom from 4.1.101.Final to 4.1.104.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.101.Final to 4.1.104.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.101.Final...netty-4.1.104.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-16 11:28:36 +11:00
dependabot[bot]
1a807731a5
#3567: Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.2...maven-javadoc-plugin-3.6.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-10 11:00:38 +11:00
dependabot[bot]
772ad9951f
#3566: Bump actions/setup-java from 3 to 4
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-10 11:00:24 +11:00
dependabot[bot]
2431c40a5c
#3562: Bump io.netty:netty-bom from 4.1.100.Final to 4.1.101.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.100.Final to 4.1.101.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.100.Final...netty-4.1.101.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-10 11:00:05 +11:00
dependabot[bot]
8144ae8d7b
#3555: Bump com.mysql:mysql-connector-j from 8.1.0 to 8.2.0
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.1.0 to 8.2.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.1.0...8.2.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-10 10:59:52 +11:00
md_5
0757c39a6f
Attempt upgrade of resolver libraries 2023-12-10 10:56:39 +11:00
md_5
231024ba42
Relax chat parsing to treat bytes as booleans to allow formatting read from NBT 2023-12-06 21:55:56 +11:00
md_5
8ce7a7f8b6
Minecraft 1.20.3 support 2023-12-06 03:40:00 +11:00
md_5
e1462ccdd1
Minecraft 1.20.3-rc1 support 2023-12-04 19:02:45 +11:00
md_5
70f346c1dc
Fix extra write in ScoreboardScore packet 2023-11-26 08:12:30 +11:00
md_5
197bf13a28
Minecraft 1.20.3-pre2 support 2023-11-25 17:02:40 +11:00
md_5
0925c06f9b
#3563: Correct max string length for reading SystemChat packets 2023-11-13 20:09:48 +13:00
Parker Hawke
16298a75f2
#3558: Add Translatable interface for fluid creation of TranslatableComponents 2023-11-10 07:03:46 +11:00
md_5
39b10c0b16
Minecraft 23w45a support 2023-11-09 19:33:11 +11:00
dependabot[bot]
bd8d114992
#3561: Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.0 to 3.6.2
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.0 to 3.6.2.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.0...maven-javadoc-plugin-3.6.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-07 20:17:54 +11:00
dependabot[bot]
30e12c6fe0
#3560: Bump org.junit.jupiter:junit-jupiter from 5.10.0 to 5.10.1
Bumps [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit5) from 5.10.0 to 5.10.1.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.10.0...r5.10.1)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-07 20:17:20 +11:00
md_5
bd009ca52d
#3559: Fix serialisation of certain scoreboard packets < 1.13 2023-11-06 20:14:57 +11:00
md_5
65d8edf62d
Minecraft 23w44a support 2023-11-06 20:14:55 +11:00
BoomEaro
f5157f12a4
#3438: Fix possible race condition in duplicate player check 2023-11-01 21:32:31 +11:00
BoomEaro
df20effacc
#3557: Replace Guava Charsets with Java StandardCharsets 2023-10-31 21:49:17 +11:00
md_5
c92581d0dc
#3556: Deserialize arrays to single components 2023-10-29 11:30:54 +11:00
Outfluencer
e442c3da5c
#3546: Add string length checks to isValidName 2023-10-28 13:11:55 +11:00
dependabot[bot]
f903c54d55
#3554: Bump org.apache.maven.plugins:maven-checkstyle-plugin
Bumps [org.apache.maven.plugins:maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.3.0 to 3.3.1.
- [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.3.0...maven-checkstyle-plugin-3.3.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-28 13:06:40 +11:00
Parker Hawke
0d45378986
#3540: Add TextComponent#fromLegacy() as an array-free alternative to #fromLegacyText() 2023-10-28 13:04:18 +11:00
md_5
0f5f09b6c5
Minecraft 23w43b support 2023-10-28 12:57:19 +11:00
md_5
e5c80d0044
Fix code formatting 2023-10-28 12:57:16 +11:00
md_5
9cdb2ba3ea
Deprecate exposed scoreboard API 2023-10-22 09:25:25 +11:00
dependabot[bot]
d0e5cf7ce5
#3549: Bump io.netty:netty-bom from 4.1.99.Final to 4.1.100.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.99.Final to 4.1.100.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.99.Final...netty-4.1.100.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-21 09:16:02 +11:00
md_5
c8568764f6
Fix writing non-compound root NBT tags 2023-10-14 16:38:11 +11:00
Outfluencer
a7dbbc2f0a
#3544: Remove redundant super call in handle(FinishConfiguration) 2023-10-05 07:21:46 +11:00
Outfluencer
68b2df2b1e
#3514: Add separator property to SelectorComponent 2023-10-05 07:21:13 +11:00
dependabot[bot]
1ef4d27dbe
#3543: Bump io.netty:netty-bom from 4.1.97.Final to 4.1.99.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.97.Final to 4.1.99.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.97.Final...netty-4.1.99.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-29 07:50:39 +10:00
Outfluencer
94a1fb5117
#3535: Queue packets of Title api 2023-09-29 07:21:56 +10:00
md_5
78aef86a8f
#3533: Don't put initial client in configure phase until server is ready 2023-09-29 06:50:28 +10:00
md_5
b34cfcde5a
Simplify UpstreamBridge packet handling code 2023-09-28 06:55:00 +10:00
DartCZ
86e079a4b1
#3523, #3534: Fix kicking players with error 2023-09-28 06:55:00 +10:00
Outfluencer
1c42c34081
#3529: Use a synchronized list for /send command 2023-09-28 06:51:10 +10:00
dependabot[bot]
fed646d18b
#3531: Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.0 to 3.5.1
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.0 to 3.5.1.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.0...maven-shade-plugin-3.5.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-26 07:52:07 +10:00
md_5
653f1691d7
Print full stack trace for packet decoder errors 2023-09-26 06:40:02 +10:00
md_5
3cb7a12738
#3527: Switching between servers causes a decoding error 2023-09-26 06:35:48 +10:00
bob7l
f3397b3003
#3525, #3526: Set encode protocol to CONFIGURATION before connecting to a downstream server 2023-09-25 18:57:40 +10:00
md_5
497c6879e0
Add (hopefully temporary) queue for plugin messages to server 2023-09-24 06:50:46 +10:00
md_5
7b27dfaf5e
#3522: Revert "#3518: Bump io.netty:netty-bom from 4.1.97.Final to 4.1.98.Final"
This reverts commit f486a251f3.
2023-09-24 06:25:28 +10:00
md_5
f9b75c4a3a
Update tests to JUnit 5 2023-09-23 18:44:14 +10:00
md_5
0509303fd3
#3519: Queue configuration phase packets from API methods 2023-09-23 10:29:09 +10:00
dependabot[bot]
f486a251f3
#3518: Bump io.netty:netty-bom from 4.1.97.Final to 4.1.98.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.97.Final to 4.1.98.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.97.Final...netty-4.1.98.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-22 08:18:54 +10:00
md_5
5a1e342e0d
Minecraft 1.20.2 support 2023-09-22 02:40:00 +10:00
md_5
d9bbdc3281
Add Java 21 compilation support 2023-09-20 18:06:33 +10:00
Parker Hawke
cfe00fa47c
#3490: Add ComponentBuilder#build() and ComponentSerializer#deserialize()
Components traditionally use the extra data to represent components as a single BaseComponent object. While BaseComponent typically mirrors this behaviour, somewhere along the development of BungeeChat this practice was made unclear. Because ComponentBuilder#create() returns an array of BaseComponents, it has sort of been silently accepted that all components should be represented as arrays, which is incorrect. This heavily influenced the direction of Spigot's component API (with additions such as CommandSender#sendMessage(BaseComponent[])) which emphasizes this misconception of "all components are arrays".

Adding new methods to ComponentBuilder and ComponentSerializer should steer use of the BungeeChat API to be more oriented towards single component instances, not arrays.
2023-09-19 07:14:18 +10:00
md_5
d68ebd1eaf
Minecraft 1.20.2-rc1 support 2023-09-17 08:10:42 +10:00
dependabot[bot]
a7cd79eb41
#3516: Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-16 10:22:07 +10:00
Outfluencer
9e83ee6f0c
#3508: Use same compression threshold checks as Vanilla 2023-09-12 20:29:01 +10:00
dependabot[bot]
7c81d91740
#3513: Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.0 to 3.4.1
Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/apache/maven-enforcer/releases)
- [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.4.0...enforcer-3.4.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-enforcer-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-12 20:28:08 +10:00
md_5
5b126b7f4d
Fix javadoc plugin version in non-dist builds 2023-09-10 11:41:56 +10:00
dependabot[bot]
9fe7d21f4b
#3510: Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-08 19:33:56 +10:00
dependabot[bot]
94ea0271ba
#3505: Bump io.netty:netty-bom from 4.1.96.Final to 4.1.97.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.96.Final to 4.1.97.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.96.Final...netty-4.1.97.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-24 20:07:19 +10:00
dependabot[bot]
3af672d2f2
#3504: Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.3.0 to 3.4.0
Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-enforcer/releases)
- [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.3.0...enforcer-3.4.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-enforcer-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-24 20:07:00 +10:00
md_5
0dd7b98428
Bump version to 1.20-R0.2-SNAPSHOT 2023-08-07 08:01:47 +10:00
md_5
a793692a2c
Release 1.20-R0.1 2023-08-07 07:56:00 +10:00
dependabot[bot]
23fb838227
#3493: Bump io.netty:netty-bom from 4.1.95.Final to 4.1.96.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.95.Final to 4.1.96.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.95.Final...netty-4.1.96.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-02 20:01:19 +10:00
dependabot[bot]
2d6d89d668
#3492: Bump io.netty:netty-bom from 4.1.94.Final to 4.1.95.Final
Bumps [io.netty:netty-bom](https://github.com/netty/netty) from 4.1.94.Final to 4.1.95.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.94.Final...netty-4.1.95.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-24 18:46:54 +10:00
BoomEaro
0199cb90ff
#3489: Add command string length limit when decoding ClientCommand 2023-07-15 10:44:41 +10:00
dependabot[bot]
958cef5084
#3488: Bump scriptus from 0.4.1 to 0.5.0
Bumps [scriptus](https://github.com/SpigotMC/Scriptus) from 0.4.1 to 0.5.0.
- [Commits](https://github.com/SpigotMC/Scriptus/commits)

---
updated-dependencies:
- dependency-name: net.md-5:scriptus
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-15 10:29:22 +10:00
Outfluencer
9f5ace9025
#3418: Add tab completion for bungee command names in pre-1.13 versions 2023-07-05 19:58:23 +10:00
dependabot[bot]
3a6e2631bf
#3479: Bump netty-bom from 4.1.93.Final to 4.1.94.Final
Bumps [netty-bom](https://github.com/netty/netty) from 4.1.93.Final to 4.1.94.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.93.Final...netty-4.1.94.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-03 18:08:33 +10:00
md_5
c7adcf9fdf
Disable maven enforcer for now 2023-06-18 20:55:47 +10:00
md_5
da3616e636
SPIGOT-7400: Downgrade maven-resolver due to issues resolving certain depends 2023-06-18 20:37:33 +10:00
dependabot[bot]
b371fe67a5
#3478: Bump maven-shade-plugin from 3.4.1 to 3.5.0
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.4.1 to 3.5.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.4.1...maven-shade-plugin-3.5.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-17 07:59:06 +10:00
Outfluencer
6324c7d527
#3401: Only synchronize necessary parts of the BungeeServerInfo#sendData method 2023-06-10 18:06:37 +10:00
Outfluencer
6263fe283b
#3426: Made find command output hover and clickable 2023-06-10 18:03:02 +10:00
Ruan
9a7617f9b8
#3475: Add KickPlayerRaw channel 2023-06-10 18:01:01 +10:00
Janmm14
9a71358dfa
#3439: Add GetPlayerServer bungee plugin message subchannel 2023-06-10 18:00:33 +10:00
Outfluencer
a96a2e80a1
#3437: Remove unused enum in ServerConnector and add color to exception message 2023-06-10 17:58:14 +10:00
md_5
68200133b6
Minecraft 1.20 support 2023-06-08 01:30:00 +10:00
dependabot[bot]
188d502c59
#3469: Bump netty-bom from 4.1.92.Final to 4.1.93.Final
Bumps [netty-bom](https://github.com/netty/netty) from 4.1.92.Final to 4.1.93.Final.
- [Commits](https://github.com/netty/netty/compare/netty-4.1.92.Final...netty-4.1.93.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-26 18:45:35 +10:00
dependabot[bot]
84ac683c1d
#3468: Bump lombok from 1.18.26 to 1.18.28
Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.26 to 1.18.28.
- [Release notes](https://github.com/projectlombok/lombok/releases)
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.26...v1.18.28)

---
updated-dependencies:
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-26 18:45:21 +10:00
dependabot[bot]
b418c94215
#3467: Bump maven-source-plugin from 3.2.1 to 3.3.0
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.1 to 3.3.0.
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.1...maven-source-plugin-3.3.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-source-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-24 07:38:43 +10:00
dependabot[bot]
38e593a698
#3466: Bump maven-checkstyle-plugin from 3.2.2 to 3.3.0
Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.2.2 to 3.3.0.
- [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.2.2...maven-checkstyle-plugin-3.3.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-24 07:38:27 +10:00
Janmm14
38028e8e90
#3455: Don't lock connections for offline uuid lookup when given uuid is not offline mode 2023-05-20 11:27:59 +10:00
md_5
3db27052a1
Bump maven-resolver dependencies 2023-05-20 11:13:38 +10:00
dependabot[bot]
e24f9223df
#3464: Bump maven-gpg-plugin from 3.0.1 to 3.1.0
Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.0.1 to 3.1.0.
- [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.0.1...maven-gpg-plugin-3.1.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-gpg-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-20 11:09:14 +10:00
dependabot[bot]
9e5ed82c99
#3461: Bump netty-bom from 4.1.91.Final to 4.1.92.Final
Bumps [netty-bom](https://github.com/netty/netty) from 4.1.91.Final to 4.1.92.Final.
- [Release notes](https://github.com/netty/netty/releases)
- [Commits](https://github.com/netty/netty/compare/netty-4.1.91.Final...netty-4.1.92.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-30 12:43:52 +10:00
dependabot[bot]
606fa278c4
#3460: Bump maven-checkstyle-plugin from 3.2.1 to 3.2.2
Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/apache/maven-checkstyle-plugin/releases)
- [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.2.1...maven-checkstyle-plugin-3.2.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-21 18:02:56 +10:00
md_5
7dd549ff1e
Add maven-enforcer-plugin for dependency convergence 2023-04-20 07:41:22 +10:00
md_5
3c12b04c98
Update dependabot.yml 2023-04-20 07:35:29 +10:00
dependabot[bot]
5545850f9d
#3459: Bump mysql-connector-j from 8.0.32 to 8.0.33
Bumps [mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.0.32 to 8.0.33.
- [Release notes](https://github.com/mysql/mysql-connector-j/releases)
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.0/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.32...8.0.33)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-20 07:26:54 +10:00
dependabot[bot]
2f909b44d7
#3458: Bump maven-resolver-transport-http from 1.9.7 to 1.9.8
Bumps [maven-resolver-transport-http](https://github.com/apache/maven-resolver) from 1.9.7 to 1.9.8.
- [Release notes](https://github.com/apache/maven-resolver/releases)
- [Commits](https://github.com/apache/maven-resolver/compare/maven-resolver-1.9.7...maven-resolver-1.9.8)

---
updated-dependencies:
- dependency-name: org.apache.maven.resolver:maven-resolver-transport-http
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-20 07:26:41 +10:00
dependabot[bot]
ff155ebbb4
#3457: Bump maven-resolver-connector-basic from 1.9.7 to 1.9.8
Bumps [maven-resolver-connector-basic](https://github.com/apache/maven-resolver) from 1.9.7 to 1.9.8.
- [Release notes](https://github.com/apache/maven-resolver/releases)
- [Commits](https://github.com/apache/maven-resolver/compare/maven-resolver-1.9.7...maven-resolver-1.9.8)

---
updated-dependencies:
- dependency-name: org.apache.maven.resolver:maven-resolver-connector-basic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-20 07:26:26 +10:00
md_5
a0a4fa0e56
Add profile for Java 20 compilation of bootstrap 2023-04-07 09:55:01 +10:00
dependabot[bot]
1b76a26691
#3456: Bump netty-bom from 4.1.90.Final to 4.1.91.Final
Bumps [netty-bom](https://github.com/netty/netty) from 4.1.90.Final to 4.1.91.Final.
- [Release notes](https://github.com/netty/netty/releases)
- [Commits](https://github.com/netty/netty/compare/netty-4.1.90.Final...netty-4.1.91.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 09:01:03 +10:00
md_5
bd7bd2739a
Update Github actions to ubuntu-22.04 2023-04-04 07:20:07 +10:00
md_5
a7ad407f4b
Update dependencies 2023-04-02 14:08:27 +10:00
dependabot[bot]
931ff0fde6
#3452: Bump animal-sniffer-maven-plugin from 1.22 to 1.23
Bumps [animal-sniffer-maven-plugin](https://github.com/mojohaus/animal-sniffer) from 1.22 to 1.23.
- [Release notes](https://github.com/mojohaus/animal-sniffer/releases)
- [Commits](https://github.com/mojohaus/animal-sniffer/compare/animal-sniffer-parent-1.22...1.23)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:animal-sniffer-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-02 12:59:50 +10:00
md_5
dfd847f705
Update native libraries 2023-03-25 11:14:25 +11:00
md_5
a1fee720b9
Deprecate string join 2023-03-25 11:00:30 +11:00
md_5
963854f8d5
Remove use of internal gson API 2023-03-25 11:00:30 +11:00
Janmm14
2ef5e7004b
#3451: Improve length field prepending on bungee -> server connection
Use alternative implementation of Varint21LengthFieldPrepender on bungee -> server connection for improved speed - it uses separate buffer to prepend the length to avoid copying large data buffer.
Not applied bungee -> client because encrypting 1-5 bytes of length separately through expensive jni call could make it not worth (not measured).
2023-03-25 11:00:30 +11:00
Janmm14
2e6f0dd442
#3450: Use readRetainedSlice method instead of slice+retain+skip 2023-03-23 20:57:53 +11:00
Outfluencer
7790783949
#3436, #3441: Check if server icon image is null 2023-03-15 18:44:36 +11:00
md_5
f4534c8273
#3446: Fix < 1.19 support 2023-03-15 18:41:25 +11:00
md_5
76673f02a4
Apply dependabot configuration 2023-03-15 18:18:15 +11:00
md_5
b47ae0944c
#3444: Use same duplicate player handling for online and offline modes 2023-03-15 07:41:50 +11:00
md_5
f9712cbc7c
Minecraft 1.19.4 support 2023-03-15 03:30:00 +11:00
md_5
1b6d845530
Update lombok and maven shade 2023-02-11 10:26:59 +11:00
Outfluencer
19424aba9d
#3430: Add new fallback field to TranslatableComponent 2023-01-28 11:32:59 +11:00
Outfluencer
71ac9b34fa
#3425: Make ip command output clickable to copy ip 2023-01-28 11:19:45 +11:00
Achsion
7651d4a249
#3423: Remove empty servers from glist by default 2023-01-28 11:15:40 +11:00
md_5
f8e0bccdf0
Update README date 2023-01-01 11:17:02 +11:00
Outfluencer
a5b6eb6afa
#3417: Support uppercase &h in Alert command 2022-12-23 10:54:57 +11:00
MrKeith
41471da9db
#3405: Fix typo in ProxiedPlayer docs and add docs to ServerDisconnectEvent 2022-12-21 18:41:55 +11:00
md_5
e71767688d
#3408: ConcurrentModificationException when player quits 2022-12-08 07:09:20 +11:00
md_5
5467e3a842
Minecraft 1.19.3 support 2022-12-08 03:00:00 +11:00
Ismael Hanbel
511017ab35
#3396: Update Netty version 2022-11-12 11:52:30 +11:00
floge07
c3e8cfac79
#3374, #3389: Improve log handling of normal java.util Logger usage by forwarding the LogRecords directly to the BungeeLogger instead of the fallback err stream. 2022-11-12 11:51:14 +11:00
rgnter
bf2b3c68f8
#3384: Update documentation of ProxyPingEvent 2022-11-12 11:43:29 +11:00
Outfluencer
68e74a8c03
#3378: Remove KickStringWriter from the pipeline after handshake arrives 2022-11-12 11:41:10 +11:00
Outfluencer
5b4a540440
#3361: Cache MessageFormats for translations 2022-11-12 11:39:31 +11:00
osfanbuff63
88da5c05c7
#3353: Update GitHub actions
Updates `actions/checkout` and `actions/setup-java` to v3.
2022-11-12 11:34:17 +11:00
md_5
2d369e8945
Update SnakeYAML version 2022-10-02 09:18:42 +11:00
md_5
02548c4b9b
Update Netty/SnakeYAML version 2022-09-22 10:16:27 +10:00
Outfluencer
71990e3ccc
#3387: Use the correct write method for ChatChain in ClientCommand 2022-08-27 07:40:18 +10:00
Outfluencer
5e7dcc48b9
#3382: Use the correct write method for ChatChain in ClientChat packet 2022-08-20 16:22:14 +10:00
Outfluencer
5cdba87b87
#3377: Add additional checks for protocol length limits 2022-08-16 19:26:33 +10:00
Outfluencer
696315615d
#3366: Improve consistency and appearance of default translations 2022-08-14 11:34:00 +10:00
Outfluencer
dd3f820040
#3363, #3369: Implement new ServerData packet to stop MOTD data from servers 2022-08-14 11:32:35 +10:00
md_5
78ca16dfe3
Minecraft 1.19.1 support 2022-07-28 04:00:00 +10:00
Noah
adc32d5a5c
#3367: Add linux aarch64 native epoll support 2022-07-23 18:53:52 +10:00
Outfluencer
12e4514813
#3355,#3357: Fix possible NPE's in LoginEvent & PreLoginEvent 2022-07-12 21:47:57 +10:00
Ivan Pekov
587fb37bdf
#3192, #3210: Handle null ServerPing#getPlayers upon a legacy ping 2022-07-02 10:35:54 +10:00
Kevin Ludwig
d221e52929
#3241: Support ping passthrough for legacy pings 2022-07-02 10:27:36 +10:00
FlorianMichael
e151a6cf92
#3156: Add kick module 2022-07-02 10:11:09 +10:00
Outfluencer
9ced5ce131
#3287: Fix HttpHandler calls done method twice 2022-07-02 10:02:16 +10:00
tsuoihito
c8e876bfe2
#3342: Fix sanitized address being not IP but hostname after InetSocketAddress#getHostName() 2022-06-30 21:28:37 +10:00
Janmm14
2a716bbc7f
#3344: Fix legacy chat conversion losing format reset information.
In legacy chat format, colors and reset do not retain any formatting.

In order to prevent this behaviour from creating unnecessary long json containing many redundant `formatting: false`, the original `fromLegacyText(...)` idea was to just override the color to white and handle the format reset just internally.

However eventual previous format rejection (aka reset) information was lost when appending multiple legacy format strings to a `ComponentBuilder`.

With this change we save the "reset wish" in the `BaseComponent` and update `ComponentBuilder`'s append function to not copy over formatting if the component has the reset flag set.
2022-06-30 21:22:16 +10:00
Janmm14
00590b6c0d
#3343: Create GitHub issue templates 2022-06-30 21:18:12 +10:00
md_5
2ff4be7846
Update gson to 2.8.9 2022-06-28 21:40:53 +10:00
md_5
ff5727c5ef
Revert broken chat PR and align with Spigot 2022-06-08 19:37:15 +10:00
Brokkonaut
e46bc343e4
#3319: Do not forward cancelled messages or handled commands 2022-06-08 17:44:08 +10:00
Lukas Alt
5972fd2353
#3318: Fixed system messages shown in action bar for MC 1.19 clients 2022-06-08 11:23:41 +10:00
bob7l
8c0e4b1d33
#3315: Further fix for offline mode support 2022-06-08 10:05:06 +10:00
md_5
a737a754d1
Downgrade dependency version 2022-06-08 09:01:05 +10:00
md_5
fc8685a042
#3311: Fix chat handling on older versions 2022-06-08 08:30:37 +10:00
md_5
cc4765b4fe
#3313: Fix offline mode support 2022-06-08 08:22:46 +10:00
md_5
eccdf87f22
Minecraft 1.19 support 2022-06-08 02:00:00 +10:00
md_5
862bb2ac72
#3258: Only show detailed connect exception to admins 2022-04-09 08:59:01 +10:00
Outfluencer
34d416a4e8
#3261: Remove unused AttributeKeys
These attribute keys are not used so we can remove them
2022-03-19 10:05:23 +11:00
Outfluencer
410f64bc9f
#3268: Correct plugin message size check 2022-03-19 10:04:45 +11:00
Outfluencer
978e68fc74
#3265: Print all thrown exception
DecoderExceptions that are not a CorruptedFrameException and dont have BadPacketException or OverflowPacketException as cause are not printed.
I also removed the ID message in BadPacketException because bad packet does not mean it has a invalid id the protocol version can also be not valid or the packet was not read to the end and more details are in the message of the exception
2022-03-19 10:04:40 +11:00
Outfluencer
a17d8f8a66
#3264: Negative packet ids are also outside of range 2022-03-09 11:21:07 +11:00
md_5
7e47490e70
Minecraft 1.18.2 support 2022-03-01 02:00:00 +11:00
nnnnt21
f4f94d3b56
#3256: Allow - and . in online mode as some accounts still have these usernames 2022-02-24 08:06:10 +11:00
md_5
eae9d45c8a
Provide more information in connect errors 2022-02-06 08:44:55 +11:00
md_5
d2d157c1fe
#3246: Fix commands not working due to MinecraftForge changes 2022-02-06 08:26:09 +11:00
Outfluencer
9c95d4ba43
#3226: Add console command name tab completion 2022-01-02 10:13:48 +11:00
md_5
6cbd7404f4
Fix checkstyle paren pad settings 2022-01-02 10:13:48 +11:00
md_5
ad8a8ef5a9
Increase per-listener event bus warning time 2022-01-01 09:22:26 +11:00
md_5
e6766a1ee2
Update README date 2022-01-01 08:50:50 +11:00
Janmm14
b4ccdaa51c
#2715: Improve BadPacketException message in MinecraftDecoder 2021-12-19 09:54:37 +11:00
Janmm14
3a11656909
#3116: Do not fill in LogRecord caller data by default in slf4j wrapper 2021-12-19 09:53:13 +11:00
Janmm14
2479fab632
#3221: Use computeIfAbsent method in EventBus 2021-12-19 09:50:48 +11:00
md_5
51eb1ac623
Dependency upgrades 2021-12-18 12:18:21 +11:00
md_5
879f37f046
Upgrade to SnakeYAML 1.30 release 2021-12-18 11:36:05 +11:00
md_5
f2aadd6014
#3223: Only rewrite spectate packet if no IP forwarding 2021-12-13 08:25:54 +11:00
md_5
1ad81504ca
Update native cipher 2021-12-10 15:54:39 +11:00
Janmm14
425ee4e142
#3215: Add time measurement per event listener method 2021-12-05 08:51:33 +11:00
Valtn
42d8300bb7
#3220: Fix server list info being cached permanently 2021-12-05 08:04:26 +11:00
md_5
a9d75c5255
Minecraft 1.18 support 2021-12-01 03:00:00 +11:00
md_5
98afd548d1
Minecraft 1.18-rc3 support 2021-11-27 08:00:00 +11:00
md_5
7fc256dba7
Minecraft 1.18-pre8 support 2021-11-25 08:00:00 +11:00
md_5
21b23624ad
#3159: Account for the (broken) configuration when ip forward is enabled on bungee but not the server 2021-11-23 15:27:31 +11:00
md_5
1ace5c0c8b
Trial snapshot SnakeYAML version 2021-11-23 08:30:38 +11:00
md_5
bee99beab1
Downgrade to Checkstyle 8.x as 9.x series has much larger memory usage 2021-11-22 15:27:24 +11:00
md_5
8b363d3d1f
Minecraft 1.18-pre5 support 2021-11-22 09:00:00 +11:00
PSNRigner
c7b0c3cd48
#3207: Rework the plugin message relaying system to allow unregistering channels 2021-11-12 19:38:47 +11:00
md_5
c0c9b28582
Update snapshot support to 1.18-pre1 2021-11-12 19:37:57 +11:00
Frank van der Heijden
c3fffbc919
#3205: Don't forward tab completions if the root command is a bungee command 2021-11-04 18:45:11 +11:00
md_5
6613aaea95
Add test fix for library classes being visible to non-dependent plugins 2021-10-09 18:02:58 +11:00
riku6460
53ce6b93a2
#3200: Fix protocol for 21w40a 2021-10-09 18:00:36 +11:00
Janmm14
d8e293842f
#2466: Use switch in "BungeeCord" plugin message handling 2021-10-09 09:25:29 +11:00
MrMicky
5cf869df1a
#3198: Remove terminally deprecated SecurityManager
See https://openjdk.java.net/jeps/411
2021-10-09 09:25:29 +11:00
md_5
f26f7d8809
Add optional 1.18 (21w40a) snapshot protocol support
Accessible via the net.md_5.bungee.protocol.snapshot JVM property.
2021-10-09 09:25:28 +11:00
Outfluencer
c5a90475af
#3195: Remove unused translations
Both translations are not used in BungeeCord or any modules.
2021-09-25 08:10:28 +10:00
Outfluencer
3008d7ef2f
#3189: Improve username validation 2021-09-25 08:09:47 +10:00
Outfluencer
1823f86dbb
#3190: Improve login protocol state machine
Prevents repetition of packets
2021-09-17 18:16:01 +10:00
Janmm14
06bf088d27
#3186: Replace String.format calls in exceptions with simple string concats 2021-09-17 18:14:21 +10:00
md_5
9953698a7c
Add GitHub Java 17 build 2021-09-16 07:43:13 +10:00
md_5
bda1605627
Minor formatting fixes 2021-07-22 11:46:41 +10:00
Outfluencer
2e0e88db0d
#3158: Remove redundant protocol version check in the TabCompleteResponse packet
No need for the second if in the read and write method use a else instead
2021-07-22 11:43:03 +10:00
Outfluencer
96482cc0cf
#3157: Read only 20 chars for clients below 1.13 in PluginMessages
20 chars is the vanilla limit for all clients below 1.13. We should use this value.
2021-07-22 11:42:48 +10:00
Outfluencer
a283aaf724
#3153: Add color support to the end command 2021-07-18 10:22:17 +10:00
Adrian Antkowiak
5db276eb52
#3147: HAProxyMessage.sourceAddress() can be null
.sourceAddress() is null when send-proxy-v2 & check option is used
2021-07-11 09:06:51 +10:00
md_5
c866619f56
Minecraft 1.17.1 support 2021-07-07 00:00:00 +10:00
Outfluencer
b9da505efe
#3142: Remove redundant name length check in InitialHandler
This check is not needed anymore as the player gets kicked while reading the LoginRequest packet if the name length is longer than 16
2021-07-04 09:40:47 +10:00
md_5
061a7c67bd
Update checkstyle 2021-07-03 11:17:12 +10:00
Ivan Pekov
6f7331e852
#3138, 3140: Check for the new leak detector netty flag 2021-06-30 19:00:22 +10:00
md_5
1b489bcc11
Attempt to fix java 8 native crash 2021-06-26 11:39:53 +10:00
md_5
da27924a49
#3115, #3125: Update natives build script, switch to Cloudflare zlib 2021-06-26 11:31:05 +10:00
Outfluencer
15b39887c5
#3133: Directly disconnect on illegal chars 2021-06-26 10:09:17 +10:00
Janmm14
f9583a7652
#3129: Replace ConnectTimeoutException with a more user-friendly string. 2021-06-26 10:06:12 +10:00
Janmm14
cb738188de
#3126: Use suppliers instead of reflection for native impl generation. 2021-06-26 10:01:30 +10:00
Outfluencer
a8b2f5268d
#3123: Apply exact vanilla string length limits for tab completion 2021-06-20 08:51:55 +10:00
Outfluencer
ad50fc9ad3
#3111: Check chat for illegal chars & moved length check into the packet class 2021-06-15 09:07:20 +10:00
md_5
a25c2b325b
Fix typo in previous commit 2021-06-13 11:26:18 +10:00
md_5
c57bf61114
#3113: Remove unnecessary slice in PacketDecompressor
Thanks @lokha for the profiling and suggestion.
2021-06-13 08:32:25 +10:00
md_5
b7935d4b14
Downgrade SnakeYAML due to issues with comments parsing 2021-06-11 21:13:42 +10:00
Janmm14
00982f3620
#3104: Use lambdas rather than reflection to create packets 2021-06-11 16:55:02 +10:00
Lukas Alt
088b2045d0
#3109: Made file log level configurable 2021-06-10 08:42:48 +10:00
Antoine L
633ff1cfc8
#3107: Fix action bar messages in 1.17 2021-06-09 18:58:20 +10:00
md_5
6cda6b6c10
Update SnakeYAML and Netty 2021-06-09 18:56:38 +10:00
md_5
90573625f1
Minecraft 1.17 support 2021-06-09 09:00:00 +10:00
Janmm14
d49e97c423
#3099: Improve toArray calls by using an empty array as parameter.
From Intellij IDEA inspections: Since late updates of OpenJDK 6 this call was intrinsified, making the performance of the empty array version the same and sometimes even better, compared to the pre-sized version.
2021-05-28 08:23:43 +10:00
md_5
39a80e414e
#3093: Support names with '.', block names with ' ' 2021-05-26 10:31:37 +10:00
md_5
ab9153ddc3
Further increase length limit for TO_CLIENT chat packets 2021-05-26 10:31:26 +10:00
md_5
7ec1f487c1
Remove ipv6 scope from forwarded addresses
Affects forwarding when epoll enabled
2021-05-25 18:42:10 +10:00
md_5
c96628b72e
#3094: Fix TO_CLIENT max Chat string length 2021-05-21 17:45:55 +10:00
md_5
e5ded9a2fb
Apply stricter length limits to client strings
Also bump snapshot version and remove redundant file header
2021-05-21 08:16:55 +10:00
md_5
5823f47467
#3090: Register events in parent classes 2021-05-19 18:41:09 +10:00
Janmm14
a0b7f09252
#3087: Force-enable multi-release jar file support for JDK9+ via System property 2021-05-18 20:34:53 +10:00
md_5
b60a30c705
Move additional dependencies to runtime scope 2021-05-16 18:09:04 +10:00
md_5
4fc1a9e770
Dependency bump 2021-05-15 17:22:35 +10:00
md_5
f0908b663f
Add optional 1.17 (21w19a) snapshot protocol support
Accessible via the net.md_5.bungee.protocol.snapshot JVM property.
2021-05-15 09:31:07 +10:00
md_5
5fa596fee9
#3084: (Regrettably) add a full SLF4J wrapper 2021-05-14 08:51:09 +10:00
md_5
ada1b95ffc
Remove redundant entity rewriting code on > 1.16.2 2021-05-12 07:59:50 +10:00
Luck
72b3bdf676
#3077: Fix regression preventing child classloaders delegating to a PluginClassloader
Bug was introduced in 425dd45109
2021-05-01 08:32:51 +10:00
Janmm14
71d1246374
#3066: Put ReadTimeoutHandler after frame decoder.
This reduces the impact of attacks that send a large packet size first and then send data very slowly but frequently enough to not trigger a timeout (as the timeout handler was before the Varint21FrameDecoder). This causes connections to stay open for a long time without much effort from an attacker, while the packet never leaves the Varint21FrameDecpder stage of the netty pipeline (causing no additional checks to happen and no logs of the connection to be created).

This will not have an impact on bad connections as without recieving full packets the underlying spigot server would timeout instead.
2021-04-28 16:52:00 +10:00
_tomcraft
ac371bb596
#3073: Release HAProxyMessage after read 2021-04-28 08:07:17 +10:00
md_5
830ee8f27d
#3061: Continue to fallback to underlying URLClassLoader 2021-04-10 07:30:17 +10:00
md_5
425dd45109
Override classloader close method for completeness 2021-04-09 15:38:21 +10:00
md_5
6a039de8db
Add preview of automatic library support
Example plugin.yml usage:
```
    libraries:
      - com.squareup.okhttp3:okhttp:4.9.0
```

Libraries will only be accessible to plugins and their transitive depends, allowing for multiple versions of the same library to be used by different plugins.

This is a preview feature. Feedback is welcome so that it may be refined before being made widely available.
2021-04-09 13:13:55 +10:00
md_5
8d783aa172
#3058: Remove world limit 2021-04-06 08:18:58 +10:00
md_5
a4e5f5005b
Add full support for building on JDK [15,) 2021-04-04 17:24:23 +10:00
Zach Levis
a7c6edeb63
#3041: Respond to login query requests in a way that matches the Vanilla client 2021-02-26 11:28:05 +11:00
Janmm14
4f23b49fef
#3037: Update ProxiedPlayer#setDisplayName javadoc to current behaviour 2021-02-14 09:37:07 +11:00
md_5
cfcc8b1a6f
Pin GitHub workflow build to ubuntu-20.04 2021-02-14 09:35:07 +11:00
md_5
ebec582ce2
Add full support for building on JDK [8, 14] 2021-02-14 09:29:55 +11:00
md_5
3d701fbe0e
#3028: Add protocol level string length limits 2021-01-25 15:54:27 +11:00
md_5
e95da11115
Bump Netty/SnakeYAML/MySQL versions 2021-01-24 08:56:07 +11:00
md_5
9f6a798ea6
Bump version to 1.16-R0.5-SNAPSHOT 2021-01-15 10:19:24 +11:00
md_5
36c8df4d2f
Release 1.16-R0.4 2021-01-15 09:49:36 +11:00
blablubbabc
baf2f60850
#3018: Serialize text component properties in the same order as Minecraft 2021-01-13 10:17:16 +11:00
md_5
9ac39005f8
Update README date 2021-01-12 09:06:25 +11:00
BlackHole
9c078b78c3
#2985: Add Keybinds.SOCIAL_INTERACTIONS 2020-11-04 19:43:11 +11:00
md_5
281aecef4c
Minecraft 1.16.4 support 2020-11-03 07:00:00 +11:00
mciolkosz
4199b0ca64
#2977: Added availability to set custom permission messages on commands. 2020-10-17 18:12:01 +11:00
md_5
6973e099fd
Misc dependency updates 2020-10-17 18:04:25 +11:00
Gerrygames
8fffa206e4
#2978: Allow sending messages from specific UUIDs 2020-10-17 17:46:01 +11:00
c987ee199d
#2955: Single quotes in messages.properties should be doubled. 2020-09-16 19:53:05 +10:00
md_5
15204131c9
#2942: Players invisible in 1.16 where bungee is online mode but IP forwarding not enabled 2020-09-14 19:56:41 +10:00
md_5
23661737ef
Minecraft 1.16.3 support 2020-09-11 07:00:00 +10:00
Sneakometer
5ab5a846aa
#2953: Fix player limit off by one
Make so the player limit is actually the limit and not limit+1
2020-09-08 12:24:04 +10:00
Mystiflow
e93c762f16
#2921: ClickEvent without value exceptions in window title 2020-08-22 17:50:54 +10:00
Jan Boerman
023f407b0d
#2928: Add IPOther special plugin message 2020-08-22 17:49:16 +10:00
WinX64
64e4f4658a
#2931: Fix exceptions on ChatColor.of(Color) due to truncation 2020-08-22 17:47:01 +10:00
md_5
aa22fe68e5
Minecraft 1.16.2 support 2020-08-12 07:14:42 +10:00
Andrew Steinborn
15b514130e
#2908: Don't frame packets for dead connections 2020-07-19 08:54:54 +10:00
md_5
a0f9333a13
Bump version to 1.16-R0.4-SNAPSHOT 2020-07-18 17:36:11 +10:00
md_5
287e28a722
Release 1.16-R0.3 2020-07-18 17:31:21 +10:00
Mystiflow
c1522ab94c
#2909: Don't serialise as array for single element contents 2020-07-16 18:53:23 +10:00
Mystiflow
0af4bfdbdf
#2905: HoverEvent getValue compat method 2020-07-15 09:05:05 +10:00
md_5
94c4fcbad7
Bump version to 1.16-R0.3-SNAPSHOT 2020-07-13 08:45:48 +10:00
md_5
a99f62f693
Release 1.16-R0.2 2020-07-13 08:23:55 +10:00
Mystiflow
fd4864d475
#2899: Various chat API stability updates
- Check if a value CAN be parsed as a BaseComponent[] before attempting to parse it through the Content deserialiser
- When removing enclosing quotes from deserialised NBT, don't remove all quotes as they may have been escaping
- Check for ALL the number suffix types
- Throw JSONParseException if: no selector in selector component, no translate in translate component
- JsonObject is not JsonPrimitive
- Cleaned up unit tests a bit
2020-07-09 19:14:01 +10:00
cvrunmin
c5610a6a13
#2897: Add params of recursive call of ChatComponent transform
This modification allows deeper levels of HoverEvent (i.e. inside extra) to be transformed into legacy version
2020-07-09 08:48:11 +10:00
Mystiflow
bcc3460dda
#2893: Refactored Hover Code for Maintainability 2020-07-07 09:09:32 +10:00
Erik Eide
4794fccfb8
#2888: Correct font check in BaseComponent 2020-07-06 08:10:42 +10:00
Mystiflow
637e7e93e0
#2884: Mojangson in hover events cannot be parsed 2020-07-05 19:09:59 +10:00
Mystiflow
2e4b08e5ab
#2878: Null check hover event before transform 2020-07-02 07:29:10 +10:00
Mariell Hoversholm
a64c34d29e
#2875: Add the MessageRaw channel 2020-07-01 10:59:32 +10:00
Mystiflow
1d40b8a88a
#2866: Add support for contents in Hover Event 2020-07-01 10:57:09 +10:00
md_5
26f538d193
Clear tab list on server change 2020-06-27 09:05:55 +10:00
md_5
afcfac31a9
#2873: BossBar stays after switching servers 2020-06-27 08:44:53 +10:00
md_5
6cff5a955c
#2864: Add release maven profile 2020-06-26 19:14:44 +10:00
Max Lee
e21b0b3773
#2870: Add rgb values to all colors 2020-06-26 18:42:49 +10:00
D3ATHBRINGER13
d65ee874e4
#2865: Bump actions/checkout version 2020-06-26 09:55:05 +10:00
Max Lee
c803f42a84
#2867: Add font setter to ComponentBuilder 2020-06-26 09:52:31 +10:00
md_5
3409fe6dd3
Clear scoreboards and bossbars on new style server switch 2020-06-25 15:25:15 +10:00
md_5
4786c0986b
Bump version to 1.16-R0.2-SNAPSHOT 2020-06-25 08:36:25 +10:00
md_5
a7180850e0
Release 1.16-R0.1 2020-06-25 08:36:03 +10:00
FivePB (Xer)
e1084bd913
#2861: Improve dimension changing support in 1.16.x 2020-06-25 08:08:54 +10:00
Polo1K
c5f839c9ad
#2862: Minecraft 1.16.1 support 2020-06-25 08:08:51 +10:00
md_5
87cb3b90ea
Improve license info in pom.xml 2020-06-24 18:35:29 +10:00
md_5
198004da86
Add release maven repository 2020-06-24 18:09:35 +10:00
md_5
b41e9be4c9
Constrain dimension to String|Integer
Fixes 1.8 server switch issues
2020-06-24 12:56:31 +10:00
md_5
739b496bf6
#2858: ChatColor#ordinal is missing 2020-06-24 08:34:05 +10:00
md_5
75af27acf1
Fix missing static on ChatColor.values 2020-06-24 07:19:46 +10:00
md_5
d0fd673b60
Minecraft 1.16 support + RGB ChatColor preview 2020-06-24 07:00:00 +10:00
MrIvanPlays
2f54c94372 #2786: Should first peek keepalive queue 2020-05-26 19:46:17 +10:00
md_5
67c2dfd884 #2794: connection throttle race condition 2020-05-10 09:44:44 +10:00
md_5
eeb3c6d3bf #2811: Shorten "Cannot request protocol" exception 2020-05-10 09:35:19 +10:00
md_5
727281e69e Make all BaseComponent.duplicate methods specific 2020-05-10 09:24:40 +10:00
Alex_qp
4e99a32537 #2808: TextComponent.duplicate should return TextComponent 2020-05-10 09:24:40 +10:00
md_5
3373eb864d #2834: Add support for long array NBT tag 2020-05-09 15:41:38 +10:00
Janmm14
b85df4f2a1 #2830: CommandSend - replace iterator-while with for-each 2020-05-02 18:16:49 +10:00
_tomcraft
855d152503
#2829: Fix action bar messages on pre 1.11 versions 2020-04-30 08:11:00 +10:00
Janmm14
a1969b2fe6
#2823: Update Netty to 4.1.49.Final 2020-04-23 08:05:09 +10:00
md_5
b91d4d3003 #2820: Sending a player via /send prints incorrect message 2020-04-22 11:49:33 +10:00
md_5
aa66633df8 #2821: Add support for brigadier:long argument type 2020-04-22 11:44:26 +10:00
Mystiflow
f1c32f84f4 #2379: Add ServerSwitchEvent getFrom API 2020-03-25 18:20:37 +11:00
md_5
cb3f87bb27 Update Netty to 4.1.48.Final 2020-03-25 15:54:36 +11:00
Byron Marohn
697f0875e6 #2770: Handle posix signals SIGTERM, SIGINT, SIGHUP gracefully
- Move working contents of Bungeecord.stop() to a separate function
named independentThreadStop() intended to be called from a separate thread.
- Added a new generic shutdown hook to call independentThreadStop when
the JVM begins shutting down.
2020-03-08 19:32:25 +11:00
md_5
6ad26cc8fa #2777: Write BungeeCord's config.yml in UTF-8 as with main config API 2020-02-24 10:28:40 +11:00
md_5
c2cc33c6d7 #2774: doImmediateRespawn not updated when switching servers 2020-02-21 09:40:13 +11:00
md_5
8ea25a8fc7 #2775: Fix LinkageError loading plugin dependency classes 2020-02-21 08:22:16 +11:00
MrIvanPlays
4363315ec5 #2722, #2713: Remove unnecessary close delaying in server / user connections 2020-02-20 12:24:01 +11:00
MrIvanPlays
c46b14b92c #2688: Protect the plugin manager from 3rd party modifications 2020-02-20 12:24:01 +11:00
md_5
f41b1fc821 Do not allow plugins to make multiple instances of their main class.
Prevents foot shooting, eg #2772
2020-02-20 12:24:01 +11:00
md_5
e6b0d43d66 Allow configuring console log level via system property 2020-02-14 13:58:52 +11:00
md_5
a52ea50006 #2769: Guardian target beam lost on server change 2020-02-10 10:28:47 +11:00
md_5
17d5dd3f94 Add dist Maven profile to generate source and Javadoc jars 2020-02-04 14:59:52 +11:00
md_5
9e8ab747e4 Add JsonConfiguration support to bungeecord-config
Thanks @FelixKlauke for the idea in #2364, however this implementation was designed to mirror as much of the existing YamlConfiguration as possible and have Gson as an optional depend.
2020-02-03 13:25:47 +11:00
Mystiflow
cdacc0b1be #2498: Add ServerConnectRequest accessor in ServerConnectEvent.
- Make the timeout and retry status mutable so plugins can modify these values directly within the ServerConnectEvent.
2020-02-03 10:36:33 +11:00
markusmarkusz
b4b998b2e5 #2761: Add ClientConnectEvent 2020-02-02 10:48:22 +11:00
md_5
a3ab2bf58e Update checkstyle 2020-02-01 09:32:35 +11:00
md_5
adee7bd283 Source jar does not need to fork build 2020-01-30 10:57:54 +11:00
md_5
7bd8a0276c Always print remote IP in InitialHandler 2020-01-30 09:01:10 +11:00
md_5
0cf27a0981 Update scriptus 2020-01-29 16:40:29 +11:00
md_5
bf673c5d8b Add pretty colours to console log levels 2020-01-29 12:03:22 +11:00
md_5
2235a32316 Optimize ColouredWriter slightly 2020-01-29 11:18:18 +11:00
md_5
1dee049007 Don't send/construct redundant kick messages 2020-01-29 11:05:38 +11:00
md_5
e9ba95b9dc Don't log full CorruptedFrameException 2020-01-29 10:48:09 +11:00
md_5
d3bd785289 #2762: Work correctly with disabled timeout 2020-01-28 20:37:04 +11:00
md_5
3ce4132c58 Switch keepalive queue to ArrayDeque
See eeb374798b
2020-01-28 20:37:04 +11:00
Sigurður
ce2dcaf71d #2763: Fix .DS_Store entry in .gitignore 2020-01-28 16:04:23 +11:00
md_5
cf72c3a788 Show slow event times in milliseconds 2020-01-27 17:01:57 +11:00
Mystiflow
cd7a3ab2b2 #2758: Improve server list ping response where remote ping failed 2020-01-25 11:16:02 +11:00
Mystiflow
0a4b9b4984 #2752: Configurable connect and ping timeouts 2020-01-25 11:12:40 +11:00
md_5
70370faf5d Add checkstyle indentation checks 2020-01-24 14:07:42 +11:00
md_5
24a53a671c Show socketAddress in BungeeServerInfo.toString 2020-01-24 14:07:14 +11:00
md_5
503b4827d9 Fix bad formatting in EntityMap 2020-01-24 13:18:09 +11:00
polo1k
eeb374798b #2710: Store queue of pending keepalives
This allows the server to send them at a rate greater than the client reply time.
2020-01-24 13:13:01 +11:00
md_5
3f6aa0336c Also check that things that should not be padded are so 2020-01-24 11:46:30 +11:00
md_5
78a8495399 Add more checkstyle rules 2020-01-24 11:33:14 +11:00
Mystiflow
636c020772 #2753: Add configurable remote ping caching 2020-01-24 10:48:50 +11:00
md_5
a4512e50fb Check Maven version in action build & don't print noisy transfer progress 2020-01-24 09:10:23 +11:00
md_5
f510989c1f Add building of pull requests via GitHub Actions 2020-01-24 08:59:45 +11:00
md_5
129884f44d Minecraft 1.15.2 support 2020-01-22 08:00:00 +11:00
md_5
4bb0fb67a8 Fix Javadoc in ServerInfo.getSocketAddress 2020-01-20 16:05:23 +11:00
md_5
68cc325ace #2755: Add ClickEvent.COPY_TO_CLIPBOARD 2020-01-19 10:18:54 +11:00
md_5
3d3a5aefa2 Remove unused .travis.yml 2020-01-18 17:47:53 +11:00
md_5
2c6a21d503 Remove stray import breaking build 2020-01-18 10:15:25 +11:00
BlackHole
b7e7274b98 #2750: Don't special case TextComponent constructor with a single extra 2020-01-16 10:45:29 +11:00
md_5
b70cb01413 Add beta support for binding bungee to unix socket addresses 2020-01-16 10:36:13 +11:00
md_5
701391f232 Update Netty to 4.1.45.Final 2020-01-15 14:34:18 +11:00
md_5
85ea4c165b Remove redundant scheduled close, already channel closed by future. 2020-01-14 19:06:14 +11:00
BlackHole
22d2cd3388 #2747: Fix TranslatableComponent.deserialize() 2020-01-13 09:19:07 +11:00
md_5
d8c222ae79 Update date 2020-01-05 11:28:26 +11:00
md_5
d20e622b7b Apply checkstyle to javadoc 2020-01-05 11:25:56 +11:00
md_5
6c8a0ccecb Remove m2e settings, causes useless warnings 2020-01-05 11:17:37 +11:00
md_5
2f547f73f7 Fix some javadoc warnings 2020-01-05 11:17:11 +11:00
Janmm14
5f29e939b0 #2720: Send different log message for pings (vs login) 2020-01-05 11:02:05 +11:00
CertainLach
465215686b #2740: Fix BaseComponent#equals() stack overflow 2020-01-05 10:44:40 +11:00
Mystiflow
d2ceccd646 #2725: Various improvements to chat API
* More versatile ComponentBuilder system
    - Allow creating a builder without an initial component
    - Duplicate the parts when component is created
    - Add getter for 'parts'
* Added cursor API for more fluid component modifying
* Don't legacy convert Titles on 1.11 or newer
* Simplify plain and legacy text converting code
    - Shares the addFormat method between all superclasses
    - Duplicate code in TranslatableComponent moved in separate method
2020-01-05 10:40:07 +11:00
Mystiflow
7ed4c41d39 #2723: Improved Send Command
Previously sending player(s) would always tell the command sender that
they were successfully summoned even if they were not. This change
checks the result of the callback to determine how many players were
sent based on which result (SUCCESS,EVENT_CANCEL,etc) and lists the
count for each type. Additionally a hoverable delimited list of player
names is shown for each result type message component in the chat.
2019-12-23 12:48:44 +11:00
md_5
065893b523 Update Netty to 4.1.44.Final and remove usage of some deprecated methods 2019-12-21 11:52:45 +11:00
md_5
4204fa2966 Fix fishing hooks / spectral arrows after switching servers on 1.15.x 2019-12-18 12:39:49 +11:00
md_5
1f24591a0d Minecraft 1.15.1 support 2019-12-18 08:00:00 +11:00
md_5
4cccf53775 Minecraft 1.15 support 2019-12-11 08:00:00 +11:00
md_5
70038c9144 Revert "#2714: Remove unnecessary throws in ServerConnector"
This reverts commit 74a6aa32a2.

Completely breaks Bungee
2019-12-05 12:28:21 +11:00
Janmm14
39ef20b298 #2716: Don't attempt to send kick packet during handshake phase 2019-12-05 12:05:35 +11:00
Janmm14
74a6aa32a2 #2714: Remove unnecessary throws in ServerConnector
As ServerConnector's handle(PacketWrapper) method only checks whether packet.packet is null, its not necessary to cancel its execution by throwing CancelSendSignal.
2019-12-05 10:24:20 +11:00
md_5
c7984070a2 Misc dependency update 2019-12-01 17:32:32 +11:00
MrIvanPlays
9e76966e0f #2608,#2684: Add some missing translations to module commands 2019-08-21 20:09:09 +10:00
md_5
450c33db64 Formatting fixes 2019-08-21 20:04:16 +10:00
md_5
34febec65f Increase outdated build delay to 8 weeks 2019-08-10 10:51:26 +10:00
md_5
5c6bc183fd Minecraft 1.14.4 support 2019-07-20 09:00:00 +10:00
Brokkonaut
7669801e69 #2671: Fix command packet parsing for Float/Double arguments 2019-07-13 16:06:35 +10:00
md_5
941d7f7262 Minecraft 1.14.3 support 2019-06-25 06:49:00 +10:00
md_5
fe2a39e4f1 Minecraft 1.14.3-pre4 support 2019-06-21 20:00:00 +10:00
md_5
8eb5683783 Bundle 1.14.2 translations 2019-06-09 19:35:11 +10:00
md_5
8fda060611 Minecraft 1.14.2 support 2019-05-28 06:30:00 +10:00
md_5
3ec223ec94 Minecraft 1.14.1 support 2019-05-14 10:00:00 +10:00
md_5
086eb847ec #2631: Fix incorrect types of fishing bobber and spectral arrow 2019-05-01 18:00:08 +10:00
md_5
7d68335c1d Fix switching to servers with larger view distance 2019-04-28 10:52:49 +10:00
killme
9bce83704a #2622: Let ThrottleTest work independently of real time 2019-04-25 20:57:03 +10:00
md_5
191afb6a6c Minecraft 1.14 support 2019-04-25 12:00:00 +10:00
Zedadias Wick
4ca942b169 #2626: Correct entity metadata type values for 1.14-pre5.
Spawn Object packet now uses Entity IDs, not Object IDs, and is sent as a VarInt rather than Byte.
2019-04-24 09:33:17 +10:00
md_5
4cef6d1c25 Actually add checkstyle config 2019-04-23 21:23:06 +10:00
md_5
af10f82d14 Apply and enforce import ordering rules 2019-04-23 15:23:40 +10:00
md_5
3f01748d75 Minecraft 1.14-pre5 support 2019-04-23 12:00:00 +10:00
md_5
5aaccd2e9e #2621: Fix score component serialization 2019-04-06 19:54:17 +11:00
md_5
771f1735e5 Clearer message for illegal IP addresses 2019-03-18 13:26:10 +11:00
md_5
4428409d41 Netty 4.1.34.Final 2019-03-17 12:58:05 +11:00
md_5
52a125dded Add --help flag 2019-03-17 12:43:12 +11:00
md_5
caeabb5b62 #2610: Fix out of date message for unsupported versions 2019-03-09 09:08:27 +11:00
md_5
e2bc7ed797 Misc formatting fixes 2019-02-26 13:11:05 +11:00
md_5
9133a6f511 Simplify packet registration 2019-02-26 13:05:02 +11:00
md_5
6d6fbb5efa Fix two minor formatting issues 2019-02-17 10:13:24 +11:00
md_5
0d6f3ee374 Make 1.13 command injection normal functionality 2019-02-17 10:10:41 +11:00
md_5
28c82238d0 Fix typo in previous commit 2019-02-03 17:58:46 +11:00
md_5
1a06ebeee0 #2599: Remove connection throttle if proxy protocol in use 2019-02-03 08:26:03 +11:00
md_5
0dd538f9ff #2594: Add second way of catching exceptions when handling UDP query 2019-01-30 22:05:59 +11:00
md_5
96b1fb1f0e #2593: Fix null tooltip string v2 2019-01-30 16:17:55 +11:00
md_5
219d55dfda #2592: Fix null tooltip string 2019-01-30 15:45:47 +11:00
md_5
29c093f83f #2586: TabCompleteResponseEvent for 1.13 2019-01-30 11:33:04 +11:00
kamcio96
7496b0a2c8 #2584: Add ComponentBuilder#appendLegacy 2019-01-20 20:02:32 +11:00
Simon Chuu
3889f8683d #2578: Add easy way to get proxy command iff it is enabled for that sender 2019-01-20 20:00:26 +11:00
md_5
712a60ffd2 Remove improperly exposed getters from AsyncEvent 2019-01-09 10:19:31 +11:00
Virizion
8b5a89bf12 #2576: Allow plugins to register multiple intents for async events 2019-01-09 10:19:31 +11:00
md_5
9a2acc826e #2569: Respect disabled_commands setting for 1.13 tab completion 2019-01-03 16:39:38 +11:00
md_5
4fa1d82b81 #2572: Add additional APIs regarding server restriction 2019-01-03 16:35:32 +11:00
md_5
a12bb4cead Clarify boolean of connect callback 2018-12-29 13:01:53 +11:00
md_5
5ef5dd2c09 #2570: Implement more aggressive connection throttling.
Once an IP has connected connection_throttle_limit times within connection_throttle milliseconds, it must wait connection_throttle milliseconds before attempting to connect again.
2018-12-27 10:25:29 +11:00
md_5
7dd09289ee Update native-cipher to mbedtls 2.15.1 2018-12-21 11:01:35 +11:00
md_5
a9a4c900e4 #2524: Allow empty groups/permissions 2018-12-21 10:35:57 +11:00
md_5
d689ba5904 #2535: Reduce verbosity of unhandled packet exception messages 2018-12-21 10:15:36 +11:00
md_5
a47b803385 #2568: Check permissions for inject_commands 2018-12-21 09:50:54 +11:00
md_5
14fbe6178f bungeecord-protocol requires sonatype-nexus-snapshots repo 2018-12-20 10:45:21 +11:00
md_5
02a65e34cf #2479: Allow injection of BungeeCord commands to 1.13 with inject_commands option 2018-12-20 10:41:18 +11:00
md_5
7793894621 #2567: Fix server changing on 1.12.x due to broken protocol link 2018-12-19 10:26:16 +11:00
md_5
e5b96b2f17 Move launcher out of bootstrap and into proxy 2018-12-18 11:19:30 +11:00
md_5
865a346903 #2546: reducedDebugInfo state not updating when changing servers 2018-12-18 11:13:42 +11:00
md_5
12a99bd291 #2560: Don't force gold on /server text 2018-12-17 11:52:40 +11:00
md_5
afef0ec1fe #2559: Unresolved ServerIP causes disconnect 2018-12-08 09:56:34 +11:00
md_5
378aaadb68 Netty 4.1.32.Final, Trove 3.1.0 2018-12-06 10:54:30 +11:00
md_5
b0737ba230 Netty 4.1.31.Final 2018-11-23 10:54:31 +11:00
md_5
6890993c28 Update to lombok 1.18.4 2018-11-23 10:44:58 +11:00
Janmm14
783979b6b9 #2549 Add security / firewall warning to readme. 2018-11-22 10:15:37 +11:00
md_5
c26705e6b1 Improve YamlConfiguration encoding defaults
Before:
Load / Save using platform default (UTF-8 on most except Windows)

After:
Load using detected encoding with fallback to UTF-8
Save using UTF-8
2018-11-07 19:41:50 +11:00
NayXegp
6c44ccd597 #2527: Minor cosmetic cleanups to imports etc
Please see https://github.com/SpigotMC/BungeeCord/pull/2527
2018-11-02 18:06:56 +11:00
md_5
ed6b03d24a Always use root locale for case conversions 2018-10-28 12:10:34 +11:00
NayXegp
27f926cfc7 #2539: Optimize dash free UUID parse 2018-10-28 12:05:50 +11:00
NayXegp
cb4108c1b4 #2539: Regex free command split 2018-10-27 18:19:58 +11:00
md_5
1c5bff7ed7 Minecraft 1.13.2 support 2018-10-23 06:00:00 +11:00
md_5
bba5098ff1 Netty 4.1.30.Final 2018-09-28 17:04:30 +10:00
NayXegp
41f8eb68c9 #2529: Use single legacy kicker instance for all channels 2018-09-26 11:16:46 +10:00
NayXegp
9886021428 #2521: Using replace instead of replaceAll 2018-09-05 07:51:23 +10:00
NayXegp
ba0739798a #2494: Add an option to disable pings in log 2018-08-29 07:53:52 +10:00
JoJoDeveloping
16b3490576 #2520: Fix ConcurrentModificationException when tasks are cancelled during shutdown 2018-08-29 07:47:12 +10:00
md_5
1bb826109c Minecraft 1.13.1 support 2018-08-23 20:52:25 +10:00
md_5
9ea82e9541 Add multiple translation registries, support for Mojang JSON 2018-08-16 07:52:41 +10:00
Mystiflow
4c47549253 #2497: Incorrect defaults in ServerConnectRequest 2018-08-12 09:43:57 +10:00
Mystiflow
715ec07a28 #2447: Add API for fluent server connect requests
API allows for more control over callback to see why the callback was performed whilst maintaining backwards compatibility
2018-07-30 12:37:34 +10:00
md_5
6fadb4250c Use shorter legacy prefix (doesn't really matter because no chance of such a plugin working) 2018-07-23 14:30:34 +10:00
md_5
d2cf50f9ee #2482: Fix error reading custom names 2018-07-23 12:44:42 +10:00
md_5
a710698277 #2482: Fix error in reading slots 2018-07-23 12:07:30 +10:00
md_5
176b75b97e #2477: Fix entity rewrites not applying 2018-07-23 11:12:20 +10:00
md_5
c9f22868b3 Revert "#2447: Add API for fluent server connect requests"
This reverts commit 7ce9ae50e7.
2018-07-22 20:13:30 +10:00
maol3
95ed7a5775 #2474: Allow ALL in the Message channel 2018-07-22 18:10:51 +10:00
Mystiflow
7ce9ae50e7 #2447: Add API for fluent server connect requests
API allows for more control over callback to see why the callback was performed whilst maintaining backwards compatibility
2018-07-22 18:04:43 +10:00
md_5
671c4d1341 Minecraft 1.13 support 2018-07-22 12:00:00 +10:00
NayXegp
0a95af5dc1 #2464: Improve information about missing packet IDs 2018-07-17 16:33:00 +10:00
md_5
5cdb181cc5 #2465: Sync SnakeYAML version with Bukkit 2018-07-15 21:20:58 +10:00
Simon Chuu
77b0a38c26 #2457: Allow objects in with to be translated into a string (for integer, float, etc.) 2018-07-15 11:39:46 +10:00
Lucas Dallabona
ab810744ec #2458: Fix NPE when using null in tab list methods 2018-07-15 11:32:33 +10:00
md_5
b1cc72e212 Minecraft 1.13-pre7 support 2018-07-15 10:00:00 +10:00
PROgrm_JARvis
ceb9ea1e52 #2436: Extend chat module with Joiner functional interface support 2018-07-12 21:44:59 +10:00
md_5
fa542c70df Fix incorrect whitespacing 2018-07-09 12:52:53 +10:00
md_5
c416c44f43 Deprecate not API ProxyServer.start method 2018-07-09 09:59:33 +10:00
Nathan Poirier
d591d0ed29 #2451: Fix direction in BadPacketException message 2018-07-09 09:58:00 +10:00
Minecrell
7410ce9077 #2449: Avoid stopping if already in progress
Currently it is possible to stop the proxy multiple times, causing
the shutdown routines to be called twice. This doesn't make any
sense and may even cause problems with some plugins.

Cancel early if stopping is already in progress to avoid this.
2018-07-09 09:57:21 +10:00
Rincewind34
ff42394bdb #2427: [Trivial] Fix small mistake in Title documentation 2018-07-08 17:55:45 +10:00
Nathan Poirier
7af538793c #2450: Instantiate PluginManager (and EventBus) after the BungeeCord Logger 2018-07-08 09:59:30 +10:00
md_5
730715e68b #2437: Behave more like underlying servers and don't send no permission messages during tab completion 2018-06-21 12:52:03 +10:00
md_5
76dc32ee32 Enable IPv6 networking stack 2018-06-20 15:43:57 +10:00
md_5
c0704194ec Revert lombok update - breaks incremental compilation 2018-06-07 21:49:20 +10:00
md_5
2356dbcae8 Update lombok for better support of newer Java versions 2018-06-07 15:34:07 +10:00
md_5
68103e9a8d Netty 4.1.25.Final; MySQL 5.1.46. 2018-06-03 10:32:47 +10:00
md_5
968916c0b8 Don't forward unusually large plugin messages during login
Thanks fejm
2018-05-13 11:42:20 +10:00
CosmoConsole
f54f0e3f6a #2421: fromLegacyText - return formatted component even if empty 2018-05-13 10:10:07 +10:00
md_5
88bacf12a3 #2420: Cap forge packet queue size 2018-05-12 21:14:44 +10:00
md_5
e93323ddbc #2420: Disable forge support by default 2018-05-12 08:24:06 +10:00
md_5
fde2c3fadf Netty 4.1.24.Final 2018-04-20 18:13:08 +10:00
md_5
79cd077a60 Netty 4.1.23.Final 2018-04-13 23:02:57 +10:00
md_5
cbfdf64a15 Add missing javadoc from previous commit 2018-04-02 12:49:47 +10:00
md_5
dce4ea193a #2396: Add way to select reset color when parsing legacy chat 2018-04-01 09:36:46 +10:00
Mystiflow
7241eb37c9 #2376 Add ServerConnectEvent Reason API 2018-04-01 09:34:27 +10:00
md_5
d4bbe0d8db Fix formatting in ComponentsTest 2018-04-01 09:31:00 +10:00
md_5
e690a7b389 #1959: Leave ping exception logging to plugins 2018-03-31 10:55:15 +11:00
games647
272258cf5a #2372: Add SettingsChangedEvent for client-side settings 2018-03-15 20:47:08 +11:00
Mystiflow
d7eef6ff2e #2388: Treat BaseComponent array appends as one. Fixes #2387.
Don't copy formatting of previous element in the array being appended
but instead from the last appended component in the builder.
Otherwise formatting will be overridden in an incorrect way from
legacy text conversions.

Added unit test failed before this change. Now passes.
2018-03-14 19:51:08 +11:00
Mystiflow
7ee0b6dccb #2378: Show supported servers in incorrect client kick messages
This makes the message match vanilla Minecraft servers
2018-03-07 13:29:43 +11:00
Joe
7653a5f0f8 #2363: Chat Component API Improvements
- duplicateWithoutFormatting deprecated and now works to include extra. Less maintenance required for any component implementations.
- Improved copyFormatting API to allow for retention copying.
- API to append a single BaseComponent in a ComponentBuilder, previously had to wrap a
component in its own array to do this.
- BaseComponent retain API that functions the same as from
ComponentBuilder.
2018-03-05 18:25:48 +11:00
Joe
74e077e0fb #2362: Fixed tablist rewrite getting wrong field
Also only sets the ping in right circumstances.
2018-02-26 07:00:37 +11:00
Senmori
a3b44aa612 #2342: Add score and selector components to chat API 2018-02-19 11:48:22 +11:00
md_5
e23195f5f2 Netty 4.1.21.Final 2018-02-07 18:26:56 +11:00
md_5
ca8f31bdc7 Merge unit tests 2018-01-28 18:00:24 +11:00
md_5
2d7c74eae5 Move chat component test to right place 2018-01-28 17:59:32 +11:00
md_5
9b2bb07d89 Fix some source code formatting 2018-01-28 10:23:52 +11:00
md_5
6b88b63941 #2335: Clarify JavaDoc for methods in PendingConnection 2018-01-28 10:20:03 +11:00
Gabscap
c0356eb72d #2333: Fix StringIndexOutOfBoundsException in TextComponent.fromLegacy 2018-01-28 09:59:34 +11:00
Foorack
aef386178a Remove deprecated guava function in config (#2327)
This removes the need to shade in the full guava library if a java program only uses bungeecord-config.
2018-01-14 21:58:26 +11:00
md_5
22bd43f725 Use root locale for upper / lowercasing 2018-01-12 08:17:44 +11:00
md_5
d600c9a526 #2323: Attempt to rewrite fishing hook data 2018-01-08 12:51:26 +11:00
Minoneer
6b7046c8b7 Fixes lookup of default configuration values for nested paths (#2322)
The lookup of default configuration values with multiple path segments failed with a class cast exception because the full path was treated as a new configuration section instead of only the root.
2018-01-08 09:19:17 +11:00
md_5
050d935891 Update Netty / MySQL 2018-01-07 22:49:33 +11:00
md_5
3508bf6c85 Add console command completion 2018-01-07 22:46:52 +11:00
md_5
dda0638869 Make bungeecord-chat API classes final - the API does not (nor should) support subclassing. 2017-12-26 15:30:48 +11:00
md_5
9fd98436af Netty 4.1.18.Final 2017-12-12 20:54:48 +11:00
md_5
eb288a80c3 Remove obsolete tab lists 2017-12-01 12:25:59 +11:00
Zhang
ed23e3b3d1 #2296: Fix tab list NPE w/ some offline mode clients 2017-12-01 12:25:39 +11:00
md_5
1dbfcfb0b5 #2297: Use server field on DownstreamBridge 2017-12-01 12:23:07 +11:00
md_5
4c84f37fd2 mysql-connector-java 5.1.44 2017-11-18 17:14:46 +11:00
md_5
cccbb3c889 Netty 4.1.17.Final 2017-11-11 08:13:00 +11:00
md_5
2e826a15e7 Make greload reload custom messages.properties 2017-11-10 11:21:58 +11:00
BlackHole
fbc5f514e2 Add KeybindComponent API 2017-11-10 11:14:17 +11:00
md_5
3e65ee2f54 Update snakeyaml to 1.19 to fix bug with duplicate keys affecting some users.
https://bitbucket.org/asomov/snakeyaml/issues/386/duplicate-keys-cause-issues
2017-11-07 19:36:59 +11:00
md_5
0fc5694b6a Fix some compiler warnings 2017-10-28 17:08:05 +11:00
md_5
4e2897710b Remove deprecated sonatype parent pom. 2017-10-28 16:46:31 +11:00
md_5
9a7bf0a361 #2254: Explicitly note config issues are not bugs 2017-10-26 21:18:16 +11:00
md_5
ec4279eeb4 #2280: Console usage of /server 2017-10-26 21:11:56 +11:00
md_5
8d49424226 #2261: Don't send any keep alive to server if invalid 2017-09-23 17:14:03 +10:00
md_5
69bbc3a71e Invalidate ping when spoof sent 2017-09-23 15:05:50 +10:00
md_5
af8d1af635 Initialize ping to -1 2017-09-23 13:56:23 +10:00
md_5
23554239d0 #2259: Have proxy handle keepalives 2017-09-23 13:18:43 +10:00
md_5
61cb2df9f3 #2258: Fix missed packet ID 2017-09-19 08:04:44 +10:00
md_5
0eaabdf5ca Update to Minecraft 1.12.2 2017-09-18 20:00:00 +10:00
Mystiflow
3db9fb1b69 #2255: Fix ComponentBuilder clone constructor
* Fix ComponentBuilder clone constructor #2255
* Fix appending text to a ComponentBuilder if current is not a TextComponent
2017-09-16 16:06:51 +10:00
Virizion
ef326dba19 Send the correct username when connecting to a server (#2242) 2017-09-05 19:33:10 +10:00
md_5
d7010d629d Fix mismatched system properties 2017-09-04 18:15:23 +10:00
md_5
7068013be8 Upgrade to Netty 4.1.15.Final 2017-08-31 07:48:50 +10:00
md_5
bd5a7e5b26 #2228: Implement basic backpressure on client 2017-08-18 18:27:25 +10:00
Mystiflow
fd675022c0 Allow appending BaseComponent arrays in ComponentBuilder 2017-08-13 12:40:44 +10:00
Mystiflow
a1f9c2e7d4 Disable plugins before shutting down EventLoops (#2214)
Because disabling plugins also cancels any pending tasks, there will be no task accessing the eventLoops.

Reimplementation of #1578, fixes #1403
2017-08-09 22:13:25 +10:00
md_5
db266a8484 Use newer writeAndFlush method 2017-08-09 22:05:06 +10:00
md_5
828e45651e Client defaults to right hand 2017-08-09 16:51:45 +10:00
md_5
1039554039 Update Mojang translations to 1.12.1 2017-08-09 16:45:53 +10:00
Foorack
dbf20957a9 Expand API to get all player sent settings 2017-08-09 16:38:03 +10:00
md_5
da88d5c502 Formatting & dependency updates 2017-08-06 11:19:08 +10:00
Mystiflow
2ae8ba0afc Various scoreboard improvements. (#2204)
- Correctly remove objectives that use heart type.
- Also sends remove score packets on server switch.
- Players are only removed if Team packet mode is 4.
2017-08-04 16:10:10 +10:00
md_5
017f3a2424 Update to Minecraft 1.12.1 2017-08-03 23:00:00 +10:00
md_5
caeb7246f0 Update to Netty 4.1.13.Final. 2017-07-07 15:11:46 +10:00
md_5
9b3b42316f Update Animal Sniffer & Signatures. 2017-07-01 19:04:04 +10:00
md_5
daac8d85e2 Add support for PROXY protocol 2017-07-01 09:38:27 +10:00
md_5
a5ffeae757 Replace OpenSSL native cipher with static mbed TLS for maximum compat 2017-06-29 08:52:13 +10:00
md_5
93819212b8 Use statically linked zlib in native-compress for maximum compat 2017-06-28 17:07:57 +10:00
md_5
6958943123 Use property to skip deploy to eliminate warnings, update lombok 2017-06-21 19:45:03 +10:00
md_5
73a81ff243 Update to Netty 4.1.12.Final 2017-06-18 17:36:41 +10:00
md_5
eab710b0aa #2154: Always send action bar differently to account for colours 2017-06-08 19:02:37 +10:00
md_5
a6483db3df #2157: Check insertion on hasFormatting 2017-06-08 18:52:46 +10:00
md_5
ff891c000e Update to Minecraft 1.12 2017-06-08 18:00:00 +10:00
md_5
e26b93728c Update to Minecraft 1.12-pre6 2017-05-30 21:50:45 +10:00
BlackHole
4db53525bf Correct some packet IDs in 1.12 EntityMap 2017-05-23 06:35:01 +10:00
md_5
09ee2b1644 Update to Minecraft 1.12-pre5
Obsoletes 1.12-pre2
2017-05-19 21:00:04 +10:00
md_5
16d261553c Minecraft 1.12-pre2 Support 2017-05-14 12:00:00 +10:00
BlackHole
5bc189fbb7 Use player name casing from LoginResult 2017-05-09 12:49:48 +10:00
md_5
806a6dfaca Add Mojang prevent_proxy_connections option. 2017-04-28 21:48:41 +10:00
Molek
bfab8a1d9c Index UUIDs to speed up player queries (#2121) 2017-04-26 16:39:49 +10:00
md_5
53cc3242e1 Update Netty to 4.1.9.Final for some fixes to warnings that users were experiencing and better Java 9 support. 2017-03-11 19:15:40 +11:00
md_5
cb60d08ee7 Update date 2017-03-06 18:10:40 +11:00
md_5
6908e700e6 Jenkins modules are now https. 2017-02-12 10:59:10 +11:00
md_5
01f44483df #2055: Mark inactive channels as closed 2017-02-07 08:58:37 +11:00
md_5
950d504bd8 Upgrade lombok 2017-02-01 14:06:17 +11:00
md_5
ff7ea427ef #2050: Revert JLine upgrade 2017-02-01 09:23:19 +11:00
md_5
0b8ab8eccc Update Netty; jline; MySQL 2017-01-30 18:27:13 +11:00
MisterFrans
db1516ba00 Add "Not authenticated with Minecraft.net" message in the messages.properties (#2044) 2017-01-18 08:36:00 +11:00
md_5
81de9d5a63 #2041: More robust closing code 2017-01-16 10:11:17 +11:00
md_5
c1bdbef9cf Give delayed close packets time to send on /end 2017-01-16 10:00:27 +11:00
md_5
6104354fa1 Implement basic entity metadata mapping to remap fireworks for boosting. 2016-12-22 22:29:00 +11:00
Minefabser
b728aea382 Fix TabListItemHeaderFooter for 1.11.1 (#2028) 2016-12-21 06:57:41 +11:00
md_5
21411af74d Add support for Minecraft 1.11.1 2016-12-21 06:23:51 +11:00
md_5
129693f533 #2026: Try multiple priorities as fallback 2016-12-19 23:09:18 +11:00
md_5
4fa9961c15 #1958: Negative compression thresholds disable compression like Vanilla 2016-12-16 10:43:29 +11:00
md_5
3ee7fdd90e Revert: Add flag -Dbungee.native=false to disable native code.
Reverted from commit 71b00d644f.
Flag was hiding under: -Dnet.md_5.bungee.native.disable=true
2016-12-05 09:08:03 +11:00
md_5
71b00d644f #2015: Add flag -Dbungee.native=false to disable native code. 2016-12-04 10:41:29 +11:00
Gabscap
ea6680281f Allow cancelling LoginEvents with component reasons.
Ultimately this PR was selected as it better matched the existing code in terms of using lombok and not adding incomplete interfacing.
If for some reason a common interface is required, this can be implemented later.

Thanks to yawkat also for the PR in #1336 -- it was difficult for the merger to compromise between this and #1957
2016-12-01 10:12:54 +11:00
md_5
2171ca9f51 Fix confusing use of static subclass methods 2016-12-01 09:46:34 +11:00
md_5
4d004d5fed Throw exception when ServerConnectEvent is handled badly 2016-11-25 10:42:30 +11:00
Nathan Poirier
8574688be7 Fix compatibility of Title packet for 1.10 and lower (#1997) 2016-11-16 09:22:09 +11:00
Mystiflow
f3e5f34aeb Allow chat messages longer than 100 characters on > 1.11 clients 2016-11-15 09:37:20 +11:00
md_5
9a4150cd47 Fix read/write mismatch 2016-11-15 08:15:32 +11:00
md_5
72002ed3bd Fix PlayerListHeaderFooter 2016-11-15 08:00:13 +11:00
Shane
95a269df7a Fix handling of Title packet for 1.11 and maintain backwards compat with 1.10 and earlier 2016-11-15 07:59:27 +11:00
md_5
9ecdde2292 Add support for Minecraft 1.11
Improve QueryHandler session handling as suggested by IchBinJoe
2016-11-15 02:40:46 +11:00
md_5
1ad81564ad Fix Javadoc in Plugin#init 2016-11-06 11:51:52 +11:00
Andrew
ee256d0a8d Make exceptions thrown by QueryHandler nicer. (#1741)
Previously, they would result in a large and scary message from Netty. This instead sends the message to the BungeeCord logger and de-establishes the connection.
2016-11-06 11:48:24 +11:00
md_5
987f2d0eb2 Remove unused connect_kick_outdated_forge message 2016-11-06 11:47:27 +11:00
Mystiflow
908b7f7374 Use server priority for downstream kicks too (#1978) 2016-11-06 11:25:46 +11:00
Mystiflow
18f57f24fa Fix issue pointed out by Supereg; store dimension on first join too (#1979)
* Only double switch if the dimension is the same.

According to the protocol, a double respawn packet is only needed to be
sent if from the same dimension, so by storing the last known dimension,
we are able to compare and avoid the double packet.

This also maintains the same behaviour for Spigot
ad2f806097

* Store current dimension on first disconnect too
2016-10-30 08:28:11 +11:00
Mystiflow
812141f400 Only double switch if the dimension is the same. (#1977)
According to the protocol, a double respawn packet is only needed to be
sent if from the same dimension, so by storing the last known dimension,
we are able to compare and avoid the double packet.

This also maintains the same behaviour for Spigot
ad2f806097
2016-10-29 17:59:38 +11:00
md_5
75b7fdac58 Fix stray imports in proxy 2016-10-19 21:15:00 +11:00
md_5
5c551fd899 Improve Quality of Channel Close Code
* Don't double disconnect due to client exceptions
* Add generic delayed close method
* Properly format imports in changed files
2016-10-19 21:08:38 +11:00
MiniDigger
24a65d8fa9 Update mojang-translations to 1.10.2 (#1969) 2016-10-11 20:12:59 +11:00
prplz
65aa7609d7 Fix possessive pronouns don't use apostrophes (#1968) 2016-10-11 20:12:50 +11:00
md_5
0581e49d49 Update Netty 2016-08-30 20:22:02 +10:00
md_5
5c809c2499 #1945: Relay MC|Brand messages 2016-08-26 16:11:38 +10:00
md_5
98e3c70460 Implicitly convert Map to Configuration 2016-08-25 11:04:19 +10:00
md_5
6563a9241b #1936: Configuration#contains(Ljava/lang/String;)Z 2016-08-21 09:10:23 +10:00
md_5
356ca08337 #1544: Reduce verbosity of common/harmless exception during initial connection 2016-08-21 09:07:33 +10:00
md_5
b86a33d058 #1941: Fix modded client+server in some cases 2016-08-21 09:02:37 +10:00
md_5
504d3c0529 #1939: Fix server brand; prevent bungee-bungee connections. 2016-08-20 11:43:48 +10:00
md_5
11c7b246e0 #1938: Better handling of null config keys 2016-08-18 09:35:58 +10:00
md_5
37b3cb4a30 #1934: Better in memory config representation 2016-08-15 18:41:52 +10:00
md_5
d6772cf1e4 #1933: Exclude favicon from ServerPing#toString 2016-08-13 14:24:50 +10:00
md_5
e7be3c6b1e Allow PluginMessages to be handled when no server connected 2016-08-11 23:02:29 +10:00
md_5
3a0b0aa116 #1930: Don't handle upstream packets if no server connected 2016-08-03 17:03:06 +10:00
md_5
a605c1acbc Netty 4.0.40 2016-07-28 20:28:18 +10:00
Brokkonaut
b374a69b2c Do not change ComponentBuilder's contents when calling create()
This allows continuing to use ComponentBuilder after create() has been called.
2016-07-21 10:48:53 +10:00
Cory Ory
b5121db886 Exclude data from PluginMessageEvent.toString 2016-07-18 13:33:48 +10:00
md_5
a05e695db9 Initialize no args TextComponent with blank text. 2016-07-18 13:32:17 +10:00
md_5
c43f25e23b Fix MC|Brand array having trailing zeroes. 2016-07-15 23:45:38 +10:00
md_5
e5ac567c79 Update to Netty 4.0.39.Final 2016-07-15 23:31:00 +10:00
md_5
5dc0a8b5c9 #1909: Downgrade to version of jline which works properly on Windows 2016-07-13 11:05:50 +10:00
md_5
eca99576a0 Move net.md_5.bungee.log to its own module.
API subject to change and should not be used externally.
2016-07-11 11:12:35 +10:00
BlackHole
1250088f98 Correctly show outdated_client and outdated_server messages
If the client protocol version is not supported, show outdated_server message only if client version is higher than highest supported protocol version, outdated_client message else.
2016-06-29 09:15:17 +10:00
md_5
507a98f28f #1859: Rewrite second leash int 2016-06-29 09:14:03 +10:00
md_5
a8c529eca5 #1859: Entity attach is an int 2016-06-28 15:28:28 +10:00
misterT2525
c5ac5a0d17 #1859: Fix EntityMap for leads. 2016-06-27 14:20:02 +10:00
md_5
e3869fea18 #1893: Alter definition of slow event 2016-06-20 20:05:07 +10:00
md_5
6f6cb58d8b Make warning message better... 2016-06-20 09:25:29 +10:00
PunKeel
3fe72154a3 Fix slow event detection
Time moves forward, so the second call to nanoTime returns a bigger number than
the first one, giving a negative elapsed time … defeating the whole purpose of
this code. :-(
2016-06-20 08:46:53 +10:00
Tom
97eef62684 Change color for cmd_find
Blue is basically unreadable (even worse with some resource packs)
2016-06-12 21:39:20 +10:00
md_5
e4cf010bda Update to Minecraft 1.10 2016-06-09 11:44:06 +10:00
md_5
ec48077dbe #1867: Just fake 1.7 login protocol for now 2016-05-15 22:05:31 +10:00
md_5
2df29701ed #1866: Correct throttle 2016-05-15 16:01:58 +10:00
PunKeel
d9a8311b8e Use expireAfterWrite to perform throttle 2016-05-15 14:54:18 +10:00
Zartec
d14b96d55e Added separate exception for packet overflows to limit log output.
Attacking a server with a hacked client causes the log to print a huge amount of stacktraces. This will limit the log output to the error message.
2016-05-15 14:52:41 +10:00
md_5
41621193ec #1862: Support 1.7 pings 2016-05-15 14:52:01 +10:00
Thinkofname
a12ac37cc3 Support Minecraft 1.9.4 and tidy up packet handling 2016-05-10 21:51:39 +10:00
BuildTools
4c7c64c9b8 #1848: Added missing call to UserConnection.connect callback for "already_connected" and "already_connecting" 2016-05-05 22:32:24 +10:00
md_5
80b3135a93 Fix formatting 2016-04-24 22:31:04 +10:00
md_5
1cd3e42182 #1841: Fix disabled throttle and improve code. 2016-04-24 22:18:23 +10:00
Janmm14
2e8ed1cfba Reimplement join throttle. 2016-04-24 11:56:24 +10:00
md_5
b9a98c88ba Java 7 support 2016-04-24 11:39:23 +10:00
md_5
0b554be10a Strip / add velocity to SpawnEntity packets that require it when rewritten 2016-04-24 09:39:22 +10:00
md_5
4872075bf7 #1762: Don't perform repetitive decompress.
Pointed out by @sfPlayer1
2016-04-12 07:55:04 +10:00
Jofkos
f070e2d064 Added ansi "erase line" 2016-04-08 07:42:11 +10:00
BlueAnanas
8f2877e806 Fix for missing lifecycle mapping metadata on scriptus for m2e 2016-04-06 22:40:33 +10:00
Thinkofname
b6b015fe1f Ensure we get a 1024 bit RSA key (Fixes #1814) 2016-03-31 16:12:30 +01:00
Thinkofname
7179dd4c0d Default readArray to capping to readableBytes instead of Short.MAX_VALUE 2016-03-30 23:31:17 +01:00
Thinkofname
1dda27e19b Revert limits mistakenly added to EncryptionRequest 2016-03-30 23:30:26 +01:00
Thinkofname
d1a1e87ab5 Support Minecraft 1.9.2 2016-03-30 16:57:54 +01:00
md_5
6b4e285186 1.9.1 support 2016-03-30 15:59:51 +01:00
Thinkofname
891ad8711d String arrays are only send by servers/Bungeecord. No need to limit their size 2016-03-29 19:41:16 +01:00
Thinkofname
540e924bfb Add limits to byte arrays and string lists 2016-03-28 21:08:00 +01:00
md_5
f265f7c594 #901: Better custom messages support 2016-03-24 14:15:16 +11:00
kashike
aaddc9fcfd Remove an optimization for simple components. Removes a workaround needed for 1.9
Previously we could optimize components with only a text value to a string
instead of a full object but with 1.9 we can no longer do this for every case.
The size reduction from this optimization was small anyway.
2016-03-16 17:12:56 +00:00
md_5
f53e66e2c0 Check all plugins have a name and main. 2016-03-12 12:00:56 +11:00
md_5
859d176c93 Update README.md and fix minor formatting error. 2016-03-09 18:16:22 +11:00
Tux
52d66897e4 Raise an error if a server in the priority list is undefined 2016-03-06 16:10:31 +11:00
md_5
8b327708ee #1335: Remove 16 char displayname limit 2016-03-05 18:56:32 +11:00
Zartec
903ada06f0 Sould break the priority lookup after server found
If the list would look like this

- test1 -> 1.8 -> ServerKickEvent cancelled -> reason set to "outdated"
- test2 -> 1.8
- test3 -> 1.9

and a player joins with version 1.8 he would never be connected to test2 because the server test2 is not equal to test1 and the server test3 is not equal to test1.
So test3 is the last in the while loop and would be used also if another server with higher priority matches the requirements.
2016-03-04 07:10:59 +11:00
Youri Kersten
a7664a5559 Remove any tracked bossbars when a client switches servers. 2016-03-03 18:57:48 +11:00
Joshua Küpper
0294fc5f20 Manually add the setDescriptionComponent(BaseComponent)
Lombok won't generate because of the overloading of setDescription(String).
2016-03-02 16:06:49 +00:00
md_5
46e7f2dfc9 Only allow ServerUnique tab lists as per 1.8 due to incomplete functionality. 2016-03-02 20:20:55 +11:00
Thinkofdeath
fc64a6c2ff Manually wrap serialized components in an extra text component to work around a 1.9 change (Fixes #1770) 2016-03-01 22:47:11 +00:00
Youri Kersten
b6671cd00c Send action bar messages using BaseComponent for 1.9 clients
Action Bar packets in 1.9 now correctly support the JSON format, however sending them the 1.8 way will kick the client. This keeps the compatibility with 1.8 clients with the version check whilst correctly sending the packet to 1.9 clients.
2016-03-01 19:32:19 +11:00
Thinkofdeath
7926230682 #1765: Fix ServerInfo.ping to handle chat components. 2016-03-01 12:38:19 +11:00
md_5
dd66e3068a Fix priority selection not playing nicely with reconnect handlers. 2016-03-01 12:34:50 +11:00
md_5
04a6eff14c Don't handle exceptions for obsolete server connectors. 2016-03-01 11:53:59 +11:00
md_5
05de455a9c Update to Minecraft 1.9 2016-03-01 09:31:12 +11:00
Thinkofdeath
12a7b7afc3 Add support for 15w33c and multiple fallback servers 2016-03-01 09:31:12 +11:00
Thinkofdeath
dfaa687f71 Remove 1.7.x Support 2016-03-01 09:31:12 +11:00
md_5
219819b738 Replace default/fallback servers with a server priority list. 2016-03-01 09:31:12 +11:00
BlackHole
7d2c2ab074 Add ComponentBuilder.insertion() 2016-02-22 08:44:57 +11:00
md_5
0646a3090a Fix scoreboards / tab lists getting out of sync due to race conditions / overlap. 2016-02-19 09:07:12 +11:00
md_5
afc02082e6 Make it clear when users connected Bungee to itself. 2016-02-17 10:34:04 +11:00
Tux
848cad2a59 Fix cancelling TabCompleteEvent.
The packet would get sent regardless if the event was cancelled, only if there were no suggestions available.
2016-02-07 17:44:07 +11:00
md_5
9c4380a201 System.err already has priority prefix. 2016-02-05 12:53:07 +11:00
md_5
8490d611bf [#1717] Perform a copy if Netty isn't using a direct address for any reason. 2016-02-05 12:50:42 +11:00
Thinkofdeath
a0f2c42d38 Clear the address cache entry when a connection fails
Should help solve the issues caused by mojang swapping the ip address of
the session server.
2016-02-05 10:19:31 +11:00
Jedediah Smith
40c0618a3a Fix NPE from duplicating TranslatableComponent 2016-02-04 23:12:19 +00:00
BlackHole
fa3678bcdd Add new 1.8 chat features 2016-02-04 23:11:35 +00:00
md_5
e556fd7150 Add Connection.isConnected()Z API.
Idea from kamcio96 in #1693
2016-02-05 10:09:47 +11:00
md_5
841c81cdc4 [#1714] Make a copy of the main Minecraft buffer as EntityMap.rewriteVarInt may require more bytes than available. 2016-01-24 19:45:02 +11:00
md_5
052131c1fa Reduce amount of memcpy within proxy pipeline. 2016-01-24 11:22:39 +11:00
md_5
79dbdea107 Use more realistic cipher test sizes and counts. 2016-01-16 14:03:47 +11:00
md_5
7fb1f4b81f Replace gitdescribe with Scriptus. 2016-01-16 13:52:53 +11:00
md_5
255d7fde9a Ensure native zlib actually loads. 2016-01-16 13:33:09 +11:00
md_5
7907610eeb Compatability and benchmark fixes for native code. 2016-01-16 13:29:50 +11:00
kamcio96
83e27f07e6 Use static instances of EntityMap 2016-01-16 12:44:32 +11:00
md_5
5cff0b2171 Remove redundant synchronization on ServerConnection.disconnect 2016-01-16 12:33:42 +11:00
md_5
2c86592ecd [#1649] Don't parse disconnect reason for servers.
Reported by @kamcio96
2016-01-16 12:29:13 +11:00
md_5
f5552963b8 Update Netty and enable EPoll transport. 2016-01-16 11:37:17 +11:00
md_5
1182affa09 Rewrite host parsing to account for IPv6. 2016-01-14 09:52:16 +11:00
Tux
a1895c556f Make BoundedArrayList follow the old behavior.
Unit tests have been included.
2016-01-11 14:09:07 +11:00
md_5
aa214c0b54 [#1695] Use BoundedArrayList to cap list size for REGISTER channels. 2016-01-10 19:00:00 +11:00
Luuk Jacobs
81bd3b5f71 Fix typo in ClickEvent.java 2016-01-05 09:14:34 +11:00
kamcio96
b6e26e0c09 Load NativeCode manually, not in constructor.
Bungee will call load method from main thread
https://github.com/SpigotMC/BungeeCord/blob/master/proxy/src/main/java/net/md_5/bungee/BungeeCord.java#L202
2015-11-19 08:42:01 +11:00
Joseph Hirschfeld
19f2e7b13e DNS IPs should only be cached for 1 minute. 2015-11-12 12:58:18 +11:00
xxyy
ba448b5670 Add configurable proxy command logging.
This commit adds a config switch that allows users to turn off
 the logging of proxy commands. It is set to off by default to
 prevent unwanted log spam and keep current behaviour.
Log proxy commands

This commit changes the PluginManager to print a message to
console and the log when a proxy command is executed.
This may assist with debugging and miscellaneous
investigations.
2015-10-26 20:59:53 +11:00
md_5
013320fd9e #1852: Fix packet compression when BungeeCord and the server are set to different compression levels. 2015-09-16 19:44:55 +10:00
md_5
8a1030e21c #1583: Two additions to console behaviour:
1) Stop trying to read anything if the console is hooked up to /dev/null
2) Don't even bother in the first place if --noconsole is used as an argument.
2015-09-16 15:09:40 +10:00
Thinkofdeath
c626254825 Only enable compression for 1.8 clients 2015-09-13 08:59:42 +01:00
md_5
4e94c278da [#1567] Let BungeeCord dictate the network compression threshold. 2015-09-13 09:29:39 +10:00
jfr
06ad0f9310 Reorder PlayerJoinEvent / UpstreamBridge initialization.
Placing the PlayerJoinEvent in front of the Upstream Bridge handling prevents us from actually accessing the target server in PostJoinEvent handlers.
2015-09-07 18:26:41 +10:00
md_5
c4a3a052d7 Update to Netty 4.0.31.Final 2015-09-06 12:11:41 +10:00
md_5
7ec1a1aa4e Fix / clarify behaviour of matchPlayer. 2015-09-05 13:42:33 +10:00
Tux
59208aad86 Improve EventBus by removing read locking.
This is primarily done by using ConcurrentHashMap, which has lock-free reads and thread-contention-based writes. Only one thread at a time can register threads, however, as baking events isn't thread safe (and there's no reason to make it thread-safe anyway).

My own benchmarks indicate 1.4-2.2 million operations/ms throughput and approximately ~1ns/event post for four threads posting events.
2015-09-05 13:33:18 +10:00
zml
bd07be8772
chat: Correct placeholder handling in translatable
This change makes TranslatableComponent still scan a
translation string for placeholders, even if the translation string
itself is being used (rather than a value found from the
ResourceBundle). This matches vanilla behavior and allows plugins that
use this system with serverside translations and other custom
translation systems to send output to the server console correctly.
2015-08-30 14:50:37 -07:00
pvmac2194
b3d15d53d6 Add <server> in the usage of /send
Just a small cosmetic fix that shows server owners that this argument exists.
2015-08-14 18:31:28 +10:00
Thinkofdeath
6343416c0c Update the PluginMessage packet to respect the protocol limit changes in 1.8 2015-07-16 23:07:30 +01:00
kamcio96
81d1c46a0d Support uuid in config.yml 2015-07-13 19:46:15 +10:00
md_5
6e5132f914 #1537: Allow /send <server> <server>.
If the first argument is a server, send all players from that server. Servers take priority in the case a player and server share a name.
2015-07-13 19:32:12 +10:00
Daniel Naylor
f3c14cf064 Fix telling newer 1.7 Forge clients that they are outdated. Fixes #1476
* Only check the version of FML if we are running Minecraft 1.7.10 - 1.8 clients are always valid.
* If the version of FML that is reported is 7.10.99.99 - report the Forge version instead.
2015-07-10 12:33:22 +10:00
Marc Baloup
a3a31fd2dd Correct handling of command's parameters for tab completion
Hi :)

There is some problem with TabExecutor and I think I found the problem.

Exemple :
/send <playerName|all|current> <targetServer>
When I write "/send " (with trailing space) and press Tab, I don't have any suggestion. But when I wrote the first character of an online player, it suggest all players which start with this same character (expected behavior)

The problem is the same when I wrote "/send marcbal " (with trailing space). When I press Tab key, I have "marcbal" suggested instead of servers suggestion. (the result is "/send marcbal marcbal"). But when i wrote the first character of a server name, it suggest all servers which start with this same character (expected behavior)

other exemple : there is 2 players online in the same server : me (marcbal) and marcbaleeee (for exemple)
when I wrote "/send marcbal " (with trailing space) and I press Tab key, I have the suggestion of the 2 player names.

I deduced that the onTabComplete() don't care about the trailing space of the command string (exemple : "/send marcbal ") and probably a problem when splitting (removing last trailing empty args), so, the onTabComplete method try to complete the first argument "marcbal" instead of the second empty argument.

To split the command line, you use the method Pattern.split(CharSequence) that remove trailing empty strings http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#split(java.lang.CharSequence)
So, we should use the other split() method, with a second argument which has to be a negative integer value. (see Javadoc)

PS : Sorry for my bad english x)
2015-07-10 12:28:26 +10:00
md_5
cc3a8c067e Check channel active before adding handlers. #1489 2015-06-06 18:41:54 +10:00
Joe
918d7229c2 Fix Deadlock in EventBus post #1493 2015-06-05 13:03:43 +10:00
sha-2
6c4e684de9 Move the compiler configuration to properties 2015-05-31 10:51:49 +10:00
minecraftshamrock
9cf57ca929 Fix AsyncEvent callback triggering.
Before this, two concurrent postCall() and completeIntent() calls might
cause the callback to be called more than once.
2015-05-18 20:22:32 +10:00
Adam
70564d9f44 Fix BaseComponent.duplicate() ignoring extra 2015-05-18 20:18:57 +10:00
Nathan Poirier
8622cf3af4 Fix BadPacketException handling It is catched by DecoderException and was not processed correctly by HandlerBoss So the console was spammed when that exception is thrown 2015-05-18 20:18:19 +10:00
Nick
5236dd301a Use an actual ArrayList when creating a TextComponent with extras.
Arrays#asList returns a java.util.Arrays.ArrayList which does not support adding more elements.  This previously broke BaseComponent#addExtra.
2015-05-18 20:16:45 +10:00
md_5
ddfd76ebda Make MinecraftDecoder a MessageToMessageDecoder 2015-05-18 20:16:12 +10:00
Thinkofdeath
93959cab4b Only force remove the player from 1.8 client's tab list 2015-05-10 22:51:14 +01:00
Thinkofdeath
585ab4f453 Readd the delay removed in f9773a69c3 2015-05-08 20:41:21 +01:00
Thinkofdeath
76052b92d3 Don't send a Kick during the STATUS protocol as it doesn't support it 2015-05-08 20:32:12 +01:00
Thinkofdeath
f9773a69c3 Don't send a kick to the server on disconnect
This was dropped from the protocol in 1.6 and was left in bungee by
mistake
2015-05-08 19:39:22 +01:00
Tux
88e71ead05 Add reset() and retain() methods to ComponentBuilder.
This method is simple: it resets the current part to default settings, keeping only the current text. It therefore acts like the old ChatColor.RESET
code. The retain method allows for more control over what is reset.

Add a test to verify proper functioning of reset()/retain().
2015-05-06 09:57:48 +01:00
md_5
d1e1ce4cdb Add option to disable native code. 2015-05-03 10:35:48 +10:00
md_5
fa828eba31 Allow using properties to change leak detection level. 2015-04-13 09:51:31 +10:00
Thinkofdeath
d76c8d4f33 Ensure the copy is freed if an exception occurs during parsing packets 2015-04-12 01:47:10 +01:00
Thinkofdeath
a48c458306 Don't send bungeecord plugin messages to the client 2015-04-08 18:22:16 +01:00
portalBlock
3973c511f5 Show the no permission message even if the command is a TabExecutor but the command was not dispatched by the tab completer. 2015-03-22 13:54:05 +11:00
Jonas Konrad
78ea41015f Fix component deserialization on obfuscated and strikethrough tags 2015-03-16 20:24:37 +11:00
Thinkofdeath
bd2eaf6879 Add missing scoreboard positions (Fixes #1397) 2015-03-12 16:42:01 +00:00
Thinkofdeath
f2d17cb216 Follow vanilla and kick the joining user on connect if the name is already taken (Fixes #1383) 2015-02-28 13:07:13 +00:00
md_5
f2673c5876 Kick only in online mode: #1382 2015-02-28 13:00:04 +11:00
Thinkofdeath
e1951c5d66 Fix spectator mode with ip-forwarding enabled 2015-02-25 22:31:05 +00:00
Thinkofdeath
988490ba87 1.8 isn't a snapshot anymore 2015-02-25 22:27:50 +00:00
md_5
62981e4c70 Downgrade netty to work around #1372 2015-02-15 10:27:30 +11:00
md_5
5699e86270 Looks like Jenkins may be having lombok issues with the new version. 2015-02-14 19:09:19 +11:00
md_5
61cee2d27c Fix formatting in a bunch of files. 2015-02-14 18:36:58 +11:00
md_5
2055c98ebe Add reason for stopping and extra arguments. 2015-02-14 18:33:49 +11:00
Joshua Rodriguez
415d5860e4 Allow setting a connections uuid when in offline mode 2015-02-14 18:33:28 +11:00
md_5
3776feb559 Don't allow duplicate UUIDs on the proxy. 2015-02-14 18:26:27 +11:00
Jonas Konrad
668cdabdf7 Fix BaseComponent.toString stack overflow 2015-02-14 18:21:43 +11:00
md_5
3e26eecd4e Fix formatting issue pointed out in #1370 2015-02-14 18:21:24 +11:00
md_5
7c1f232e85 Update depend versions, limit use of most Java 1.7 APIs. 2015-02-08 13:07:41 +11:00
md_5
2b49358bea Fix EventBus unit test. 2015-02-08 12:48:26 +11:00
md_5
b4997f6379 Add better exception handling for native code. 2015-02-08 09:11:52 +11:00
md_5
eeaa44e1e7 #1362: Tighter catch on errors in native lib compilation. 2015-02-08 08:08:20 +11:00
md_5
f4ae511af0 2 megabytes is sufficient for testing purposes. 2015-02-07 14:19:33 +11:00
md_5
32693aeaff Don't compile with the stdlib, I don't think it is needed. 2015-02-07 14:14:33 +11:00
md_5
0d569ac0d1 Refactor native code and implement our own JNI wrapper around zlib.
The previous native cipher code has been refactored so that it may be loaded and used slightly more generically, allowing more native components to be easily added as time goes on.
I have also written a new native code compression module, which wraps around zlib in the same manner that Inflater / Deflater does, however it operates directly on the memory addresses of it's input / output buffers which means that we can save one, or maybe even two copies. To support this, the VarInt decoder has been adjusted to always use a native buffer.
2015-02-07 14:06:41 +11:00
Thinkofdeath
e6da9cbba8 Manually reset the networkaddress.cache.ttl value to the defaults (Fixes #1268)
When searching for the networkaddress.cache.* values java will default to these
values when it can't find a manually set value, however if a security manager is
in place then as a special case java will set the cache lifetime to infinite.
Manually setting the values solves this issue.
2015-02-04 08:50:52 +00:00
md_5
61d2765715 Only check name for server reload modification. 2015-01-24 13:34:38 +11:00
portalBlock
e68ed48fc3 Use the cached constructor when instantiating a packet. 2015-01-22 18:25:45 +11:00
md_5
cf722de1d2 #1130: Add scheduler unit tests and make more robust. 2015-01-18 12:09:38 +11:00
Daniel Naylor
28496e0471 Add API for getting whether the user is a Forge user.
For Minecraft+Forge 1.8 we can detect whether the user is a Forge user before we get the mod list, due to the changes to the initial (not FML|HS) handshake that are now made (which is for vanilla client support). Bungee can exploit this to detect FML clients from the off, but it still does not tell us what the mod list is. Thus, creating this API method for users who simply need to know whether the user is connected via FML is no longer a duplication of the getModList api method.
2015-01-12 19:23:07 +11:00
Daniel Naylor
4809f1f80a Update IP forwarding to ignore FML and other null character delimited tokens (for now)
For Forge 1.8, a new \0FML\0 token is included in the handshake packet host field. Whilst from a Forge <-> Bungee standpoint, this is good in the long run (we can detect Forge/FML clients right from the off, allowing us to expose a reliable API for detecting modded 1.8+ clients), it plays havoc with IP forwarding on Spigot servers, as they expect a very specific format.

Until we can look at improving this situation (probably by creating an updated IP forwarding protocol on the server side), this removes the FML marker from the handshake whenever IP forwarding is on. If you have a FML 1.8 network, IP forwarding MUST be off.

With thanks to @geNAZt for finding the issue.
2015-01-12 19:23:07 +11:00
Tux
ae12554316 Faster Travis CI builds
See http://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/
2015-01-12 11:55:09 +11:00
xxyy
5091515f0b Add TabCompleteResponseEvent 2015-01-12 11:53:28 +11:00
md_5
52b75cd18b Don't nuke command on tab complete if no args specified. 2015-01-12 11:07:43 +11:00
md_5
a5f2b423d4 #1325 - Fix /server with extra args. 2015-01-12 11:07:32 +11:00
mrapple
54c9ade1a6 Move mojang translations to chat module, fixes SpigotMC/BungeeCord#1301 2014-12-23 19:23:24 +11:00
md_5
bc6d7719a7 Finish single argument for command server tab completion. 2014-12-22 20:14:20 +11:00
md_5
2ab0715226 Fix server command to properly tab complete, be case insensitive. 2014-12-22 20:02:19 +11:00
md_5
1711223b02 Use string lists in preference to string arrays. 2014-12-22 19:59:14 +11:00
md_5
cd15b82361 Compile chat API with 1.6 2014-12-16 16:09:25 +11:00
zreed
22084b2c75 Try loading native cipher from java.library.path first 2014-12-16 13:21:25 +11:00
Tux
972b4c1fe5 Further fix task clean up issues by moving the BungeeScheduler's cancel(ScheduledTask) method to just call the cancel() method on the task. The cancel call was moved to BungeeTask's cancel method.
This patch makes the patch transparent to existing callers using cancel(ScheduledTask) from the scheduler. It also simplifies some logic in BungeeTask itself.
2014-12-14 17:18:49 +11:00
Tux
36c4af35de Fix issues cleaning up after repeating tasks.
A mass of NullPointerExceptions would be outputted when tasks were stopped. This is resolved by checking if we are still running (indicating a possible scheduler cancel) before telling the scheduler to pull the plug.

Ideally, the entire BungeeCord scheduler should be rewritten. It has quite a few issues which could be avoided with a new system.
2014-12-14 17:18:49 +11:00
md_5
02d3660f32 Fix fancy terminal on Windows.
This is a workaround for quite possibly the weirdest bug I have ever encountered in my life! When jansi attempts to extract its natives, by default it tries to extract a specific version, using the loading class's implementation version. Normally this works completely fine, however when on Windows certain characters such as - and : can trigger special behaviour. Furthermore this behaviour only occurs in specific combinations due to the parsing done by jansi. For example test-test works fine, but test-test-test does not! In order to avoid this all together but still keep our versions the same as they were, we set the override property to the essentially garbage version BungeeCord. This version is only used when extracting the libraries to their temp folder.
2014-12-14 13:07:13 +11:00
md_5
37e37e9a55 Fix timestamp format.... 2014-12-13 11:53:03 +11:00
md_5
a03c21cc09 Tweak outdated timers a little. 2014-12-13 11:14:16 +11:00
md_5
45bf7a9ab9 Move ansi console system install right into the bootstrap. 2014-12-13 11:13:40 +11:00
Thinkofdeath
ef364d9053 Actually put the tasks in the tasksByPlugin Multimap (Fixes #1278) 2014-11-26 16:42:45 +00:00
Minecrell
f19cc7fe4f Add chat position API. 2014-11-22 09:17:37 +11:00
Minecrell
772c8d7f2b Improve legacy client ping support. 2014-11-15 10:18:40 +00:00
Thinkofdeath
830f18a357 Manually remove the player from everyone's tab list on disconnect
This is needed because when the player disconnects from bungee they are removed from the connection map, this causes the tab-list rewrite to fail due the player no longer being on bungee and therefor it ends up not removing the player (online vs offline uuid). This would only happen on servers without ip-forwarding enabled
2014-11-11 10:33:22 +00:00
elmo92
c21275b877 Don't send no permission message on tab completion.
Instead returns the empty completions.
2014-11-08 10:08:42 +11:00
md_5
532a94382b Block really wrong offline mode names, see #1270 2014-11-08 10:04:59 +11:00
md_5
56c372a3ce Fix HTTP client now that Mojang has their stuff together. 2014-11-08 10:02:48 +11:00
Minecrell
faf903469e Add methods to load configurations with defaults.
Add Configuration constructor for empty configurations.

Use defaults for the Configuration object getter.
2014-10-17 20:37:59 +11:00
Daniel Naylor
4d389df7c8 Be more selective when sending reset packets.
Always send the packet when going from modded -> anything, send the packet later when going from vanilla -> modded, never send it on a vanilla -> vanilla switch.
2014-10-17 20:37:10 +11:00
Daniel Naylor
cfad2c65d4 Implement Support for MinecraftForge / FML 1.7.10
Additional implementation help provided by @jk-5 and @bloodmc.
2014-09-27 19:38:28 +10:00
md_5
8715c5fd82 Actually update translations to 1.8 2014-09-27 08:25:36 +10:00
md_5
cbb190cfd3 Fix a few import ordering issues. 2014-09-26 10:11:16 +10:00
md_5
acf5f2f443 Fix bootstrap Java 7 warner so that it actually works! 2014-09-25 11:13:23 +10:00
md_5
57a07dc2e2 Update Depend Versions:
Guava 17.0 -> 18.0
Lombok 1.12.6 -> 1.14.8
Gson 2.2.4 -> 2.3
SnakeYaml 1.13 -> 1.14
2014-09-25 11:05:21 +10:00
Minecrell
6fcfb5aecb Add more message arguments. See #1214. 2014-09-25 10:53:41 +10:00
md_5
4e3b5670a0 [#1224] Add connect / read timeout for module download incase Jenkins is down. 2014-09-25 10:52:16 +10:00
md_5
ee3b209c2d Declare game version support as 1.8 2014-09-25 10:49:20 +10:00
md_5
25ee8a1496 Revert "Revert "Update Mojang translations to 1.8""
This reverts commit dd1a28ea1e.
2014-09-25 10:47:27 +10:00
md_5
988905331f Force javadoc plugin 2.7 2014-09-25 10:47:17 +10:00
md_5
dd1a28ea1e Revert "Update Mojang translations to 1.8"
This reverts commit 5ec36efb52.
2014-09-25 10:41:40 +10:00
md_5
0a0146b68a [#1219] Fix Title#reset javadoc link 2014-09-25 10:30:52 +10:00
md_5
ca2227bad4 [#1212] Clarify Javadoc of ServerConnectEvent 2014-09-25 10:23:52 +10:00
md_5
3cd4f169bd [#1191] Stop getPermissions from creating blank groups. 2014-09-25 10:21:15 +10:00
md_5
5ec36efb52 Update Mojang translations to 1.8 2014-09-25 10:18:29 +10:00
md_5
dcc9be9dfe [#1218] Check which player instance we remove from the connection maps.
Legitimate but slightly sneaky fix for the issue of racing for addition / removal. An alternate fix would be a multimap.
2014-09-12 18:45:50 +10:00
md_5
efdedbd4e8 Trove should not be a core depend. 2014-09-12 18:24:14 +10:00
Thinkofdeath
1623fb6952 Only update the dns cache on new lookups (Fixes #1221)
This causes the cached entry to be looked up every 5 minutes instead of the previous system where it was kept as long as it was used. This fixes an issue where after Mojang's session servers go down the ip address tends to change. This caused bungee to repeatedly hit the old (inactive) one which with the previous system would be re-cached every time someone tried to connect
2014-09-11 10:18:34 +01:00
Minecrell
4e353e9277 Add Title API. 2014-09-07 09:30:57 +01:00
Minecrell
d6b7157c1c Add player list header / footer API. 2014-09-07 09:26:52 +01:00
Steve Anton
bc48ab3fb8 Make ProxyPingEvent async 2014-09-07 12:03:55 +10:00
Thinkofdeath
65ae8b4c6a Correctly send the MC|Brand packet 2014-09-02 13:54:52 +01:00
Thinkofdeath
73d7e0cf99 Bump protocol to 1.8 2014-09-02 09:44:07 +01:00
md_5
2cec5f344a Update versions to 1.8... oops 2014-09-01 16:56:03 +10:00
md_5
4573285a70 Fix build expiration. 2014-09-01 16:47:16 +10:00
md_5
5282a8f45a Just use server specific tab lists for now. 2014-08-31 19:18:19 +10:00
md_5
6eedc77954 Remove javadoc / delombok for now, interferes with build process. 2014-08-31 19:05:51 +10:00
md_5
f15eed338d Fix tab list 2014-08-31 19:01:24 +10:00
md_5
faa284c8fc Move chat API into own submodule. 2014-08-31 18:56:03 +10:00
Thinkofdeath
4bb3850b40 Fix another missed offline mode case 2014-08-31 09:34:31 +01:00
Thinkofdeath
1f132876e6 Handle offline mode in the tab list 2014-08-31 09:25:31 +01:00
md_5
c822c48fef Add BungeeCord to the outdated ping message. 2014-08-31 18:23:45 +10:00
Thinkofdeath
26521cf2ff Add support for Minecraft 1.8.x
This commit allows BungeeCord to support Minecraft clients both of versions 1.7.x and of 1.8.x. There should be no breakages to any other support, however following their deprecation and uselessness within 1.8, the Tab list APIs have been removed.

Please report any issues to GitHub and be sure to mention client, server and BungeeCord versions.

When used with an appropriate server jar (such as multi protocol Spigot), this will allow clients of many versions to concurrently be connected to the same set of servers.
2014-08-31 09:03:12 +01:00
md_5
e99bbff22e Fix Javadoc for Jenkins... maybe 2014-08-31 13:53:53 +10:00
md_5
19b48672af Fix longstanding forward typo 2014-08-31 10:13:50 +10:00
md_5
f81b8a3550 Use delombok for JavaDoc generation, #1188 2014-08-31 10:12:11 +10:00
md_5
87797ef719 Fix slight JavaDoc formatting issue. 2014-08-31 09:27:59 +10:00
Thinkofdeath
86c5e321f2 Disable epoll by default due to timeouts its causing
Anyone who wants to continue testing epoll for us may do so with `-Dbungee.epoll=true`
2014-08-21 08:11:11 +01:00
mrapple
41ccf3f9d3 Fix LoginEvent firing after PreLoginEvent is cancelled 2014-08-19 22:43:05 +01:00
Thinkofdeath
e573f7b89c Correct toLegacyText the same way toPlainText was previously 2014-08-17 18:50:28 +01:00
Minecrell
664c66fb97 Ignore unknown entries in plugin description files.
Fixes #955.
2014-08-17 19:58:15 +10:00
md_5
caa562c4a1 Final nail in the coffin for xxx cannot be cast to yyy bug. 2014-08-17 09:54:37 +10:00
md_5
483805067d Update Netty and enable Epoll as bugs have been fixed. 2014-08-17 09:52:59 +10:00
Tux
5e0aa2e60d Finalize the ServerDisconnectEvent target field.
There is no good reason for it to be mutable in the first place, considering that the event instance is not used after the method is called.
2014-08-17 09:34:06 +10:00
IfarPL
f9f9c3213d Added 'ForwardToPlayer' subchannel 2014-08-16 20:20:54 +10:00
Thinkofdeath
be35e283ec Revert "Mojang allows multiple status queries in a connection, we should too."
This reverts commit 77f6930280.
2014-08-11 23:17:31 +01:00
md_5
dd9bd2a2e3 Shuffle Jansi/Jline versions 2014-08-04 18:19:35 +10:00
md_5
3188d946b3 Fix javadoc 2014-08-04 16:15:46 +10:00
Ad237
072e360d0f Add KickPlayer subchannel
Can be used to kick a player who is on a different server
2014-08-03 18:13:39 +10:00
md_5
ee3efd75d7 Change a few aspects from last PR 2014-08-03 18:12:44 +10:00
Jonas Konrad
d85400bc69 Add forward parameter to only forward to online servers [Adds #1120] 2014-08-03 18:10:38 +10:00
Jonas Konrad
b544bb34cb Add ServerInfo method to send plugin message only if server is online 2014-08-03 18:10:38 +10:00
Gabscap
8676dd47f6 Disable plugins in reverse order 2014-08-03 18:09:18 +10:00
Melair
089a8dd311 Allow customisation of kicking during initial server connection. In particular allow removal of server name by modification of messages.properties. 2014-07-30 19:16:19 +10:00
Thinkofdeath
d1d4cc7bbf Tidy up the handling of Spawn Object and fix a off by one error with it 2014-07-30 09:26:17 +01:00
Thinkofdeath
74f5ffd08b Duplicate any extra components when duplicated 2014-07-25 13:22:58 +01:00
Joshua Küpper
9fc862cb74 Make ComponentBuilder clonable 2014-07-25 13:22:54 +01:00
md_5
0d174b51c5 Clarify PreLoginEvent 2014-07-22 20:27:46 +10:00
md_5
1b18e64fb2 Handle objective value changes. Although the client *shouldn't* be using this for any sort of keying, it may indeed be. Closes #1116 awaiting testing. 2014-07-22 20:24:38 +10:00
Isaias
c42d3a375f Fix uniqueId returning null in LoginEvent 2014-07-21 13:49:45 +01:00
Thinkofdeath
fc0a21f548 Correct a typo in Spawn Object rewriting 2014-07-21 09:48:21 +01:00
md_5
65eba06980 Don't let Bungee run in dirs with ! in name.
Java uses ! to indicate a resource inside of a jar/zip/other container. Running Bungee from within a directory that has a ! will cause this to muck up.
2014-07-19 21:22:20 +10:00
md_5
87a64c3f3e Fix locale object getter, closes #1113 2014-07-16 17:13:56 +10:00
md_5
be13a00386 Add missing return - closes #1114 2014-07-16 17:12:52 +10:00
md_5
949f150ea0 Fix some out of style formatting. 2014-07-12 19:50:56 +10:00
md_5
c965e60f5e Cipher thread locals should be static 2014-07-12 19:49:12 +10:00
Thinkofdeath
02e219262a Fix TranslatableComponent's handling of missing translations 2014-07-12 10:34:24 +01:00
Thinkofdeath
a0e8b172ef Restrict access to some internal methods. 2014-07-12 19:33:04 +10:00
md_5
215b70dcd7 Fix some more things picked up by static analysis. 2014-07-12 19:30:00 +10:00
md_5
a6095c680f [#1111] Ignore scorebaord objective action 2 like we did before 2014-07-12 17:33:57 +10:00
md_5
9d5c886045 Fix some more static analysis warnings 2014-07-12 14:01:06 +10:00
md_5
19bb8f72c7 Fix some static analysis warnings. 2014-07-12 13:33:13 +10:00
md_5
4dfd510583 Override context specific permission check 2014-07-10 13:56:59 +10:00
md_5
705b554b3b Add basis of grouped thread factory and make the scheduler use it. 2014-07-10 11:18:42 +10:00
md_5
6615500f08 Block all of java, not just java.lang 2014-07-10 10:50:00 +10:00
md_5
d63d5a2791 <yawkat> is that debug code i spot md_5? 2014-07-10 10:42:55 +10:00
md_5
2444dd15ab Fix #1106 - plugins using ssl throwing exceptions 2014-07-10 10:39:58 +10:00
md_5
2dd3d2101d Close #1105 - don't let security manager get replaced 2014-07-09 09:41:19 +10:00
md_5
8ce26e0370 Pass plugin into executor getter for future proofing 2014-07-08 15:53:25 +10:00
md_5
5d1b660e32 Implement Security Manager
This commit adds the basis for the intergration of a security manager into BungeeCord. The goal of the security manager is to prevent plugins from doing potentially dangerous or otherwise undesirable behaviour that may damage the stability of Bungee itself or pose a risk to the user's server.

One common theme in some Bungee plugins, especially those which were written in the very early days, is using Threads and ExecutorServices for scheduling purposes. Not only is this inefficient as there is no use of the thread caching features provided by the scheduler, it is also difficult to track who created which thread. Additionally creating threads not managed by the BungeeCord scheduler poses issues for when|if a plugin reload system is implemented, as these threads cannot be appropriately cleaned up and may continue to leak class references or perhaps even continue executing.

At this stage the SecurityManager is set to warn of prohibited actions, but not block them. For some plugins using external APIs, where usage of an ExecutorService is unavoidable, we have included an Unsafe interface to the scheduler which allows direct access to the underlying ExecutorService, or potentially a compatability wrapper.
2014-07-08 15:22:26 +10:00
md_5
7347daf203 Delay kicks in initial handler.
See source for reasoning
2014-07-08 15:16:22 +10:00
md_5
02cb1fc65b Allocate cipher with EVP_CIPHER_CTX_new. Thanks @Adam- for the tip. 2014-07-02 12:57:17 +10:00
md_5
7318750ed0 Update native cipher to make use of the OpenSSL EVP API so that it can actually utilise hardware acceleration and other goodies.
Whereas before OpenSSL would often lose benchmarks now it always wins.
2014-07-01 20:13:30 +10:00
md_5
21be93a1b1 [#1094] Remove config values set to null, add unit test for such behaviour. 2014-07-01 13:40:17 +10:00
md_5
bb69af5cd0 Disable epoll whilst we try to replicate some issues 2014-06-29 09:22:34 +10:00
Minecrell
a668da76d0 Write log messages with lower levels to the log file. 2014-06-29 09:13:16 +10:00
thinkofdeath
4cc009a9c0 Merge pull request #1089 from yawkat/typo-0
Fix typo
2014-06-28 14:04:10 +01:00
Jonas Konrad
4ef58d53b1 Fix typo 2014-06-28 13:45:26 +02:00
Jonas Konrad
afa37505c5 Fix javadocs for java 8 doclint 2014-06-28 09:05:50 +10:00
md_5
a53b63720b Add a comment 2014-06-26 19:24:05 +10:00
md_5
348457f613 Quickly test SO_REUSEADDR 2014-06-26 19:19:11 +10:00
md_5
fbb2f695b0 Show correct error when cannot bind query 2014-06-26 19:08:05 +10:00
md-5
350cbd7bb6 Merge pull request #1080 from RuriRyan/master
Fixed RemoteQuery, which broke with the Epoll update
2014-06-26 11:38:42 +10:00
RuriRyan
489242b1ef Fixed RemoteQuery, which broke with the Epoll update 2014-06-25 23:29:08 +02:00
md_5
4ac117fb4c Actually include native code, thanks again @normanmaurer 2014-06-25 18:21:59 +10:00
md_5
500b0af782 [Performance] Attempt to use Netty's Epoll implementation on Linux.
This will attempt to make use of Netty's EpollEventLoopGroup and Epoll(Server)SocketChannel when on Linux and the native libraries load correctly. It should bring a large increase in performance and hopefully reliability. Big thanks to the @netty team for implementing this and @normanmaurer for some tips on the support detection.

Feedback is appreciated.
2014-06-25 18:14:50 +10:00
md_5
2b304ecebc Close plugin log handlers on disable 2014-06-24 18:22:35 +10:00
md_5
81d83bdd8a Calling parent logger seems to work nowadays - closes #1071 2014-06-24 18:21:13 +10:00
md_5
b9f2f3cfae Add a getKeys method to the Configuration API 2014-06-24 16:59:15 +10:00
md_5
923aa05d4a Downgrade forced hosts errors to a warning log level 2014-06-24 16:56:24 +10:00
md_5
e54388a5e0 Add matchPlayer API 2014-06-23 17:26:30 +10:00
md_5
59ba644623 Make IP command tabbable - closes #999 2014-06-23 17:16:14 +10:00
md_5
fbc69543fd Reset yaml locations on any error, closes #1007 2014-06-23 17:13:41 +10:00
maciekmm
4d1f0cbb26 Added getKickedFrom() to ServerKickEvent. 2014-06-22 17:11:27 +10:00
md_5
e849afbb23 Add simple address cache for those with slow or otherwise unresponsive DNS servers.
I wonder when @netty was supposed to add async dns lookups.
2014-06-20 20:04:22 +10:00
Moehritz
1a7efeabc4 Fix unregisterCommand(s) - second try 2014-06-20 19:43:36 +10:00
Gabscap
f6e41c856c Closing all handlers on stop() 2014-06-20 19:28:01 +10:00
md_5
151344aaff Fix typo in unused readUnsignedByte method of MinecraftProtocol 2014-06-20 19:26:34 +10:00
md_5
b167a45690 Revert "Reenable throttle since we only support 1.7+"
This reverts commit f23691df23.
2014-06-13 16:25:53 +10:00
vemacs
31bd836203 Write server name in ServerIP subchannel response.
Behaves similarly to the UUIDOther implementation.
2014-06-11 16:13:32 +10:00
Jonas Konrad
4dce37cd13 Prefix "BungeeCord > " to forwarded MC|Brand messages [Fixes #1038] 2014-06-11 16:12:30 +10:00
xxyy
107d6b011d Fix ServerPing NPE w/ String favicons
Currently, passing a null favicon String to the ServerPing(Protocol, Players, String, String) constructor causes a NPE. However, passing a null `Favicon` object to the corresponding constructor does not cause one. Setting the favicon String using the setFavicon(String) method doesn't cause a NPE either.

Therefore, the NPE thrown by the constructor is inconsistent and should be avoided. Please find a sample NPE here: http://newpaste.md-5.net/pmtqjc8vl (Note the `null` favicon)

This PR changes the documented (unintended?) behaviour by adding a null check before passing the favicon String to the alternative `Favicon` object constructor. This makes the constructor consistent with the other one and the `setFavicon(String)` method. This also adds compatibility for old (made before Favicon API) plugins passing `null` favicon Strings (and expecting no favicon to be displayed instead of a NPE).

Thanks!
2014-06-11 16:09:20 +10:00
md_5
f23691df23 Reenable throttle since we only support 1.7+ 2014-06-11 16:08:33 +10:00
md_5
77f6930280 Mojang allows multiple status queries in a connection, we should too. 2014-06-11 16:07:14 +10:00
md_5
9604a9a31e Show 1.7.9 as supported version 2014-06-11 16:05:07 +10:00
md_5
91989564e5 Add method to get player's locale 2014-06-11 16:03:10 +10:00
Thinkofdeath
3c938c03c7 Fix BaseComponent calling the wrong method when inheriting from another BaseComponent (Fixes #1049) 2014-06-08 13:07:42 +01:00
md_5
9226df86f0 Lazy init vhost address. 2014-05-31 18:46:35 +10:00
md_5
00db351dd6 Deprecate tab list API - it will be removed in Minecraft 1.8 as the updates by Mojang render it useless. 2014-05-25 09:19:34 +10:00
md_5
ad2ff54b76 Bump a few versions, should probably think about exposing the new EPollEventLoop. 2014-05-15 17:07:31 +10:00
md_5
ece641da23 Change lobby to fallback in fallback_lobby translation. 2014-05-03 17:31:19 +10:00
Jonas Konrad
2af8dac70c Pull up getFaviconObject to the API 2014-05-03 17:29:48 +10:00
Thinkofdeath
33a098f4ba Merge branch 'vemacs-master' 2014-05-01 11:00:12 +01:00
vemacs
e4e01ccb55 Null check 2014-05-01 10:59:14 +01:00
thinkofdeath
6c9e6abc9f Merge pull request #1004 from GunfighterJ/master
Correct the shutdown message
2014-04-26 19:48:03 +01:00
GunfighterJ
84c7e073e0 Grammar Nazi 2014 2014-04-26 13:44:59 -05:00
Thinkofdeath
9e46739343 Improve the CommandServer tooltip
Includes the grammar fix from #953
2014-04-25 20:53:10 +01:00
thinkofdeath
8fe72383a1 Merge pull request #1002 from yawkat/server-info-tostring
Add toString for BungeeServerInfo
2014-04-25 20:33:37 +01:00
Jonas Konrad
a56bbe38b2 toString for BungeeServerInfo 2014-04-22 15:24:18 +02:00
md_5
312a74c5f1 Close #963 - log remote ping errors to console, friendly message to clients. 2014-04-19 19:48:43 +10:00
vemacs
71c86f9f90 Add ServerIP subchannel 2014-04-18 10:33:26 -06:00
Thinkofdeath
6475385f87 Use ProtocolConstants instead of raw protocol numbers 2014-04-16 14:57:09 +01:00
Thinkofdeath
6775b9230c Update Team packet's field names. unknown -> nameTagVisibility, unknown2 -> color 2014-04-16 14:46:48 +01:00
Thinkofdeath
c8e6b6fd7a Add 'Combat Event' to 14w11a's EntityMap 2014-04-16 14:34:30 +01:00
Thinkofdeath
bca3663a1f Add 'Camera' to 14w11a's EntityMap 2014-04-16 14:26:11 +01:00
Thinkofdeath
f71272a1c0 Add 14w11a EntityMap support 2014-04-16 11:56:04 +01:00
Thinkofdeath
ca7c755ecd Split up EntityMap into different protocol versions 2014-04-16 11:14:29 +01:00
md_5
5a638f2290 Enable 14w11 support, changing servers is a bit iffy though due to EntityMap not being complete. 2014-04-16 11:01:41 +10:00
md_5
3715756be7 Update packets for MINECRAFT_14_11_a 2014-04-16 10:48:40 +10:00
md_5
1a1a51b38d Replace direction strings with concrete enums 2014-04-16 10:28:07 +10:00
md_5
bc2b4db419 Replace literal numbers with usages of the ProtocolConstants class. 2014-04-16 10:18:16 +10:00
Jonas Konrad
994a996981 Fix NPE while encoding when favicon was missing 2014-04-15 20:17:26 +10:00
Jonas Konrad
e2eba52162 Revert "Revert "Implement Favicon API""
This reverts commit 13decac4b9.
2014-04-15 20:17:26 +10:00
md_5
13decac4b9 Revert "Implement Favicon API"
This reverts commit 18316eb5f8.
2014-04-15 15:08:12 +10:00
md_5
7ebe5184a4 Clarify favicon.create javadoc 2014-04-15 11:11:11 +10:00
md_5
b08f1995f6 Return most recent protocol version to 'unsupported' server lists 2014-04-15 11:08:28 +10:00
Keir Nellyer
a642346a2c Add method to get a connected player via their UUID 2014-04-15 11:07:17 +10:00
Jonas Konrad
18316eb5f8 Implement Favicon API 2014-04-15 11:05:20 +10:00
md_5
3ced0b675d Implement Skin forwarding - YOU MUST UPDATE SPIGOT FIRST 2014-04-15 10:38:15 +10:00
md_5
66a70fef5b Add #983 - disabled commands for players only. 2014-04-14 16:24:16 +10:00
md_5
dc2da29c16 Code format. 2014-04-13 14:15:41 +10:00
Thinkofdeath
3b71a2b570 Fix ping decoding (Fixes #969) 2014-04-13 00:07:11 +01:00
Thinkofdeath
1aa5379030 Handle new clients pinging old versions (Fixes #972 and Fixes #969) 2014-04-12 10:16:58 +01:00
Thinkofdeath
153bca00be Fix 1.7.7 support 2014-04-10 13:34:08 +01:00
Thinkofdeath
747628f40c Remove @RequiredArgsConstructor from PlayerInfoSerializer as the javadoc fails to build with it 2014-04-09 21:01:33 +01:00
Thinkofdeath
bf9521472b Support setting uuid's on ServerPing.PlayerInfo + fix plugins which don't provide a valid uuid. 2014-04-09 20:26:07 +01:00
Thinkofdeath
86ef046544 Pass the protocol version through when using ping pass through 2014-04-09 16:42:08 +01:00
Thinkofdeath
cd518690fd Rewrite the spawn player packet's uuid to support skins on non ip-fowarded servers 2014-04-04 12:14:04 +01:00
Thinkofdeath
1d3adc5317 1.7.6-pre1 Support 2014-04-04 21:42:10 +11:00
Keir Nellyer
13848def72 Return a Users UUID as a UUID object whilst keeping support for returning as a String 2014-04-04 21:35:07 +11:00
Keir Nellyer
a4dd0dba88 Allow 'softdepends' in plugin description 2014-04-01 19:55:59 +11:00
md_5
e025ad8ed7 Bump netty from 4.0.14 -> 4.0.17 2014-04-01 14:36:19 +11:00
Alex Ivanov
720f5df2f4 Use correct padding for UDP queries 2014-04-01 14:33:46 +11:00
md_5
52bf6184c7 Don't disable find by default 2014-03-30 15:53:57 +11:00
md_5
f7a5748464 Delay event loop initialization until after system properties are set. Closes #943 2014-03-29 15:21:04 +11:00
md-5
61e3d27ae9 Add more Java versions to Travis 2014-03-20 20:15:33 +11:00
md_5
1bbbfdb0d5 Close #938 - re add our register channel manipulation 2014-03-20 20:12:06 +11:00
thinkofdeath
a8584f81ed Merge pull request #935 from yawkat/fix-legacy-convert-npe
Fix NPE when converting invalid color character from legacy text (Fixes #934)
2014-03-15 19:24:00 +00:00
Jonas Konrad
5ae2e24c84 Fix uppercase color codes 2014-03-15 20:19:48 +01:00
Jonas Konrad
c29676e4fc Fix NPE when converting invalid color character from legacy text 2014-03-15 19:56:19 +01:00
Jonas Konrad
92ebce2ec6 Add TabCompleteEvent 2014-03-14 20:51:47 +11:00
kamcio96
9cd7c1ac03 Add ProxyReloadEvent 2014-03-14 20:49:45 +11:00
md_5
924dcaab38 Move default server fallback 2014-03-14 19:29:13 +11:00
md_5
8502ab54c0 Revert "Fix #872 - use default server if forced host not found, OR force default is set."
This reverts commit 1fb7a3bf1d.
2014-03-14 19:27:51 +11:00
md_5
3301c95066 Revert "Rejig forced hosts some more - closes #927"
This reverts commit 72cadac76e.
2014-03-14 19:27:46 +11:00
Thinkofdeath
49f4dcb5b7 Ensure we have the capacity to resize the buffer 2014-03-13 19:51:46 +00:00
Thinkofdeath
13d679e7d7 Correctly resize the spawn object packet 2014-03-13 19:30:27 +00:00
md_5
72cadac76e Rejig forced hosts some more - closes #927 2014-03-13 13:32:48 +11:00
md_5
227301ec73 Don't throw full exception on bad magic 2014-03-13 07:40:22 +11:00
Maciej Mionskowski
f2b0e3e3c3 Fixed config saving and value setting. Probably fixes #798 2014-03-11 15:21:31 +11:00
md_5
575a6b6ea0 Fix some errors related to disabling modules - #890 2014-03-11 15:16:52 +11:00
Thinkofdeath
5beafed279 Null check the locations.yml Map before changing into a CaseInsensitiveMap (Fixes #920) 2014-03-10 19:34:11 +00:00
Thinkofdeath
2a7ad3c2b2 Append/trim extra data for spawn object packets with a 0 id 2014-03-10 19:25:15 +00:00
md_5
00352f585a Revert code which wasn't meant to be commited. 2014-03-10 13:36:17 +11:00
md_5
290e31b4c5 Update some depend versions, leaving netty for a later date when there aren't as many recent changes. 2014-03-10 11:34:35 +11:00
md_5
1fb7a3bf1d Fix #872 - use default server if forced host not found, OR force default is set. 2014-03-10 11:23:26 +11:00
Jonas Konrad
52fbceec54 Fix client disconnects when a server goes down - #886 2014-03-10 11:17:52 +11:00
md_5
e609145a0d Add module authors - closes #902 2014-03-10 11:13:49 +11:00
md_5
4a7f8015e5 Close #918 - use case insensitive lookup for Yaml locations 2014-03-10 11:04:46 +11:00
md-5
003a1973d4 Update CommandEnd javadoc 2014-03-10 09:23:44 +11:00
md_5
db7f3c770d Fix EventBus when used with Byte.MAX_PRIORITY - closes #910. Also includes additional unit test cases to cover any future regressions. 2014-03-04 20:49:53 +11:00
md_5
eec3c09c32 Tweak ciper messages - closes #905 2014-02-27 16:00:44 +11:00
md_5
565af4d53e Remove switchMutex since its no longer required 2014-02-27 07:32:23 +11:00
md_5
37ed331515 Ensure user's client and server component are both in the same event loop. Probably closes #893 2014-02-26 21:28:04 +11:00
Thinkofdeath
38f12840ca Correct component loop detector 2014-02-21 20:56:10 +00:00
Thinkofdeath
941450b4e4 Detect component loops 2014-02-21 10:13:40 +00:00
md_5
e87d25c321 Remove playerCount from team - closes #889 2014-02-21 20:18:39 +11:00
md_5
886f7499fb Update compile-native script. 2014-02-16 11:40:36 +11:00
md_5
8064a3d4fb Revert "Compile native cipher on ancient CentOS for maximum compatability - closes #880"
This reverts commit 7bfa024c23.
2014-02-16 11:39:47 +11:00
md_5
5039922fa7 Revert "Compile on CentOS 6.4 with OpenSSL 1.0.0e and glibc 2.12"
This reverts commit eb753c8109.
2014-02-16 11:39:42 +11:00
md_5
eb753c8109 Compile on CentOS 6.4 with OpenSSL 1.0.0e and glibc 2.12 2014-02-15 19:37:53 -05:00
md_5
7bfa024c23 Compile native cipher on ancient CentOS for maximum compatability - closes #880 2014-02-16 00:13:13 -05:00
md_5
d98ade5a9b Mojang uses "if > 100", therefore the inverse of that is "if <=100" regarding chat length. 2014-02-13 07:25:56 +11:00
md_5
a272afd693 Some 32bit var ints need 5 bytes 2014-02-13 07:13:48 +11:00
md_5
0f24eaeea3 Mojang caps chat to 100, we should too 2014-02-12 19:59:02 +11:00
md_5
56e9e6a245 Delete extracted native code on exit 2014-02-12 19:53:33 +11:00
md_5
87f3706736 Cap VarInt down to 4 bytes. Early Mojang implementations used 32 BYTES, then they changed it to 5 BYTES. I think they mean 4 BYTES = 32 BITS. 2014-02-12 19:51:43 +11:00
md_5
90104b03b7 Only allow key sizes of 16 in native cipher 2014-02-12 19:45:28 +11:00
md_5
a9b2660aa8 Unknown git commit or version = unknown version sig 2014-02-12 19:15:00 +11:00
md_5
0b7789035f Revert as its unstable anyway. 2014-02-12 18:02:02 +11:00
md_5
3f7850dc5a Clean up JNI code, add stack trace to check up on Jenkins test. 2014-02-12 17:43:49 +11:00
md_5
2e80bf30dd Various improvements to native cipher so that it now actually destroys Java in terms of speed. Closes #871 - thanks @ninja- 2014-02-12 17:37:08 +11:00
md-5
b3627652f2 Merge pull request #869 from Cube-Space/permission-api
Added getPermissions() to the CommandSender API
2014-02-09 14:36:15 +11:00
md_5
b5216148d6 Remove a bit of synchronization 2014-02-09 11:02:26 +11:00
Fabian Fassbender
4faf507ad9 Added getPermissions() to the CommandSender API to get a unmodifiable Collection of all Permissions. The ConsoleSender returns an empty Set where as the UserConnection gives its real Permissions. 2014-02-08 14:17:01 +01:00
md_5
9a4f0a6f59 Revert disconnect change. Forgot we use void futures. 2014-02-08 12:42:27 +11:00
md_5
98a5db9abf Skip deploying of modules - speeds up Jenkins build. 2014-02-08 12:24:31 +11:00
md_5
015dc0c65a Dem string typos 2014-02-08 12:21:13 +11:00
md_5
c1b9e9032f Fix typo 2014-02-08 12:20:08 +11:00
md_5
5e5038c839 Fix Java 7 detection - closes #861 2014-02-08 09:40:08 +11:00
md_5
36ea27454d Disable selector rebuild - closes #851 2014-02-08 09:39:45 +11:00
md_5
2eb2953442 Optimize throwing of CancelSendSignal's by storing a single instance. 2014-02-08 09:36:41 +11:00
md_5
4abffa9f24 Optimize / clean up server disconnect method 2014-02-08 09:33:05 +11:00
md_5
f08df9555c Remove dead IP forward code, Mojang aint bringing that one back 2014-02-08 09:19:28 +11:00
Thinkofdeath
4c5689d10e Fix typo in EntityMap 2014-02-04 11:03:12 +00:00
md_5
224db6596e Make console log handler obey Filters. Closes #866 2014-02-04 16:44:53 +11:00
MinePlayer64
df82720ade Remove unnecessary import 2014-02-02 21:58:13 +11:00
MinePlayer64
33f87498be Use the API to build message 2014-02-02 21:58:13 +11:00
MinePlayer64
d0af22a0f2 Make /server more fancy
Let users click on a server to join it
2014-02-02 21:58:13 +11:00
md_5
4fa137a465 Add java property for log date format, closes #764 2014-02-02 12:45:53 +11:00
md_5
0d7ee821d2 Adjust wording - closes #823 2014-02-02 12:43:18 +11:00
md_5
1f1cdb47e4 Search for bungee.yml and then plugin.yml for Bungee plugins. 2014-02-02 12:22:25 +11:00
md_5
ddab9a84c4 Close #859 - more favicon validation 2014-02-02 12:20:37 +11:00
md_5
5adc0000d8 Add small benchmark to the native cipher suite - see #755 2014-02-02 10:18:01 +11:00
md_5
a0cc5d84be Add explicit casts to make clang support easier - see #755 2014-02-02 10:15:19 +11:00
Thinkofdeath
edce7f7c3d Add tab completion to /send (Fixes #853) 2014-02-01 11:21:59 +00:00
md_5
19b4c09a16 Remove unused fields 2014-02-01 10:38:43 +11:00
md_5
35a5230b52 Remove artifacts from legacy forge support. 2014-02-01 10:38:43 +11:00
md_5
90fcfecb7c Use lombok for vhost 2014-02-01 10:38:43 +11:00
md-5
542d2c2a5b Close #850 - send 127 for legacy protocol version 2014-02-01 09:27:22 +11:00
md_5
649f83dee2 Fix team packet for 1.7 servers 2014-01-28 13:28:06 +11:00
md_5
842392d59c Dual version entity ID rewriting 2014-01-27 11:39:10 +11:00
md_5
b2f517fa63 Implement dual protocol version support. 2014-01-27 11:26:27 +11:00
Thinkofdeath
5c12f900b3 Correct the extra check 2014-01-26 01:12:55 +00:00
Thinkofdeath
6641d199b3 Move the extra check out of hasFormatting 2014-01-26 00:41:13 +00:00
Thinkofdeath
83b0229277 Fix formatting leaking through components when arrays are used + cases where component's extra wouldn't serialize 2014-01-26 00:37:33 +00:00
md_5
5f7963b0c4 Add more validation to server icons. Closes #828 2014-01-22 12:16:48 +11:00
md_5
dae96ac18b Close #819 - remove trailing . from hostname if it exists 2014-01-22 12:09:29 +11:00
md_5
aa91354666 Make sure plugin onLoad is really called onLoad. This fixes regression #822 from when we implemented plugin depends. 2014-01-22 12:07:16 +11:00
md_5
05f4e69afd Bring reconnect yaml handler setting in line with what we had before (only create if needed) 2014-01-17 09:35:29 +11:00
md_5
71e64bf532 Register reconnect_yaml module 2014-01-17 09:31:46 +11:00
md_5
219d485835 Make the yaml reconnect handler a module 2014-01-17 09:25:22 +11:00
md_5
b698fa9806 Actually allow people to run these builds. 2014-01-15 07:39:25 +11:00
md_5
6602c22147 Ensure modules are enabled even when we can't detect version 2014-01-14 13:18:14 +11:00
md_5
f1b329bf21 Finish implementing modules. If anyone wants to test... be my guest. 2014-01-14 13:13:27 +11:00
Thinkofdeath
d4e4796739 Remove pointless Getter annotations 2014-01-13 19:48:49 +00:00
md_5
ab1aacbdc9 Implement a first tempt and module retrieval system 2014-01-13 15:16:17 +11:00
md_5
a426a5ec22 Implement module loader, blacklist this build from loading. 2014-01-13 14:28:07 +11:00
md_5
93cf50b4e1 Rum gitdescribe earlier in the build process. 2014-01-10 10:03:02 +11:00
md_5
7483b4d276 Shuffle some internal stuff to API so that modules will compile 2014-01-10 09:58:31 +11:00
md_5
4be58a7c00 Copy across all the commands and add their bootstrap plugins. 2014-01-10 09:53:33 +11:00
md_5
90d68bd38e Should be of jar packaging 2014-01-10 09:38:53 +11:00
md_5
7dba8c8a87 Implement skeleton modules for our 5 initial commands. 2014-01-10 09:35:27 +11:00
Joey Sacchini
cb4f70ecc7 Fix null pointer in depend resolution. This closes issue #515. 2014-01-07 14:34:07 +11:00
Thinkofdeath
2100da2a9f Don't remove the legacy decoder if a legacy packet is found
Removing the decoder causes the bytebuf to be passed on to the next handler to be parsed normal packet which causes an error with legacy handshakes.
2014-01-05 17:06:07 +00:00
md_5
986f52b1e1 Try harder to find translations when not using English. Closes #787 2014-01-05 11:34:34 +11:00
md_5
7faefde51b Add name_too_long translation 2014-01-05 11:27:19 +11:00
TheUnnamedDude
8c367d86e7 Properly kick older clients 2014-01-05 11:25:42 +11:00
md_5
80caa2b669 Code format :( 2014-01-03 19:52:35 +11:00
md_5
9f8c04ef86 Update some dependency versions: Guava, MySQL, JavaAssist, Netty. 2014-01-03 19:51:44 +11:00
Thinkofdeath
b0a8371570 Fix client crash when an empty message is sent using TextComponent.fromLegacyText 2014-01-02 15:39:38 +00:00
thinkofdeath
0d7cd78901 Merge pull request #773 from YoshiGenius/patch-1
Fix javadoc - spelling and details
2014-01-01 15:16:46 -08:00
Thinkofdeath
e7f1a88e6e Formatting fixes 2013-12-30 16:15:39 +00:00
thinkofdeath
28c8bf47ff Merge pull request #789 from kosgan10/patch-1
Fix errors for console
2013-12-30 08:14:21 -08:00
kosgan10
5e57356e6a Change Exception > Throwable 2013-12-30 18:10:39 +02:00
kosgan10
f3766bc10b Fix hover messages for players 2013-12-30 18:07:30 +02:00
kosgan10
6c795a25ff Change message to use ComponentBuilder 2013-12-30 15:43:58 +02:00
kosgan10
d3159fe6ca Fix imports 2013-12-30 15:38:13 +02:00
kosgan10
93ba9b3a3e Fix errors for console 2013-12-30 15:36:35 +02:00
Thinkofdeath
c184667a26 Add packet names as comments to EntityMap to make updating between versions easier 2013-12-28 22:55:09 +00:00
md_5
5ea4763ae9 Implement UUID forwarding, you MUST update Spigot for this to work 2013-12-24 10:10:11 +11:00
md_5
d0d0f4ec9f Make getPlayers a little safer. Should probably use a CopyOnWrite collection though. 2013-12-23 17:41:27 +11:00
YoshiGenius
0ff1f4724a Add new lines 2013-12-23 08:45:48 +11:00
YoshiGenius
1baba3cd7d Fix javadoc - spelling and details 2013-12-22 13:05:45 +11:00
Keir Nellyer
608eaace1c Fix NPE when no Callback is defined FIXES #772 2013-12-21 12:14:42 +00:00
md_5
075518b643 Implement a connect callback - see #760 2013-12-21 13:11:27 +11:00
md_5
f7d3dfd61d Show severe error for missing forced error, but don't crash 2013-12-20 18:57:13 +11:00
md_5
b713ccff10 Validate forced hosts config on reload 2013-12-19 19:30:24 +11:00
md_5
f0e1625078 Implement delombok to close #770 2013-12-19 10:04:48 +11:00
md_5
60d6f31876 Generate offline mode UUIDs the same way Mojang does. 2013-12-16 22:41:19 +11:00
Thinkofdeath
359e2b2a16 Fix typo in /alertraw error message 2013-12-15 13:17:29 +00:00
thinkofdeath
0dcba749dc Merge pull request #748 from thinkofdeath/master
Chat Component API
2013-12-14 02:31:42 -08:00
Thinkofdeath
00ac965d42 Remove class Getter annotation 2013-12-14 10:16:58 +00:00
md-5
32c6ab710a Delay is not in milliseconds, its in the TimeUnit 2013-12-13 12:46:52 +11:00
Thinkofdeath
5d68b422e5 Add ComponentBuilder + make events final
An example of ComponentBuilder usage can be found at CommandAlertRaw
2013-12-10 11:50:34 +00:00
Thinkofdeath
6093cde93f Fix last commit 2013-12-08 18:04:20 +00:00
Thinkofdeath
4537055caa Fix shooterID/ownerID not getting remapped 2013-12-08 17:36:29 +00:00
Thinkofdeath
17fc120e07 Move 0x13 to clientbound only 2013-12-08 16:47:17 +00:00
Thinkofdeath
230cca0f9e Fix server-bound entity ids as well 2013-12-08 16:42:49 +00:00
Thinkofdeath
cfda905d98 Fix entity id remapping
The old system only worked in ints and 1.7 changed some to varints. Since the length of the varint is variable more work is needed to remap ids
2013-12-08 15:09:12 +00:00
Thinkofdeath
bc746a546f Added another unit test + formatted code 2013-12-08 10:17:02 +00:00
Thinkofdeath
70bb3ddcce Added some unit tests 2013-12-08 00:48:10 +00:00
Thinkofdeath
4ef15ae764 Fixed TranslatableComponents missing the end of the translated text 2013-12-08 00:47:45 +00:00
Thinkofdeath
3f9ca85831 Add missing documentation 2013-12-07 23:35:43 +00:00
Thinkofdeath
c17fa03ccd Remove string methods from HoverEvent. TextComponents will become strings if formatting isn't used 2013-12-07 15:10:08 +00:00
Thinkofdeath
0040955204 Fix events not working when no formatting is used 2013-12-07 13:59:00 +00:00
Thinkofdeath
60e2e6bfa4 Add /alertraw command + fix events 2013-12-07 13:35:52 +00:00
Thinkofdeath
2cb3b6f934 Fix TranslatableComponent's toPlainText and toLegacyText not handling %1$s and %d 2013-12-07 13:16:10 +00:00
Thinkofdeath
c7e590e286 Move en_US.properties to mojang-translations/en_US.properties 2013-12-06 23:21:52 +00:00
Thinkofdeath
696679809d Support printing TranslatableComponents 2013-12-06 23:18:10 +00:00
Thinkofdeath
e3e551d825 Use varargs instead of arrays 2013-12-06 23:02:05 +00:00
Thinkofdeath
854b6faf0e Fixed broadcasts getting double logged 2013-12-06 22:40:41 +00:00
Thinkofdeath
890fac27c5 More formatting fixes 2013-12-06 22:40:40 +00:00
Thinkofdeath
35c1b26a20 Fix formatting 2013-12-06 22:40:40 +00:00
Thinkofdeath
2c8b15cb1e Use components for ServerKickEvent (fixes #744) + minor refactoring 2013-12-06 22:40:40 +00:00
Thinkofdeath
c20d8f9cd6 Chat Component API 2013-12-06 22:40:40 +00:00
md_5
85c27f30ee Properly abort kicks on ServerConnector 2013-12-07 09:33:37 +11:00
md-5
0446351f9d @GunfighterJ for grammar nazi 2013 2013-12-05 09:24:00 +11:00
Thinkofdeath
54d307da57 Reduce the size of json output
Nulls are not outputted (https://sites.google.com/site/gson/gson-user-guide#TOC-Null-Object-Support)
2013-12-03 08:17:38 +11:00
Thinkofdeath
81e43aab98 Update ChatConverter 2013-12-03 08:17:38 +11:00
Thinkofdeath
18db187347 Use the ChatConverter from spigot to fix 1.7 formatting bugs 2013-12-03 08:17:38 +11:00
md_5
63d49ac296 Add some failsafe length preconditions 2013-12-02 18:49:39 +11:00
hcherndon
aad83d787f Add methods to expose parts of the proxy internal config. This is depreceated as it is subject to breaking changes without warning. 2013-12-02 15:17:19 +11:00
Keir Nellyer
af751dae5a Add new plugin message sub-channels to get a players real UUID 2013-12-02 08:37:17 +11:00
md_5
f7851b0436 Implement ServerDisconnectEvent. Wow so many server switch events. 2013-11-25 11:12:49 +11:00
md_5
d7e78d0945 Ability to disable outdated message 2013-11-24 19:42:05 +11:00
md_5
94ee61cd35 Native cipher, with more smoke tests! 2013-11-19 07:16:06 +11:00
md_5
897a59254c Still segfaulting. 2013-11-18 20:00:15 +11:00
md_5
c1ba555553 Hopefully fix native cipher segfault 2013-11-18 07:18:23 +11:00
ninja-
c70006a36c Implement new, high-performance cipher in native code. Currently available only for Linux-x64, other platforms will fallback to Java cipher. 2013-11-18 07:17:14 +11:00
md_5
12ef019d69 Revert native cipher, causing SIGSEGV 2013-11-17 16:51:11 +11:00
md_5
c18537f294 Ultra blazing fast native code for 64 bit linux! Testers welcome! Thanks @ninja- for his hard work. 2013-11-17 15:59:51 +11:00
ninja-
fc189e81d5 Implement new, high-performance cipher in native code. Currently available only for Linux-x64, other platforms will fallback to Java cipher. 2013-11-17 15:59:18 +11:00
md-5
aaa8b4a53d Forgot to rewrite 0x1A, thanks @Mati0703 2013-11-17 14:45:58 +11:00
md_5
e39428ea0b Mojang can't seem to decide what chat format to use for kicks, so lets just send a literal without our own prefix through. This (uncleanly) closes #714. 2013-11-16 11:22:38 +11:00
md_5
e4602f027e Don't pointlessly create new gson instances 2013-11-16 11:11:43 +11:00
md_5
2f2406206e Fix chat event javadoc - closes #713 2013-11-16 11:11:04 +11:00
md_5
3ae8308a4b Small cleanup 2013-11-15 16:53:10 +11:00
md_5
8a38921f21 Bump netty release 2013-11-15 16:28:35 +11:00
md_5
cc0d3a8e49 Config -> Conf to prevent messup with shades. How did this skip by? 2013-11-06 20:12:39 +11:00
md_5
f81bf8e7c5 Code format + fix pom 2013-11-06 20:11:17 +11:00
zh32
e755573fb3 Removed unused import and made code nicer. 2013-11-06 20:07:16 +11:00
zh32
a201b5897a Added async PreLoginEvent to change online mode per connection. 2013-11-06 20:07:16 +11:00
md_5
b4cd88c13d Make UDP query actually work. 2013-11-06 20:02:37 +11:00
md_5
8e390b5714 Proper replacement for #701, closes #691 2013-11-05 18:16:33 +11:00
md_5
14371a1a8c Don't rewrite the actual host packet, just a copy. 2013-11-05 18:07:55 +11:00
md_5
61326db3ee Not having a good night, thought I removed that code. 2013-11-03 18:00:30 +11:00
md_5
90625bc196 Remove test code 2013-11-03 17:15:44 +11:00
md_5
155e274e72 Fix disconnects during LoginEvent when using online mode clients 2013-11-03 17:04:59 +11:00
md_5
04b52aa4f4 Close #699 - case sensitivity of command tab complete 2013-11-03 10:02:37 +11:00
md_5
4040d9f20a [Breaking] Fix player online sample 2013-11-01 22:00:46 +11:00
md_5
02619c6132 Close #689 - fix serverinfo.ping 2013-11-01 17:52:14 +11:00
md_5
26863032a1 Fix #671 - user timing out when connectNow is used. 2013-11-01 17:46:41 +11:00
md_5
a0d3bf97d1 Close #690, wire up the old proxy ping event for old clients 2013-11-01 17:43:03 +11:00
md_5
3becbe4d38 Fix #686 - rewriting of bows and fishing hooks 2013-11-01 17:38:53 +11:00
md_5
7205e69ce6 Correct some issues with being banned. See #658 which may be relevant 2013-11-01 17:24:35 +11:00
md_5
c84d6f0035 Add really efficient text -> json translation. Doesn't support format codes yet. 2013-11-01 17:14:18 +11:00
md_5
20b1b37e54 Did someone say great performance increases? 2013-10-28 20:43:28 +11:00
md_5
2117a6b7de Undo kick changes 2013-10-27 21:41:10 +11:00
md_5
e6c1015027 Reload favicon on greload 2013-10-27 20:07:36 +11:00
md_5
8665784bb5 Oh right, stage 2013-10-27 18:23:07 +11:00
md_5
efd5bd58e4 Fix colours wrapping, somewhat 2013-10-27 18:18:44 +11:00
md_5
e006673550 Fix kicks + don't allow connections to online mode servers 2013-10-27 18:12:18 +11:00
md_5
2129cb3614 Fix kicks? 2013-10-27 18:09:27 +11:00
md_5
6ce43fb876 Sample is an array 2013-10-27 13:51:06 +11:00
md_5
b9158b7322 Implement 1.7 style pings 2013-10-27 12:59:35 +11:00
md_5
5dfd14fbe5 Enhance ping API 2013-10-27 12:36:30 +11:00
md_5
e1f7b7b126 Add new ip forward method, must be manually enabled 2013-10-27 12:06:17 +11:00
md_5
4dff25f880 In favour of #678 - use supported class version 2013-10-27 11:38:28 +11:00
md_5
5dc91e3a01 1.7.2 update 2013-10-26 08:30:42 +11:00
md_5
e2e32100cd Common method to wrap text. Thanks @lazertester 2013-10-25 20:39:06 +11:00
md_5
a7e4854661 Fix kick 2013-10-25 20:09:18 +11:00
md_5
6e69d476ef Fix 1.7 potion etc support 2013-10-25 17:25:13 +11:00
md_5
1e2eda94db Don't log metrics 2013-10-24 07:14:06 +11:00
md_5
37dc600fe0 BungeeCord can into server icon 2013-10-23 20:44:48 +11:00
md_5
07d9a56567 ***WARNING - FOR MINECRAFT 1.7*** Update master to 1.7.
Merge branch 'origin/snapshot'
2013-10-23 17:45:21 +11:00
md_5
0952e53d11 Update to 1.7 poms. 2013-10-23 17:33:21 +11:00
md_5
2101964330 1.7 pre release support 2013-10-23 06:30:16 +11:00
md_5
cdf47d84d8 Fix offline mode. Latest snapshot appears to be pretty much functional, although the client itself seems to have some reliability issues. 2013-10-19 20:01:22 +11:00
md_5
b7babd2888 Fix ping player counts being swapped 2013-10-19 17:56:14 +11:00
md_5
da5fa4bb7c Fix outdatedness 2013-10-19 17:50:54 +11:00
md_5
00854988fb Latest snapshot. Doesnt seem to be worky though 2013-10-19 17:42:45 +11:00
md_5
4f8085678c 1.6.4 ping support 2013-10-19 17:27:13 +11:00
md_5
6341ad4c5a Merge branch 'origin/master' 2013-10-19 16:44:27 +11:00
md_5
9b84e75eaa Update lombok to support latest netbeans 2013-10-19 10:01:42 +11:00
md_5
194b09b2dd Dont expand events - closes #666 2013-10-19 07:10:31 +11:00
md_5
3b9af0ab85 Fix 41b support 2013-10-16 17:29:49 +11:00
md_5
18db20fe42 41b update 2013-10-15 16:29:36 +11:00
md_5
062dd38b2b Fix pinging. I love you @Sircmpwn 2013-10-12 15:50:08 +11:00
md_5
69b209bcc6 Fix /server command. Now working! 2013-10-12 15:36:22 +11:00
md_5
d96e561a6f Cleanup debug 2013-10-12 15:30:32 +11:00
md_5
26be0566f4 I love @Cobi 2013-10-12 15:29:39 +11:00
md_5
1551bf6f3a Ping stuffs, doesnt seem to work for some reason though 2013-10-12 13:51:33 +11:00
md_5
e0ebf1af21 All my work on 1.7 so far. Pinging doesnt work, but everything else is near functional. Gotta figure out wtf is happening. 2013-10-12 12:08:26 +11:00
md_5
b8c9330bd6 Sigh 2013-10-12 12:01:17 +11:00
md_5
1b41682e37 Checkpoint 2013-10-12 11:36:53 +11:00
md_5
b358fd25f5 Done with the proxy to client part. Now we just need the proxy to server part. 2013-10-11 21:40:23 +11:00
md_5
dbdae87ec6 Basically done with login 2013-10-11 21:36:28 +11:00
md_5
7121c20338 Compiles yet again 2013-10-11 20:34:21 +11:00
md_5
d900417d95 It compiles 2013-10-11 20:00:54 +11:00
md_5
7be929bb08 Update protocol - major overhaul 2013-10-11 19:26:40 +11:00
md_5
4257b81d8c WIP 2013-10-11 18:40:21 +11:00
md_5
96acdb97fd Update to latest snapshot. 2013-10-11 16:16:02 +11:00
md_5
edc5b4dc91 Close #656 - fix find filter. 2013-10-11 10:24:55 +11:00
md_5
220a95aece We cannot throttle like this if we want 1.7 compat, lets disable it until we work on a more compatible one. 2013-10-10 07:25:20 +11:00
md_5
4685099808 Close #564 adding a blank arg is a silly idea 2013-10-09 22:37:27 +11:00
md-5
6c14f40108 Reduce the time we wait for legacy pings. 2013-10-08 09:06:28 +11:00
md_5
b041d84063 Null check plugin input for servers 2013-10-07 16:55:29 +11:00
md_5
a9d3d9461f Mojang nerfed tab lists :( 2013-10-06 08:42:52 +11:00
md_5
3fc7064997 Add missing setters for handshake. 2013-10-05 09:50:20 +10:00
md_5
80001aa1f0 UDP + Java + IPV6 != Friends 2013-09-30 17:58:02 +10:00
marvin
a0d94282f6 Add PlayerHandshakeEvent which allows changing of versions and online mode status amongst other things. 2013-09-30 09:22:49 +10:00
md_5
33e11f4c44 Allow for iterables to be CSV-ified 2013-09-29 18:49:20 +10:00
md_5
b541e7aa76 Custom glist formatting 2013-09-29 18:45:11 +10:00
zaiyers
dd06937a3b changes to tab completion
* PacketCBTabComplete: options for completion should be seperated by
NUL
 * PluginManager: append an empty argument to arguments if command ends
with a whitespace (this will match all suggestions)
 * PlayerCommand: suggest only matching players instead of all players
2013-09-29 09:37:39 +10:00
md_5
891dc87b16 Allow unrecognised command line args 2013-09-28 21:00:38 +10:00
md_5
8e77cb35ff Use JDK map for throttle 2013-09-28 18:32:39 +10:00
md_5
59b32a8621 Remove access from PendingConnection interface 2013-09-28 17:37:30 +10:00
md_5
02324206e3 Clean up packets a tad 2013-09-28 17:03:33 +10:00
md_5
73ce828e6e [#637] - Fix resource bundle resolution 2013-09-26 09:24:30 +10:00
md_5
79d04bec2e [#582] Widen synchronized block for packet queue. 2013-09-26 09:20:52 +10:00
md_5
cbcd874d47 Close #626 - command line argument for version. Also refactors into a bootstrap which warns users when not using Java 7! 2013-09-25 17:21:03 +10:00
md_5
09f123ce9a guery -> query 2013-09-24 17:50:44 +10:00
md_5
0a5f8556fe Add config saving 2013-09-24 12:14:47 +10:00
md_5
103a509f26 Fix access of yaml config 2013-09-24 12:11:04 +10:00
md_5
32a5271dc3 Implement basic udp query to close #185 2013-09-24 10:09:55 +10:00
md_5
14389eb370 Use correct main class 2013-09-23 10:30:41 +10:00
md_5
a8b6a6b4aa Finish basic Yaml configuration API, complete with unit tests. Needs a lot of work with regards to how sections are handled, open to massive improvements from anyone that has more know-how. 2013-09-23 10:28:30 +10:00
md_5
8133304cce Use = for properties 2013-09-22 17:37:06 +10:00
md_5
3e8c21a485 Add specific exception for bad packets. 2013-09-21 16:57:17 +10:00
Matty Southall
f12dcc72d9 Fix compile error when compiling on OS X 2013-09-21 10:55:39 +10:00
md_5
a7a32509c7 find * -type f -print0 | xargs -0 sed -i 's/1.6.2/1.6.4/g' 2013-09-20 19:51:57 +10:00
md_5
703a393888 Procol -> Protocol. Fix typo, thanks @libraryaddict 2013-09-20 15:41:30 +10:00
md_5
3c961cd5d9 1.6.4 - MOJANG 2013-09-20 08:23:06 +10:00
md_5
12ee68a315 Update to 1.6.3 2013-09-19 17:41:01 +10:00
md_5
db5510cc4e Only interrupt tab completion if we have things to complete! 2013-09-17 10:28:51 +10:00
md_5
5ed5c71aea Move AbstractReconnectManager to the API and rename to AbstractReconnectHandler. 2013-09-16 08:21:53 +10:00
md_5
38a8469ab4 Cap command completion to one argument 2013-09-15 15:14:47 +10:00
md_5
9538dcf4d4 Properly tab complete 2013-09-15 14:04:51 +10:00
md_5
33f654ce6f *unused imports 2013-09-15 07:44:13 +10:00
md_5
c108e4e1ce Server command completion 2013-09-15 07:43:50 +10:00
md_5
e998faeec1 Add tab completion for find command. Also change api a bit. 2013-09-15 07:37:20 +10:00
md_5
d67acd7bc9 Add functionality to replicate #336 2013-09-15 07:29:22 +10:00
md_5
702f434db1 Add API to support #468 - force setting of reconnect server 2013-09-15 07:12:58 +10:00
md_5
47b5631562 Not part of the contract 2013-09-15 06:54:58 +10:00
Robin Lambertz
80e23d6646 Allow removal of listeners / commands by plugin 2013-09-15 06:52:46 +10:00
md_5
1dca12cffb Use boolean not binary and 2013-09-15 06:48:06 +10:00
md_5
29c897c9cf Add Tab Completion loosely based on @TheUnnamedDude's work. 2013-09-15 06:46:10 +10:00
md_5
042f47cbb9 Wrapped buffers are not thread safe. 2013-09-10 21:33:44 +10:00
md_5
422e97f495 Don't let pingbuf be released 2013-09-10 21:26:59 +10:00
md_5
08789d8f9f Write down a supported message type (ByteBuf) when using the ping handler. 2013-09-10 20:56:40 +10:00
md_5
96444ae304 Fix a message consisting only of a space causing the player to be kicked. 2013-09-10 16:23:05 +10:00
md_5
af58db8a67 Simpler, unit tested throttle to close #613 2013-09-10 12:02:29 +10:00
md_5
49cffebd9b Dynamic build dates - see #526 2013-09-10 11:37:48 +10:00
md_5
ffdb917f2c Use translation - closes #578 2013-09-09 14:58:56 +10:00
md_5
9c9657e36d Update links 2013-09-09 14:41:58 +10:00
md_5
1342baed47 Use fluid bytes instead of enum + format. 2013-09-09 14:36:48 +10:00
Dabo Ross
e3a7490bcd Fix formatting error - not sure how that happened 2013-09-09 14:27:23 +10:00
Dabo Ross
3e8693793c Add multiple listeners to EventPriorityTest 2013-09-09 14:27:23 +10:00
Dabo Ross
bb47aba682 Add UnregisteringListenerTest 2013-09-09 14:27:23 +10:00
Dabo Ross
d0e5ee4e09 Don't try to bake handlers when there are no more handlers. Remove them instead! 2013-09-09 14:27:23 +10:00
Dabo Ross
07e330b005 Create test for event priorities 2013-09-09 14:27:23 +10:00
Dabo Ross
024288e587 Added a Map<Class<?>, EventHandlerMethod[]> and implemented using it. I believe this should have a positive performance effect. 2013-09-09 14:27:23 +10:00
Dabo Ross
53a6bb1dee Added EventHandlerMethod wrapper for Listener and Method 2013-09-09 14:27:23 +10:00
Dabo Ross
0f06b2c4e0 Implement usage of EventPriority in EventBus 2013-09-09 14:27:23 +10:00
Dabo Ross
d3c1acce83 Add EventPriority method to EventHandler 2013-09-09 14:27:23 +10:00
Dabo Ross
eaea090d37 Add EventPriority 2013-09-09 14:27:22 +10:00
md_5
7384e797fc Bump date 2013-09-08 11:49:27 +10:00
md_5
d4d93ddbb9 Bump to Netty 4.0.9 2013-09-08 08:45:37 +10:00
md_5
ccdf2a89d8 Close #518 - use csv method for perms command 2013-09-07 12:22:43 +10:00
md_5
89edb00c05 Properly cancel tasks! 2013-09-05 19:52:41 +10:00
md_5
00a0277a13 Just call our own logger, screw jdk logger parenting 2013-09-03 11:36:00 +10:00
md_5
68f11e46f7 Depend updates. 2013-08-27 12:30:00 +10:00
Ammar Askar
c352e854ee Catch exceptions when disabling plugins 2013-08-25 10:27:25 +10:00
md_5
d8c92cd311 Add ConnectOther channel for moving other players from a plugin 2013-08-25 10:23:17 +10:00
md_5
99f361ca77 Instead of storing packets about to be passed on as a byte array, store them as a Netty buffer, which is likely to be pooled, direct and manually memory managed leading to increased performance and less GC strain. In order to ensure no resources are leaked, we free them at the end of each handle cycle if they have not been passed to a channel for writing. In initial profiles this now causes encryption to be one of the most intensive parts of BungeeCord, however in depth profiling snapshots may provide further routes for optimization. 2013-08-20 19:29:43 +10:00
md_5
738ed99d54 Code format. 2013-08-20 19:28:09 +10:00
md_5
ad0da59267 Really need to automatically do this. Add a few weeks to expire time 2013-08-20 18:50:52 +10:00
md_5
1dcc8d6a4b Close #572 - kick event message 2013-08-20 11:18:51 +10:00
md_5
0840a77153 Dem dates :( 2013-08-15 07:44:33 +10:00
md_5
61a93a54a9 ammar2 missed a spot 2013-08-14 22:14:32 +10:00
md_5
da0281508e Oi! Get back inside of that if statement. NOW! 2013-08-13 18:53:16 +10:00
Ammar Askar
51e92de2dd Only save to reconnectHandler if we have a listener that isn't forcing to the default server 2013-08-13 18:50:19 +10:00
md_5
f948acd634 Don't loop registering of listeners 2013-08-12 20:31:51 +10:00
md_5
773ce089c1 Fix http client 2013-08-10 07:30:41 +10:00
md_5
a07eba7965 Netty 4.0.7.Final - fixes memory leak 2013-08-09 19:50:48 +10:00
md_5
b68b6a76c7 Recover from broken yaml 2013-08-09 17:23:16 +10:00
md_5
332033bb02 Disable resource leak detector for ~15% cpu reduction 2013-08-09 16:58:14 +10:00
md_5
172b8bc75b Update to Netty 4.0.6-Final 2013-08-09 16:56:09 +10:00
md_5
db5a147491 Revert changes to SeverConnectedEvent 2013-08-06 11:14:54 +10:00
md_5
f083e27649 More translations! 2013-08-05 17:29:47 +10:00
md_5
b64a7be19b Bump date to the 9th 2013-08-04 21:34:56 +10:00
md_5
c4d60a8fa9 Hold player for ServerSwitchEvent - see #539 2013-08-04 21:28:10 +10:00
md_5
f07cfe0cf7 Make the ServerConnectedEvent async to allow stalling it. Closes #538 by @BjoernAkAManf. 2013-08-04 20:58:17 +10:00
md_5
4463b0c1b2 Use Java 7 API to make classloader thread safe. Closes #516 2013-08-04 20:23:31 +10:00
mrapple
ee8f33c196 Add State to ServerKickEvent 2013-08-04 18:57:13 +10:00
md_5
14ac2dd308 Allow setting whether to bind to the local address. 2013-08-04 18:56:48 +10:00
md_5
fb94612315 Fix throttle to 1) Work, 2) Not throttle outbound connections 2013-08-02 19:31:46 +10:00
md_5
4c96880580 Lets just silence java.util.NoSuchElementException: decrypt - PEOPLE DON'T UNDERSTAND ITS NOT AN ERROR. 2013-08-02 19:11:16 +10:00
md_5
4c4cdd51a1 Downgrade to Netty CR9 2013-08-02 07:32:42 +10:00
md_5
1f38152530 [URGENT] Add connection throttle. 2013-08-01 13:37:32 +10:00
md_5
911f08d52c Disable packet grouping in an attempt to increase reliability. 2013-07-31 20:18:54 +10:00
md_5
8f961c9d4e Put colours in default motd to try and force quoting in the dumped yaml 2013-07-27 12:12:12 +10:00
md_5
8a5d8a57f7 Don't infinite loop on tasks with no period 2013-07-24 17:38:46 +10:00
md_5
c54553d0f9 How kind of @lazertester to test the new scheduler! 2013-07-24 17:32:08 +10:00
md_5
600a1b4ff5 Update expire date 2013-07-24 17:02:37 +10:00
md_5
09e592295f Update to Netty 4.0.4-Final 2013-07-24 15:58:02 +10:00
md_5
fa0ee02beb Update Netty - if you guys could verify the leak has been fixed, that would be great, #523 2013-07-22 19:40:14 +10:00
md_5
b23b54d9e4 Bump Netty minor version 2013-07-19 19:31:46 +10:00
md_5
b3e8feb4cb Update POMs to 1.6.2 2013-07-18 20:13:07 +10:00
md_5
d0d1562155 Hi, I'm Mojang and I make hundreds of millions of dollars a year. I still like to think I am an Indy company, so I randomly remove existing game features and don't provide replacements.
Removes Texture Pack setting
2013-07-18 20:10:45 +10:00
md_5
f510ab2a0b Update to netty 4 final, exciting! 2013-07-17 16:47:49 +10:00
md_5
fb1cab499d Always use eventloop since we cannot be sure about plugins, thanks @MonsieurApple for the report. 2013-07-12 09:29:53 +10:00
md_5
58ca63e2b1 Use a defensive copy for shorter lock time 2013-07-11 11:14:12 +10:00
md_5
499337c98e Optimized yaml reconnect locations! Ding dong sqlite is dead.. 2013-07-11 11:12:43 +10:00
md_5
526137be7b Remove our packet queuing as it may be contributing to high CPU usage and/or memory leaks. 2013-07-11 10:14:51 +10:00
md_5
47839cb11c writeStringUTF8WithoutLengthHeaderBecause @Dinnerbone StuffedUpTheMCBrandPacket 2013-07-10 23:42:50 +10:00
md_5
55a6cc56ef Recycle messagelist when channel goes inactive (reverted from commit daa58ffe58) 2013-07-10 23:41:37 +10:00
md_5
8c2bea5be2 Fix possible race condition with regards to abandoning servers 2013-07-10 13:02:25 +10:00
md_5
daa58ffe58 Recycle messagelist when channel goes inactive 2013-07-10 09:18:58 +10:00
md_5
0189ad9c17 Add disabled commands 2013-07-09 14:55:27 +10:00
md_5
9adcb05d45 Fix 1.6.2 support 2013-07-08 22:37:59 +10:00
md_5
10e81041b2 Update to 1.6.2 2013-07-08 21:29:09 +10:00
md_5
0c56945ffd Implement upcoming Minecraft API to get the server brand - thanks @Grum for the hint. 2013-07-08 21:29:09 +10:00
md_5
0a36cbd5bc Fix compilation -> add silly catch block 2013-07-08 08:41:11 +10:00
md_5
61b4777177 Use more threads for IO to eliminate resource starvation possibly leading to high CPU usage. This brings the count back in line with what we had pre 1.6 / late 1.5 2013-07-08 08:35:12 +10:00
md_5
7d1904584b Back to Java cipher, they are both the same speed 2013-07-08 08:33:25 +10:00
md_5
475571986c Make sure packets are written before closing 2013-07-07 13:08:25 +10:00
md_5
55c2bcd634 Undo recent SQLite changes - might need to seek *another* DB engine - whats H2 like for concurrency? 2013-07-06 08:30:38 +10:00
md_5
db4abfe486 Expand streams a little bit 2013-07-05 19:17:25 +10:00
md_5
9424bdedca Implement basic MC stream 2013-07-05 19:06:46 +10:00
md_5
52b3c6b77c Dont need to force use of eventloop anymore 2013-07-05 09:32:20 +10:00
md_5
be29799f5a [Beta] Implement own HTTP client for online mode checks, instead of asynchttpclient 2013-07-05 09:29:28 +10:00
md_5
c0d581d41f Rework SQLite again to use thread local connections - closes #492 2013-07-05 08:23:29 +10:00
md_5
6b50c7c599 Move HTTP client stuffs into bungee-proxy 2013-07-04 21:59:38 +10:00
hyperring
b4101874cc Fixed forced_hosts MOTD
Noticed a tiny bug in creating a ServerPing response. The response was still using the old listener.getMotd() when it should be using the new motd variable (to take advantage of the new forced_hosts MOTD methods).
2013-07-04 21:39:33 +10:00
md_5
66de4c95ef Implement BouncyCastle as the cipher engine. 2013-07-04 21:13:10 +10:00
md_5
927a295add Add SSL support 2013-07-04 11:48:09 +10:00
md_5
2cbea83c02 HTTP is working, still need to do HTTPS though 2013-07-04 11:32:36 +10:00
md_5
87884ad084 Downgrade maven compiler - new one is still derp 2013-07-04 11:12:25 +10:00
md_5
94cc2412e7 Flush pending messages when manipulating pipeline - fixes forge support 2013-07-04 11:11:57 +10:00
md_5
924b90e325 Add statr of work on HTTP client. 2013-07-04 10:52:54 +10:00
md_5
3f476a30b4 Get depend name right :p 2013-07-04 10:31:00 +10:00
md_5
f579b31bca Add framework for HTTP api 2013-07-04 10:29:37 +10:00
md_5
cac35116c3 Import cleanup 2013-07-04 10:03:41 +10:00
md_5
bd42fb23a0 Update to Netty CR9 2013-07-04 09:58:29 +10:00
md_5
ffbebaff69 Remove old @Subscribe event handling 2013-07-04 09:43:32 +10:00
md_5
b741722e5d Close #489 - disable resource leak detector for performance reasons 2013-07-04 09:22:27 +10:00
md_5
07288c722c Update maven compiler version 2013-07-02 21:04:10 +10:00
md_5
85e82a2e34 Update POMs to 1.6.1 2013-07-02 20:59:04 +10:00
md_5
3aef35ccbb Warn about non existant fallback 2013-07-02 19:43:48 +10:00
md_5
d1760dad93 Custom outdated messages, tick! 2013-07-02 19:26:21 +10:00
md_5
d3d11cf283 Update to netty CR8 2013-07-02 15:31:20 +10:00
md_5
d3bada58d4 Close #469 - chat event setMessage 2013-07-02 10:45:37 +10:00
md-5
23517a9a97 Merge pull request #476 from vemacs/patch-1
Supposedly fix walk speeds
2013-07-01 14:10:43 -07:00
vemacs
fdc87e88f5 Supposedly fix walk speeds 2013-07-01 15:34:17 -04:00
md_5
12941ffe62 Close #471 - sync sqlite operations to guard against deadlocks 2013-07-01 21:25:39 +10:00
md_5
06e732d8c7 Close #474 - 1.5 ping to 1.6 bungee 2013-07-01 21:20:18 +10:00
md_5
5c4ea3c7a0 Solve long standing issue of creating too many TCP packets. This fix works very effectively. 2013-07-01 17:38:50 +10:00
md_5
632fa8bd94 Partially support forced_hosts MOTD without SRV records - gonna think how best to put this in the config, for now its server: motd:, might remove listener motd later on 2013-07-01 14:05:57 +10:00
md_5
8732904bfd Add stream helper to PacketFA 2013-07-01 13:45:36 +10:00
md_5
788b96dc0a knohacks - thanks @ammaraskar 2013-07-01 13:37:03 +10:00
md_5
1296783d9b Update to Minecraft 1.6.1 2013-07-01 13:19:18 +10:00
md_5
a9603a6372 Bump Javassist version 2013-06-29 15:04:13 +10:00
md_5
b15ed87ad5 Netty CR7 m8 2013-06-29 15:02:38 +10:00
md_5
3e816f628b Update to Netty CR6 2013-06-27 16:22:06 +10:00
md_5
7bfc4bf819 Remove outbound boss for now 2013-06-27 10:16:23 +10:00
David Marby
f8d15f4c88 Fix bad packet ID with bows 2013-06-27 10:14:34 +10:00
md_5
a73b06eee3 Close #462 - shutdown gracefully 2013-06-26 20:48:13 +10:00
md_5
2069679140 Silence JLine errors 2013-06-25 11:29:47 +10:00
md_5
9a173968f1 Update to Netty CR3 but include workaround for (bug?) present in it. Feedback is welcome, #448 is related. 2013-06-23 10:40:27 +10:00
AgentK
13f1fa7443 Reject clients on other protocol versions. 2013-06-21 16:36:37 +10:00
md_5
0f7da279ef Close #450 - errors from our backport 2013-06-19 13:30:43 +10:00
md_5
a6ba661a32 Back to CR1 we go. Deal with the issues. 2013-06-19 07:36:40 +10:00
md_5
22133bc8d2 Close #445 - error when clients use forge 2013-06-18 21:10:16 +10:00
md_5
f9c9517958 Why can no one ever provide helpful information to attempt to diagnose a bug, it is ridiculous that you can expect my help when you don't even provide a version number.
I am seriously just tired of this and need a break.
2013-06-18 20:52:18 +10:00
md_5
7a79bd0816 Update to Netty CR5, boasts very nice performance and should hopefully fix many of the issues we have seen. 2013-06-18 17:14:34 +10:00
md_5
6a60376033 If #438 does not go away, then BungeeCord users are derps, since this class has no been reverted to the exact same state before the so called issue inducing commit 2013-06-17 19:10:38 +10:00
md_5
4ce0eee232 #438 please just go away. 2013-06-17 17:25:20 +10:00
md_5
72f3a79759 Do what we can about Jline not being installed 2013-06-17 17:05:02 +10:00
md_5
dbb6aebf58 #3 windows fix 2013-06-17 16:29:21 +10:00
md_5
54040ec48d Windows fix #2 2013-06-17 16:17:50 +10:00
md_5
8c4ddf458c Fix #1 for windows. 2013-06-17 16:13:27 +10:00
md_5
07fb6490f8 Close issue #440 - players remaining after logout 2013-06-17 14:19:16 +10:00
Robin Lambertz
d9eb8c66b8 Change order of boolean so the latch is decremented all the time 2013-06-17 14:16:54 +10:00
md_5
7fab3ba372 Try twice to init jline 2013-06-16 21:27:15 +10:00
md_5
92c3ef1989 Fix custom tab API to allow using as soon as constructed 2013-06-16 15:40:31 +10:00
md_5
fbf2d8969e Exception caught should rely on channel activity state, not OUR close flag 2013-06-16 11:30:03 +10:00
md_5
1881507712 Move scoreboard stuff to the sscore package in preparation for refactor 2013-06-16 09:10:25 +10:00
md_5
fd2a72477f Move tab list stuff to the 'tab' package 2013-06-16 09:08:48 +10:00
md_5
d4cbac1bdf Add tab list getter to api 2013-06-16 07:56:38 +10:00
md_5
fa0671ab2a Finish up TabApi impl. 2013-06-16 07:55:15 +10:00
md_5
184154a8b3 Close issue #437 2013-06-16 07:26:29 +10:00
md_5
cbec4e836a Harsher reload warning 2013-06-15 21:12:15 +10:00
md_5
3ce7982778 Clean up pipeline flow. 2013-06-15 21:08:49 +10:00
md_5
b55944e2fb Dont spam the console with too many exceptions 2013-06-14 07:31:58 +10:00
md_5
12cba14657 Tweak our channel promise to be a bit more hellpful on errors 2013-06-13 20:53:35 +10:00
md_5
78e67283cc Roblabla feels listeners should be at the top 2013-06-11 20:23:48 +10:00
md_5
f0f1e71c93 Implement super sexy console to close #315 2013-06-11 18:55:15 +10:00
md_5
3c1a5aabfd Add translation + fix spelling for mojang servers down 2013-06-11 10:29:19 +10:00
md_5
f0d4e8c24a I feel like the time for change is here 2013-06-10 14:55:57 +10:00
md_5
ba8bd7faf0 Try to cut off packet race conditions when moving servers. 2013-06-10 08:54:52 +10:00
md_5
787692070e Set a row limit to stop at, we should shrink this after a while. Meh api is good enough for me 2013-06-08 15:48:26 +10:00
md_5
523e991018 Doesnt allow ALL possible variations of a string, but its good enough for now 2013-06-08 15:34:30 +10:00
md_5
7733fbfb28 Make tab list work! 2013-06-08 14:43:03 +10:00
md_5
44ac36941f Use 1 based index 2013-06-08 14:10:15 +10:00
md_5
0235c4a01e Make sure to init the tab list 2013-06-08 14:08:48 +10:00
md_5
b4220e9229 Refactor all the tab APIs 2013-06-08 14:06:09 +10:00
md_5
9b9addfccd Add interfaces for custom TabAPI, just need to add the hooks now, and of course a pretty example. As always, not tested yet. 2013-06-08 13:51:23 +10:00
md_5
b75a2b5060 [Breaking] Close #423 by making tab list per listener. 2013-06-08 13:13:17 +10:00
md_5
b5aecd5dcc Stab at fixing forge and wecui support when combined. F**** I hate mods. 2013-06-08 12:35:50 +10:00
md_5
4d51d16512 Fix mods like wecui not working after switching servers.
#364
2013-06-08 09:45:45 +10:00
md_5
05a9342854 Ramp up warning in preparation for breaking commit 2013-06-06 20:23:50 +10:00
md_5
483fede234 Work around windows bugs 2013-06-06 18:13:56 +10:00
md_5
ce8f1b44b6 Musical versions 2013-06-05 20:30:34 +10:00
md_5
b1e3f6a75b And people think dependancy loading is easy. Close #381 2013-06-05 18:24:33 +10:00
DerFlash
33d315b719 Tone down PingHandler too 2013-06-04 07:42:13 +10:00
md_5
d11e130d61 Close #365 - prettier error when mc.net is down 2013-06-03 19:54:41 +10:00
md_5
45a93c8cfc Close #417: whois -> find 2013-06-03 19:49:35 +10:00
md_5
fd411edddb Tone down logging for surprisingly large reduction in CPU usage - Closes #401 2013-06-03 19:48:21 +10:00
md_5
ac5e8dbaff Fix the bad packets! Naughty naughty packets! 2013-06-03 19:35:38 +10:00
md_5
340d82812a Reorder checks to prevent malformed packets throwing errors 2013-06-02 22:19:49 +10:00
md_5
eaf99cf4a6 Yo dawg. Lets start populating the seen row 2013-06-02 17:11:44 +10:00
md_5
4baae5a230 Add space to whois 2013-06-02 14:39:51 +10:00
md_5
aa1a871967 Actually use our threadLocal. Do'h 2013-06-02 14:33:47 +10:00
md_5
18f5ed3102 Close #410 - forge crashes 2013-06-02 10:30:44 +10:00
md_5
d1dd7379b1 Use cleaner equals check and actually set member field 2013-06-02 10:23:21 +10:00
md_5
0b0d09427d Proper case sensitivity + dont reverse lookup forced hosts 2013-06-02 09:23:05 +10:00
md_5
dce0f6b408 Missed some getters 2013-06-01 18:01:04 +10:00
md_5
c5307c4451 Dont use getters in team packet and add null check to team name 2013-06-01 18:00:17 +10:00
md_5
4f2b98188e Don't allow stupid users to connect bungee to themselves 2013-06-01 17:55:51 +10:00
md_5
d5eb37c7a6 Add debug to tryFailure 2013-06-01 17:46:11 +10:00
md_5
2a421cdd8d Close #306 use SQLite for reconnect locations 2013-06-01 17:29:14 +10:00
md_5
757f8f0cb9 Fix comparisons of objects in case insensitive hashmap 2013-06-01 16:07:17 +10:00
md_5
388d2620db Fix forge support with new protocol - closes #407 2013-06-01 12:55:02 +10:00
md_5
3ba52cb98b Might need a better way to do this...... oh well, add all the netbeans code style files 2013-06-01 11:12:03 +10:00
md_5
e652214071 Close issue #406 - tab list 2013-06-01 11:10:56 +10:00
md_5
0821404f92 Add netbeans config file 2013-06-01 11:09:46 +10:00
md-5
11b90b91b7 Update ServerConnection.java 2013-05-31 20:45:00 +10:00
md-5
aa3989db19 damn web editor 2013-05-31 19:26:15 +11:00
md-5
76c914db14 Update InitialHandler.java 2013-05-31 18:22:19 +10:00
md_5
639e5f3c1d Add 'unsafe' api for things like packet sending that may be implementation specific or break at any time 2013-05-31 17:02:45 +10:00
md_5
9fd69068ae [TESTING] Merge protocol api into master. This should provide slightly better performance and allow more flexibility for plugin developers. 2013-05-31 16:54:19 +10:00
md_5
9c35cad824 Will do final tests tomorrow, but all seems to work. Yay for efficiency and options for plugin developers! 2013-05-30 19:36:43 +10:00
md_5
d82b29e15a Finish up protocol API - we now compile again. Extensive testing is required, but that is for another day. 2013-05-30 19:11:05 +10:00
md_5
9b0c827c37 Now just to implement the necessary constructors and constants 2013-05-30 18:29:59 +10:00
md_5
125d3f07f7 Fix up failing test 2013-05-30 18:15:10 +10:00
md_5
2f45f0d578 Rework protocol system 2013-05-30 18:09:46 +10:00
md_5
ad4c143ce4 Finish and create passing unit tests for the integrity of all packet classes. 2013-05-30 17:34:56 +10:00
md_5
835e4e332c Start work on more efficient, publically accessable packet API 2013-05-30 16:38:53 +10:00
md_5
0578f94522 Rework shutdown sequence to close #391 2013-05-30 16:23:02 +10:00
md_5
0cd4c9030c Close #396 - broken API spec for "ALL" server 2013-05-29 12:03:41 +10:00
md_5
0d666168f0 Close #398 by printing debug so we can identify the issue if it arises again 2013-05-29 12:02:06 +10:00
md_5
cfb823f077 Close #395 - work around trove quirks 2013-05-29 12:00:57 +10:00
md_5
36a5e89ff9 I told you so 2013-05-27 19:28:50 +10:00
md_5
bb4e8e29a5 Update Netty version and remove our workaround - if this breaks, @mibby keeps the pieces. 2013-05-27 18:22:59 +10:00
md_5
8e34e038d6 Remove chat event firing when we get a message from server to client, as Mojang has decided to completely break this in the next major Minecraft release. 2013-05-26 21:24:32 +10:00
md_5
d1950389cc Just leave field as map... 2013-05-26 12:26:26 +10:00
md_5
9d841bb91a Store config in a case insensitive map 2013-05-26 12:25:46 +10:00
zSwayz
828cebcc4b Sexified
Pls add D:
2013-05-26 09:28:12 +10:00
md_5
12fec2fcdd Add some not null checks to API methods 2013-05-25 17:26:54 +10:00
md_5
8b6b134662 Maybe one day we will want to set this null - it can start null, so it can become null 2013-05-25 17:24:37 +10:00
md_5
538beb33a6 Remove now redundant field from InitialHandler 2013-05-25 17:22:43 +10:00
md_5
97338cbfad Its impossible unless you have a creative server and no mobs and no nothing, but we must allow 0 as an entity ID 2013-05-25 17:18:03 +10:00
md_5
3e28decef2 Remove getServer from the api - long depreceated 2013-05-25 17:09:29 +10:00
md_5
f93b647df3 Move protocol version declaration 2013-05-25 17:03:00 +10:00
md_5
775ffdc998 Optimize online count and broadcast methods 2013-05-25 17:01:39 +10:00
md_5
80c22027de Slightly more optimized getChannels 2013-05-25 16:52:41 +10:00
md_5
122987dd83 No space for lost connection translation 2013-05-25 16:50:39 +10:00
md_5
ac4bab2425 More case insensitive tests and read write lock for connections 2013-05-25 16:50:04 +10:00
md_5
a51ffb1f4c Use our own promise to work around @netty pipeline issues 2013-05-25 11:55:54 +10:00
md_5
77e0dcc7f8 Dont throw exceptions on missing translations 2013-05-25 11:54:17 +10:00
md_5
ddb93fd988 That was an easy test - just had time to write 2013-05-24 14:45:33 +10:00
md_5
7eac22d362 Make perms case insensitive - need to write unit test still 2013-05-24 14:44:40 +10:00
md_5
185dc97ca6 *chatcolor import 2013-05-24 14:41:15 +10:00
md_5
e0d19cf305 Show current server in server command 2013-05-24 14:37:40 +10:00
md_5
0e9002091b Add whois command 2013-05-24 14:35:27 +10:00
md_5
9fdcded97f Close #376 - case insensitive servers and maps 2013-05-24 14:31:31 +10:00
md_5
32fdc83841 Close #383 - swallow exceptions once and for all 2013-05-24 14:16:43 +10:00
md_5
1bf126d4f8 Close #384 - reset locations.yml on error 2013-05-24 14:12:50 +10:00
md_5
56533c6259 Close issue #374 - take a lock when checking channel state / writing 2013-05-23 13:49:58 +10:00
md-5
4cb46c6e5c Merge pull request #372 from roblabla/patch-2
Add global PlayerCount if target is "ALL"
2013-05-22 05:01:48 -07:00
md_5
6decf860c9 Update warning 2013-05-22 21:01:52 +10:00
md_5
29f22f9be9 Just swallow the error because thats what we did before. 2013-05-22 18:27:53 +10:00
md_5
98860ffd02 SLightly more atomic locations.yml saving to guard against ctrl+c'ing users 2013-05-22 17:07:46 +10:00
md_5
2c225a05e7 Add atomic close tracking. Closes #370. 2013-05-22 09:24:55 +10:00
Robin Lambertz
c1dfd0fb7b Add global PlayerCount if target is "ALL"
This allows bukkit servers to get the global bungeecord player count.
2013-05-21 22:14:00 +02:00
md_5
9be44d51a6 Update to netty CR3 2013-05-21 11:30:05 +10:00
md_5
2a2c2717d5 Connect via bound address - closes #337.
Blame JacobiCarter if this breaks
2013-05-19 18:14:59 +10:00
md_5
3f994a1c4c Downgrade to @netty CR1 2013-05-19 18:02:01 +10:00
md_5
9a0da50e6c Fix formatting 2013-05-16 16:49:14 +10:00
md_5
67fdc830c2 Protected access please 2013-05-16 16:47:21 +10:00
md_5
64e8a79551 Close #348 - translation key 2013-05-16 06:40:01 +10:00
md_5
afc387ce0d Set local address to listener address, closes #337 (reverse-merged from commit 57793e93f0) 2013-05-16 06:39:29 +10:00
md_5
8a70af5293 Clean up code style surrounding bootstrap creation 2013-05-15 19:08:14 +10:00
md_5
57793e93f0 Set local address to listener address, closes #337 2013-05-15 19:05:38 +10:00
md_5
a48ef137bd Make connect event implement cancellable, closes #338 2013-05-15 19:04:22 +10:00
md_5
ff32d29e09 Gracefully shutdown event loop, closes #346 2013-05-15 19:02:10 +10:00
md_5
9f3359f8fa Thanks Lex! Closes #319 2013-05-15 18:59:13 +10:00
Jacobi Carter
539fccb873 The client handles the server sending the same score multiple times to overwrite the previous entry. 2013-05-14 18:52:12 +10:00
md_5
b25c81daf3 Update to latest netty, fix event bus bug, comment and rework PacketDecoder to new netty for better performance 2013-05-14 18:32:30 +10:00
md_5
21a354fa75 Add home grown event bus 2013-05-14 11:38:39 +10:00
mickare
aefe3333a9 Add per plugin loggers 2013-05-14 11:19:01 +10:00
md_5
0afefa8f61 Allow nested event dispatch. Yet another thing which I should one day try and PR to Guava 2013-05-13 18:39:45 +10:00
md_5
834ac24b38 Add EventBus test, which fails, now to fix! 2013-05-13 18:36:12 +10:00
md_5
c465eca03b Just escape utf chars 2013-05-12 22:01:42 +10:00
md_5
beb0bf9836 Fu*** offline mode users 2013-05-12 16:09:21 +10:00
md_5
688c42219c Actually translate message 2013-05-12 15:55:51 +10:00
md_5
1ea53f01aa Add a series of new translations 2013-05-12 13:40:43 +10:00
md_5
202dab5c98 Add texture pack API 2013-05-12 09:28:36 +10:00
md_5
49ea7f908f Add server switch event 2013-05-12 09:15:17 +10:00
Harry
9d3bddedb6 Return if command should not be executed to avoid exceptions and unnecessary messages to the player. 2013-05-06 07:22:56 +10:00
md_5
332bdaaec0 Refactor forge support - closes #318 2013-05-05 08:31:44 +10:00
md_5
904a1bfaa3 *register channels. This fixes plugins being broke 2013-05-04 10:20:53 +10:00
md_5
5eb7a6eba7 Fix forge support - closes #312 2013-05-04 09:40:10 +10:00
md_5
8e262cf428 Close issue #311 - exception feedback on server connector 2013-05-04 09:28:28 +10:00
md_5
125df5c22d Add SQLite driver for future use 2013-05-03 21:25:47 +10:00
md_5
7b631092f5 Add experimental Forge support. This may cause issues when using Vanilla clients etc, so caution is advised. Please visit GitHub to report any issues you encounter. Thanks @LexManos for providing the basis for this implementation. 2013-05-03 21:21:55 +10:00
md_5
d3c1339cc9 Make sure we write out custom login packets 2013-05-03 20:36:55 +10:00
md_5
679bf2fca9 Synchronize on pending packet queue, add forge/no forge constructor argument to login packet, and don't send channel registers twice 2013-05-03 20:29:36 +10:00
md_5
7436621481 Refactor encryption to be two step like vanilla. Thanks @LexManos for pointing this out. 2013-05-03 19:35:00 +10:00
md_5
6236cff658 Refactor encrypt util class in preparation for forge support. 2013-05-03 19:10:54 +10:00
md_5
6b504d9160 Use faster collections for the various tab lists. 2013-05-03 18:20:10 +10:00
md_5
d1124ca70b Cleanup imports 2013-05-03 14:39:25 +10:00
md_5
779582d441 Use multimap in scheduler 2013-05-03 14:33:04 +10:00
md_5
b91564f77a Fix eclipse gitignore, I think - don't use eclipse 2013-05-03 14:24:35 +10:00
Zach Bruggeman
30b2e5008b Add ResourceBundle localization 2013-05-03 14:22:12 +10:00
md_5
140830efe0 Close #300 - cleaner disconnects when server is full 2013-05-03 14:16:48 +10:00
md_5
5f8e76c61c Revert "ConcurrentHashMap is junk - lets stick to standard unless issues arise."
This reverts commit 5d1a2c59a7 and closes #304
2013-05-03 14:15:23 +10:00
md_5
b7511abfda Update to 1.5.2, closes #302 2013-05-02 07:32:45 +10:00
397 changed files with 40095 additions and 5052 deletions

63
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View 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
View 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.

View 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

27
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,27 @@
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"
# Needs to be synchronised with maven-resolver-provider dependencies
- dependency-name: "org.apache.maven.resolver:maven-resolver-connector-basic"
- dependency-name: "org.apache.maven.resolver:maven-resolver-transport-http"
# 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

23
.github/workflows/maven.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: Maven Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
java: [8, 11, 17, 21]
name: Java ${{ matrix.java }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: zulu
java-version: ${{ matrix.java }}
- run: java -version && mvn --version
- run: mvn --activate-profiles dist --no-transfer-progress package

11
.gitignore vendored
View File

@ -1,12 +1,11 @@
# Eclipse stuff
.classpath/
.project/
.classpath
.project
.settings/
# netbeans
nbproject/
nbactions.xml
nb-configuration.xml
# we use maven!
build.xml
@ -25,7 +24,7 @@ dist/
manifest.mf
# Mac filesystem dust
.DS_Store/
.DS_Store
# intellij
*.iml
@ -35,4 +34,6 @@ manifest.mf
# other files
*.log*
*.yml
# delombok
*/src/main/lombok

6
.gitmodules vendored Normal file
View 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

View File

@ -1,5 +0,0 @@
language: java
jdk:
- openjdk7
notifications:
email: false

View File

@ -1,19 +1,26 @@
BungeeCord
==========
The most reliable Minecraft server portal suite.
------------------------------------------------
BungeeCord is a piece of Java software which allows a user to link multiple Minecraft servers together, allowing players to teleport between them and access advanced features. This makes it perfect for servers looking to expand their player base and spread across multiple gameplay styles.
Layer 7 proxy designed to link Minecraft servers.
--------------------------------------------------
History
-------
For a long time developers have tried to create these mythical 'cloud' systems as outlined above. Until now, none of them have succeeded in making a fully open source and reliable 'cloud'. You may have already noticed my quoting of the word 'cloud', and this is one of the last times you will see it in this document. BungeeCord is **NOT** a 'cloud'. The actual meaning of the aforementioned word is quoted below:
BungeeCord is a sophisticated proxy and API designed mainly to teleport players between multiple Minecraft servers. It is the latest incarnation of similar software written by the author from 2011-present.
>The use of computing resources (hardware and software) that are delivered as a service over a network (typically the Internet).
Information
-----------
BungeeCord is maintained by [SpigotMC](https://www.spigotmc.org/) and has its own [discussion thread](https://www.spigotmc.org/go/bungeecord) with plenty of helpful information and links.
BungeeCord does not do this and therefore is not a 'cloud'. Please do not refer to it as one, since the owners and operators of real clouds will get very angry, and you will be seen as ignorant and stupid. Instead I encourage you to use the term 'Server Port Suite' or something to that effect.
### Security warning
Installation & Usage
--------------------
For and in depth guide to the installation and usage of BungeeCord you should check the current primary download location. The current link is provided below for your convenience.
As your Minecraft servers have to run without authentication (online-mode=false) for BungeeCord to work, this poses a new security risk. Users may connect to your servers directly, under any username they wish to use. The kick "If you wish to use IP forwarding, please enable it in your BungeeCord config as well!" does not protect your Spigot servers.
<http://www.spigotmc.org/threads/bungeecord.392/>
To combat this, you need to restrict access to these servers for example with a firewall (please see [firewall guide](https://www.spigotmc.org/wiki/firewall-guide/)).
Source
------
Source code is currently available on [GitHub](https://www.spigotmc.org/go/bungeecord-git).
Binaries
--------
Precompiled binaries are available for end users on [Jenkins](https://www.spigotmc.org/go/bungeecord-dl).
(c) 2012-2024 SpigotMC Pty. Ltd.

31
api/nb-configuration.xml Normal file
View File

@ -0,0 +1,31 @@
<?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>

View File

@ -4,15 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.md-5</groupId>
<groupId>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-parent</artifactId>
<version>1.5-SNAPSHOT</version>
<version>1.21-R0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.5-SNAPSHOT</version>
<version>1.21-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>BungeeCord-API</name>
@ -20,21 +19,59 @@
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0.1</version>
<groupId>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-chat</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.ning</groupId>
<artifactId>async-http-client</artifactId>
<version>1.7.14</version>
<groupId>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-config</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-event</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-protocol</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-unix-common</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-resolver-provider</artifactId>
<version>3.9.6</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.9.18</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.9.18</version>
<!-- not part of the API proper -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.12</version>
<version>2.2</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -1,111 +0,0 @@
/*
* Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.common.eventbus;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.reflect.TypeToken;
import com.google.common.util.concurrent.UncheckedExecutionException;
import java.lang.reflect.Method;
import java.util.Set;
/**
* A {@link HandlerFindingStrategy} for collecting all event handler methods that are marked with
* the {@link Subscribe} annotation.
*
* @author Cliff Biffle
* @author Louis Wasserman
*/
class AnnotatedHandlerFinder implements HandlerFindingStrategy {
/**
* A thread-safe cache that contains the mapping from each class to all methods in that class and
* all super-classes, that are annotated with {@code @Subscribe}. The cache is shared across all
* instances of this class; this greatly improves performance if multiple EventBus instances are
* created and objects of the same class are registered on all of them.
*/
private static final LoadingCache<Class<?>, ImmutableList<Method>> handlerMethodsCache =
CacheBuilder.newBuilder()
.weakKeys()
.build(new CacheLoader<Class<?>, ImmutableList<Method>>() {
@Override
public ImmutableList<Method> load(Class<?> concreteClass) throws Exception {
return getAnnotatedMethodsInternal(concreteClass);
}
});
/**
* {@inheritDoc}
*
* This implementation finds all methods marked with a {@link Subscribe} annotation.
*/
@Override
public Multimap<Class<?>, EventHandler> findAllHandlers(Object listener) {
Multimap<Class<?>, EventHandler> methodsInListener = HashMultimap.create();
Class<?> clazz = listener.getClass();
for (Method method : getAnnotatedMethods(clazz)) {
Class<?>[] parameterTypes = method.getParameterTypes();
Class<?> eventType = parameterTypes[0];
EventHandler handler = new EventHandler(listener, method);
methodsInListener.put(eventType, handler);
}
return methodsInListener;
}
private static ImmutableList<Method> getAnnotatedMethods(Class<?> clazz) {
try {
return handlerMethodsCache.getUnchecked(clazz);
} catch (UncheckedExecutionException e) {
throw Throwables.propagate(e.getCause());
}
}
private static ImmutableList<Method> getAnnotatedMethodsInternal(Class<?> clazz) {
Set<? extends Class<?>> supers = TypeToken.of(clazz).getTypes().rawTypes();
ImmutableList.Builder<Method> result = ImmutableList.builder();
for (Method method : clazz.getMethods()) {
/*
* Iterate over each distinct method of {@code clazz}, checking if it is annotated with
* @Subscribe by any of the superclasses or superinterfaces that declare it.
*/
for (Class<?> c : supers) {
try {
Method m = c.getMethod(method.getName(), method.getParameterTypes());
if (m.isAnnotationPresent(Subscribe.class)) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 1) {
throw new IllegalArgumentException("Method " + method
+ " has @Subscribe annotation, but requires " + parameterTypes.length
+ " arguments. Event handler methods must require a single argument.");
}
Class<?> eventType = parameterTypes[0];
result.add(method);
break;
}
} catch (NoSuchMethodException ignored) {
// Move on.
}
}
}
return result.build();
}
}

View File

@ -0,0 +1,141 @@
package net.md_5.bungee;
import com.google.common.base.Joiner;
import com.google.common.primitives.UnsignedLongs;
import io.netty.channel.unix.DomainSocketAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
import java.util.UUID;
/**
* Series of utility classes to perform various operations.
*/
public class Util
{
public static final int DEFAULT_PORT = 25565;
/**
* Method to transform human readable addresses into usable address objects.
*
* @param hostline in the format of 'host:port'
* @return the constructed hostname + port.
*/
public static SocketAddress getAddr(String hostline)
{
URI uri = null;
try
{
uri = new URI( hostline );
} catch ( URISyntaxException ex )
{
}
if ( uri != null && "unix".equals( uri.getScheme() ) )
{
return new DomainSocketAddress( uri.getPath() );
}
if ( uri == null || uri.getHost() == null )
{
try
{
uri = new URI( "tcp://" + hostline );
} catch ( URISyntaxException ex )
{
throw new IllegalArgumentException( "Bad hostline: " + hostline, ex );
}
}
if ( uri.getHost() == null )
{
throw new IllegalArgumentException( "Invalid host/address: " + hostline );
}
return new InetSocketAddress( uri.getHost(), ( uri.getPort() ) == -1 ? DEFAULT_PORT : uri.getPort() );
}
/**
* Formats an integer as a hex value.
*
* @param i the integer to format
* @return the hex representation of the integer
*/
public static String hex(int 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
* debugging.
*
* @param t the {@link Throwable} to format.
* @return a string representing information about the {@link Throwable}
*/
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
StackTraceElement[] trace = t.getStackTrace();
return t.getClass().getSimpleName() + " : " + t.getMessage()
+ ( ( includeLineNumbers && trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" );
}
public static String csv(Iterable<?> 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)
{
return Joiner.on( separators ).join( objects );
}
/**
* Converts a String to a UUID
*
* @param uuid The string to be converted
* @return The result
*/
public static UUID getUUID(String uuid)
{
return new UUID( UnsignedLongs.parseUnsignedLong( uuid.substring( 0, 16 ), 16 ), UnsignedLongs.parseUnsignedLong( uuid.substring( 16 ), 16 ) );
}
}

View File

@ -0,0 +1,41 @@
package net.md_5.bungee.api;
import com.google.common.base.Preconditions;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public abstract class AbstractReconnectHandler implements ReconnectHandler
{
@Override
public ServerInfo getServer(ProxiedPlayer player)
{
ServerInfo server = getForcedHost( player.getPendingConnection() );
if ( server == null )
{
server = getStoredServer( player );
if ( server == null )
{
server = ProxyServer.getInstance().getServerInfo( player.getPendingConnection().getListener().getDefaultServer() );
}
Preconditions.checkState( server != null, "Default server not defined" );
}
return server;
}
public static ServerInfo getForcedHost(PendingConnection con)
{
String forced = ( con.getVirtualHost() == null ) ? null : con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() );
if ( forced == null && con.getListener().isForceDefault() )
{
forced = con.getListener().getDefaultServer();
}
return ( forced == null ) ? null : ProxyServer.getInstance().getServerInfo( forced );
}
protected abstract ServerInfo getStoredServer(ProxiedPlayer player);
}

View File

@ -1,186 +0,0 @@
package net.md_5.bungee.api;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Simplistic enumeration of all supported color values for chat.
*/
public enum ChatColor
{
/**
* Represents black.
*/
BLACK( '0' ),
/**
* Represents dark blue.
*/
DARK_BLUE( '1' ),
/**
* Represents dark green.
*/
DARK_GREEN( '2' ),
/**
* Represents dark blue (aqua).
*/
DARK_AQUA( '3' ),
/**
* Represents dark red.
*/
DARK_RED( '4' ),
/**
* Represents dark purple.
*/
DARK_PURPLE( '5' ),
/**
* Represents gold.
*/
GOLD( '6' ),
/**
* Represents gray.
*/
GRAY( '7' ),
/**
* Represents dark gray.
*/
DARK_GRAY( '8' ),
/**
* Represents blue.
*/
BLUE( '9' ),
/**
* Represents green.
*/
GREEN( 'a' ),
/**
* Represents aqua.
*/
AQUA( 'b' ),
/**
* Represents red.
*/
RED( 'c' ),
/**
* Represents light purple.
*/
LIGHT_PURPLE( 'd' ),
/**
* Represents yellow.
*/
YELLOW( 'e' ),
/**
* Represents white.
*/
WHITE( 'f' ),
/**
* Represents magical characters that change around randomly.
*/
MAGIC( 'k' ),
/**
* Makes the text bold.
*/
BOLD( 'l' ),
/**
* Makes a line appear through the text.
*/
STRIKETHROUGH( 'm' ),
/**
* Makes the text appear underlined.
*/
UNDERLINE( 'n' ),
/**
* Makes the text italic.
*/
ITALIC( 'o' ),
/**
* Resets all previous chat colors or formats.
*/
RESET( 'r' );
/**
* The special character which prefixes all chat colour codes. Use this if
* you need to dynamically convert colour codes from your custom format.
*/
public static final char COLOR_CHAR = '\u00A7';
/**
* Pattern to remove all colour codes.
*/
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile( "(?i)" + String.valueOf( COLOR_CHAR ) + "[0-9A-FK-OR]" );
/**
* Colour instances keyed by their active character.
*/
private static final Map<Character, ChatColor> BY_CHAR = new HashMap<>();
/**
* The code appended to {@link #COLOR_CHAR} to make usable colour.
*/
private final char code;
/**
* This colour's colour char prefixed by the {@link #COLOR_CHAR}.
*/
private final String toString;
static
{
for ( ChatColor colour : values() )
{
BY_CHAR.put( colour.code, colour );
}
}
private ChatColor(char code)
{
this.code = code;
this.toString = new String( new char[]
{
COLOR_CHAR, code
} );
}
@Override
public String toString()
{
return toString;
}
/**
* Strips the given message of all color codes
*
* @param input String to strip of color
* @return A copy of the input string, without any coloring
*/
public static String stripColor(final String input)
{
if ( input == null )
{
return null;
}
return STRIP_COLOR_PATTERN.matcher( input ).replaceAll( "" );
}
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate)
{
char[] b = textToTranslate.toCharArray();
for ( int i = 0; i < b.length - 1; i++ )
{
if ( b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf( b[i + 1] ) > -1 )
{
b[i] = ChatColor.COLOR_CHAR;
b[i + 1] = Character.toLowerCase( b[i + 1] );
}
}
return new String( b );
}
/**
* Get the colour represented by the specified code.
*
* @param code the code to search for
* @return the mapped colour, or null if non exists
*/
public static ChatColor getByChar(char code)
{
return BY_CHAR.get( code );
}
}

View File

@ -1,6 +1,7 @@
package net.md_5.bungee.api;
import java.util.Collection;
import net.md_5.bungee.api.chat.BaseComponent;
public interface CommandSender
{
@ -17,6 +18,7 @@ public interface CommandSender
*
* @param message the message to send
*/
@Deprecated
public void sendMessage(String message);
/**
@ -25,8 +27,23 @@ public interface CommandSender
*
* @param messages the messages to send
*/
@Deprecated
public void sendMessages(String... messages);
/**
* Send a message to this sender.
*
* @param message the message to send
*/
public void sendMessage(BaseComponent... message);
/**
* Send a message to this sender.
*
* @param message the message to send
*/
public void sendMessage(BaseComponent message);
/**
* Get all groups this user is part of. This returns an unmodifiable
* collection.
@ -64,4 +81,12 @@ public interface CommandSender
* @param value the value of the node
*/
public void setPermission(String permission, boolean value);
/**
* Get all Permissions which this CommandSender has
*
* @return a unmodifiable Collection of Strings which represent their
* permissions
*/
public Collection<String> getPermissions();
}

View File

@ -0,0 +1,121 @@
package net.md_5.bungee.api;
import com.google.common.base.Preconditions;
import com.google.common.io.BaseEncoding;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
/**
* Favicon shown in the server list.
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class Favicon
{
private static final TypeAdapter<Favicon> FAVICON_TYPE_ADAPTER = new TypeAdapter<Favicon>()
{
@Override
public void write(JsonWriter out, Favicon value) throws IOException
{
if ( value == null )
{
out.nullValue();
} else
{
out.value( value.getEncoded() );
}
}
@Override
public Favicon read(JsonReader in) throws IOException
{
JsonToken peek = in.peek();
if ( peek == JsonToken.NULL )
{
in.nextNull();
return null;
}
String enc = in.nextString();
return enc == null ? null : create( enc );
}
};
public static TypeAdapter<Favicon> getFaviconTypeAdapter()
{
return FAVICON_TYPE_ADAPTER;
}
/**
* The base64 encoded favicon, including MIME header.
*/
@NonNull
@Getter
private final String encoded;
/**
* Creates a favicon from an image.
*
* @param image the image to create on
* @return the created favicon instance
* @throws IllegalArgumentException if the favicon is larger than
* {@link Short#MAX_VALUE} or not of dimensions 64x64 pixels.
*/
public static Favicon create(BufferedImage image)
{
Preconditions.checkArgument( image != null, "image is null" );
// check size
if ( image.getWidth() != 64 || image.getHeight() != 64 )
{
throw new IllegalArgumentException( "Server icon must be exactly 64x64 pixels" );
}
// dump image PNG
byte[] imageBytes;
try
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write( image, "PNG", stream );
imageBytes = stream.toByteArray();
} catch ( IOException e )
{
// ByteArrayOutputStream should never throw this
throw new AssertionError( e );
}
// encode with header
String encoded = "data:image/png;base64," + BaseEncoding.base64().encode( imageBytes );
// check encoded image size
if ( encoded.length() > Short.MAX_VALUE )
{
throw new IllegalArgumentException( "Favicon file too large for server to process" );
}
// create
return new Favicon( encoded );
}
/**
* Creates a Favicon from an encoded PNG.
*
* @param encodedString a base64 mime encoded PNG string
* @return the created favicon
* @deprecated Use #create(java.awt.image.BufferedImage) instead
*/
@Deprecated
public static Favicon create(String encodedString)
{
return new Favicon( encodedString );
}
}

View File

@ -0,0 +1,128 @@
package net.md_5.bungee.api;
import java.util.Collection;
import java.util.Map;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.config.ServerInfo;
/**
* Core configuration adaptor for the proxy api.
*
* @deprecated This class is subject to rapid change between releases
*/
@Deprecated
public interface ProxyConfig
{
/**
* Time before users are disconnected due to no network activity.
*
* @return timeout
*/
int getTimeout();
/**
* UUID used for metrics.
*
* @return uuid
*/
String getUuid();
/**
* Set of all listeners.
*
* @return listeners
*/
Collection<ListenerInfo> getListeners();
/**
* Set of all servers.
*
* @return servers
*/
Map<String, ServerInfo> getServers();
/**
* Does the server authenticate with Mojang.
*
* @return online mode
*/
boolean isOnlineMode();
/**
* Whether proxy commands are logged to the proxy log.
*
* @return log commands
*/
boolean isLogCommands();
/**
* Time in milliseconds to cache server list info from a ping request from
* the proxy to a server.
*
* @return cache time
*/
int getRemotePingCache();
/**
* Returns the player max.
*
* @return player limit
*/
int getPlayerLimit();
/**
* A collection of disabled commands.
*
* @return disabled commands
*/
Collection<String> getDisabledCommands();
/**
* Time in milliseconds before timing out a clients request to connect to a
* server.
*
* @return connect timeout
*/
int getServerConnectTimeout();
/**
* Time in milliseconds before timing out a ping request from the proxy to a
* server when attempting to request server list info.
*
* @return ping timeout
*/
int getRemotePingTimeout();
/**
* The connection throttle delay.
*
* @return throttle
*/
@Deprecated
int getThrottle();
/**
* Whether the proxy will parse IPs with spigot or not.
*
* @return ip forward
*/
@Deprecated
boolean isIpForward();
/**
* The encoded favicon.
*
* @return favicon
* @deprecated Use #getFaviconObject instead.
*/
@Deprecated
String getFavicon();
/**
* The favicon used for the server ping list.
*
* @return favicon
*/
Favicon getFaviconObject();
}

View File

@ -1,19 +1,20 @@
package net.md_5.bungee.api;
import net.md_5.bungee.api.plugin.PluginManager;
import com.google.common.base.Preconditions;
import com.ning.http.client.AsyncHttpClient;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
import lombok.Getter;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.config.ConfigurationAdapter;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginManager;
import net.md_5.bungee.api.scheduler.TaskScheduler;
public abstract class ProxyServer
@ -49,6 +50,15 @@ public abstract class ProxyServer
*/
public abstract String getVersion();
/**
* Gets a localized string from the .properties file.
*
* @param name translation name
* @param args translation arguments
* @return the localized string
*/
public abstract String getTranslation(String name, Object... args);
/**
* Gets the main logger which can be used as a suitable replacement for
* {@link System#out} and {@link System#err}.
@ -73,18 +83,12 @@ public abstract class ProxyServer
public abstract ProxiedPlayer getPlayer(String name);
/**
* Get a server by its name. The instance returned will be taken from a
* player currently on that server to facilitate abstract proxy -> server
* actions.
* Gets a connected player via their UUID
*
* @param name the name to lookup
* @return the associated server
* @deprecated in most cases the {@link #getServerInfo(java.lang.String)}
* method should be used, as it will return a server even when no players
* are online.
* @param uuid of the player
* @return their player instance
*/
@Deprecated
public abstract Server getServer(String name);
public abstract ProxiedPlayer getPlayer(UUID uuid);
/**
* Return all servers registered to this proxy, keyed by name. Unlike the
@ -127,21 +131,6 @@ public abstract class ProxyServer
*/
public abstract void setConfigurationAdapter(ConfigurationAdapter adapter);
/**
* Get the currently in use tab list handle.
*
* @return the tab list handler
*/
public abstract TabListHandler getTabListHandler();
/**
* Set the used tab list handler, should not be changed once players have
* connected
*
* @param handler the tab list handler to set
*/
public abstract void setTabListHandler(TabListHandler handler);
/**
* Get the currently in use reconnect handler.
*
@ -162,12 +151,11 @@ public abstract class ProxyServer
public abstract void stop();
/**
* Start this instance so that it may accept connections.
* Gracefully mark this instance for shutdown.
*
* @throws Exception any exception thrown during startup causing the
* instance to fail to boot
* @param reason the reason for stopping. This will be shown to players.
*/
public abstract void start() throws Exception;
public abstract void stop(String reason);
/**
* Register a channel for use with plugin messages. This is required by some
@ -196,6 +184,7 @@ public abstract class ProxyServer
*
* @return the supported Minecraft version
*/
@Deprecated
public abstract String getGameVersion();
/**
@ -203,7 +192,8 @@ public abstract class ProxyServer
*
* @return the Minecraft protocol version
*/
public abstract byte getProtocolVersion();
@Deprecated
public abstract int getProtocolVersion();
/**
* Factory method to construct an implementation specific server info
@ -211,10 +201,23 @@ public abstract class ProxyServer
*
* @param name name of the server
* @param address connectable Minecraft address + port of the server
* @param motd the motd when used as a forced server
* @param restricted whether the server info restricted property will be set
* @return the constructed instance
*/
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address, boolean restricted);
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address, String motd, boolean restricted);
/**
* Factory method to construct an implementation specific server info
* instance.
*
* @param name name of the server
* @param address connectable Minecraft address + port of the server
* @param motd the motd when used as a forced server
* @param restricted whether the server info restricted property will be set
* @return the constructed instance
*/
public abstract ServerInfo constructServerInfo(String name, SocketAddress address, String motd, boolean restricted);
/**
* Returns the console overlord for this proxy. Being the console, this
@ -240,11 +243,72 @@ public abstract class ProxyServer
public abstract TaskScheduler getScheduler();
/**
* Gets the the web client used by this proxy to facilitate making web
* requests. Care should be taken to ensure that all operations are non
* blocking where applicable.
* Get the current number of connected users. The default implementation is
* more efficient than {@link #getPlayers()} as it does not take a lock or
* make a copy.
*
* @return the server's {@link AsyncHttpClient} instance
* @return the current number of connected players
*/
public abstract AsyncHttpClient getHttpClient();
public abstract int getOnlineCount();
/**
* Send the specified message to the console and all connected players.
*
* @param message the message to broadcast
*/
@Deprecated
public abstract void broadcast(String message);
/**
* Send the specified message to the console and all connected players.
*
* @param message the message to broadcast
*/
public abstract void broadcast(BaseComponent... message);
/**
* Send the specified message to the console and all connected players.
*
* @param message the message to broadcast
*/
public abstract void broadcast(BaseComponent message);
/**
* Gets the commands which are disabled and will not be run on this proxy.
*
* @return the set of disabled commands
*/
public abstract Collection<String> getDisabledCommands();
/**
* Gets BungeeCord's core config.
*
* @return the config.
*/
public abstract ProxyConfig getConfig();
/**
* Attempts to match any players with the given name, and returns a list of
* all possible matches.
*
* The exact algorithm to use to match players is implementation specific,
* but in general you can expect this method to return player's whose names
* begin with the specified prefix.
*
* @param match the (partial) name to match
* @return list of all possible players, singleton if there is an exact
* match
*/
public abstract Collection<ProxiedPlayer> matchPlayer(String match);
/**
* Creates a new empty title configuration. In most cases you will want to
* {@link Title#reset()} the current title first so your title won't be
* affected by a previous one.
*
* @return A new empty title configuration.
* @see Title
*/
public abstract Title createTitle();
}

View File

@ -12,7 +12,7 @@ public interface ReconnectHandler
* @param player the connecting player
* @return the server to connect to
*/
public ServerInfo getServer(ProxiedPlayer player);
ServerInfo getServer(ProxiedPlayer player);
/**
* Save the server of this player before they disconnect so it can be
@ -20,12 +20,20 @@ public interface ReconnectHandler
*
* @param player the player to save
*/
public void setServer(ProxiedPlayer player);
void setServer(ProxiedPlayer player); // TOOD: String + String arguments?
/**
* Save all pending reconnect locations. Whilst not used for database
* connections, this method will be called at a predefined interval to allow
* the saving of reconnect files.
*/
public void save();
void save();
/**
* Close all connections indicating that the proxy is about to shutdown and
* all data should be saved. No new requests will be made after this method
* has been called.
*
*/
void close();
}

View File

@ -0,0 +1,81 @@
package net.md_5.bungee.api;
import lombok.Builder;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectEvent;
/**
* A request to connect a server.
*/
@Getter
@Builder(builderClassName = "Builder")
public class ServerConnectRequest
{
/**
* The result from this callback after request has been executed by proxy.
*/
public enum Result
{
/**
* ServerConnectEvent to the new server was canceled.
*/
EVENT_CANCEL,
/**
* Already connected to target server.
*/
ALREADY_CONNECTED,
/**
* Already connecting to target server.
*/
ALREADY_CONNECTING,
/**
* Successfully connected to server.
*/
SUCCESS,
/**
* Connection failed, error can be accessed from callback method handle.
*/
FAIL
}
/**
* Target server to connect to.
*/
@NonNull
private final ServerInfo target;
/**
* Reason for connecting to server.
*/
@NonNull
private final ServerConnectEvent.Reason reason;
/**
* Callback to execute post request.
*/
private final Callback<Result> callback;
/**
* Timeout in milliseconds for request.
*/
@Setter
private int connectTimeout;
/**
* Should the player be attempted to connect to the next server in their
* queue if the initial request fails.
*/
@Setter
private boolean retry;
/**
* Class that sets default properties/adds methods to the lombok builder
* generated class.
*/
public static class Builder
{
private int connectTimeout = ProxyServer.getInstance().getConfig().getServerConnectTimeout();
}
}

View File

@ -1,33 +1,160 @@
package net.md_5.bungee.api;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import net.md_5.bungee.Util;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
/**
* Represents the standard list data returned by opening a server in the
* Minecraft client server list, or hitting it with a packet 0xFE.
*/
@Data
@ToString(exclude = "favicon")
@NoArgsConstructor
@AllArgsConstructor
public class ServerPing
{
/**
* Numeric protocol version supported by the server.
*/
private final byte protocolVersion;
/**
* Human readable game version.
*/
private final String gameVersion;
/**
* Server MOTD.
*/
private final String motd;
/**
* Current amount of players on the server.
*/
private final int currentPlayers;
/**
* Max amount of players the server will allow.
*/
private final int maxPlayers;
private Protocol version;
@Data
@AllArgsConstructor
public static class Protocol
{
private String name;
private int protocol;
}
private Players players;
@Data
@AllArgsConstructor
public static class Players
{
private int max;
private int online;
private PlayerInfo[] sample;
}
@Data
@AllArgsConstructor
public static class PlayerInfo
{
private String name;
private UUID uniqueId;
private static final UUID md5UUID = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" );
public PlayerInfo(String name, String id)
{
setName( name );
setId( id );
}
public void setId(String id)
{
try
{
uniqueId = Util.getUUID( id );
} catch ( Exception e )
{
// Fallback on a valid uuid otherwise Minecraft complains
uniqueId = md5UUID;
}
}
public String getId()
{
return uniqueId.toString().replace( "-", "" );
}
}
private BaseComponent description;
private Favicon favicon;
@Data
public static class ModInfo
{
private String type = "FML";
private List<ModItem> modList = new ArrayList<>();
}
@Data
@AllArgsConstructor
public static class ModItem
{
private String modid;
private String version;
}
// Right now, we don't get the mods from the user, so we just use a stock ModInfo object to
// create the server ping. Vanilla clients will ignore this.
private final ModInfo modinfo = new ModInfo();
@Deprecated
public ServerPing(Protocol version, Players players, String description, String favicon)
{
this( version, players, TextComponent.fromLegacy( description ), favicon == null ? null : Favicon.create( favicon ) );
}
@Deprecated
public ServerPing(Protocol version, Players players, String description, Favicon favicon)
{
this( version, players, TextComponent.fromLegacy( description ), favicon );
}
@Deprecated
public String getFavicon()
{
return getFaviconObject() == null ? null : getFaviconObject().getEncoded();
}
public Favicon getFaviconObject()
{
return this.favicon;
}
@Deprecated
public void setFavicon(String favicon)
{
setFavicon( favicon == null ? null : Favicon.create( favicon ) );
}
public void setFavicon(Favicon favicon)
{
this.favicon = favicon;
}
@Deprecated
public void setDescription(String description)
{
this.description = TextComponent.fromLegacy( description );
}
@Deprecated
public String getDescription()
{
return BaseComponent.toLegacyText( description );
}
public void setDescriptionComponent(BaseComponent description)
{
this.description = description;
}
public BaseComponent getDescriptionComponent()
{
return description;
}
}

View File

@ -0,0 +1,24 @@
package net.md_5.bungee.api;
/**
* Represents a player's skin settings. These settings can be changed by the
* player under Skin Configuration in the Options menu.
*/
public interface SkinConfiguration
{
boolean hasCape();
boolean hasJacket();
boolean hasLeftSleeve();
boolean hasRightSleeve();
boolean hasLeftPants();
boolean hasRightPants();
boolean hasHat();
}

View File

@ -1,48 +0,0 @@
package net.md_5.bungee.api;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public interface TabListHandler
{
/**
* Called when a player first connects to the proxy.
*
* @param player the connecting player
*/
public void onConnect(ProxiedPlayer player);
/**
* Called when a player changes their connected server.
*
* @param player the player who changed servers
*/
public void onServerChange(ProxiedPlayer player);
/**
* Called when a players ping changes. The new ping will have not updated in
* the player instance until this method returns.
*
* @param player the player who's ping changed
* @param ping the player's new ping.
*/
public void onPingChange(ProxiedPlayer player, int ping);
/**
* Called when a player disconnects.
*
* @param player the disconnected player
*/
public void onDisconnect(ProxiedPlayer player);
/**
* Called when a list update packet is sent from server to client.
*
* @param player receiving this packet
* @param name the player which this packet is relevant to
* @param online whether the subject player is online
* @param ping ping of the subject player
* @return whether to send the packet to the client
*/
public boolean onListUpdate(ProxiedPlayer player, String name, boolean online, int ping);
}

View File

@ -0,0 +1,106 @@
package net.md_5.bungee.api;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
/**
* Represents a configuration of a title. A title in Minecraft consists of a
* main title and a sub title. It will {@link #fadeIn(int)}, {@link #stay(int)},
* and {@link #fadeOut(int)} for a specified amount of time. In most cases you
* will want to {@link #reset()} the current title first so your title won't be
* affected by a previous one.
* <p>
* You can create a new configuration by calling
* {@link ProxyServer#createTitle()}.
*/
public interface Title
{
/**
* Set the title to send to the player.
*
* @param text The text to use as the title.
* @return This title configuration.
*/
public Title title(BaseComponent text);
/**
* Set the title to send to the player.
*
* @param text The text to use as the title.
* @return This title configuration.
*/
public Title title(BaseComponent... text);
/**
* Set the subtitle to send to the player.
*
* @param text The text to use as the subtitle.
* @return This title configuration.
*/
public Title subTitle(BaseComponent text);
/**
* Set the subtitle to send to the player.
*
* @param text The text to use as the subtitle.
* @return This title configuration.
*/
public Title subTitle(BaseComponent... text);
/**
* Set the duration in ticks of the fade in effect of the title. Once this
* period of time is over the title will stay for the amount of time
* specified in {@link #stay(int)}. The default value for the official
* Minecraft version is 20 (1 second).
*
* @param ticks The amount of ticks (1/20 second) for the fade in effect.
* @return This title configuration.
*/
public Title fadeIn(int ticks);
/**
* Set the duration in ticks how long the title should stay on the screen.
* Once this period of time is over the title will fade out using the
* duration specified in {@link #fadeOut(int)}. The default value for the
* official Minecraft version is 60 (3 seconds).
*
* @param ticks The amount of ticks (1/20 second) for the stay effect.
* @return This title configuration.
*/
public Title stay(int ticks);
/**
* Set the duration in ticks of the fade out effect of the title. The
* default value for the official Minecraft version is 20 (1 second).
*
* @param ticks The amount of ticks (1/20 second) for the fade out effect.
* @return This title configuration.
*/
public Title fadeOut(int ticks);
/**
* Remove the currently displayed title from the player's screen. This will
* keep the currently used display times and will only remove the title.
*
* @return This title configuration.
*/
public Title clear();
/**
* Remove the currently displayed title from the player's screen and set the
* configuration back to the default values.
*
* @return This title configuration.
*/
public Title reset();
/**
* Send this title configuration to the specified player. This is the same
* as calling {@link ProxiedPlayer#sendTitle(Title)}.
*
* @param player The player to send the title to.
* @return This title configuration.
*/
public Title send(ProxiedPlayer player);
}

View File

@ -43,6 +43,15 @@ public interface ConfigurationAdapter
*/
public boolean getBoolean(String path, boolean def);
/**
* Get a list from the specified path.
*
* @param path the path to retrieve the list form.
* @param def the default value
* @return the retrieved list
*/
public Collection<?> getList(String path, Collection<?> def);
/**
* Get the configuration all servers which may be accessible via the proxy.
*

View File

@ -1,7 +1,10 @@
package net.md_5.bungee.api.config;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
@ -9,13 +12,14 @@ import lombok.Data;
* multiple listeners on different ports.
*/
@Data
@AllArgsConstructor
public class ListenerInfo
{
/**
* Host to bind to.
*/
private final InetSocketAddress host;
private final SocketAddress socketAddress;
/**
* Displayed MOTD.
*/
@ -29,14 +33,10 @@ public class ListenerInfo
*/
private final int tabListSize;
/**
* Name of the server which users will be taken to by default.
* List of servers in order of join attempt. First attempt is the first
* element, second attempt is the next element, etc etc.
*/
private final String defaultServer;
/**
* Name of the server which users will be taken when current server goes
* down.
*/
private final String fallbackServer;
private final List<String> serverPriority;
/**
* Whether reconnect locations will be used, or else the user is simply
* transferred to the default server on connect.
@ -48,8 +48,71 @@ public class ListenerInfo
*/
private final Map<String, String> forcedHosts;
/**
* Get the texture pack used for servers connected to this proxy. May be
* null.
* The type of tab list to use
*/
private final TexturePackInfo texturePack;
private final String tabListType;
/**
* Whether to set the local address when connecting to servers.
*/
private final boolean setLocalAddress;
/**
* Whether to pass the ping through when we can reliably get the target
* server (force default server).
*/
private final boolean pingPassthrough;
/**
* What port to run udp query on.
*/
private final int queryPort;
/**
* Whether to enable udp query.
*/
private final boolean queryEnabled;
/**
* Whether to support HAProxy PROXY protocol.
*/
private final boolean proxyProtocol;
@Deprecated
public ListenerInfo(InetSocketAddress host, String motd, int maxPlayers, int tabListSize, List<String> serverPriority, boolean forceDefault, Map<String, String> forcedHosts, String tabListType, boolean setLocalAddress, boolean pingPassthrough, int queryPort, boolean queryEnabled)
{
this( host, motd, maxPlayers, tabListSize, serverPriority, forceDefault, forcedHosts, tabListType, setLocalAddress, pingPassthrough, queryPort, queryEnabled, false );
}
/**
* Gets the highest priority server to join.
*
* @return default server
* @deprecated replaced by {@link #serverPriority}
*/
@Deprecated
public String getDefaultServer()
{
return serverPriority.get( 0 );
}
/**
* Gets the second highest priority server to join, or else the highest
* priority.
*
* @return fallback server
* @deprecated replaced by {@link #serverPriority}
*/
@Deprecated
public String getFallbackServer()
{
return ( serverPriority.size() > 1 ) ? serverPriority.get( 1 ) : getDefaultServer();
}
/**
* Gets the bind address as an InetSocketAddress if possible.
*
* @return bind host
* @deprecated BungeeCord can listen via Unix domain sockets
*/
@Deprecated
public InetSocketAddress getHost()
{
return (InetSocketAddress) socketAddress;
}
}

View File

@ -1,6 +1,7 @@
package net.md_5.bungee.api.config;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collection;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.CommandSender;
@ -26,9 +27,19 @@ public interface ServerInfo
* class.
*
* @return the IP and port pair for this server
* @deprecated BungeeCord can connect via Unix domain sockets
*/
@Deprecated
InetSocketAddress getAddress();
/**
* Gets the connectable address for this server. Implementations expect this
* to be used as the unique identifier per each instance of this class.
*
* @return the address for this server
*/
SocketAddress getSocketAddress();
/**
* Get the set of all players on this server.
*
@ -36,6 +47,29 @@ public interface ServerInfo
*/
Collection<ProxiedPlayer> getPlayers();
/**
* Returns the MOTD which should be used when this server is a forced host.
*
* @return the motd
*/
String getMotd();
/**
* Whether this server is restricted and therefore only players with the
* given permission can access it.
*
* @return if restricted
*/
boolean isRestricted();
/**
* Get the permission required to access this server. Only enforced when the
* server is restricted.
*
* @return access permission
*/
String getPermission();
/**
* Whether the player can access this server. It will only return false when
* the player has no permission and this server is restricted.
@ -46,13 +80,35 @@ public interface ServerInfo
boolean canAccess(CommandSender sender);
/**
* Send data by any available means to this server.
* Send data by any available means to this server. This data may be queued
* and there is no guarantee of its timely arrival.
*
* In recent Minecraft versions channel names must contain a colon separator
* and consist of [a-z0-9/._-]. This will be enforced in a future version.
* The "BungeeCord" channel is an exception and may only take this form.
*
* @param channel the channel to send this data via
* @param data the data to send
*/
void sendData(String channel, byte[] data);
/**
* Send data by any available means to this server.
*
* In recent Minecraft versions channel names must contain a colon separator
* and consist of [a-z0-9/._-]. This will be enforced in a future version.
* The "BungeeCord" channel is an exception and may only take this form.
*
* @param channel the channel to send this data via
* @param data the data to send
* @param queue hold the message for later sending if it cannot be sent
* immediately.
* @return <code>true</code> if the message was sent immediately,
* <code>false</code> otherwise if queue is true, it has been queued, if it
* is false it has been discarded.
*/
boolean sendData(String channel, byte[] data, boolean queue);
/**
* Asynchronously gets the current player count on this server.
*

View File

@ -1,17 +0,0 @@
package net.md_5.bungee.api.config;
import lombok.Data;
@Data
public class TexturePackInfo
{
/**
* The URL of the texture pack.
*/
private final String url;
/**
* The square dimension of this texture pack.
*/
private final int size;
}

View File

@ -1,6 +1,9 @@
package net.md_5.bungee.api.connection;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.DefinedPacket;
/**
* A proxy connection is defined as a connection directly connected to a socket.
@ -14,8 +17,17 @@ public interface Connection
* Gets the remote address of this connection.
*
* @return the remote address
* @deprecated BungeeCord can accept connections via Unix domain sockets
*/
public InetSocketAddress getAddress();
@Deprecated
InetSocketAddress getAddress();
/**
* Gets the remote address of this connection.
*
* @return the remote address
*/
SocketAddress getSocketAddress();
/**
* Disconnects this end of the connection for the specified reason. If this
@ -25,5 +37,52 @@ public interface Connection
* @param reason the reason shown to the player / sent to the server on
* disconnect
*/
public void disconnect(String reason);
@Deprecated
void disconnect(String reason);
/**
* Disconnects this end of the connection for the specified reason. If this
* is an {@link ProxiedPlayer} the respective server connection will be
* closed too.
*
* @param reason the reason shown to the player / sent to the server on
* disconnect
*/
void disconnect(BaseComponent... reason);
/**
* Disconnects this end of the connection for the specified reason. If this
* is an {@link ProxiedPlayer} the respective server connection will be
* closed too.
*
* @param reason the reason shown to the player / sent to the server on
* disconnect
*/
void disconnect(BaseComponent reason);
/**
* Gets whether this connection is currently open, ie: not disconnected, and
* able to send / receive data.
*
* @return current connection status
*/
boolean isConnected();
/**
* Get the unsafe methods of this class.
*
* @return the unsafe method interface
*/
Unsafe unsafe();
interface Unsafe
{
/**
* Send a packet to this connection.
*
* @param packet the packet to send
*/
void sendPacket(DefinedPacket packet);
}
}

View File

@ -1,7 +1,10 @@
package net.md_5.bungee.api.connection;
import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import net.md_5.bungee.api.config.ListenerInfo;
import org.jetbrains.annotations.ApiStatus;
/**
* Represents a user attempting to log into the proxy.
@ -14,26 +17,114 @@ public interface PendingConnection extends Connection
*
* @return the requested username, or null if not set
*/
public String getName();
String getName();
/**
* Get the numerical client version of the player attempting to log in.
*
* @return the protocol version of the remote client
*/
public byte getVersion();
int getVersion();
/**
* Get the requested virtual host that the client tried to connect to.
*
* @return request virtual host or null if invalid / not specified.
*/
public InetSocketAddress getVirtualHost();
InetSocketAddress getVirtualHost();
/**
* Get the listener that accepted this connection.
*
* @return the accepting listener
*/
public ListenerInfo getListener();
ListenerInfo getListener();
/**
* Get this connection's UUID, if set.
*
* @return the UUID
* @deprecated In favour of {@link #getUniqueId()}
*/
@Deprecated
String getUUID();
/**
* Get this connection's UUID, if set.
*
* @return the UUID
*/
UUID getUniqueId();
/**
* Set the connection's uuid
*
* @param uuid connection UUID
*/
void setUniqueId(UUID uuid);
/**
* Get this connection's online mode.
* <br>
* See {@link #setOnlineMode(boolean)} for a description of how this option
* works.
*
* @return the online mode
*/
boolean isOnlineMode();
/**
* Set this connection's online mode.
* <br>
* May be called only during the PlayerHandshakeEvent to set the online mode
* configuration setting for this connection only (i.e. whether or not the
* client will be treated as if it is connecting to an online mode server).
*
* @param onlineMode status
*/
void setOnlineMode(boolean onlineMode);
/**
* Check if the client is using the older unsupported Minecraft protocol
* used by Minecraft clients older than 1.7.
*
* @return Whether the client is using a legacy client.
*/
boolean isLegacy();
/**
* Gets if this connection has been transferred from another server.
*
* @return true if the connection has been transferred
*/
@ApiStatus.Experimental
boolean isTransferred();
/**
* Retrieves a cookie from this pending connection.
*
* @param cookie the resource location of the cookie, for example
* "bungeecord:my_cookie"
* @return a {@link CompletableFuture} that will be completed when the
* Cookie response is received. If the cookie is not set in the client, the
* {@link CompletableFuture} will complete with a null value
* @throws IllegalStateException if the player's version is not at least
* 1.20.5
*/
@ApiStatus.Experimental
CompletableFuture<byte[]> retrieveCookie(String cookie);
/**
* Sends a login payload request to the client.
*
* @param channel the channel to send this data via
* @param data the data to send
* @return a {@link CompletableFuture} that will be completed when the Login
* Payload response is received. If the Vanilla client doesn't know the
* channel, the {@link CompletableFuture} will complete with a null value
* @throws IllegalStateException if the player's version is not at least
* 1.13
*/
@ApiStatus.Experimental
CompletableFuture<byte[]> sendData(String channel, byte[] data);
}

View File

@ -1,29 +1,101 @@
package net.md_5.bungee.api.connection;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ServerConnectRequest;
import net.md_5.bungee.api.SkinConfiguration;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.score.Scoreboard;
import org.jetbrains.annotations.ApiStatus;
/**
* 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.
*/
public interface ProxiedPlayer extends Connection, CommandSender
{
/**
* Represents the player's chat state.
*/
public enum ChatMode
{
/**
* The player will see all chat.
*/
SHOWN,
/**
* The player will only see everything except messages marked as chat.
*/
COMMANDS_ONLY,
/**
* The chat is completely disabled, the player won't see anything.
*/
HIDDEN;
}
public enum MainHand
{
LEFT,
RIGHT;
}
/**
* Gets this player's display name.
*
* @return the players current display name
*/
public String getDisplayName();
String getDisplayName();
/**
* Sets this players display name to be used as their nametag and tab list
* name.
* Sets this player's display name to be used by proxy commands and plugins.
*
* @param name the name to set
*/
public void setDisplayName(String name);
void setDisplayName(String name);
/**
* Send a message to the specified screen position of this player.
*
* @param position the screen position
* @param message the message to send
*/
public void sendMessage(ChatMessageType position, BaseComponent... message);
/**
* Send a message to the specified screen position of this player.
*
* @param position the screen position
* @param message the message to send
*/
public void sendMessage(ChatMessageType position, BaseComponent message);
/**
* Send a message to this player.
*
* @param sender the sender of the message
* @param message the message to send
*/
public void sendMessage(UUID sender, BaseComponent... message);
/**
* Send a message to this player.
*
* @param sender the sender of the message
* @param message the message to send
*/
public void sendMessage(UUID sender, BaseComponent message);
/**
* Connects / transfers this user to the specified connection, gracefully
@ -32,41 +104,282 @@ public interface ProxiedPlayer extends Connection, CommandSender
*
* @param target the new server to connect to
*/
public void connect(ServerInfo target);
void connect(ServerInfo target);
/**
* Connects / transfers this user to the specified connection, gracefully
* closing the current one. Depending on the implementation, this method
* might return before the user has been connected.
*
* @param target the new server to connect to
* @param reason the reason for connecting to the new server
*/
void connect(ServerInfo target, ServerConnectEvent.Reason reason);
/**
* Connects / transfers this user to the specified connection, gracefully
* closing the current one. Depending on the implementation, this method
* might return before the user has been connected.
*
* @param target the new server to connect to
* @param callback the method called when the connection is complete, or
* when an exception is encountered. The boolean parameter denotes success
* (true) or failure (false).
*/
void connect(ServerInfo target, Callback<Boolean> callback);
/**
* Connects / transfers this user to the specified connection, gracefully
* closing the current one. Depending on the implementation, this method
* might return before the user has been connected.
*
* @param target the new server to connect to
* @param callback the method called when the connection is complete, or
* when an exception is encountered. The boolean parameter denotes success
* (true) or failure (false).
* @param reason the reason for connecting to the new server
*/
void connect(ServerInfo target, Callback<Boolean> callback, ServerConnectEvent.Reason reason);
/**
* Connects / transfers this user to the specified connection, gracefully
* closing the current one. Depending on the implementation, this method
* might return before the user has been connected.
*
* @param request request to connect with
*/
void connect(ServerConnectRequest request);
/**
* Gets the server this player is connected to.
*
* @return the server this player is connected to
*/
public Server getServer();
Server getServer();
/**
* Gets the ping time between the proxy and this connection.
*
* @return the current ping time
*/
public int getPing();
int getPing();
/**
* Send a plugin message to this player.
*
* In recent Minecraft versions channel names must contain a colon separator
* and consist of [a-z0-9/._-]. This will be enforced in a future version.
* The "BungeeCord" channel is an exception and may only take this form.
*
* @param channel the channel to send this data via
* @param data the data to send
*/
public void sendData(String channel, byte[] data);
void sendData(String channel, byte[] data);
/**
* Get the pending connection that belongs to this player.
*
* @return the pending connection that this player used
*/
public PendingConnection getPendingConnection();
PendingConnection getPendingConnection();
/**
* Make this player chat (say something), to the server he is currently on.
*
* @param message the message to say
*/
public void chat(String message);
void chat(String message);
/**
* Get the server which this player will be sent to next time the log in.
*
* @return the server, or null if default
*/
ServerInfo getReconnectServer();
/**
* Set the server which this player will be sent to next time the log in.
*
* @param server the server to set
*/
void setReconnectServer(ServerInfo server);
/**
* Get this connection's UUID, if set.
*
* @return the UUID
* @deprecated In favour of {@link #getUniqueId()}
*/
@Deprecated
String getUUID();
/**
* Get this connection's UUID, if set.
*
* @return the UUID
*/
UUID getUniqueId();
/**
* Gets this player's locale.
*
* @return the locale
*/
Locale getLocale();
/**
* Gets this player's view distance.
*
* @return the view distance, or a reasonable default
*/
byte getViewDistance();
/**
* Gets this player's chat mode.
*
* @return the chat flags set, or a reasonable default
*/
ChatMode getChatMode();
/**
* Gets if this player has chat colors enabled or disabled.
*
* @return if chat colors are enabled
*/
boolean hasChatColors();
/**
* Gets this player's skin settings.
*
* @return the players skin setting
*/
SkinConfiguration getSkinParts();
/**
* Gets this player's main hand setting.
*
* @return main hand setting
*/
MainHand getMainHand();
/**
* Set the header and footer displayed in the tab player list.
*
* @param header The header for the tab player list, null to clear it.
* @param footer The footer for the tab player list, null to clear it.
*/
void setTabHeader(BaseComponent header, BaseComponent footer);
/**
* Set the header and footer displayed in the tab player list.
*
* @param header The header for the tab player list, null to clear it.
* @param footer The footer for the tab player list, null to clear it.
*/
void setTabHeader(BaseComponent[] header, BaseComponent[] footer);
/**
* Clears the header and footer displayed in the tab player list.
*/
void resetTabHeader();
/**
* Sends a {@link Title} to this player. This is the same as calling
* {@link Title#send(ProxiedPlayer)}.
*
* @param title The title to send to the player.
* @see Title
*/
void sendTitle(Title title);
/**
* Gets whether this player is using a FML client.
* <p>
* This method is only reliable if BungeeCord links Minecraft 1.8 servers
* together, as Bungee can pick up whether a user is a Forge user with the
* initial handshake. If this is used for a 1.7 network, this might return
* <code>false</code> even if the user is a FML user, as Bungee can only
* determine this information if a handshake successfully completes.
* </p>
*
* @return <code>true</code> if it is known that the user is using a FML
* client, <code>false</code> otherwise.
*/
boolean isForgeUser();
/**
* Gets this player's Forge Mod List, if the player has sent this
* information during the lifetime of their connection to Bungee. There is
* no guarantee that information is available at any time, as it is only
* sent during a FML handshake. Therefore, this will only contain
* information for a user that has attempted joined a Forge server.
* <p>
* Consumers of this API should be aware that an empty mod list does
* <em>not</em> indicate that a user is not a Forge user, and so should not
* use this API to check for this. See the {@link #isForgeUser()
* isForgeUser} method instead.
* </p>
* <p>
* Calling this when handling a
* {@link net.md_5.bungee.api.event.ServerConnectedEvent} may be the best
* place to do so as this event occurs after a FML handshake has completed,
* if any has occurred.
* </p>
*
* @return A {@link Map} of mods, where the key is the name of the mod, and
* the value is the version. Returns an empty list if the FML handshake has
* not occurred for this {@link ProxiedPlayer} yet.
*/
Map<String, String> getModList();
/**
* Get the {@link Scoreboard} that belongs to this player.
*
* @return this player's {@link Scoreboard}
* @deprecated for internal use only, setters will not have the expected
* effect, will not update client state, and may corrupt proxy state
*/
@Deprecated
Scoreboard getScoreboard();
/**
* Retrieves a cookie from this player.
*
* @param cookie the resource location of the cookie, for example
* "bungeecord:my_cookie"
* @return a {@link CompletableFuture} that will be completed when the
* Cookie response is received. If the cookie is not set in the client, the
* {@link CompletableFuture} will complete with a null value
* @throws IllegalStateException if the player's version is not at least
* 1.20.5
*/
@ApiStatus.Experimental
CompletableFuture<byte[]> retrieveCookie(String cookie);
/**
* Stores a cookie in this player's client.
*
* @param cookie the resource location of the cookie, for example
* "bungeecord:my_cookie"
* @param data the data to store in the cookie
* @throws IllegalStateException if the player's version is not at least
* 1.20.5
*/
@ApiStatus.Experimental
void storeCookie(String cookie, byte[] data);
/**
* Requests this player to connect to a different server specified by host
* and port.
*
* This is a client-side transfer - host and port should not specify a
* BungeeCord backend server.
*
* @param host the host of the server to transfer to
* @param port the port of the server to transfer to
* @throws IllegalStateException if the players version is not at least
* 1.20.5
*/
@ApiStatus.Experimental
void transfer(String host, int port);
}

View File

@ -18,6 +18,10 @@ public interface Server extends Connection
/**
* Send data by any available means to this server.
*
* In recent Minecraft versions channel names must contain a colon separator
* and consist of [a-z0-9/._-]. This will be enforced in a future version.
* The "BungeeCord" channel is an exception and may only take this form.
*
* @param channel the channel to send this data via
* @param data the data to send
*/

View File

@ -1,13 +1,14 @@
package net.md_5.bungee.api.event;
import com.google.common.base.Preconditions;
import java.util.Collections;
import java.util.Set;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.plugin.Event;
@ -19,13 +20,14 @@ import net.md_5.bungee.api.plugin.Plugin;
* @param <T> Type of this event
*/
@Data
@Getter(AccessLevel.NONE)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class AsyncEvent<T> extends Event
{
private final Callback<T> done;
private final Set<Plugin> intents = Collections.newSetFromMap( new ConcurrentHashMap<Plugin, Boolean>() );
private final Map<Plugin, AtomicInteger> intents = new ConcurrentHashMap<>();
private final AtomicBoolean fired = new AtomicBoolean();
private final AtomicInteger latch = new AtomicInteger();
@ -33,43 +35,59 @@ public class AsyncEvent<T> extends Event
@SuppressWarnings("unchecked")
public void postCall()
{
fired.set( true );
if ( latch.get() == 0 )
{
done.done( (T) this, null );
}
fired.set( true );
}
/**
* Register an intent that this plugin will continue to perform work on a
* background task, and wishes to let the event proceed once the registered
* background task has completed.
* background task has completed. Multiple intents can be registered by a
* plugin, but the plugin must complete the same amount of intents for the
* event to proceed.
*
* @param plugin the plugin registering this intent
*/
public void registerIntent(Plugin plugin)
{
Preconditions.checkState( !fired.get(), "Event %s has already been fired", this );
Preconditions.checkState( !intents.contains( plugin ), "Plugin %s already registered intent for event %s", plugin, this );
intents.add( plugin );
AtomicInteger intentCount = intents.get( plugin );
if ( intentCount == null )
{
intents.put( plugin, new AtomicInteger( 1 ) );
} else
{
intentCount.incrementAndGet();
}
latch.incrementAndGet();
}
/**
* Notifies this event that this plugin has done all its required processing
* and wishes to let the event proceed.
* Notifies this event that this plugin has completed an intent and wishes
* to let the event proceed once all intents have been completed.
*
* @param plugin a plugin which has an intent registered for this event
*/
@SuppressWarnings("unchecked")
public void completeIntent(Plugin plugin)
{
Preconditions.checkState( intents.contains( plugin ), "Plugin %s has not registered intent for event %s", plugin, this );
intents.remove( plugin );
if ( latch.decrementAndGet() == 0 )
AtomicInteger intentCount = intents.get( plugin );
Preconditions.checkState( intentCount != null && intentCount.get() > 0, "Plugin %s has not registered intents for event %s", plugin, this );
intentCount.decrementAndGet();
if ( fired.get() )
{
done.done( (T) this, null );
if ( latch.decrementAndGet() == 0 )
{
done.done( (T) this, null );
}
} else
{
latch.decrementAndGet();
}
}
}

View File

@ -3,12 +3,14 @@ package net.md_5.bungee.api.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.Connection;
import net.md_5.bungee.api.plugin.Cancellable;
import net.md_5.bungee.api.plugin.PluginManager;
/**
* Event called when a player sends a message to a server, or a server sends a
* message to a player.
* Event called when a player sends a message to a server.
*/
@Data
@ToString(callSuper = true)
@ -40,4 +42,25 @@ public class ChatEvent extends TargetedEvent implements Cancellable
{
return message.length() > 0 && message.charAt( 0 ) == '/';
}
/**
* Checks whether this message is run on this proxy server.
*
* @return if this command runs on the proxy
* @see PluginManager#isExecutableCommand(java.lang.String,
* net.md_5.bungee.api.CommandSender)
*/
public boolean isProxyCommand()
{
if ( !isCommand() )
{
return false;
}
int index = message.indexOf( " " );
String commandName = ( index == -1 ) ? message.substring( 1 ) : message.substring( 1, index );
CommandSender sender = ( getSender() instanceof CommandSender ) ? (CommandSender) getSender() : null;
return ProxyServer.getInstance().getPluginManager().isExecutableCommand( commandName, sender );
}
}

View File

@ -0,0 +1,35 @@
package net.md_5.bungee.api.event;
import java.net.SocketAddress;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.plugin.Cancellable;
import net.md_5.bungee.api.plugin.Event;
/**
* Event called to represent an initial client connection.
* <br>
* Note: This event is called at an early stage of every connection, handling
* should be <b>fast</b>.
*/
@Data
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class ClientConnectEvent extends Event implements Cancellable
{
/**
* Cancelled state.
*/
private boolean cancelled;
/**
* Remote address of connection.
*/
private final SocketAddress socketAddress;
/**
* Listener that accepted the connection.
*/
private final ListenerInfo listener;
}

View File

@ -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.&lt;CommandSender&gt;literal( "server" )
* .requires( sender -&gt; sender.hasPermission( "bungeecord.command.server" ) )
* .executes( a -&gt; 0 )
* .then( RequiredArgumentBuilder.argument( "serverName", StringArgumentType.greedyString() )
* .suggests( SuggestionRegistry.ASK_SERVER )
* )
* .build()
* );
* event.getRoot().addChild( LiteralArgumentBuilder.&lt;CommandSender&gt;literal( "send" )
* .requires( sender -&gt; 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
* Minecrafts recipes.
* </li>
* <li>
* {@code builder.suggests(SuggestionRegistry.AVAILABLE_SOUNDS)} to
* suggest Minecrafts default sound identifiers.
* </li>
* <li>
* {@code builder.suggests(SuggestionRegistry.SUMMONABLE_ENTITIES)} to
* suggest Minecrafts 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;
}
}

View File

@ -4,6 +4,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.plugin.Cancellable;
@ -23,7 +25,7 @@ public class LoginEvent extends AsyncEvent<LoginEvent> implements Cancellable
/**
* Message to use when kicking if this event is canceled.
*/
private String cancelReason;
private BaseComponent reason;
/**
* Connection attempting to login.
*/
@ -34,4 +36,47 @@ public class LoginEvent extends AsyncEvent<LoginEvent> implements Cancellable
super( done );
this.connection = connection;
}
/**
* @return reason to be displayed
* @deprecated use component methods instead
*/
@Deprecated
public String getCancelReason()
{
return TextComponent.toLegacyText( getReason() );
}
/**
* @param cancelReason reason to be displayed
* @deprecated use component methods instead
*/
@Deprecated
public void setCancelReason(String cancelReason)
{
setReason( TextComponent.fromLegacy( cancelReason ) );
}
/**
* @return reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public BaseComponent[] getCancelReasonComponents()
{
return new BaseComponent[]
{
getReason()
};
}
/**
* @param cancelReason reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public void setCancelReason(BaseComponent... cancelReason)
{
setReason( TextComponent.fromArray( cancelReason ) );
}
}

View File

@ -0,0 +1,34 @@
package net.md_5.bungee.api.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.plugin.Event;
import net.md_5.bungee.protocol.packet.Handshake;
/**
* Event called to represent a player first making their presence and username
* known.
*/
@Data
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class PlayerHandshakeEvent extends Event
{
/**
* Connection attempting to login.
*/
private final PendingConnection connection;
/**
* The handshake.
*/
private final Handshake handshake;
public PlayerHandshakeEvent(PendingConnection connection, Handshake handshake)
{
this.connection = connection;
this.handshake = handshake;
}
}

View File

@ -10,7 +10,7 @@ import net.md_5.bungee.api.plugin.Cancellable;
* Event called when a plugin message is sent to the client or server.
*/
@Data
@ToString(callSuper = true)
@ToString(callSuper = true, exclude = "data")
@EqualsAndHashCode(callSuper = true)
public class PluginMessageEvent extends TargetedEvent implements Cancellable
{

View File

@ -3,21 +3,33 @@ package net.md_5.bungee.api.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Event;
/**
* Event called as soon as a connection has an {@link ProxiedPlayer} and is
* ready to be connected to a server.
* Event called as soon as a connection has a {@link ProxiedPlayer} and is ready
* to be connected to a server.
*/
@Data
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class PostLoginEvent extends Event
public class PostLoginEvent extends AsyncEvent<PostLoginEvent>
{
/**
* The player involved with this event.
*/
private final ProxiedPlayer player;
/**
* The server to which the player will initially be connected.
*/
private ServerInfo target;
public PostLoginEvent(ProxiedPlayer player, ServerInfo target, Callback<PostLoginEvent> done)
{
super( done );
this.player = player;
this.target = target;
}
}

View File

@ -0,0 +1,87 @@
package net.md_5.bungee.api.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.plugin.Cancellable;
/**
* Event called to represent a player first making their presence and username
* known.
*
* This will NOT contain many attributes relating to the player which are filled
* in after authentication with Mojang's servers. Examples of attributes which
* are not available include their UUID.
*/
@Data
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class PreLoginEvent extends AsyncEvent<PreLoginEvent> implements Cancellable
{
/**
* Cancelled state.
*/
private boolean cancelled;
/**
* Message to use when kicking if this event is canceled.
*/
private BaseComponent reason;
/**
* Connection attempting to login.
*/
private final PendingConnection connection;
public PreLoginEvent(PendingConnection connection, Callback<PreLoginEvent> done)
{
super( done );
this.connection = connection;
}
/**
* @return reason to be displayed
* @deprecated use component methods instead
*/
@Deprecated
public String getCancelReason()
{
return BaseComponent.toLegacyText( getReason() );
}
/**
* @param cancelReason reason to be displayed
* @deprecated Use component methods instead
*/
@Deprecated
public void setCancelReason(String cancelReason)
{
setReason( TextComponent.fromLegacy( cancelReason ) );
}
/**
* @return reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public BaseComponent[] getCancelReasonComponents()
{
return new BaseComponent[]
{
getReason()
};
}
/**
* @param cancelReason reason to be displayed
* @deprecated use single component methods instead
*/
@Deprecated
public void setCancelReason(BaseComponent... cancelReason)
{
setReason( TextComponent.fromArray( cancelReason ) );
}
}

View File

@ -1,21 +1,19 @@
package net.md_5.bungee.api.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.plugin.Event;
/**
* 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
@AllArgsConstructor
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class ProxyPingEvent extends Event
public class ProxyPingEvent extends AsyncEvent<ProxyPingEvent>
{
/**
@ -26,4 +24,11 @@ public class ProxyPingEvent extends Event
* The data to respond with.
*/
private ServerPing response;
public ProxyPingEvent(PendingConnection connection, ServerPing response, Callback<ProxyPingEvent> done)
{
super( done );
this.connection = connection;
this.response = response;
}
}

View File

@ -0,0 +1,22 @@
package net.md_5.bungee.api.event;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Event;
/**
* Called when somebody reloads BungeeCord
*/
@Getter
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class ProxyReloadEvent extends Event
{
/**
* Creator of the action.
*/
private final CommandSender sender;
}

View File

@ -1,18 +1,25 @@
package net.md_5.bungee.api.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import net.md_5.bungee.api.ServerConnectRequest;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Cancellable;
import net.md_5.bungee.api.plugin.Event;
/**
* Called when deciding to connect to a server. At the time when this event is
* called, no connection has actually been made. Cancelling the event will
* ensure that the connection does not proceed and can be useful to prevent
* certain players from accessing certain servers.
*/
@Data
@AllArgsConstructor
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class ServerConnectEvent extends Event
public class ServerConnectEvent extends Event implements Cancellable
{
/**
@ -22,5 +29,77 @@ public class ServerConnectEvent extends Event
/**
* Server the player will be connected to.
*/
@NonNull
private ServerInfo target;
/**
* Reason for connecting to a new server.
*/
private final Reason reason;
/**
* Request used to connect to given server.
*/
private final ServerConnectRequest request;
/**
* Cancelled state.
*/
private boolean cancelled;
@Deprecated
public ServerConnectEvent(ProxiedPlayer player, ServerInfo target)
{
this( player, target, Reason.UNKNOWN );
}
@Deprecated
public ServerConnectEvent(ProxiedPlayer player, ServerInfo target, Reason reason)
{
this( player, target, reason, null );
}
public ServerConnectEvent(ProxiedPlayer player, ServerInfo target, Reason reason, ServerConnectRequest request)
{
this.player = player;
this.target = target;
this.reason = reason;
this.request = request;
}
public enum Reason
{
/**
* Redirection to lobby server due to being unable to connect to
* original server
*/
LOBBY_FALLBACK,
/**
* Execution of a command
*/
COMMAND,
/**
* Redirecting to another server when client loses connection to server
* due to an exception.
*/
SERVER_DOWN_REDIRECT,
/**
* Redirecting to another server when kicked from original server.
*/
KICK_REDIRECT,
/**
* Plugin message request.
*/
PLUGIN_MESSAGE,
/**
* Initial proxy connect.
*/
JOIN_PROXY,
/**
* Plugin initiated connect.
*/
PLUGIN,
/**
* Unknown cause.
*/
UNKNOWN
}
}

View File

@ -0,0 +1,36 @@
package net.md_5.bungee.api.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
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
@AllArgsConstructor
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class ServerDisconnectEvent extends Event
{
/**
* Player disconnecting from a server.
*/
@NonNull
private final ProxiedPlayer player;
/**
* Server the player is disconnecting from.
*/
@NonNull
private final ServerInfo target;
}

View File

@ -3,6 +3,8 @@ package net.md_5.bungee.api.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.chat.BaseComponent;
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.plugin.Cancellable;
@ -25,19 +27,97 @@ public class ServerKickEvent extends Event implements Cancellable
* Player being kicked.
*/
private final ProxiedPlayer player;
/**
* The server the player was kicked from, should be used in preference to
* {@link ProxiedPlayer#getServer()}.
*/
private final ServerInfo kickedFrom;
/**
* Kick reason.
*/
private String kickReason;
private BaseComponent reason;
/**
* Server to send player to if this event is cancelled.
*/
private ServerInfo cancelServer;
/**
* State in which the kick occured.
*/
private State state;
public ServerKickEvent(ProxiedPlayer player, String kickReason, ServerInfo cancelServer)
public enum State
{
CONNECTING, CONNECTED, UNKNOWN;
}
@Deprecated
public ServerKickEvent(ProxiedPlayer player, BaseComponent[] kickReasonComponent, ServerInfo cancelServer)
{
this( player, kickReasonComponent, cancelServer, State.UNKNOWN );
}
@Deprecated
public ServerKickEvent(ProxiedPlayer player, BaseComponent[] kickReasonComponent, ServerInfo cancelServer, State state)
{
this( player, player.getServer().getInfo(), kickReasonComponent, cancelServer, state );
}
@Deprecated
public ServerKickEvent(ProxiedPlayer player, ServerInfo kickedFrom, BaseComponent[] kickReasonComponent, ServerInfo cancelServer, State state)
{
this( player, kickedFrom, TextComponent.fromArray( kickReasonComponent ), cancelServer, state );
}
public ServerKickEvent(ProxiedPlayer player, ServerInfo kickedFrom, BaseComponent reason, ServerInfo cancelServer, State state)
{
this.player = player;
this.kickReason = kickReason;
this.kickedFrom = kickedFrom;
this.reason = reason;
this.cancelServer = cancelServer;
this.state = state;
}
/**
* @return the kick reason
* @deprecated use component methods instead
*/
@Deprecated
public String getKickReason()
{
return BaseComponent.toLegacyText( getReason() );
}
/**
* @param reason the kick reason
* @deprecated use component methods instead
*/
@Deprecated
public void setKickReason(String reason)
{
this.setReason( TextComponent.fromLegacy( reason ) );
}
/**
* @return the kick reason
* @deprecated use single component methods instead
*/
@Deprecated
public BaseComponent[] getKickReasonComponent()
{
return new BaseComponent[]
{
getReason()
};
}
/**
* @param kickReasonComponent the kick reason
* @deprecated use single component methods instead
*/
@Deprecated
public void setKickReasonComponent(BaseComponent[] kickReasonComponent)
{
this.setReason( TextComponent.fromArray( kickReasonComponent ) );
}
}

View File

@ -0,0 +1,28 @@
package net.md_5.bungee.api.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Event;
/**
* Called when a player has changed servers.
*/
@Data
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class ServerSwitchEvent extends Event
{
/**
* Player whom the server is for.
*/
private final ProxiedPlayer player;
/**
* Server the player is switch from. May be null if initial proxy
* connection.
*/
private final ServerInfo from;
}

View File

@ -0,0 +1,32 @@
package net.md_5.bungee.api.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Event;
/**
* Called after a {@link ProxiedPlayer} changed one or more of the following
* (client-side) settings:
*
* <ul>
* <li>View distance</li>
* <li>Locale</li>
* <li>Displayed skin parts</li>
* <li>Chat visibility</li>
* <li>Chat colors</li>
* <li>Main hand side (left or right)</li>
* </ul>
*/
@Data
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
public class SettingsChangedEvent extends Event
{
/**
* Player who changed the settings.
*/
private final ProxiedPlayer player;
}

View File

@ -0,0 +1,41 @@
package net.md_5.bungee.api.event;
import java.util.List;
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 a player uses tab completion.
* @deprecated please use {@link TabCompleteRequestEvent} to support 1.13+ suggestions.
*/
@Deprecated
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class TabCompleteEvent 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. This list is mutable. If
* this list is empty, the request will be forwarded to the server.
*/
private final List<String> suggestions;
public TabCompleteEvent(Connection sender, Connection receiver, String cursor, List<String> suggestions)
{
super( sender, receiver );
this.cursor = cursor;
this.suggestions = suggestions;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,38 @@
package net.md_5.bungee.api.event;
import java.util.List;
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 a backend server sends a response to a player asking to
* tab-complete a chat message or command. Note that this is not called when
* BungeeCord or a plugin responds to a tab-complete request. Use
* {@link TabCompleteEvent} for that.
*/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class TabCompleteResponseEvent extends TargetedEvent implements Cancellable
{
/**
* Whether the event is cancelled.
*/
private boolean cancelled;
/**
* Mutable list of suggestions sent back to the player. If this list is
* empty, an empty list is sent back to the client.
*/
private final List<String> suggestions;
public TabCompleteResponseEvent(Connection sender, Connection receiver, List<String> suggestions)
{
super( sender, receiver );
this.suggestions = suggestions;
}
}

View File

@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
import lombok.AccessLevel;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.md_5.bungee.api.CommandSender;
/**
@ -17,6 +18,8 @@ public abstract class Command
private final String name;
private final String permission;
private final String[] aliases;
@Setter(AccessLevel.PROTECTED)
private String permissionMessage;
/**
* Construct a new command with no permissions or aliases.
@ -42,6 +45,7 @@ public abstract class Command
this.name = name;
this.permission = permission;
this.aliases = aliases;
this.permissionMessage = null;
}
/**
@ -51,4 +55,15 @@ public abstract class Command
* @param args arguments used to invoke this command
*/
public abstract void execute(CommandSender sender, String[] args);
/**
* Check if this command can be executed by the given sender.
*
* @param sender the sender to check
* @return whether the sender can execute this
*/
public boolean hasPermission(CommandSender sender)
{
return permission == null || permission.isEmpty() || sender.hasPermission( permission );
}
}

View File

@ -0,0 +1,128 @@
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() );
}
} );
// SPIGOT-7638: Add system properties,
// since JdkVersionProfileActivator needs 'java.version' when a profile has the 'jdk' element
// otherwise it will silently fail and not resolves the dependencies in the affected pom.
session.setSystemProperties( System.getProperties() );
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;
}
}

View File

@ -1,10 +1,16 @@
package net.md_5.bungee.api.plugin;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.File;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
import lombok.Getter;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ConfigurationAdapter;
import net.md_5.bungee.api.scheduler.GroupedThreadFactory;
/**
* Represents any Plugin that may be loaded at runtime to enhance existing
@ -19,6 +25,24 @@ public class Plugin
private ProxyServer proxy;
@Getter
private File file;
@Getter
private Logger logger;
public Plugin()
{
ClassLoader classLoader = getClass().getClassLoader();
Preconditions.checkState( classLoader instanceof PluginClassloader, "Plugin requires " + PluginClassloader.class.getName() );
( (PluginClassloader) classLoader ).init( this );
}
protected Plugin(ProxyServer proxy, PluginDescription description)
{
ClassLoader classLoader = getClass().getClassLoader();
Preconditions.checkState( !( classLoader instanceof PluginClassloader ), "Cannot use initialization constructor at runtime" );
// init( proxy, description );
}
/**
* Called when the plugin has just been loaded. Most of the proxy will not
@ -70,13 +94,30 @@ public class Plugin
/**
* Called by the loader to initialize the fields in this plugin.
*
* @param proxy current proxy instance
* @param description the description that describes this plugin
* @param jarfile this plugins jar or container
*/
final void init(ProxyServer proxy, PluginDescription description, File file)
final void init(ProxyServer proxy, PluginDescription description)
{
this.proxy = proxy;
this.description = description;
this.file = file;
this.file = description.getFile();
this.logger = new PluginLogger( this );
}
//
private ExecutorService service;
@Deprecated
public ExecutorService getExecutorService()
{
if ( service == null )
{
String name = ( getDescription() == null ) ? "unknown" : getDescription().getName();
service = Executors.newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat( name + " Pool Thread #%1$d" )
.setThreadFactory( new GroupedThreadFactory( this, name ) ).build() );
}
return service;
}
//
}

View File

@ -1,35 +1,89 @@
package net.md_5.bungee.api.plugin;
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.URLClassLoader;
import java.util.HashSet;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.util.Set;
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;
public class PluginClassloader extends URLClassLoader
@ToString(of = "desc")
final class PluginClassloader extends URLClassLoader
{
private static final Set<PluginClassloader> allLoaders = new HashSet<>();
private static final Set<PluginClassloader> allLoaders = new CopyOnWriteArraySet<>();
//
private final ProxyServer proxy;
private final PluginDescription desc;
private final JarFile jar;
private final Manifest manifest;
private final URL url;
private final ClassLoader libraryLoader;
//
private Plugin plugin;
public PluginClassloader(URL[] urls)
static
{
super( urls );
ClassLoader.registerAsParallelCapable();
}
public PluginClassloader(ProxyServer proxy, PluginDescription desc, File file, ClassLoader libraryLoader) throws IOException
{
super( new URL[]
{
file.toURI().toURL()
} );
this.proxy = proxy;
this.desc = desc;
this.jar = new JarFile( file );
this.manifest = jar.getManifest();
this.url = file.toURI().toURL();
this.libraryLoader = libraryLoader;
allLoaders.add( this );
}
@Override
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
{
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 )
{
}
if ( checkLibraries && libraryLoader != null )
{
try
{
return libraryLoader.loadClass( name );
} catch ( ClassNotFoundException ex )
{
}
}
if ( checkOther )
{
for ( PluginClassloader loader : allLoaders )
@ -38,13 +92,91 @@ public class PluginClassloader extends URLClassLoader
{
try
{
return loader.loadClass0( name, resolve, false );
return loader.loadClass0( name, resolve, false, proxy.getPluginManager().isTransitiveDepend( desc, loader.desc ) );
} catch ( ClassNotFoundException ex )
{
}
}
}
}
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)
{
Preconditions.checkArgument( plugin != null, "plugin" );
Preconditions.checkArgument( plugin.getClass().getClassLoader() == this, "Plugin has incorrect ClassLoader" );
if ( this.plugin != null )
{
throw new IllegalArgumentException( "Plugin already initialized!" );
}
this.plugin = plugin;
plugin.init( proxy, desc );
}
}

View File

@ -1,6 +1,9 @@
package net.md_5.bungee.api.plugin;
import java.io.File;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -35,4 +38,20 @@ public class PluginDescription
* Plugin hard dependencies.
*/
private Set<String> depends = new HashSet<>();
/**
* Plugin soft dependencies.
*/
private Set<String> softDepends = new HashSet<>();
/**
* File we were loaded from.
*/
private File file = null;
/**
* Optional description.
*/
private String description = null;
/**
* Optional libraries.
*/
private List<String> libraries = new LinkedList<>();
}

View File

@ -0,0 +1,24 @@
package net.md_5.bungee.api.plugin;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class PluginLogger extends Logger
{
private final String pluginName;
protected PluginLogger(Plugin plugin)
{
super( plugin.getClass().getCanonicalName(), null );
pluginName = "[" + plugin.getDescription().getName() + "] ";
setParent( plugin.getProxy().getLogger() );
}
@Override
public void log(LogRecord logRecord)
{
logRecord.setMessage( pluginName + logRecord.getMessage() );
super.log( logRecord );
}
}

View File

@ -1,44 +1,89 @@
package net.md_5.bungee.api.plugin;
import com.google.common.base.Preconditions;
import com.google.common.eventbus.EventBus;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
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.InputStream;
import java.net.URL;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
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.event.LoginEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.event.EventBus;
import net.md_5.bungee.event.EventHandler;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.introspector.PropertyUtils;
/**
* Class to manage bridging between plugin duties and implementation duties, for
* example event handling and plugin management.
*/
@RequiredArgsConstructor
public class PluginManager
public final class PluginManager
{
private static final Pattern argsSplit = Pattern.compile( " " );
/*========================================================================*/
private final ProxyServer proxy;
/*========================================================================*/
private final Yaml yaml = new Yaml();
private final EventBus eventBus = new EventBus();
private final Map<String, Plugin> plugins = new HashMap<>();
private final Yaml yaml;
private final EventBus eventBus;
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 Map<String, PluginDescription> toLoad = new HashMap<>();
private final Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create();
private final Multimap<Plugin, Listener> listenersByPlugin = ArrayListMultimap.create();
@SuppressWarnings("unchecked")
public PluginManager(ProxyServer proxy)
{
this.proxy = proxy;
// Ignore unknown entries in the plugin descriptions
Constructor yamlConstructor = new Constructor( new LoaderOptions() );
PropertyUtils propertyUtils = yamlConstructor.getPropertyUtils();
propertyUtils.setSkipMissingProperties( true );
yamlConstructor.setPropertyUtils( propertyUtils );
yaml = new Yaml( yamlConstructor );
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;
}
/**
* Register a command so that it may be executed.
@ -48,11 +93,12 @@ public class PluginManager
*/
public void registerCommand(Plugin plugin, Command command)
{
commandMap.put( command.getName().toLowerCase(), command );
commandMap.put( command.getName().toLowerCase( Locale.ROOT ), command );
for ( String alias : command.getAliases() )
{
commandMap.put( alias.toLowerCase(), command );
commandMap.put( alias.toLowerCase( Locale.ROOT ), command );
}
commandsByPlugin.put( plugin, command );
}
/**
@ -62,7 +108,54 @@ public class PluginManager
*/
public void unregisterCommand(Command command)
{
commandMap.values().remove( command );
while ( commandMap.values().remove( command ) );
commandsByPlugin.values().remove( command );
}
/**
* Unregister all commands owned by a {@link Plugin}
*
* @param plugin the plugin to register the commands of
*/
public void unregisterCommands(Plugin plugin)
{
for ( Iterator<Command> it = commandsByPlugin.get( plugin ).iterator(); it.hasNext(); )
{
Command command = it.next();
while ( commandMap.values().remove( command ) );
it.remove();
}
}
private Command getCommandIfEnabled(String commandName, CommandSender sender)
{
String commandLower = commandName.toLowerCase( Locale.ROOT );
// Check if command is disabled when a player sent the command
if ( ( sender instanceof ProxiedPlayer ) && proxy.getDisabledCommands().contains( commandLower ) )
{
return null;
}
return commandMap.get( commandLower );
}
/**
* Checks if the command is registered and can possibly be executed by the
* sender (without taking permissions into account).
*
* @param commandName the name of the command
* @param sender the sender executing the command
* @return whether the command will be handled
*/
public boolean isExecutableCommand(String commandName, CommandSender sender)
{
return getCommandIfEnabled( commandName, sender ) != null;
}
public boolean dispatchCommand(CommandSender sender, String commandLine)
{
return dispatchCommand( sender, commandLine, null );
}
/**
@ -71,28 +164,55 @@ public class PluginManager
* @param sender the sender executing the command
* @param commandLine the complete command line including command name and
* arguments
* @param tabResults list to place tab results into. If this list is non
* null then the command will not be executed and tab results will be
* returned instead.
* @return whether the command was handled
*/
public boolean dispatchCommand(CommandSender sender, String commandLine)
public boolean dispatchCommand(CommandSender sender, String commandLine, List<String> tabResults)
{
String[] split = argsSplit.split( commandLine );
Command command = commandMap.get( split[0].toLowerCase() );
String[] split = commandLine.split( " ", -1 );
// Check for chat that only contains " "
if ( split.length == 0 || split[0].isEmpty() )
{
return false;
}
Command command = getCommandIfEnabled( split[0], sender );
if ( command == null )
{
return false;
}
String permission = command.getPermission();
if ( permission != null && !permission.isEmpty() && !sender.hasPermission( permission ) )
if ( !command.hasPermission( sender ) )
{
sender.sendMessage( ChatColor.RED + "You do not have permission to execute this command!" );
if ( tabResults == null )
{
sender.sendMessage( ( command.getPermissionMessage() == null ) ? proxy.getTranslation( "no_permission" ) : command.getPermissionMessage() );
}
return true;
}
String[] args = Arrays.copyOfRange( split, 1, split.length );
try
{
command.execute( sender, args );
if ( tabResults == null )
{
if ( proxy.getConfig().isLogCommands() )
{
proxy.getLogger().log( Level.INFO, "{0} executed command: /{1}", new Object[]
{
sender.getName(), commandLine
} );
}
command.execute( sender, args );
} else if ( commandLine.contains( " " ) && command instanceof TabExecutor )
{
for ( String s : ( (TabExecutor) command ).onTabComplete( sender, args ) )
{
tabResults.add( s );
}
}
} catch ( Exception ex )
{
sender.sendMessage( ChatColor.RED + "An internal error occurred whilst executing this command, please check the console log for details." );
@ -122,75 +242,24 @@ public class PluginManager
return plugins.get( name );
}
/**
* Enable all plugins by calling the {@link Plugin#onEnable()} method.
*/
public void enablePlugins()
public void loadPlugins()
{
Map<Plugin, Boolean> pluginStatuses = new HashMap<>();
for ( Map.Entry<String, Plugin> entry : plugins.entrySet() )
Map<PluginDescription, Boolean> pluginStatuses = new HashMap<>();
for ( Map.Entry<String, PluginDescription> entry : toLoad.entrySet() )
{
Plugin plugin = entry.getValue();
if ( !this.enablePlugin( pluginStatuses, new Stack<Plugin>(), plugin ) )
PluginDescription plugin = entry.getValue();
if ( !enablePlugin( pluginStatuses, new Stack<PluginDescription>(), plugin ) )
{
ProxyServer.getInstance().getLogger().warning( "Failed to enable " + entry.getKey() );
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Failed to enable {0}", entry.getKey() );
}
}
toLoad.clear();
toLoad = null;
}
private boolean enablePlugin(Map<Plugin, Boolean> pluginStatuses, Stack<Plugin> dependStack, Plugin plugin)
public void enablePlugins()
{
if ( pluginStatuses.containsKey( plugin ) )
{
return pluginStatuses.get( plugin );
}
// success status
boolean status = true;
// try to load dependencies first
for ( String dependName : plugin.getDescription().getDepends() )
{
Plugin depend = this.plugins.get( dependName );
Boolean dependStatus = depend != null ? pluginStatuses.get( depend ) : Boolean.FALSE;
if ( dependStatus == null )
{
if ( dependStack.contains( depend ) )
{
StringBuilder dependencyGraph = new StringBuilder();
for ( Plugin element : dependStack )
{
dependencyGraph.append( element.getDescription().getName() ).append( " -> " );
}
dependencyGraph.append( plugin.getDescription().getName() ).append( " -> " ).append( dependName );
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Circular dependency detected: " + dependencyGraph );
status = false;
} else
{
dependStack.push( plugin );
dependStatus = this.enablePlugin( pluginStatuses, dependStack, depend );
dependStack.pop();
}
}
if ( dependStatus == Boolean.FALSE )
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} (required by {1}) is unavailable", new Object[]
{
depend.getDescription().getName(), plugin.getDescription().getName()
} );
status = false;
}
if ( !status )
{
break;
}
}
// do actual loading
if ( status )
for ( Plugin plugin : plugins.values() )
{
try
{
@ -202,59 +271,98 @@ public class PluginManager
} catch ( Throwable t )
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Exception encountered when loading plugin: " + plugin.getDescription().getName(), t );
}
}
}
private boolean enablePlugin(Map<PluginDescription, Boolean> pluginStatuses, Stack<PluginDescription> dependStack, PluginDescription plugin)
{
if ( pluginStatuses.containsKey( plugin ) )
{
return pluginStatuses.get( plugin );
}
// combine all dependencies for 'for loop'
Set<String> dependencies = new HashSet<>();
dependencies.addAll( plugin.getDepends() );
dependencies.addAll( plugin.getSoftDepends() );
// success status
boolean status = true;
// try to load dependencies first
for ( String dependName : dependencies )
{
PluginDescription depend = toLoad.get( dependName );
Boolean dependStatus = ( depend != null ) ? pluginStatuses.get( depend ) : Boolean.FALSE;
if ( dependStatus == null )
{
if ( dependStack.contains( depend ) )
{
StringBuilder dependencyGraph = new StringBuilder();
for ( PluginDescription element : dependStack )
{
dependencyGraph.append( element.getName() ).append( " -> " );
}
dependencyGraph.append( plugin.getName() ).append( " -> " ).append( dependName );
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Circular dependency detected: {0}", dependencyGraph );
status = false;
} else
{
dependStack.push( plugin );
dependStatus = this.enablePlugin( pluginStatuses, dependStack, depend );
dependStack.pop();
}
}
if ( dependStatus == Boolean.FALSE && plugin.getDepends().contains( dependName ) ) // only fail if this wasn't a soft dependency
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} (required by {1}) is unavailable", new Object[]
{
String.valueOf( dependName ), plugin.getName()
} );
status = false;
}
dependencyGraph.putEdge( plugin.getName(), dependName );
if ( !status )
{
break;
}
}
// do actual loading
if ( status )
{
try
{
URLClassLoader loader = new PluginClassloader( proxy, plugin, plugin.getFile(), ( libraryLoader != null ) ? libraryLoader.createLoader( plugin ) : null );
Class<?> main = loader.loadClass( plugin.getMain() );
Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance();
plugins.put( plugin.getName(), clazz );
clazz.onLoad();
ProxyServer.getInstance().getLogger().log( Level.INFO, "Loaded plugin {0} version {1} by {2}", new Object[]
{
plugin.getName(), plugin.getVersion(), plugin.getAuthor()
} );
} catch ( Throwable t )
{
proxy.getLogger().log( Level.WARNING, "Error loading plugin " + plugin.getName(), t );
}
}
pluginStatuses.put( plugin, status );
return status;
}
/**
* Load a plugin from the specified file. This file must be in jar format.
* This will not enable plugins, {@link #enablePlugins()} must be called.
*
* @param file the file to load from
* @throws Exception Any exceptions encountered when loading a plugin from
* this file.
*/
public void loadPlugin(File file) throws Exception
{
Preconditions.checkNotNull( file, "file" );
Preconditions.checkArgument( file.isFile(), "Must load from file" );
try ( JarFile jar = new JarFile( file ) )
{
JarEntry pdf = jar.getJarEntry( "plugin.yml" );
Preconditions.checkNotNull( pdf, "Plugin must have a plugin.yml" );
try ( InputStream in = jar.getInputStream( pdf ) )
{
PluginDescription desc = yaml.loadAs( in, PluginDescription.class );
URLClassLoader loader = new PluginClassloader( new URL[]
{
file.toURI().toURL()
} );
Class<?> main = loader.loadClass( desc.getMain() );
Plugin plugin = (Plugin) main.getDeclaredConstructor().newInstance();
plugin.init( proxy, desc, file );
plugins.put( desc.getName(), plugin );
plugin.onLoad();
ProxyServer.getInstance().getLogger().log( Level.INFO, "Loaded plugin {0} version {1} by {2}", new Object[]
{
desc.getName(), desc.getVersion(), desc.getAuthor()
} );
}
}
}
/**
* Load all plugins from the specified folder.
*
* @param folder the folder to search for plugins in
*/
public void loadPlugins(File folder)
public void detectPlugins(File folder)
{
Preconditions.checkNotNull( folder, "folder" );
Preconditions.checkArgument( folder.isDirectory(), "Must load from a directory" );
@ -263,9 +371,24 @@ public class PluginManager
{
if ( file.isFile() && file.getName().endsWith( ".jar" ) )
{
try
try ( JarFile jar = new JarFile( file ) )
{
loadPlugin( file );
JarEntry pdf = jar.getJarEntry( "bungee.yml" );
if ( pdf == null )
{
pdf = jar.getJarEntry( "plugin.yml" );
}
Preconditions.checkNotNull( pdf, "Plugin must have a plugin.yml or bungee.yml" );
try ( InputStream in = jar.getInputStream( pdf ) )
{
PluginDescription desc = yaml.loadAs( in, PluginDescription.class );
Preconditions.checkNotNull( desc.getName(), "Plugin from %s has no name", file );
Preconditions.checkNotNull( desc.getMain(), "Plugin from %s has no main", file );
desc.setFile( file );
toLoad.put( desc.getName(), desc );
}
} catch ( Exception ex )
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load plugin from file " + file, ex );
@ -290,12 +413,12 @@ public class PluginManager
eventBus.post( event );
event.postCall();
long elapsed = start - System.nanoTime();
if ( elapsed > 250000 )
long elapsed = System.nanoTime() - start;
if ( elapsed > 250000000 )
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Event {0} took more {1}ns to process!", new Object[]
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Event {0} took {1}ms to process!", new Object[]
{
event, elapsed
event, elapsed / 1000000
} );
}
return event;
@ -304,13 +427,69 @@ public class PluginManager
/**
* Register a {@link Listener} for receiving called events. Methods in this
* Object which wish to receive events must be annotated with the
* {@link Subscribe} annotation.
* {@link EventHandler} annotation.
*
* @param plugin the owning plugin
* @param listener the listener to register events for
*/
public void registerListener(Plugin plugin, Listener listener)
{
for ( Method method : listener.getClass().getDeclaredMethods() )
{
Preconditions.checkArgument( !method.isAnnotationPresent( Subscribe.class ),
"Listener %s has registered using deprecated subscribe annotation! Please update to @EventHandler.", listener );
}
eventBus.register( listener );
listenersByPlugin.put( plugin, listener );
}
/**
* Unregister a {@link Listener} so that the events do not reach it anymore.
*
* @param listener the listener to unregister
*/
public void unregisterListener(Listener listener)
{
eventBus.unregister( listener );
listenersByPlugin.values().remove( listener );
}
/**
* Unregister all of a Plugin's listener.
*
* @param plugin target plugin
*/
public void unregisterListeners(Plugin plugin)
{
for ( Iterator<Listener> it = listenersByPlugin.get( plugin ).iterator(); it.hasNext(); )
{
eventBus.unregister( it.next() );
it.remove();
}
}
/**
* Get an unmodifiable collection of all registered commands.
*
* @return commands
*/
public Collection<Map.Entry<String, Command>> getCommands()
{
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;
}
}

View File

@ -0,0 +1,9 @@
package net.md_5.bungee.api.plugin;
import net.md_5.bungee.api.CommandSender;
public interface TabExecutor
{
public Iterable<String> onTabComplete(CommandSender sender, String[] args);
}

View File

@ -0,0 +1,34 @@
package net.md_5.bungee.api.scheduler;
import java.util.concurrent.ThreadFactory;
import lombok.Data;
import net.md_5.bungee.api.plugin.Plugin;
@Data
@Deprecated
public class GroupedThreadFactory implements ThreadFactory
{
private final ThreadGroup group;
public static final class BungeeGroup extends ThreadGroup
{
private BungeeGroup(String name)
{
super( name );
}
}
public GroupedThreadFactory(Plugin plugin, String name)
{
this.group = new BungeeGroup( name );
}
@Override
public Thread newThread(Runnable r)
{
return new Thread( group, r );
}
}

View File

@ -1,6 +1,5 @@
package net.md_5.bungee.api.scheduler;
import java.util.concurrent.TimeUnit;
import net.md_5.bungee.api.plugin.Plugin;
/**
@ -31,11 +30,7 @@ public interface ScheduledTask
Runnable getTask();
/**
* Get the delay in the specified unit before this task will next be
* executed.
*
* @param unit the unit to get the delay in
* @return the time before the next execution of this task
* Cancel this task to suppress subsequent executions.
*/
long getDelay(TimeUnit unit);
void cancel();
}

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.api.scheduler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import net.md_5.bungee.api.plugin.Plugin;
@ -65,10 +66,29 @@ public interface TaskScheduler
*
* @param owner the plugin owning this task
* @param task the task to run
* @param delay the delay in milliseconds before this task will be executed
* @param delay the delay before this task will be executed
* @param period the interval before subsequent executions of this task
* @param unit the unit in which the delay and period will be measured
* @return the scheduled task
*/
ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit);
/**
* Get the unsafe methods of this class.
*
* @return the unsafe method interface
*/
Unsafe unsafe();
interface Unsafe
{
/**
* An executor service which underlies this scheduler.
*
* @param plugin owning plugin
* @return the underlying executor service or compatible wrapper
*/
ExecutorService getExecutorService(Plugin plugin);
}
}

View File

@ -1,11 +1,13 @@
package net.md_5.bungee.api.scoreboard;
package net.md_5.bungee.api.score;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* Represents an objective entry.
*/
@Data
@AllArgsConstructor
public class Objective
{
@ -16,5 +18,9 @@ public class Objective
/**
* Value of the objective.
*/
private final String value; // displayName
private String value;
/**
* Type; integer or hearts
*/
private String type;
}

View File

@ -0,0 +1,28 @@
package net.md_5.bungee.api.score;
/**
* Represents locations for a scoreboard to be displayed.
*/
public enum Position
{
LIST,
SIDEBAR,
BELOW,
SIDEBAR_BLACK,
SIDEBAR_DARK_BLUE,
SIDEBAR_DARK_GREEN,
SIDEBAR_DARK_AQUA,
SIDEBAR_DARK_RED,
SIDEBAR_DARK_PURPLE,
SIDEBAR_GOLD,
SIDEBAR_GRAY,
SIDEBAR_DARK_GRAY,
SIDEBAR_BLUE,
SIDEBAR_GREEN,
SIDEBAR_AQUA,
SIDEBAR_RED,
SIDEBAR_LIGHT_PURPLE,
SIDEBAR_YELLOW,
SIDEBAR_WHITE;
}

View File

@ -1,4 +1,4 @@
package net.md_5.bungee.api.scoreboard;
package net.md_5.bungee.api.score;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package net.md_5.bungee.api.scoreboard;
package net.md_5.bungee.api.score;
import com.google.common.base.Preconditions;
import java.util.Collection;
@ -59,10 +59,14 @@ public class Scoreboard
public void addScore(Score score)
{
Preconditions.checkNotNull( score, "score" );
Preconditions.checkArgument( !scores.containsKey( score.getItemName() ), "Score %s already exists in this scoreboard", score.getItemName() );
scores.put( score.getItemName(), score );
}
public Score getScore(String name)
{
return scores.get( name );
}
public void addTeam(Team team)
{
Preconditions.checkNotNull( team, "team" );
@ -75,6 +79,11 @@ public class Scoreboard
return teams.get( name );
}
public Objective getObjective(String name)
{
return objectives.get( name );
}
public void removeObjective(String objectiveName)
{
objectives.remove( objectiveName );

View File

@ -1,20 +1,25 @@
package net.md_5.bungee.api.scoreboard;
package net.md_5.bungee.api.score;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;
import lombok.NonNull;
@Data
public class Team
{
@NonNull
private final String name;
private String displayName;
private String prefix;
private String suffix;
private byte friendlyMode;
private byte friendlyFire;
private String nameTagVisibility;
private String collisionRule;
private int color;
private Set<String> players = new HashSet<>();
public Collection<String> getPlayers()

View File

@ -1,10 +0,0 @@
package net.md_5.bungee.api.scoreboard;
/**
* Represents locations for a scoreboard to be displayed.
*/
public enum Position
{
LIST, SIDEBAR, BELOW;
}

View File

@ -0,0 +1,50 @@
package net.md_5.bungee.command;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import java.util.Locale;
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.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
/**
* @deprecated internal use only
*/
@Deprecated
public abstract class PlayerCommand extends Command implements TabExecutor
{
public PlayerCommand(String name)
{
super( name );
}
public PlayerCommand(String name, String permission, String... aliases)
{
super( name, permission, aliases );
}
@Override
public Iterable<String> onTabComplete(CommandSender sender, String[] args)
{
final String lastArg = ( args.length > 0 ) ? args[args.length - 1].toLowerCase( Locale.ROOT ) : "";
return Iterables.transform( Iterables.filter( ProxyServer.getInstance().getPlayers(), new Predicate<ProxiedPlayer>()
{
@Override
public boolean apply(ProxiedPlayer player)
{
return player.getName().toLowerCase( Locale.ROOT ).startsWith( lastArg );
}
} ), new Function<ProxiedPlayer, String>()
{
@Override
public String apply(ProxiedPlayer player)
{
return player.getName();
}
} );
}
}

View File

@ -0,0 +1,22 @@
package net.md_5.bungee.util;
import gnu.trove.strategy.HashingStrategy;
import java.util.Locale;
class CaseInsensitiveHashingStrategy implements HashingStrategy
{
static final CaseInsensitiveHashingStrategy INSTANCE = new CaseInsensitiveHashingStrategy();
@Override
public int computeHashCode(Object object)
{
return ( (String) object ).toLowerCase( Locale.ROOT ).hashCode();
}
@Override
public boolean equals(Object o1, Object o2)
{
return o1.equals( o2 ) || ( o1 instanceof String && o2 instanceof String && ( (String) o1 ).toLowerCase( Locale.ROOT ).equals( ( (String) o2 ).toLowerCase( Locale.ROOT ) ) );
}
}

View File

@ -0,0 +1,18 @@
package net.md_5.bungee.util;
import gnu.trove.map.hash.TCustomHashMap;
import java.util.Map;
public class CaseInsensitiveMap<V> extends TCustomHashMap<String, V>
{
public CaseInsensitiveMap()
{
super( CaseInsensitiveHashingStrategy.INSTANCE );
}
public CaseInsensitiveMap(Map<? extends String, ? extends V> map)
{
super( CaseInsensitiveHashingStrategy.INSTANCE, map );
}
}

View File

@ -0,0 +1,18 @@
package net.md_5.bungee.util;
import gnu.trove.set.hash.TCustomHashSet;
import java.util.Collection;
public class CaseInsensitiveSet extends TCustomHashSet<String>
{
public CaseInsensitiveSet()
{
super( CaseInsensitiveHashingStrategy.INSTANCE );
}
public CaseInsensitiveSet(Collection<? extends String> collection)
{
super( CaseInsensitiveHashingStrategy.INSTANCE, collection );
}
}

View File

@ -0,0 +1,93 @@
package net.md_5.bungee.api;
import static org.junit.jupiter.api.Assertions.*;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collection;
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 org.junit.jupiter.api.Test;
public class ServerConnectRequestTest
{
private static final ServerInfo DUMMY_INFO = new ServerInfo()
{
@Override
public String getName()
{
return null;
}
@Override
public SocketAddress getSocketAddress()
{
return null;
}
@Override
public InetSocketAddress getAddress()
{
return null;
}
@Override
public Collection<ProxiedPlayer> getPlayers()
{
return null;
}
@Override
public String getMotd()
{
return null;
}
@Override
public boolean isRestricted()
{
return false;
}
@Override
public String getPermission()
{
return null;
}
@Override
public boolean canAccess(CommandSender sender)
{
return true;
}
@Override
public void sendData(String channel, byte[] data)
{
}
@Override
public boolean sendData(String channel, byte[] data, boolean queue)
{
return false;
}
@Override
public void ping(Callback<ServerPing> callback)
{
}
};
@Test
public void testNullTarget()
{
assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( null ).reason( ServerConnectEvent.Reason.JOIN_PROXY ).build() );
}
@Test
public void testNullReason()
{
assertThrows( NullPointerException.class, () -> ServerConnectRequest.builder().target( DUMMY_INFO ).reason( null ).build() );
}
}

View File

@ -0,0 +1,56 @@
package net.md_5.bungee.util;
import static org.junit.jupiter.api.Assertions.*;
import io.netty.channel.unix.DomainSocketAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.Util;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@RequiredArgsConstructor
public class AddressParseTest
{
public static Stream<Arguments> data()
{
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 ),
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 ),
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 ),
Arguments.of( "unix:///var/run/bungee.sock", "/var/run/bungee.sock", -1 )
);
}
@ParameterizedTest
@MethodSource("data")
public void test(String line, String host, int port)
{
SocketAddress parsed = Util.getAddr( line );
if ( parsed instanceof InetSocketAddress )
{
InetSocketAddress tcp = (InetSocketAddress) parsed;
assertEquals( host, tcp.getHostString() );
assertEquals( port, tcp.getPort() );
} else if ( parsed instanceof DomainSocketAddress )
{
DomainSocketAddress unix = (DomainSocketAddress) parsed;
assertEquals( host, unix.path() );
assertEquals( -1, port );
} else
{
throw new AssertionError( "Unknown socket " + parsed );
}
}
}

View File

@ -0,0 +1,34 @@
package net.md_5.bungee.util;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class CaseInsensitiveTest
{
@Test
public void testMaps()
{
Object obj = new Object();
CaseInsensitiveMap<Object> map = new CaseInsensitiveMap<>();
map.put( "FOO", obj );
assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive
assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved
// Assert that remove is case insensitive
map.remove( "FoO" );
assertFalse( map.contains( "foo" ) );
}
@Test
public void testSets()
{
CaseInsensitiveSet set = new CaseInsensitiveSet();
set.add( "FOO" );
assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive
set.remove( "FoO" );
assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive
}
}

View File

@ -0,0 +1,29 @@
package net.md_5.bungee.util;
import static org.junit.jupiter.api.Assertions.*;
import java.util.UUID;
import net.md_5.bungee.Util;
import org.junit.jupiter.api.Test;
public class UUIDTest
{
@Test
public void testSingle()
{
UUID uuid = UUID.fromString( "af74a02d-19cb-445b-b07f-6866a861f783" );
UUID uuid1 = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" );
assertEquals( uuid, uuid1 );
}
@Test
public void testMany()
{
for ( int i = 0; i < 1000; i++ )
{
UUID expected = UUID.randomUUID();
UUID actual = Util.getUUID( expected.toString().replace( "-", "" ) );
assertEquals( expected, actual, "Could not parse UUID " + expected );
}
}
}

View File

@ -0,0 +1,31 @@
<?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>

109
bootstrap/pom.xml Normal file
View File

@ -0,0 +1,109 @@
<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>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-parent</artifactId>
<version>1.21-R0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>bungeecord-bootstrap</artifactId>
<version>1.21-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>BungeeCord-Bootstrap</name>
<description>Java 1.6 loader for BungeeCord</description>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.javadoc.skip>true</maven.javadoc.skip>
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
<groupId>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-proxy</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>BungeeCord-${project.version}-${build.number}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<archive>
<manifestEntries>
<Main-Class>net.md_5.bungee.Bootstrap</Main-Class>
<Implementation-Version>${describe}</Implementation-Version>
<Specification-Version>${maven.build.timestamp}</Specification-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.SF</exclude>
<exclude>**/*.DSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
</plugins>
</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>

View File

@ -0,0 +1,17 @@
package net.md_5.bungee;
public class Bootstrap
{
public static void main(String[] args) throws Exception
{
if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 52.0 )
{
System.err.println( "*** ERROR *** BungeeCord requires Java 8 or above to function! Please download and install it!" );
System.out.println( "You can check your Java version with the command: java -version" );
return;
}
BungeeCordLauncher.main( args );
}
}

31
chat/nb-configuration.xml Normal file
View File

@ -0,0 +1,31 @@
<?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>

28
chat/pom.xml Normal file
View File

@ -0,0 +1,28 @@
<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>fr.pandacube.bungeecord</groupId>
<artifactId>bungeecord-parent</artifactId>
<version>1.21-R0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>bungeecord-chat</artifactId>
<version>1.21-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>BungeeCord-Chat</name>
<description>Minecraft JSON chat API intended for use with BungeeCord</description>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,330 @@
package net.md_5.bungee.api;
import com.google.common.base.Preconditions;
import java.awt.Color;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
import lombok.Getter;
/**
* Simplistic enumeration of all supported color values for chat.
*/
public final class ChatColor
{
/**
* The special character which prefixes all chat colour codes. Use this if
* you need to dynamically convert colour codes from your custom format.
*/
public static final char COLOR_CHAR = '\u00A7';
public static final String ALL_CODES = "0123456789AaBbCcDdEeFfKkLlMmNnOoRrXx";
/**
* Pattern to remove all colour codes.
*/
public static final Pattern STRIP_COLOR_PATTERN = Pattern.compile( "(?i)" + String.valueOf( COLOR_CHAR ) + "[0-9A-FK-ORX]" );
/**
* Colour instances keyed by their active character.
*/
private static final Map<Character, ChatColor> BY_CHAR = new HashMap<Character, ChatColor>();
/**
* Colour instances keyed by their name.
*/
private static final Map<String, ChatColor> BY_NAME = new HashMap<String, ChatColor>();
/**
* Represents black.
*/
public static final ChatColor BLACK = new ChatColor( '0', "black", new Color( 0x000000 ) );
/**
* Represents dark blue.
*/
public static final ChatColor DARK_BLUE = new ChatColor( '1', "dark_blue", new Color( 0x0000AA ) );
/**
* Represents dark green.
*/
public static final ChatColor DARK_GREEN = new ChatColor( '2', "dark_green", new Color( 0x00AA00 ) );
/**
* Represents dark blue (aqua).
*/
public static final ChatColor DARK_AQUA = new ChatColor( '3', "dark_aqua", new Color( 0x00AAAA ) );
/**
* Represents dark red.
*/
public static final ChatColor DARK_RED = new ChatColor( '4', "dark_red", new Color( 0xAA0000 ) );
/**
* Represents dark purple.
*/
public static final ChatColor DARK_PURPLE = new ChatColor( '5', "dark_purple", new Color( 0xAA00AA ) );
/**
* Represents gold.
*/
public static final ChatColor GOLD = new ChatColor( '6', "gold", new Color( 0xFFAA00 ) );
/**
* Represents gray.
*/
public static final ChatColor GRAY = new ChatColor( '7', "gray", new Color( 0xAAAAAA ) );
/**
* Represents dark gray.
*/
public static final ChatColor DARK_GRAY = new ChatColor( '8', "dark_gray", new Color( 0x555555 ) );
/**
* Represents blue.
*/
public static final ChatColor BLUE = new ChatColor( '9', "blue", new Color( 0x5555FF ) );
/**
* Represents green.
*/
public static final ChatColor GREEN = new ChatColor( 'a', "green", new Color( 0x55FF55 ) );
/**
* Represents aqua.
*/
public static final ChatColor AQUA = new ChatColor( 'b', "aqua", new Color( 0x55FFFF ) );
/**
* Represents red.
*/
public static final ChatColor RED = new ChatColor( 'c', "red", new Color( 0xFF5555 ) );
/**
* Represents light purple.
*/
public static final ChatColor LIGHT_PURPLE = new ChatColor( 'd', "light_purple", new Color( 0xFF55FF ) );
/**
* Represents yellow.
*/
public static final ChatColor YELLOW = new ChatColor( 'e', "yellow", new Color( 0xFFFF55 ) );
/**
* Represents white.
*/
public static final ChatColor WHITE = new ChatColor( 'f', "white", new Color( 0xFFFFFF ) );
/**
* Represents magical characters that change around randomly.
*/
public static final ChatColor MAGIC = new ChatColor( 'k', "obfuscated" );
/**
* Makes the text bold.
*/
public static final ChatColor BOLD = new ChatColor( 'l', "bold" );
/**
* Makes a line appear through the text.
*/
public static final ChatColor STRIKETHROUGH = new ChatColor( 'm', "strikethrough" );
/**
* Makes the text appear underlined.
*/
public static final ChatColor UNDERLINE = new ChatColor( 'n', "underline" );
/**
* Makes the text italic.
*/
public static final ChatColor ITALIC = new ChatColor( 'o', "italic" );
/**
* Resets all previous chat colors or formats.
*/
public static final ChatColor RESET = new ChatColor( 'r', "reset" );
/**
* Count used for populating legacy ordinal.
*/
private static int count = 0;
/**
* This colour's colour char prefixed by the {@link #COLOR_CHAR}.
*/
private final String toString;
@Getter
private final String name;
private final int ordinal;
/**
* The RGB color of the ChatColor. null for non-colors (formatting)
*/
@Getter
private final Color color;
private ChatColor(char code, String name)
{
this( code, name, null );
}
private ChatColor(char code, String name, Color color)
{
this.name = name;
this.toString = new String( new char[]
{
COLOR_CHAR, code
} );
this.ordinal = count++;
this.color = color;
BY_CHAR.put( code, this );
BY_NAME.put( name.toUpperCase( Locale.ROOT ), this );
}
private ChatColor(String name, String toString, int rgb)
{
this.name = name;
this.toString = toString;
this.ordinal = -1;
this.color = new Color( rgb );
}
@Override
public int hashCode()
{
int hash = 7;
hash = 53 * hash + Objects.hashCode( this.toString );
return hash;
}
@Override
public boolean equals(Object obj)
{
if ( this == obj )
{
return true;
}
if ( obj == null || getClass() != obj.getClass() )
{
return false;
}
final ChatColor other = (ChatColor) obj;
return Objects.equals( this.toString, other.toString );
}
@Override
public String toString()
{
return toString;
}
/**
* Strips the given message of all color codes
*
* @param input String to strip of color
* @return A copy of the input string, without any coloring
*/
public static String stripColor(final String input)
{
if ( input == null )
{
return null;
}
return STRIP_COLOR_PATTERN.matcher( input ).replaceAll( "" );
}
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate)
{
char[] b = textToTranslate.toCharArray();
for ( int i = 0; i < b.length - 1; i++ )
{
if ( b[i] == altColorChar && ALL_CODES.indexOf( b[i + 1] ) > -1 )
{
b[i] = ChatColor.COLOR_CHAR;
b[i + 1] = Character.toLowerCase( b[i + 1] );
}
}
return new String( b );
}
/**
* Get the colour represented by the specified code.
*
* @param code the code to search for
* @return the mapped colour, or null if non exists
*/
public static ChatColor getByChar(char code)
{
return BY_CHAR.get( code );
}
public static ChatColor of(Color color)
{
return of( "#" + String.format( "%08x", color.getRGB() ).substring( 2 ) );
}
public static ChatColor of(String string)
{
Preconditions.checkArgument( string != null, "string cannot be null" );
if ( string.length() == 7 && string.charAt( 0 ) == '#' )
{
int rgb;
try
{
rgb = Integer.parseInt( string.substring( 1 ), 16 );
} catch ( NumberFormatException ex )
{
throw new IllegalArgumentException( "Illegal hex string " + string );
}
StringBuilder magic = new StringBuilder( COLOR_CHAR + "x" );
for ( char c : string.substring( 1 ).toCharArray() )
{
magic.append( COLOR_CHAR ).append( c );
}
return new ChatColor( string, magic.toString(), rgb );
}
ChatColor defined = BY_NAME.get( string.toUpperCase( Locale.ROOT ) );
if ( defined != null )
{
return defined;
}
throw new IllegalArgumentException( "Could not parse ChatColor " + string );
}
/**
* See {@link Enum#valueOf(java.lang.Class, java.lang.String)}.
*
* @param name color name
* @return ChatColor
* @deprecated holdover from when this class was an enum
*/
@Deprecated
public static ChatColor valueOf(String name)
{
Preconditions.checkNotNull( name, "Name is null" );
ChatColor defined = BY_NAME.get( name );
Preconditions.checkArgument( defined != null, "No enum constant " + ChatColor.class.getName() + "." + name );
return defined;
}
/**
* Get an array of all defined colors and formats.
*
* @return copied array of all colors and formats
* @deprecated holdover from when this class was an enum
*/
@Deprecated
public static ChatColor[] values()
{
return BY_CHAR.values().toArray( new ChatColor[ 0 ] );
}
/**
* See {@link Enum#name()}.
*
* @return constant name
* @deprecated holdover from when this class was an enum
*/
@Deprecated
public String name()
{
return getName().toUpperCase( Locale.ROOT );
}
/**
* See {@link Enum#ordinal()}.
*
* @return ordinal
* @deprecated holdover from when this class was an enum
*/
@Deprecated
public int ordinal()
{
Preconditions.checkArgument( ordinal >= 0, "Cannot get ordinal of hex color" );
return ordinal;
}
}

View File

@ -0,0 +1,12 @@
package net.md_5.bungee.api;
/**
* Represents the position on the screen where a message will appear.
*/
public enum ChatMessageType
{
CHAT,
SYSTEM,
ACTION_BAR
}

View File

@ -0,0 +1,743 @@
package net.md_5.bungee.api.chat;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ComponentBuilder.FormatRetention;
@Setter
@ToString(exclude = "parent")
@EqualsAndHashCode(exclude = "parent")
public abstract class BaseComponent
{
@Setter(AccessLevel.NONE)
BaseComponent parent;
/**
* The component's style.
*/
@Getter
private ComponentStyle style = new ComponentStyle();
/**
* The text to insert into the chat when this component (and child
* components) are clicked while pressing the shift key
*/
@Getter
private String insertion;
/**
* Appended components that inherit this component's formatting and events
*/
@Getter
private List<BaseComponent> extra;
/**
* The action to perform when this component (and child components) are
* clicked
*/
@Getter
private ClickEvent clickEvent;
/**
* The action to perform when this component (and child components) are
* hovered over
*/
@Getter
private HoverEvent hoverEvent;
/**
* Whether this component rejects previous formatting
*/
@Getter
private transient boolean reset;
/**
* Default constructor.
*
* @deprecated for use by internal classes only, will be removed.
*/
@Deprecated
public BaseComponent()
{
}
BaseComponent(BaseComponent old)
{
copyFormatting( old, FormatRetention.ALL, true );
if ( old.getExtra() != null )
{
for ( BaseComponent extra : old.getExtra() )
{
addExtra( extra.duplicate() );
}
}
}
/**
* Copies the events and formatting of a BaseComponent. Already set
* formatting will be replaced.
*
* @param component the component to copy from
*/
public void copyFormatting(BaseComponent component)
{
copyFormatting( component, FormatRetention.ALL, true );
}
/**
* Copies the events and formatting of a BaseComponent.
*
* @param component the component to copy from
* @param replace if already set formatting should be replaced by the new
* component
*/
public void copyFormatting(BaseComponent component, boolean replace)
{
copyFormatting( component, FormatRetention.ALL, replace );
}
/**
* Copies the specified formatting of a BaseComponent.
*
* @param component the component to copy from
* @param retention the formatting to copy
* @param replace if already set formatting should be replaced by the new
* component
*/
public void copyFormatting(BaseComponent component, FormatRetention retention, boolean replace)
{
if ( retention == FormatRetention.EVENTS || retention == FormatRetention.ALL )
{
if ( replace || clickEvent == null )
{
setClickEvent( component.getClickEvent() );
}
if ( replace || hoverEvent == null )
{
setHoverEvent( component.getHoverEvent() );
}
}
if ( retention == FormatRetention.FORMATTING || retention == FormatRetention.ALL )
{
if ( replace || !style.hasColor() )
{
setColor( component.getColorRaw() );
}
if ( replace || !style.hasShadowColor() )
{
setShadowColor( component.getShadowColorRaw() );
}
if ( replace || !style.hasFont() )
{
setFont( component.getFontRaw() );
}
if ( replace || style.isBoldRaw() == null )
{
setBold( component.isBoldRaw() );
}
if ( replace || style.isItalicRaw() == null )
{
setItalic( component.isItalicRaw() );
}
if ( replace || style.isUnderlinedRaw() == null )
{
setUnderlined( component.isUnderlinedRaw() );
}
if ( replace || style.isStrikethroughRaw() == null )
{
setStrikethrough( component.isStrikethroughRaw() );
}
if ( replace || style.isObfuscatedRaw() == null )
{
setObfuscated( component.isObfuscatedRaw() );
}
if ( replace || insertion == null )
{
setInsertion( component.getInsertion() );
}
}
}
/**
* Retains only the specified formatting.
*
* @param retention the formatting to retain
*/
public void retain(FormatRetention retention)
{
if ( retention == FormatRetention.FORMATTING || retention == FormatRetention.NONE )
{
setClickEvent( null );
setHoverEvent( null );
}
if ( retention == FormatRetention.EVENTS || retention == FormatRetention.NONE )
{
setColor( null );
setShadowColor( null );
setBold( null );
setItalic( null );
setUnderlined( null );
setStrikethrough( null );
setObfuscated( null );
setInsertion( null );
}
}
/**
* Clones the BaseComponent and returns the clone.
*
* @return The duplicate of this BaseComponent
*/
public abstract BaseComponent duplicate();
/**
* Clones the BaseComponent without formatting and returns the clone.
*
* @return The duplicate of this BaseComponent
* @deprecated API use discouraged, use traditional duplicate
*/
@Deprecated
public BaseComponent duplicateWithoutFormatting()
{
BaseComponent component = duplicate();
component.retain( FormatRetention.NONE );
return component;
}
/**
* Converts the components to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @param components the components to convert
* @return the string in the old format
*/
public static String toLegacyText(BaseComponent... components)
{
StringBuilder builder = new StringBuilder();
for ( BaseComponent msg : components )
{
builder.append( msg.toLegacyText() );
}
return builder.toString();
}
/**
* Converts the components into a string without any formatting
*
* @param components the components to convert
* @return the string as plain text
*/
public static String toPlainText(BaseComponent... components)
{
StringBuilder builder = new StringBuilder();
for ( BaseComponent msg : components )
{
builder.append( msg.toPlainText() );
}
return builder.toString();
}
/**
* Set the {@link ComponentStyle} for this component.
* <p>
* Unlike {@link #applyStyle(ComponentStyle)}, this method will overwrite
* all style values on this component.
*
* @param style the style to set, or null to set all style values to default
*/
public void setStyle(ComponentStyle style)
{
this.style = ( style != null ) ? style.clone() : new ComponentStyle();
}
/**
* Set this component's color.
* <p>
* <b>Warning: This should be a color, not formatting code (ie,
* {@link ChatColor#color} should not be null).</b>
*
* @param color the component color, or null to use the default
*/
public void setColor(ChatColor color)
{
this.style.setColor( color );
}
/**
* Returns the color of this component. This uses the parent's color if this
* component doesn't have one. {@link net.md_5.bungee.api.ChatColor#WHITE}
* is returned if no color is found.
*
* @return the color of this component
*/
public ChatColor getColor()
{
if ( !style.hasColor() )
{
if ( parent == null )
{
return ChatColor.WHITE;
}
return parent.getColor();
}
return style.getColor();
}
/**
* Returns the color of this component without checking the parents color.
* May return null
*
* @return the color of this component
*/
public ChatColor getColorRaw()
{
return style.getColor();
}
/**
* Set this component's shadow color.
*
* @param color the component shadow color, or null to use the default
*/
public void setShadowColor(Color color)
{
this.style.setShadowColor( color );
}
/**
* Returns the shadow color of this component. This uses the parent's shadow color if this
* component doesn't have one. null is returned if no shadow color is found.
*
* @return the shadow color of this component
*/
public Color getShadowColor()
{
if ( !style.hasShadowColor() )
{
if ( parent == null )
{
return null;
}
return parent.getShadowColor();
}
return style.getShadowColor();
}
/**
* Returns the shadow color of this component without checking the parents
* shadow color. May return null
*
* @return the shadow color of this component
*/
public Color getShadowColorRaw()
{
return style.getShadowColor();
}
/**
* Set this component's font.
*
* @param font the font to set, or null to use the default
*/
public void setFont(String font)
{
this.style.setFont( font );
}
/**
* Returns the font of this component. This uses the parent's font if this
* component doesn't have one.
*
* @return the font of this component, or null if default font
*/
public String getFont()
{
if ( !style.hasFont() )
{
if ( parent == null )
{
return null;
}
return parent.getFont();
}
return style.getFont();
}
/**
* Returns the font of this component without checking the parents font. May
* return null
*
* @return the font of this component
*/
public String getFontRaw()
{
return style.getFont();
}
/**
* Set whether or not this component is bold.
*
* @param bold the new bold state, or null to use the default
*/
public void setBold(Boolean bold)
{
this.style.setBold( bold );
}
/**
* Returns whether this component is bold. This uses the parent's setting if
* this component hasn't been set. false is returned if none of the parent
* chain has been set.
*
* @return whether the component is bold
*/
public boolean isBold()
{
if ( style.isBoldRaw() == null )
{
return parent != null && parent.isBold();
}
return style.isBold();
}
/**
* Returns whether this component is bold without checking the parents
* setting. May return null
*
* @return whether the component is bold
*/
public Boolean isBoldRaw()
{
return style.isBoldRaw();
}
/**
* Set whether or not this component is italic.
*
* @param italic the new italic state, or null to use the default
*/
public void setItalic(Boolean italic)
{
this.style.setItalic( italic );
}
/**
* Returns whether this component is italic. This uses the parent's setting
* if this component hasn't been set. false is returned if none of the
* parent chain has been set.
*
* @return whether the component is italic
*/
public boolean isItalic()
{
if ( style.isItalicRaw() == null )
{
return parent != null && parent.isItalic();
}
return style.isItalic();
}
/**
* Returns whether this component is italic without checking the parents
* setting. May return null
*
* @return whether the component is italic
*/
public Boolean isItalicRaw()
{
return style.isItalicRaw();
}
/**
* Set whether or not this component is underlined.
*
* @param underlined the new underlined state, or null to use the default
*/
public void setUnderlined(Boolean underlined)
{
this.style.setUnderlined( underlined );
}
/**
* Returns whether this component is underlined. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is underlined
*/
public boolean isUnderlined()
{
if ( style.isUnderlinedRaw() == null )
{
return parent != null && parent.isUnderlined();
}
return style.isUnderlined();
}
/**
* Returns whether this component is underlined without checking the parents
* setting. May return null
*
* @return whether the component is underlined
*/
public Boolean isUnderlinedRaw()
{
return style.isUnderlinedRaw();
}
/**
* Set whether or not this component is strikethrough.
*
* @param strikethrough the new strikethrough state, or null to use the
* default
*/
public void setStrikethrough(Boolean strikethrough)
{
this.style.setStrikethrough( strikethrough );
}
/**
* Returns whether this component is strikethrough. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is strikethrough
*/
public boolean isStrikethrough()
{
if ( style.isStrikethroughRaw() == null )
{
return parent != null && parent.isStrikethrough();
}
return style.isStrikethrough();
}
/**
* Returns whether this component is strikethrough without checking the
* parents setting. May return null
*
* @return whether the component is strikethrough
*/
public Boolean isStrikethroughRaw()
{
return style.isStrikethroughRaw();
}
/**
* Set whether or not this component is obfuscated.
*
* @param obfuscated the new obfuscated state, or null to use the default
*/
public void setObfuscated(Boolean obfuscated)
{
this.style.setObfuscated( obfuscated );
}
/**
* Returns whether this component is obfuscated. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is obfuscated
*/
public boolean isObfuscated()
{
if ( style.isObfuscatedRaw() == null )
{
return parent != null && parent.isObfuscated();
}
return style.isObfuscated();
}
/**
* Returns whether this component is obfuscated without checking the parents
* setting. May return null
*
* @return whether the component is obfuscated
*/
public Boolean isObfuscatedRaw()
{
return style.isObfuscatedRaw();
}
/**
* Apply the style from the given {@link ComponentStyle} to this component.
* <p>
* Any style values that have been explicitly set in the style will be
* applied to this component. If a value is not set in the style, it will
* not override the style set in this component.
*
* @param style the style to apply
*/
public void applyStyle(ComponentStyle style)
{
if ( style.hasColor() )
{
setColor( style.getColor() );
}
if ( style.hasShadowColor() )
{
setShadowColor( style.getShadowColor() );
}
if ( style.hasFont() )
{
setFont( style.getFont() );
}
if ( style.isBoldRaw() != null )
{
setBold( style.isBoldRaw() );
}
if ( style.isItalicRaw() != null )
{
setItalic( style.isItalicRaw() );
}
if ( style.isUnderlinedRaw() != null )
{
setUnderlined( style.isUnderlinedRaw() );
}
if ( style.isStrikethroughRaw() != null )
{
setStrikethrough( style.isStrikethroughRaw() );
}
if ( style.isObfuscatedRaw() != null )
{
setObfuscated( style.isObfuscatedRaw() );
}
}
public void setExtra(List<BaseComponent> components)
{
for ( BaseComponent component : components )
{
component.parent = this;
}
extra = components;
}
/**
* Appends a text element to the component. The text will inherit this
* component's formatting
*
* @param text the text to append
*/
public void addExtra(String text)
{
addExtra( new TextComponent( text ) );
}
/**
* Appends a component to the component. The text will inherit this
* component's formatting
*
* @param component the component to append
*/
public void addExtra(BaseComponent component)
{
if ( extra == null )
{
extra = new ArrayList<BaseComponent>();
}
component.parent = this;
extra.add( component );
}
/**
* Returns whether the component has any styling applied to it.
*
* @return Whether any styling is applied
*/
public boolean hasStyle()
{
return !style.isEmpty();
}
/**
* Returns whether the component has any formatting or events applied to it
*
* @return Whether any formatting or events are applied
*/
public boolean hasFormatting()
{
return hasStyle() || insertion != null
|| hoverEvent != null || clickEvent != null;
}
/**
* Converts the component into a string without any formatting
*
* @return the string as plain text
*/
public String toPlainText()
{
StringBuilder builder = new StringBuilder();
toPlainText( builder );
return builder.toString();
}
void toPlainText(StringBuilder builder)
{
if ( extra != null )
{
for ( BaseComponent e : extra )
{
e.toPlainText( builder );
}
}
}
/**
* Converts the component to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @return the string in the old format
*/
public String toLegacyText()
{
StringBuilder builder = new StringBuilder();
toLegacyText( builder );
return builder.toString();
}
void toLegacyText(StringBuilder builder)
{
if ( extra != null )
{
for ( BaseComponent e : extra )
{
e.toLegacyText( builder );
}
}
}
void addFormat(StringBuilder builder)
{
builder.append( getColor() );
if ( isBold() )
{
builder.append( ChatColor.BOLD );
}
if ( isItalic() )
{
builder.append( ChatColor.ITALIC );
}
if ( isUnderlined() )
{
builder.append( ChatColor.UNDERLINE );
}
if ( isStrikethrough() )
{
builder.append( ChatColor.STRIKETHROUGH );
}
if ( isObfuscated() )
{
builder.append( ChatColor.MAGIC );
}
}
}

View File

@ -0,0 +1,62 @@
package net.md_5.bungee.api.chat;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
@Getter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
public final class ClickEvent
{
/**
* The type of action to perform on click.
*/
private final Action action;
/**
* Depends on the action.
*
* @see Action
*/
private final String value;
public enum Action
{
/**
* Open a url at the path given by
* {@link net.md_5.bungee.api.chat.ClickEvent#value}.
*/
OPEN_URL,
/**
* Open a file at the path given by
* {@link net.md_5.bungee.api.chat.ClickEvent#value}.
*/
OPEN_FILE,
/**
* Run the command given by
* {@link net.md_5.bungee.api.chat.ClickEvent#value}.
*/
RUN_COMMAND,
/**
* Inserts the string given by
* {@link net.md_5.bungee.api.chat.ClickEvent#value} into the player's
* text box.
*/
SUGGEST_COMMAND,
/**
* Change to the page number given by
* {@link net.md_5.bungee.api.chat.ClickEvent#value} in a book.
*/
CHANGE_PAGE,
/**
* Copy the string given by
* {@link net.md_5.bungee.api.chat.ClickEvent#value} into the player's
* clipboard.
*/
COPY_TO_CLIPBOARD
}
}

View File

@ -0,0 +1,580 @@
package net.md_5.bungee.api.chat;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.NoArgsConstructor;
import net.md_5.bungee.api.ChatColor;
/**
* <p>
* ComponentBuilder simplifies creating basic messages by allowing the use of a
* chainable builder.
* </p>
* <pre>
* new ComponentBuilder("Hello ").color(ChatColor.RED).
* append("World").color(ChatColor.BLUE). append("!").bold(true).create();
* </pre>
* <p>
* All methods (excluding {@link #append(String)} and {@link #create()} work on
* the last part appended to the builder, so in the example above "Hello " would
* be {@link net.md_5.bungee.api.ChatColor#RED} and "World" would be
* {@link net.md_5.bungee.api.ChatColor#BLUE} but "!" would be bold and
* {@link net.md_5.bungee.api.ChatColor#BLUE} because append copies the previous
* part's formatting
* </p>
*/
@NoArgsConstructor
public final class ComponentBuilder
{
/**
* The position for the current part to modify. Modified cursors will
* automatically reset to the last part after appending new components.
* Default value at -1 to assert that the builder has no parts.
*/
@Getter
private int cursor = -1;
@Getter
private final List<BaseComponent> parts = new ArrayList<BaseComponent>();
private BaseComponent dummy;
private ComponentBuilder(BaseComponent[] parts)
{
for ( BaseComponent baseComponent : parts )
{
this.parts.add( baseComponent.duplicate() );
}
resetCursor();
}
/**
* Creates a ComponentBuilder from the other given ComponentBuilder to clone
* it.
*
* @param original the original for the new ComponentBuilder.
*/
public ComponentBuilder(ComponentBuilder original)
{
this( original.parts.toArray( new BaseComponent[ 0 ] ) );
}
/**
* Creates a ComponentBuilder with the given text as the first part.
*
* @param text the first text element
*/
public ComponentBuilder(String text)
{
this( new TextComponent( text ) );
}
/**
* Creates a ComponentBuilder with the given component as the first part.
*
* @param component the first component element
*/
public ComponentBuilder(BaseComponent component)
{
this( new BaseComponent[]
{
component
} );
}
private BaseComponent getDummy()
{
if ( dummy == null )
{
dummy = new BaseComponent()
{
@Override
public BaseComponent duplicate()
{
return this;
}
};
}
return dummy;
}
/**
* Resets the cursor to index of the last element.
*
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder resetCursor()
{
cursor = parts.size() - 1;
return this;
}
/**
* Sets the position of the current component to be modified
*
* @param pos the cursor position synonymous to an element position for a
* list
* @return this ComponentBuilder for chaining
* @throws IndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
public ComponentBuilder setCursor(int pos) throws IndexOutOfBoundsException
{
if ( ( this.cursor != pos ) && ( pos < 0 || pos >= parts.size() ) )
{
throw new IndexOutOfBoundsException( "Cursor out of bounds (expected between 0 + " + ( parts.size() - 1 ) + ")" );
}
this.cursor = pos;
return this;
}
/**
* Appends a component to the builder and makes it the current target for
* formatting. The component will have all the formatting from previous
* part.
*
* @param component the component to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent component)
{
return append( component, FormatRetention.ALL );
}
/**
* Appends a component to the builder and makes it the current target for
* formatting. You can specify the amount of formatting retained from
* previous part.
*
* @param component the component to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent component, FormatRetention retention)
{
BaseComponent previous = ( parts.isEmpty() ) ? null : parts.get( parts.size() - 1 );
if ( previous == null )
{
previous = dummy;
dummy = null;
}
if ( previous != null && !component.isReset() )
{
component.copyFormatting( previous, retention, false );
}
parts.add( component );
resetCursor();
return this;
}
/**
* Appends the components to the builder and makes the last element the
* current target for formatting. The components will have all the
* formatting from previous part.
*
* @param components the components to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent[] components)
{
return append( components, FormatRetention.ALL );
}
/**
* Appends the components to the builder and makes the last element the
* current target for formatting. You can specify the amount of formatting
* retained from previous part.
*
* @param components the components to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent[] components, FormatRetention retention)
{
Preconditions.checkArgument( components.length != 0, "No components to append" );
for ( BaseComponent component : components )
{
append( component, retention );
}
return this;
}
/**
* Appends the {@link TranslationProvider} object to the builder and makes
* the last element the current target for formatting. The components will
* have all the formatting from previous part.
*
* @param translatable the translatable object to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(TranslationProvider translatable)
{
return append( translatable, FormatRetention.ALL );
}
/**
* Appends the {@link TranslationProvider} object to the builder and makes
* the last element the current target for formatting. You can specify the
* amount of formatting retained from previous part.
*
* @param translatable the translatable object to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(TranslationProvider translatable, FormatRetention retention)
{
return append( translatable.asTranslatableComponent(), retention );
}
/**
* Appends the text to the builder and makes it the current target for
* formatting. The text will have all the formatting from previous part.
*
* @param text the text to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(String text)
{
return append( text, FormatRetention.ALL );
}
/**
* Parse text to BaseComponent[] with colors and format, appends the text to
* the builder and makes it the current target for formatting. The component
* will have all the formatting from previous part.
*
* @param text the text to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder appendLegacy(String text)
{
return append( TextComponent.fromLegacyText( text ) );
}
/**
* Appends the text to the builder and makes it the current target for
* formatting. You can specify the amount of formatting retained from
* previous part.
*
* @param text the text to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(String text, FormatRetention retention)
{
return append( new TextComponent( text ), retention );
}
/**
* Allows joining additional components to this builder using the given
* {@link Joiner} and {@link FormatRetention#ALL}.
*
* Simply executes the provided joiner on this instance to facilitate a
* chain pattern.
*
* @param joiner joiner used for operation
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(Joiner joiner)
{
return joiner.join( this, FormatRetention.ALL );
}
/**
* Allows joining additional components to this builder using the given
* {@link Joiner}.
*
* Simply executes the provided joiner on this instance to facilitate a
* chain pattern.
*
* @param joiner joiner used for operation
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(Joiner joiner, FormatRetention retention)
{
return joiner.join( this, retention );
}
/**
* Remove the component part at the position of given index.
*
* @param pos the index to remove at
* @throws IndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
public void removeComponent(int pos) throws IndexOutOfBoundsException
{
if ( parts.remove( pos ) != null )
{
resetCursor();
}
}
/**
* Gets the component part at the position of given index.
*
* @param pos the index to find
* @return the component
* @throws IndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
public BaseComponent getComponent(int pos) throws IndexOutOfBoundsException
{
return parts.get( pos );
}
/**
* Gets the component at the position of the cursor.
*
* @return the active component or null if builder is empty
*/
public BaseComponent getCurrentComponent()
{
return ( cursor == -1 ) ? getDummy() : parts.get( cursor );
}
/**
* Sets the color of the current part.
*
* @param color the new color
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder color(ChatColor color)
{
getCurrentComponent().setColor( color );
return this;
}
/**
* Sets the font of the current part.
*
* @param font the new font
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder font(String font)
{
getCurrentComponent().setFont( font );
return this;
}
/**
* Sets whether the current part is bold.
*
* @param bold whether this part is bold
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder bold(boolean bold)
{
getCurrentComponent().setBold( bold );
return this;
}
/**
* Sets whether the current part is italic.
*
* @param italic whether this part is italic
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder italic(boolean italic)
{
getCurrentComponent().setItalic( italic );
return this;
}
/**
* Sets whether the current part is underlined.
*
* @param underlined whether this part is underlined
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder underlined(boolean underlined)
{
getCurrentComponent().setUnderlined( underlined );
return this;
}
/**
* Sets whether the current part is strikethrough.
*
* @param strikethrough whether this part is strikethrough
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder strikethrough(boolean strikethrough)
{
getCurrentComponent().setStrikethrough( strikethrough );
return this;
}
/**
* Sets whether the current part is obfuscated.
*
* @param obfuscated whether this part is obfuscated
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder obfuscated(boolean obfuscated)
{
getCurrentComponent().setObfuscated( obfuscated );
return this;
}
/**
* Applies the provided {@link ComponentStyle} to the current part.
*
* @param style the style to apply
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder style(ComponentStyle style)
{
getCurrentComponent().applyStyle( style );
return this;
}
/**
* Sets the insertion text for the current part.
*
* @param insertion the insertion text
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder insertion(String insertion)
{
getCurrentComponent().setInsertion( insertion );
return this;
}
/**
* Sets the click event for the current part.
*
* @param clickEvent the click event
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder event(ClickEvent clickEvent)
{
getCurrentComponent().setClickEvent( clickEvent );
return this;
}
/**
* Sets the hover event for the current part.
*
* @param hoverEvent the hover event
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder event(HoverEvent hoverEvent)
{
getCurrentComponent().setHoverEvent( hoverEvent );
return this;
}
/**
* Sets the current part back to normal settings. Only text is kept.
*
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder reset()
{
return retain( FormatRetention.NONE );
}
/**
* Retains only the specified formatting. Text is not modified.
*
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder retain(FormatRetention retention)
{
getCurrentComponent().retain( retention );
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
* 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
*/
public BaseComponent[] create()
{
BaseComponent[] cloned = new BaseComponent[ parts.size() ];
int i = 0;
for ( BaseComponent part : parts )
{
cloned[i++] = part.duplicate();
}
return cloned;
}
public enum FormatRetention
{
/**
* Specify that we do not want to retain anything from the previous
* component.
*/
NONE,
/**
* Specify that we want the formatting retained from the previous
* component.
*/
FORMATTING,
/**
* Specify that we want the events retained from the previous component.
*/
EVENTS,
/**
* Specify that we want to retain everything from the previous
* component.
*/
ALL
}
/**
* Functional interface to join additional components to a ComponentBuilder.
*/
public interface Joiner
{
/**
* Joins additional components to the provided {@link ComponentBuilder}
* and then returns it to fulfill a chain pattern.
*
* Retention may be ignored and is to be understood as an optional
* recommendation to the Joiner and not as a guarantee to have a
* previous component in builder unmodified.
*
* @param componentBuilder to which to append additional components
* @param retention the formatting to possibly retain
* @return input componentBuilder for chaining
*/
ComponentBuilder join(ComponentBuilder componentBuilder, FormatRetention retention);
}
}

View File

@ -0,0 +1,263 @@
package net.md_5.bungee.api.chat;
import java.awt.Color;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.md_5.bungee.api.ChatColor;
/**
* Represents a style that may be applied to a {@link BaseComponent}.
*/
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public final class ComponentStyle implements Cloneable
{
/**
* The color of this style.
* <p>
* <b>Warning: This should be a color, not formatting code (ie,
* {@link ChatColor#color} should not be null).</b>
*/
private ChatColor color;
/**
* The shadow color of this style.
*/
private Color shadowColor;
/**
* The font of this style.
*/
private String font;
/**
* Whether this style is bold.
*/
private Boolean bold;
/**
* Whether this style is italic.
*/
private Boolean italic;
/**
* Whether this style is underlined.
*/
private Boolean underlined;
/**
* Whether this style is strikethrough.
*/
private Boolean strikethrough;
/**
* Whether this style is obfuscated.
*/
private Boolean obfuscated;
/**
* Returns the color of this style. May return null.
*
* @return the color of this style, or null if default color
*/
public ChatColor getColor()
{
return color;
}
/**
* Returns whether or not this style has a color set.
*
* @return whether a color is set
*/
public boolean hasColor()
{
return ( color != null );
}
/**
* Returns the shadow color of this style. May return null.
*
* @return the shadow color of this style, or null if default color
*/
public Color getShadowColor()
{
return shadowColor;
}
/**
* Returns whether or not this style has a shadow color set.
*
* @return whether a shadow color is set
*/
public boolean hasShadowColor()
{
return ( shadowColor != null );
}
/**
* Returns the font of this style. May return null.
*
* @return the font of this style, or null if default font
*/
public String getFont()
{
return font;
}
/**
* Returns whether or not this style has a font set.
*
* @return whether a font is set
*/
public boolean hasFont()
{
return ( font != null );
}
/**
* Returns whether this style is bold.
*
* @return whether the style is bold
*/
public boolean isBold()
{
return ( bold != null ) && bold.booleanValue();
}
/**
* Returns whether this style is bold. May return null.
*
* @return whether the style is bold, or null if not set
*/
public Boolean isBoldRaw()
{
return bold;
}
/**
* Returns whether this style is italic. May return null.
*
* @return whether the style is italic
*/
public boolean isItalic()
{
return ( italic != null ) && italic.booleanValue();
}
/**
* Returns whether this style is italic. May return null.
*
* @return whether the style is italic, or null if not set
*/
public Boolean isItalicRaw()
{
return italic;
}
/**
* Returns whether this style is underlined.
*
* @return whether the style is underlined
*/
public boolean isUnderlined()
{
return ( underlined != null ) && underlined.booleanValue();
}
/**
* Returns whether this style is underlined. May return null.
*
* @return whether the style is underlined, or null if not set
*/
public Boolean isUnderlinedRaw()
{
return underlined;
}
/**
* Returns whether this style is strikethrough
*
* @return whether the style is strikethrough
*/
public boolean isStrikethrough()
{
return ( strikethrough != null ) && strikethrough.booleanValue();
}
/**
* Returns whether this style is strikethrough. May return null.
*
* @return whether the style is strikethrough, or null if not set
*/
public Boolean isStrikethroughRaw()
{
return strikethrough;
}
/**
* Returns whether this style is obfuscated.
*
* @return whether the style is obfuscated
*/
public boolean isObfuscated()
{
return ( obfuscated != null ) && obfuscated.booleanValue();
}
/**
* Returns whether this style is obfuscated. May return null.
*
* @return whether the style is obfuscated, or null if not set
*/
public Boolean isObfuscatedRaw()
{
return obfuscated;
}
/**
* Returns whether this style has no formatting explicitly set.
*
* @return true if no value is set, false if at least one is set
*/
public boolean isEmpty()
{
return color == null && shadowColor == null && font == null && bold == null
&& italic == null && underlined == null
&& strikethrough == null && obfuscated == null;
}
@Override
public ComponentStyle clone()
{
return new ComponentStyle( color, shadowColor, font, bold, italic, underlined, strikethrough, obfuscated );
}
/**
* Get a new {@link ComponentStyleBuilder}.
*
* @return the builder
*/
public static ComponentStyleBuilder builder()
{
return new ComponentStyleBuilder();
}
/**
* Get a new {@link ComponentStyleBuilder} with values initialized to the
* style values of the supplied {@link ComponentStyle}.
*
* @param other the component style whose values to copy into the builder
* @return the builder
*/
public static ComponentStyleBuilder builder(ComponentStyle other)
{
return new ComponentStyleBuilder()
.color( other.color )
.shadowColor( other.shadowColor )
.font( other.font )
.bold( other.bold )
.italic( other.italic )
.underlined( other.underlined )
.strikethrough( other.strikethrough )
.obfuscated( other.obfuscated );
}
}

View File

@ -0,0 +1,140 @@
package net.md_5.bungee.api.chat;
import java.awt.Color;
import net.md_5.bungee.api.ChatColor;
/**
* <p>
* ComponentStyleBuilder simplifies creating component styles by allowing the
* use of a chainable builder.
* </p>
* <pre>
* ComponentStyle style = ComponentStyle.builder()
* .color(ChatColor.RED)
* .font("custom:font")
* .bold(true).italic(true).create();
*
* BaseComponent component = new ComponentBuilder("Hello world").style(style).create();
* // Or it can be used directly on a component
* TextComponent text = new TextComponent("Hello world");
* text.applyStyle(style);
* </pre>
*
* @see ComponentStyle#builder()
* @see ComponentStyle#builder(ComponentStyle)
*/
public final class ComponentStyleBuilder
{
private ChatColor color;
private Color shadowColor;
private String font;
private Boolean bold, italic, underlined, strikethrough, obfuscated;
/**
* Set the style color.
*
* @param color the color to set, or null to use the default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder color(ChatColor color)
{
this.color = color;
return this;
}
/**
* Set the style shadow color.
*
* @param shadowColor the shadow color to set, or null to use the default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder shadowColor(Color shadowColor)
{
this.shadowColor = shadowColor;
return this;
}
/**
* Set the style font.
*
* @param font the font key to set, or null to use the default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder font(String font)
{
this.font = font;
return this;
}
/**
* Set the style's bold property.
*
* @param bold the bold value to set, or null to use the default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder bold(Boolean bold)
{
this.bold = bold;
return this;
}
/**
* Set the style's italic property.
*
* @param italic the italic value to set, or null to use the default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder italic(Boolean italic)
{
this.italic = italic;
return this;
}
/**
* Set the style's underlined property.
*
* @param underlined the underlined value to set, or null to use the default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder underlined(Boolean underlined)
{
this.underlined = underlined;
return this;
}
/**
* Set the style's strikethrough property.
*
* @param strikethrough the strikethrough value to set, or null to use the
* default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder strikethrough(Boolean strikethrough)
{
this.strikethrough = strikethrough;
return this;
}
/**
* Set the style's obfuscated property.
*
* @param obfuscated the obfuscated value to set, or null to use the default
* @return this ComponentStyleBuilder for chaining
*/
public ComponentStyleBuilder obfuscated(Boolean obfuscated)
{
this.obfuscated = obfuscated;
return this;
}
/**
* Build the {@link ComponentStyle} using the values set in this builder.
*
* @return the created ComponentStyle
*/
public ComponentStyle build()
{
return new ComponentStyle( color, shadowColor, font, bold, italic, underlined, strikethrough, obfuscated );
}
}

View File

@ -0,0 +1,146 @@
package net.md_5.bungee.api.chat;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.api.chat.hover.content.Content;
import net.md_5.bungee.api.chat.hover.content.Entity;
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.chat.ComponentSerializer;
@Getter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
public final class HoverEvent
{
/**
* The action of this event.
*/
private final Action action;
/**
* List of contents to provide for this event.
*/
private final List<Content> contents;
/**
* Returns whether this hover event is prior to 1.16
*/
@Setter
private boolean legacy = false;
/**
* Creates event with an action and a list of contents.
*
* @param action action of this event
* @param contents array of contents, provide at least one
*/
public HoverEvent(Action action, Content... contents)
{
Preconditions.checkArgument( contents.length != 0,
"Must contain at least one content" );
this.action = action;
this.contents = new ArrayList<>();
for ( Content it : contents )
{
addContent( it );
}
}
/**
* Legacy constructor to create hover event.
*
* @param action the action
* @param value the value
* @deprecated {@link #HoverEvent(Action, Content[])}
*/
@Deprecated
public HoverEvent(Action action, BaseComponent[] value)
{
// Old plugins may have somehow hacked BaseComponent[] into
// anything other than SHOW_TEXT action. Ideally continue support.
this.action = action;
this.contents = new ArrayList<>( Collections.singletonList( new Text( value ) ) );
this.legacy = true;
}
@Deprecated
public BaseComponent[] getValue()
{
Content content = contents.get( 0 );
if ( content instanceof Text && ( (Text) content ).getValue() instanceof BaseComponent[] )
{
return (BaseComponent[]) ( (Text) content ).getValue();
}
TextComponent component = new TextComponent( ComponentSerializer.toString( content ) );
return new BaseComponent[]
{
component
};
}
/**
* Adds a content to this hover event.
*
* @param content the content add
* @throws IllegalArgumentException if is a legacy component and already has
* a content
* @throws UnsupportedOperationException if content action does not match
* hover event action
*/
public void addContent(Content content) throws UnsupportedOperationException
{
Preconditions.checkArgument( !legacy || contents.size() == 0,
"Legacy HoverEvent may not have more than one content" );
content.assertAction( action );
contents.add( content );
}
public enum Action
{
SHOW_TEXT,
SHOW_ITEM,
SHOW_ENTITY,
/**
* Removed since 1.12. Advancements instead simply use show_text. The ID
* of an achievement or statistic to display. Example: new
* ComponentText( "achievement.openInventory" )
*/
@Deprecated
SHOW_ACHIEVEMENT,
}
/**
* Gets the appropriate {@link Content} class for an {@link Action} for the
* GSON serialization
*
* @param action the action to get for
* @param array if to return the arrayed class
* @return the class
*/
public static Class<?> getClass(HoverEvent.Action action, boolean array)
{
Preconditions.checkArgument( action != null, "action" );
switch ( action )
{
case SHOW_TEXT:
return ( array ) ? Text[].class : Text.class;
case SHOW_ENTITY:
return ( array ) ? Entity[].class : Entity.class;
case SHOW_ITEM:
return ( array ) ? Item[].class : Item.class;
default:
throw new UnsupportedOperationException( "Action '" + action.name() + " not supported" );
}
}
}

View File

@ -0,0 +1,73 @@
package net.md_5.bungee.api.chat;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* Metadata for use in conjunction with {@link HoverEvent.Action#SHOW_ITEM}
*/
@Builder(builderClassName = "Builder", access = AccessLevel.PRIVATE)
@ToString(of = "nbt")
@EqualsAndHashCode(of = "nbt")
@Setter
public final class ItemTag
{
@Getter
private final String nbt;
/*
TODO
private BaseComponent name;
@Singular("ench")
private List<Enchantment> enchantments;
@Singular("lore")
private List<BaseComponent[]> lore;
private Boolean unbreakable;
@RequiredArgsConstructor
public static class Enchantment
{
private final int level;
private final int id;
}
*/
private ItemTag(String nbt)
{
this.nbt = nbt;
}
public static ItemTag ofNbt(String nbt)
{
return new ItemTag( nbt );
}
public static class Serializer implements JsonSerializer<ItemTag>, JsonDeserializer<ItemTag>
{
@Override
public ItemTag deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException
{
return ItemTag.ofNbt( element.getAsJsonPrimitive().getAsString() );
}
@Override
public JsonElement serialize(ItemTag itemTag, Type type, JsonSerializationContext context)
{
return context.serialize( itemTag.getNbt() );
}
}
}

View File

@ -0,0 +1,66 @@
package net.md_5.bungee.api.chat;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public final class KeybindComponent extends BaseComponent
{
/**
* The keybind identifier to use.
* <br>
* Will be replaced with the actual key the client is using.
*/
private String keybind;
/**
* Creates a keybind component from the original to clone it.
*
* @param original the original for the new keybind component.
*/
public KeybindComponent(KeybindComponent original)
{
super( original );
setKeybind( original.getKeybind() );
}
/**
* Creates a keybind component with the passed internal keybind value.
*
* @param keybind the keybind value
* @see Keybinds
*/
public KeybindComponent(String keybind)
{
setKeybind( keybind );
}
@Override
public KeybindComponent duplicate()
{
return new KeybindComponent( this );
}
@Override
protected void toPlainText(StringBuilder builder)
{
builder.append( getKeybind() );
super.toPlainText( builder );
}
@Override
protected void toLegacyText(StringBuilder builder)
{
addFormat( builder );
builder.append( getKeybind() );
super.toLegacyText( builder );
}
}

View File

@ -0,0 +1,52 @@
package net.md_5.bungee.api.chat;
/**
* All keybind values supported by vanilla Minecraft.
* <br>
* Values may be removed if they are no longer supported.
*
* @see KeybindComponent
*/
public interface Keybinds
{
String JUMP = "key.jump";
String SNEAK = "key.sneak";
String SPRINT = "key.sprint";
String LEFT = "key.left";
String RIGHT = "key.right";
String BACK = "key.back";
String FORWARD = "key.forward";
String ATTACK = "key.attack";
String PICK_ITEM = "key.pickItem";
String USE = "key.use";
String DROP = "key.drop";
String HOTBAR_1 = "key.hotbar.1";
String HOTBAR_2 = "key.hotbar.2";
String HOTBAR_3 = "key.hotbar.3";
String HOTBAR_4 = "key.hotbar.4";
String HOTBAR_5 = "key.hotbar.5";
String HOTBAR_6 = "key.hotbar.6";
String HOTBAR_7 = "key.hotbar.7";
String HOTBAR_8 = "key.hotbar.8";
String HOTBAR_9 = "key.hotbar.9";
String INVENTORY = "key.inventory";
String SWAP_HANDS = "key.swapHands";
String LOAD_TOOLBAR_ACTIVATOR = "key.loadToolbarActivator";
String SAVE_TOOLBAR_ACTIVATOR = "key.saveToolbarActivator";
String PLAYERLIST = "key.playerlist";
String CHAT = "key.chat";
String COMMAND = "key.command";
String SOCIAL_INTERACTIONS = "key.socialInteractions";
String ADVANCEMENTS = "key.advancements";
String SPECTATOR_OUTLINES = "key.spectatorOutlines";
String SCREENSHOT = "key.screenshot";
String SMOOTH_CAMERA = "key.smoothCamera";
String FULLSCREEN = "key.fullscreen";
String TOGGLE_PERSPECTIVE = "key.togglePerspective";
}

View File

@ -0,0 +1,101 @@
package net.md_5.bungee.api.chat;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* This component displays the score based on a player score on the scoreboard.
* <br>
* The <b>name</b> is the name of the player stored on the scoreboard, which may
* be a "fake" player. It can also be a target selector that <b>must</b> resolve
* to 1 target, and may target non-player entities.
* <br>
* With a book, /tellraw, or /title, using the wildcard '*' in the place of a
* name or target selector will cause all players to see their own score in the
* specified objective.
* <br>
* <b>Signs cannot use the '*' wildcard</b>
* <br>
* These values are filled in by the server-side implementation.
* <br>
* As of 1.12.2, a bug ( MC-56373 ) prevents full usage within hover events.
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public final class ScoreComponent extends BaseComponent
{
/**
* The name of the entity whose score should be displayed.
*/
private String name;
/**
* The internal name of the objective the score is attached to.
*/
private String objective;
/**
* The optional value to use instead of the one present in the Scoreboard.
*/
private String value = "";
/**
* Creates a new score component with the specified name and objective.<br>
* If not specifically set, value will default to an empty string;
* signifying that the scoreboard value should take precedence. If not null,
* nor empty, {@code value} will override any value found in the
* scoreboard.<br>
* The value defaults to an empty string.
*
* @param name the name of the entity, or an entity selector, whose score
* should be displayed
* @param objective the internal name of the objective the entity's score is
* attached to
*/
public ScoreComponent(String name, String objective)
{
setName( name );
setObjective( objective );
}
/**
* Creates a score component from the original to clone it.
*
* @param original the original for the new score component
*/
public ScoreComponent(ScoreComponent original)
{
super( original );
setName( original.getName() );
setObjective( original.getObjective() );
setValue( original.getValue() );
}
@Override
public ScoreComponent duplicate()
{
return new ScoreComponent( this );
}
@Override
protected void toPlainText(StringBuilder builder)
{
builder.append( this.value );
super.toPlainText( builder );
}
@Override
protected void toLegacyText(StringBuilder builder)
{
addFormat( builder );
builder.append( this.value );
super.toLegacyText( builder );
}
}

View File

@ -0,0 +1,85 @@
package net.md_5.bungee.api.chat;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* This component processes a target selector into a pre-formatted set of
* discovered names.
* <br>
* Multiple targets may be obtained, and with commas separating each one and a
* final "and" for the last target. The resulting format cannot be overwritten.
* This includes all styling from team prefixes, insertions, click events, and
* hover events.
* <br>
* These values are filled in by the server-side implementation.
* <br>
* As of 1.12.2, a bug ( MC-56373 ) prevents full usage within hover events.
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public final class SelectorComponent extends BaseComponent
{
/**
* An entity target selector (@p, @a, @r, @e, or @s) and, optionally,
* selector arguments (e.g. @e[r=10,type=Creeper]).
*/
private String selector;
/**
* The separator of multiple selected entities.
* <br>
* The default is {@code {"color": "gray", "text": ", "}}.
*/
private BaseComponent separator;
/**
* Creates a selector component from the original to clone it.
*
* @param original the original for the new selector component
*/
public SelectorComponent(SelectorComponent original)
{
super( original );
setSelector( original.getSelector() );
setSeparator( original.getSeparator() );
}
/**
* Creates a selector component from the selector
*
* @param selector the selector as a String
*/
public SelectorComponent(String selector)
{
setSelector( selector );
}
@Override
public SelectorComponent duplicate()
{
return new SelectorComponent( this );
}
@Override
protected void toPlainText(StringBuilder builder)
{
builder.append( this.selector );
super.toPlainText( builder );
}
@Override
protected void toLegacyText(StringBuilder builder)
{
addFormat( builder );
builder.append( this.selector );
super.toLegacyText( builder );
}
}

View File

@ -0,0 +1,302 @@
package net.md_5.bungee.api.chat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import net.md_5.bungee.api.ChatColor;
@Getter
@Setter
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public final class TextComponent extends BaseComponent
{
private static final Pattern url = Pattern.compile( "^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$" );
/**
* Converts the old formatting system that used
* {@link net.md_5.bungee.api.ChatColor#COLOR_CHAR} into the new json based
* system.
*
* @param message the text to convert
* @return the components needed to print the message to the client
*/
public static BaseComponent fromLegacy(String message)
{
return fromLegacy( message, ChatColor.WHITE );
}
/**
* Converts the old formatting system that used
* {@link net.md_5.bungee.api.ChatColor#COLOR_CHAR} into the new json based
* system.
*
* @param message the text to convert
* @param defaultColor color to use when no formatting is to be applied
* (i.e. after ChatColor.RESET).
* @return the components needed to print the message to the client
*/
public static BaseComponent fromLegacy(String message, ChatColor defaultColor)
{
ComponentBuilder componentBuilder = new ComponentBuilder();
populateComponentStructure( message, defaultColor, componentBuilder::append );
return componentBuilder.build();
}
/**
* Converts the old formatting system that used
* {@link net.md_5.bungee.api.ChatColor#COLOR_CHAR} into the new json based
* system.
*
* @param message the text to convert
* @return the components needed to print the message to the client
* @deprecated {@link #fromLegacy(String)} 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.
*/
@Deprecated
public static BaseComponent[] fromLegacyText(String message)
{
return fromLegacyText( message, ChatColor.WHITE );
}
/**
* Converts the old formatting system that used
* {@link net.md_5.bungee.api.ChatColor#COLOR_CHAR} into the new json based
* system.
*
* @param message the text to convert
* @param defaultColor color to use when no formatting is to be applied
* (i.e. after ChatColor.RESET).
* @return the components needed to print the message to the client
* @deprecated {@link #fromLegacy(String, ChatColor)} 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.
*/
@Deprecated
public static BaseComponent[] fromLegacyText(String message, ChatColor defaultColor)
{
ArrayList<BaseComponent> components = new ArrayList<>();
populateComponentStructure( message, defaultColor, components::add );
return components.toArray( new BaseComponent[ 0 ] );
}
private static void populateComponentStructure(String message, ChatColor defaultColor, Consumer<BaseComponent> appender)
{
StringBuilder builder = new StringBuilder();
TextComponent component = new TextComponent();
Matcher matcher = url.matcher( message );
for ( int i = 0; i < message.length(); i++ )
{
char c = message.charAt( i );
if ( c == ChatColor.COLOR_CHAR )
{
if ( ++i >= message.length() )
{
break;
}
c = message.charAt( i );
if ( c >= 'A' && c <= 'Z' )
{
c += 32;
}
ChatColor format;
if ( c == 'x' && i + 12 < message.length() )
{
StringBuilder hex = new StringBuilder( "#" );
for ( int j = 0; j < 6; j++ )
{
hex.append( message.charAt( i + 2 + ( j * 2 ) ) );
}
try
{
format = ChatColor.of( hex.toString() );
} catch ( IllegalArgumentException ex )
{
format = null;
}
i += 12;
} else
{
format = ChatColor.getByChar( c );
}
if ( format == null )
{
continue;
}
if ( builder.length() > 0 )
{
TextComponent old = component;
component = new TextComponent( old );
old.setText( builder.toString() );
builder = new StringBuilder();
appender.accept( old );
}
if ( format == ChatColor.BOLD )
{
component.setBold( true );
} else if ( format == ChatColor.ITALIC )
{
component.setItalic( true );
} else if ( format == ChatColor.UNDERLINE )
{
component.setUnderlined( true );
} else if ( format == ChatColor.STRIKETHROUGH )
{
component.setStrikethrough( true );
} else if ( format == ChatColor.MAGIC )
{
component.setObfuscated( true );
} else
{
if ( format == ChatColor.RESET )
{
format = defaultColor;
}
component = new TextComponent();
component.setColor( format );
component.setReset( true );
}
continue;
}
int pos = message.indexOf( ' ', i );
if ( pos == -1 )
{
pos = message.length();
}
if ( matcher.region( i, pos ).find() )
{ //Web link handling
if ( builder.length() > 0 )
{
TextComponent old = component;
component = new TextComponent( old );
old.setText( builder.toString() );
builder = new StringBuilder();
appender.accept( old );
}
TextComponent old = component;
component = new TextComponent( old );
String urlString = message.substring( i, pos );
component.setText( urlString );
component.setClickEvent( new ClickEvent( ClickEvent.Action.OPEN_URL,
urlString.startsWith( "http" ) ? urlString : "http://" + urlString ) );
appender.accept( component );
i += pos - i - 1;
component = old;
continue;
}
builder.append( c );
}
component.setText( builder.toString() );
appender.accept( component );
}
/**
* Internal compatibility method to transform an array of components to a
* single component.
*
* @param components array
* @return single component
*/
public static BaseComponent fromArray(BaseComponent... components)
{
if ( components == null )
{
return null;
}
if ( components.length == 1 )
{
return components[0];
}
return new TextComponent( components );
}
/**
* The text of the component that will be displayed to the client
*/
private String text;
/**
* Creates a TextComponent with blank text.
*/
public TextComponent()
{
this.text = "";
}
/**
* Creates a TextComponent with formatting and text from the passed
* component
*
* @param textComponent the component to copy from
*/
public TextComponent(TextComponent textComponent)
{
super( textComponent );
setText( textComponent.getText() );
}
/**
* Creates a TextComponent with blank text and the extras set to the passed
* array
*
* @param extras the extras to set
*/
public TextComponent(BaseComponent... extras)
{
this();
if ( extras.length == 0 )
{
return;
}
setExtra( new ArrayList<BaseComponent>( Arrays.asList( extras ) ) );
}
/**
* Creates a duplicate of this TextComponent.
*
* @return the duplicate of this TextComponent.
*/
@Override
public TextComponent duplicate()
{
return new TextComponent( this );
}
@Override
protected void toPlainText(StringBuilder builder)
{
builder.append( text );
super.toPlainText( builder );
}
@Override
protected void toLegacyText(StringBuilder builder)
{
addFormat( builder );
builder.append( text );
super.toLegacyText( builder );
}
@Override
public String toString()
{
return "TextComponent{text=" + text + ", " + super.toString() + '}';
}
}

View File

@ -0,0 +1,231 @@
package net.md_5.bungee.api.chat;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.chat.TranslationRegistry;
@Getter
@Setter
@ToString
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public final class TranslatableComponent extends BaseComponent
{
private static final Pattern FORMAT = Pattern.compile( "%(?:(\\d+)\\$)?([A-Za-z%]|$)" );
/**
* The key into the Minecraft locale files to use for the translation. The
* text depends on the client's locale setting. The console is always en_US
*/
private String translate;
/**
* The components to substitute into the translation
*/
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.
*
* @param original the original for the new translatable component.
*/
public TranslatableComponent(TranslatableComponent original)
{
super( original );
setTranslate( original.getTranslate() );
setFallback( original.getFallback() );
if ( original.getWith() != null )
{
List<BaseComponent> temp = new ArrayList<>();
for ( BaseComponent baseComponent : original.getWith() )
{
temp.add( baseComponent.duplicate() );
}
setWith( temp );
}
}
/**
* Creates a translatable component with the passed substitutions
*
* @param translate the translation key
* @param with the {@link java.lang.String}s and
* {@link net.md_5.bungee.api.chat.BaseComponent}s to use into the
* translation
* @see #translate
* @see #setWith(java.util.List)
*/
public TranslatableComponent(String translate, Object... with)
{
setTranslate( translate );
if ( with != null && with.length != 0 )
{
List<BaseComponent> temp = new ArrayList<BaseComponent>();
for ( Object w : with )
{
if ( w instanceof BaseComponent )
{
temp.add( (BaseComponent) w );
} else
{
temp.add( new TextComponent( String.valueOf( w ) ) );
}
}
setWith( temp );
}
}
/**
* Creates a translatable component with the passed substitutions
*
* @param translatable the translatable object
* @param with the {@link java.lang.String}s and
* {@link net.md_5.bungee.api.chat.BaseComponent}s to use into the
* translation
* @see #translate
* @see #setWith(java.util.List)
*/
public TranslatableComponent(TranslationProvider translatable, Object... with)
{
this( translatable.getTranslationKey(), with );
}
/**
* Creates a duplicate of this TranslatableComponent.
*
* @return the duplicate of this TranslatableComponent.
*/
@Override
public TranslatableComponent duplicate()
{
return new TranslatableComponent( this );
}
/**
* Sets the translation substitutions to be used in this component. Removes
* any previously set substitutions
*
* @param components the components to substitute
*/
public void setWith(List<BaseComponent> components)
{
for ( BaseComponent component : components )
{
component.parent = this;
}
with = components;
}
/**
* Adds a text substitution to the component. The text will inherit this
* component's formatting
*
* @param text the text to substitute
*/
public void addWith(String text)
{
addWith( new TextComponent( text ) );
}
/**
* Adds a component substitution to the component. The text will inherit
* this component's formatting
*
* @param component the component to substitute
*/
public void addWith(BaseComponent component)
{
if ( with == null )
{
with = new ArrayList<BaseComponent>();
}
component.parent = this;
with.add( component );
}
@Override
protected void toPlainText(StringBuilder builder)
{
convert( builder, false );
super.toPlainText( builder );
}
@Override
protected void toLegacyText(StringBuilder builder)
{
convert( builder, true );
super.toLegacyText( builder );
}
private void convert(StringBuilder builder, boolean applyFormat)
{
String trans = TranslationRegistry.INSTANCE.translate( translate );
if ( trans.equals( translate ) && fallback != null )
{
trans = fallback;
}
Matcher matcher = FORMAT.matcher( trans );
int position = 0;
int i = 0;
while ( matcher.find( position ) )
{
int pos = matcher.start();
if ( pos != position )
{
if ( applyFormat )
{
addFormat( builder );
}
builder.append( trans.substring( position, pos ) );
}
position = matcher.end();
String formatCode = matcher.group( 2 );
switch ( formatCode.charAt( 0 ) )
{
case 's':
case 'd':
String withIndex = matcher.group( 1 );
BaseComponent withComponent = with.get( withIndex != null ? Integer.parseInt( withIndex ) - 1 : i++ );
if ( applyFormat )
{
withComponent.toLegacyText( builder );
} else
{
withComponent.toPlainText( builder );
}
break;
case '%':
if ( applyFormat )
{
addFormat( builder );
}
builder.append( '%' );
break;
}
}
if ( trans.length() != position )
{
if ( applyFormat )
{
addFormat( builder );
}
builder.append( trans.substring( position, trans.length() ) );
}
}
}

View File

@ -0,0 +1,38 @@
package net.md_5.bungee.api.chat;
/**
* An object capable of being translated by the client in a
* {@link TranslatableComponent}.
*/
public interface TranslationProvider
{
/**
* Get the translation key.
*
* @return the translation key
*/
String getTranslationKey();
/**
* Get this translatable object as a {@link TranslatableComponent}.
*
* @return the translatable component
*/
default TranslatableComponent asTranslatableComponent()
{
return asTranslatableComponent( (Object[]) null );
}
/**
* Get this translatable object as a {@link TranslatableComponent}.
*
* @param with the {@link String Strings} and
* {@link BaseComponent BaseComponents} to use in the translation
* @return the translatable component
*/
default TranslatableComponent asTranslatableComponent(Object... with)
{
return new TranslatableComponent( this, with );
}
}

View File

@ -0,0 +1,32 @@
package net.md_5.bungee.api.chat.hover.content;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.chat.HoverEvent;
@ToString
@EqualsAndHashCode
public abstract class Content
{
/**
* Required action for this content type.
*
* @return action
*/
public abstract HoverEvent.Action requiredAction();
/**
* Tests this content against an action
*
* @param input input to test
* @throws UnsupportedOperationException if action incompatible
*/
public void assertAction(HoverEvent.Action input) throws UnsupportedOperationException
{
if ( input != requiredAction() )
{
throw new UnsupportedOperationException( "Action " + input + " not compatible! Expected " + requiredAction() );
}
}
}

View File

@ -0,0 +1,43 @@
package net.md_5.bungee.api.chat.hover.content;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.HoverEvent;
@Data
@AllArgsConstructor
@ToString
@EqualsAndHashCode(callSuper = true)
public class Entity extends Content
{
/**
* Namespaced entity ID.
*
* Will use 'minecraft:pig' if null.
*/
private String type;
/**
* Entity UUID in hyphenated hexadecimal format.
*
* Should be valid UUID. TODO : validate?
*/
@NonNull
private String id;
/**
* Name to display as the entity.
*
* This is optional and will be hidden if null.
*/
private BaseComponent name;
@Override
public HoverEvent.Action requiredAction()
{
return HoverEvent.Action.SHOW_ENTITY;
}
}

Some files were not shown because too many files have changed in this diff Show More