New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling multiple protocols simultaneously #3201

Open
SafwatHalaby opened this Issue May 16, 2016 · 25 comments

Comments

Projects
None yet
10 participants
@SafwatHalaby
Member

SafwatHalaby commented May 16, 2016

Older clients simply cannot handle newer features. How should we deal with that?

Possible resolutions:

  • Dropping support for older protocols.
  • Setting up a single allowed protocol in settings.ini.

In any case, the current situation is unacceptable. Older clients can easily crash when playing along with 1.9 clients.

@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby May 16, 2016

Member

Known problems:

  • A player with purpur blocks (or any new block?) in the inventory will crash instantly upon login with 1.8.x clients.
  • 1.7.x is generally unstable for some people, see #2026, #2736

I will edit this list as I find more.

Member

SafwatHalaby commented May 16, 2016

Known problems:

  • A player with purpur blocks (or any new block?) in the inventory will crash instantly upon login with 1.8.x clients.
  • 1.7.x is generally unstable for some people, see #2026, #2736

I will edit this list as I find more.

@SafwatHalaby SafwatHalaby changed the title from Simultaneous multiprotocol support is problematic and possibly impossible. to Handling multiple protocols Simultaneously May 16, 2016

@SafwatHalaby SafwatHalaby changed the title from Handling multiple protocols Simultaneously to Handling multiple protocols simultaneously May 16, 2016

@Pokechu22

This comment has been minimized.

Show comment
Hide comment
@Pokechu22

Pokechu22 May 16, 2016

Contributor

All versions gracefully handle unknown blocks, substituting them for air. They do not handle unknown items at all, instead crashing. This includes blocks within the inventory, which are items in that context.

It may make sense to edit the item serialization code for 1.7 and 1.8 to have them substitute items that are unrecognized. Perhaps, replacing them with a similar item (end stone bricks → end stone, for example). That'll at least stop crashing.

