Skip to content

Floodgate support for Bukkit - #494

Merged
TuxCoding merged 37 commits into
TuxCoding:mainfrom
Smart123s:main
May 16, 2021
Merged

Floodgate support for Bukkit#494
TuxCoding merged 37 commits into
TuxCoding:mainfrom
Smart123s:main

Conversation

@Smart123s

@Smart123s Smart123s commented Mar 20, 2021

Copy link
Copy Markdown
Contributor

Summary of your change

Adds support for automatically registering and logging in with both linked and standalone Bedrock Players. Auto login is verified by Floodgate and the player's Xbox Live account.

New Configuration options

These options only work on Bukkit/Spigot/Paper servers, not on BungeeCord

autoLoginFloodgate

This enables auto login for every player connecting through Floodgate.
Possible values: false, true, linked
Linked means that only Bedrock accounts linked to a Java account will be logged in automatically
This value is treated as a string and requires apostrophes

allowFloodgateNameConflict

This enables Floodgate players to join the server, even if autoRegister is true and there's an existing Java Premium
account with the same name
Possible values:

  • false: Check for Premium Java name conflicts as described in autoRegister
    • autoRegister must be true for this to work
  • true: Bypass autoRegister's name conflict checking
  • linked: Bedrock accounts linked to a Java account will be allowed to join with conflicting names
    Note: Linking a new account requires players to log in with a non-linked Bedrock account first
    Enabling this will make linking new Bedrock players impossible
    More information on linking accounts: https://github.com/GeyserMC/Geyser/wiki/Floodgate#account-linking
    Releated Floodgate issue: Add ability to directly link to Mojang account on login GeyserMC/Floodgate#37

    Floodgate 2.0 uses a different Linking method (called Global Linking) and this is no longer relevant.
    This value is treated as a string and requires apostrophes

autoRegisterFloodgate

This enables auto registering every player connecting through Floodgate.
autoLoginFloodgate must be true for this to work

Related issue

Implements / fixes #328
Additional issues in the implementation may be caused by #493

There is an issue UNRELATED to this fork which makes the building of the Bungee part of the plugin fail. The fork can still be tested as it does NOT touch the Bungee version. For more information, see this build report from the upstream version of the plugin. This is now fixed.

Known Bugs

  • Auto Registering from a Bedrock clinet will cause a Java Client with the same name to also be registered, but will not be automatically logged in Auto (and not auto?) registering with a Java account and then logging out, and logging in with a bedrock account with the same name will cause the Bedrock account to be auto logged in without linking. See also at Tests - Same bedrock and java usernames.
  • Profile.isSaved() is 'false' when logging in from Bedrock after auto registering through Bedrock so FastLogin will try to register for a second time, insted of logging in -- fixed by switching to authPlugin.isRegistered()
  • (Auto?) Registering as a Bedrock player will not create/store a StoredProfile in the database.
  • Registering from a Bedrock account gives "Successfully registered", and right after that "This user isn't registered". Joining for a second time successfully logs the player in. So the problem is with logging in right after registering. Maybe it something to do with the asynchronous task? - EDIT (2020 March 25): It's no longer doing it. Nothing has been changed since the last test.

To be tested

All of the points below should be tried with almost every possible combinations of the configuration entries: autoRegister, premiumUuid, nameChangeCheck, autoLogin, autoLoginFloodgate, allowFloodgateNameConflict, autoRegisterFloodgate

Same bedrock and java usernames

With unlinked accounts - Same bedrock and java usernames

  • With the Java account logging in first (and registering)
    • Auto login from Java account
    • Auto login from Bedrock account
  • With the Bedrock account logging in first (and registering) see known bugs
    • Auto login from Java account
    • Auto login from Bedrock account

With linked accounts (after linking) - Same bedrock and java usernames

  • Auto login from Java account
  • Auto login from Bedrock account

Different bedrock and java usernames

  • Auto login from Bedrock account
  • Auto register from Bedrock account
  • Linked account auto login from both devices

Miscellaneous

  • Does the FloodgateAPI return null (used here) if Geyser config remote.auth-type is set to offline and Floodgate is installed on the server and...
  • ...the player is using cracked Minecraft Bedrock (the official client does not allow you to play multiplayer without logging in to Xbox Live) - IF NOT, THIS CAN ALLOW CRACKED MC-BE USERS TO AUTO-LOGIN WITH ANY USERNAME
  • ...the player is logged in to Xbox Live when connecting - This should be fine
    Added GeyserConnector.getInstance().getDefaultAuthType() == AuthType.FLOODGATE which should solve this problem.

To Do

This Todo list is incomplete, please help me add elements to it.

  • Find a better way to implement 'autoRegisterFloodgate: false' in ConectionListener.java#98
  • Rewrite comments in config.yml to make them easier to understand
    • Add experimental warning messages
  • Check if the workaround for used to detect players connecting through Geyser is reliable (use1, use2)
    EDIT: the use cases point to the removed Floodgate 1.0 implementation.
    • Maybe put them into a common function to avoid code duplication?
  • Decide if players with the same name should be auto logged in from different platforms (they have different UUIDs)
    This behavior will be made configurable in a future Pull Request.
  • Support Floodgate 2.0
  • Check if the changes didn't break Floodgate's Xbox authentication. Floodgate should block offline Bedrock players from connecting.

The Floodgate API requires UUID which is inaccessible at the level
FastLogion operates on.
A workaround for this is to check if the currently connecting player is
also a part of the Geyser server's online players list.
*TODO: Check for Java and Bedrock name conflicts with multiple
configurations.*
This is buggy in most cases.
Check config.yml for details.
Knwon Bug: Profile.isSaved() is 'false' when logging in from Bedrock
after auto registering through Bedrock so FastLogin will try to register
for a second time, insted of logging in
@Smart123s

Copy link
Copy Markdown
Contributor Author

There is an issue unrelated to this fork which makes the building of the Bungee part of the plugin fail. The fork can still be tested as it does not touch the Bungee version. For more information, see this build report from the upstream version of the plugin.

@TuxCoding TuxCoding added the enhancement New feature or change request label Mar 21, 2021

@TuxCoding TuxCoding left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For more information, see this build report from the upstream version of the plugin.

I noticed that. I hoped the author would fix it. I'll go to look into an alternative.

Auto Registering from a Bedrock clinet will cause a Java Client with the same name to also be registered, but will not be automatically logged in

The ForceLoginTask will register and login the player at the same time. So I wonder what went wrong here or are they separate login events?

Profile.isSaved() is 'false' when logging in from Bedrock after auto registering through Bedrock so FastLogin will try to register for a second time, insted of logging in

Try the auth plugin isRegstered method

Maybe put them into a common function to avoid code duplication?

You could also put the stuff into an extra class in order to isolate it. This could make it easier to test against it.

Comment thread bukkit/pom.xml Outdated
</exclusion>
</exclusions>
</dependency>

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move the dependencies up, because they are not auth plugins.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the dependencies above <!--Login Plugins--> and left the repositories alone.
Please check if they in the right place now.

for (GeyserSession geyserPlayer : GeyserConnector.getInstance().getPlayers()) {
if (geyserPlayer.getName().equals(player.getName())) {
// this also returns a floodgatePlayer for linked Java accounts
// that's why the Geyser Server's player list also has to be checked

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean you have tried the getPlayerByUUID method? This would save us this loop check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to my tests, FloodgateAPI.getPlayer(player.getUniqueId()) also returns a FloodgatePlayer instance if the player is connecting from Java Edition (JE) but has a linked Bedrock Edition (BE) account.
Later in the code floodgatePlayer != null is used to decide if a player is connecting from BE. But since JE accounts with linked BE accounts also have a return value, I had to filter them out. That's what the for loop is used for.
I couldn't find a better solution (yet), but honestly, I didn't spend much time looking. I am planning to figure out an alternative method for this. If I won't find anything better, than at least I'll try switching name to uuid in line 60.

player.getName());
String allowNameConflict = plugin.getCore().getConfig().getString("allowFloodgateNameConflict");
// check if the Bedrock player is linked to a Java account
boolean isLinked = floodgatePlayer.fetchLinkedPlayer() != null;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be a blocking request, so it has to be async in order to not block the main thread.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved this to an asynchronous task.

@Smart123s

Copy link
Copy Markdown
Contributor Author

For more information, see this build report from the upstream version of the plugin.

I noticed that. I hoped the author would fix it. I'll go to look into an alternative.

I have opened another Pull Request that could be an alternative to that.

@Smart123s

Copy link
Copy Markdown
Contributor Author

Maybe put them into a common function to avoid code duplication?

You could also put the stuff into an extra class in order to isolate it. This could make it easier to test against it.

Can I create a FloodgateHook class in com.github.games647.fastlogin.bukkit.hook or is it reserved for auth plugins?
Or should I put it somewhere else?

@TuxCoding

Copy link
Copy Markdown
Owner

Can I create a FloodgateHook class in com.github.games647.fastlogin.bukkit.hook or is it reserved for auth plugins?
Or should I put it somewhere else?

That's normally for auth plugins. Maybe we should choose a better name for that. You could put into the auth package, because it's related to login/auth handling.

@Smart123s

Copy link
Copy Markdown
Contributor Author

I need your opinion on this one (and on everything else of course):
In this scenario there are two players with the same name, but one of them is playing from Java Edition (JE), and the other one is playing from Bedrock Edition (BE).
They obviously can't be online at the same time, because one name can only be online at a time on the server. (Who would /tp apply to if there were two Steves on the server? 😄 )
However, if they play at different times, than I've allowed auto login for both of them (if auto-login is enabled for both playtforms in the config, of course), since they have different UUIDs. I have tested this with the following combinations:

  • Cracked JE - Bedrock (with Xbox)
  • Premium JE - Bedrock (with Xbox)
    Floodgate requires Xbox, so disabling it is not an option.

Is it good this way, or should only one of them be able to auto log in?
Note 1 : Floodgate prefixes are not working (#493), which would eliminate this issue for servers who are using them.
Note 2: The allowFloodgateNameConflict configuration option only cehcks for Premium Java Usernames at the moment, using NameCheckTask.

@Smart123s

Copy link
Copy Markdown
Contributor Author

Okay, so I think that the PR is ready (well, besides a new bug that I've added to the Known bugs list, any idea on how to fix it?) for another review, and for merging if you find everything alright. Could you please check the tasks that I've left unticked? Also, I've commented on all of your "change requests", could you close them if you are satisfied with my solutions? Please, don't forget to properly test my code before merging it, I'm not sure if I hadn't broken anything, and I don't want to compromise anyone's server's security. Also, are the configuration options understandable?

@Smart123s
Smart123s marked this pull request as ready for review March 22, 2021 20:46
@Smart123s
Smart123s requested a review from TuxCoding March 24, 2021 09:42
@BluMonkie

Copy link
Copy Markdown

Hi, i tried compiling your fork but it still removes the floodgate prefix, any fix for this as of yet?

@Smart123s

Copy link
Copy Markdown
Contributor Author

Hi, i tried compiling your fork but it still removes the floodgate prefix, any fix for this as of yet?

No, nothing yet. I'd really like to tell you to view to #493 but there's no usable information there either.
And to be honest, I haven't néven looked into this issue yet, but I'll definitely do it in the near future.
One workaround could be to make FastLogin inject the prefixes instead of Floodgate, but it'd be really hacky.
I think that the root of the problem might be related to an event being cancelled by FastLogin, but I am not sure. As I've said earlier, I haven't looked into this.

@BluMonkie

Copy link
Copy Markdown

Thanks for the fast response. I guess i will just stick to bungeecord for now.

Smart123s added 4 commits May 9, 2021 09:06
The FloodgateApi is the same for Bukkit and Bungee, so the Floodgate
related code could be used in a future Bungee implementation too.

Currently, Bungee will report Floodgate disabled to core, so the
upstream Floodgate implementation will be used there.
If enough code will be moved to core, I might consider enabling these
features to BungeeCord too.
@Smart123s

Copy link
Copy Markdown
Contributor Author

Introduction

Okay, so at this point I want to do a little bit of heads-up about this Pull Request, where it is, where it's going, what are the plans for the future, and what I have done lately.

Where did it start?

My initial plan with this PR was to implement Floodgate support for Bukkit without even touching BungeeCord and/or Core, so I wouldn't break Bungee. It's worth noting that I haven't even tried the Bungee version of FastLogin back then. Well, a lot of things changed since then.

Supporting BungeeCord

Yesterday, I took a look at #498 and realized that the features I've been working on (namely autoLogin, autoRegister and floodgateNameConflict) are not present in Bungee, but could be implemented in a similar way to it's Bukkit counterpart. In fact, the FloodgateApi is the same for all platforms.

Moving code to core

So it got me thinking that most of my code could be reused for a BungeeCord implementation of the above mentioned features. Today, I decided to move the low-level name conflict checking code from Bukkit to the core. This is kind of a first step. Since it's high-level part is not in the core yet, I've kept it disabled in Bungee (via a boolean set to false).

Adding Bungee features in this Pull Request

As I've mentioned earlier, this PR was supposed to be Bukkit only (look at the title of the PR), however I think that at this point it would be reasonable to expand it, and add configuration options to BungeeCord too.

Question 1: Should I do it in this PR, or should I keep this Bukkit only, and open another PR for BungeeCord?

Things that are not going to be done

I think that a proper fix for #493 is out of scope for this PR. I've looked at it several times and it seems to be an upstream issue somewhere. A workaround could be to make FastLogin assign the prefixes instead of Floodgate. I haven't tried it, so I don't know how complicated would it be to achieve that. However, a drawback of this approach could be that if the original bug goes away, then we'll have to deal with duplicate prefixes.

Question 2: Should I implement the workaround for Floodgate name-prefix when using FastLoign with ProtocolLib Bukkit?

To Do

There are two tasks in the original PR message that haven't been completed yet:

Decide if players with the same name should be auto logged in from different platforms (they have different UUIDs)

There are two reasons why this is important. Firstly, Floodgate name prefixes are not obligatory and can be turned off. Secondly, #493 is still present.
My plan for this is to add new option to autoRegister and autoLogin called non-conflicting which would only login/register players whose name doesn't conflict with a premium Java player's name. (Although after looking at the code for five minutes, I've realized that it might require more code modifications than what I've originally expected.)

Check if the changes didn't break Floodgate's Xbox authentication. Floodgate should block offline Bedrock players from connecting.

That's actually a hard one, because if I sign out of my Microsoft account on my phone, the it won't let me connect to any server. My idea is to find a cracked version of the game which supports joining cracked servers too. Or if anyone has another idea on how to test this, please let me know. Or if someone could post actual test results, it'd be really awesome.

Closing thoughts

@games647 could you please answer the two questions that I've asked above. I've also left comments on the changes you requested. Could you please check if those are OK now?

Thank you for reading this rather long comment. Have a nice day.

@TuxCoding

Copy link
Copy Markdown
Owner

Question 1: Should I do it in this PR, or should I keep this Bukkit only, and open another PR for BungeeCord?

Keep it for Bukkit. You shouldn't blow up a pull request. PRs in reasonable atomic steps are much better. They are easier to manage and merge. You can always expand later. Think of it like a little bit bigger than commits. New features, bug fixes that already provide an improvement should directly be integrated into it. It makes it easier to test.

Question 2: Should I implement the workaround for Floodgate name-prefix when using FastLoign with ProtocolLib Bukkit?

Create a new PR for that.

I think that a proper fix for #493 is out of scope for this PR. I've looked at it several times and it seems to be an upstream issue somewhere. A workaround could be to make FastLogin assign the prefixes instead of Floodgate. I haven't tried it, so I don't know how complicated would it be to achieve that. However, a drawback of this approach could be that if the original bug goes away, then we'll have to deal with duplicate prefixes.

It could be related to faking the receiving of a LoginStartPacket. We intercept this packet and create a new one. This is where the username will be and could be the reason of overwriting it.

@games647 could you please answer the two questions that I've asked above. I've also left comments on the changes you requested. Could you please check if those are OK now?

Looks good to me.

@Smart123s

Copy link
Copy Markdown
Contributor Author

Keep it for Bukkit. You shouldn't blow up a pull request. PRs in reasonable atomic steps are much better. They are easier to manage and merge. You can always expand later. Think of it like a little bit bigger than commits. New features, bug fixes that already provide an improvement should directly be integrated into it. It makes it easier to test.

Ok, you are right. I'll add a warning to onEnable() about #493 and leave the rest of the code as is.
I'll try to find a version of Minecraft Bedrock Edition that lets me connect to servers WITHOUT having to sign in to Xbox live to check if Floodgate's authentication system still works. I'll leave another comment once I found the app & ran the tests. Or if you've done it already, then please stop me from wasting my time. 😄

I think that a proper fix for #493 is out of scope for this PR. I've looked at it several times and it seems to be an upstream issue somewhere. A workaround could be to make FastLogin assign the prefixes instead of Floodgate. I haven't tried it, so I don't know how complicated would it be to achieve that. However, a drawback of this approach could be that if the original bug goes away, then we'll have to deal with duplicate prefixes.

It could be related to faking the receiving of a LoginStartPacket. We intercept this packet and create a new one. This is where the username will be and could be the reason of overwriting it.

It looks like I forgot to mention (although I though that I've done it before, sorry about that) that I've opened a ticket GeyserMC/Floodgate#143. In short, the prefixes break after registering an async start listener using ProtocolLib, without doing anything in the actual eventhandler.

@Smart123s

Copy link
Copy Markdown
Contributor Author

I've reverted the commit where I have moved some code to Core since that part turned out to be useless for BungeeCord, so I thought that it shouldn't be merged.
I've also added warning when starting Floodgate Bukkit with either Floodgate 1.0 or 2.0 and ProtocolLib.
After several hours wasted, I was unable to find a Bedrock Edition client that allows you to connect to servers without having to sign in to Xbox live, so I gave up on that.
I'm not planning more code changes for this Pull Request.

Comment thread bungee/src/main/resources/bungee.yml Outdated
@TuxCoding

Copy link
Copy Markdown
Owner

It looks like I forgot to mention (although I though that I've done it before, sorry about that) that I've opened a ticket GeyserMC/Floodgate#143. In short, the prefixes break after registering an async start listener using ProtocolLib, without doing anything in the actual eventhandler.

I experienced that somewhere else too, but I don't remember it. There is the importance of naming commits clearly.

Could also be a ProtocolLib issue in this case, depending how the listener actually differs from the synchronous solution.

Comment thread bukkit/src/main/resources/plugin.yml
Smart123s added 3 commits May 16, 2021 17:53
Rebased to remove Bungee related changes
Floodgate 1.0 does not work with the current Bukkit implementation.
ProtocolLib and Floodgate don' play along nicely when used with FastLogin
Related issue: TuxCoding#493
@TuxCoding
TuxCoding merged commit 119b9cb into TuxCoding:main May 16, 2021
@Smart123s Smart123s mentioned this pull request Oct 19, 2021
2 tasks
@Trinchezito

Copy link
Copy Markdown

.< nothing so far, anyone found alternative plugin similar to fastlogin?

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

Labels

enhancement New feature or change request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Floodgate (plugin) support

5 participants