Skip to content

Conversation

@Owen1212055
Copy link
Member

Please provide feedback on naming, and general event consensis.

But my goal is to have the following:

  • Full cookie getting/setting support in the login/config/play stage. This means you'll be able to disconnect players during LOGIN depending on sent cookies. (Bukkit only allows play stage, and PARTLY config stage) (CookieConnection)
  • Allowing to boot players into the config stage/ out of it
  • Allow to add custom configuration tasks, so for example being able to load player data. (AsyncPlayerConnectionConfigurateEvent)
  • Allowing to load resource packs during config stage better
  • Transfer the player in config/player
  • send custom report details (shown in client debug log)

@github-project-automation github-project-automation bot moved this to Awaiting review in Paper PR Queue Mar 15, 2025
@Warriorrrr Warriorrrr added type: feature Request for a new Feature. scope: api labels Mar 17, 2025
@kennytv kennytv requested a review from Copilot April 14, 2025 09:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 45 out of 46 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • paper-api-generator.settings.gradle.kts: Language not supported
Comments suppressed due to low confidence (3)

paper-api/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java:22

  • The deprecation version 'idk' is unclear; please update it to a proper version string to improve clarity.
@Deprecated(since = "idk")

paper-api/src/main/java/io/papermc/paper/event/connection/configuration/PlayerConfigurationConnectionEvent.java:8

  • [nitpick] The field 'loginConnection' should be renamed to 'configurationConnection' to better reflect its purpose in a configuration event.
private final PlayerConfigurationConnection loginConnection;

paper-api/src/main/java/io/papermc/paper/connection/PlayerCommonConnection.java:3

  • [nitpick] Consider clarifying the name of this interface to more clearly describe its purpose, such as 'PlayerSharedConnection' or a similar term.
// TODO: Naming?

/**
* Completes the configuration for this player, which will cause this player to reenter the game.
* <p>
* Note, this should be only be called if you are reconfiguring the player.
Copy link
Contributor

Choose a reason for hiding this comment

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

This, similar to #enterConfiguration poses the interesting issue of "ah, you just requested what is basically a destruction of this connection state, what happens to this instance".

Calling #clearChat after this is illegal.
Getters might be fine. But we should look into a proper way to signal, "you destroyed this connection instance".

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree here. But, I am not sure as the current standard has been to silently fail in many places.
image
So we could very much add some validation, but it all ends up nooping.

@github-project-automation github-project-automation bot moved this from Awaiting review to Changes required in Paper PR Queue May 20, 2025

import net.kyori.adventure.text.Component;

public interface PlayerConnection {
Copy link
Member

Choose a reason for hiding this comment

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

It would be really good if the hierarchy of types here was adjusted so this class could be sealed and permit the two API interfaces. Would make switching on it nicer, especially in events where you only have the PlayerConnection, and to know what type it is, you do a switch pattern match. It's not a super simple change, because of the impl CommonCookeConnection abstract class, but things could def be moved around.

Copy link
Member Author

Choose a reason for hiding this comment

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

After playing around with this a bit, I am not sure about it really. This does require alot of moving around and possible duplication that I am not fully sure is worth it.

Additionally, its a bit of an odd situation, as I am not sure in what cases you'd be casting like this in the first place.

/**
* Represents a connection that has properties shared between the GAME and CONFIG stage.
*/
public interface PlayerCommonConnection extends CookieConnection {
Copy link
Member

Choose a reason for hiding this comment

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

Same situation here regarding sealed interfaces being nicer for switch pattern matching (doesn't require default case)

Copy link
Member Author

Choose a reason for hiding this comment

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

see above

* Indicates that this player is being reconfigured, meaning that this connection will be held in the configuration
* stage unless kicked out through {@link PlayerConfigurationConnection#completeConfiguration()}
*/
public class PlayerConnectionReconfigurateEvent extends PlayerConfigurationConnectionEvent {
Copy link
Member

Choose a reason for hiding this comment

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

I feel like this event, and PlayerConnectionInitialConfigureEvent can be compiled with just an enum "cause" or something. They are just both fired right before switching to configuration phase, from either login or from game. Just a PlayerEnterConfigurationPhaseEvent or something with a cause?

Copy link
Member Author

Choose a reason for hiding this comment

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

The reason why I made this separate is because both are treated very differently.
Basically I felt like differenciating that this player is going to be held forever in config phase vs they are going through the config phase as normal was an important enough disctinction.

Copy link
Member

Choose a reason for hiding this comment

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

But in both cases, doesn't the player just automatically go through the tasks in the configuration phase?

In plain vanilla, if you call that function to kick the player back to config phase, won't they just come right back in as if they had just logged in? Or do you have to somehow trigger something to let them back in?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, in reconfiguration the tasks are not run. This causes the player to just be stuck in the stage until released.
startConfiguration is only called when login packet is received, so there are no "tasks" that are being executed.

You have to "somehow" trigger to let them back in.

Copy link
Member Author

Choose a reason for hiding this comment

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

@Owen1212055 Owen1212055 added the publish-pr Enables a workflow to build Paperclip jars on the pull request. label Jun 21, 2025
@Owen1212055 Owen1212055 marked this pull request as ready for review June 21, 2025 03:03
@Owen1212055 Owen1212055 requested a review from a team as a code owner June 21, 2025 03:03
@papermc-pr-publishing
Copy link

papermc-pr-publishing bot commented Jun 21, 2025

Last updated for: ab69660e4e3be260ae7bf18e00ddebef4d7a090f.

Download the Paperclip jar for this pull request: paper-12301.zip

Maven Publication

The artifacts published by this PR:

Repository Declaration

In order to use the artifacts published by the PR, add the following repository to your buildscript:

repositories {
    maven("https://maven-prs.papermc.io/Paper/pr12301") {
        name = "Maven for PR #12301" // https://github.com/PaperMC/Paper/pull/12301
        mavenContent {
            includeModule("io.papermc.paper", "dev-bundle")
            includeModule("io.papermc.paper", "paper-api")
        }
    }
}

Copy link
Member

@kennytv kennytv left a comment

Choose a reason for hiding this comment

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

also ctrl+f and remove at least half of the mentions of the word "currently" (especially in event headers)💩

*
* @return the configuring player audience
*/
Audience getConfiguringPlayer();
Copy link
Member

Choose a reason for hiding this comment

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

If its just an "Audience", how to I, in a callback where I only have the audience, get access to the methods I can use on the connection?

@Owen1212055 Owen1212055 force-pushed the feat/config-api branch 2 times, most recently from cffc660 to 65619e6 Compare June 25, 2025 04:09
@kennytv kennytv changed the base branch from main to dev/1.21.7 June 26, 2025 19:21
Owen1212055 and others added 5 commits June 26, 2025 21:23
Fix disconnect continuing to tick ServerLoginPacketListenerImpl

Fixes #8676

This implements a solution that preemptively exits the tick loop if we have already marked the connection as disconnecting. This avoids changing the result of Connection#isConnected in order to avoid other possibly unintentional changes. Fundamentally it should be investigated if closing the connection async is really still needed.

This also additionally removes the login disconnecting logic for server stopping, as this was also a possible issue in the config stage but also shouldn't be an issue as connections are closed on server stop very early.

Additionally, do not check for isConnecting() on VERIFYING, as that seemed to be an old diff originally trying to resolve this code, however isConnected is not updated at this point so it pretty much was useless.
This needs to be moved out as there is no serverplayer in the configuration stage. Additionally, fix logging inconsistency.
@kennytv kennytv dismissed stale reviews from Machine-Maker and lynxplay June 26, 2025 19:37

woop

@kennytv kennytv merged commit ac9f763 into dev/1.21.7 Jun 26, 2025
4 checks passed
@kennytv kennytv deleted the feat/config-api branch June 26, 2025 19:55
@github-project-automation github-project-automation bot moved this from Changes required to Merged in Paper PR Queue Jun 26, 2025
kennytv pushed a commit that referenced this pull request Jun 26, 2025
This implements a solution that preemptively exits the tick loop if we have already marked the connection as disconnecting. This avoids changing the result of Connection#isConnected in order to avoid other possibly unintentional changes. Fundamentally it should be investigated if closing the connection async is really still needed.

This also additionally removes the login disconnecting logic for server stopping, as this was also a possible issue in the config stage but also shouldn't be an issue as connections are closed on server stop very early.

Additionally, do not check for isConnecting() on VERIFYING, as that seemed to be an old diff originally trying to resolve this code, however isConnected is not updated at this point so it pretty much was useless.
kennytv pushed a commit that referenced this pull request Jun 30, 2025
This implements a solution that preemptively exits the tick loop if we have already marked the connection as disconnecting. This avoids changing the result of Connection#isConnected in order to avoid other possibly unintentional changes. Fundamentally it should be investigated if closing the connection async is really still needed.

This also additionally removes the login disconnecting logic for server stopping, as this was also a possible issue in the config stage but also shouldn't be an issue as connections are closed on server stop very early.

Additionally, do not check for isConnecting() on VERIFYING, as that seemed to be an old diff originally trying to resolve this code, however isConnected is not updated at this point so it pretty much was useless.
kennytv pushed a commit that referenced this pull request Jun 30, 2025
This implements a solution that preemptively exits the tick loop if we have already marked the connection as disconnecting. This avoids changing the result of Connection#isConnected in order to avoid other possibly unintentional changes. Fundamentally it should be investigated if closing the connection async is really still needed.

This also additionally removes the login disconnecting logic for server stopping, as this was also a possible issue in the config stage but also shouldn't be an issue as connections are closed on server stop very early.

Additionally, do not check for isConnecting() on VERIFYING, as that seemed to be an old diff originally trying to resolve this code, however isConnected is not updated at this point so it pretty much was useless.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

publish-pr Enables a workflow to build Paperclip jars on the pull request. scope: api type: feature Request for a new Feature.

Projects

Status: Merged

Development

Successfully merging this pull request may close these issues.

6 participants