It would be harder to do the same thing with blocks, though it still is possible (the chunk serialization code isn't exactly designed for substitutions). But the client doesn't crash with unknown blocks; it only produces what appears to be an air block.

Contributor

Pokechu22 commented May 16, 2016

All versions gracefully handle unknown blocks, substituting them for air. They do not handle unknown items at all, instead crashing. This includes blocks within the inventory, which are items in that context.

It may make sense to edit the item serialization code for 1.7 and 1.8 to have them substitute items that are unrecognized. Perhaps, replacing them with a similar item (end stone bricks → end stone, for example). That'll at least stop crashing.

It would be harder to do the same thing with blocks, though it still is possible (the chunk serialization code isn't exactly designed for substitutions). But the client doesn't crash with unknown blocks; it only produces what appears to be an air block.

@sphinxc0re

This comment has been minimized.

Show comment
Hide comment
@sphinxc0re

sphinxc0re May 16, 2016

Contributor

It might be even better to use the cProtocol class for that since all protocol handlers derive from that class

Contributor

sphinxc0re commented May 16, 2016

It might be even better to use the cProtocol class for that since all protocol handlers derive from that class

@madmaxoft

This comment has been minimized.

Show comment
Hide comment
@madmaxoft

madmaxoft May 16, 2016

Member

The multi-protocol support is not meant to allow different client versions to play together on a single server. The main point of the feature is to allow smooth transition - when a new Minecraft version comes out, we want to give the server admins the possibility to decide the exact moment when they move their server to the new version, while still keeping up with the new features.

There's already a simple plugin that allows only a single client version on the server: https://github.com/madmaxoft/SingleClientVersion

I think we should keep the status quo.

Member

madmaxoft commented May 16, 2016

The multi-protocol support is not meant to allow different client versions to play together on a single server. The main point of the feature is to allow smooth transition - when a new Minecraft version comes out, we want to give the server admins the possibility to decide the exact moment when they move their server to the new version, while still keeping up with the new features.

There's already a simple plugin that allows only a single client version on the server: https://github.com/madmaxoft/SingleClientVersion

I think we should keep the status quo.

@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby May 17, 2016

Member

So, I need a plugin to prevent a crash.

Shouldn't the allow only a single version policy be integrated into Cuberite? It's good for all use cases. You never want to allow multiple versions.

Member

SafwatHalaby commented May 17, 2016

So, I need a plugin to prevent a crash.

Shouldn't the allow only a single version policy be integrated into Cuberite? It's good for all use cases. You never want to allow multiple versions.

@Pokechu22

This comment has been minimized.

Show comment
Hide comment
@Pokechu22

Pokechu22 May 17, 2016

Contributor

I disagree; allowing multiple versions is a valid use case. Have you tried connecting to hypixel or mineplex? You can do it from 1.8 or 1.9, and it's the same server.

What you don't want to do is allow users to connect to a server with 1.9 items using 1.8, generally. A server using only 1.8 items with 1.9 is logical, but the other way around invites problems. That doesn't mean you don't ever want to connect 1.9 to 1.8, but generally you won't.

Contributor

Pokechu22 commented May 17, 2016

I disagree; allowing multiple versions is a valid use case. Have you tried connecting to hypixel or mineplex? You can do it from 1.8 or 1.9, and it's the same server.

What you don't want to do is allow users to connect to a server with 1.9 items using 1.8, generally. A server using only 1.8 items with 1.9 is logical, but the other way around invites problems. That doesn't mean you don't ever want to connect 1.9 to 1.8, but generally you won't.

@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby May 18, 2016

Member

Good point.

Then, the ideal solution would be an option which prevents items/features/mobs that are newer than 1.x, where 1.x is the desired minimum version. Drawbacks:

  • Some maintenance is required. (e.g. generator shouldn't generate new blocks when option is enabled, etc).
  • if an item/feature/mob is actually dropped and is missing in the newer version, maintenance get more complicated. (I don't know if this ever happened and this doesn't seem to be the case with 1.8 - 1.9).

In fact, this seems like the only crash-proof solution other than dropping older protocols. Even with the allow only a single version policy, a malicous player can use a modded 1.7.x to insert a 1.8.x item/feature/mob into the game, crashing it for everyone.

Member

SafwatHalaby commented May 18, 2016

Good point.

Then, the ideal solution would be an option which prevents items/features/mobs that are newer than 1.x, where 1.x is the desired minimum version. Drawbacks:

  • Some maintenance is required. (e.g. generator shouldn't generate new blocks when option is enabled, etc).
  • if an item/feature/mob is actually dropped and is missing in the newer version, maintenance get more complicated. (I don't know if this ever happened and this doesn't seem to be the case with 1.8 - 1.9).

In fact, this seems like the only crash-proof solution other than dropping older protocols. Even with the allow only a single version policy, a malicous player can use a modded 1.7.x to insert a 1.8.x item/feature/mob into the game, crashing it for everyone.

@madmaxoft

This comment has been minimized.

Show comment
Hide comment
@madmaxoft

madmaxoft May 18, 2016

Member

I think, rather than the option, it could still be done in the SingleClientVersion plugin. That way, admins (and us, as well) are free to experiment mixing the client versions.

True, the maintenance could get a bit nasty, but not overly complicated. If done properly, maintenance would mean copying a block of text from each old version and wrapping it in some Lua syntax, when the items.ini is last updated for that old version.

Member

madmaxoft commented May 18, 2016

I think, rather than the option, it could still be done in the SingleClientVersion plugin. That way, admins (and us, as well) are free to experiment mixing the client versions.

True, the maintenance could get a bit nasty, but not overly complicated. If done properly, maintenance would mean copying a block of text from each old version and wrapping it in some Lua syntax, when the items.ini is last updated for that old version.

@Schwertspize

This comment has been minimized.

Show comment
Hide comment
@Schwertspize

Schwertspize May 18, 2016

Contributor

Well if you want to keep the features of a new version, have you thought of modifying the data sent to older clients? Like if you got block a from 1.9 in a world (or item), connect with 1.8 you get instead something like stone with a variant showing the "missing texture" stuff. Also, you could use the variant like the item ID, so you got 1:284 or something instead of 284. Also, you could send a custom name for items

For creatures, for example, think of similar ways of keeping them handled by the server and as a feature, but just replace the stuff the client cannot handle with similar stuff and/or 'invalid texture'

If you handle it on a protocol base, the server can calculate everything as if it were eg ender bricks (?) but the client only sees enderstone if necessary...

An advantage would be, that you can write code once, to replace some data in the packages which get send, but read the description what to replace with what similar to the crafting.txt, you could easily have an 1.8 file, an 1.7 file and of the next version is out an 1.9 file too, with the same code, and depending on what the server admin wants to enable.
Eg config.ini

[EnabledVersions]
V1.8=protocol-1.8.txt
V1.5=protocol-anything.txt
Contributor

Schwertspize commented May 18, 2016

Well if you want to keep the features of a new version, have you thought of modifying the data sent to older clients? Like if you got block a from 1.9 in a world (or item), connect with 1.8 you get instead something like stone with a variant showing the "missing texture" stuff. Also, you could use the variant like the item ID, so you got 1:284 or something instead of 284. Also, you could send a custom name for items

For creatures, for example, think of similar ways of keeping them handled by the server and as a feature, but just replace the stuff the client cannot handle with similar stuff and/or 'invalid texture'

If you handle it on a protocol base, the server can calculate everything as if it were eg ender bricks (?) but the client only sees enderstone if necessary...

An advantage would be, that you can write code once, to replace some data in the packages which get send, but read the description what to replace with what similar to the crafting.txt, you could easily have an 1.8 file, an 1.7 file and of the next version is out an 1.9 file too, with the same code, and depending on what the server admin wants to enable.
Eg config.ini

[EnabledVersions]
V1.8=protocol-1.8.txt
V1.5=protocol-anything.txt
@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby May 18, 2016

Member

I think, rather than the option, it could still be done in the SingleClientVersion plugin. That way, admins (and us, as well) are free to experiment mixing the client versions.

True, the maintenance could get a bit nasty, but not overly complicated.

How can a plugin realistically do this? If you really want to be to support e.g. 1.8 and 1.9 in a crash proof manner, then the terrain generator must not generate 1.9 blocks, players in creative mode must not use 1.9 items, 1.9 mobs must not spawn, dual-wielding packets must not be sent to 1.8 clients, etc. etc.

It does sound overly complicated.

Member

SafwatHalaby commented May 18, 2016

I think, rather than the option, it could still be done in the SingleClientVersion plugin. That way, admins (and us, as well) are free to experiment mixing the client versions.

True, the maintenance could get a bit nasty, but not overly complicated.

How can a plugin realistically do this? If you really want to be to support e.g. 1.8 and 1.9 in a crash proof manner, then the terrain generator must not generate 1.9 blocks, players in creative mode must not use 1.9 items, 1.9 mobs must not spawn, dual-wielding packets must not be sent to 1.8 clients, etc. etc.

It does sound overly complicated.

@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby May 18, 2016

Member

@Schwertspize block/item/mob substitoution could work for some features. But I don't know if it can cover it all. And it adds complication.

Member

SafwatHalaby commented May 18, 2016

@Schwertspize block/item/mob substitoution could work for some features. But I don't know if it can cover it all. And it adds complication.

@worktycho

This comment has been minimized.

Show comment
Hide comment
@worktycho

worktycho May 18, 2016

Member

Its pretty complicated, and heavy work. Serialization is a pretty simple loop at the movement, and substitution would add to that significantly. If we could create a lookup array that fits in l1, it might not have too much impact. (Blocks are minimum 512 Byte table, unless we want the cost of hash lookups, roughly 400B for items).

Member

worktycho commented May 18, 2016

Its pretty complicated, and heavy work. Serialization is a pretty simple loop at the movement, and substitution would add to that significantly. If we could create a lookup array that fits in l1, it might not have too much impact. (Blocks are minimum 512 Byte table, unless we want the cost of hash lookups, roughly 400B for items).

@madmaxoft

This comment has been minimized.

Show comment
Hide comment
@madmaxoft

madmaxoft May 18, 2016

Member

From what I've heard, the client does in fact survive unknown blocks, so we wouldn't need to filter those. We'd just need to filter out the unknown items, and those are pretty well reachable through hooks and there's only a handful.

Member

madmaxoft commented May 18, 2016

From what I've heard, the client does in fact survive unknown blocks, so we wouldn't need to filter those. We'd just need to filter out the unknown items, and those are pretty well reachable through hooks and there's only a handful.

@Pokechu22

This comment has been minimized.

Show comment
Hide comment
@Pokechu22

Pokechu22 May 18, 2016

Contributor

As I mentioned - the client survives unknown blocks when the blocks are placed. However, it can't deal with unknown blocks or items in the inventory. (Blocks in the inventory are, technichally, items; some things that qualify as blocks aren't items, such as water blocks or piston heads).

Even without considering other versions, it's possible to accidentally get invalid blocks in the inventory - consider a modded client using Forge. If the player accidentally grabs a modded block from the creative inventory, that'll break things for other players. So inbound items need to be checked as well as outbound ones.

There are a bunch of optimizations in chunk serialization that would be able to replace the costs of doing block lookup. In 1.9, a custom palette could be used to dummy out unrecognized blocks (this is a vanilla behavior) - the unknown block could easily be marked as another one. In 1.8 and below, manual replacement would be needed. But that could be combined with the primary bitmask (in both versions) - using that, you can avoid sending chunk sections (16x16x16 ones) that are entirely air, which would be a highly valuable improvement. Chunk serialization is currently simple, but it's also naïve and could be improved for both bandwidth and processing speed.

Contributor

Pokechu22 commented May 18, 2016

As I mentioned - the client survives unknown blocks when the blocks are placed. However, it can't deal with unknown blocks or items in the inventory. (Blocks in the inventory are, technichally, items; some things that qualify as blocks aren't items, such as water blocks or piston heads).

Even without considering other versions, it's possible to accidentally get invalid blocks in the inventory - consider a modded client using Forge. If the player accidentally grabs a modded block from the creative inventory, that'll break things for other players. So inbound items need to be checked as well as outbound ones.

There are a bunch of optimizations in chunk serialization that would be able to replace the costs of doing block lookup. In 1.9, a custom palette could be used to dummy out unrecognized blocks (this is a vanilla behavior) - the unknown block could easily be marked as another one. In 1.8 and below, manual replacement would be needed. But that could be combined with the primary bitmask (in both versions) - using that, you can avoid sending chunk sections (16x16x16 ones) that are entirely air, which would be a highly valuable improvement. Chunk serialization is currently simple, but it's also naïve and could be improved for both bandwidth and processing speed.

@jammet

This comment has been minimized.

Show comment
Hide comment
@jammet

jammet May 18, 2016

Contributor

Keep in mind that pure survival servers (even those who now use Cuberite with 1.9) will not have any of the new blocks or even mobs yet, right? They're not implemented, the world isn't generating purpur blocks - wherever they come from (I have to catch up on 1.9 really soon).

Contributor

jammet commented May 18, 2016

Keep in mind that pure survival servers (even those who now use Cuberite with 1.9) will not have any of the new blocks or even mobs yet, right? They're not implemented, the world isn't generating purpur blocks - wherever they come from (I have to catch up on 1.9 really soon).

@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby May 19, 2016

Member

@jammet Correct, but that won't be true forever.

Member

SafwatHalaby commented May 19, 2016

@jammet Correct, but that won't be true forever.

@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby May 21, 2016

Member

I think that it would be very, very wise to have the 1 protocol only policy by default, and have it set to the latest by default in settings.ini. Any other solution will simply take too long. Edge cases that want multiple versions can modify settings.ini

Member

SafwatHalaby commented May 21, 2016

I think that it would be very, very wise to have the 1 protocol only policy by default, and have it set to the latest by default in settings.ini. Any other solution will simply take too long. Edge cases that want multiple versions can modify settings.ini

@jammet

This comment has been minimized.

Show comment
Hide comment
@jammet

jammet May 21, 2016

Contributor

I'm not really involved in the details, but I'd say it makes sense to put focus on the protocol you want to use primarily, and get it's feature set and stability sooner, first - as a sprint - and then later go over the older ones and see if they're still in good condition. Maybe have a build that's entirely 1.8 for a few months, and only seeing fixes, while the 1.9 is the current branch.

Contributor

jammet commented May 21, 2016

I'm not really involved in the details, but I'd say it makes sense to put focus on the protocol you want to use primarily, and get it's feature set and stability sooner, first - as a sprint - and then later go over the older ones and see if they're still in good condition. Maybe have a build that's entirely 1.8 for a few months, and only seeing fixes, while the 1.9 is the current branch.

@PureTryOut

This comment has been minimized.

Show comment
Hide comment
@PureTryOut

PureTryOut Jun 17, 2016

I think that the best option is to be able to specify a specific protocol version in settings.ini, which is the minimum protocol needed to join. Say you set 1.7 there, then 1.7 and higher can join, but not 1.6 and lower. Same if you set the server to require at least 1.9: 1.8 and lower would be refused of joining, but 1.9 (and in future 1.10) would be able to join fine.

When setting up an entirely new server without configuring anything, it would just only accept the very newest protocol supported, so 1.9 right now.

I'm guessing this is how Hypixel and such do it with Spigot.

PureTryOut commented Jun 17, 2016

I think that the best option is to be able to specify a specific protocol version in settings.ini, which is the minimum protocol needed to join. Say you set 1.7 there, then 1.7 and higher can join, but not 1.6 and lower. Same if you set the server to require at least 1.9: 1.8 and lower would be refused of joining, but 1.9 (and in future 1.10) would be able to join fine.

When setting up an entirely new server without configuring anything, it would just only accept the very newest protocol supported, so 1.9 right now.

I'm guessing this is how Hypixel and such do it with Spigot.

@jammet

This comment has been minimized.

Show comment
Hide comment
@jammet

jammet Jun 17, 2016

Contributor

I'm one of those people who like ease-of-use. I'm don't know what to make
of these protocols and I'd always want to be suggested sane defaults. You
know ... suggested settings.

On Fri, Jun 17, 2016 at 10:12 PM, PureTryOut notifications@github.com
wrote:

I think that the best option is to be able to specify a specific protocol
version in settings.ini, which is the minimum protocol needed to join.
Say you set 1.7 there, then 1.7 and higher can join, but not 1.6 and lower.
Same if you set the server to require at least 1.9: 1.8 and lower would be
refused of joining, but 1.9 (and in future 1.10) would be able to join fine.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#3201 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ALYzf0WdiuncoMh81d9-N4_KQVInkZA4ks5qMv-8gaJpZM4IfPKK
.

Contributor

jammet commented Jun 17, 2016

I'm one of those people who like ease-of-use. I'm don't know what to make
of these protocols and I'd always want to be suggested sane defaults. You
know ... suggested settings.

On Fri, Jun 17, 2016 at 10:12 PM, PureTryOut notifications@github.com
wrote:

I think that the best option is to be able to specify a specific protocol
version in settings.ini, which is the minimum protocol needed to join.
Say you set 1.7 there, then 1.7 and higher can join, but not 1.6 and lower.
Same if you set the server to require at least 1.9: 1.8 and lower would be
refused of joining, but 1.9 (and in future 1.10) would be able to join fine.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#3201 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ALYzf0WdiuncoMh81d9-N4_KQVInkZA4ks5qMv-8gaJpZM4IfPKK
.

@Pokechu22

This comment has been minimized.

Show comment
Hide comment
@Pokechu22

Pokechu22 Jun 17, 2016

Contributor

@PureTryOut That's the way that ViaVersion, the spigot plugin that handles multiple protocol versions, does it. You can always connect from a newer version, but not an older version (though in that case, the version is based off of the version that the server is running, not a configuration file, but it's the same idea).

It's probably the best way to handle it (though there should be easy enough ways to configure for older versions - manually creating block and recipe files to downgrade would not go well).

Contributor

Pokechu22 commented Jun 17, 2016

@PureTryOut That's the way that ViaVersion, the spigot plugin that handles multiple protocol versions, does it. You can always connect from a newer version, but not an older version (though in that case, the version is based off of the version that the server is running, not a configuration file, but it's the same idea).

