Compare commits

...

597 Commits

Author SHA1 Message Date
YHDiamond fb283fcce8
Add advancements GUI (#1579)
Using /geyser advancements, Bedrock clients can get a visual on their progress.

Co-authored-by: yehudahrrs <47502993+yehudahrrs@users.noreply.github.com>
Co-authored-by: Olivia <chew@chew.pw>
Co-authored-by: rtm516 <rtm516@users.noreply.github.com>
Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
Co-authored-by: rtm516 <ryantmilner@hotmail.co.uk>
Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com>
2021-01-11 21:23:09 -05:00
rtm516 1c0cc4622a
Microsoft account authentication (#1808)
Microsoft accounts can now use Geyser, while maintaining full backwards compatibility with Mojang accounts.

Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com>
2021-01-11 15:52:02 -05:00
Camotoy 6aa74a2322
Allow server pong to appear if MOTDs are too long (#1445)
* Prevent server pong from appearing if MOTDs are too long

If the server MOTDs are 340 characters or longer, they will not appear. If this is the case, we trim each.

* Implement a more exact fix
2021-01-11 15:37:37 -05:00
Camotoy 2cc8726c12
Shade in the entire net.kyori package (#1826) 2021-01-11 14:11:21 -05:00
Camotoy 999fa7298a
Clarify proxy protocol config message (#1824) 2021-01-10 20:01:04 -05:00
Camotoy d6461e71fb
Add message if Geyser thinks the English locale is missing (#1825) 2021-01-10 20:00:48 -05:00
David Choo 9232c5565f
Add Ender Dragon effects and sounds (#1781)
* Add Ender Dragon effects and sounds

* Add proper death effect and clean up

* Add Ender Dragon respawn sound

* Possibly fix dragon breath direction?

* Update mappings

* Fix death animation triggering at low health

* Trigger death event when health is 0 and add explosions back

* Add comment
2021-01-09 20:43:03 -05:00
Camotoy ade4c14911
Block breaking refactors (#1336)
Client-side block animations and reach checks are now added.

This commit also includes cleanup in BlockChangeTranslator as well as proper Netherite tool support for calculating block breaking.

Co-authored-by: rtm516 <rtm516@users.noreply.github.com>
2021-01-07 22:43:36 -05:00
Camotoy fe23c79053
Implement book editing (#1117)
* Implement book editing

Updates the PR created by @ForceUpdate1 for 1.16 support. Seems to work fine now that hand support is in MCProtocolLib.

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>

* Remove debug line

* Simplify code

Currently still borked for creative mode.

* Fix books on creative

* Bug fixes

* Fix NPE?

* Blind fixes

* Send Book update before any player actions

* Remove debug prints

* Fix out of bounds for page replace and add

* Fix editing desync and remove empty pages from the end

* Send edit packet after signing

* Refactor

* Clean up and fix creative

* Apply suggestions from code review

Co-authored-by: rtm516 <rtm516@users.noreply.github.com>

Co-authored-by: ForceUpdate1 <mneuhaus44@gmail.com>
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
Co-authored-by: David Choo <davchoo3@gmail.com>
Co-authored-by: rtm516 <rtm516@users.noreply.github.com>
2021-01-07 19:40:34 -05:00
Camotoy 7cefb5713e
Clarify that enabling Xbox achievements blocks all commands (#1810) 2021-01-07 16:50:57 -05:00
SupremeMortal dc46905e50
Use Artifactory Jenkins plugin for deployment (#1818)
* Use artifactory jenkins plugin

* Bump version to 1.2.0-SNAPSHOT
2021-01-07 19:51:40 +00:00
rtm516 bbbb7034f6
Trigger builds of Geyser-Fabric and GeyserAndroid after a build success (#1815)
* Trigger builds of Geyser-Fabric and GeyserAndroid after a build success

* Enable GeyserAndroid and fix paths

* Only build for master

* Disable propagation of build results

* Don't wait for sequential builds
2021-01-07 12:21:35 +00:00
Camotoy 92c86cf15b
Null check tick thread (#1812) 2021-01-05 23:28:31 -05:00
Camotoy 0641800be7
Add Tickable interface (#1790)
* Add Tickable interface

By having a tickable interface, we're only dedicating one thread to ticking entities and running tasks as opposed to several. This will also help with implementing world border support.

* removeEntity already clears tickableEntities for us

* Only tick the entity if it's not being ticked
2021-01-05 18:41:20 -05:00
AJ Ferguson b6389317f0
Fix minor bug in auth form (#1806) 2021-01-05 13:45:01 -05:00
Nickg two 29e47cf636
[ci skip] changed a 2020 to 2021 (#1801)
lol imagine being in 2020
2021-01-04 21:24:07 -05:00
Camotoy 69dc4a9644
[ci-skip] Improve README for better information (#1702) 2021-01-04 15:54:52 -05:00
D3ATHBRINGER13 446f16bc33
Update LICENSE to 2021 (#1799) 2021-01-04 14:14:55 -05:00
Camotoy 50b80a64d3
Dimension switching cleanup (#1694)
* Dimension switching cleanup

Cleans up dimension switching logic that should no longer be needed. Also fixes above Nether Bedrock building dimension switching.

* Clear thunder on dimension switch too

* Clarify fake dimension switch function name

* Javadoc that
2021-01-03 19:06:20 -05:00
Kooldude183 3f7d669676
Update README.md (#1774)
* Update README.md

Add v1.16.201 in list of supported Bedrock versions

* Update README.md

Change to `v1.16.100 - v1.16.201`
2021-01-03 12:54:07 -05:00
Camotoy 1c7567d79d
Various resource pack fixes (#1769)
- Fixes an instance where an invalid pack_manifest file could be present
- Fixes instances where JSON files were not read as UTF-8
2021-01-03 12:53:26 -05:00
YHDiamond 1a08e1104d
Fix stopsound bug (#1771)
* Fix stopsound not working bug

* removed extra imports

* Update JavaPlayerStopSoundTranslator.java

* Update JavaPlayerStopSoundTranslator.java

* Update JavaPlayerStopSoundTranslator.java

* Fix packet names and fix specific sounds not stopping

Co-authored-by: YHDiamond <47502993+yehudahrrs@users.noreply.github.com>
Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com>
2021-01-02 18:51:41 -05:00
Camotoy 396d1b6b61
Fix items on campfires (#1779) 2021-01-01 18:33:21 -05:00
Camotoy eccb48844e
Allow enderman to make provoked sound when angry (#1763) 2021-01-01 16:55:04 -05:00
Camotoy 186d94917a
Update copyright to 2021 (#1772)
* Update copyright to 2021

Free commit!

* These don't need a copyright

* Don't downgrade the mappings
2021-01-01 10:10:36 -05:00
Camotoy 77153e6d4a
Work around there being a void floor in Bedrock (#1405)
* Work around there being a void floor in Bedrock

If the player's Y coordinate is -38 or below, we teleport the player below the void floor and they can safely die. :)

* Don't teleport if below Y -40

* sigh

* Have floorY be its own variable

* Add more comment

* More comments

* Finish my thought
2020-12-31 20:05:00 -05:00
Camotoy a17f2203a8
Fix oddities in chunk sections with older Spigot versions (#1758) 2020-12-29 21:49:36 -05:00
AJ Ferguson e3b94bc859
Thrown potion entity color (#1756)
* Fix thrown potion color

* Prevent area effect cloud from appearing to catch on fire

* Don't set ENCHANTED flag on all potions
2020-12-29 18:58:02 -05:00
David Choo fe63a7f7ab
Fix pick block (#1753)
* Use pick_item mappings

* Update mappings

* Update mappings and fix wording
2020-12-29 18:09:42 -05:00
Camotoy d1c571d710
Fix anvil renaming (#1744)
Turns out it *was* our fault. Oops.
2020-12-26 19:51:11 -05:00
Tim203 77de991bcf
Change Jenkins url and name to Open Collaboration (#1732) 2020-12-26 21:40:49 +01:00
Camotoy eb5e4d79bb
Add visual damage support with thorns (#1728) 2020-12-26 15:39:46 -05:00
Camotoy 9fc6228fc0
GeyserSession: remove 32 render distance cap (#1546)
Having an incongruency between the server render distance and the client render distance appears to cause issues, and I have not been able to encounter such a crash.
2020-12-24 13:40:57 -05:00
Mark eca626aad6
Add missing netty-codec-haproxy dependency (#1731) 2020-12-24 00:31:23 -05:00
Mark c67d91943c
HAProxy PROXY protocol support for downstream connections (#1688)
* Implement downstream PROXY protocol support

* Clarify the configuration version updating procedure

* Bump netty-resolver-dns to 4.1.56.Final

* Update Netty to .56

* Don't increase jar size by 2MB

Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com>
2020-12-23 20:47:29 -05:00
Camotoy dbfdae63f1
Add precautions to prevent stack traces on incomplete/unknown place sounds (#1717) 2020-12-20 20:42:14 -05:00
Camotoy f5c0c549ef
Improve doDaylightCycle translation (#1711)
Previously, we wouldn't send the time if the server was sending the same time with doDaylightCycle on. However, this isn't vanilla behavior (for Bedrock nor Java) and can occasionally cause irregularities. The time is now always sent to Bedrock clients, and a daylightCycle field is added to GeyserSession to keep track of the doDaylightCycle gamerule we need to send to Bedrock. Removing the map we used to store the time may also improve memory usage since this was never cleaned up.
2020-12-20 20:41:28 -05:00
Camotoy b490dcfcbb
Improve doDaylightCycle translation (#1711)
Previously, we wouldn't send the time if the server was sending the same time with doDaylightCycle on. However, this isn't vanilla behavior (for Bedrock nor Java) and can occasionally cause irregularities. The time is now always sent to Bedrock clients, and a daylightCycle field is added to GeyserSession to keep track of the doDaylightCycle gamerule we need to send to Bedrock. Removing the map we used to store the time may also improve memory usage since this was never cleaned up.
2020-12-20 20:41:07 -05:00
Camotoy d69896b381
Fix NPE when no item can be found from a block (#1718)
This commit also removes an old map previously used for block entity translators
2020-12-20 20:40:21 -05:00
Camotoy c92150013f
Allow /help to work even if command suggestions are disabled (#1703)
* Allow /help to work even if command suggestions are disabled

This sends a minimal available commands packet to permit /help sending to the server.

* Fix whitespace

* Just send an empty packet

* Change variable name
2020-12-17 14:10:58 -05:00
rtm516 ce9cd92b2e
Update GeyserConnector.java to fix JavaDoc (#1701) 2020-12-17 17:25:38 +00:00
qlow 9f6182f8df
Added a simple way to get a player by their xuid (#1642)
* Added IGeyserPingPassthrough#getPingInformation(InetSocketAddress) to make logging of the pinging IPs possible

* Added GeyserConnector#getPlayerByXboxUuid

* Added GeyserConnector#getPlayerByUuid and added some javadocs

* Update connector/src/main/java/org/geysermc/connector/GeyserConnector.java

Co-authored-by: rtm516 <rtm516@users.noreply.github.com>

* Update connector/src/main/java/org/geysermc/connector/GeyserConnector.java

Co-authored-by: rtm516 <rtm516@users.noreply.github.com>

* Update GeyserConnector.java

* Update SkinManager.java

* Update SkinProvider.java

* Renamed getPlayerByXboxUuid to getPlayerByXuid

Co-authored-by: qlow <info@qlow.eu>
Co-authored-by: rtm516 <rtm516@users.noreply.github.com>
2020-12-17 11:58:49 -05:00
Kooldude183 02d99380d3
Add info about clickable links in "What can't be fixed" (#1687)
* Add info about clickable links in "What can't be fixed"

* Add "Glowing effect"
2020-12-17 11:58:25 -05:00
Camotoy 82179797ab
Add proper ominous banner translation (#1692)
The ominous banner is a separate banner type in Bedrock. If we detect the ominous banner pattern, then we set the ominous banner type in NBT. This process is also checked vice-versa, allowing the ominous banner to be pulled from the Bedrock creative menu.
2020-12-16 12:50:16 -05:00
Camotoy 988fd66a85
Fix boat movement on land (#1668)
* Fix boat movement on land

1.16.100 appears to now take advantage of two newer entity metadata properties, IS_BUOYANT and BUOYANCY_DATA. Without the former, moving on land will not work properly. With the former and without the latter, moving in water no longer works.

* Use offset kind of
2020-12-15 13:09:40 -05:00
Camotoy aed1eef6e1
Update Adventure and fix some legacy hover events (#1681) 2020-12-15 11:24:02 -05:00
Camotoy 55cf7d1c54
Fix more scoreboard crashing and oddities (#1665)
* Various fixes

* Apply updateType fix as well

* Slight optimization
2020-12-14 18:22:31 -05:00
EasyClifton feaaf9edec
Add What can't be fixed and info about player heads (#1680)
* Add What can't be fixed and info about player heads

* Update README.md
2020-12-14 18:22:18 -05:00
Camotoy 8b5ef7478c
Fix PS4 behavior with NetworkStackLatencyTranslator (#1678) 2020-12-14 15:47:17 -05:00
Camotoy 799f6341c8
Fix Netty dependency usage on Velocity (#1672) 2020-12-13 23:03:11 -05:00
RednedEpic 41cb593dc4 Update langauges submodule 2020-12-12 01:48:12 -06:00
RednedEpic 655e218115 Add settings command for settings menu as it broke in the settings screen in 1.16.100 2020-12-12 01:45:54 -06:00
RednedEpic 31209be79e Ensure spawn radius is always 0 on the client's end
Fixes #1496 to the best of my knowledge. Any issue regarding the spawnpoint being off in terms of radius is up to the server at this point - would not be an us situation here.
2020-12-12 01:23:30 -06:00
jackson-57 50662bc65c
Update todo list in README.md (#1656) 2020-12-12 00:46:29 -06:00
RednedEpic 70031c65e7 Handle keepalives better (Closes #965)
Bedrock cuts off the last 3 digits consistently every time, meaning that the keepalive returned from bedrock is never fully accurate. However, if we multiply the value by 1000, then divide by 1000 when sending back to java, the proper value is returned.
2020-12-12 00:45:41 -06:00
RednedEpic a60ab4e80e Fix colored particles (Closes #1627) 2020-12-11 17:15:49 -06:00
RednedEpic 047bf5f0f4 Fix armor stand rotation (Closes #1634) 2020-12-11 17:06:33 -06:00
Camotoy f19922ecf0
EnderCrystalEntity: don't appear to be on fire if fire is below (#1651) 2020-12-11 12:55:37 -05:00
Camotoy bb21d05459
Update README to show all supported versions (#1647) 2020-12-11 12:55:19 -05:00
Kooldude183 39a11da7e5
Fix resource pack description in config (#1649) 2020-12-10 22:13:54 +00:00
Camotoy 87c52ad524
Add a config option for toggling showing coordinates (#1645) 2020-12-10 11:13:36 -05:00
rtm516 91cdda95db
Change version in query to use a more informative string (#1635)
* Change version in query to use a more informative string

* Fix removal of string

* Cleaner implementation of version

* Fix build

* Make more explicit what we're replacing

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-12-09 15:14:12 -05:00
rosiecube 2a44874458
Fix Bedrock ItemEntity Y position bug (#1636)
Setting motion while on the ground causes visual issues. Additionally, there is an offset difference in the movement of an item entity.
2020-12-09 15:09:14 -05:00
Camotoy 8e274daa75
Change default protocol version to 422 (#1640)
* Change default protocol version to 422

* Update Protocol

* Actually update to Protocol 2.6.1-SNAPSHOT

* Keep languages commit the same
2020-12-09 11:30:59 -05:00
D3ATHBRINGER13 3bcdf4cca1
Add map and banner cloning and map extending (#1623)
* Add all the crafting multi uuids

* Remove BANNER_ADD_PATTERN

* Remove TODO
2020-12-07 14:27:42 -05:00
qlow a173005767
Added IGeyserPingPassthrough#getPingInformation(InetSocketAddress) to make logging of the pinging IPs possible (#1633)
Co-authored-by: qlow <info@qlow.eu>
2020-12-07 14:04:50 -05:00
Camotoy 798ae34cd1
WolfEntity: fix entire wolf being set to a color in rare instances (#1630) 2020-12-06 14:46:31 -05:00
Camotoy 2f294c9466
Fix player heads with a custom name (#1625) 2020-12-04 17:48:33 -05:00
OnlyBMan 2c0f3ec84d
Custom skull block support (#683)
Custom skulls are now implemented within the world when placed as a block. This is achieved by placing a fake player entity in the same spot.

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
Co-authored-by: bundabrg <brendan@grieve.com.au>
Co-authored-by: bundabrg <bundabrg@grieve.com.au>
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-12-04 16:55:24 -05:00
rtm516 2067143b57
Fix supported version display name (#1593)
* Fix supported version display name

* Update connector/src/main/java/org/geysermc/connector/network/BedrockProtocol.java
2020-12-03 19:21:32 -05:00
D3ATHBRINGER13 b92d8d53e9
Bump languages submodule (#1619) 2020-12-03 18:20:39 +00:00
Camotoy f6a26410da
Supply a unique network ID for each recipe (#1615)
This fixes crashes in the Minecraft betas.
2020-12-02 15:39:24 -05:00
Bastian Oppermann 24fd7dafc5
Do not send server custom chart for Metrics (#1610)
The server chart is automatically populated by the bStats backend.
2020-12-01 11:40:07 +00:00
Camotoy ffd0c211fc
Fix villagers accepting books (#1605)
* Hopefully fix villagers accepting books

Fixes a couple of inconsistencies getting books from the creative menu.

* Fix fake news
2020-11-30 10:55:35 -05:00
rtm516 eb687e6638
Add check to fix NONE team color causing an NPE (#1602) 2020-11-28 15:10:19 +00:00
Camotoy 0215c383b0
GUI: Don't exit if there is a config error (#1600)
Leave the window open so the user understands there is an error.

This also changes the exit code to 1 when exiting without a GUI since we have an error.
2020-11-27 18:55:33 -05:00
rtm516 da2dc69441
Update MCProtocolLib to Adventure migration (#1572)
* Use raw message data instead of converting the message

* Update MCProtocolLib to Adventure

* Ignore MCProtocolLib Adventure depend

* Remove unused dependency

* Fix isMessage handling `null` wrong.

* Update to adventure 4.2.0

* Clean-up isMessage

* Fix tests

* Clean-up of catch statements
2020-11-27 18:28:08 -05:00
Camotoy 11d9d30050
Fix mounts being unmountable with cache chunks (#1576)
Teleports need to be confirmed before riding
2020-11-27 17:56:32 -05:00
Carbuino 894275b8c4
Update UpstreamPacketHandler.java (#1570)
Changed the logging in message to display in the Action Bar instead of spamming the chat.
2020-11-24 11:14:02 -05:00
RednedEpic 896638ed84 Add support for latest beta (1.16.200.56) 2020-11-24 00:47:57 -06:00
rtm516 e412ba0993
Clear the Reflections scanners to stop it trying to scan (#1582) 2020-11-23 01:08:59 +00:00
rtm516 881e7a051c
Another android fix (#1575)
* Fix en_us hash reading on Android (again)

* Fix hash generation methods for Android
2020-11-22 10:40:53 +00:00
rtm516 9ed3197191
Fix en_us downloading and hashing on Android (#1574) 2020-11-22 01:59:57 +00:00
rtm516 0268ef7d2b
Clean-up translation string implementation (#1567) 2020-11-21 00:44:33 +00:00
Camotoy 67d5993ae1
LivingEntity: add visual support for riptide spin attack (#1551) 2020-11-20 18:06:27 -05:00
circuit10 a70d3e2150
Fix inconsistencies with movement and position (#699)
Movement is now significant better, especially on slabs, stairs, and other half-blocks.

Co-authored-by: RednedEpic <redned235@gmail.com>
Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
Co-authored-by: Tim203 <mctim203@gmail.com>
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-11-20 14:56:39 -05:00
rtm516 4297215420
More chat fixes (#1557)
* Fix positional translation arguments not being handled

* Fix locale fallback

* Fix command completion

* Remove the expensive call to `containsKey`

* Unify adventure versions

* Fix some more formatting issues due to parity

* Fix and update tests

* Update adventure

* Add Javadoc for getCommandNames

* Formatting

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-11-18 23:18:36 +00:00
Camotoy 199778faea
Fix regressions from 1.16.100 (#1558)
* Fix regressions from 1.16.100

- Update mappings to fix recipe regressions and item differences
- Villager trading NBT now prefers the String identifier and not the integer ID

* Fix lodestone compass breaking
2020-11-18 01:10:49 -05:00
Camotoy 99558b61a6
Print reason for disconnect when outdated (#1556) 2020-11-17 13:28:08 -05:00
Camotoy 003a1bef03
Revert artifactory changes preventing compilation (#1555) 2020-11-17 12:54:09 -05:00
Camotoy 123b074cc7
Update to Bedrock 1.16.100 (#1552)
* Initial work on 1.16.100 - currently crashes the client

* Update runtime item states

* Use new Bedrock runtime IDs

Bedrock now hardcodes block runtime IDs in alphabetical order of the identifiers. This commit updates Geyser to accomodate.

- Remove runtime_block_states.dat and replace it with blockpalette.nbt
- Calculate the block runtime ID based on the order of the block palette
- Separate BlockTranslator.AIR into Bedrock and Java values
- Update the second layer of chunks to use air when not waterlogged
- Don't send item palette for now, as that's what crashes the game (will look into for v415)
- Other misc. changes

* Improve second layer chunk translation

* v415 support

- Add a message warning people they are on a beta version of Geyser

* Update to protocol v417

There are still some mappings changes that need to be gone through.

* Update runtime item states and clean up item frames

* Future-proof enchanment table

* Update for v418

* Update to v419

* Apply proper air ID to waterlogged chunk layer

* Fix missing import

* Remove beta warning

* Update mappings

* Manually patch runtime_item_states and send the ITEMS registry

* Update README

* Disable grindstone and smithing inventories (since they're broken)

* Use artifactory jenkins plugin (#1548)

* Use artifactory jenkins plugin

* Bump version to 1.2.0-SNAPSHOT

Co-authored-by: SupremeMortal <6178101+SupremeMortal@users.noreply.github.com>
2020-11-17 11:03:12 -06:00
rtm516 512f8cd6c2
Rewrite message handling in MessageUtils to use Adventure (#1498)
* Rewrite message handling in MessageUtils to use Adventure

* Move to static Adventure commit to fix a bug

* Initial test implementation

* Add RGB downgrade test

* Move MessageUtils and rename

* Clean-up and fix tests

* Fixed sign and book content handling

* Fix blank signs causing NPEs

* Fix reset before message being stripped

* Add comment about the reset character

* Fix legacy style server motds

* Fix more messages being handled wrong

* Fix title packets being handled wrong

* Fix trailing formatting characters on the end of sign lines

* Add auto updating of Java locale files

* Add en_us locale updating and hash caching

* Changes to hash determining

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-11-16 23:57:57 +00:00
Camotoy 47f25f1205
BannerTranslator: fix NPE when no block entity data (#1543) 2020-11-15 18:48:11 -05:00
RednedEpic 981ac3bf11 Move PlatformType to common module 2020-11-14 17:49:56 -06:00
Camotoy 445444204f
Fix GlobalPalette translation (#1528)
* Fix GlobalPalette translation

Global palettes don't have their own internal palette, which cannot be iterated through to create a Bedrock palette. Therefore we simply iterate over the whole palette one time. This commit also fixes a regression with flowers/pistons being on multiple chunk sections.

* Don't declare bedrockPalette until after global palette check
2020-11-14 12:05:33 -06:00
Niklas bf05f64fac
Update LabyMod cape url (#1540) 2020-11-14 11:52:10 -06:00
Camotoy 80cf407fae
Update MCProtocolLib to fix more custom recipe stuff (#1534) 2020-11-13 23:00:09 -05:00
Camotoy e748240a02
Add more interactive tags (mobile buttons) (#1443)
* Add more interactive tags (mobile buttons)

This expands our support for showing the interactive tags on touchscreen and console setups. This is not complete - specifically, the food compatibility of creatures needs to be expanded upon (I will work on this later and does not stop this PR from being mergable). This also includes:

- Creepers who are ignited with flint and steel now show up properly
- Zombie villagers now shake properly when converting and show their region outfits

* Add more food choices and add more panda entity metadata

* Re-add eating flag

* Remove debug line

* Refactor dimension usage, finish interactive tag usage, bees

* Print statements... ._.

* Don't make eating item packet data a non-constant

* Move BAMBOO to ItemRegistry

* Add missing break

* Make changes

* Minor final changes
2020-11-11 19:28:45 -05:00
rtm516 3676dd185f
Fix even more entity metadata flags (#1483)
* Fix even more entity metadata flags

* Add comment explaining magic value

* Fix horse flags and add more information

* Add more information about the Horse eating particles
2020-11-11 18:13:13 +00:00
David Choo 4237503d6d
Fix laying crash (#1510)
* Fix crash with GSit lay and use Java bed position data

* Fix GSit's lay position

* Move Bed Position metadata to the right class

* Actually fix lay for PosePlugin

* Revert "Actually fix lay for PosePlugin"

This reverts commit 3f21261162.

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-11-10 12:05:16 -05:00
Camotoy 109922f796
Update MCProtocolLib to fix datapacks that send empty result recipes (#1522)
Example: https://www.planetminecraft.com/data-pack/true-survival-a-hardcore-minecraft-experience/
2020-11-09 14:26:29 -05:00
Tim203 e00715ceab
Fixed some issues related to Scoreboards (#1446)
* Fixes some issues related to Scoreboard Teams

* The cached Score info should update no matter what kind of update the Team got.
* Team entities specified at the create Team packet should also be checked if they exist as Score in the registered Objectives

* Rewrote some Scoreboard code and fixed various issues

* Minor formatting changes
2020-11-09 10:34:27 +01:00
rtm516 2d95302b10
Add support for passing config options as arguments (#1506) 2020-11-07 13:17:17 -06:00
rtm516 c7654ff98c
Disable the sponsor button (#1509) 2020-11-07 18:47:45 +00:00
rtm516 a6cc28ee80
Add config option for enabling achievements (#1504)
* Add config option for enabling achievements

* Disabled achievements by default and added warning about commands being disabled

* Update config.yml

* Rename achievements-enabled to xbox-achievements-enabled for clarity

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-11-07 00:52:09 +00:00
Camotoy 0e15aa7441
Fireball and ghast improvements (#1469)
* Fireball and ghast improvements

- Ghasts now visually show if they're charging a fireball
- Fireballs are now vastly better and will update better

* Add gravity and drag to projectiles

* Add check for session close and improve fireball

* Remove motion stuff from fireball

* Make fireball hittable

* Add wither skull entity

* Small changes

* Add note about laggy fireballs

Co-authored-by: David Choo <davchoo3@gmail.com>
2020-11-05 18:42:33 -05:00
Tim203 c64d57439f
Block entity performance improvements (#1481)
* BlockEntity performance improvements

* Use chunk cache if possible for block caching

* Get new block state from ViaVersion if block entity

* Add Javadoc for FlowerPotBlockEntityTranslator.isFlowerBlock

* Remove debug line

* Don't add all RequiresBlockState instances if cache chunks is enabled

* Double chest map get optimization

* Last changes

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-11-05 22:36:22 +01:00
Camotoy 434a2e1500
Fix bell sound and visuals (#1502)
* Fix bell sound and visuals

The bell sound now correctly plays.

Bells will also visually ring when rung by another player.

* Compress elses

* Add more whitespace to new code
2020-11-05 14:59:01 -05:00
David Choo ce64dd2788
Fix sitting with armor stand and animal mount offsets (#1492)
* Fix sitting with armor stand and animal offsets

* Fix riding players

* Moved @Getter
2020-11-04 20:30:55 -05:00
Matthias Neid ea521078e1
Update supported version in README to 1.16.4 (#1488) 2020-11-02 16:44:45 -05:00
Camotoy 69d4d9f0d6
Send position update every 3 seconds if idle (#1421)
* Send position update every 3 seconds if idle

Prevents timeouts in certain instances when AFK.

* Cancel position sending on dimension switching

* Remove debug lines

* Create function to centralize movement translation
2020-11-02 16:04:08 -05:00
Camotoy 3e0d898b6a
Update to 1.16.4 (#1487)
* 1.16.4-pre1 support

* Update to support ViaVersion 3.2.0 (#1358)

* Update to support ViaVersion 3.2.0

This commit updates ViaVersion integration to support their recent mappings changes. 

Co-authored-by: Nassim <jahnke.nassim@gmail.com>

* Send adventure settings on gamemode change after gamemode swap

* Update Velocity to 1.1.0 proper

* Update to 1.16.4

Co-authored-by: Nassim <jahnke.nassim@gmail.com>
2020-11-02 13:28:31 -06:00
Camotoy ca1f87d464
MapItemTranslator: support map tag being of short value (#1475)
GSigns sends this as a short. Who knows why.
2020-10-31 22:38:56 -04:00
Camotoy e0f5deb329
Add support for more recipes (#1434)
* Add support for more recipes

- Tool repairing
- Book cloning
- Suspicious stew
- Tipped arrows

What still needs to be done:

- Map cloning/extending (though there may be item mapping mismatch getting in the way)
- Banner duplication (couldn't figure this out)

* Add some more spacing

* Explain recipe UUIDs
2020-10-29 18:40:42 -04:00
David Choo 8fdaf6a385
Ender dragon Melee Attacks (#1466)
* Create and position Ender Dragon Bounding Box

Currently allows the player to "kill aura" target
the ender dragon.

* Use an entity to handle attacks for each hitbox

* Use the proper flag to make entities invisible

* Clean up and add some comments

* Ender dragon entity metadata improvements

* Add doc to segment functions

* Add changes

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-10-29 18:35:46 -04:00
Camotoy 045c0e0637
Introduce CommandSender.getLocale() (#1431)
* Introduce CommandSender.getLocale()

This allows Geyser-specific commands (e.g. `/geyser help`) to be displayed in the (Java or Bedrock) player's default language, which stops those commands from simply being displayed in the default locale.

* Tweak Javadoc

* Set CommandManager's GeyserConnector to final

* Clean up
2020-10-29 18:30:52 -04:00
Camotoy 9b46bf8bc9
BedrockActionTranslator: Fix occasional death stall (#1432)
Usually this happened when joining from another dimension after the player exited to the main menu on the death screen. The player would not realize that they are dead.
2020-10-29 16:44:45 -04:00
Camotoy a2a7e99402
GUI Improvements (#1462)
- Added `GeyserCommand.isExecutableOnConsole()`. If this is set to false, the command will not appear as an option in the GUI.
- Added `GeyserCommand.getSubCommands()`. If not empty, the subcommand options will now appear in the GUI.
2020-10-27 18:40:00 -04:00
SupremeMortal 04f0318bd0 Use new Open Collaboration maven repository 2020-10-27 11:24:18 +00:00
David Choo d93d4d0942
Projectile fixes (#1451)
* Predict the trajectory of projectiles and add particles

* Correct lingering potion gravity

* Update last position on move absolute

* Clean up

* Add egg to ItemRegistry and update mappings
2020-10-26 11:54:37 -04:00
rtm516 c30cb78e74
Add statistics menu (#1424)
* Add statistics menu

* Changed back button text

* Add check to make sure the player requested the statistics display

* Better item translation support; misc changes

* Clean up session getting?

* Remove extra debug that is likely unnecessary

* Remove unused function

* Update languages submodule

* Clean up javadoc comment

* Fix typo

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-10-24 23:33:49 +01:00
RednedEpic dfba278f4d Use correct methods in refreshEmotes 2020-10-23 01:36:34 -05:00
RednedEpic ee8c718c62 Translate emote list packet 2020-10-23 01:25:24 -05:00
rtm516 7f2b2e0913
Bedrock <-> Bedrock skin display fix (#1195)
* Implement partial bedrock skin fix

* Fix equals method

* Fix ViaVersion

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-10-22 23:01:03 -05:00
Redned 62d984da61
Make userAuths information more clear 2020-10-19 20:56:01 -05:00
Camotoy 7f5fac38c6
Update to Adventure 4.1.1 (#1410)
* Update to Adventure 4.0.0

* Update to 4.0.1

* Update again, I guess.
2020-10-19 19:09:16 -04:00
Camotoy b02bc33393
GeyserSession: Set a default value for attackSpeed (#1419)
Fixes cooldowns not showing on a fresh world.
2020-10-19 19:03:31 -04:00
DaPorkchop_ 18e2a52d98
fix decoding sections with duplicate palette entries (#1430) 2020-10-19 09:43:51 +01:00
Camotoy 45429a9357
SettingsUtils: fix 'show coordinates' setting persistence (#1429)
The boolean that toggled this was accidentally in the wrong spot.
2020-10-18 23:29:11 -04:00
DaPorkchop_ 0635605a24
fix chunk section decoding (#1418)
* fix chunk section decoding

* switch back to official MCProtocolLib
2020-10-18 10:59:37 -04:00
David Choo 5c28eaca15
Fix mob mount positions (#1392)
* Fix mob mount positions

Uses offsets from Java Edition.

* Fix Boat mount pos for multiple passengers and Fix Ravager

Remove unnecessary horse metadata

* Fix Minecart & Boat Mount Pos, Fix Player Height Offset

* Use offset of EntityType.PLAYER

* Add back metadata
2020-10-17 23:50:41 -04:00
Camotoy ae70dbeece
JavaOpenWindowTranslator: Use MessageUtils for inventory name (#1416)
* JavaOpenWindowTranslator: Use MessageUtils for inventory name

* Remove important messaging
2020-10-17 23:13:04 -04:00
RednedEpic 64f2233581 Fix wolf collar color when it's no longer angry (Closes #1404) 2020-10-15 01:54:05 -05:00
DaPorkchop_ 7d2745dee6
Faster chunk conversion (#1400)
* BlockStorage is never used concurrently, no need to synchronize

* initial, semi-functional, faster chunk conversion

* faster chunk conversion works well for every situation except spigot

* delete unused ChunkPosition class

* preallocate and pool chunk encoding buffers

* make it work correctly on spigot

* make field naming more consistent

* attempt to upgrade to latest MCProtocolLib

* remove debug code

* compile against my MCProtocolLib fork while i wait for my upstream PR to be accepted

* return to Steveice10 MCProtocolLib
2020-10-15 01:30:25 -05:00
RednedEpic 40de801eb0 Add sound when an arrow hits a player 2020-10-15 01:21:44 -05:00
Tim203 2ca2436cdc
Don't use the general thread pool to run an async method (#1397)
* Don't use the general thread pool for an async method

* Align nested class at the bottom
2020-10-14 23:34:24 -04:00
DaPorkchop_ 73bec588fa
fix some NPEs caused by race conditions in chunk conversion (#1396)
* fix some NPEs caused by race conditions in chunk conversion

tbh the whole session should be read-write locked for every operation

* fix code style issues
2020-10-13 11:11:52 -04:00
DaPorkchop_ 191777773c
Don't use wrapper objects for positions in ChunkCache (#1398)
* make ChunkPosition use a hashCode implementation with far better hash distribution

this should improve the performance when used as a hash table key

* ChunkCache no longer uses position wrapper objects

this yields a roughly 15-20% increase in performance when converting chunk data

* fix code style issues
2020-10-13 15:44:47 +01:00
RednedEpic 9b3cd8f725 Fix area effect clouds 2020-10-12 20:36:11 -05:00
Camotoy 1b00eaca4a
Set AuthType in Metrics to lowercase (#1395) 2020-10-12 21:28:54 -04:00
Luke 3f7120d9da
Add player device OS to metrics (#1391)
* Add player device os to metrics

* Add player version, Geyser version, and default locale

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-10-12 21:17:15 -04:00
Camotoy 96db37c14c
Fix bucket interactions on creative mode (#1369)
* Fix bucket interactions on creative mode

Bedrock uses the BLOCK_INTERACT enum of BedrockActionTranslator to truly indicate if a bucket should be used or not. In order to hook into this, we need to delay the bucket placing by about 5 milliseconds - this gives us time to cancel the interaction if needed.

Bucket sounds will now not play in this case as well.
2020-10-12 20:02:41 -04:00
Camotoy ffcff96bea
Set default values for classes as well (#1387)
Geyser can now start even if the config file is empty. Tested on Spigot and doesn't affect custom values.
2020-10-10 18:08:21 -04:00
Camotoy ec609fa868
Make crossbows prettier (#1359)
- Fix crossbow NBT translation - now crossbows will show as loaded
- Pillagers now more closely resemble Java Edition pose behavior
2020-10-08 20:40:50 -04:00
Camotoy 59f72d0e65
BedrockMobEquipmentTranslator: Don't change item slot if already on that slot (#1353)
* BedrockMobEquipmentTranslator: Don't change item slot if already on that slot

* Update comment
2020-10-09 01:07:50 +01:00
Tim203 45c5ef02cd
Various Scoreboard fixes (#1381)
* Various Scoreboard fixes

Fixes #1328 and a few other potential Scoreboard problems

* Consistent whitespacing

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-10-08 19:30:05 -04:00
Camotoy 4514167835
Fix fire being punched in all directions (#1370)
Apply the fix we have for fire but for all block faces.
2020-10-08 18:44:15 -04:00
Arktisfox 16eb2a491a
Area cloud fixes (#684)
* Fix NotNull error with particles, replace incorrect string meta with int meta.

* Add back newline

* Remove debug line

* Update Protocol and prepare for merge

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-10-08 18:33:36 -04:00
Camotoy 172a5a6db8
Add Fabric as a platform type (#1376)
* PlatformType: Add Fabric as a platform

* Don't use XML reflections on Fabric
2020-10-07 18:51:36 -04:00
Camotoy 90656a9846
Jenkins improvements (#1368)
- Show changes in the Discord webhook
- Delete after 20 builds

Co-authored-by: rtm516 <ryantmilner@hotmail.co.uk>
2020-10-07 18:50:39 -04:00
Camotoy ba6f174058
Add support for fishing rods pulling Bedrock players (#1355)
Fishing rods pulling players is a clientside feature on Java. On Bedrock, a SetEntityMotionPacket is sent to the client. Therefore this PR implements the Java fishing rod pulling mechanics and sends it off to Bedrock, which sends MovePlayerPackets that are sent to the server.
2020-10-02 15:44:46 -04:00
Camotoy 772cb246f0
Forward keep alive packets to the client (#1344)
* Forward keep alive packets to the client

Previously, MCProtocolLib (our Java protocol library) handled keep alive packets for us. This commit disables that option and 'forwards' the keep alive packets to the client, and sending the keep alive packet back once Bedrock sends us a ping response.

* Delete DataCache

* Update to latest MCProtocolLib

* Swap values around as a sanity check
2020-09-29 14:15:11 -04:00
Camotoy 3c4cde9677
Tipped arrow translation (#1331)
* Tipped arrow translation

- Tipped arrow items are now properly translated both ways
- Tipped arrow particle effects are also translated, by having a list of all colors Java could send us and their Bedrock ID

* Remove a whitespace
2020-09-29 13:30:37 -04:00
Camotoy aee9ccc7d2
DoorSoundInteractionHandler: ignore iron [trap]doors (#1343) 2020-09-29 13:21:43 -04:00
Camotoy 9bb52afc8a
BedrockRespawnTranslator: prevent some respawn bugs (#1346) 2020-09-29 13:21:25 -04:00
Camotoy a5b00e09a1
Villager trade fixes (#1350)
This commit mainly focuses on fixing the crashing of villagers that occurred pre-1.14.

Co-authored-by: AJ Ferguson <AJ-Ferguson@users.noreply.github.com>
2020-09-29 13:19:37 -04:00
bundabrg 650c02ef66
Remove 'geyser' from parameters when executing a command under Spigot, Bungeecord, Sponge, Velocity (#1266)
* Remove 'geyser' from parameters when executing a command under Spigot, Bungeecode, Sponge, Velocity

Fixes https://github.com/bundabrg/GeyserReversion/issues/8

* Fix case when there are no sub commands

Co-authored-by: bundabrg <bundabrg@grieve.com.au>
2020-09-28 23:49:46 -04:00
EasyClifton 3650321576
Update README.md (#1349)
Make the server address look cool (for build 405, sorry)
2020-09-28 17:09:57 -05:00
rtm516 7c49391b9d
Fix gamemodes not fully applying on server switch (#1348)
* Fix gamemodes not fully applying on server switch

* Revert previous commit and move session flag updating to the adventure settings method
2020-09-28 17:43:50 -04:00
Luke d9b05f5b72
Update the CI link in the README (#1339) 2020-09-25 15:52:44 -04:00
Camotoy beae39e280
Prevent Bedrock from changing gamemode client-side (#1337)
In vanilla Bedrock, if you have operator status, the client sends a packet to change gamemode without confirmation from the server. Since we have a custom server option to request the gamemode, we just reset the gamemode and ignore this packet.
2020-09-25 20:09:02 +01:00
Camotoy fa0864b8a1
Fix picking up liquids with buckets (#1311)
* Fix picking up liquids with buckets

The last fix to prevent bucket placement upon interacting with an inventory had an oversight with empty buckets, making them unusable. This commit fixes that while keeping the previous fix.

* Remove debug line

* Fix milk drinking and visual bucket item apperance

* Comment elaboration

* Make indentiation better
2020-09-24 15:11:42 -04:00
Camotoy 1ec768d95d
Fix interaction spam bug (#1324)
* Fix interaction spam bug

This references the Nukkit 1.0 fix for the client bug of spamming to interact. Holding down still works.

* Remove interaction position set at action type 1

* Remove debug line
2020-09-24 12:54:18 -04:00
Redned 0cd43818f1
Use SERVER_READY in BedrockRespawnTranslator to fix respawn bug 2020-09-22 20:10:38 -05:00
Camotoy b4c7682130
Implement experience sounds (#1320)
Bedrock sends a level event for the experience sound around the same time as a Java entity collect item packet is sent.
2020-09-22 14:16:57 -04:00
Camotoy 2dc7dc10ff
Remove warning about slot 50 (#1325)
We know that it occurs with console crafting.
2020-09-22 14:15:59 -04:00
Camotoy 02aeddbadd
Scoreboard: Fix various issues (#1286)
* Scoreboard: update score on UpdateType.ADD

* Actually fix

* Readd the Objective when a score changes

It looks like Objectives only update when you Remove the Objective and add it back using the SetDisplayObjective. This is hopefully a hotfix, but I think that there is no better way.

* Explain score tracking

Co-authored-by: Tim203 <mctim203@gmail.com>
2020-09-21 23:55:13 -04:00
Camotoy 2db1d16f5c
Only send the client brand on game join (#1299)
* Only send the client brand on game join

* Apply suggested changes
2020-09-21 16:06:25 -04:00
Comstepr 5fafa0759e
Update pullrequest.yml (#1305) 2020-09-18 21:21:44 -04:00
Camotoy 2f2164f387
InventoryUtils: Don't send Java packet on hotbar item selection (#1301)
The Bedrock client sends a confirmation packet we translate regardless.
2020-09-17 23:07:20 -04:00
rtm516 99e72f35b3
Add support for manually supplying Bedrock resource packs (#1076)
* send resource packs

A lot of this code is nukkit-credits in the classes

* send resource packs

A lot of this code is nukkit-credits in the classes

* Remove unnecessary code/debugs

* use separately generated hashes

* Updated mappings and added .mcpack support

* "packs" directory auto-create (#484)

* "packs" directory auto-create

* cleaned indentation in ResourcePack.java

* Cleaned ResourcePack.java

* Another cleanup

I hate editor on github.

* Yet another

* Another indentation cleanup

* Fix resource pack loading

(cherry picked from commit f93b07491e)

* Move back to internal sha256 hashing

(cherry picked from commit 812a3d82b2)

* Add resource pack loading back after merge

* Add comments, config option and removed unused files

* Fix packs folder location and cleanup code

* Move to better options for the client

* Fix typos in comments

* Fix pack loading

* Try to make it compile

* Final touches?

* Add Javadoc for MathUtils#constrain

Co-authored-by: EOT3000 <43685885+EOT3000@users.noreply.github.com>
Co-authored-by: Vesek <61123478+Vesek@users.noreply.github.com>
Co-authored-by: Heath123 <heath.mitchell27@gmail.com>
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-09-16 20:08:26 -04:00
rtm516 1a49e882d3
[Android] Remove usage of MCProtocolLib Base64 in SkinUtils + more (#1237)
* Remove usage of MCProtocolLib Base64 in SkinUtils

* Fix path resolution for downloading locales
2020-09-16 11:33:59 -04:00
Camotoy 3c1d4aae93
Fix inconsistencies with players and the player list (#1298)
* Fix inconsistencies with players and the player list

This commit makes the player list entry packet control the player cache, fixing inconsistencies that appeared when removing the override on despawning the player.

* Update comments
2020-09-16 00:18:18 -04:00
Camotoy f9c1d3f218
Remove Protocol v409 support (#1300)
* Remove Protocol v409 support

Protocol has dropped support for this version.

* Fix movement

* Use a static commit for Protocol
2020-09-16 00:11:56 -04:00
Camotoy 6638c53029
Implement command block and jigsaw support (#1291)
* Implement command block and jigsaw support

- Command block UI is now fully implemented to match Java Edition.
- Command block minecarts are now supported.
- Command blocks now show the correct type of command block.
- Jigsaw blocks are translated.

Structure blocks can be implemented, but these will be trickier as there are significant GUI differences between Java and Bedrock.

* Add more detail about command block minecart color

* Set PlayerPermission.OPERATOR to allow command blocks to be destroyed
2020-09-14 20:54:19 -04:00
Camotoy f5a9254fae
Disconnect player if Java sends disconnection (#1274) 2020-09-14 20:53:47 -04:00
Camotoy 9c8eb00cd5
JavaCollectItemTranslator: check null for entities (#1267) 2020-09-14 20:52:50 -04:00
Camotoy 3b274ef9d1
Pick block improvements (#1265)
* Pick block improvements

- Creative block picking is now implemented. If the survival-styled block picking fails, then the item is created, following Java-style mechanics.
- Entity 'picking' is also implemented. The item is crafted using the same mechanics, and the same rules apply as normal block-picking (except it only works in creative mode, following Java.

* Switch some logic around
2020-09-14 20:52:16 -04:00
Camotoy 1e1402a23f
DumpInfo: Mark internal IP as sensitive (#1264)
Sometimes the internal IP is the external IP of the server.
2020-09-14 20:51:07 -04:00
Camotoy b13f5e900f
PlayerEntity: despawn even if still on the player list (#1263)
Fixes LibsDisguises not working, as it uses the same entity ID for the disguised entity and player. The player still appears on the player list.
2020-09-14 20:50:21 -04:00
Camotoy 26802e6dab
Translate CanPlaceOn/CanDestroy NBT (#1253)
* Translate CanPlaceOn/CanDestroy NBT

This commit adds support for the translation of the CanPlaceOn/CanDestroy NBT for Bedrock clients.

* Remove debug line
2020-09-14 20:50:07 -04:00
Camotoy 9643b208f3
Check if Fireworks tag is null (#1255)
Thank you Mineplex, very cool.
2020-09-14 20:40:41 -04:00
Camotoy 46c34842d8
BedrockInventoryTransactionTranslator: check to make sure bucket usage is on purpose (#1280)
Otherwise buckets can be activated when opening block inventories.
2020-09-12 09:47:43 -04:00
Camotoy 8c8630814d
Update to 1.16.3 (#1272)
* Update for 1.16.3-rc1

* Update to 1.16.3

* Update README

* Update MCProtocolLib
2020-09-10 10:30:56 -05:00
Camotoy d47360d6fb
GeyserSession: send command permission level OPERATOR if qualified (#1254)
Mobile clients have a GUI for commands that shows if CommandPermission.OPERATOR or higher is sent. The commands present all require OP permission 2 or higher; therefore we set that command permission if the server tells us we have a OP permission level of 2 or higher.
2020-09-05 16:22:31 -04:00
Camotoy 854849f63c
Update mappings to fix 1.16 wood slabs (#1249) 2020-09-04 14:08:04 -04:00
Camotoy 5b76a85895
Non-full-chunk support (#574)
This commit adds non-full chunk support if chunk caching is enabled.
2020-09-03 19:00:36 -04:00
Camotoy 4c58568eb4
Relocate Google Common (#1242)
Fixes NoSuchMethodErrors from occuring on certain Spigot servers.
2020-09-02 23:42:53 -04:00
Camotoy 4f761c5bde
Translate scoreboard nametag visibility (#1240)
This commit adds support for name tag visibility in teams. If a player is set to hide their nametag, it will be hidden from the Bedrock client. Notably, this fixes most NPC nametag hiding, including Citizens. This does not fix some NPC nametag hiding - there are several NPCs in Hypixel that still have a nametag show up, and they are not a part of any team.
2020-09-01 23:39:14 -05:00
Camotoy b21f477366
Parrot mounting fixes (#1236)
* Parrot mounting fixes

- Fix duplicate parrots when a parrot leaves the player
- Fix rotation of parrots

* Remove critical debug information
2020-09-01 23:39:06 -05:00
Camotoy dcf1731d8a
Implement correct sign wrapping (#1228)
* Implement correct sign wrapping

This commit ensures that the auto-wrapping nature of Bedrock with signs is corrected. If a Bedrock player sends a sign that is auto-wrapped, it will now be interpreted by Geyser to fit on multiple lines. Additionally, Geyser will crop incoming sign text to prevent auto-wrapping.

* Don't wrap if it's the last line
2020-09-01 23:38:36 -05:00
Camotoy 81a48bf96d
Relocate the rest of our dependencies (#1227)
- Relocate all of our dependencies. This does not include MCProtocolLib and Nukkit dependencies at this time as there are no other known plugins that use these dependencies.
- Switch to a static commit for Adventure dependencies.

Tested working on all versions.
2020-09-01 23:38:10 -05:00
Comstepr b97bf56d99
Minor changes to config.yml (#1224) 2020-09-01 23:37:49 -05:00
Camotoy 6f161a380f
GeyserSession: Always set Keep Inventory to true (#1213)
* GeyserSession: Always set Keep Inventory to true

This prevents the client from removing items on death in creative mode if Keep Inventory is true, but doesn't break existing behavior. Essentially, this assures full server-side behavior of the inventory during death.

* Small comment update

* OK, it was fine before the last commit, but make it better
2020-09-01 23:37:24 -05:00
Camotoy d717085c6b
JaveNotifyClientTranslator: Translate invalid bed message (#1212)
This isn't sent as its own message but as a specific event.
2020-09-01 23:36:53 -05:00
Camotoy 7c4868cada
LocaleUtils: don't NPE if no default locale mapping exists (#1239) 2020-09-01 18:29:53 -04:00
Camotoy b5f6ada4ae
ScoreboardUpdater: Quick fix to lessen CPU usage (#1238)
This prevents one/multiple CPU cores from taking up 100% usage. A better, permanent fix will replace this in the coming days.
2020-09-01 19:30:40 +02:00
Camotoy 2f9ff0c622
ShulkerBoxItemTranslator: Ensure Items ListTag is present (#1221)
* ShulkerBoxItemTranslator: Ensure Items ListTag is present

* Compile
2020-08-30 00:18:23 -04:00
RednedEpic 37c4192c12 Show the supported Bedrock versions in the version command rather than just the default codec 2020-08-28 19:11:32 -05:00
jackson-57 caa5098d2c
Fix minor spelling error in issue template (#1214) 2020-08-28 16:58:37 -04:00
Camotoy 3f00803499
connector/pom.xml: Move back to main MCProtocolLib repository (#1211)
Fixes a regression where ClientPlayerAbilitiesPacket was sending the incorrect flag.
2020-08-28 15:16:35 -04:00
rtm516 79bf56a75c
Tweaks to support Android (#1206)
* Downgrade reflections to 0.9.11

* Add comment explaining downgrade

* Move to pre-build reflections

* Update skins to use https and relative cache dir

* Move to https OptiFine cape url

* Add javadoc to isProduction

* Add ANDROID as a platform type

* Re-ordered PlatformType

* Change stop command to call onDisable
2020-08-28 19:36:24 +01:00
Tim203 1c84993853
Scoreboard improvements (#1166)
* Added a way to check if debug logging is enabled

* Improved scoreboard performance

* Include Teams in pps and return pending pps instead when higher then pps

Some servers have a huge amount of score packets when the player logs in, but before this commit, only after the first high pps (packets per second) the ScoreboardUpdater will be used (after pending packets per second have been moved to packets per second). But this commit fixes that the ScoreboardUpdater can be used on the second that the pps is getting high.

* Fixed team pre + suffix "null" issue and added threshold config option

Fixed team pre + suffix "null" issue.
When the prefix and/or suffix of a Team is null, "null" will be returned instead of null (Due to the way that MCProtocolLib is made and designed). This is fixed by simply checking if the prefix and/or suffix equal "null" and if that is the case, replace it with "".

Added threshold option.
Gave the person who is running Geyser an option to specify the first Scoreboard packets per second threshold to further improve performance by lowering the setting or decrease performance by relaxing the setting a bit. The value can't be higher then 250 (the second threshold), because it'll always choose the lowest threshold.

* Forgot to bump config version

* Small changes

* Reverted version bump, changed Sponge config, changed FloodgateKeyLoader

Reverted version bump
Camotoy said that you only need to bump the config version if the change is breaking, the config version bump has been reverted.

Changed Sponge config
The Sponge config has been modified to look like the other platform configurations.

Changed FloodgateKeyLoader

* Changed default-locale and (remote) address as requested by Camotoy

* Reduce bandwidth and a few final tweaks

* Made the scoreboard-packet-threshold a bit higher due to improvements
2020-08-28 10:47:52 -05:00
rtm516 7cbfdcf521
Fix reflections relocation (#1199) 2020-08-28 10:29:48 -05:00
abeshi-softwire 5458a85ed7
Adding option to use different config file for standalone (#1102)
* Added config option to standalone Geyser

* Cleanup

* Added --gui, --nogui options

* Made new options read default config.yml from correct place internally

* Changed to locale strings rather than hardcoded English

* Using separate options texts

* Changed '-c' to be string parameter so it isn't translated
2020-08-25 17:39:51 -04:00
James Cahill 81f58ee9bf
Add Server Name config option (#1170)
* Add bedrock.server-name config option

* Fix spelling mistake oops!

* Remove trailing whitespace
2020-08-25 09:29:55 -04:00
Camotoy c1a70c7754
Translate client-computed recipes (#1181)
* Translate client-computed recipes

A handful of recipes are complex enough on Java Edition that the client simply calculates them after getting an assurance that they are valid recipes. This PR stores those recipes in a Bedrock-compatible format in mappings, then generates the CraftingData information on startup to send to the Bedrock client when called. This fixes firework rocket and star crafting, and fixes leather armor and shulker box dyeing.

The recipe information for everything except leather armor was taken right from the Bedrock server. The leather armor had to be created separately (see https://github.com/DoctorMacc/LeatherDyeingCreation). There will be a slight visual difference in the crafting result preview if the armor is not perfectly dyed to one of the sixteen colors, but this is a visual issue that will persist unless we calculate every single possbile combination.

* Revert other changes

* Register shulker box recipes properly

* Add break

* Update mappings
2020-08-24 21:14:44 -05:00
Camotoy 6e8106eeec
Add shulker box item tooltip translating (#1189)
* Add shulker box item tooltip translating

This commit adds support for previewing the items inside of a shulker box. This does not do a full translation, and only does enough to translate the item information to the client, so as to prevent any accidental item modifying/removing on creative mode.

* Swap values
2020-08-24 21:05:39 -05:00
Camotoy 65c45386b9
Update mappings (#1196) 2020-08-24 21:04:25 -05:00
Camotoy aaa3d7238d
BedrockEmoteTranslator: ensure sending player is valid for all other sessions (#1194) 2020-08-24 10:26:37 -04:00
Camotoy 8b7165a564
Implement (hopefully) temporary dimension switching fix (#1188)
This fixes rare (?) instances where dimension switching doesn't finish loading on the client. Ideally a proper fix would send the finishing packets in the correct order but I didn't get far in this regard.

Fixes #1154 and #1072.

Other miscellaeous chunk-related fixes have also been included here.
2020-08-24 09:31:21 -04:00
E404NNF 1d5b453595
Add a warning at start about movement translation (#1069)
Co-authored-by: Redned <redned235@gmail.com>
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-08-23 11:34:09 -04:00
Comstepr a306e9d35b
Add smithing table to what's left to be added/fixed (#1187)
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-08-23 11:29:02 -04:00
EasyClifton 73e09def06
Add Loom to fix list (#1185)
Added loom to the What's Left to be Added/Fixed list.
2020-08-23 11:24:31 -04:00
Jordie 2d6264d7c1
Add visual support for signs colored with dye (#1180)
* Fix dyed signs in Bedrock Edition

Add visual support (in Bedrock Edition) for signs colored with dye (in Java Edition)

* Javadoc for getBedrockSignColor(string)

* Simplified getBedrockSignColor(string)
2020-08-22 16:39:40 -04:00
Camotoy 713085adf2
Fix NPE if block data string isn't in mappings (#1172)
This happens when the server version is below the current version and the block state changed. A better solution would be to use ViaVersion to translate the block state strings but this would require getting the server version and figuring out mappings from there.
2020-08-21 12:02:09 -05:00
Camotoy 94d6c872b1
Prevent a comma from appearing if Geyser fails to bind (#1174) 2020-08-21 12:01:50 -05:00
Camotoy ee42067d87
Don't play a sound when falling onto a block (#1175) 2020-08-21 12:01:38 -05:00
Camotoy 7fcfa7d54d
Implement an enchantment table GUI (#1177)
Until 1.16, enchantment tables were impossible to implement properly in Geyser. When a user selects an enchantment in Bedrock, the client creates the book on its end and assumes the server is OK with it. Java requires a button to be pressed to select the enchantment. With 1.16, server authoritative inventories remove that on Bedrock. However, until our inventory rewrite is finished we are still stuck without enchantment table support. This commit serves as an alternative as we wait.

Enchantment table GUI support is still impossible since we are using the pre-1.16 inventory system. To solve this, this commit replaces the enchantment table GUI with a hopper GUI. The first slot serves as the spot you place the weapon. The second slot acts as the lapis slot - Geyser prevents any item from going in there that is not lapis. The final three slots act as the buttons; an enchanted book acts as each button, with the ability to show the translated text of each enchantment.

https://cdn.discordapp.com/attachments/613194828359925800/746164042359504927/unknown.png
2020-08-20 20:53:47 -04:00
Camotoy d6290ccb66
Auto-configure more if setting is enabled (#1168)
* Auto-configure more if setting is enabled

- Geyser dumps now show if the config was automatic
- Floodgate is now automatically detected if the address is also automatically found
- If the plugin versions' servers have the listening address set to something different, set our remote address to that

* Fix Sponge config

* Remove redundant Getter
2020-08-19 13:14:17 -04:00
James Cahill e7363b4e9f
Add 'passthrough-protocol-name' config option (#1124)
* Initial version (tested)

* Don't bump config version

* Misc changes

* Add punctuation to config
2020-08-17 22:36:15 -05:00
RednedEpic 80a36344eb Only one of the values here needs to be greater than 0 2020-08-17 20:46:03 -05:00
RednedEpic 44f521ed04 Set player motion when explosion takes place 2020-08-17 20:40:57 -05:00
RednedEpic 6db56fd68b Disable fireworks for consoles (Addresses #1083, #1164)
Not ideal, but there isn't a whole lot we can do as this is a game bug within console versions.
2020-08-17 20:04:12 -05:00
Camotoy 8c514d9feb
Fix Xbox authentication and add support for proxies (#1162)
Waterdog and ProxyPass will work when `enable-proxy-connections` is set to true at the expense of security.
2020-08-17 12:04:09 -04:00
Camotoy b07433698a
Translate specific messages (#1161) 2020-08-16 19:02:59 -04:00
Camotoy 78e8792a2d
FireworkEntity: don't process if item is null (#1160) 2020-08-16 15:25:35 -04:00
R-Josef 0e91475c62
Follows specified address/port in remote config for plugin versions: fix #1110 (#1145)
* fix #1110

* updating comments in config.yml

* Fix indentation

* Centralize localhost retrieval; remove unnecessary Docker check

* Add config.yml

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-08-16 12:45:52 -05:00
Camotoy 1ead2900a3
Translate RAIN_STRENGTH to Bedrock client (#1151)
* Translate RAIN_STRENGTH to Bedrock client

Previously Geyser ignored RAIN_STRENGTH and instead relied on START_RAIN and STOP_RAIN only. This is unreliable on a vanilla server as these values are swapped around. This commit also implements thunder strength which was untranslated.

* Update rain code in JavaRespawnTranslator
2020-08-16 12:43:16 -05:00
rtm516 4af17df46f
Add support for sensitive data in dumps (#1149)
* Add sensitive dumps

* Add better arg handling and offline dumps

* Add sensitive parameters for plugin IPs

* Add sensitive property to the Bedrock remote address

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-08-15 16:06:50 -04:00
Camotoy 4bcf44638e
ConnectorServerEventHandler: set default packet handler (#1148)
This allows disconnect packets to be sent and kick unsupported versions of the game.
2020-08-13 09:56:03 -05:00
Camotoy bf238f52c7
Update to latest MCProtocolLib (#1140) 2020-08-12 16:27:13 -04:00
Camotoy 1fb68dc9e3
LoginEncryptionUtils: Add proper string for no Xbox account (#1139) 2020-08-12 13:48:40 -05:00
RednedEpic e2a9566926 Kick player with invalid chain data for additional security
The client should disallow players to join servers if they're not logged in, however this just adds a second layer of security in the event that it's somehow bypassed.
2020-08-12 10:42:02 -05:00
bundabrg e02495ca7f
Fix Alex/Steve skins being sent incorrectly (#1135)
* Return permanent skins (alex/steve) when queried instead of returning an empty skin due to invalid lookup
* Fix Alex/Steve being shown incorrectly due to java signed integers

Co-authored-by: bundabrg <bundabrg@grieve.com.au>
2020-08-12 08:23:11 -05:00
Camotoy fb5a894595
EntityUtils: Properly map 1.14 entity status effects (#1133)
Previously, Hero of the Village and Bad Omen effects were mapped to 0. This commit updates them to their proper Bedrock values.

Fixes #1129
2020-08-12 08:22:13 -05:00
bundabrg fbf30a6059
Fix Skin Selfie (#1131)
Co-authored-by: bundabrg <bundabrg@grieve.com.au>
2020-08-11 23:06:32 -04:00
Redned d3ef3a4a34
Merge pull request #1127 from GeyserMC/feature/1.16.2
1.16.2 Support
2020-08-11 13:42:47 -05:00
DoctorMacc 5db0e7898f
Bump MCProtocolLib 2020-08-11 14:33:37 -04:00
rtm516 41d299fae5
Change version number to 1.1.0 2020-08-11 19:10:48 +01:00
rtm516 016a5c04ea
Fix chat translation parameters not having color sometimes 2020-08-11 18:45:14 +01:00
DoctorMacc 31fec1d4bf
Update to 1.16.2 2020-08-11 12:35:45 -04:00
DoctorMacc 8b691d22d5
Add v408 as the default protocol
smh mojang
2020-08-11 12:16:18 -04:00
DoctorMacc 6ccf629a8a
Update to 1.16.2-rc2; add multiversion support 2020-08-11 10:00:14 -04:00
DoctorMacc 953fe8fec3
Update mappings 2020-08-11 09:09:29 -04:00
DoctorMacc 2dc71382e7
Merge branch 'master' of https://github.com/GeyserMC/Geyser into feature/1.16.2 2020-08-11 09:07:23 -04:00
DoctorMacc 009381d9c7
Update for protocol v409 2020-08-11 09:06:28 -04:00
EasyClifton afc7dfeb45
Add Command Block and Structure block to the fix list (#1119)
* Add Command Block and Structure block to the fix list

* Add Horse Inventory to the fix list

Added Horse to the What's left to be added/fixed list.
2020-08-11 10:57:49 +01:00
rtm516 b84986a502
Fix quotes breaking formatted message strings (#1118) 2020-08-10 21:44:20 +01:00
DoctorMacc a676e86f6c
Remove debug line 2020-08-10 11:22:59 -04:00
rtm516 c7958af1db
Fix dust particles type (#1108) 2020-08-10 09:31:49 -05:00
Camotoy 9ac13f37b7
Update submodules (#1109) 2020-08-10 09:31:39 -05:00
rtm516 439027d510
Fix Shulker color and open state (#1113) 2020-08-10 09:31:08 -05:00
DoctorMacc 6e80f22ee9
Update to 1.16.2-rc1 2020-08-09 22:43:57 -04:00
Savagetechguy 3ef7e30230 Fix fire not extinguishing on server side when on bedrock
Fixes #875
Fixes #906
2020-08-08 17:59:03 -05:00
RednedEpic 04cf8b2a99 Fix javadoc errors 2020-08-08 17:56:15 -05:00
rtm516 0a5048232f
Add support for client side settings (#1035)
* Port code from #486

Co-authored-by: Luke <32024335+lukeeey@users.noreply.github.com>

* Fix and clean code and add default gamemode changing

* Clean copyright

* Remove direct modification of server, clean up code and add player list xuid fetching.

* Move to custom settings menu

* Move sendAdventureSettings to GeyserSession

* Add javadoc comments

* Add translation support

* Remove updated copyright

* Clean up

* Clarify some javadoc comments

* Remove obsolete code

* Update languages submodule

* Fix javadoc comments

* Fix compile

Co-authored-by: Luke <32024335+lukeeey@users.noreply.github.com>
Co-authored-by: Redned <redned235@gmail.com>
2020-08-08 17:41:12 -05:00
Camotoy 0fde30fc78
GeyserSession: always send naturalRegeneration=false gamerule (#1097)
This essentially gives the server full control over the health visual.
2020-08-08 16:50:49 -05:00
Camotoy 7df476183a
Implement proper mappings for pistons, dropper, dispenser (#1103)
This commit gets rid of the hacky workaround implemented for pistons, droppers and dispensers and actually implements the vanilla data values.
2020-08-08 16:50:32 -05:00
Camotoy d49856cd7f
Change scoreboard errors to debug only (#781)
Prevents errors from occuring that don't stop operation of Geyser.
2020-08-07 14:10:26 -04:00
bundabrg 0ca1096f45
Fix Skin Caching and Fix Skin Restorer (#680)
* Fix Skin Caching

Changes:
* Instead of caching a skin based upon the player we cached it based upon the textureURL. This means multiple players with the same skin will benefit from the cache and more importantly will mean a player changing their skin will not get a false cache hit.
* This should fix all issues with SkinRestorer and will now correctly show the skin both to the player themselves and to other players

Closes #518

* Remove duplicated code

* Minimize playerlist updates

Changes:
* All async skin stuff will now just update skins and not be involved with sending the session to the player. This eliminates issues where the player list changes whilst an async task is occuring plus it means no invisible players while retrieving skin.
* Fix bug when retrieving cached skin

* When sending PlayerList packets ensure the skins have appropriate skinIds so the Bedrock client will cache hit/miss as needed

* Make sure to add and remove player when setting skin if they do not belong on the playerlist

* Make use of AuthData UUID when removing the player

* Revert removal of checking if entity is valid when initialized

This section is supposed to send all spawned entities in the java world to a player only after they've initialized. By removing this check it would also be sending entities that exist but are not spawned.

* Optimizations

Changes:
* Check for duplicate requests based on textureURL instead of player ID
* Don't use the PlayerSkinPacket. It duplicates the data sent in the PlayerListPacket and without it the players still get skin updates.

* Support caching of skins to disk based on configuration variable

If a skin is downloaded it will be saved to `cache/skins` using a base64 encoded filename of the textureUrl, if allowed by setting a non 0 value for the configuration variable `cache-skins`

When reading a skin we try load it from a cache file first before trying to download it.

We don't yet expire them but do update their last modification so we know which ones have been accessed.

* Update `config.yml` with cache-skins directive, defaulting to disabled

* Merge Fixes

* Cache all images instead of just skins

Changes:
* Move the image caching from skins to where images may get downloaded so this also covers capes and anything else that uses the same method of image retrieval
* Updated config value from `cache-skins` to `cache-images`
* Updated cache location from `cache/skins` to `cache/images`
* Images are stored in png format with a uuid. This may make debugging easier as they can be directly opened.

* Implement cached image expiry

If `cache-images` is set to a value greater than 0 then a scheduled task will occur once a day that will remove images with a modification date older than the value in days.

* Force skin changes as trusted

* Resolve PR queries

* Fix signed int causing issues calculating expiry time for images

* Reset Defaults to 0 and implement Google Timed Eviction cache for Images

* Add memory cache for Capes

Co-authored-by: Brendan Grieve <brendan.grieve@zepli.com.au>
Co-authored-by: bundabrg <bundabrg@grieve.com.au>
2020-08-07 12:33:21 -04:00
DoctorMacc 098a0e7993
Update to 1.16.2-pre2 2020-08-05 18:57:41 -04:00
rtm516 dea9329bb4
Update mappings submodule to fix 1.16 slabs and stonecutter (#1089) 2020-08-05 16:36:58 +01:00
DoctorMacc e8df81167b
Merge latest master 2020-08-05 11:20:25 -04:00
AJ Ferguson 61dbcb0c80
Update effects mappings (#949)
* Update effects mappings

* Use STOP_RECORD as the default record instead of null

* Add comments

* Update mappings submodule

* Update MCProtocolLib and effects

* Change level event used for EVAPORATE effect

The bedrock client plays an additional sound when using CAULDRON_EXPLODE.
The java client does not play any sound.

* Update mappings submodule
2020-08-03 13:42:43 -08:00
Camotoy 11c713dc6f
JavaEntityMetadataTranslator: replace stack trace with concise warning (#1086)
* JavaEntityMetadataTranslator: replace stack trace with concise warning

Removes the stack trace given when a ClassCastException occurs and replaces it with a friendlier message. Class cast errors will happen since some servers send incorrect values, and apparently it is default Minecraft behavior to ignore them.

* Update languages submodule
2020-08-03 16:29:52 -05:00
AJ Ferguson 86f18c9392
Remove Y pos workaround in BedrockItemFrameDropItemTranslator (#1037) 2020-08-01 14:41:59 -04:00
Camotoy 07f3d45cc4
Check for display tag when translating anvil contents (#1073) 2020-08-01 11:57:25 -05:00
Camotoy 7fc14d8956
Add customizable MTU support (#1068)
* Add customizable MTU support

Fixes clients being unable to connect in rare instances.

* Make config.yml nicer
2020-07-31 19:47:23 -04:00
Redned af5e8a83ca
Add test server to README 2020-07-31 14:57:06 -05:00
Arktisfox 54bee1f868
Small entity metadata fix, other player bow implementation (#685)
* Move blocking case to LivingEntity, and make other players bows animate.

This moves metadata ID 7 to LivingEntity, it's proper place. It also sets the 'USING_ITEM' flag which animates other players bows.

* Add skeleton aiming support

Skeletons don't have support of pushing their bows back on Bedrock, but this allows them to hold their arms up

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-07-30 22:10:55 -04:00
rtm516 f7ac078ead
Fix clone-remote-port (#1062) 2020-07-30 17:49:59 -05:00
Camotoy 238a3a8df1
Support immediate respawn gamerule (#970)
* Support immediate respawn gamerule

This commit now supports immediate respawn if the server enables it - both on the setting being applied on join and the setting being modified in-game. This also refactors the respawning process to more closely match BDS behavior - nothing broke in my testing but more testing is needed.

* Reuse spawned variable instead of creating new variable
2020-07-30 15:31:12 -05:00
Camotoy a4339be212
Only send metadata update once per Java metadata packet (#1022)
While this doesn't fix any bugs, it may be a slight performance enhancement as we aren't sending multiple packets per one Java entity metadata packet.
2020-07-30 15:15:07 -05:00
Camotoy 9097f8547b
Add rabbit jumping animation (#1027)
* Add rabbit jumping animation

This isn't perfect as Bedrock uses a duration and Java just sends the jumping animation. There may be something else missing from the puzzle piece.

* Remove debug line
2020-07-30 15:12:09 -05:00
bundabrg 784cb73301
Test if slot 50 used and under what conditions. (#1028) 2020-07-30 15:11:35 -05:00
bundabrg 11300254f0
Fix Anvil renames by trying a component first then fallback to plain text (#1052)
Closes #1039
2020-07-30 15:10:43 -05:00
rtm516 b10e5d5af3
Clean copyright message and update all files (#1053) 2020-07-30 15:10:15 -05:00
rtm516 50346a95cd
Update closest color conversion (#1057)
ViaVersion altered their color conversion to fix an issue and this just copies those changes
2020-07-30 15:09:53 -05:00
toinouH 427cb69a14
clone-remote-port option Updated (#1061)
* Added clone remote port option for bukkit, bungee and velocity

* Added clone remote port option for sponge

* Changed clone-remote-port description in config.yml

* Update config.yml

Updated config.yml to include a better description of the clone-remote-port option

* Updated GeyserSpongePlugin

An incorrect port was being edited before (remote instead of bedrock)

* Update config.yml

Co-authored-by: TeaNoDonuts <blackalegator@gmail.com>
2020-07-30 15:09:40 -05:00
rtm516 600c54d89d
Add translation badge and remove manual remapping of language codes (#1060) 2020-07-30 15:07:59 -05:00
rtm516 118747c66b
Move MEGABYTE to a constant (#1059) 2020-07-30 17:40:53 +01:00
rtm516 0c3a6f1a6a
Check if the passenger is null before trying to update metadata (#1001)
* Check if the passenger is null before trying to update metadata

* Fix variable name
2020-07-30 12:19:26 -04:00
rtm516 b7f0780a56
Fix duplicate info and add more info to dumps (#1058)
* Fix duplicate info and add more info to dumps

* Add gui to standalone dump info
2020-07-30 11:59:42 -04:00
DoctorMacc bf07f1a9ba
Update to 1.16.2-pre1 2020-07-29 21:05:18 -04:00
DoctorMacc 43c062c23c
Update to latest master 2020-07-29 16:25:42 -04:00
Camotoy 964432e4f8
Update submodules (#1047) 2020-07-28 21:01:58 -04:00
Camotoy f5e78371be
Hide stack trace if an SRV record is unable to be found. (#1046) 2020-07-28 17:47:08 -05:00
Camotoy fe75320d6d
Add WORLD_IMMUTABLE flag to spectator mode (#1034)
Prevents the client from trying to interact with blocks
2020-07-27 18:18:22 -04:00
AJ Ferguson b9846fe797
Small inventory fixes (#1029)
* Increase minimum delay between closing and opening a new window

* Fix potential crash when opening player inventory
2020-07-27 11:17:55 -04:00
Heath123 d316d3a5a8
Add .vscode to .gitignore (#1033)
* Add .vscode to .gitignore

* Use Toptal gitignore generator

rtm516 said this would be cleaner, which makes sense

* Use gitignore.io links

* Uncomment #.project
2020-07-27 11:30:24 +01:00
bundabrg d03f56e7e8
Fix Merchant Inventory Transaction (#1017) 2020-07-25 23:06:06 -04:00
Camotoy 5c2a225533
Check for null when looking for SRV (#1025) 2020-07-25 17:21:13 -05:00
Phillipp W af484a425b
SRV resolving / Small Handshake rework (#968)
Handshake now uses the server address directly from the config and no longer the IP from a domain (Some servers use the address that is given during the handshake)
2020-07-25 13:42:43 -04:00
rtm516 64727db67b
Fix Wolf anger display (#1021) 2020-07-25 12:53:44 -04:00
bundabrg fffac8a552
Fix Spawn position not using offset. (#1015) 2020-07-25 10:38:00 -04:00
DoctorMacc 523e304290
Update mappings 2020-07-24 16:45:44 -04:00
DoctorMacc 127bc39c53
Merge branch 'master' of https://github.com/GeyserMC/Geyser into feature/1.16.2 2020-07-24 15:45:28 -04:00
AJ Ferguson 5b1116b15a
Creative items (#1013) 2020-07-24 15:42:15 -04:00
DoctorMacc 9a3a7ef50f
Merge branch 'master' of https://github.com/GeyserMC/Geyser into feature/1.16.2 2020-07-24 10:48:00 -04:00
DoctorMacc ae77388b2e
Allow compilation; update GeyserConnector 2020-07-24 10:45:36 -04:00
DoctorMacc 6b7dad1483
Update for protocol 408 and 20w30a 2020-07-24 10:39:10 -04:00
Camotoy b103d86ff9
Fix buckets on desktop survival (#1003) 2020-07-23 14:37:14 -04:00
Camotoy ad9184ad13
Update Adventure-Legacy dependency (#996) 2020-07-22 14:52:12 -04:00
Camotoy b211b9da2e
Update entity status mappings (#995)
- Add support for LIVING_BURN entity status
- Properly send sheep graze event
2020-07-22 11:03:09 -04:00
ForceUpdate1 765efe8a33
Fix anvil item rename (#992)
* fix anvil item rename

* fix anvil item rename
2020-07-21 15:01:55 -05:00
rtm516 30c007d04b
Fix buckets not working on mobile (#767)
Desktop clients send an extra item use packet for buckets whereas mobile clients dont send the second use packet causing the issue as a ClientPlayerUseItemPacket doesn't get sent to the Java server.

Buckets on mobile may still be glitchy as the player must be directly facing the block they want to place liquid on.
2020-07-21 13:17:55 -04:00
D3ATHBRINGER13 8daf4ef2b7
Add piglin brutes (#989) 2020-07-20 19:45:38 -04:00
DoctorMacc df503ded57
Merge branch 'master' of https://github.com/GeyserMC/Geyser into feature/1.16.2 2020-07-20 19:03:28 -04:00
DoctorMacc 3b8d1758b3
Initial update for 20w29a 2020-07-20 19:02:18 -04:00
Camotoy 7bb297dd42
Update submodules (#979) 2020-07-20 14:34:19 +01:00
Camotoy e5fc66d72f
Fix elytra flying in creative mode (#956)
Sending a ClientPlayerAbilitiesPacket allows the player to successfully fly.

This commit also removes the setting of the CAN_FLY entity flag on creative mode. This did not break anything in my testing.
2020-07-18 15:57:37 -05:00
Camotoy 221e5bd103
Disconnect client if using an invalid Mojang account (#975)
This commit supresses the NPE that was previously sent when using an invalid Mojang account. Instead, the Bedrock client is disconnected with an error message.
2020-07-18 15:56:12 -05:00
rtm516 64d5390800
Allow for returning of error messages (#955)
* Allow for returning of error messages

* Fix request not sending before error check
2020-07-14 18:58:09 -04:00
Camotoy af0182d116
Update CONTRIBUTING.md (#940) 2020-07-14 17:29:08 -05:00
rtm516 e9d2a922b3
Update bug report template (#954) 2020-07-14 23:21:13 +01:00
rtm516 ab116dcbc3
Update map colors to 1.16 (#947) 2020-07-14 02:18:30 -05:00
rtm516 04e73efd94
Fix enchantment conversion (#920)
* Fix java to bedrock enchantments

* Fix NBT conversion and add Soul Speed enchantment

* Remove unused import
2020-07-14 02:18:11 -05:00
AJ Ferguson 23f33881cd
Fix potion effect colors (#951) 2020-07-14 02:17:20 -05:00
Camotoy c4db0e2e63
Manually disconnect client on LoginDisconnectPacket (#950)
The client will not get kicked on a LoginDisconnectPacket causing them to remain in an empty world perpetually.
2020-07-13 21:53:55 -04:00
rtm516 0a14e3c441
Add an extra headless check to fix occational errors (#945)
* Add an extra headless check

* Update GeyserStandaloneBootstrap.java

* Rename checkHeadless to isHeadless
2020-07-14 00:20:56 +01:00
RednedEpic e7657c7d07 Fix enchantments for servers that don't namespace them (Fixes #897) 2020-07-11 19:52:20 -05:00
RednedEpic 5ceb4145ac Fix fireworks (Closes #917) 2020-07-11 19:40:26 -05:00
rtm516 485ba1b8a7
Check the name tag exists for anvil renaming to prevent an NPE (#936)
* Check the name tag exists for anvil renaming to prevent an NPE

* Fix item names being empty if display tag exists with no name
2020-07-11 21:58:12 +01:00
Camotoy 7757913c00
Update MCProtocolLib to fix cached chunks on non-Spigot (#937) 2020-07-11 16:47:21 -04:00
Camotoy e942d7c553
Don't use player locale for outdated message. (#931)
Too early in the login cycle to grab it.

This commit also updates the languages submodule.
2020-07-11 12:51:10 -05:00
rtm516 5e5e3b0d28
Add a User-Agent to the rest of the web requests (#932) 2020-07-11 12:22:02 -05:00
Savagetechguy 4daa568311
Fixed Villager Position when Sleeping (#933)
* Update Entity.java

* Switched to VillagerEntity.java and added indents and whitespace

* Fix indents and whitespace and changed to pattern and matcher

* Clean up indentation problems

Co-authored-by: Savagetechguy <jakehorner@gmail.com>
Co-authored-by: Redned <redned235@gmail.com>
2020-07-11 12:20:03 -05:00
Camotoy 3e0cb28a63
Fix scoreboard prefix/suffix translation errors (#929)
Uses getTranslatedBedrockMessage() instead of getBedrockMessage().

Fixes #923.
2020-07-10 14:14:54 -04:00
rtm516 5e664882b1
Fix no gravity falling block entities (#927)
* Fix no gravity falling block entities

Co-authored-by: AJ Ferguson <AJ-Ferguson@users.noreply.github.com>

* Add spacing

Co-authored-by: AJ Ferguson <AJ-Ferguson@users.noreply.github.com>
Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-07-10 09:43:52 -05:00
rtm516 225e2a9fb8
Make a copy of the players list when disconnecting them all on shutdown (#928) 2020-07-10 09:43:30 -05:00
rtm516 67c2b37337
Fix version checking on older Java versions (#926)
* Fix version checking on older Java versions
We add a useragent header to stop cloudflare blocking the default Java useragent

* Explain why we need the user agent

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-07-10 00:50:08 +01:00
Camotoy cbb2586fba
Don't throw a stack trace when detecting for GUI (#919) 2020-07-08 18:44:10 -04:00
Camotoy 9cc468cee9
Remove debug string 2020-07-08 12:42:20 -04:00
DoctorMacc bfdc452e3e Add emote support for Bedrock-to-Bedrock players 2020-07-08 12:38:54 -04:00
DoctorMacc fe254380dc Clean up some TODOs 2020-07-08 12:36:26 -04:00
DoctorMacc 915ad2d057 Update languages submodule 2020-07-08 11:31:09 -04:00
DoctorMacc 83ae3199c9 Update languages submodule 2020-07-08 11:10:40 -04:00
DoctorMacc 21ea1f2408 Update MCProtocolLib to fix #836 2020-07-07 20:14:50 -04:00
DoctorMacc 40032987fa Add magma cube jumping visual 2020-07-07 19:27:12 -04:00
DoctorMacc 0cea703b46 Save ItemEntry classes for items 2020-07-07 16:40:19 -04:00
rtm516 5f6566ad0e Move to dynamic item ID mapping in ItemRegistry 2020-07-07 16:23:21 +01:00
rtm516 c2be7a181d Fix Piglin bartering animation (Fixes #863) 2020-07-07 16:11:52 +01:00
rtm516 a16deb269a Fix exact color matches not being formatted correctly (Fixes #912) 2020-07-07 15:09:24 +01:00
rtm516 75f2891ec0 Fix map_uuid nbt type 2020-07-07 14:47:56 +01:00
rtm516 8807d5d9c6 Fix banner block patterns 2020-07-07 14:30:33 +01:00
DoctorMacc f9760b721c Don't process the display tag if it's empty 2020-07-07 08:30:11 -04:00
AJ Ferguson 50176e10a8 Fix inabilty to place items into brewing stand 2020-07-06 23:44:39 -08:00
DoctorMacc 9359f401f8 Don't use 1.16 branch of mappings 2020-07-06 21:54:33 -04:00
DoctorMacc 52a125634d Resolve merge conflict 2020-07-06 21:44:47 -04:00
DoctorMacc 4353c184d9 Revert all 1.14.60-specific changes 2020-07-06 21:42:12 -04:00
DoctorMacc f68632f433 Block-related updates
- Fix block breaking animation
- Fix block breaking particles
- Don't initialize Geyser's chunk cache if using Spigot
2020-07-06 21:38:10 -04:00
RednedEpic 24f9651cc6 Convert map of players to list (may address #833) 2020-07-06 20:11:34 -05:00
AJ Ferguson 699402e635 Fix bug with maps 2020-07-06 15:52:38 -08:00
rtm516 02905c2a35 Add the adventure-api maven repo 2020-07-06 23:41:54 +01:00
rtm516 c454e443df Fix maps with negative IDs causing out of bounds errors 2020-07-06 23:36:31 +01:00
rtm516 ba736575f7 Fix RGB colors on signs causing chunk issues, fix items names not being displayed correctly 2020-07-06 23:36:04 +01:00
DoctorMacc 545dfa38f0 JavaUpdateTileEntityTranslator improvements
- Remove the use of deprecated functions
- Check for empty NBT (fixes errors on CubeCraft)
2020-07-06 16:22:07 -04:00
DoctorMacc 82c6276794 Move back to using the main repository for MCProtocolLib 2020-07-06 15:19:48 -04:00
rtm516 7e51040a8e Fix fallback locale not loading 2020-07-06 14:41:55 +01:00
James Harrison 3cdc208174
Update MinecraftCapes endpoints (#907)
Updates the mccapes endpoints with the new domain.
2020-07-06 09:26:00 -04:00
theminecoder 66570a623d
Fix scoreboards bleeding into other servers (#902) 2020-07-06 08:10:36 -05:00
rtm516 b0e291edc4 Fix version checking and add failed language string 2020-07-06 12:18:14 +01:00
rtm516 ad751ecb5b Fix ping passthrough throwing errors on unknown properties (Fixes #903) 2020-07-06 11:18:17 +01:00
Camotoy afcf1e3acd
Change versioning to match supported Bedrock version; add versioning command (#730)
* Change versioning to match supported Bedrock version

Line up Geyser's versioning to match with the highest/currently supported Bedrock version for future tracking of older Geyser versions.

* Add version command

* Fix DEV check for version command

* Remove SNAPSHOT

* Update languages submodule

Co-authored-by: rtm516 <ryantmilner@hotmail.co.uk>
2020-07-05 21:38:24 -04:00
DoctorMacc ca4d827d28 Don't cause a recursion error if Geyser can't find the locale 2020-07-05 21:13:28 -04:00
rtm516 6cdf1eaf43 Fix player table throwing errors on interaction 2020-07-06 00:46:51 +01:00
rtm516 cfaf4051b7
Add Translation support (#504)
Adds full multi-language support to any Bedrock-supported language.

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-07-05 19:35:51 -04:00
RednedEpic d1e5960d69 Send a dimension change upon join game packet now sent by bungeecord on 1.16 2020-07-05 18:33:05 -05:00
RednedEpic 69d7db4493 Update mappings submodule 2020-07-05 17:18:33 -05:00
RednedEpic da1674c8d6 Update to Cloudburst NBT 2.0 2020-07-05 15:59:44 -05:00
rtm516 5958b5d0ba Fix ram graph causing memory leak and add cleanup of options menu on reload 2020-07-05 21:07:49 +01:00
DoctorMacc 4062f1ee55 Fix flower pots and item frames 2020-07-05 00:03:51 -04:00
RednedEpic 8ac5d6e13d Fix memory leak in legacy ping passthrough (Fixes #674, #813) 2020-07-04 16:35:48 -05:00
RednedEpic cc2bbc675f Update mappings submodule 2020-07-04 13:08:36 -05:00
DoctorMacc a7fbe995f8 Add comment and check for null when removing passengers 2020-07-04 10:26:32 -04:00
rtm516 da96a5b19c Fix Strider cold state when riding and removing of the RIDING flag when a parent is killed 2020-07-03 22:55:54 +01:00
AJ Ferguson ab71bf0727 Fix bug when dropping items from an open inventory 2020-07-03 12:18:35 -08:00
dependabot[bot] 0daa4451ec Bump log4j-core from 2.13.1 to 2.13.2 in /bootstrap/standalone (#886)
Bumps log4j-core from 2.13.1 to 2.13.2.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-02 20:22:11 -04:00
dependabot[bot] 4c74f82c19
Bump log4j-core from 2.13.1 to 2.13.2 in /bootstrap/standalone (#886)
Bumps log4j-core from 2.13.1 to 2.13.2.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-02 19:18:44 -05:00
rtm516 61072948b9 Add GUI to standalone 2020-07-02 20:10:43 -04:00
DoctorMacc 699ae0b88e Set strider entity offset properly if not a player entity 2020-07-01 20:27:39 -04:00
DoctorMacc c17f21eedc Fix respawn bugs - hopefully for good
Thanks to @bundabrg for spotting this one.
2020-07-01 12:28:03 -04:00
rtm516 0f342c1e80 Update mappings to fix fences and plant stems 2020-07-01 14:26:00 +01:00
DoctorMacc 51dfda1c91 Clean up formatting 2020-07-01 08:22:21 -04:00
DoctorMacc 81651cfac5 Add support for 3D biomes; fix Nether biome display 2020-06-30 20:39:21 -04:00
rtm516 c804a6edfb Fix respawning and death not being registered on the client 2020-06-30 17:08:22 +01:00
Camotoy ed3fbf3ee0
Add message about 'outdated' Geyser. (#877)
Ensures people are aware of a 1.16 build.
2020-06-30 11:27:28 -04:00
D3ATHBRINGER13 4c2a8789af
Update Bedrock Version (#868)
* Update Bedrock Version

* Update README.md
2020-06-30 11:22:39 -04:00
rtm516 e7fae53552 Fix Strider shaking 2020-06-30 13:51:44 +01:00
rtm516 a9bb8745f5 Fix Zombified Piglin fire flicker 2020-06-30 13:20:03 +01:00
DoctorMacc ba6adc988b Strider mounting fixes; update mappings
This commit refactors health visual logic to make it a global system for each living entity.
2020-06-29 21:34:01 -04:00
AJ Ferguson eb3bde15a7 Fix stored enchantments accidentally being dropped 2020-06-29 16:59:02 -08:00
AJ Ferguson 95144266d2 Handle int tag for enchantment level 2020-06-29 16:59:02 -08:00
rtm516 7710261b70 Add Loadstone Compass tracking 2020-06-30 00:52:32 +01:00
DoctorMacc 4c89a8e303 Return to using Protocol develop branch 2020-06-29 17:52:59 -04:00
DoctorMacc fc4a87a9c9 Fix blocks not updating 2020-06-29 16:46:29 -04:00
DoctorMacc ebc1f13e9b Update dependencies ('item marked as non-null' error is fixed') 2020-06-29 16:03:54 -04:00
AJ Ferguson e77f2b5dbb Drop long array nbt tag when translating to bedrock 2020-06-29 10:59:51 -08:00
rtm516 d394cc6280 Update entity metadata 2020-06-29 15:37:54 +01:00
rtm516 91c33242c6 Fix baby states and collisions of 1.16 mobs 2020-06-29 14:40:06 +01:00
rtm516 70009c4bf9 Clean chat code and fix skins 2020-06-29 13:50:16 +01:00
DoctorMacc f2f59e4e37 Fill in renamed villager trading values (villager trading UI now opens) 2020-06-28 23:44:38 -04:00
AJ Ferguson 12d5982c57 Anvil fixes 2020-06-28 16:14:57 -08:00
rtm516 f5da962f6f Fix disconnect message formatting 2020-06-28 23:38:27 +01:00
AJ Ferguson c2c64fd1cf Fix some recipes with multiple ingredient options 2020-06-28 13:33:38 -08:00
RednedEpic 8e8bc2817a Return if sound is null and update mappings 2020-06-28 12:35:17 -05:00
D3ATHBRINGER13 980e82a2d9
Replace Bukkit with Spigot (#831) 2020-06-28 10:52:53 -05:00
Tim203 2df3d4cbca
Update to the latest MCProtocolLib commit 2020-06-28 16:44:57 +02:00
rtm516 9569416124 Fix chat formatting and team colors 2020-06-28 14:57:41 +01:00
AJ Ferguson 1410b67189 Update mappings submodule
Fixes shulker boxes
2020-06-27 22:36:41 -08:00
DoctorMacc 6e94428f60 Non-working smithing table inventory support 2020-06-28 01:53:35 -04:00
AJ Ferguson e3e8bb2799 Fix first item of creative inventory not showing 2020-06-27 20:47:10 -08:00
AJ Ferguson 2e0eb6dfb7 Fix creative item list 2020-06-27 15:26:16 -08:00
Tim203 8f763dfc5f
Move common stuff used only by connector and bootstrap to connector 2020-06-28 00:27:00 +02:00
Tim203 dd1747cae9
Updated the mappings and fixed building 2020-06-27 23:47:52 +02:00
toinouH 3cd85ed76f
Update README.md (#811)
Versions of Java and Bedrock Edition supported updated
2020-06-27 12:06:57 -04:00
rtm516 7743f6d718
Add dump command (#808)
* Add dump command
Adds a command to collect and dump infomation about the Geyser install and bootstrap and submit it to a dumps site.

* Finalize URL; misc. fixes; add 'architecture' param

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-06-27 11:36:48 -04:00
DoctorMacc 75f470cb33 Fix creative items 2020-06-27 11:35:02 -04:00
rtm516 5b147f8dd1 Fix en_us locale downloading (#809)
Fixes occasional inventories not working because of being unable to read the locale.
2020-06-27 02:00:10 -04:00
rtm516 61bfd46a15
Fix en_us locale downloading (#809)
Fixes occasional inventories not working because of being unable to read the locale.
2020-06-27 01:58:52 -04:00
endevrr d516dc5b90
Update Mappings (#816)
* Relocate Reflections Dependency

* Update some mappings
2020-06-27 01:00:35 -04:00
AJ Ferguson ba9129129c Quick inventory fixes. WIP
Temporary. The inventory system will be rewritten very soon.
2020-06-26 18:51:09 -08:00
rtm516 17a1e82eca Add closest color mapping for RGB chat colors 2020-06-26 23:33:38 +01:00
DoctorMacc 54f6fada12 Remove try/catch from BlockTranslator and ItemTranslator 2020-06-26 11:15:21 -04:00
DoctorMacc e60f47f65d Fix zombified piglins 2020-06-25 22:52:48 -04:00
DoctorMacc 409293f1db Add new 1.16 entities 2020-06-25 22:32:04 -04:00
DoctorMacc 6f2bf659a9 Update JavaEntityEquipmentTranslator for Java 1.16 2020-06-25 21:53:51 -04:00
DoctorMacc bb630dc867 Update PotionMixData 2020-06-25 12:03:20 -04:00
DoctorMacc 06fa0de793 Add translator for PacketViolationWarningPacket 2020-06-25 11:16:36 -04:00
DoctorMacc bd16925bab Update mappings repository 2020-06-25 11:11:21 -04:00
DoctorMacc 71aada1df3 Fix dimension switching; add static references to new Java dimensions 2020-06-24 20:27:27 -04:00
D3ATHBRINGER13 e4d990329d Bump action versions (#810) 2020-06-24 19:35:55 -04:00
D3ATHBRINGER13 e81c6f21bf
Bump action versions (#810) 2020-06-24 18:32:07 -05:00
DoctorMacc a964befef2 Merge branch 'feature/1.16' of https://github.com/GeyserMC/Geyser into feature/1.16 2020-06-24 18:23:02 -04:00
AJ Ferguson f0aaebc0ec Bump block state version 2020-06-24 14:14:20 -08:00
DoctorMacc 1572ac20f1 Update mappings repository 2020-06-24 17:53:26 -04:00
DoctorMacc 1490d6d062 Update ViaVersion dependency 2020-06-24 17:39:25 -04:00
Camotoy c1c2e3baa4
Allow for newest ViaVersion to work with Geyser (#805)
* Allow for newest ViaVersion to work with Geyser

Most users should now just not use 2.2.3.

* Update ViaVersion dependency
2020-06-24 17:38:41 -04:00
DoctorMacc 8be0c4b27e Update some entity properties based on wiki.vg 2020-06-24 16:40:42 -04:00
DoctorMacc 60fa43c739 Update Bedrock resources dumped by @bundabrg 2020-06-24 14:19:57 -04:00
DoctorMacc b34dc05c1d Uncomment JavaDeclareCommandsTranslator and update 2020-06-24 12:16:30 -04:00
DoctorMacc 2b874b4f24 Merge branch 'feature/1.16' of https://github.com/GeyserMC/Geyser into feature/1.16 2020-06-24 11:14:27 -04:00
DoctorMacc 78df56c7a0 Update for 1.16.1 2020-06-24 11:14:11 -04:00
endevrr ca7484a5cf
Relocate Reflections Dependency (#802) 2020-06-23 19:51:59 -04:00
DoctorMacc 3ea1059a62 Update for 1.16 2020-06-23 09:34:12 -04:00
DoctorMacc 0471fa89f4 Bedrock 1.16 updating part 2 (Doesn't work) 2020-06-22 21:21:42 -04:00
DoctorMacc ea1a9e5427 Bedrock 1.16 updating part 1 2020-06-22 20:11:09 -04:00
DoctorMacc 56f9330a2d Remove ServerSpawnWeatherEntityPacket 2020-06-21 19:22:59 -04:00
DoctorMacc 63244ade53 Rename Geyser-Bukkit to Geyser-Spigot 2020-06-21 16:27:42 -04:00
DoctorMacc 427f4ef83d Merge master into Spigot rename 2020-06-21 16:21:47 -04:00
DoctorMacc b9ccabb3bb According to all known laws of aviation, bees exist 2020-06-20 22:46:09 -04:00
DoctorMacc 117cdf282d Begin updating Geyser. Requires manual MCProtocolLib compile 2020-06-20 22:24:45 -04:00
DoctorMacc 77873b6fbb Update ViaVersion integration 2020-06-20 20:35:40 -04:00
DoctorMacc dbe1755a8e Update mappings repository 2020-06-20 18:28:07 -04:00
DoctorMacc 1015b830ce Merge branch 'master' of https://github.com/GeyserMC/Geyser into mcprotocollibupdate 2020-06-20 17:50:00 -04:00
Redned d0c95d3969
Use higher res logo 2020-06-20 14:40:12 -05:00
Redned abf04d5004
Update logo 2020-06-20 14:35:53 -05:00
bundabrg e66f57f9f0
Provide a platform independent method of retrieving the datafolder (#769)
* Provide a platform independent method of retrieving the datafolder

* LocaleUtils now uses datafolder

* Make use of Path instead of File

Changes:
* Rename getDataFolder() to getConfigFile() and update to return a Path in each bootstrap

* Rename filePath to tmpFilePath

* Update Velocity configFile to configFile Path
2020-06-20 12:54:40 -05:00
Camotoy 100d7b7759
Add villager interactive tag (#788)
* Add villager interactive tag

This adds a button/controller guide for villager trading, if the villager is able to trade.

* Use a broader variable for metadata
2020-06-20 13:44:40 -04:00
Camotoy effd7602af
Clarify Bedrock remote address change (#787)
There's no reason for most users to try changing this.
2020-06-19 13:39:40 -05:00
rtm516 8c5f5829e0 Merge branch 'mcprotocollibupdate' of https://github.com/DoctorMacc/Geyser into DoctorMacc-mcprotocollibupdate 2020-06-19 19:30:14 +01:00
rtm516 47cadc7689 Fix json data in chat 2020-06-19 19:29:01 +01:00
DoctorMacc 5327610c35 Don't forget about Bukkit 2020-06-19 13:42:55 -04:00
DoctorMacc 65f61ec703 Finish block state changes 2020-06-19 09:06:29 -04:00
rtm516 5eb7c9d1dc
Add a setter to the auth type to allow for changing at runtime (#784)
This is mainly for GeyserConnect but may be useful in other cases
2020-06-19 08:50:10 -04:00
rtm516 ad4c1ff0c7 Update Message system 2020-06-19 11:57:34 +01:00
DoctorMacc d6119375b2 (Incomplete) Update MCProtocolLib 2020-06-18 21:44:50 -04:00
rtm516 38ee19a32a
Fix toggle component json generation (#777) 2020-06-18 00:03:52 +01:00
Camotoy 6388a91587
Reset color instead of turning color to white for standalone (#759)
Allows non-black-back terminals to see the Geyser log.
2020-06-16 19:05:39 -05:00
Camotoy 9369b20209
Add 1.9+ PvP 'Cooldown' (#768)
* Add 1.9+ PvP 'Cooldown'

This commit adds a subtitle that acts as the Java cooldown. This is an optional feature disabled in the config with `show-cooldown`. This does not appear on plugins that use OldCombatMechanics.

* No need to bump up the config version; I was just tested with OldCombatMechanics

* Use simpler casting

* Use session variable of lastHitTime for theoretically better performance

* Reuse attribute value calculation from AttributeUtils

* Remove unused imports

* Revert config version update in config.yml
2020-06-16 19:03:28 -05:00
Camotoy 256c62ce88
Entity (mostly rotation) fixes (#675)
* Entity (mostly rotation) fixes

    This PR adds:

    - Pig health displaying. Doesn't fix pigs being able to be controlled
    - Entity rotation is *mostly* correct. Villagers and sitting cats still seem to be odd but the ender dragon works great.

* Remove debug line

* Abstract rotation updating to functions per-entity

* Don't include changes from other projects

* Minor improvements

* Make updateRotation and updatePositionAndRotation cleaner

* Javadoc
2020-06-16 18:58:06 -05:00
rtm516 a6f91d5e15
Fix maps not loading in sometimes (#758)
* Fix maps not loading in sometimes
Adds a default map ID so the map item isnt invisible on bedrock.
Respond to the MapInfoRequestPacket so the image loads on first join.

* Remove debug log

* Add comments
2020-06-15 14:24:52 -04:00
Sirawit Thaya 649cf28399
Fixed incorrectly arguments parsing (#773) 2020-06-15 11:20:38 +01:00
rtm516 0d6c3309e2
Fix form images (#771) 2020-06-13 19:01:58 -05:00
DoctorMacc cc3b4c3eda Merge latest master; copy over old Geyser-Bukkit configs 2020-06-11 16:39:29 -04:00
Camotoy 7fcd8f2daf
Fix block entities on older versions (#756)
* Fix block entities on older versions

This commit solves two problems related to block entities on older versions:

- Occasionally, tags would contain the ID under a StringTag with an empty value, and not the ID tag.
- The block entity regex did not account for block entity tags that were already in a Bedrock-compatible format (BlockEntity)

* Move BLOCK_ENTITY_TRANSLATIONS to BlockEntityTranslator
2020-06-10 18:02:29 -05:00
Camotoy 34b367bfc3
Configuration updates (#653)
* Configuration updates

The main feature of this commit is switching Bukkit and BungeeCord to using Jackson configuration. This allows comments to load. Along with this, the Jackson configs have been consolidated into one abstract class, and a check is made to ensure auth-type cannot be set to Floodgate if Floodgate is not installed.

* Add deleted file; remove imports

* Re-add changing of Bukkit port

* Alphabetize import

* Alphabetize Bungee import

* Updates

* Swap values in GeyserJacksonConfiguration

* Add a null check for GeyserConnector in Bukkit's onDisable
2020-06-10 17:58:29 -05:00
Camotoy 7231758a19
Prevent swimming animation from appearing on older servers (#692)
The swimming animation could be played on older servers since that was a legacy value for using an item.
2020-06-10 17:52:36 -05:00
rtm516 a5eba85880
Add ServerPlayerListDataPacket to ignored packets (#755)
This packet handles the header and footer of the scoreboard, therefore this does not exist in bedrock.
2020-06-10 17:52:07 -05:00
Heath123 6e127edfd6
Stop using TrigMath class (#753)
* Stop using TrigMath class

* Use MathUtils
2020-06-09 14:50:21 +02:00
Camotoy 891490a443
Relocate Jackson dependency (#678) 2020-06-08 20:23:15 -05:00
Heath123 1da130ab07
Fix initial movement speed (#751)
Bedrock clients move very fast by default until they get an attribute packet correcting the speed.
2020-06-08 08:13:25 -04:00
Redned bafe7d430a
Update README to not include villager trading in what needs to be implemented 2020-06-06 13:15:54 -05:00
Redned 96d47548f7
Merge pull request #740 from GeyserMC/feature/villager-trading
Add villager trading support
2020-06-06 13:15:15 -05:00
DoctorMacc afb12e923b Show villager display name 2020-06-06 00:04:05 -04:00
DoctorMacc 4c5d80e2e9 Update to latest master 2020-06-05 22:52:11 -04:00
rtm516 ccb44f604e
Fix query not following normal MC standards (#736)
Changed the query token generation to generate a 4 byte int represented as a null terminated string
2020-06-04 20:04:38 -04:00
AJ Ferguson 1d8995efe6
Add minimum delay between closing and opening a new window (#735)
Should fix new windows not showing up with some plugins like Lottery.
2020-06-04 14:49:32 -04:00
Camotoy 69a4cd3860
Use static commit of MCProtocolLib (#734)
This prevents changes upstream from immediately affecting Geyser workflow. This also removes the CodeMC repository in favor of Jitpack (which can use the commit hash as a version).
2020-06-03 22:57:36 -04:00
rtm516 5fca5d5ef5
Fix position of non-marker invisible armour stands (#697)
This adds the height of the armour stand to the position if its invisible and not a marker to counteract the scale being 0 therefore having a wrong nametag position
2020-06-03 21:12:16 +01:00
rtm516 5eef265f80
Fix display of some more entities (#726)
* Fix display of Evoker and Evoker Fangs

* Fix spawner minecart display

* Centeralise custom blocks for spawner and furnace minecarts

* Add comment explaining class
2020-06-02 18:16:04 -05:00
rtm516 a91eaa7821
Add item name translation (#559)
* Added item name translation

* Change to more appropriate NPE catch

* Remove whitespace

* Switch from try/catch to null checking

* Update mappings

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-06-02 16:33:37 -04:00
AJ Ferguson 3d357af739
Inventory Fixes (#602)
* Fix edge case when shift clicking an output slot

* Don't send window close packet if window is already closed

* Limit amount of window close packets sent to the client

Fixes hidden inventory bar bug

* Restrict user from unusable chest inventory slots

* Fix crafting table slot mappings

* Always send cursor update
2020-06-02 08:48:26 -08:00
Camotoy 18891a22f1
Check for instance of TranslationMessage (#722)
Checks for class of custom name ID in case it's translation message.
2020-06-02 10:45:33 -04:00
AJ Ferguson 05024dde8c
Don't manually grab MCProtocolLib's dependencies (#720)
* Don't manually grab MCProtocolLib's dependencies

* Add netty-resolver-dns and exclude netty-all
2020-06-01 22:19:16 -04:00
rtm516 5bb345daa6
Fix new minecart with block breaking furnace minecart display (#717)
This handles DISPLAY_ITEM and related properties separately on furnace minecarts in order to prevent overwriting furnace minecart graphics.

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-06-01 15:59:46 -04:00
rtm516 ac5ab229f9
Fix Ender Crystal collision and explosion effects (#716)
Fixed the collision box being non-existent for ender crystals and fixed explosion effects not being displayed properly
2020-06-01 15:57:27 -04:00
Camotoy 215e5a7e21
Add custom minecart metadata (#713)
Adds display item, offset, and enable values.
2020-05-31 21:47:54 -04:00
rtm516 b8615874f9
Add furnace minecart (#712)
Adds the display of the furnace minecart, functions as expected.
2020-05-31 21:46:36 -04:00
Camotoy b8a3009c9d
Ignore all downstream packet errors (#693)
* Ignore all downstream packet errors

Instead of kicking the client off because of an error, we simply display a logger warning and suppress the error.

* If debug mode, print stacktrace
2020-05-30 17:31:20 -05:00
Camotoy 64e3204611
Implement translator for AdventureSettingsPacket (#691)
* Implement translator for AdventureSettingsPacket

The AdventureSettingsPacket is translated into ClientSettingsPacket so the MAY_FLY and FLYING flags are sent to the server. This fixes double-jumping on some servers that rely on the client sending their flying information through this packet.

* Remove top-secret code analysis
2020-05-29 18:56:21 -05:00
Heath123 5c8f6eb184
Fix relative teleports (#688) 2020-05-29 15:11:38 -04:00
rtm516 3f76ae1d48
Add ignore for ServerKeepAlivePacket (#664)
This packet is already handled by MCProtocolLib for us.

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-05-28 11:43:31 -04:00
rtm516 1a92f6974c
Add byte conversion to allow int NBT values for Fireworks (#681)
Firework NBT data might be either an int or byte and bedrock only takes it as a byte.

Co-authored-by: Arktisfox <65837019+Arktisfox@users.noreply.github.com>
2020-05-28 11:38:23 -04:00
DoctorMacc ccf9eff7ca Update workflow 2020-05-26 10:47:34 -04:00
DoctorMacc cae888eac9 Include PlatformType.java 2020-05-26 10:17:52 -04:00
DoctorMacc af669f2e88 Rename internal ping passthrough variable 2020-05-26 10:11:28 -04:00
DoctorMacc 2dc755ca98 Rename Geyser-Bukkit to Geyser-Spigot
Despite the Bukkit suffix being correct in terms of the API, the name causes some people to download CraftBukkit instead of Spigot or Paper. All internal references to Bukkit have been renamed to Spigot.
2020-05-26 10:05:25 -04:00
Camotoy 14fcd77925
Fix entities stacking on top of each other when mounted (#660)
The offset was being called but not properly saved to a variable. The check will also not apply if there is only one mounted entity.
2020-05-25 22:43:29 -05:00
bundabrg a929c411d2
Use authData UUID when sending playerlist packets to the client (#654)
Bedrock knows its own UUID and when it receives the Java uuid it will either crash (MCEE) or add a ghost player onto the playerlist (Bedrock).
This change will check if an entity is the client and if so replace the entities UUID with the AuthData UUID.

A refactor of JavaPlayerListEntryTranslator was also done as I got confused each time what it was doing so it is now hopefully a bit clearer and also fixes the case where an entity is removed but still exists on the server (Vanished).
2020-05-25 22:39:57 -05:00
bundabrg cc6c7fe78d
When spawning don't add the player offset (#655)
Fixes falling when logging in
2020-05-25 22:35:26 -05:00
Arktisfox 0178492b59
Fix some book translation failures (#661)
Book pages can be sent as plain text rather than JSON. The text library doesn't use lenient parsing, so this fails, and the book isn't visible in the inventory.

This will convert the text into JSON if it's not already, before feeding it to the text library.
2020-05-25 21:19:37 -04:00
rtm516 d0545c57c4
Fix some fireworks colors and NPE of there is no NBT (#650)
Adds Bukkit colors and an additional NPE check
2020-05-25 17:57:10 -04:00
RednedEpic 6b68bbb413 Large refactoring to item translator and registry/util classes
- Merged ItemTranslator and ItemStackTranslator together.
- Split ItemTranslator into two classes: ItemTranslator and ItemRegistry. The registry is where items are registered, and the translator class is where item translation takes place.
- Made most of ItemTranslator's methods static and removed the initialization in Toolbox.
- Moved a handful of registry classes previously ending with 'Utils' to a 'Registry' class to be more fitting for the term.
- Moved inventory and block entity registration out of Translators.
- Renamed Translators to PacketTranslatorRegistry.
- Yeeted Toolbox.
- Minor cleanups and small refactors.
2020-05-24 20:07:05 -05:00
RednedEpic 7154e1c816 Strip Minecraft identifier when playing non-mapped sounds to allow for bedrock-exclusive sounds to be played 2020-05-24 14:56:05 -05:00
rtm516 3a39e9afee
Added Crossbow nbt translator (#590)
They still infinitely reload but they correctly track if they have data in now.
2020-05-24 15:51:30 -04:00
RednedEpic 0215220ac1 Fix spectator mode 2020-05-24 14:46:36 -05:00
RednedEpic 56d84c24d3 Reduce nesting in item nbt translators 2020-05-24 14:21:06 -05:00
RednedEpic 6dabc22d22 Add null check for fireworks tag (Closes #636) 2020-05-24 13:20:38 -05:00
Arktisfox d918139c44
Check if firework item explosions tag is null (corresponding entity fix) (#633)
* Check if firework item explosions tag is null (corresponding entity fix)

* Add null check on flight

* Add null check around Flight

* Fix newline on if statement

* Fix newline on if statement, add null check on flight, remove debug code.

* fix missing space..
2020-05-24 13:15:02 -05:00
RednedEpic 286970676b Add null check for shield code (Fixes #644) 2020-05-24 13:06:25 -05:00
RednedEpic 259be96652 Update mappings submodule (Fixes #630) 2020-05-24 12:51:56 -05:00
RednedEpic 3d0dbff87b Remove effects on world/server change (Fixes #467)
The server re-sends these effects upon joining the new world or server.
2020-05-23 23:45:39 -05:00
RednedEpic 7f5414cdef Fix painting offset if height is equal to 3 (Fixes #629) 2020-05-23 23:27:16 -05:00
RednedEpic ebd88c76aa Don't delay item frame interactions
Causes interacting (moving) an item in an item frame to delay by about half a second. This delay is still present on chunk load where this delay is absolutely needed in order to the item frame to show up.
2020-05-23 23:14:29 -05:00
RednedEpic 681cbeeae5 Add armor stand entity offset (Fixes #627) 2020-05-23 22:45:34 -05:00
Camotoy fe6257bb38
Check if firework item explosions tag is null (#626) 2020-05-23 21:16:11 -04:00
RednedEpic a49f6fe0e3 Specify API version for Bukkit to stop legacy material loading (Closes #595) 2020-05-23 18:58:36 -05:00
RednedEpic 0574feb87e Fix block breaking animations when in water (Closes #494) 2020-05-23 18:29:11 -05:00
Camotoy 99f69b3a7d
Rewrite Ping Passthrough (#468)
* Fix ping passthrough on BungeeCord

* Initial implementation of direct ping passthrough

* Finished implementation of direct ping passthrough

* Remove test for something else entirely

* Fix standalone

* Add config option for ping passthrough interval

* Use GeyserPingInfo to reduce methods

* Add querying; modify ping passthrough

* Add separate config options for passthrough MOTD and player counts

* Convert all plugin bootstraps to use internal ping events to that other plugins can handle ping modifications

* Small changes

* Fix invalid packet spawm

* Add legacy ping passthrough option

* Fix BungeeCord

* Proper UUID for BungeeCord, thanks @theminecoder

* Update config version and messages

* Merge master... again

* Add missing javadocs and minor changes

Co-authored-by: James Harrison <james@fasttortoise.co.uk>
Co-authored-by: theminecoder <theminecoder.dev@gmail.com>
Co-authored-by: Redned <redned235@gmail.com>
2020-05-23 16:50:04 -05:00
Camotoy 59da87a10f
Merge entity mounts branch to master (#589)
* Initial support for entity mounts*

* This only works for viewing other players on mounts/vehicles. Currently, mounting on vehicles through Geyser with bedrock does not work at all, though, you can see other Java players on mounts just fine.

* Fix Bedrock player mounting; add minecart offset

* Remove debug code

* Fix boat animation

* Remove debug code

* Add notice of possible steering flip

* Add translator for PlayerInputPacket

* Upload WIP code for BoatEntity.java

* Add animation for rowing on Bedrock side

* Clean up debug code, start on boat movement

* Add notice about flying horses

* Rename BedrockPlayerInputPacket.java to BedrockPlayerInputTranslator.java

* Delete BedrockPlayerInputPacket.java

* Use Translator Annotation again; Thanks to LegacyGamerHD

* Upload ineffective mount-on-login code

* Upload current changes with no debug code

* Change case where applicable

* Change Integer[] to int[]; Change schedule() to execute()

* Don't use Thread.Sleep() and instead call itself again

* Fix players not being linked on login/chunk load

* Little changes

* Minor improvements/fixes to boats

* Remove empty file

* Fix horse flying.

* Various entity mounting fixes

* Add mounting offsets for skeleton and zombie horses

* Another round of entity mount-related fixes

- Add offsets for skeleton and zombie horses (Thanks to tester DirtNasty)
- Boats can now be placed in survival (Thanks again to tester DirtNasty)
- Boats and minecarts can now shake

* Add translating for ServerVehicleMovePacket

* Cleaning up

* More cleaning up

* Add interactive tag support for mountable entities

* Boats move far more nicely

* Add horse heart visuals

* Update interactive tags

Co-authored-by: RednedEpic <redned235@gmail.com>
2020-05-23 16:39:17 -05:00
rtm516 d8d9fb7190
Fireworks! (#579)
* Fixed firework entity

* Added firework item translator

* Fixed mappings submodule
2020-05-23 16:33:39 -05:00
Camotoy 22a1073e54
Debugging improvements (#585)
* Debugging improvements

- Added an ObjectArrayList of packets we don't anticipate ever translating. Currently only holds ServerUpdateLightPacket which we don't use and probably don't need.
- Only print debugging logs from sounds if they failed to play.

* Add space
2020-05-23 16:11:54 -05:00
Camotoy 714c450291
Add players able to sleep in beds (#575)
* Add players able to sleep in beds

This commit sets the correct metadata and flags when the Java pose changes to sleeping.

* Player view while sleeping now works

* Fixed bed offset for other players
2020-05-23 16:09:11 -05:00
rtm516 fc6532732d
Adds skin ears from MinecraftCapes.co.uk + Clientside linked account skins + Elytra textures (#539)
* Added ears geometry support

* Added ear fetching from mc capes

* Added support for deadmau5

* Commented, documented and cleaned code

* Allow bedrock players to see their java skin/cape/ears when joining

* Optimised Imports

* Fix missing else statement

* Moved ears and fixed elytra skins

* Added ears config option

* Fixed cape/elytra transparency

* Fixed slim skin geometry

* Fixed async ears request and added alex skin

* Fixed default elytra not showing with no cape

* Moved to normal Base64 functions

Co-authored-by: James Harrison <james@fasttortoise.co.uk>
2020-05-23 16:06:34 -05:00
Camotoy 1664221fa9
Add optional workaround for >Y128 Nether building (#615)
* Add optional workaround for >Y128 Nether building

This commit adds a config option for building above the Nether by changing the Nether's dimension ID to match the End's.

* Only check for workaround application once

* Fix mappings?

* Include a bit more for the above bedrock nether building config option

Co-authored-by: Redned <redned235@gmail.com>
2020-05-23 16:02:51 -05:00
rtm516 8f01221275
Updated to support latest MCProtocolLib (#623)
* Updated to support latest MCProtocolLib

* Cleaned up names and imports

* Fixed minecarts

* Fixed throwables

* Fixed tnt
2020-05-23 15:56:49 -05:00
OnlyBMan 81d3b0ef10
Fix painting rotation (#597)
* Fix painting rotation

* add comment and spacing

* Dont sleep everything :P

* Fix whitespace

* Remove whitespace

* Fix underlying issue

Instead of adding a delay, exclude Painting in HeadLookTranslator.java. Thanks AJ!

* Remove unneeded import

Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
2020-05-21 18:45:35 -05:00
Camotoy 61e0e796da
Fix /geyser offhand command on Bukkit (#611)
If CommandSender is not an instance of GeyserSession, we iterate through all GeyserSessions in order to find the sender.
2020-05-21 17:48:24 -05:00
Camotoy 93d15c16f5
Fix NPE if Bukkit configuration is out of date. (#614) 2020-05-21 10:29:32 -04:00
Camotoy a7f363ec09
Add option for disabling command suggestions; add config version (#598)
* Add option for disabling command suggestions; add config version

This commit adds an option for disabling command suggestions. If enabled, command suggestions will not be sent to the server so as to remove command freezing. This commit also adds a config version variable so users are notified when to regenerate their configs.

* Rename GeyserConfiguration.checkGeyserConfiguration()
2020-05-20 22:43:22 -05:00
Camotoy 83c7858a8c
Fix bug where online mode players couldn't move after logging in (#610) 2020-05-20 13:43:17 -04:00
Camotoy fbfc987d2b
Fix mapping for Burning Skull painting type (#608)
Otherwise, painting shows up as a 1x1 painting of another kind.
2020-05-20 12:40:07 -05:00
rtm516 18415d5d15
Fixed trident display and some arrow related cleanup (#609)
* Fixed trident display and some arrow related cleanup

* Renamed trident entity
2020-05-20 12:39:58 -05:00
Camotoy 1395b719cb
Add missing break to JavaEntityStatusTranslator (#600) 2020-05-20 10:12:31 -05:00
Creeperface01 5fe38fa83f
Show form window immediately after spawn (#606) 2020-05-20 10:12:03 -05:00
rtm516 3ab5c697c1
Updated mappings submodule (#596) 2020-05-19 21:39:10 +01:00
AJ Ferguson 2366559694 Store villager data in the player and fix wandering trader 2020-05-19 09:41:44 -08:00
AJ Ferguson 95297e4047 Update villager xp while trading 2020-05-19 07:28:33 -08:00
AJ Ferguson e2d46c3d49 Work on villager trading 2020-05-18 21:15:29 -08:00
rtm516 c0f678a8af
Added a docker container IP warning (#584)
* Added a docker container IP warning

* Corrected messages

* Moved to normal java file read instead of starting cat

* Fixed capitalisation on method name
2020-05-18 22:27:35 -05:00
Camotoy fd36930502
Add entity event for drowning. (#588)
This commit translates Java's LIVING_DROWN entity status to Bedrock's HURT_ANIMATION.
2020-05-18 22:26:27 -05:00
OnlyBMan fc5230c248
Add firework boost for elytras (#552)
* Add firework boost for elytras!

* Change how to detect player glide

* Add comments explaining code

* Remove unused ID
2020-05-18 10:46:35 -04:00
Camotoy 31d3d2e289
Add some elder guardian properties (#586)
- Adds the ELDER flag to all elder guardians, so they look like elder guardians and not giant regular guardians.
- Translates AFFECTED_BY_ELDER_GUARDIAN in JavaNotifyClientTranslator to add the elder guardian curse event.
2020-05-17 23:35:26 -05:00
rtm516 405ffb2666
Added mob spawner block entity data (#587) 2020-05-17 23:35:01 -05:00
rtm516 43ee7d6027
Fixed creepers, giants and eye of ender (#578) 2020-05-17 01:26:13 -05:00
RednedEpic b0d0c168d2 Fix bossbar causing players to be unable to break blocks or interact in small areas (Closes #537) 2020-05-17 01:06:07 -05:00
Camotoy 57717795a3
Add enchantment table book on chunk load (#568)
Java's block entity ID is enchantment_table whereas Bedrock's is EnchantTable; this commit adds an exception to the block entity regex as such.
2020-05-16 23:59:03 -05:00
rtm516 95b7055c10
Added map icons (#572)
* Added map icons

* Cleaned up and moved to enum
2020-05-16 23:58:00 -05:00
Camotoy 563cde2ade
Switch to client's translation for jukebox song name. (#573)
Just for consistency with the other part of the code.
2020-05-16 23:57:34 -05:00
rtm516 3220532083
Fixed fishing rod lines not connecting to other players (#580) 2020-05-16 23:57:18 -05:00
RednedEpic 30e38b3a2f Add basic villager trading support (incomplete)
This commit implements basic functionality for villager trading. This is still incomplete and is buggy in areas such as with villager trades that have more than one input and trade inputs and outputs containing NBT.

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
2020-05-16 23:52:39 -05:00
Camotoy b4ecb88d49 Add air bubble UI support (#569)
This commit translates entity metadata ID 1 into the AIR entity metadata.
2020-05-15 15:29:54 -05:00
Camotoy 1b260c16d7
Leash fixes (#567)
* Leash fixes

- Adds visuals for leash string by translating ServerEntityAttachPacket
- Updates position offset for lead knots, making them properly appear on fences

* Add basic description of JavaEntityAttachTranslator
2020-05-15 12:50:34 -05:00
rtm516 2830756a55
Fixed unusable space being off by 1 (#561) 2020-05-15 11:08:44 -05:00
rtm516 919af5203d
Fix banner items loosing patterns in inventory (#560) 2020-05-14 19:41:42 -05:00
Camotoy d4995acec6
Add support for absorption (golden hearts) (#553)
Absorption is an attribute in Bedrock and an entity metadata value in Java. This commit sends an attribute update packet when the metadata value is updated.
2020-05-14 11:30:33 -05:00
Redned c6527fa723
Update README.md 2020-05-13 17:53:13 -05:00
Camotoy d5c14921e9
Add message when playing record (#549)
It appears that the record message is client-sided in Java Edition, so this sends a message whenever a record is played in-world.
2020-05-13 16:08:52 -05:00
Camotoy 278f59103e
Replace illusioners with pillagers (#550)
Illusioners do not exist in Bedrock edition; this commit replaces them with pillagers so they can be somewhat replicated.
2020-05-13 16:08:32 -05:00
rtm516 6aadfb3a63
Fixed wither shield (#544) 2020-05-13 16:08:14 -05:00
Camotoy 9673e1e4aa
Use ViaVersion for block placing sounds (#551)
GeyserBukkitBlockPlaceListener previous assumed that getBlockData() was available. This separates the ViaVersion code from getBlockAt to make it accessible elsewhere.
2020-05-13 16:07:41 -05:00
rtm516 46b0054435
Fixed guardian beam getting stuck on players (#540)
* Fixed guardian beam getting stuck on players

* Fixed formatting
2020-05-12 21:31:42 -05:00
Camotoy d63d0def5a
Break for loop in GeyserBukkitBlockPlaceListener when a player is found (#538)
No need to keep searching when a player is found.
2020-05-12 14:59:28 -05:00
rtm516 0c60af66b2
Fixed customised skins causing strange display (#534)
* Fixed customised skins causing strange display

* Cleaned up floodgate player checking

* Fixed cape scale

Co-authored-by: James Harrison <james@fasttortoise.co.uk>
2020-05-11 23:45:16 -05:00
rtm516 c84c0f23cb
Fixed invisible flag not getting set back (#535)
* Fixed invisible flag not getting set back

* Fixed indentation
2020-05-11 23:44:30 -05:00
rtm516 324bc67c97
Fixed small armour stands not respecting invisibility (#533) 2020-05-11 14:56:50 -05:00
rtm516 f9ee569cd5
Various entity fixes (#529)
* Fixed invisible entities nametags being displayed

* Fixed most entity collision boxes

* Fixed area effect cloud not displaying

* Fixed armour stand size and marker

* Fix baby collision boxes

* Fixed squid animation (rotation still broken)

* Fix Guardian beam for local player

* Fixed armour stand invisibility

* Fixed Wither boss data

* Fixed  fishing line attach to entities
2020-05-11 00:09:16 -05:00
Camotoy 64bfad2af9
Use Bukkit methods to send block sound (#522) 2020-05-10 15:25:28 -05:00
Heath123 720ae3c92d
Add survival-style block pick support (#526)
* Add survival-style block pick support

* Add BedrockBlockPickRequestPacketTranslator.java

* Remove unnecessary println

* Edit styling and add null check

* Fix compile error

* Remove nesting and unnecessary check

* Further reduce nesting

* Change 1-line statements and add missing comment

* Fix creating translator

* Fix imports
2020-05-10 15:05:51 -05:00
RednedEpic cf63098864 Add Windows Phone in DeviceOS (Fixes #520) 2020-05-10 15:03:12 -05:00
RednedEpic d2a18f8fd5 Remove dangling entity link packet in PlayerEntity for parrots 2020-05-10 14:47:40 -05:00
Camotoy 6192237cc9
Add parrots on player shoulders (#530)
* Add parrots on player shoulders

Parrots on player shoulders are a separate entity in Bedrock, but part of the player metadata in Java. This commit creates a parrot entity from the NBT data given by the player's entity data.

* Remove unused import

* Nullify parrot after despawning

* Remove debug code
2020-05-10 14:38:39 -05:00
Camotoy 34d4817795
Add visual support for double chests (#523)
* Add visual support for double chests

* Update mappings submodule
2020-05-10 14:26:00 -05:00
Camotoy d4291888b3
Fallback to ViaVersion to convert block state (#515)
* Fallback to ViaVersion to convert block state

* Use ViaVersion 3.0.0-SNAPSHOT

* Detect versions better; change logic for getting blocks
2020-05-09 21:37:18 -05:00
rtm516 7b3893ff78
Fixed empty listen IPs breaking automatic config (#519) 2020-05-08 22:58:29 -05:00
RednedEpic e58ffdd3c0 Add support for block break animations from java players to bedrock 2020-05-08 00:18:05 -05:00
RednedEpic edc8ea998c Add slime and magma cube size support 2020-05-07 22:57:08 -05:00
James Harrison 2355c503c9
Enderchest and Invisible Players fix. (#506)
* Fix EnderChests not showing on legacy servers (Hypixel)
Fix NPCs/Players sometimes being invisible

* Remove unused import

* Fix standard
2020-05-07 21:49:44 -05:00
Camotoy f11bae0bf0
Fix signs (#439)
* Fix signs on everything except Paper

* Fix sign line placement

* Update shulker box block entity

Co-authored-by: James Harrison <james@fasttortoise.co.uk>
2020-05-06 16:52:57 -05:00
rtm516 5ae95433e5
Bedrock to Bedrock legacy skin support (#276)
* Added legacy skin support for bedrock to bedrock clients

* Added bedrock to bedrock cape handling

* Added bedrock geometry support

* Bedrock skins now work in all auth modes

* Tonne of debug info

* Added fix to prevent customised skins from being loaded

* Added skin size to bedrock client data

* Cleaned debugging code

* Made bedrock cape take priority over third party

* Cut the customised skin image in half to hopefully get it to map

* Removed hacky conversion attempt

* Fixed bedrock skin caching on load and 1.14.60 support

* Cleaned up debug messages

* Added linked player ignore
2020-05-06 16:50:01 -05:00
Luke 4c1dae6714
Add unusable inventory space message (#492)
* Add unusable inventory space message

* Remove unused imports

* Fixed barrier pickup (#1)

Co-authored-by: rtm516 <rtm516@users.noreply.github.com>
2020-05-06 16:05:03 -05:00
Chase MacDonnell 425df396cb
Don't load floodgate if it isn't needed (velocity) (#499)
Co-authored-by: Chase M <1860157-chasemacdonnell@users.noreply.gitlab.com>
2020-05-06 16:02:52 -05:00
Camotoy 48147c2ce3
Fix Floodgate players causing errors on Bukkit. (#490)
Co-authored-by: Tim203 <mctim203@gmail.com>
2020-05-05 12:53:25 -05:00
Luke 7195d20fae
Implement helper methods for sending packets (#487)
* Implement helper methods for sending packets, fixes an NPE when chatting before connecting to the remote server

* Change method names

* Add a space between doc comment lines

* Add debug messages
2020-05-05 10:51:43 -05:00
rtm516 96a7770c22
Fixed entity bugs introduced by 6642f1e and added fishing lines (#483)
* Fixed entity bugs introduced by 6642f1e

* Fixed fishing line not displaying

* Clean extra line and added todo
2020-05-05 10:48:01 -05:00
557 changed files with 35006 additions and 13763 deletions

2
.github/FUNDING.yml vendored
View File

@ -1,7 +1,7 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: GeyserMC
patreon: #GeyserMC # Disabled currently
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel

View File

@ -7,34 +7,51 @@ assignees: ''
---
<!--- DELETING THIS TEMPLATE WILL GET YOUR ISSUE CLOSED! --->
<!--- Please follow this format COMPLETELY and make sure the bug you are reporting has not been reported yet. Reports should contain as much information or context as possible to help us find the problem. Simply creating an issue on a vague topic will not help us at all, and if you are unsure if something should belong here, please contact us on [Discord](http://discord.geysermc.org).-->
<!--- Issues pertaining to connection problem, or anything of that covered on the [Common Issues](https://github.com/GeyserMC/Geyser/wiki/Common-Issues) do not belong here and only clutter this issue tracker. -->
<!--- Issues pertaining to connection problems, or anything of that covered on the [Common Issues](https://github.com/GeyserMC/Geyser/wiki/Common-Issues) do not belong here and only clutter this issue tracker. -->
**Describe the bug**
<!--- A clear and concise description of what the bug is. -->
A clear and concise description of what the bug is.
**To Reproduce**
<!--- Steps to reproduce the behavior: -->
<!--- 1. Go to '...' -->
<!--- 2. Click on '....' -->
<!--- 3. Scroll down to '....' -->
<!--- 4. See error -->
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
<!--- A clear and concise description of what you expected to happen. -->
A clear and concise description of what you expected to happen.
**Screenshots / Videos**
<!--- If applicable, add screenshots to help explain your problem. -->
**Server Version**
<!--- Give us the exact output from /version. Saying "latest" does not help us at all. -->
If applicable, add screenshots to help explain your problem.
**Geyser Version**
<!--- Give us the exact build number as well as branch if applicable. Saying "latest" does not help us at all. Please also include if you are running the standalone version, or specify which plugin version you are using. If your issue is a connection problem, please specify if you are using the Floodgate plugin. -->
**Server Version and Plugins**
If you just run Geyser-Spigot, you can leave this area blank as the next section covers this information.
If you're running a multi-server instance, or using Geyser Standalone:
- Give us the exact output from `/version` on all servers involved. Saying "latest" does not help us at all.
- Please list all plugins on all servers involved.
If this bug occurs on a server you do not control, please fill this in to the best of your knowledge.
**Geyser Dump**
If Geyser starts correctly, please also include the link to a dump by using `/geyser dump`. If you use the Standalone GUI, the option can be found under `Commands` => `Dump`. This provides us information about your server that we can use to debug your issue.
**Minecraft: Bedrock Edition Version**
<!-- The version of your Minecraft: Bedrock Edition client you tested with. -->
The version of your Minecraft: Bedrock Edition client you tested with, along with your device type (e.g. Windows 10, Switch...).
**Additional Context**
<!--- Add any other context about the problem here. Include any plugins on the Minecraft server that may cause problems. --->
Add any other context about the problem here.

View File

@ -11,4 +11,4 @@ assignees: ''
Add a description
**Alternatives?**
Any alternatives you have tryed
List any alternatives you might have tried

View File

@ -8,8 +8,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/cache@v1
- uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
@ -22,33 +22,33 @@ jobs:
- name: submodules-init
uses: snickerbockers/submodules-init@v4
- name: Build with Maven
run: mvn -B package
run: mvn -B package -T 2C
- name: Archive artifacts (Geyser Standalone)
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
if: success()
with:
name: Geyser Standalone
path: bootstrap/standalone/target/Geyser.jar
- name: Archive artifacts (Geyser Bukkit)
uses: actions/upload-artifact@v1
- name: Archive artifacts (Geyser Spigot)
uses: actions/upload-artifact@v2
if: success()
with:
name: Geyser Bukkit
path: bootstrap/bukkit/target/Geyser-Bukkit.jar
name: Geyser Spigot
path: bootstrap/spigot/target/Geyser-Spigot.jar
- name: Archive artifacts (Geyser BungeeCord)
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
if: success()
with:
name: Geyser BungeeCord
path: bootstrap/bungeecord/target/Geyser-BungeeCord.jar
- name: Archive artifacts (Geyser Sponge)
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
if: success()
with:
name: Geyser Sponge
path: bootstrap/sponge/target/Geyser-Sponge.jar
- name: Archive artifacts (Geyser Velocity)
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
if: success()
with:
name: Geyser Velocity

41
.gitignore vendored
View File

@ -1,6 +1,6 @@
# Created by https://www.gitignore.io/api/git,java,maven,eclipse,netbeans,jetbrains+all
# Edit at https://www.gitignore.io/?templates=git,java,maven,eclipse,netbeans,jetbrains+all
# Created by https://www.gitignore.io/api/git,java,maven,eclipse,netbeans,jetbrains+all,visualstudiocode
# Edit at https://www.gitignore.io/gitignore?templates=git,java,maven,eclipse,netbeans,jetbrains+all,visualstudiocode
### Eclipse ###
.metadata
@ -53,22 +53,19 @@ local.properties
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
### Eclipse Patch ###
# Eclipse Core
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Annotation Processing
.apt_generated
### Eclipse Patch ###
# Spring Boot Tooling
.sts4-cache/
### Git ###
@ -112,7 +109,7 @@ local.properties
hs_err_pid*
### JetBrains+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
@ -142,6 +139,9 @@ hs_err_pid*
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
@ -207,6 +207,7 @@ release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
### NetBeans ###
@ -219,7 +220,20 @@ dist/
nbdist/
.nb-gradle/
# End of https://www.gitignore.io/api/git,java,maven,eclipse,netbeans,jetbrains+all
### VisualStudioCode ###
# Note: Manually edited to remove settings files
.vscode/*
# !.vscode/settings.json
# !.vscode/tasks.json
# !.vscode/launch.json
# !.vscode/extensions.json
# *.code-workspace
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
# End of https://www.gitignore.io/api/git,java,maven,eclipse,netbeans,jetbrains+all,visualstudiocode
### Geyser ###
run/
@ -227,3 +241,6 @@ config.yml
logs/
public-key.pem
locales/
/cache/
/packs/
/dump.json

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "connector/src/main/resources/mappings"]
path = connector/src/main/resources/mappings
url = https://github.com/GeyserMC/mappings.git
[submodule "connector/src/main/resources/languages"]
path = connector/src/main/resources/languages
url = https://github.com/GeyserMC/languages.git

View File

@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (c) 2019-&amp;#36;today.year GeyserMC. http://geysermc.org&#10; &#10; Permission is hereby granted, free of charge, to any person obtaining a copy&#10; of this software and associated documentation files (the &quot;Software&quot;), to deal&#10; in the Software without restriction, including without limitation the rights&#10; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10; copies of the Software, and to permit persons to whom the Software is&#10; furnished to do so, subject to the following conditions:&#10; &#10; The above copyright notice and this permission notice shall be included in&#10; all copies or substantial portions of the Software.&#10; &#10; THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10; THE SOFTWARE.&#10; &#10; @author GeyserMC&#10; @link https://github.com/GeyserMC/Geyser&#10; " />
<option name="notice" value="Copyright (c) 2019-&amp;#36;today.year GeyserMC. http://geysermc.org&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE.&#10;&#10;@author GeyserMC&#10;@link https://github.com/GeyserMC/Geyser" />
<option name="myName" value="Geyser" />
</copyright>
</component>

View File

@ -1 +1,44 @@
When contributing, please remember to read wiki about the api. Learn Steivice10's library and the nukkit protocol library if you are editing any core classes. Keep your code clean and readable, and please be mindful of fil conflicts. If you need help, join our discord. Other than that, you're all set!
Thank for for considering a contribution! Generally, Geyser welcomes PRs from everyone. There are some guidelines about what features should go where:
*Pull requests that may not get accepted:* Niche features that apply to a specific group, for example integration with a specific plugin. For now, please create a separate plugin if possible.
*Pull requests for Floodgate:* Anything that opens up information within the game for developers to use.
*Pull requests for Geyser:* Anything that fixes compatibility between Java or Bedrock, or improves the quality of play for Bedrock players. The exception is wherever direct server access is required; in this case it may be better for Floodgate.
We have some general style guides that should be applied throughout the code:
```java
private static final AIR_ITEM = 0; // Static item names should be capitalized
public Int2IntMap items = new Int2IntOpenHashMap(); // Use the interface as the class type but initialize with the implementation.
public int nameWithMultipleWords = 0;
/**
* Javadoc comment to explain what a function does.
*/
public void applyStuff() {
if (condition) {
// Do stuff.
} else if (anotherCondition) {
// Do something else.
}
switch (value) {
case 0:
break;
case 1:
break:
}
}
```
Make sure to comment your code where possible.
The nature of our software requires a lot of arrays and maps to be stored - where possible, use Fastutil's specialized maps. For example, if you're storing block state translations, use an `Int2IntMap`.
We have a rundown of all the tools you need to develop over on our [wiki](https://github.com/GeyserMC/Geyser/wiki/Developer-Guide). If you have any questions, please feel free to reach out to our [Discord](https://discord.geysermc.org)!

66
Jenkinsfile vendored
View File

@ -5,7 +5,7 @@ pipeline {
jdk 'Java 8'
}
options {
buildDiscarder(logRotator(artifactNumToKeepStr: '5'))
buildDiscarder(logRotator(artifactNumToKeepStr: '20'))
}
stages {
stage ('Build') {
@ -24,17 +24,77 @@ pipeline {
when {
branch "master"
}
steps {
sh 'mvn javadoc:jar source:jar deploy -DskipTests'
rtMavenDeployer(
id: "maven-deployer",
serverId: "opencollab-artifactory",
releaseRepo: "maven-releases",
snapshotRepo: "maven-snapshots"
)
rtMavenResolver(
id: "maven-resolver",
serverId: "opencollab-artifactory",
releaseRepo: "release",
snapshotRepo: "snapshot"
)
rtMavenRun(
pom: 'pom.xml',
goals: 'javadoc:jar source:jar install -DskipTests',
deployerId: "maven-deployer",
resolverId: "maven-resolver"
)
rtPublishBuildInfo(
serverId: "opencollab-artifactory"
)
}
}
}
post {
always {
script {
def changeLogSets = currentBuild.changeSets
def message = "**Changes:**"
if (changeLogSets.size() == 0) {
message += "\n*No changes.*"
} else {
def repositoryUrl = scm.userRemoteConfigs[0].url.replace(".git", "")
def count = 0;
def extra = 0;
for (int i = 0; i < changeLogSets.size(); i++) {
def entries = changeLogSets[i].items
for (int j = 0; j < entries.length; j++) {
if (count <= 10) {
def entry = entries[j]
def commitId = entry.commitId.substring(0, 6)
message += "\n - [`${commitId}`](${repositoryUrl}/commit/${entry.commitId}) ${entry.msg}"
count++
} else {
extra++;
}
}
}
if (extra != 0) {
message += "\n - ${extra} more commits"
}
}
env.changes = message
}
deleteDir()
withCredentials([string(credentialsId: 'geyser-discord-webhook', variable: 'DISCORD_WEBHOOK')]) {
discordSend description: "**Build:** [${currentBuild.id}](${env.BUILD_URL})\n**Status:** [${currentBuild.currentResult}](${env.BUILD_URL})\n\n[**Artifacts on Jenkins**](https://ci.nukkitx.com/job/Geyser)", footer: 'NukkitX Jenkins', link: env.BUILD_URL, successful: currentBuild.resultIsBetterOrEqualTo('SUCCESS'), title: "${env.JOB_NAME} #${currentBuild.id}", webhookURL: DISCORD_WEBHOOK
discordSend description: "**Build:** [${currentBuild.id}](${env.BUILD_URL})\n**Status:** [${currentBuild.currentResult}](${env.BUILD_URL})\n${changes}\n\n[**Artifacts on Jenkins**](https://ci.opencollab.dev/job/GeyserMC/job/Geyser)", footer: 'Open Collaboration Jenkins', link: env.BUILD_URL, successful: currentBuild.resultIsBetterOrEqualTo('SUCCESS'), title: "${env.JOB_NAME} #${currentBuild.id}", webhookURL: DISCORD_WEBHOOK
}
}
success {
script {
if (env.BRANCH_NAME == 'master') {
build propagate: false, wait: false, job: 'GeyserMC/Geyser-Fabric/java-1.16'
build propagate: false, wait: false, job: 'GeyserMC/GeyserAndroid/master'
}
}
}
}

View File

@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,19 +1,24 @@
<img src="https://geysermc.org/img/geyserlogo.png" alt="Geyser" width="600"/>
<img src="https://geysermc.org/img/geyser-1760-860.png" alt="Geyser" width="600"/>
[![forthebadge made-with-java](http://ForTheBadge.com/images/badges/made-with-java.svg)](https://java.com/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Build Status](https://ci.nukkitx.com/job/Geyser/job/master/badge/icon)](https://ci.nukkitx.com/job/Geyser/job/master/)
[![Build Status](https://ci.opencollab.dev/job/Geyser/job/master/badge/icon)](https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/master/)
[![Discord](https://img.shields.io/discord/613163671870242838.svg?color=%237289da&label=discord)](http://discord.geysermc.org/)
[![HitCount](http://hits.dwyl.io/Geyser/GeyserMC.svg)](http://hits.dwyl.io/Geyser/GeyserMC)
[![Crowdin](https://badges.crowdin.net/geyser/localized.svg)](https://translate.geysermc.org/)
Geyser is a bridge between Minecraft: Bedrock Edition and Minecraft: Java Edition, closing the gap from those wanting to play true cross-platform.
Geyser is an open collaboration project by [CubeCraft Games](https://cubecraft.net).
## What is Geyser?
Geyser is a proxy, bridging the gap between Minecraft: Bedrock Edition and Minecraft: Java Edition servers.
The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible. **Please note, this project is still a work in progress and should not be used on production. Expect bugs!**
### Currently supporting Minecraft Bedrock v1.14.6(0) and Minecraft Java v1.15.2.
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here!
### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.201 and Minecraft Java v1.16.4.
## Setting Up
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.
@ -25,16 +30,30 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set
- Docs: https://github.com/GeyserMC/Geyser/wiki
- Download: http://ci.geysermc.org
- Discord: http://discord.geysermc.org/
- Donate: https://patreon.com/GeyserMC
- ~~Donate: https://patreon.com/GeyserMC~~ Currently disabled.
- Test Server: `test.geysermc.org` port `25565` for Java and `19132` for Bedrock
## What's Left to be Added/Fixed
- The Following Inventories
- [ ] Enchantment Table
- [ ] Beacon
- [ ] Cartography Table
- [ ] Stonecutter
- [ ] Villager Trading
- Lecterns
- Near-perfect movement (to the point where anticheat on large servers is unlikely to ban you)
- Resource pack conversion/CustomModelData
- Some Entity Flags
- The Following Inventories
- Enchantment Table (as a proper GUI)
- Beacon
- Cartography Table
- Stonecutter
- Structure Block
- Horse Inventory
- Loom
- Smithing Table
## What can't be fixed
The following things can't be fixed because of Bedrock limitations. They might be fixable in the future, but not as of now.
- Custom heads in inventories
- Clickable links in chat
- Glowing effect
## Compiling
1. Clone the repo to your computer

View File

@ -1,206 +0,0 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bukkit;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.Plugin;
import org.geysermc.connector.FloodgateKeyLoader;
import org.geysermc.connector.GeyserConfiguration;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class GeyserBukkitConfiguration implements GeyserConfiguration {
private FileConfiguration config;
private File dataFolder;
private BukkitBedrockConfiguration bedrockConfig;
private BukkitRemoteConfiguration remoteConfig;
private BukkitMetricsInfo metricsInfo;
private Map<String, BukkitUserAuthenticationInfo> userAuthInfo = new HashMap<>();
private Path floodgateKey;
public GeyserBukkitConfiguration(File dataFolder, FileConfiguration config) {
this.dataFolder = dataFolder;
this.config = config;
bedrockConfig = new BukkitBedrockConfiguration();
remoteConfig = new BukkitRemoteConfiguration();
metricsInfo = new BukkitMetricsInfo();
if (!config.contains("userAuths"))
return;
for (String key : config.getConfigurationSection("userAuths").getKeys(false)) {
userAuthInfo.put(key, new BukkitUserAuthenticationInfo(key));
}
}
public void loadFloodgate(GeyserBukkitPlugin plugin) {
Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate-bukkit");
floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), config.getString("floodgate-key-file", "public-key.pem")), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null);
}
@Override
public IBedrockConfiguration getBedrock() {
return bedrockConfig;
}
@Override
public IRemoteConfiguration getRemote() {
return remoteConfig;
}
@Override
public Map<String, BukkitUserAuthenticationInfo> getUserAuths() {
return userAuthInfo;
}
@Override
public boolean isPingPassthrough() {
return config.getBoolean("ping-passthrough", false);
}
@Override
public int getMaxPlayers() {
return config.getInt("max-players", 10);
}
@Override
public boolean isDebugMode() {
return config.getBoolean("debug-mode", false);
}
@Override
public int getGeneralThreadPool() {
return config.getInt("general-thread-pool", 32);
}
@Override
public boolean isAllowThirdPartyCapes() {
return config.getBoolean("allow-third-party-capes", true);
}
@Override
public String getDefaultLocale() {
return config.getString("default-locale", "en_us");
}
@Override
public Path getFloodgateKeyFile() {
return floodgateKey;
}
@Override
public boolean isCacheChunks() {
return true; // We override this as with Bukkit, we have direct access to the server implementation
}
@Override
public IMetricsInfo getMetrics() {
return metricsInfo;
}
public class BukkitBedrockConfiguration implements IBedrockConfiguration {
@Override
public String getAddress() {
return config.getString("bedrock.address", "0.0.0.0");
}
@Override
public int getPort() {
return config.getInt("bedrock.port", 25565);
}
@Override
public String getMotd1() {
return config.getString("bedrock.motd1", "GeyserMC");
}
@Override
public String getMotd2() {
return config.getString("bedrock.motd2", "GeyserMC");
}
}
public class BukkitRemoteConfiguration implements IRemoteConfiguration {
@Override
public String getAddress() {
return config.getString("remote.address", "127.0.0.1");
}
@Override
public int getPort() {
return config.getInt("remote.port", 25565);
}
@Override
public String getAuthType() {
return config.getString("remote.auth-type", "online");
}
}
public class BukkitUserAuthenticationInfo implements IUserAuthenticationInfo {
private String key;
public BukkitUserAuthenticationInfo(String key) {
this.key = key;
}
@Override
public String getEmail() {
return config.getString("userAuths." + key + ".email");
}
@Override
public String getPassword() {
return config.getString("userAuths." + key + ".password");
}
}
public class BukkitMetricsInfo implements IMetricsInfo {
@Override
public boolean isEnabled() {
return config.getBoolean("metrics.enabled", true);
}
@Override
public String getUniqueId() {
return config.getString("metrics.uuid", "generateduuid");
}
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*
*/
package org.geysermc.platform.bukkit;
import org.geysermc.common.main.IGeyserMain;
public class GeyserBukkitMain extends IGeyserMain {
public static void main(String[] args) {
new GeyserBukkitMain().displayMessage();
}
public String getPluginType() {
return "Spigot or Paper (recommended)";
}
public String getPluginFolder() {
return "plugins";
}
}

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bukkit;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.bootstrap.GeyserBootstrap;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.network.translators.world.WorldManager;
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor;
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager;
import org.geysermc.platform.bukkit.world.GeyserBukkitWorldManager;
import java.util.UUID;
public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
private GeyserBukkitCommandManager geyserCommandManager;
private GeyserBukkitConfiguration geyserConfig;
private GeyserBukkitLogger geyserLogger;
private GeyserBukkitWorldManager geyserWorldManager;
private GeyserConnector connector;
@Override
public void onEnable() {
saveDefaultConfig();
this.geyserConfig = new GeyserBukkitConfiguration(getDataFolder(), getConfig());
if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) {
getConfig().set("metrics.uuid", UUID.randomUUID().toString());
saveConfig();
}
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!Bukkit.getIp().equals("0.0.0.0")) {
getConfig().set("remote.address", Bukkit.getIp());
}
getConfig().set("remote.port", Bukkit.getPort());
saveConfig();
this.geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode());
geyserConfig.loadFloodgate(this);
this.connector = GeyserConnector.start(PlatformType.BUKKIT, this);
this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector);
this.geyserWorldManager = new GeyserBukkitWorldManager();
this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector));
}
@Override
public void onDisable() {
connector.shutdown();
}
@Override
public GeyserBukkitConfiguration getGeyserConfig() {
return geyserConfig;
}
@Override
public GeyserBukkitLogger getGeyserLogger() {
return geyserLogger;
}
@Override
public CommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
@Override
public WorldManager getWorldManager() {
return this.geyserWorldManager;
}
}

View File

@ -6,21 +6,21 @@
<parent>
<groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../</relativePath>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>bootstrap-bungeecord</artifactId>
<dependencies>
<dependency>
<groupId>org.geysermc</groupId>
<artifactId>connector</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.14-SNAPSHOT</version>
<version>1.15-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@ -61,10 +61,34 @@
<pattern>net.md_5.bungee.jni</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.jni</shadedPattern>
</relocation>
<relocation>
<pattern>com.fasterxml.jackson</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.jackson</shadedPattern>
</relocation>
<relocation>
<pattern>io.netty</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.netty</shadedPattern>
</relocation>
<relocation>
<pattern>org.reflections</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.reflections</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.google.common</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.guava</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.google.guava</shadedPattern>
</relocation>
<relocation>
<pattern>org.dom4j</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.dom4j</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori</pattern>
<shadedPattern>org.geysermc.platform.bungeecord.shaded.kyori</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
@ -80,4 +104,4 @@
</plugin>
</plugins>
</build>
</project>
</project>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,181 +25,26 @@
package org.geysermc.platform.bungeecord;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.config.Configuration;
import org.geysermc.connector.FloodgateKeyLoader;
import org.geysermc.connector.GeyserConfiguration;
import org.geysermc.connector.configuration.GeyserJacksonConfiguration;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class GeyserBungeeConfiguration implements GeyserConfiguration {
private File dataFolder;
private Configuration config;
private BungeeBedrockConfiguration bedrockConfig;
private BungeeRemoteConfiguration remoteConfig;
private BungeeMetricsInfo metricsInfo;
private Map<String, BungeeUserAuthenticationInfo> userAuthInfo = new HashMap<>();
private Path floodgateKey;
public GeyserBungeeConfiguration(File dataFolder, Configuration config) {
this.dataFolder = dataFolder;
this.config = config;
bedrockConfig = new BungeeBedrockConfiguration();
remoteConfig = new BungeeRemoteConfiguration();
metricsInfo = new BungeeMetricsInfo();
if (!config.contains("userAuths"))
return;
for (String key : config.getSection("userAuths").getKeys()) {
userAuthInfo.put(key, new BungeeUserAuthenticationInfo(key));
}
}
@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
public final class GeyserBungeeConfiguration extends GeyserJacksonConfiguration {
@JsonIgnore
private Path floodgateKeyPath;
public void loadFloodgate(GeyserBungeePlugin plugin) {
Plugin floodgate = plugin.getProxy().getPluginManager().getPlugin("floodgate-bungee");
floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), config.getString("floodgate-key-file", "public-key.pem")), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null);
}
Path geyserDataFolder = plugin.getDataFolder().toPath();
Path floodgateDataFolder = floodgate != null ? floodgate.getDataFolder().toPath() : null;
@Override
public BungeeBedrockConfiguration getBedrock() {
return bedrockConfig;
}
@Override
public BungeeRemoteConfiguration getRemote() {
return remoteConfig;
}
@Override
public Map<String, BungeeUserAuthenticationInfo> getUserAuths() {
return userAuthInfo;
}
@Override
public boolean isPingPassthrough() {
return config.getBoolean("ping-passthrough", false);
}
@Override
public int getMaxPlayers() {
return config.getInt("max-players", 10);
}
@Override
public boolean isDebugMode() {
return config.getBoolean("debug-mode", false);
}
@Override
public int getGeneralThreadPool() {
return config.getInt("general-thread-pool", 32);
}
@Override
public boolean isAllowThirdPartyCapes() {
return config.getBoolean("allow-third-party-capes", true);
}
@Override
public String getDefaultLocale() {
return config.getString("default-locale", "en_us");
}
@Override
public Path getFloodgateKeyFile() {
return floodgateKey;
}
@Override
public boolean isCacheChunks() {
return config.getBoolean("cache-chunks", false);
}
@Override
public BungeeMetricsInfo getMetrics() {
return metricsInfo;
}
public class BungeeBedrockConfiguration implements IBedrockConfiguration {
@Override
public String getAddress() {
return config.getString("bedrock.address", "0.0.0.0");
}
@Override
public int getPort() {
return config.getInt("bedrock.port", 25565);
}
@Override
public String getMotd1() {
return config.getString("bedrock.motd1", "GeyserMC");
}
@Override
public String getMotd2() {
return config.getString("bedrock.motd2", "GeyserMC");
}
}
public class BungeeRemoteConfiguration implements IRemoteConfiguration {
@Override
public String getAddress() {
return config.getString("remote.address", "127.0.0.1");
}
@Override
public int getPort() {
return config.getInt("remote.port", 25565);
}
@Override
public String getAuthType() {
return config.getString("remote.auth-type", "online");
}
}
public class BungeeUserAuthenticationInfo implements IUserAuthenticationInfo {
private String key;
public BungeeUserAuthenticationInfo(String key) {
this.key = key;
}
@Override
public String getEmail() {
return config.getString("userAuths." + key + ".email");
}
@Override
public String getPassword() {
return config.getString("userAuths." + key + ".password");
}
}
public class BungeeMetricsInfo implements IMetricsInfo {
@Override
public boolean isEnabled() {
return config.getBoolean("metrics.enabled", true);
}
@Override
public String getUniqueId() {
return config.getString("metrics.uuid", "generateduuid");
}
floodgateKeyPath = FloodgateKeyLoader.getKeyPath(this, floodgate, floodgateDataFolder, geyserDataFolder, plugin.getGeyserLogger());
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bungeecord;
import lombok.Getter;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;
import org.geysermc.connector.common.serializer.AsteriskSerializer;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Getter
public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
private String platformName;
private String platformVersion;
private boolean onlineMode;
private List<ListenerInfo> listeners;
private List<PluginInfo> plugins;
GeyserBungeeDumpInfo(ProxyServer proxy) {
super();
this.platformName = proxy.getName();
this.platformVersion = proxy.getVersion();
this.onlineMode = proxy.getConfig().isOnlineMode();
this.listeners = new ArrayList<>();
this.plugins = new ArrayList<>();
for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) {
String hostname;
if (AsteriskSerializer.showSensitive || (listener.getHost().getHostString().equals("") || listener.getHost().getHostString().equals("0.0.0.0"))) {
hostname = listener.getHost().getHostString();
} else {
hostname = "***";
}
this.listeners.add(new ListenerInfo(hostname, listener.getHost().getPort()));
}
for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
this.plugins.add(new PluginInfo(true, plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), Arrays.asList(plugin.getDescription().getAuthor())));
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,19 +25,21 @@
package org.geysermc.platform.bungeecord;
import lombok.Getter;
import lombok.Setter;
import org.geysermc.connector.GeyserLogger;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GeyserBungeeLogger implements GeyserLogger {
private final Logger logger;
@Getter @Setter
private boolean debug;
private Logger logger;
private boolean debugMode;
public GeyserBungeeLogger(Logger logger, boolean debugMode) {
public GeyserBungeeLogger(Logger logger, boolean debug) {
this.logger = logger;
this.debugMode = debugMode;
this.debug = debug;
}
@Override
@ -72,12 +74,8 @@ public class GeyserBungeeLogger implements GeyserLogger {
@Override
public void debug(String message) {
if (debugMode)
if (debug) {
info(message);
}
@Override
public void setDebug(boolean debug) {
debugMode = debug;
}
}
}

View File

@ -1,32 +1,31 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bungeecord;
import org.geysermc.common.main.IGeyserMain;
import org.geysermc.connector.common.main.IGeyserMain;
public class GeyserBungeeMain extends IGeyserMain {

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bungeecord;
import lombok.AllArgsConstructor;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.protocol.ProtocolConstants;
import org.geysermc.connector.common.ping.GeyserPingInfo;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@AllArgsConstructor
public class GeyserBungeePingPassthrough implements IGeyserPingPassthrough, Listener {
private final ProxyServer proxyServer;
@Override
public GeyserPingInfo getPingInformation(InetSocketAddress inetSocketAddress) {
CompletableFuture<ProxyPingEvent> future = new CompletableFuture<>();
proxyServer.getPluginManager().callEvent(new ProxyPingEvent(new GeyserPendingConnection(inetSocketAddress), getPingInfo(), (event, throwable) -> {
if (throwable != null) future.completeExceptionally(throwable);
else future.complete(event);
}));
ProxyPingEvent event = future.join();
ServerPing response = event.getResponse();
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
response.getDescriptionComponent().toLegacyText(),
new GeyserPingInfo.Players(response.getPlayers().getMax(), response.getPlayers().getOnline()),
new GeyserPingInfo.Version(response.getVersion().getName(), response.getVersion().getProtocol())
);
if (event.getResponse().getPlayers().getSample() != null) {
Arrays.stream(event.getResponse().getPlayers().getSample()).forEach(proxiedPlayer -> {
geyserPingInfo.getPlayerList().add(proxiedPlayer.getName());
});
}
return geyserPingInfo;
}
// This is static so pending connection can use it
private static ListenerInfo getDefaultListener() {
return ProxyServer.getInstance().getConfig().getListeners().iterator().next();
}
private ServerPing getPingInfo() {
return new ServerPing(
new ServerPing.Protocol(proxyServer.getName() + " " + proxyServer.getGameVersion(), ProtocolConstants.SUPPORTED_VERSION_IDS.get(ProtocolConstants.SUPPORTED_VERSION_IDS.size() - 1)),
new ServerPing.Players(getDefaultListener().getMaxPlayers(), proxyServer.getOnlineCount(), null),
getDefaultListener().getMotd(), proxyServer.getConfig().getFaviconObject()
);
}
private static class GeyserPendingConnection implements PendingConnection {
private static final UUID FAKE_UUID = UUID.nameUUIDFromBytes("geyser!internal".getBytes());
private final InetSocketAddress remote;
public GeyserPendingConnection(InetSocketAddress remote) {
this.remote = remote;
}
@Override
public String getName() {
throw new UnsupportedOperationException();
}
@Override
public int getVersion() {
return ProtocolConstants.SUPPORTED_VERSION_IDS.get(ProtocolConstants.SUPPORTED_VERSION_IDS.size() - 1);
}
@Override
public InetSocketAddress getVirtualHost() {
return null;
}
@Override
public ListenerInfo getListener() {
return getDefaultListener();
}
@Override
public String getUUID() {
return FAKE_UUID.toString();
}
@Override
public UUID getUniqueId() {
return FAKE_UUID;
}
@Override
public void setUniqueId(UUID uuid) {
throw new UnsupportedOperationException();
}
@Override
public boolean isOnlineMode() {
return true;
}
@Override
public void setOnlineMode(boolean b) {
throw new UnsupportedOperationException();
}
@Override
public boolean isLegacy() {
return false;
}
@Override
public InetSocketAddress getAddress() {
return remote;
}
@Override
public SocketAddress getSocketAddress() {
return getAddress();
}
@Override
public void disconnect(String s) {
throw new UnsupportedOperationException();
}
@Override
public void disconnect(BaseComponent... baseComponents) {
throw new UnsupportedOperationException();
}
@Override
public void disconnect(BaseComponent baseComponent) {
throw new UnsupportedOperationException();
}
@Override
public boolean isConnected() {
return false;
}
@Override
public Unsafe unsafe() {
throw new UnsupportedOperationException();
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -27,21 +27,23 @@ package org.geysermc.platform.bungeecord;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.bootstrap.GeyserBootstrap;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor;
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.UUID;
import java.util.logging.Level;
@ -50,6 +52,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
private GeyserBungeeCommandManager geyserCommandManager;
private GeyserBungeeConfiguration geyserConfig;
private GeyserBungeeLogger geyserLogger;
private IGeyserPingPassthrough geyserBungeePingPassthrough;
private GeyserConnector connector;
@ -58,64 +61,47 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
if (!getDataFolder().exists())
getDataFolder().mkdir();
File file = new File(getDataFolder(), "config.yml");
Configuration configuration = null;
if (!file.exists()) {
try (InputStream in = getResourceAsStream("config.yml")) {
Files.copy(in, file.toPath());
} catch (IOException ex) {
getLogger().log(Level.SEVERE, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
return;
}
}
try {
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "config.yml"));
} catch(IOException e) {
e.printStackTrace();
if (!getDataFolder().exists())
getDataFolder().mkdir();
File configFile = FileUtils.fileOrCopiedFromResource(new File(getDataFolder(), "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class);
} catch (IOException ex) {
getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
ex.printStackTrace();
}
if (configuration == null) {
getLogger().severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!");
return;
}
this.geyserConfig = new GeyserBungeeConfiguration(getDataFolder(), configuration);
boolean configHasChanged = false;
if (getProxy().getConfig().getListeners().size() == 1) {
ListenerInfo listener = getProxy().getConfig().getListeners().toArray(new ListenerInfo[0])[0];
InetSocketAddress javaAddr = listener.getHost();
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!javaAddr.getHostString().equals("0.0.0.0")) {
configuration.set("remote.address", javaAddr.getHostString());
// By default this should be localhost but may need to be changed in some circumstances
if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) {
this.geyserConfig.setAutoconfiguredRemote(true);
// Don't use localhost if not listening on all interfaces
if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) {
this.geyserConfig.getRemote().setAddress(javaAddr.getHostString());
}
this.geyserConfig.getRemote().setPort(javaAddr.getPort());
}
configuration.set("remote.port", javaAddr.getPort());
configHasChanged = true;
}
if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) {
configuration.set("metrics.uuid", UUID.randomUUID().toString());
configHasChanged = true;
}
if (configHasChanged) {
try {
ConfigurationProvider.getProvider(YamlConfiguration.class).save(configuration, new File(getDataFolder(), "config.yml"));
} catch (IOException ex) {
getLogger().log(Level.SEVERE, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
return;
if (geyserConfig.getBedrock().isCloneRemotePort()) {
geyserConfig.getBedrock().setPort(javaAddr.getPort());
}
}
this.geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && getProxy().getPluginManager().getPlugin("floodgate-bungee") == null) {
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
return;
} else if (geyserConfig.isAutoconfiguredRemote() && getProxy().getPluginManager().getPlugin("floodgate-bungee") != null) {
// Floodgate installed means that the user wants Floodgate authentication
geyserLogger.debug("Auto-setting to Floodgate authentication.");
geyserConfig.getRemote().setAuthType("floodgate");
}
geyserConfig.loadFloodgate(this);
@ -123,6 +109,12 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
this.geyserCommandManager = new GeyserBungeeCommandManager(connector);
if (geyserConfig.isLegacyPingPassthrough()) {
this.geyserBungeePingPassthrough = GeyserLegacyPingPassthrough.init(connector);
} else {
this.geyserBungeePingPassthrough = new GeyserBungeePingPassthrough(getProxy());
}
this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor(connector));
}
@ -145,4 +137,19 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
public CommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
@Override
public IGeyserPingPassthrough getGeyserPingPassthrough() {
return geyserBungeePingPassthrough;
}
@Override
public Path getConfigFolder() {
return getDataFolder().toPath();
}
@Override
public BootstrapDumpInfo getDumpInfo() {
return new GeyserBungeeDumpInfo(getProxy());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,17 +25,20 @@
package org.geysermc.platform.bungeecord.command;
import lombok.AllArgsConstructor;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.utils.LanguageUtils;
@AllArgsConstructor
public class BungeeCommandSender implements CommandSender {
private net.md_5.bungee.api.CommandSender handle;
private final net.md_5.bungee.api.CommandSender handle;
public BungeeCommandSender(net.md_5.bungee.api.CommandSender handle) {
this.handle = handle;
// Ensure even Java players' languages are loaded
LanguageUtils.loadGeyserLocale(getLocale());
}
@Override
public String getName() {
@ -51,4 +54,14 @@ public class BungeeCommandSender implements CommandSender {
public boolean isConsole() {
return !(handle instanceof ProxiedPlayer);
}
@Override
public String getLocale() {
if (handle instanceof ProxiedPlayer) {
ProxiedPlayer player = (ProxiedPlayer) handle;
String locale = player.getLocale().getLanguage() + "_" + player.getLocale().getCountry();
return LanguageUtils.formatLocale(locale);
}
return LanguageUtils.getDefaultLocale();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -27,19 +27,18 @@ package org.geysermc.platform.bungeecord.command;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.utils.LanguageUtils;
import java.util.ArrayList;
import java.util.Arrays;
public class GeyserBungeeCommandExecutor extends Command implements TabExecutor {
private GeyserConnector connector;
private final GeyserConnector connector;
public GeyserBungeeCommandExecutor(GeyserConnector connector) {
super("geyser");
@ -52,20 +51,23 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
if (args.length > 0) {
if (getCommand(args[0]) != null) {
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + "You do not have permission to execute this command!"));
BungeeCommandSender commandSender = new BungeeCommandSender(sender);
String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());
commandSender.sendMessage(ChatColor.RED + message);
return;
}
getCommand(args[0]).execute(new BungeeCommandSender(sender), args);
getCommand(args[0]).execute(new BungeeCommandSender(sender), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
}
} else {
getCommand("help").execute(new BungeeCommandSender(sender), args);
getCommand("help").execute(new BungeeCommandSender(sender), new String[0]);
}
}
@Override
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 1) {
return Arrays.asList("?", "help", "reload", "shutdown", "stop");
return connector.getCommandManager().getCommandNames();
}
return new ArrayList<>();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -6,12 +6,11 @@
<parent>
<groupId>org.geysermc</groupId>
<artifactId>geyser-parent</artifactId>
<version>parent</version>
<relativePath>../</relativePath>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>bootstrap-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<repositories>
<repository>
<id>spigot-public</id>
@ -35,8 +34,8 @@
</repository>
</repositories>
<modules>
<module>bukkit</module>
<module>bungeecord</module>
<module>spigot</module>
<module>sponge</module>
<module>standalone</module>
<module>velocity</module>

View File

@ -6,26 +6,37 @@
<parent>
<groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../</relativePath>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>bootstrap-bukkit</artifactId>
<artifactId>bootstrap-spigot</artifactId>
<dependencies>
<dependency>
<groupId>org.geysermc</groupId>
<artifactId>connector</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.14-R0.1-SNAPSHOT</version>
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>us.myles</groupId>
<artifactId>viaversion</artifactId>
<version>3.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.geysermc.adapters</groupId>
<artifactId>spigot-all</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>${outputName}-Bukkit</finalName>
<finalName>${outputName}-Spigot</finalName>
<resources>
<resource>
<directory>src/main/resources/</directory>
@ -40,7 +51,7 @@
<configuration>
<archive>
<manifestEntries>
<Main-Class>org.geysermc.platform.bukkit.GeyserBukkitMain</Main-Class>
<Main-Class>org.geysermc.platform.spigot.GeyserSpigotMain</Main-Class>
</manifestEntries>
</archive>
</configuration>
@ -59,11 +70,35 @@
<relocations>
<relocation>
<pattern>io.netty</pattern>
<shadedPattern>org.geysermc.platform.bukkit.shaded.netty</shadedPattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.netty</shadedPattern>
</relocation>
<relocation>
<pattern>it.unimi.dsi.fastutil</pattern>
<shadedPattern>org.geysermc.platform.bukkit.shaded.fastutil</shadedPattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.fastutil</shadedPattern>
</relocation>
<relocation>
<pattern>com.fasterxml.jackson</pattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.jackson</shadedPattern>
</relocation>
<relocation>
<pattern>org.reflections</pattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.reflections</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.google.common</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.guava</pattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.google.guava</shadedPattern>
</relocation>
<relocation>
<pattern>org.dom4j</pattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.dom4j</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori</pattern>
<shadedPattern>org.geysermc.platform.spigot.shaded.kyori</shadedPattern>
</relocation>
</relocations>
</configuration>

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.geysermc.connector.FloodgateKeyLoader;
import org.geysermc.connector.configuration.GeyserJacksonConfiguration;
import java.nio.file.Path;
@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
public final class GeyserSpigotConfiguration extends GeyserJacksonConfiguration {
@JsonIgnore
private Path floodgateKeyPath;
public void loadFloodgate(GeyserSpigotPlugin plugin) {
Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate-bukkit");
Path geyserDataFolder = plugin.getDataFolder().toPath();
Path floodgateDataFolder = floodgate != null ? floodgate.getDataFolder().toPath() : null;
floodgateKeyPath = FloodgateKeyLoader.getKeyPath(this, floodgate, floodgateDataFolder, geyserDataFolder, plugin.getGeyserLogger());
}
@Override
public boolean isCacheChunks() {
return true; // We override this as with Bukkit, we have direct access to the server implementation
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.geysermc.connector.common.serializer.AsteriskSerializer;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import java.util.ArrayList;
import java.util.List;
@Getter
public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
private String platformName;
private String platformVersion;
private String platformAPIVersion;
private boolean onlineMode;
private String serverIP;
private int serverPort;
private List<PluginInfo> plugins;
GeyserSpigotDumpInfo() {
super();
this.platformName = Bukkit.getName();
this.platformVersion = Bukkit.getVersion();
this.platformAPIVersion = Bukkit.getBukkitVersion();
this.onlineMode = Bukkit.getOnlineMode();
if (AsteriskSerializer.showSensitive || (Bukkit.getIp().equals("") || Bukkit.getIp().equals("0.0.0.0"))) {
this.serverIP = Bukkit.getIp();
} else {
this.serverIP = "***";
}
this.serverPort = Bukkit.getPort();
this.plugins = new ArrayList<>();
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
this.plugins.add(new PluginInfo(plugin.isEnabled(), plugin.getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), plugin.getDescription().getAuthors()));
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,20 +23,21 @@
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bukkit;
package org.geysermc.platform.spigot;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.geysermc.connector.GeyserLogger;
import java.util.logging.Level;
import java.util.logging.Logger;
@AllArgsConstructor
public class GeyserBukkitLogger implements GeyserLogger {
private Logger logger;
private boolean debugMode;
public class GeyserSpigotLogger implements GeyserLogger {
private final Logger logger;
@Getter @Setter
private boolean debug;
@Override
public void severe(String message) {
@ -70,12 +71,8 @@ public class GeyserBukkitLogger implements GeyserLogger {
@Override
public void debug(String message) {
if (debugMode)
if (debug) {
info(message);
}
@Override
public void setDebug(boolean debug) {
debugMode = debug;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,23 +23,21 @@
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.connector.network.translators;
package org.geysermc.platform.spigot;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.common.main.IGeyserMain;
public class NbtItemStackTranslator {
public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) {
public class GeyserSpigotMain extends IGeyserMain {
public static void main(String[] args) {
new GeyserSpigotMain().displayMessage();
}
public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) {
public String getPluginType() {
return "Spigot or Paper (recommended)";
}
public boolean acceptItem(ItemEntry itemEntry) {
return true;
public String getPluginFolder() {
return "plugins";
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot;
import com.github.steveice10.mc.protocol.MinecraftConstants;
import lombok.AllArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.util.CachedServerIcon;
import org.geysermc.connector.common.ping.GeyserPingInfo;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.Iterator;
@AllArgsConstructor
public class GeyserSpigotPingPassthrough implements IGeyserPingPassthrough {
private final GeyserSpigotLogger logger;
@Override
public GeyserPingInfo getPingInformation(InetSocketAddress inetSocketAddress) {
try {
ServerListPingEvent event = new GeyserPingEvent(inetSocketAddress.getAddress(), Bukkit.getMotd(), Bukkit.getOnlinePlayers().size(), Bukkit.getMaxPlayers());
Bukkit.getPluginManager().callEvent(event);
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(event.getMotd(),
new GeyserPingInfo.Players(event.getMaxPlayers(), event.getNumPlayers()),
new GeyserPingInfo.Version(Bukkit.getVersion(), MinecraftConstants.PROTOCOL_VERSION) // thanks Spigot for not exposing this, just default to latest
);
Bukkit.getOnlinePlayers().stream().map(Player::getName).forEach(geyserPingInfo.getPlayerList()::add);
return geyserPingInfo;
} catch (Exception e) {
logger.debug("Error while getting Bukkit ping passthrough: " + e.toString());
return new GeyserPingInfo(null, null, null);
}
}
// These methods are unimplemented on spigot api by default so we add stubs so plugins don't complain
private static class GeyserPingEvent extends ServerListPingEvent {
public GeyserPingEvent(InetAddress address, String motd, int numPlayers, int maxPlayers) {
super(address, motd, numPlayers, maxPlayers);
}
@Override
public void setServerIcon(CachedServerIcon icon) throws IllegalArgumentException, UnsupportedOperationException {
}
@Override
public Iterator<Player> iterator() throws UnsupportedOperationException {
return Collections.EMPTY_LIST.iterator();
}
}
}

View File

@ -0,0 +1,308 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot;
import com.github.steveice10.mc.protocol.MinecraftConstants;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.adapters.spigot.SpigotAdapters;
import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.bootstrap.GeyserBootstrap;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import org.geysermc.connector.network.translators.world.WorldManager;
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor;
import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager;
import org.geysermc.platform.spigot.command.SpigotCommandSender;
import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener;
import org.geysermc.platform.spigot.world.manager.*;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingData;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
private GeyserSpigotCommandManager geyserCommandManager;
private GeyserSpigotConfiguration geyserConfig;
private GeyserSpigotLogger geyserLogger;
private IGeyserPingPassthrough geyserSpigotPingPassthrough;
private GeyserSpigotWorldManager geyserWorldManager;
private GeyserConnector connector;
@Override
public void onEnable() {
// This is manually done instead of using Bukkit methods to save the config because otherwise comments get removed
try {
if (!getDataFolder().exists()) {
getDataFolder().mkdir();
File bukkitConfig = new File("plugins/Geyser-Bukkit/config.yml");
if (bukkitConfig.exists()) { // Copy over old configs
getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copy_bukkit_config"));
Files.copy(bukkitConfig.toPath(), new File(getDataFolder().toString() + "/config.yml").toPath());
getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copied_bukkit_config"));
}
}
File configFile = FileUtils.fileOrCopiedFromResource(new File(getDataFolder(), "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpigotConfiguration.class);
} catch (IOException ex) {
getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
ex.printStackTrace();
}
// By default this should be localhost but may need to be changed in some circumstances
if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) {
geyserConfig.setAutoconfiguredRemote(true);
// Don't use localhost if not listening on all interfaces
if (!Bukkit.getIp().equals("0.0.0.0") && !Bukkit.getIp().equals("")) {
geyserConfig.getRemote().setAddress(Bukkit.getIp());
}
geyserConfig.getRemote().setPort(Bukkit.getPort());
}
if (geyserConfig.getBedrock().isCloneRemotePort()) {
geyserConfig.getBedrock().setPort(Bukkit.getPort());
}
this.geyserLogger = new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && Bukkit.getPluginManager().getPlugin("floodgate-bukkit") == null) {
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
this.getPluginLoader().disablePlugin(this);
return;
} else if (geyserConfig.isAutoconfiguredRemote() && Bukkit.getPluginManager().getPlugin("floodgate-bukkit") != null) {
// Floodgate installed means that the user wants Floodgate authentication
geyserLogger.debug("Auto-setting to Floodgate authentication.");
geyserConfig.getRemote().setAuthType("floodgate");
}
geyserConfig.loadFloodgate(this);
this.connector = GeyserConnector.start(PlatformType.SPIGOT, this);
if (geyserConfig.isLegacyPingPassthrough()) {
this.geyserSpigotPingPassthrough = GeyserLegacyPingPassthrough.init(connector);
} else {
this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger);
}
this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector);
boolean isViaVersion = (Bukkit.getPluginManager().getPlugin("ViaVersion") != null);
if (isViaVersion) {
if (!isCompatible(Via.getAPI().getVersion().replace("-SNAPSHOT", ""), "3.2.0")) {
geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.viaversion.too_old",
"https://ci.viaversion.com/job/ViaVersion/"));
isViaVersion = false;
}
}
// Used to determine if Block.getBlockData() is present.
boolean isLegacy = !isCompatible(Bukkit.getServer().getVersion(), "1.13.0");
if (isLegacy)
geyserLogger.debug("Legacy version of Minecraft (1.12.2 or older) detected; falling back to ViaVersion for block state retrieval.");
boolean use3dBiomes = isCompatible(Bukkit.getServer().getVersion(), "1.16.0");
if (!use3dBiomes) {
geyserLogger.debug("Legacy version of Minecraft (1.15.2 or older) detected; not using 3D biomes.");
}
// Set if we need to use a different method for getting a player's locale
SpigotCommandSender.setUseLegacyLocaleMethod(!isCompatible(Bukkit.getServer().getVersion(), "1.12.0"));
if (connector.getConfig().isUseAdapters()) {
try {
String name = Bukkit.getServer().getClass().getPackage().getName();
String nmsVersion = name.substring(name.lastIndexOf('.') + 1);
SpigotAdapters.registerWorldAdapter(nmsVersion);
if (isViaVersion && isViaVersionNeeded()) {
if (isLegacy) {
// Pre-1.13
this.geyserWorldManager = new GeyserSpigot1_12NativeWorldManager();
} else {
// Post-1.13
this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this, use3dBiomes);
}
} else {
// No ViaVersion
this.geyserWorldManager = new GeyserSpigotNativeWorldManager(use3dBiomes);
}
geyserLogger.debug("Using NMS adapter: " + this.geyserWorldManager.getClass() + ", " + nmsVersion);
} catch (Exception e) {
if (geyserConfig.isDebugMode()) {
geyserLogger.debug("Error while attempting to find NMS adapter. Most likely, this can be safely ignored. :)");
e.printStackTrace();
}
}
} else {
geyserLogger.debug("Not using NMS adapter as it is disabled in the config.");
}
if (this.geyserWorldManager == null) {
// No NMS adapter
if (isLegacy && isViaVersion) {
// Use ViaVersion for converting pre-1.13 block states
this.geyserWorldManager = new GeyserSpigot1_12WorldManager();
} else if (isLegacy) {
// Not sure how this happens - without ViaVersion, we don't know any block states, so just assume everything is air
this.geyserWorldManager = new GeyserSpigotFallbackWorldManager();
} else {
// Post-1.13
this.geyserWorldManager = new GeyserSpigotWorldManager(use3dBiomes);
}
geyserLogger.debug("Using default world manager: " + this.geyserWorldManager.getClass());
}
GeyserSpigotBlockPlaceListener blockPlaceListener = new GeyserSpigotBlockPlaceListener(connector, this.geyserWorldManager);
Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this);
this.getCommand("geyser").setExecutor(new GeyserSpigotCommandExecutor(connector));
}
@Override
public void onDisable() {
if (connector != null) {
connector.shutdown();
}
}
@Override
public GeyserSpigotConfiguration getGeyserConfig() {
return geyserConfig;
}
@Override
public GeyserSpigotLogger getGeyserLogger() {
return geyserLogger;
}
@Override
public CommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
@Override
public IGeyserPingPassthrough getGeyserPingPassthrough() {
return geyserSpigotPingPassthrough;
}
@Override
public WorldManager getWorldManager() {
return this.geyserWorldManager;
}
@Override
public Path getConfigFolder() {
return getDataFolder().toPath();
}
@Override
public BootstrapDumpInfo getDumpInfo() {
return new GeyserSpigotDumpInfo();
}
public boolean isCompatible(String version, String whichVersion) {
int[] currentVersion = parseVersion(version);
int[] otherVersion = parseVersion(whichVersion);
int length = Math.max(currentVersion.length, otherVersion.length);
for (int index = 0; index < length; index = index + 1) {
int self = (index < currentVersion.length) ? currentVersion[index] : 0;
int other = (index < otherVersion.length) ? otherVersion[index] : 0;
if (self != other) {
return (self - other) > 0;
}
}
return true;
}
private int[] parseVersion(String versionParam) {
versionParam = (versionParam == null) ? "" : versionParam;
if (versionParam.contains("(MC: ")) {
versionParam = versionParam.split("\\(MC: ")[1];
versionParam = versionParam.split("\\)")[0];
}
String[] stringArray = versionParam.split("[_.-]");
int[] temp = new int[stringArray.length];
for (int index = 0; index <= (stringArray.length - 1); index = index + 1) {
String t = stringArray[index].replaceAll("\\D", "");
try {
temp[index] = Integer.parseInt(t);
} catch (NumberFormatException ex) {
temp[index] = 0;
}
}
return temp;
}
/**
* @return the server version before ViaVersion finishes initializing
*/
public ProtocolVersion getServerProtocolVersion() {
String bukkitVersion = Bukkit.getServer().getVersion();
// Turn "(MC: 1.16.4)" into 1.16.4.
String version = bukkitVersion.split("\\(MC: ")[1].split("\\)")[0];
return ProtocolVersion.getClosest(version);
}
/**
* This function should not run unless ViaVersion is installed on the server.
*
* @return true if there is any block mappings difference between the server and client.
*/
private boolean isViaVersionNeeded() {
ProtocolVersion serverVersion = getServerProtocolVersion();
List<Pair<Integer, Protocol>> protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
serverVersion.getVersion());
if (protocolList == null) {
// No translation needed!
return false;
}
for (int i = protocolList.size() - 1; i >= 0; i--) {
MappingData mappingData = protocolList.get(i).getValue().getMappingData();
if (mappingData != null) {
return true;
}
}
// All mapping data is null, which means client and server block states are the same
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,39 +23,42 @@
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bukkit.command;
package org.geysermc.platform.spigot.command;
import lombok.AllArgsConstructor;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.utils.LanguageUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@AllArgsConstructor
public class GeyserBukkitCommandExecutor implements TabExecutor {
public class GeyserSpigotCommandExecutor implements TabExecutor {
private GeyserConnector connector;
private final GeyserConnector connector;
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length > 0) {
if (getCommand(args[0]) != null) {
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
sender.sendMessage(ChatColor.RED + "You do not have permission to execute this command!");
SpigotCommandSender commandSender = new SpigotCommandSender(sender);
String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());;
commandSender.sendMessage(ChatColor.RED + message);
return true;
}
getCommand(args[0]).execute(new BukkitCommandSender(sender), args);
getCommand(args[0]).execute(new SpigotCommandSender(sender), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
return true;
}
} else {
getCommand("help").execute(new BukkitCommandSender(sender), args);
getCommand("help").execute(new SpigotCommandSender(sender), new String[0]);
return true;
}
return true;
@ -64,7 +67,7 @@ public class GeyserBukkitCommandExecutor implements TabExecutor {
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 1) {
return Arrays.asList("?", "help", "reload", "shutdown", "stop");
return connector.getCommandManager().getCommandNames();
}
return new ArrayList<>();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,18 +23,18 @@
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.bukkit.command;
package org.geysermc.platform.spigot.command;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.platform.bukkit.GeyserBukkitPlugin;
import org.geysermc.platform.spigot.GeyserSpigotPlugin;
import java.lang.reflect.Field;
public class GeyserBukkitCommandManager extends CommandManager {
public class GeyserSpigotCommandManager extends CommandManager {
private static CommandMap COMMAND_MAP;
@ -48,9 +48,9 @@ public class GeyserBukkitCommandManager extends CommandManager {
}
}
private GeyserBukkitPlugin plugin;
private GeyserSpigotPlugin plugin;
public GeyserBukkitCommandManager(GeyserBukkitPlugin plugin, GeyserConnector connector) {
public GeyserSpigotCommandManager(GeyserSpigotPlugin plugin, GeyserConnector connector) {
super(connector);
this.plugin = plugin;

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot.command;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.utils.LanguageUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class SpigotCommandSender implements CommandSender {
/**
* Whether to use {@code Player.getLocale()} or {@code Player.spigot().getLocale()}, depending on version.
* 1.12 or greater should not use the legacy method.
*/
private static boolean USE_LEGACY_METHOD = false;
private static Method LOCALE_METHOD;
private final org.bukkit.command.CommandSender handle;
private final String locale;
public SpigotCommandSender(org.bukkit.command.CommandSender handle) {
this.handle = handle;
this.locale = getSpigotLocale();
// Ensure even Java players' languages are loaded
LanguageUtils.loadGeyserLocale(locale);
}
@Override
public String getName() {
return handle.getName();
}
@Override
public void sendMessage(String message) {
handle.sendMessage(message);
}
@Override
public boolean isConsole() {
return handle instanceof ConsoleCommandSender;
}
@Override
public String getLocale() {
return locale;
}
/**
* Set if we are on pre-1.12, and therefore {@code player.getLocale()} doesn't exist and we have to get
* {@code player.spigot().getLocale()}.
*
* @param useLegacyMethod if we are running pre-1.12 and therefore need to use reflection to get the player locale
*/
public static void setUseLegacyLocaleMethod(boolean useLegacyMethod) {
USE_LEGACY_METHOD = useLegacyMethod;
if (USE_LEGACY_METHOD) {
try {
//noinspection JavaReflectionMemberAccess - of course it doesn't exist; that's why we're doing it
LOCALE_METHOD = Player.Spigot.class.getMethod("getLocale");
} catch (NoSuchMethodException e) {
GeyserConnector.getInstance().getLogger().debug("Player.Spigot.getLocale() doesn't exist? Not a big deal but if you're seeing this please report it to the developers!");
}
}
}
/**
* So we only have to do nasty reflection stuff once per command
*
* @return the locale of the Spigot player
*/
private String getSpigotLocale() {
if (handle instanceof Player) {
Player player = (Player) handle;
if (USE_LEGACY_METHOD) {
try {
// sigh
// This was the only option on older Spigot instances and now it's gone
return (String) LOCALE_METHOD.invoke(player.spigot());
} catch (IllegalAccessException | InvocationTargetException ignored) {
}
} else {
return player.getLocale();
}
}
return LanguageUtils.getDefaultLocale();
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot.world;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
import lombok.AllArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.platform.spigot.world.manager.GeyserSpigotWorldManager;
@AllArgsConstructor
public class GeyserSpigotBlockPlaceListener implements Listener {
private final GeyserConnector connector;
private final GeyserSpigotWorldManager worldManager;
@EventHandler
public void place(final BlockPlaceEvent event) {
for (GeyserSession session : connector.getPlayers()) {
if (event.getPlayer() == Bukkit.getPlayer(session.getPlayerEntity().getUsername())) {
LevelSoundEventPacket placeBlockSoundPacket = new LevelSoundEventPacket();
placeBlockSoundPacket.setSound(SoundEvent.PLACE);
placeBlockSoundPacket.setPosition(Vector3f.from(event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ()));
placeBlockSoundPacket.setBabySound(false);
if (worldManager.isLegacy()) {
placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(worldManager.getBlockAt(session,
event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())));
} else {
String javaBlockId = event.getBlockPlaced().getBlockData().getAsString();
placeBlockSoundPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaIdBlockMap().getOrDefault(javaBlockId, BlockTranslator.JAVA_AIR_ID)));
}
placeBlockSoundPacket.setIdentifier(":");
session.sendUpstreamPacket(placeBlockSoundPacket);
session.setLastBlockPlacePosition(null);
session.setLastBlockPlacedId(null);
break;
}
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot.world.manager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.geysermc.adapters.spigot.SpigotAdapters;
import org.geysermc.adapters.spigot.SpigotWorldAdapter;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
/**
* Used with ViaVersion and pre-1.13.
*/
public class GeyserSpigot1_12NativeWorldManager extends GeyserSpigot1_12WorldManager {
private final SpigotWorldAdapter adapter;
public GeyserSpigot1_12NativeWorldManager() {
this.adapter = SpigotAdapters.getWorldAdapter();
// Unlike post-1.13, we can't build up a cache of block states, because block entities need some special conversion
}
@Override
public int getBlockAt(GeyserSession session, int x, int y, int z) {
Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername());
if (player == null) {
return BlockTranslator.JAVA_AIR_ID;
}
// Get block entity storage
BlockStorage storage = Via.getManager().getConnection(player.getUniqueId()).get(BlockStorage.class);
int blockId = adapter.getBlockAt(player.getWorld(), x, y, z);
return getLegacyBlock(storage, blockId, x, y, z);
}
}

View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot.world.manager;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingData;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
import java.util.List;
/**
* Should be used when ViaVersion is present, no NMS adapter is being used, and we are pre-1.13.
*
* You need ViaVersion to connect to an older server with the Geyser-Spigot plugin.
*/
public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
/**
* Specific mapping data for 1.12 to 1.13. Used to convert the 1.12 block into the 1.13 block state.
* (Block IDs did not change between server versions until 1.13 and after)
*/
private final MappingData mappingData1_12to1_13;
/**
* The list of all protocols from the client's version to 1.13.
*/
private final List<Pair<Integer, Protocol>> protocolList;
public GeyserSpigot1_12WorldManager() {
super(false);
this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData();
this.protocolList = ProtocolRegistry.getProtocolPath(CLIENT_PROTOCOL_VERSION,
ProtocolVersion.v1_13.getVersion());
}
@Override
@SuppressWarnings("deprecation")
public int getBlockAt(GeyserSession session, int x, int y, int z) {
Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername());
if (player == null) {
return BlockTranslator.JAVA_AIR_ID;
}
// Get block entity storage
BlockStorage storage = Via.getManager().getConnection(player.getUniqueId()).get(BlockStorage.class);
Block block = player.getWorld().getBlockAt(x, y, z);
// Black magic that gets the old block state ID
int blockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
return getLegacyBlock(storage, blockId, x, y, z);
}
/**
*
* @param storage ViaVersion's block entity storage (used to fix block entity state differences)
* @param blockId the pre-1.13 block id
* @param x X coordinate of block
* @param y Y coordinate of block
* @param z Z coordinate of block
* @return the block state updated to the latest Minecraft version
*/
@SuppressWarnings("deprecation")
public int getLegacyBlock(BlockStorage storage, int blockId, int x, int y, int z) {
// Convert block state from old version (1.12.2) -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 -> 1.16.2
blockId = mappingData1_12to1_13.getNewBlockId(blockId);
// Translate block entity differences - some information was stored in block tags and not block states
if (storage.isWelcome(blockId)) { // No getOrDefault method
BlockStorage.ReplacementData data = storage.get(new Position(x, (short) y, z));
if (data != null && data.getReplacement() != -1) {
blockId = data.getReplacement();
}
}
for (int i = protocolList.size() - 1; i >= 0; i--) {
MappingData mappingData = protocolList.get(i).getValue().getMappingData();
if (mappingData != null) {
blockId = mappingData.getNewBlockStateId(blockId);
}
}
return blockId;
}
@SuppressWarnings("deprecation")
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername());
if (player == null) {
return;
}
World world = player.getWorld();
// Get block entity storage
BlockStorage storage = Via.getManager().getConnection(player.getUniqueId()).get(BlockStorage.class);
for (int blockY = 0; blockY < 16; blockY++) { // Cache-friendly iteration order
for (int blockZ = 0; blockZ < 16; blockZ++) {
for (int blockX = 0; blockX < 16; blockX++) {
Block block = world.getBlockAt((x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ);
// Black magic that gets the old block state ID
int blockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
chunk.set(blockX, blockY, blockZ, getLegacyBlock(storage, blockId, (x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ));
}
}
}
}
@Override
public boolean isLegacy() {
return true;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot.world.manager;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
/**
* Should only be used when we know {@link GeyserSpigotWorldManager#getBlockAt(GeyserSession, int, int, int)}
* cannot be accurate. Typically, this is when ViaVersion is not installed but a client still manages to connect.
* If this occurs to you somehow, please let us know!!
*/
public class GeyserSpigotFallbackWorldManager extends GeyserSpigotWorldManager {
public GeyserSpigotFallbackWorldManager() {
// Since this is pre-1.13 (and thus pre-1.15), there will never be 3D biomes.
super(false);
}
@Override
public int getBlockAt(GeyserSession session, int x, int y, int z) {
return BlockTranslator.JAVA_AIR_ID;
}
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
// Do nothing, since we can't do anything with the chunk
}
@Override
public boolean hasMoreBlockDataThanChunkCache() {
return false;
}
@Override
public boolean isLegacy() {
return true;
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot.world.manager;
import com.github.steveice10.mc.protocol.MinecraftConstants;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntList;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.platform.spigot.GeyserSpigotPlugin;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.data.MappingData;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import java.util.List;
/**
* Used when block IDs need to be translated to the latest version
*/
public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorldManager {
private final Int2IntMap oldToNewBlockId;
public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin, boolean use3dBiomes) {
super(use3dBiomes);
IntList allBlockStates = adapter.getAllBlockStates();
oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size());
ProtocolVersion serverVersion = plugin.getServerProtocolVersion();
List<Pair<Integer, Protocol>> protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
serverVersion.getVersion());
for (int oldBlockId : allBlockStates) {
int newBlockId = oldBlockId;
// protocolList should *not* be null; we checked for that before initializing this class
for (int i = protocolList.size() - 1; i >= 0; i--) {
MappingData mappingData = protocolList.get(i).getValue().getMappingData();
if (mappingData != null) {
newBlockId = mappingData.getNewBlockStateId(newBlockId);
}
}
oldToNewBlockId.put(oldBlockId, newBlockId);
}
}
@Override
public int getBlockAt(GeyserSession session, int x, int y, int z) {
int nativeBlockId = super.getBlockAt(session, x, y, z);
return oldToNewBlockId.getOrDefault(nativeBlockId, nativeBlockId);
}
@Override
public boolean isLegacy() {
return true;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -21,25 +21,31 @@
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*
*/
package org.geysermc.platform.bukkit.world;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
package org.geysermc.platform.spigot.world.manager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.geysermc.adapters.spigot.SpigotAdapters;
import org.geysermc.adapters.spigot.SpigotWorldAdapter;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.WorldManager;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
public class GeyserBukkitWorldManager extends WorldManager {
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
protected final SpigotWorldAdapter adapter;
public GeyserSpigotNativeWorldManager(boolean use3dBiomes) {
super(use3dBiomes);
adapter = SpigotAdapters.getWorldAdapter();
}
@Override
public BlockState getBlockAt(GeyserSession session, int x, int y, int z) {
if (session.getPlayerEntity() == null) {
return BlockTranslator.AIR;
public int getBlockAt(GeyserSession session, int x, int y, int z) {
Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername());
if (player == null) {
return BlockTranslator.JAVA_AIR_ID;
}
return BlockTranslator.getJavaIdBlockMap().get(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z).getBlockData().getAsString());
return adapter.getBlockAt(player.getWorld(), x, y, z);
}
}

View File

@ -0,0 +1,195 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.spigot.world.manager;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.MinecraftConstants;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.GeyserWorldManager;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.GameRule;
import org.geysermc.connector.utils.LanguageUtils;
import java.io.InputStream;
/**
* The base world manager to use when there is no supported NMS revision
*/
public class GeyserSpigotWorldManager extends GeyserWorldManager {
/**
* The current client protocol version for ViaVersion usage.
*/
protected static final int CLIENT_PROTOCOL_VERSION = MinecraftConstants.PROTOCOL_VERSION;
/**
* Whether the server is pre-1.16 and therefore does not support 3D biomes on an API level guaranteed.
*/
private final boolean use3dBiomes;
/**
* Stores a list of {@link Biome} ordinal numbers to Minecraft biome numeric IDs.
*
* Working with the Biome enum in Spigot poses two problems:
* 1: The Biome enum values change in both order and names over the years.
* 2: There is no way to get the Minecraft biome ID from the name itself with Spigot.
* To solve both of these problems, we store a JSON file of every Biome enum that has existed,
* along with its 1.16 biome number.
*
* The key is the Spigot Biome ordinal; the value is the Minecraft Java biome numerical ID
*/
private final Int2IntMap biomeToIdMap = new Int2IntOpenHashMap(Biome.values().length);
public GeyserSpigotWorldManager(boolean use3dBiomes) {
this.use3dBiomes = use3dBiomes;
// Load the values into the biome-to-ID map
InputStream biomeStream = FileUtils.getResource("biomes.json");
JsonNode biomes;
try {
biomes = GeyserConnector.JSON_MAPPER.readTree(biomeStream);
} catch (Exception e) {
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e);
}
// Only load in the biomes that are present in this version of Minecraft
for (Biome enumBiome : Biome.values()) {
JsonNode biome = biomes.get(enumBiome.toString());
if (biome != null) {
biomeToIdMap.put(enumBiome.ordinal(), biome.intValue());
} else {
GeyserConnector.getInstance().getLogger().debug("No biome mapping found for " + enumBiome.toString() +
", defaulting to 0");
biomeToIdMap.put(enumBiome.ordinal(), 0);
}
}
}
@Override
public int getBlockAt(GeyserSession session, int x, int y, int z) {
Player bukkitPlayer;
if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) {
return BlockTranslator.JAVA_AIR_ID;
}
World world = bukkitPlayer.getWorld();
return BlockTranslator.getJavaIdBlockMap().getOrDefault(world.getBlockAt(x, y, z).getBlockData().getAsString(), BlockTranslator.JAVA_AIR_ID);
}
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
Player bukkitPlayer;
if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) {
return;
}
World world = bukkitPlayer.getWorld();
for (int blockY = 0; blockY < 16; blockY++) { // Cache-friendly iteration order
for (int blockZ = 0; blockZ < 16; blockZ++) {
for (int blockX = 0; blockX < 16; blockX++) {
Block block = world.getBlockAt((x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ);
int id = BlockTranslator.getJavaIdBlockMap().getOrDefault(block.getBlockData().getAsString(), BlockTranslator.JAVA_AIR_ID);
chunk.set(blockX, blockY, blockZ, id);
}
}
}
}
@Override
public boolean hasMoreBlockDataThanChunkCache() {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int[] getBiomeDataAt(GeyserSession session, int x, int z) {
if (session.getPlayerEntity() == null) {
return new int[1024];
}
int[] biomeData = new int[1024];
World world = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld();
int chunkX = x << 4;
int chunkZ = z << 4;
int chunkXmax = chunkX + 16;
int chunkZmax = chunkZ + 16;
// 3D biomes didn't exist until 1.15
if (use3dBiomes) {
for (int localX = chunkX; localX < chunkXmax; localX += 4) {
for (int localY = 0; localY < 255; localY += + 4) {
for (int localZ = chunkZ; localZ < chunkZmax; localZ += 4) {
// Index is based on wiki.vg's index requirements
final int i = ((localY >> 2) & 63) << 4 | ((localZ >> 2) & 3) << 2 | ((localX >> 2) & 3);
biomeData[i] = biomeToIdMap.getOrDefault(world.getBiome(localX, localY, localZ).ordinal(), 0);
}
}
}
} else {
// Looks like the same code, but we're not checking the Y coordinate here
for (int localX = chunkX; localX < chunkXmax; localX += 4) {
for (int localY = 0; localY < 255; localY += + 4) {
for (int localZ = chunkZ; localZ < chunkZmax; localZ += 4) {
// Index is based on wiki.vg's index requirements
final int i = ((localY >> 2) & 63) << 4 | ((localZ >> 2) & 3) << 2 | ((localX >> 2) & 3);
biomeData[i] = biomeToIdMap.getOrDefault(world.getBiome(localX, localZ).ordinal(), 0);
}
}
}
}
return biomeData;
}
public Boolean getGameRuleBool(GeyserSession session, GameRule gameRule) {
return Boolean.parseBoolean(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getGameRuleValue(gameRule.getJavaID()));
}
@Override
public int getGameRuleInt(GeyserSession session, GameRule gameRule) {
return Integer.parseInt(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getGameRuleValue(gameRule.getJavaID()));
}
@Override
public boolean hasPermission(GeyserSession session, String permission) {
return Bukkit.getPlayer(session.getPlayerEntity().getUsername()).hasPermission(permission);
}
/**
* This must be set to true if we are pre-1.13, and {@link BlockData#getAsString() does not exist}.
*
* This should be set to true if we are post-1.13 but before the latest version, and we should convert the old block state id
* to the current one.
*
* @return whether there is a difference between client block state and server block state that requires extra processing
*/
public boolean isLegacy() {
return false;
}
}

View File

@ -0,0 +1,155 @@
{
"MUTATED_ICE_FLATS" : 140,
"MUTATED_TAIGA" : 133,
"SAVANNA_PLATEAU_MOUNTAINS" : 164,
"DEEP_WARM_OCEAN" : 47,
"REDWOOD_TAIGA_HILLS" : 33,
"THE_VOID" : 127,
"COLD_TAIGA_MOUNTAINS" : 158,
"BAMBOO_JUNGLE_HILLS" : 169,
"MOUNTAINS" : 3,
"MESA_PLATEAU" : 39,
"SNOWY_TAIGA_HILLS" : 31,
"DEEP_FROZEN_OCEAN" : 50,
"EXTREME_HILLS" : 3,
"BIRCH_FOREST_MOUNTAINS" : 155,
"FOREST" : 4,
"BIRCH_FOREST" : 27,
"SNOWY_TUNDRA" : 12,
"ICE_SPIKES" : 140,
"FROZEN_OCEAN" : 10,
"WARPED_FOREST" : 172,
"WOODED_BADLANDS_PLATEAU" : 38,
"BADLANDS_PLATEAU" : 39,
"ICE_PLAINS_SPIKES" : 140,
"MEGA_TAIGA" : 32,
"MUTATED_SAVANNA_ROCK" : 164,
"SAVANNA_PLATEAU" : 36,
"DARK_FOREST_HILLS" : 157,
"END_MIDLANDS" : 41,
"SHATTERED_SAVANNA_PLATEAU" : 164,
"SAVANNA" : 35,
"MUSHROOM_ISLAND_SHORE" : 15,
"SWAMP" : 6,
"ICE_MOUNTAINS" : 13,
"BEACH" : 16,
"MUTATED_MESA_CLEAR_ROCK" : 167,
"END_HIGHLANDS" : 42,
"COLD_BEACH" : 26,
"JUNGLE" : 21,
"MUTATED_TAIGA_COLD" : 158,
"TALL_BIRCH_HILLS" : 156,
"DARK_FOREST" : 29,
"WOODED_HILLS" : 18,
"HELL" : 8,
"MUTATED_REDWOOD_TAIGA" : 160,
"MESA_PLATEAU_FOREST" : 38,
"MUSHROOM_ISLAND" : 14,
"BADLANDS" : 37,
"END_BARRENS" : 43,
"MUTATED_EXTREME_HILLS_WITH_TREES" : 162,
"MUTATED_JUNGLE_EDGE" : 151,
"MODIFIED_BADLANDS_PLATEAU" : 167,
"ROOFED_FOREST_MOUNTAINS" : 157,
"SOUL_SAND_VALLEY" : 170,
"DESERT" : 2,
"MUTATED_PLAINS" : 129,
"MUTATED_BIRCH_FOREST" : 155,
"WOODED_MOUNTAINS" : 34,
"TAIGA_HILLS" : 19,
"BAMBOO_JUNGLE" : 168,
"SWAMPLAND_MOUNTAINS" : 134,
"DESERT_MOUNTAINS" : 130,
"REDWOOD_TAIGA" : 32,
"MUSHROOM_FIELDS" : 14,
"GIANT_TREE_TAIGA_HILLS" : 33,
"PLAINS" : 1,
"JUNGLE_EDGE" : 23,
"SAVANNA_MOUNTAINS" : 163,
"DEEP_COLD_OCEAN" : 49,
"DESERT_LAKES" : 130,
"MOUNTAIN_EDGE" : 20,
"SNOWY_MOUNTAINS" : 13,
"MESA_PLATEAU_MOUNTAINS" : 167,
"JUNGLE_MOUNTAINS" : 149,
"SMALLER_EXTREME_HILLS" : 20,
"MESA_PLATEAU_FOREST_MOUNTAINS" : 166,
"NETHER_WASTES" : 8,
"BIRCH_FOREST_HILLS_MOUNTAINS" : 156,
"MUTATED_JUNGLE" : 149,
"WARM_OCEAN" : 44,
"DEEP_OCEAN" : 24,
"STONE_BEACH" : 25,
"MODIFIED_JUNGLE" : 149,
"MUTATED_SAVANNA" : 163,
"TAIGA_COLD_HILLS" : 31,
"OCEAN" : 0,
"SMALL_END_ISLANDS" : 40,
"MUSHROOM_FIELD_SHORE" : 15,
"GRAVELLY_MOUNTAINS" : 131,
"FROZEN_RIVER" : 11,
"TAIGA_COLD" : 30,
"BASALT_DELTAS" : 173,
"EXTREME_HILLS_WITH_TREES" : 34,
"MEGA_TAIGA_HILLS" : 33,
"MUTATED_FOREST" : 132,
"MUTATED_BIRCH_FOREST_HILLS" : 156,
"SKY" : 9,
"LUKEWARM_OCEAN" : 45,
"EXTREME_HILLS_MOUNTAINS" : 131,
"COLD_TAIGA_HILLS" : 31,
"THE_END" : 9,
"SUNFLOWER_PLAINS" : 129,
"SAVANNA_ROCK" : 36,
"ERODED_BADLANDS" : 165,
"STONE_SHORE" : 25,
"EXTREME_HILLS_PLUS_MOUNTAINS" : 162,
"CRIMSON_FOREST" : 171,
"VOID" : 127,
"SNOWY_TAIGA" : 30,
"SNOWY_TAIGA_MOUNTAINS" : 158,
"FLOWER_FOREST" : 132,
"COLD_OCEAN" : 46,
"BEACHES" : 16,
"MESA" : 37,
"MUSHROOM_SHORE" : 15,
"MESA_CLEAR_ROCK" : 39,
"NETHER" : 8,
"ICE_PLAINS" : 12,
"SHATTERED_SAVANNA" : 163,
"ROOFED_FOREST" : 29,
"GIANT_SPRUCE_TAIGA_HILLS" : 161,
"SNOWY_BEACH" : 26,
"MESA_BRYCE" : 165,
"JUNGLE_EDGE_MOUNTAINS" : 151,
"MUTATED_DESERT" : 130,
"MODIFIED_GRAVELLY_MOUNTAINS" : 158,
"MEGA_SPRUCE_TAIGA" : 160,
"TAIGA_MOUNTAINS" : 133,
"SMALL_MOUNTAINS" : 20,
"EXTREME_HILLS_PLUS" : 34,
"GIANT_SPRUCE_TAIGA" : 160,
"FOREST_HILLS" : 18,
"DESERT_HILLS" : 17,
"MUTATED_REDWOOD_TAIGA_HILLS" : 161,
"MEGA_SPRUCE_TAIGA_HILLS" : 161,
"RIVER" : 7,
"GIANT_TREE_TAIGA" : 32,
"SWAMPLAND" : 6,
"JUNGLE_HILLS" : 22,
"TALL_BIRCH_FOREST" : 155,
"DEEP_LUKEWARM_OCEAN" : 48,
"MESA_ROCK" : 38,
"SWAMP_HILLS" : 134,
"MODIFIED_WOODED_BADLANDS_PLATEAU" : 166,
"MODIFIED_JUNGLE_EDGE" : 151,
"BIRCH_FOREST_HILLS" : 28,
"COLD_TAIGA" : 30,
"TAIGA" : 5,
"MUTATED_MESA_ROCK" : 166,
"MUTATED_SWAMPLAND" : 134,
"ICE_FLATS" : 12,
"MUTATED_ROOFED_FOREST" : 157,
"MUTATED_MESA" : 165,
"MUTATED_EXTREME_HILLS" : 131
}

View File

@ -1,8 +1,10 @@
main: org.geysermc.platform.bukkit.GeyserBukkitPlugin
name: ${outputName}-Bukkit
main: org.geysermc.platform.spigot.GeyserSpigotPlugin
name: ${outputName}-Spigot
author: ${project.organization.name}
website: ${project.organization.url}
version: ${project.version}
softdepend: ["ViaVersion"]
api-version: 1.13
commands:
geyser:
description: The main command for Geyser.

View File

@ -6,15 +6,15 @@
<parent>
<groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../</relativePath>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>bootstrap-sponge</artifactId>
<dependencies>
<dependency>
<groupId>org.geysermc</groupId>
<artifactId>connector</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
@ -69,6 +69,26 @@
<pattern>it.unimi.dsi.fastutil</pattern>
<shadedPattern>org.geysermc.platform.sponge.shaded.fastutil</shadedPattern>
</relocation>
<relocation>
<pattern>org.reflections</pattern>
<shadedPattern>org.geysermc.platform.sponge.shaded.reflections</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>org.geysermc.platform.sponge.shaded.google.common</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.guava</pattern>
<shadedPattern>org.geysermc.platform.sponge.shaded.google.guava</shadedPattern>
</relocation>
<relocation>
<pattern>org.dom4j</pattern>
<shadedPattern>org.geysermc.platform.sponge.shaded.dom4j</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori</pattern>
<shadedPattern>org.geysermc.platform.sponge.shaded.kyori</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,181 +25,13 @@
package org.geysermc.platform.sponge;
import lombok.AllArgsConstructor;
import org.geysermc.connector.configuration.GeyserJacksonConfiguration;
import ninja.leaping.configurate.ConfigurationNode;
import org.geysermc.connector.GeyserConfiguration;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
public class GeyserSpongeConfiguration implements GeyserConfiguration {
private File dataFolder;
private ConfigurationNode node;
private SpongeBedrockConfiguration bedrockConfig;
private SpongeRemoteConfiguration remoteConfig;
private SpongeMetricsInfo metricsInfo;
private Map<String, SpongeUserAuthenticationInfo> userAuthInfo = new HashMap<>();
public GeyserSpongeConfiguration(File dataFolder, ConfigurationNode node) {
this.dataFolder = dataFolder;
this.node = node;
this.bedrockConfig = new SpongeBedrockConfiguration(node.getNode("bedrock"));
this.remoteConfig = new SpongeRemoteConfiguration(node.getNode("remote"));
this.metricsInfo = new SpongeMetricsInfo();
if (node.getNode("userAuths").getValue() == null)
return;
List<String> userAuths = new ArrayList<String>(((LinkedHashMap)node.getNode("userAuths").getValue()).keySet());
for (String key : userAuths) {
userAuthInfo.put(key, new SpongeUserAuthenticationInfo(key));
}
}
public final class GeyserSpongeConfiguration extends GeyserJacksonConfiguration {
@Override
public SpongeBedrockConfiguration getBedrock() {
return bedrockConfig;
}
@Override
public SpongeRemoteConfiguration getRemote() {
return remoteConfig;
}
@Override
public Map<String, SpongeUserAuthenticationInfo> getUserAuths() {
return userAuthInfo;
}
@Override
public boolean isPingPassthrough() {
return node.getNode("ping-passthrough").getBoolean(false);
}
@Override
public int getMaxPlayers() {
return node.getNode("max-players").getInt(100);
}
@Override
public boolean isDebugMode() {
return node.getNode("debug-mode").getBoolean(false);
}
@Override
public int getGeneralThreadPool() {
return node.getNode("genereal-thread-pool").getInt(32);
}
@Override
public boolean isAllowThirdPartyCapes() {
return node.getNode("allow-third-party-capes").getBoolean(true);
}
@Override
public String getDefaultLocale() {
return node.getNode("default-locale").getString("en_us");
}
@Override
public Path getFloodgateKeyFile() {
return Paths.get(dataFolder.toString(), node.getNode("floodgate-key-file").getString("public-key.pem"));
}
@Override
public boolean isCacheChunks() {
return node.getNode("cache-chunks").getBoolean(false);
}
@Override
public SpongeMetricsInfo getMetrics() {
return metricsInfo;
}
@AllArgsConstructor
public class SpongeBedrockConfiguration implements IBedrockConfiguration {
private ConfigurationNode node;
@Override
public String getAddress() {
return node.getNode("address").getString("0.0.0.0");
}
@Override
public int getPort() {
return node.getNode("port").getInt(19132);
}
@Override
public String getMotd1() {
return node.getNode("motd1").getString("GeyserMC");
}
@Override
public String getMotd2() {
return node.getNode("motd2").getString("GeyserMC");
}
}
@AllArgsConstructor
public class SpongeRemoteConfiguration implements IRemoteConfiguration {
private ConfigurationNode node;
@Override
public String getAddress() {
return node.getNode("address").getString("127.0.0.1");
}
@Override
public int getPort() {
return node.getNode("port").getInt(25565);
}
@Override
public String getAuthType() {
return node.getNode("auth-type").getString("online");
}
}
public class SpongeUserAuthenticationInfo implements IUserAuthenticationInfo {
private String key;
public SpongeUserAuthenticationInfo(String key) {
this.key = key;
}
@Override
public String getEmail() {
return node.getNode("userAuths").getNode(key).getNode("email").getString();
}
@Override
public String getPassword() {
return node.getNode("userAuths").getNode(key).getNode("password").getString();
}
}
public class SpongeMetricsInfo implements IMetricsInfo {
@Override
public boolean isEnabled() {
return node.getNode("metrics").getNode("enabled").getBoolean(true);
}
@Override
public String getUniqueId() {
return node.getNode("metrics").getNode("uuid").getString("generateduuid");
}
public Path getFloodgateKeyPath() {
return null; //floodgate isn't available for Sponge
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.sponge;
import lombok.Getter;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import org.spongepowered.api.Platform;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.plugin.PluginContainer;
import java.util.ArrayList;
import java.util.List;
@Getter
public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
private String platformName;
private String platformVersion;
private boolean onlineMode;
private String serverIP;
private int serverPort;
private List<PluginInfo> plugins;
GeyserSpongeDumpInfo() {
super();
PluginContainer container = Sponge.getPlatform().getContainer(Platform.Component.IMPLEMENTATION);
this.platformName = container.getName();
this.platformVersion = container.getVersion().get();
this.onlineMode = Sponge.getServer().getOnlineMode();
this.serverIP = Sponge.getServer().getBoundAddress().get().getHostString();
this.serverPort = Sponge.getServer().getBoundAddress().get().getPort();
this.plugins = new ArrayList<>();
for (PluginContainer plugin : Sponge.getPluginManager().getPlugins()) {
String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown");
this.plugins.add(new PluginInfo(true, plugin.getName(), plugin.getVersion().get(), pluginClass, plugin.getAuthors()));
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,15 +26,16 @@
package org.geysermc.platform.sponge;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.geysermc.connector.GeyserLogger;
import org.slf4j.Logger;
@AllArgsConstructor
public class GeyserSpongeLogger implements GeyserLogger {
private Logger logger;
private boolean debugMode;
private final Logger logger;
@Getter @Setter
private boolean debug;
@Override
public void severe(String message) {
@ -68,12 +69,8 @@ public class GeyserSpongeLogger implements GeyserLogger {
@Override
public void debug(String message) {
if (debugMode)
if (debug) {
info(message);
}
@Override
public void setDebug(boolean debugMode) {
this.debugMode = debugMode;
}
}
}

View File

@ -1,32 +1,31 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.sponge;
import org.geysermc.common.main.IGeyserMain;
import org.geysermc.connector.common.main.IGeyserMain;
public class GeyserSpongeMain extends IGeyserMain {

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.sponge;
import com.github.steveice10.mc.protocol.MinecraftConstants;
import org.geysermc.connector.common.ping.GeyserPingInfo;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import org.spongepowered.api.MinecraftVersion;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.event.SpongeEventFactory;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.cause.EventContext;
import org.spongepowered.api.event.server.ClientPingServerEvent;
import org.spongepowered.api.network.status.StatusClient;
import org.spongepowered.api.profile.GameProfile;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.util.Optional;
public class GeyserSpongePingPassthrough implements IGeyserPingPassthrough {
private static final Cause CAUSE = Cause.of(EventContext.empty(), Sponge.getServer());
private static Method SpongeStatusResponse_create;
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public GeyserPingInfo getPingInformation(InetSocketAddress inetSocketAddress) {
// come on Sponge, this is in commons, why not expose it :(
ClientPingServerEvent event;
try {
if (SpongeStatusResponse_create == null) {
Class SpongeStatusResponse = Class.forName("org.spongepowered.common.network.status.SpongeStatusResponse");
Class MinecraftServer = Class.forName("net.minecraft.server.MinecraftServer");
SpongeStatusResponse_create = SpongeStatusResponse.getDeclaredMethod("create", MinecraftServer);
}
Object response = SpongeStatusResponse_create.invoke(null, Sponge.getServer());
event = SpongeEventFactory.createClientPingServerEvent(CAUSE, new GeyserStatusClient(inetSocketAddress), (ClientPingServerEvent.Response) response);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
Sponge.getEventManager().post(event);
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
event.getResponse().getDescription().toPlain(),
new GeyserPingInfo.Players(
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getMax(),
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getOnline()
),
new GeyserPingInfo.Version(
event.getResponse().getVersion().getName(),
MinecraftConstants.PROTOCOL_VERSION) // thanks for also not exposing this sponge
);
event.getResponse().getPlayers().get().getProfiles().stream()
.map(GameProfile::getName)
.map(op -> op.orElseThrow(IllegalStateException::new))
.forEach(geyserPingInfo.getPlayerList()::add);
return geyserPingInfo;
}
@SuppressWarnings("NullableProblems")
private static class GeyserStatusClient implements StatusClient {
private final InetSocketAddress remote;
public GeyserStatusClient(InetSocketAddress remote) {
this.remote = remote;
}
@Override
public InetSocketAddress getAddress() {
return this.remote;
}
@Override
public MinecraftVersion getVersion() {
return Sponge.getPlatform().getMinecraftVersion();
}
@Override
public Optional<InetSocketAddress> getVirtualHost() {
return Optional.empty();
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,14 +26,16 @@
package org.geysermc.platform.sponge;
import com.google.inject.Inject;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.loader.ConfigurationLoader;
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.bootstrap.GeyserBootstrap;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor;
import org.geysermc.platform.sponge.command.GeyserSpongeCommandManager;
import org.slf4j.Logger;
@ -47,6 +49,7 @@ import org.spongepowered.api.plugin.Plugin;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.util.UUID;
@Plugin(id = "geyser", name = GeyserConnector.NAME + "-Sponge", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC")
@ -62,6 +65,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
private GeyserSpongeCommandManager geyserCommandManager;
private GeyserSpongeConfiguration geyserConfig;
private GeyserSpongeLogger geyserLogger;
private IGeyserPingPassthrough geyserSpongePingPassthrough;
private GeyserConnector connector;
@ -74,40 +78,44 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
try {
configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString()));
} catch (IOException ex) {
logger.warn("Failed to copy config.yml from jar path!");
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"));
ex.printStackTrace();
}
ConfigurationLoader loader = YAMLConfigurationLoader.builder().setPath(configFile.toPath()).build();
ConfigurationNode config;
try {
config = loader.load();
this.geyserConfig = new GeyserSpongeConfiguration(configDir, config);
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpongeConfiguration.class);
} catch (IOException ex) {
logger.warn("Failed to load config.yml!");
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"));
ex.printStackTrace();
return;
}
ConfigurationNode serverIP = config.getNode("remote").getNode("address");
ConfigurationNode serverPort = config.getNode("remote").getNode("port");
if (Sponge.getServer().getBoundAddress().isPresent()) {
InetSocketAddress javaAddr = Sponge.getServer().getBoundAddress().get();
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!javaAddr.getHostString().equals("0.0.0.0")) {
serverIP.setValue("127.0.0.1");
if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) {
this.geyserConfig.setAutoconfiguredRemote(true);
geyserConfig.getRemote().setPort(javaAddr.getPort());
}
}
serverPort.setValue(javaAddr.getPort());
if (geyserConfig.getBedrock().isCloneRemotePort()){
geyserConfig.getBedrock().setPort(geyserConfig.getRemote().getPort());
}
this.geyserLogger = new GeyserSpongeLogger(logger, geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
this.connector = GeyserConnector.start(PlatformType.SPONGE, this);
this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), connector);
if (geyserConfig.isLegacyPingPassthrough()) {
this.geyserSpongePingPassthrough = GeyserLegacyPingPassthrough.init(connector);
} else {
this.geyserSpongePingPassthrough = new GeyserSpongePingPassthrough();
}
this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), connector);
Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(connector), "geyser");
}
@ -131,6 +139,16 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
return this.geyserCommandManager;
}
@Override
public IGeyserPingPassthrough getGeyserPingPassthrough() {
return geyserSpongePingPassthrough;
}
@Override
public Path getConfigFolder() {
return configDir.toPath();
}
@Listener
public void onServerStart(GameStartedServerEvent event) {
onEnable();
@ -140,4 +158,9 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
public void onServerStop(GameStoppedEvent event) {
onDisable();
}
@Override
public BootstrapDumpInfo getDumpInfo() {
return new GeyserSpongeDumpInfo();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,10 +26,10 @@
package org.geysermc.platform.sponge.command;
import lombok.AllArgsConstructor;
import org.geysermc.common.ChatColor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.common.ChatColor;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.utils.LanguageUtils;
import org.spongepowered.api.command.CommandCallable;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.command.CommandResult;
@ -55,13 +55,14 @@ public class GeyserSpongeCommandExecutor implements CommandCallable {
if (args.length > 0) {
if (getCommand(args[0]) != null) {
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
source.sendMessage(Text.of(ChatColor.RED + "You do not have permission to execute this command!"));
// Not ideal to use log here but we dont get a session
source.sendMessage(Text.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
return CommandResult.success();
}
getCommand(args[0]).execute(new SpongeCommandSender(source), args);
getCommand(args[0]).execute(new SpongeCommandSender(source), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
}
} else {
getCommand("help").execute(new SpongeCommandSender(source), args);
getCommand("help").execute(new SpongeCommandSender(source), new String[0]);
}
return CommandResult.success();
}
@ -69,7 +70,7 @@ public class GeyserSpongeCommandExecutor implements CommandCallable {
@Override
public List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> targetPosition) throws CommandException {
if (arguments.split(" ").length == 1) {
return Arrays.asList("?", "help", "reload", "shutdown", "stop");
return connector.getCommandManager().getCommandNames();
}
return new ArrayList<>();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -6,21 +6,21 @@
<parent>
<groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../</relativePath>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>bootstrap-standalone</artifactId>
<dependencies>
<dependency>
<groupId>org.geysermc</groupId>
<artifactId>connector</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.minecrell</groupId>
<artifactId>terminalconsoleappender</artifactId>
<version>1.1.1</version>
<version>1.2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
@ -63,7 +63,7 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.1</version>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,47 +25,221 @@
package org.geysermc.platform.standalone;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import lombok.Getter;
import net.minecrell.terminalconsole.TerminalConsoleAppender;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConfiguration;
import org.geysermc.connector.bootstrap.GeyserBootstrap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.bootstrap.GeyserBootstrap;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.configuration.GeyserJacksonConfiguration;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.platform.standalone.command.GeyserCommandManager;
import org.geysermc.platform.standalone.gui.GeyserStandaloneGUI;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;
public class GeyserStandaloneBootstrap implements GeyserBootstrap {
private GeyserCommandManager geyserCommandManager;
private GeyserConfiguration geyserConfig;
private GeyserStandaloneConfiguration geyserConfig;
private GeyserStandaloneLogger geyserLogger;
private IGeyserPingPassthrough geyserPingPassthrough;
private GeyserStandaloneGUI gui;
@Getter
private boolean useGui = System.console() == null && !isHeadless();
private String configFilename = "config.yml";
private GeyserConnector connector;
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final Map<String, String> argsConfigKeys = new HashMap<>();
public static void main(String[] args) {
new GeyserStandaloneBootstrap().onEnable();
GeyserStandaloneBootstrap bootstrap = new GeyserStandaloneBootstrap();
// Set defaults
boolean useGuiOpts = bootstrap.useGui;
String configFilenameOpt = bootstrap.configFilename;
List<BeanPropertyDefinition> availableProperties = getPOJOForClass(GeyserJacksonConfiguration.class);
for (int i = 0; i < args.length; i++) {
// By default, standalone Geyser will check if it should open the GUI based on if the GUI is null
// Optionally, you can force the use of a GUI or no GUI by specifying args
// Allows gui and nogui without options, for backwards compatibility
String arg = args[i];
switch (arg) {
case "--gui":
case "gui":
useGuiOpts = true;
break;
case "--nogui":
case "nogui":
useGuiOpts = false;
break;
case "--config":
case "-c":
if (i >= args.length - 1) {
System.err.println(MessageFormat.format(LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.config_not_specified"), "-c"));
return;
}
configFilenameOpt = args[i+1]; i++;
System.out.println(MessageFormat.format(LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.config_specified"), configFilenameOpt));
break;
case "--help":
case "-h":
System.out.println(MessageFormat.format(LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.usage"), "[java -jar] Geyser.jar [opts]"));
System.out.println(" " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.options"));
System.out.println(" -c, --config [file] " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.config"));
System.out.println(" -h, --help " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.help"));
System.out.println(" --gui, --nogui " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.gui"));
return;
default:
// We have likely added a config option argument
if (arg.startsWith("--")) {
// Split the argument by an =
String[] argParts = arg.substring(2).split("=");
if (argParts.length == 2) {
// Split the config key by . to allow for nested options
String[] configKeyParts = argParts[0].split("\\.");
// Loop the possible config options to check the passed key is valid
boolean found = false;
for (BeanPropertyDefinition property : availableProperties) {
if (configKeyParts[0].equals(property.getName())) {
if (configKeyParts.length > 1) {
// Loop sub-section options to check the passed key is valid
for (BeanPropertyDefinition subProperty : getPOJOForClass(property.getRawPrimaryType())) {
if (configKeyParts[1].equals(subProperty.getName())) {
found = true;
break;
}
}
} else {
found = true;
}
break;
}
}
// Add the found key to the stored list for later usage
if (found) {
argsConfigKeys.put(argParts[0], argParts[1]);
break;
}
}
}
System.err.println(LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.unrecognised", arg));
return;
}
}
bootstrap.onEnable(useGuiOpts, configFilenameOpt);
}
public void onEnable(boolean useGui, String configFilename) {
this.configFilename = configFilename;
this.useGui = useGui;
this.onEnable();
}
public void onEnable(boolean useGui) {
this.useGui = useGui;
this.onEnable();
}
@Override
public void onEnable() {
Logger logger = (Logger) LogManager.getRootLogger();
for (Appender appender : logger.getAppenders().values()) {
// Remove the appender that is not in use
// Prevents multiple appenders/double logging and removes harmless errors
if ((useGui && appender instanceof TerminalConsoleAppender) || (!useGui && appender instanceof ConsoleAppender)) {
logger.removeAppender(appender);
}
}
if (useGui && gui == null) {
gui = new GeyserStandaloneGUI();
gui.redirectSystemStreams();
gui.startUpdateThread();
}
geyserLogger = new GeyserStandaloneLogger();
LoopbackUtil.checkLoopback(geyserLogger);
try {
File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
File configFile = FileUtils.fileOrCopiedFromResource(new File(configFilename), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class);
handleArgsConfigOptions();
if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) {
geyserConfig.setAutoconfiguredRemote(true); // Doesn't really need to be set but /shrug
geyserConfig.getRemote().setAddress("127.0.0.1");
}
} catch (IOException ex) {
geyserLogger.severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
System.exit(0);
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
if (gui == null) {
System.exit(1);
} else {
// Leave the process running so the GUI is still visible
return;
}
}
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
connector = GeyserConnector.start(PlatformType.STANDALONE, this);
geyserCommandManager = new GeyserCommandManager(connector);
geyserLogger.start();
if (gui != null) {
gui.setupInterface(geyserLogger, geyserCommandManager);
}
geyserPingPassthrough = GeyserLegacyPingPassthrough.init(connector);
if (!useGui) {
geyserLogger.start(); // Throws an error otherwise
}
}
/**
* Check using {@link java.awt.GraphicsEnvironment} that we are a headless client
*
* @return If the current environment is headless
*/
private boolean isHeadless() {
try {
Class<?> graphicsEnv = Class.forName("java.awt.GraphicsEnvironment");
Method isHeadless = graphicsEnv.getDeclaredMethod("isHeadless");
return (boolean) isHeadless.invoke(null);
} catch (Exception ignore) { }
return true;
}
@Override
@ -88,4 +262,115 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
public CommandManager getGeyserCommandManager() {
return geyserCommandManager;
}
@Override
public IGeyserPingPassthrough getGeyserPingPassthrough() {
return geyserPingPassthrough;
}
@Override
public Path getConfigFolder() {
// Return the current working directory
return Paths.get(System.getProperty("user.dir"));
}
@Override
public BootstrapDumpInfo getDumpInfo() {
return new GeyserStandaloneDumpInfo(this);
}
/**
* Get the {@link BeanPropertyDefinition}s for the given class
*
* @param clazz The class to get the definitions for
* @return A list of {@link BeanPropertyDefinition} for the given class
*/
public static List<BeanPropertyDefinition> getPOJOForClass(Class<?> clazz) {
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructType(clazz);
// Introspect the given type
BeanDescription beanDescription = OBJECT_MAPPER.getSerializationConfig().introspect(javaType);
// Find properties
List<BeanPropertyDefinition> properties = beanDescription.findProperties();
// Get the ignored properties
Set<String> ignoredProperties = OBJECT_MAPPER.getSerializationConfig().getAnnotationIntrospector()
.findPropertyIgnorals(beanDescription.getClassInfo()).getIgnored();
// Filter properties removing the ignored ones
return properties.stream()
.filter(property -> !ignoredProperties.contains(property.getName()))
.collect(Collectors.toList());
}
/**
* Set a POJO property value on an object
*
* @param property The {@link BeanPropertyDefinition} to set
* @param parentObject The object to alter
* @param value The new value of the property
*/
private static void setConfigOption(BeanPropertyDefinition property, Object parentObject, Object value) {
Object parsedValue = value;
// Change the values type if needed
if (int.class.equals(property.getRawPrimaryType())) {
parsedValue = Integer.valueOf((String) parsedValue);
} else if (boolean.class.equals(property.getRawPrimaryType())) {
parsedValue = Boolean.valueOf((String) parsedValue);
}
// Force the value to be set
AnnotatedField field = property.getField();
field.fixAccess(true);
field.setValue(parentObject, parsedValue);
}
/**
* Update the loaded {@link GeyserStandaloneConfiguration} with any values passed in the command line arguments
*/
private void handleArgsConfigOptions() {
// Get the available properties from the class
List<BeanPropertyDefinition> availableProperties = getPOJOForClass(GeyserJacksonConfiguration.class);
for (Map.Entry<String, String> configKey : argsConfigKeys.entrySet()) {
String[] configKeyParts = configKey.getKey().split("\\.");
// Loop over the properties looking for any matches against the stored one from the argument
for (BeanPropertyDefinition property : availableProperties) {
if (configKeyParts[0].equals(property.getName())) {
if (configKeyParts.length > 1) {
// Loop through the sub property if the first part matches
for (BeanPropertyDefinition subProperty : getPOJOForClass(property.getRawPrimaryType())) {
if (configKeyParts[1].equals(subProperty.getName())) {
geyserLogger.info(LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.set_config_option", configKey.getKey(), configKey.getValue()));
// Set the sub property value on the config
try {
Object subConfig = property.getGetter().callOn(geyserConfig);
setConfigOption(subProperty, subConfig, configKey.getValue());
} catch (Exception e) {
geyserLogger.error("Failed to set config option: " + property.getFullName());
}
break;
}
}
} else {
geyserLogger.info(LanguageUtils.getLocaleStringLog("geyser.bootstrap.args.set_config_option", configKey.getKey(), configKey.getValue()));
// Set the property value on the config
try {
setConfigOption(property, geyserConfig, configKey.getValue());
} catch (Exception e) {
geyserLogger.error("Failed to set config option: " + property.getFullName());
}
}
break;
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,90 +26,17 @@
package org.geysermc.platform.standalone;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import org.geysermc.connector.GeyserConfiguration;
import org.geysermc.connector.configuration.GeyserJacksonConfiguration;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
public class GeyserStandaloneConfiguration implements GeyserConfiguration {
private BedrockConfiguration bedrock;
private RemoteConfiguration remote;
@JsonProperty("floodgate-key-file")
private String floodgateKeyFile;
private Map<String, UserAuthenticationInfo> userAuths;
@JsonProperty("ping-passthrough")
private boolean pingPassthrough;
@JsonProperty("max-players")
private int maxPlayers;
@JsonProperty("debug-mode")
private boolean debugMode;
@JsonProperty("general-thread-pool")
private int generalThreadPool;
@JsonProperty("allow-third-party-capes")
private boolean allowThirdPartyCapes;
@JsonProperty("default-locale")
private String defaultLocale;
@JsonProperty("cache-chunks")
private boolean cacheChunks;
private MetricsInfo metrics;
@JsonIgnoreProperties(ignoreUnknown = true)
public final class GeyserStandaloneConfiguration extends GeyserJacksonConfiguration {
@Override
public Path getFloodgateKeyFile() {
return Paths.get(floodgateKeyFile);
}
@Getter
public static class BedrockConfiguration implements IBedrockConfiguration {
private String address;
private int port;
private String motd1;
private String motd2;
}
@Getter
public static class RemoteConfiguration implements IRemoteConfiguration {
private String address;
private int port;
private String motd1;
private String motd2;
@JsonProperty("auth-type")
private String authType;
}
@Getter
public static class UserAuthenticationInfo implements IUserAuthenticationInfo {
private String email;
private String password;
}
@Getter
public static class MetricsInfo implements IMetricsInfo {
private boolean enabled;
@JsonProperty("uuid")
private String uniqueId;
public Path getFloodgateKeyPath() {
return Paths.get(getFloodgateKeyFile());
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.standalone;
import lombok.Getter;
import org.geysermc.connector.dump.BootstrapDumpInfo;
@Getter
public class GeyserStandaloneDumpInfo extends BootstrapDumpInfo {
private boolean isGui;
GeyserStandaloneDumpInfo(GeyserStandaloneBootstrap bootstrap) {
super();
this.isGui = bootstrap.isUseGui();
}
}

View File

@ -1,43 +1,41 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.standalone;
import lombok.extern.log4j.Log4j2;
import net.minecrell.terminalconsole.SimpleTerminalConsole;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import org.geysermc.common.ChatColor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.GeyserLogger;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.common.ChatColor;
@Log4j2
public class GeyserStandaloneLogger extends SimpleTerminalConsole implements org.geysermc.connector.GeyserLogger, CommandSender {
public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger, CommandSender {
private boolean colored = true;
@Override
@ -82,7 +80,7 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements org
@Override
public void info(String message) {
log.info(printConsole(ChatColor.WHITE + message, colored));
log.info(printConsole(ChatColor.RESET + ChatColor.BOLD + message, colored));
}
@Override
@ -96,7 +94,11 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements org
@Override
public void setDebug(boolean debug) {
Configurator.setLevel(log.getName(), debug ? org.apache.logging.log4j.Level.DEBUG : log.getLevel());
Configurator.setLevel(log.getName(), debug ? Level.DEBUG : Level.INFO);
}
public boolean isDebug() {
return log.isDebugEnabled();
}
@Override

View File

@ -1,12 +1,38 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.standalone;
import org.geysermc.connector.common.ChatColor;
import org.geysermc.connector.utils.LanguageUtils;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Paths;
import org.geysermc.common.ChatColor;
public class LoopbackUtil {
private static final String checkExemption = "powershell -Command \"CheckNetIsolation LoopbackExempt -s\""; // Java's Exec feature runs as CMD, NetIsolation is only accessible from PowerShell.
private static final String loopbackCommand = "powershell -Command \"CheckNetIsolation LoopbackExempt -a -n='Microsoft.MinecraftUWP_8wekyb3d8bbwe'\"";
@ -31,12 +57,12 @@ public class LoopbackUtil {
Files.write(Paths.get(System.getenv("temp") + "/loopback_minecraft.bat"), loopbackCommand.getBytes(), new OpenOption[0]);
process = Runtime.getRuntime().exec(startScript);
geyserLogger.info(ChatColor.AQUA + "Added loopback exemption to Windows!");
geyserLogger.info(ChatColor.AQUA + LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.added"));
}
} catch (Exception e) {
e.printStackTrace();
geyserLogger.error("Couldn't auto add loopback exemption to Windows!");
geyserLogger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.failed"));
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.standalone.gui;
import lombok.Getter;
import java.awt.*;
import java.util.regex.Pattern;
public enum ANSIColor {
// Normal colors
BLACK("(0;)?30(0;)?m", Color.getHSBColor(0.000f, 0.000f, 0.000f)),
RED("(0;)?31(0;)?m", Color.getHSBColor(0.000f, 1.000f, 0.502f)),
GREEN("(0;)?32(0;)?m", Color.getHSBColor(0.333f, 1.000f, 0.502f)),
YELLOW("(0;)?33(0;)?m", Color.getHSBColor(0.167f, 1.000f, 0.502f)),
BLUE("(0;)?34(0;)?m", Color.getHSBColor(0.667f, 1.000f, 0.502f)),
MAGENTA("(0;)?35(0;)?m", Color.getHSBColor(0.833f, 1.000f, 0.502f)),
CYAN("(0;)?36(0;)?m", Color.getHSBColor(0.500f, 1.000f, 0.502f)),
WHITE("(0;)?37(0;)?m", Color.getHSBColor(0.000f, 0.000f, 0.753f)),
// Bold colors
B_BLACK("(1;30|30;1)m", Color.getHSBColor(0.000f, 0.000f, 0.502f)),
B_RED("(1;31|31;1)m", Color.getHSBColor(0.000f, 1.000f, 1.000f)),
B_GREEN("(1;32|32;1)m", Color.getHSBColor(0.333f, 1.000f, 1.000f)),
B_YELLOW("(1;33|33;1)m", Color.getHSBColor(0.167f, 1.000f, 1.000f)),
B_BLUE("(1;34|34;1)m", Color.getHSBColor(0.667f, 1.000f, 1.000f)),
B_MAGENTA("(1;35|35;1)m", Color.getHSBColor(0.833f, 1.000f, 1.000f)),
B_CYAN("(1;36|36;1)m", Color.getHSBColor(0.500f, 1.000f, 1.000f)),
B_WHITE("(1;37|37;1)m", Color.getHSBColor(0.000f, 0.000f, 1.000f)),
RESET("0m", Color.getHSBColor(0.000f, 0.000f, 1.000f));
private static final ANSIColor[] VALUES = values();
private static final String PREFIX = Pattern.quote("\u001B[");
private final String ANSICode;
@Getter
private final Color color;
ANSIColor(String ANSICode, Color color) {
this.ANSICode = ANSICode;
this.color = color;
}
public static ANSIColor fromANSI(String code) {
for (ANSIColor value : VALUES) {
if (code.matches(PREFIX + value.ANSICode)) {
return value;
}
}
return B_WHITE;
}
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.standalone.gui;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
/**
* This class was based on this code: https://stackoverflow.com/a/6899478/5299903
*/
public class ColorPane extends JTextPane {
private static Color colorCurrent = ANSIColor.RESET.getColor();
private String remaining = "";
/**
* Append the given string in the given color to the text pane
* @param c The color
* @param s The text
*/
private void append(Color c, String s) {
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);
int len = getDocument().getLength();
try {
getDocument().insertString(len, s, aset);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
/**
* Extract the ANSI color codes from the string and add each part to the text pane
*
* @param s The text to parse
*/
public void appendANSI(String s) { // convert ANSI color codes first
int aPos = 0; // current char position in addString
int aIndex = 0; // index of next Escape sequence
int mIndex = 0; // index of "m" terminating Escape sequence
String tmpString = "";
boolean stillSearching = true; // true until no more Escape sequences
String addString = remaining + s;
remaining = "";
if (addString.length() > 0) {
aIndex = addString.indexOf("\u001B"); // find first escape
if (aIndex == -1) { // no escape/color change in this string, so just send it with current color
append(colorCurrent, addString);
return;
}
// otherwise There is an escape character in the string, so we must process it
if (aIndex > 0) { // Escape is not first char, so send text up to first escape
tmpString = addString.substring(0, aIndex);
append(colorCurrent, tmpString);
aPos = aIndex; // aPos is now at the beginning of the first escape sequence
}
// while there's text in the input buffer
stillSearching = true;
while (stillSearching) {
mIndex = addString.indexOf("m", aPos); // find the end of the escape sequence
if (mIndex < 0) { // the buffer ends halfway through the ansi string!
remaining = addString.substring(aPos, addString.length());
stillSearching = false;
continue;
} else {
tmpString = addString.substring(aPos, mIndex+1);
colorCurrent = ANSIColor.fromANSI(tmpString).getColor();
}
aPos = mIndex + 1;
// now we have the color, send text that is in that color (up to next escape)
aIndex = addString.indexOf("\u001B", aPos);
if (aIndex == -1) { // if that was the last sequence of the input, send remaining text
tmpString = addString.substring(aPos, addString.length());
append(colorCurrent, tmpString);
stillSearching = false;
continue; // jump out of loop early, as the whole string has been sent now
}
// there is another escape sequence, so send part of the string and prepare for the next
tmpString = addString.substring(aPos, aIndex);
aPos = aIndex;
append(colorCurrent, tmpString);
}
}
}
}

View File

@ -0,0 +1,355 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.standalone.gui;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.platform.standalone.GeyserStandaloneLogger;
import org.geysermc.platform.standalone.command.GeyserCommandManager;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.Document;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class GeyserStandaloneGUI {
private static final DefaultTableModel playerTableModel = new DefaultTableModel();
private static final List<Integer> ramValues = new ArrayList<>();
private static final ColorPane consolePane = new ColorPane();
private static final GraphPanel ramGraph = new GraphPanel();
private static final JTable playerTable = new JTable(playerTableModel);
private static final int originalFontSize = consolePane.getFont().getSize();
private static final long MEGABYTE = 1024L * 1024L;
private final JMenu commandsMenu;
private final JMenu optionsMenu;
public GeyserStandaloneGUI() {
// Create the frame and setup basic settings
JFrame frame = new JFrame(LanguageUtils.getLocaleStringLog("geyser.gui.title"));
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setSize(800, 400);
frame.setMinimumSize(frame.getSize());
// Remove Java UI look
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ignored) { }
// Show a confirm dialog on close
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we)
{
String[] buttons = {LanguageUtils.getLocaleStringLog("geyser.gui.exit.confirm"), LanguageUtils.getLocaleStringLog("geyser.gui.exit.deny")};
int result = JOptionPane.showOptionDialog(frame, LanguageUtils.getLocaleStringLog("geyser.gui.exit.message"), frame.getTitle(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttons, buttons[1]);
if (result == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
Container cp = frame.getContentPane();
// Fetch and set the icon for the frame
URL image = getClass().getClassLoader().getResource("icon.png");
if (image != null) {
ImageIcon icon = new ImageIcon(image);
frame.setIconImage(icon.getImage());
}
// Setup the split pane and event listeners
JSplitPane splitPane = new JSplitPane();
splitPane.setDividerLocation(600);
splitPane.addPropertyChangeListener("dividerLocation", e -> splitPaneLimit((JSplitPane)e.getSource()));
splitPane.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
splitPaneLimit((JSplitPane)e.getSource());
}
});
cp.add(splitPane, BorderLayout.CENTER);
// Set the background and disable input for the text pane
consolePane.setBackground(Color.BLACK);
consolePane.setEditable(false);
// Wrap the text pane in a scroll pane and add it to the form
JScrollPane consoleScrollPane = new JScrollPane(consolePane);
//cp.add(consoleScrollPane, BorderLayout.CENTER);
splitPane.setLeftComponent(consoleScrollPane);
// Create a new menu bar for the top of the frame
JMenuBar menuBar = new JMenuBar();
// Create 'File'
JMenu fileMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file"));
fileMenu.setMnemonic(KeyEvent.VK_F);
menuBar.add(fileMenu);
// 'Open Geyser folder' button
JMenuItem openButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.open_folder"), KeyEvent.VK_O);
openButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
openButton.addActionListener(e -> {
try {
Desktop.getDesktop().open(new File("./"));
} catch (IOException ignored) { }
});
fileMenu.add(openButton);
fileMenu.addSeparator();
// 'Exit' button
JMenuItem exitButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.exit"), KeyEvent.VK_X);
exitButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_MASK));
exitButton.addActionListener(e -> System.exit(0));
fileMenu.add(exitButton);
// Create 'Commands'
commandsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.commands"));
commandsMenu.setMnemonic(KeyEvent.VK_C);
menuBar.add(commandsMenu);
// Create 'View'
JMenu viewMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view"));
viewMenu.setMnemonic(KeyEvent.VK_V);
menuBar.add(viewMenu);
// 'Zoom in' button
JMenuItem zoomInButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_in"));
zoomInButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK));
zoomInButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() + 1)));
viewMenu.add(zoomInButton);
// 'Zoom in' button
JMenuItem zoomOutButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_out"));
zoomOutButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK));
zoomOutButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() - 1)));
viewMenu.add(zoomOutButton);
// 'Reset Zoom' button
JMenuItem resetZoomButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.reset_zoom"));
resetZoomButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), originalFontSize)));
viewMenu.add(resetZoomButton);
// create 'Options'
optionsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options"));
viewMenu.setMnemonic(KeyEvent.VK_O);
menuBar.add(optionsMenu);
// Set the frames menu bar
frame.setJMenuBar(menuBar);
JPanel rightPane = new JPanel();
rightPane.setLayout(new CardLayout(5, 5));
//cp.add(rightPane, BorderLayout.EAST);
splitPane.setRightComponent(rightPane);
JPanel rightContentPane = new JPanel();
rightContentPane.setLayout(new GridLayout(2, 1, 5, 5));
rightPane.add(rightContentPane);
// Set the ram graph to 0
for (int i = 0; i < 10; i++) {
ramValues.add(0);
}
ramGraph.setValues(ramValues);
ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.loading"));
rightContentPane.add(ramGraph);
playerTableModel.addColumn(LanguageUtils.getLocaleStringLog("geyser.gui.table.ip"));
playerTableModel.addColumn(LanguageUtils.getLocaleStringLog("geyser.gui.table.username"));
JScrollPane playerScrollPane = new JScrollPane(playerTable);
rightContentPane.add(playerScrollPane);
// This has to be done last
frame.setVisible(true);
}
/**
* Queue up an update to the text pane so we don't block the main thread
*
* @param text The text to append
*/
private void updateTextPane(final String text) {
SwingUtilities.invokeLater(() -> {
consolePane.appendANSI(text);
Document doc = consolePane.getDocument();
consolePane.setCaretPosition(doc.getLength());
});
}
/**
* Redirect the default io streams to the text pane
*/
public void redirectSystemStreams() {
// Setup a new output stream to forward it to the text pane
OutputStream out = new OutputStream() {
@Override
public void write(final int b) {
updateTextPane(String.valueOf((char) b));
}
@Override
public void write(byte[] b, int off, int len) {
updateTextPane(new String(b, off, len));
}
@Override
public void write(byte[] b) {
write(b, 0, b.length);
}
};
// Override the system output streams
System.setOut(new PrintStream(out, true));
System.setErr(new PrintStream(out, true));
}
/**
* Add all the Geyser commands to the commands menu, and setup the debug mode toggle
*
* @param geyserStandaloneLogger The current logger
* @param geyserCommandManager The commands manager
*/
public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, GeyserCommandManager geyserCommandManager) {
commandsMenu.removeAll();
optionsMenu.removeAll();
for (Map.Entry<String, GeyserCommand> command : geyserCommandManager.getCommands().entrySet()) {
// Remove the offhand command and any alias commands to prevent duplicates in the list
if (!command.getValue().isExecutableOnConsole() || command.getValue().getAliases().contains(command.getKey())) {
continue;
}
// Create the button that runs the command
boolean hasSubCommands = command.getValue().hasSubCommands();
// Add an extra menu if there are more commands that can be run
JMenuItem commandButton = hasSubCommands ? new JMenu(command.getValue().getName()) : new JMenuItem(command.getValue().getName());
commandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription());
if (!hasSubCommands) {
commandButton.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{ }));
} else {
// Add a submenu that's the same name as the menu can't be pressed
JMenuItem otherCommandButton = new JMenuItem(command.getValue().getName());
otherCommandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription());
otherCommandButton.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{ }));
commandButton.add(otherCommandButton);
// Add a menu option for all possible subcommands
for (String subCommandName : command.getValue().getSubCommands()) {
JMenuItem item = new JMenuItem(subCommandName);
item.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{subCommandName}));
commandButton.add(item);
}
}
commandsMenu.add(commandButton);
}
// 'Debug Mode' toggle
JCheckBoxMenuItem debugMode = new JCheckBoxMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options.toggle_debug_mode"));
debugMode.setSelected(geyserStandaloneLogger.isDebug());
debugMode.addActionListener(e -> geyserStandaloneLogger.setDebug(!geyserStandaloneLogger.isDebug()));
optionsMenu.add(debugMode);
}
/**
* Start the thread to update the form information every 1s
*/
public void startUpdateThread() {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable periodicTask = () -> {
if (GeyserConnector.getInstance() != null) {
// Update player table
playerTableModel.getDataVector().removeAllElements();
for (GeyserSession player : GeyserConnector.getInstance().getPlayers()) {
Vector<String> row = new Vector<>();
row.add(player.getSocketAddress().getHostName());
row.add(player.getPlayerEntity().getUsername());
playerTableModel.addRow(row);
}
playerTableModel.fireTableDataChanged();
}
// Update ram graph
final long freeMemory = Runtime.getRuntime().freeMemory();
final long totalMemory = Runtime.getRuntime().totalMemory();
final int freePercent = (int)(freeMemory * 100.0 / totalMemory + 0.5);
ramValues.add(100 - freePercent);
ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.usage", String.format("%,d", (totalMemory - freeMemory) / MEGABYTE), freePercent));
// Trim the list
int k = ramValues.size();
if ( k > 10 )
ramValues.subList(0, k - 10).clear();
// Update the graph
ramGraph.setValues(ramValues);
};
// SwingUtilities.invokeLater is called so we don't run into threading issues with the GUI
executor.scheduleAtFixedRate(() -> SwingUtilities.invokeLater(periodicTask), 0, 1, TimeUnit.SECONDS);
}
/**
* Make sure the JSplitPane divider is within a set of bounds
*
* @param splitPane The JSplitPane to check
*/
private void splitPaneLimit(JSplitPane splitPane) {
JRootPane frame = splitPane.getRootPane();
int location = splitPane.getDividerLocation();
if (location < frame.getWidth() - frame.getWidth() * 0.4f) {
splitPane.setDividerLocation(Math.round(frame.getWidth() - frame.getWidth() * 0.4f));
} else if (location > frame.getWidth() - 200) {
splitPane.setDividerLocation(frame.getWidth() - 200);
}
}
}

View File

@ -0,0 +1,187 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.standalone.gui;
import lombok.Setter;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* This has been modified to fit Geyser more but is based on
* https://gist.github.com/roooodcastro/6325153#gistcomment-3107524
*/
public final class GraphPanel extends JPanel {
private final static int padding = 10;
private final static int labelPadding = 25;
private final static int pointWidth = 4;
private final static int numberYDivisions = 10;
private final static Color lineColor = new Color(44, 102, 230, 255);
private final static Color pointColor = new Color(100, 100, 100, 255);
private final static Color gridColor = new Color(200, 200, 200, 255);
private static final Stroke graphStroke = new BasicStroke(2f);
private List<Integer> values = new ArrayList<>(10);
@Setter
private String xLabel = "";
public GraphPanel() {
setPreferredSize(new Dimension(200 - (padding * 2), 150 - (padding * 2)));
}
public void setValues(Collection<Integer> newValues) {
values.clear();
addValues(newValues);
}
public void addValues(Collection<Integer> newValues) {
values.addAll(newValues);
updateUI();
}
@Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
if (!(graphics instanceof Graphics2D)) {
graphics.drawString("Graphics is not Graphics2D, unable to render", 0, 0);
return;
}
final Graphics2D g = (Graphics2D) graphics;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
final int length = values.size();
final int width = getWidth();
final int height = getHeight();
final int maxScore = getMaxScore();
final int minScore = getMinScore();
final int scoreRange = maxScore - minScore;
// draw white background
g.setColor(Color.WHITE);
g.fillRect(
padding + labelPadding,
padding,
width - (2 * padding) - labelPadding,
height - 2 * padding - labelPadding);
g.setColor(Color.BLACK);
final FontMetrics fontMetrics = g.getFontMetrics();
final int fontHeight = fontMetrics.getHeight();
// create hatch marks and grid lines for y axis.
for (int i = 0; i < numberYDivisions + 1; i++) {
final int x1 = padding + labelPadding;
final int x2 = pointWidth + padding + labelPadding;
final int y = height - ((i * (height - padding * 2 - labelPadding)) / numberYDivisions + padding + labelPadding);
if (length > 0) {
g.setColor(gridColor);
g.drawLine(padding + labelPadding + 1 + pointWidth, y, width - padding, y);
g.setColor(Color.BLACK);
final int tickValue = (int) (minScore + ((scoreRange * i) / numberYDivisions));
final String yLabel = tickValue + "";
final int labelWidth = fontMetrics.stringWidth(yLabel);
g.drawString(yLabel, x1 - labelWidth - 5, y + (fontHeight / 2) - 3);
}
g.drawLine(x1, y, x2, y);
}
// and for x axis
if (length > 1) {
for (int i = 0; i < length; i++) {
final int x = i * (width - padding * 2 - labelPadding) / (length - 1) + padding + labelPadding;
final int y1 = height - padding - labelPadding;
final int y2 = y1 - pointWidth;
if ((i % ((int) ((length / 20.0)) + 1)) == 0) {
g.setColor(gridColor);
g.drawLine(x, height - padding - labelPadding - 1 - pointWidth, x, padding);
g.setColor(Color.BLACK);
/*g.setColor(Color.BLACK);
final String xLabel = i + "";
final int labelWidth = fontMetrics.stringWidth(xLabel);
g.drawString(xLabel, x - labelWidth / 2, y1 + fontHeight + 3);*/
}
g.drawLine(x, y1, x, y2);
}
}
// create x and y axes
g.drawLine(padding + labelPadding, height - padding - labelPadding, padding + labelPadding, padding);
g.drawLine(padding + labelPadding, height - padding - labelPadding, width - padding, height - padding - labelPadding);
g.setColor(Color.BLACK);
final int labelWidth = fontMetrics.stringWidth(xLabel);
final int labelX = ((padding + labelPadding) + (width - padding)) / 2;
final int labelY = height - padding - labelPadding;
g.drawString(xLabel, labelX - labelWidth / 2, labelY + fontHeight + 3);
final Stroke oldStroke = g.getStroke();
g.setColor(lineColor);
g.setStroke(graphStroke);
final double xScale = ((double) width - (2 * padding) - labelPadding) / (length - 1);
final double yScale = ((double) height - 2 * padding - labelPadding) / scoreRange;
final List<Point> graphPoints = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
final int x1 = (int) (i * xScale + padding + labelPadding);
final int y1 = (int) ((maxScore - values.get(i)) * yScale + padding);
graphPoints.add(new Point(x1, y1));
}
for (int i = 0; i < graphPoints.size() - 1; i++) {
final int x1 = graphPoints.get(i).x;
final int y1 = graphPoints.get(i).y;
final int x2 = graphPoints.get(i + 1).x;
final int y2 = graphPoints.get(i + 1).y;
g.drawLine(x1, y1, x2, y2);
}
boolean drawDots = width > (length * pointWidth);
if (drawDots) {
g.setStroke(oldStroke);
g.setColor(pointColor);
for (Point graphPoint : graphPoints) {
final int x = graphPoint.x - pointWidth / 2;
final int y = graphPoint.y - pointWidth / 2;
g.fillOval(x, y, pointWidth, pointWidth);
}
}
}
private int getMinScore() {
return 0;
}
private int getMaxScore() {
return 100;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@ -1,9 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<TerminalConsole name="Console">
<TerminalConsole name="TerminalConsole">
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red dark, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
</TerminalConsole>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red dark, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
</Console>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %level{length=1} - %msg%n"/>
<Policies>
@ -14,6 +17,7 @@
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="TerminalConsole"/>
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Root>

View File

@ -6,21 +6,21 @@
<parent>
<groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../</relativePath>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>bootstrap-velocity</artifactId>
<dependencies>
<dependency>
<groupId>org.geysermc</groupId>
<artifactId>connector</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
@ -57,10 +57,34 @@
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.fasterxml.jackson</pattern>
<shadedPattern>org.geysermc.platform.velocity.shaded.jackson</shadedPattern>
</relocation>
<relocation>
<pattern>it.unimi.dsi.fastutil</pattern>
<shadedPattern>org.geysermc.platform.velocity.shaded.fastutil</shadedPattern>
</relocation>
<relocation>
<pattern>org.reflections</pattern>
<shadedPattern>org.geysermc.platform.velocity.shaded.reflections</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>org.geysermc.platform.velocity.shaded.google.common</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.guava</pattern>
<shadedPattern>org.geysermc.platform.velocity.shaded.google.guava</shadedPattern>
</relocation>
<relocation>
<pattern>org.dom4j</pattern>
<shadedPattern>org.geysermc.platform.velocity.shaded.dom4j</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori</pattern>
<shadedPattern>org.geysermc.platform.velocity.shaded.kyori</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
@ -69,7 +93,16 @@
<artifactSet>
<excludes>
<exclude>com.google.code.gson:*</exclude>
<exclude>io.netty:*</exclude>
<!-- Needed because Velocity provides every dependency except netty-resolver-dns -->
<exclude>io.netty:netty-transport-native-epoll:*</exclude>
<exclude>io.netty:netty-transport-native-unix-common:*</exclude>
<exclude>io.netty:netty-transport-native-kqueue:*</exclude>
<exclude>io.netty:netty-handler:*</exclude>
<exclude>io.netty:netty-common:*</exclude>
<exclude>io.netty:netty-buffer:*</exclude>
<exclude>io.netty:netty-resolver:*</exclude>
<exclude>io.netty:netty-transport:*</exclude>
<exclude>io.netty:netty-codec:*</exclude>
<exclude>org.slf4j:*</exclude>
<exclude>org.ow2.asm:*</exclude>
</excludes>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,106 +25,26 @@
package org.geysermc.platform.velocity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.proxy.ProxyServer;
import lombok.Getter;
import lombok.Setter;
import org.geysermc.connector.FloodgateKeyLoader;
import org.geysermc.connector.GeyserConfiguration;
import org.geysermc.connector.configuration.GeyserJacksonConfiguration;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Optional;
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
public class GeyserVelocityConfiguration implements GeyserConfiguration {
private BedrockConfiguration bedrock;
private RemoteConfiguration remote;
@JsonProperty("floodgate-key-file")
private String floodgateKeyFile;
private Map<String, UserAuthenticationInfo> userAuths;
@JsonProperty("ping-passthrough")
private boolean pingPassthrough;
@JsonProperty("max-players")
private int maxPlayers;
@JsonProperty("debug-mode")
private boolean debugMode;
@JsonProperty("general-thread-pool")
private int generalThreadPool;
@JsonProperty("allow-third-party-capes")
private boolean allowThirdPartyCapes;
@JsonProperty("default-locale")
private String defaultLocale;
@JsonProperty("cache-chunks")
private boolean cacheChunks;
private MetricsInfo metrics;
private Path floodgateKey;
@JsonIgnoreProperties(ignoreUnknown = true)
public final class GeyserVelocityConfiguration extends GeyserJacksonConfiguration {
@JsonIgnore
private Path floodgateKeyPath;
public void loadFloodgate(GeyserVelocityPlugin plugin, ProxyServer proxyServer, File dataFolder) {
Optional<PluginContainer> floodgate = proxyServer.getPluginManager().getPlugin("floodgate");
floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), floodgateKeyFile.isEmpty() ? floodgateKeyFile : "public-key.pem"), floodgate.get(), Paths.get("plugins/floodgate/"));
}
@Override
public Path getFloodgateKeyFile() {
return floodgateKey;
}
@Getter
public static class BedrockConfiguration implements IBedrockConfiguration {
private String address;
private int port;
private String motd1;
private String motd2;
}
@Getter
public static class RemoteConfiguration implements IRemoteConfiguration {
@Setter
private String address;
@Setter
private int port;
private String motd1;
private String motd2;
@JsonProperty("auth-type")
private String authType;
}
@Getter
public static class UserAuthenticationInfo implements IUserAuthenticationInfo {
private String email;
private String password;
}
@Getter
public static class MetricsInfo implements IMetricsInfo {
private boolean enabled;
@JsonProperty("uuid")
private String uniqueId;
PluginContainer floodgate = proxyServer.getPluginManager().getPlugin("floodgate").orElse(null);
floodgateKeyPath = FloodgateKeyLoader.getKeyPath(this, floodgate, Paths.get("plugins/floodgate/"), dataFolder.toPath(), plugin.getGeyserLogger());
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.velocity;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.proxy.ProxyServer;
import lombok.Getter;
import org.geysermc.connector.common.serializer.AsteriskSerializer;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import java.util.ArrayList;
import java.util.List;
@Getter
public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
private String platformName;
private String platformVersion;
private String platformVendor;
private boolean onlineMode;
private String serverIP;
private int serverPort;
private List<PluginInfo> plugins;
GeyserVelocityDumpInfo(ProxyServer proxy) {
super();
this.platformName = proxy.getVersion().getName();
this.platformVersion = proxy.getVersion().getVersion();
this.platformVendor = proxy.getVersion().getVendor();
this.onlineMode = proxy.getConfiguration().isOnlineMode();
if (AsteriskSerializer.showSensitive || (proxy.getBoundAddress().getHostString().equals("") || proxy.getBoundAddress().getHostString().equals("0.0.0.0"))) {
this.serverIP = proxy.getBoundAddress().getHostString();
} else {
this.serverIP = "***";
}
this.serverPort = proxy.getBoundAddress().getPort();
this.plugins = new ArrayList<>();
for (PluginContainer plugin : proxy.getPluginManager().getPlugins()) {
String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown");
this.plugins.add(new PluginInfo(true, plugin.getDescription().getName().get(), plugin.getDescription().getVersion().get(), pluginClass, plugin.getDescription().getAuthors()));
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,15 +26,16 @@
package org.geysermc.platform.velocity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.geysermc.connector.GeyserLogger;
import org.slf4j.Logger;
@AllArgsConstructor
public class GeyserVelocityLogger implements GeyserLogger {
private Logger logger;
private boolean debugMode;
private final Logger logger;
@Getter @Setter
private boolean debug;
@Override
public void severe(String message) {
@ -68,12 +69,8 @@ public class GeyserVelocityLogger implements GeyserLogger {
@Override
public void debug(String message) {
if (debugMode)
if (debug) {
info(message);
}
@Override
public void setDebug(boolean debugMode) {
this.debugMode = debugMode;
}
}
}

View File

@ -1,32 +1,31 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.velocity;
import org.geysermc.common.main.IGeyserMain;
import org.geysermc.connector.common.main.IGeyserMain;
public class GeyserVelocityMain extends IGeyserMain {

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.velocity;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.ServerPing;
import lombok.AllArgsConstructor;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.geysermc.connector.common.ping.GeyserPingInfo;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
@AllArgsConstructor
public class GeyserVelocityPingPassthrough implements IGeyserPingPassthrough {
private final ProxyServer server;
@Override
public GeyserPingInfo getPingInformation(InetSocketAddress inetSocketAddress) {
ProxyPingEvent event;
try {
event = server.getEventManager().fire(new ProxyPingEvent(new GeyserInboundConnection(inetSocketAddress), ServerPing.builder()
.description(server.getConfiguration().getMotdComponent()).onlinePlayers(server.getPlayerCount())
.maximumPlayers(server.getConfiguration().getShowMaxPlayers()).build())).get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
LegacyComponentSerializer.legacy().serialize(event.getPing().getDescription(), '§'),
new GeyserPingInfo.Players(
event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getMax(),
event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getOnline()
),
new GeyserPingInfo.Version(
event.getPing().getVersion().getName(),
event.getPing().getVersion().getProtocol()
)
);
event.getPing().getPlayers().get().getSample().stream().map(ServerPing.SamplePlayer::getName).forEach(geyserPingInfo.getPlayerList()::add);
return geyserPingInfo;
}
private static class GeyserInboundConnection implements InboundConnection {
private final InetSocketAddress remote;
public GeyserInboundConnection(InetSocketAddress remote) {
this.remote = remote;
}
@Override
public InetSocketAddress getRemoteAddress() {
return this.remote;
}
@Override
public Optional<InetSocketAddress> getVirtualHost() {
return Optional.empty();
}
@Override
public boolean isActive() {
return false;
}
@Override
public ProtocolVersion getProtocolVersion() {
return ProtocolVersion.MAXIMUM_VERSION;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,18 +26,22 @@
package org.geysermc.platform.velocity;
import com.google.inject.Inject;
import com.velocitypowered.api.command.CommandManager;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.proxy.ProxyServer;
import lombok.Getter;
import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.bootstrap.GeyserBootstrap;
import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.dump.BootstrapDumpInfo;
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
import org.geysermc.connector.ping.IGeyserPingPassthrough;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor;
import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager;
import org.slf4j.Logger;
@ -45,6 +49,8 @@ import org.slf4j.Logger;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
@Plugin(id = "geyser", name = GeyserConnector.NAME + "-Velocity", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC")
@ -62,41 +68,65 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
private GeyserVelocityCommandManager geyserCommandManager;
private GeyserVelocityConfiguration geyserConfig;
private GeyserVelocityLogger geyserLogger;
private IGeyserPingPassthrough geyserPingPassthrough;
private GeyserConnector connector;
@Getter
private final Path configFolder = Paths.get("plugins/" + GeyserConnector.NAME + "-Velocity/");
@Override
public void onEnable() {
File configDir = new File("plugins/" + GeyserConnector.NAME + "-Velocity/");
try {
if (!configDir.exists())
configDir.mkdir();
File configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
if (!configFolder.toFile().exists())
//noinspection ResultOfMethodCallIgnored
configFolder.toFile().mkdirs();
File configFile = FileUtils.fileOrCopiedFromResource(configFolder.resolve("config.yml").toFile(), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class);
} catch (IOException ex) {
logger.warn("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
ex.printStackTrace();
}
InetSocketAddress javaAddr = proxyServer.getBoundAddress();
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!javaAddr.getHostString().equals("0.0.0.0")) {
geyserConfig.getRemote().setAddress(javaAddr.getHostString());
// By default this should be localhost but may need to be changed in some circumstances
if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) {
this.geyserConfig.setAutoconfiguredRemote(true);
// Don't use localhost if not listening on all interfaces
if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) {
this.geyserConfig.getRemote().setAddress(javaAddr.getHostString());
}
geyserConfig.getRemote().setPort(javaAddr.getPort());
}
geyserConfig.getRemote().setPort(javaAddr.getPort());
if (geyserConfig.getBedrock().isCloneRemotePort()) {
geyserConfig.getBedrock().setPort(javaAddr.getPort());
}
this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
geyserConfig.loadFloodgate(this, proxyServer, configDir);
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && !proxyServer.getPluginManager().getPlugin("floodgate").isPresent()) {
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
return;
} else if (geyserConfig.isAutoconfiguredRemote() && proxyServer.getPluginManager().getPlugin("floodgate").isPresent()) {
// Floodgate installed means that the user wants Floodgate authentication
geyserLogger.debug("Auto-setting to Floodgate authentication.");
geyserConfig.getRemote().setAuthType("floodgate");
}
geyserConfig.loadFloodgate(this, proxyServer, configFolder.toFile());
this.connector = GeyserConnector.start(PlatformType.VELOCITY, this);
this.geyserCommandManager = new GeyserVelocityCommandManager(connector);
this.commandManager.register(new GeyserVelocityCommandExecutor(connector), "geyser");
this.commandManager.register("geyser", new GeyserVelocityCommandExecutor(connector));
if (geyserConfig.isLegacyPingPassthrough()) {
this.geyserPingPassthrough = GeyserLegacyPingPassthrough.init(connector);
} else {
this.geyserPingPassthrough = new GeyserVelocityPingPassthrough(proxyServer);
}
}
@Override
@ -119,6 +149,11 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
return this.geyserCommandManager;
}
@Override
public IGeyserPingPassthrough getGeyserPingPassthrough() {
return geyserPingPassthrough;
}
@Subscribe
public void onInit(ProxyInitializeEvent event) {
onEnable();
@ -128,4 +163,9 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
public void onShutdown(ProxyShutdownEvent event) {
onDisable();
}
@Override
public BootstrapDumpInfo getDumpInfo() {
return new GeyserVelocityDumpInfo(proxyServer);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,37 +25,48 @@
package org.geysermc.platform.velocity.command;
import com.velocitypowered.api.command.Command;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.SimpleCommand;
import lombok.AllArgsConstructor;
import net.kyori.text.TextComponent;
import org.geysermc.common.ChatColor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.common.ChatColor;
import org.geysermc.connector.utils.LanguageUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@AllArgsConstructor
public class GeyserVelocityCommandExecutor implements Command {
public class GeyserVelocityCommandExecutor implements SimpleCommand {
private GeyserConnector connector;
private final GeyserConnector connector;
@Override
public void execute(CommandSource source, String[] args) {
if (args.length > 0) {
if (getCommand(args[0]) != null) {
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
source.sendMessage(TextComponent.of(ChatColor.RED + "You do not have permission to execute this command!"));
public void execute(Invocation invocation) {
if (invocation.arguments().length > 0) {
if (getCommand(invocation.arguments()[0]) != null) {
if (!invocation.source().hasPermission(getCommand(invocation.arguments()[0]).getPermission())) {
CommandSender sender = new VelocityCommandSender(invocation.source());
sender.sendMessage(ChatColor.RED + LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale()));
return;
}
getCommand(args[0]).execute(new VelocityCommandSender(source), args);
getCommand(invocation.arguments()[0]).execute(new VelocityCommandSender(invocation.source()), invocation.arguments().length > 1 ? Arrays.copyOfRange(invocation.arguments(), 1, invocation.arguments().length) : new String[0]);
}
} else {
getCommand("help").execute(new VelocityCommandSender(source), args);
getCommand("help").execute(new VelocityCommandSender(invocation.source()), new String[0]);
}
}
@Override
public List<String> suggest(Invocation invocation) {
if (invocation.arguments().length == 0) {
return connector.getCommandManager().getCommandNames();
}
return new ArrayList<>();
}
private GeyserCommand getCommand(String label) {
return connector.getCommandManager().getCommands().get(label);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -28,17 +28,21 @@ package org.geysermc.platform.velocity.command;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.ConsoleCommandSource;
import com.velocitypowered.api.proxy.Player;
import lombok.AllArgsConstructor;
import net.kyori.text.TextComponent;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.utils.LanguageUtils;
import java.util.Locale;
@AllArgsConstructor
public class VelocityCommandSender implements CommandSender {
private CommandSource handle;
private final CommandSource handle;
public VelocityCommandSender(CommandSource handle) {
this.handle = handle;
// Ensure even Java players' languages are loaded
LanguageUtils.loadGeyserLocale(getLocale());
}
@Override
public String getName() {
@ -59,4 +63,13 @@ public class VelocityCommandSender implements CommandSender {
public boolean isConsole() {
return handle instanceof ConsoleCommandSource;
}
@Override
public String getLocale() {
if (handle instanceof Player) {
Locale locale = ((Player) handle).getPlayerSettings().getLocale();
return LanguageUtils.formatLocale(locale.getLanguage() + "_" + locale.getCountry());
}
return LanguageUtils.getDefaultLocale();
}
}

View File

@ -6,11 +6,10 @@
<parent>
<groupId>org.geysermc</groupId>
<artifactId>geyser-parent</artifactId>
<version>parent</version>
<relativePath>../</relativePath>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>

View File

@ -1,33 +0,0 @@
package org.geysermc.common;
import lombok.Getter;
@Getter
public enum AuthType {
OFFLINE,
ONLINE,
FLOODGATE;
public static final AuthType[] VALUES = values();
public static AuthType getById(int id) {
return id < VALUES.length ? VALUES[id] : OFFLINE;
}
/**
* Convert the AuthType string (from config) to the enum, OFFLINE on fail
*
* @param name AuthType string
*
* @return The converted AuthType
*/
public static AuthType getByName(String name) {
String upperCase = name.toUpperCase();
for (AuthType type : VALUES) {
if (type.name().equals(upperCase)) {
return type;
}
}
return OFFLINE;
}
}

View File

@ -1,3 +1,28 @@
/*
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.common;
import lombok.AllArgsConstructor;
@ -7,11 +32,13 @@ import lombok.Getter;
@AllArgsConstructor
public enum PlatformType {
BUKKIT("Bukkit"),
ANDROID("Android"),
BUNGEECORD("BungeeCord"),
FABRIC("Fabric"),
SPIGOT("Spigot"),
SPONGE("Sponge"),
STANDALONE("Standalone"),
VELOCITY("Velocity");
private String platformName;
private final String platformName;
}

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*
*/
package org.geysermc.common.main;
import javax.swing.*;
import java.io.InputStream;
import java.util.Scanner;
public class IGeyserMain {
public void displayMessage() {
String message = createMessage();
if (System.console() == null) {
JOptionPane.showMessageDialog(null, message, "GeyserMC Plugin: " + this.getPluginType(), JOptionPane.ERROR_MESSAGE);
}
printMessage(message);
}
private String createMessage() {
String message = "";
InputStream helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("help.txt");
Scanner help = new Scanner(helpStream).useDelimiter("\\Z");
String line = "";
while (help.hasNext()) {
line = help.next();
line = line.replace("${plugin_type}", this.getPluginType());
line = line.replace("${plugin_folder}", this.getPluginFolder());
message += line + "\n";
}
return message;
}
private void printMessage(String message) {
System.out.print(message);
}
public String getPluginType() {
return "unknown";
}
public String getPluginFolder() {
return "unknown";
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -92,7 +92,7 @@ public class CustomFormWindow extends FormWindow {
}
public void setResponse(String data) {
if (data == null || data.equalsIgnoreCase("null") || data.isEmpty()) {
if (data == null || data.trim().equalsIgnoreCase("null") || data.isEmpty()) {
closed = true;
return;
}
@ -108,7 +108,7 @@ public class CustomFormWindow extends FormWindow {
List<String> componentResponses = new ArrayList<>();
try {
componentResponses = new ObjectMapper().readValue(data, new TypeReference<List<String>>(){});
componentResponses = new ObjectMapper().readValue(data.trim(), new TypeReference<List<String>>(){});
} catch (IOException e) { }
for (String response : componentResponses) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -72,14 +72,14 @@ public class SimpleFormWindow extends FormWindow {
}
public void setResponse(String data) {
if (data == null || data.equalsIgnoreCase("null")) {
if (data == null || data.trim().equalsIgnoreCase("null")) {
closed = true;
return;
}
int buttonID;
try {
buttonID = Integer.parseInt(data);
buttonID = Integer.parseInt(data.trim());
} catch (Exception ex) {
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -32,14 +32,14 @@ public class FormImage {
@Getter
@Setter
private FormImageType type;
private String type;
@Getter
@Setter
private String data;
public FormImage(FormImageType type, String data) {
this.type = type;
this.type = type.getName();
this.data = data;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,9 +25,17 @@
package org.geysermc.common.window.component;
import lombok.Getter;
import lombok.Setter;
public class ToggleComponent extends FormComponent {
@Getter
@Setter
private String text;
@Getter
@Setter
private boolean defaultValue;
public ToggleComponent(String text) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal

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