Fabric API

Fabric API

106M Downloads

Custom Payload cannot be sent in ClientConfigurationConnectionEvents.INIT

zly2006 opened this issue ยท 4 comments

commented

Description

ClientConfigurationConnectionEvents.DISCONNECT and READY are both telling me not to send any packets. However, I also cannot send packet in the INIT event because when then INIT event fired, the connections are still in LOGIN state.

I tried to investigate fabric api's code, the INIT events are all fired after the packet listener constructors are called, however, the new packet listener constructor called does not mean the connection moved into a new state, see code before.

Since INIT might mean constructor, I don't know if this is a bug. if not, then we have no events to send packets in configuration phase.

Environment

fabric api: 0.99.5+1.21
mc: 1.21 pre3

Reason

// net.minecraft.client.network.ClientLoginNetworkHandler
    public void onSuccess(LoginSuccessS2CPacket packet) {
        this.switchTo(ClientLoginNetworkHandler.State.JOINING);
        GameProfile gameProfile = packet.profile();
        this.connection.transitionInbound(ConfigurationStates.S2C, new ClientConfigurationNetworkHandler(this.client, this.connection, new ClientConnectionState(gameProfile, this.client.getTelemetryManager().createWorldSession(this.newWorld, this.worldLoadTime, this.minigameName),  newClientDynamicRegistryType.createCombinedDynamicRegistries().getCombinedRegistryManager(), FeatureFlags.DEFAULT_ENABLED_FEATURES, (String)null, this.serverInfo, this.parentScreen, this.serverCookies, (ChatHud.ChatState)null, packet.strictErrorHandling(), Map.of(), ServerLinks.EMPTY)));
        // ClientConfigurationConnectionEvents.INIT fired at the new ClientConfigurationNetworkHandler statement above
        this.connection.send(EnterConfigurationC2SPacket.INSTANCE);
        this.connection.transitionOutbound(ConfigurationStates.C2S);
        this.connection.send(new CustomPayloadC2SPacket(new BrandCustomPayload(ClientBrandRetriever.getClientModName())));
        this.connection.send(new ClientOptionsC2SPacket(this.client.options.getSyncedOptions()));
        // should inject here, after the client and server entered configuration phase
    }
commented

imo a START event should be added, which is fired when you can start sending packets in the configuration phase. If you agree with this idea I can help implement it and open a PR.

commented

got a workaround:

C2SConfigurationChannelEvents.REGISTER.register { _, sender, _, channels ->
  if (MyPacket.ID.id in channels) {
    sender.sendPacket(MyPacket(...data))
  }
}

but i still hope to make it like this:

ClientConfigurationConnectionEvents.INIT.register { _, _ -> sendPacket... }
commented

Yeah, there is an issue here.

I think ClientConfigurationConnectionEvents.READY should really be ClientConfigurationConnectionEvents.COMPLETE.

There should then be a ClientConfigurationConnectionEvents.JOIN or maybe ClientConfigurationConnectionEvents.CONFIGURE event that gets fired when you are able to send packets.

commented

Yeah, there is an issue here.

I think ClientConfigurationConnectionEvents.READY should really be ClientConfigurationConnectionEvents.COMPLETE.

There should then be a ClientConfigurationConnectionEvents.JOIN or maybe ClientConfigurationConnectionEvents.CONFIGURE event that gets fired when you are able to send packets.

OK, will open a PR (I ve fixed this but currently no tests)