It's probably the best way to handle it (though there should be easy enough ways to configure for older versions - manually creating block and recipe files to downgrade would not go well).

@PureTryOut

This comment has been minimized.

Show comment
Hide comment
@PureTryOut

PureTryOut Jun 17, 2016

It's probably the best way to handle it (though there should be easy enough ways to configure for older versions - manually creating block and recipe files to downgrade would not go well).

Probably yes, and I guess the easiest for now as well. This issue seems quite important so I would think implementing the preventing of lower version to join should be added first. Afterwards a way could be added to let older protocols join as well and disable features from newer versions when needed.

PureTryOut commented Jun 17, 2016

It's probably the best way to handle it (though there should be easy enough ways to configure for older versions - manually creating block and recipe files to downgrade would not go well).

Probably yes, and I guess the easiest for now as well. This issue seems quite important so I would think implementing the preventing of lower version to join should be added first. Afterwards a way could be added to let older protocols join as well and disable features from newer versions when needed.

@SafwatHalaby

This comment has been minimized.

Show comment
Hide comment
@SafwatHalaby

SafwatHalaby Sep 2, 2016

Member

Keep in mind that pure survival servers...

Note that creative servers can obtain new items, and thus crash older clients.

Member

SafwatHalaby commented Sep 2, 2016

Keep in mind that pure survival servers...

Note that creative servers can obtain new items, and thus crash older clients.

@mhsjlw

This comment has been minimized.

Show comment
Hide comment
@mhsjlw

mhsjlw Sep 6, 2016

I believe that only the newest major version should be supported. All older versions '1.8.x' and '1.9.x' should be either kept in another branch or kept as a release to be no longer maintained except for major patches that affect stability.

mhsjlw commented Sep 6, 2016

I believe that only the newest major version should be supported. All older versions '1.8.x' and '1.9.x' should be either kept in another branch or kept as a release to be no longer maintained except for major patches that affect stability.

@mohe2015

This comment has been minimized.

Show comment
Hide comment
@mohe2015

mohe2015 Sep 7, 2016

Contributor

I think it is very important to have the possibility to join from '1.8.x' and '1.9.x' because many servers need that. So the server should run 1.8 but it should allow newer clients to join.

Contributor

mohe2015 commented Sep 7, 2016

I think it is very important to have the possibility to join from '1.8.x' and '1.9.x' because many servers need that. So the server should run 1.8 but it should allow newer clients to join.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment