Skip to content
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

Suggestion to fix #1946: BungeeCord Plugin #2019

Open
TheMuffinPony opened this issue May 27, 2018 · 4 comments
Open

Suggestion to fix #1946: BungeeCord Plugin #2019

TheMuffinPony opened this issue May 27, 2018 · 4 comments
Assignees
Labels
type: enhancement Features and feature requests.
Milestone

Comments

@TheMuffinPony
Copy link

Hello,
As some of you might know, I left an issue a while back, specifically #1946 (which is about the inconsistency between BungeeCord servers). I have a suggestion that can fix it: A BungeeCord plugin.

I'm not 100% sure about Bungee plugins, but somehow each Essentials plugin takes commands from the BungeeCord plugin. For instance, let's suppose there's a two-minute cooldown between using /heal. Assuming servers had synced health, you could go to server 1, use /heal, go to server 2, and use /heal successfully again (despite there still being an active cooldown on server 1).

Now, let's assume that the BungeeCord plugin was properly installed and configured. Our player does /heal. This makes Essentials on server 1 tell the Bungee server "Player foo used /heal; cooldown disables at " (but with UUIDs). Then, the Bungee server remembers that. Once foo joins another server, the Bungee server tells that server "Enable heal cooldown for foo until ."

This would also make Essentials banning even better, as the server would just tell the Bungee server Bar banned Foo because 'Demo ban', and then the Bungee server would worry about keeping Foo banned. There might be a config option to send the ban to all servers (although, it shouldn't be necessary, since anyone running Bungee should be using iptables or some other mechanism to keep players from directly joining a server).

Servers could also be grouped, i.e. if you had two synced survival servers, you could preserve the cooldown between servers, but not have it transfer to a creative server.

Broadcast could also be sent to all servers; /tpa could work between servers, etc.

Now, as I said earlier, I have no idea how Bungee plugins work, so I don't know how possible this is.

@Xeyame
Copy link
Contributor

Xeyame commented May 27, 2018

Or just install a mysql based command cooldown plugin for Spigot and handle bans on the BungeeCord (And if you want, sync them back to spigot)
Again Essentials isn't designed for multiserver at all.

@mdcfe mdcfe closed this as completed May 27, 2018
@mdcfe mdcfe reopened this May 27, 2018
@mdcfe
Copy link
Member

mdcfe commented May 27, 2018

EDIT: essay incoming

The approach described by @TheMuffinPony is the obvious approach taken by most plugins that sync over BungeeCord - listen to events and send BungeeCord plugin messages between servers through the plugin - and it seems like a sensible suggestion.

In fact, I started to implement this as a standalone plugin not too long ago, to avoid needing to actually modify EssentialsX to support syncing (as some server owners won't want those features), but it was held up for a few different reasons.

One issue that hinders this approach is that in order for BungeeCord plugin messages to work, there must be a player connected through the BungeeCord proxy to each Minecraft server at all times. If no players are online on any one server on the network, there isn't a pathway to send data across to that server, so that server will gradually fall out of sync with other servers and some kind of replay mechanism would be necessary.

To avoid this, it would likely be necessary to sync the data through an external mechanism such as Redis PubSub, but this still requires that either every server is always online or a queue is created for offline servers to be able to catch up on missed data changes.

Another key problem that held up the progress of my plugin, though, is that this approach is susceptible to infinite loops. For example, say there are three servers on a network; Server 1, Server 2 and Server 3. When a player decides to change his nickname:

  • Player A runs /nick Bob on Server 1.
  • Server 1 changes Player A's nickname to Bob.
  • Server 1 syncs the changed nickname, sending a message to Server 2 and Server 3 to say "Player A's nickname changed to Bob".
  • Server 2 and Server 3 receive this message and both change Player A's nickname to "Bob".
  • Server 2 and Server 3 both sync their changed nicknames, each sending messages to Server 1 and each other to say "Player A's nickname changed to Bob".
  • Server 1, Server 2 and Server 3 now all change Player A's nickname again.
  • Server 1, Server 2 and Server 3 all sync the nickname to each other again, sending another message to each other, and so the loop carries on.

One way to avoid this is to check if a message has been sent recently and discard it if it has (check against a cache of messages), but this may be unreliable if lots of messages are sent and there is a high latency between servers.

Another way to avoid this is to check if the data sent in the message is actually different to what's currently set on the user, but this adds additional calls each time data is synced and could cause unintended side effects (like changing people's display names unintentionally).

A third way is to only attempt to send data to other servers if it wasn't set by the sync code. This is efficient as it doesn't require extra calls, but instead, implementing it would require extending EssentialsX's API to accommodate for this (namely adding a boolean propagate argument overload every method that triggers a sync). This means it would require more effort to implement this in a separate plugin, as it is fully dependent on EssentialsX adding the required hooks.


The third approach to deduplicating messages looks like the most realistic option to avoid infinite loops, while using an external mechanism like an SQL database or Redis as a form of queue would likely be necessary to avoid servers ending up out of sync. This could also later be extended to support Nucleus (which imho would be absolutely amazing to see), but overall the whole system would take a lot of time and effort to get right just for EssentialsX.

/essay

@mdcfe mdcfe added the type: enhancement Features and feature requests. label May 27, 2018
@mdcfe mdcfe self-assigned this May 27, 2018
@mdcfe mdcfe added this to the 2.16.0 milestone Jun 15, 2018
@felix920506
Copy link

I think this should add the ability to sync the chat messages across servers in bungeecord.

@mdcfe
Copy link
Member

mdcfe commented Nov 2, 2018

@felix920506 That is the job of a fully featured chat plugin, not EssentialsX.

@mdcfe mdcfe removed this from the 2.17.0 milestone May 30, 2019
@JRoy JRoy added this to the 5.0.0 milestone Mar 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement Features and feature requests.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants