CloudburstMC / Protocol

A protocol library for Minecraft Bedrock Edition
https://git.io/ProtocolLib
Apache License 2.0
310 stars 96 forks source link

ForceExperimentalGameplay option error #209

Closed CoolLoong closed 10 months ago

CoolLoong commented 10 months ago

StartGamePacket#setForceExperimentalGameplay=true will block player join the server, which I think is an error caused by using writeOptional. The protocol library version I am using is 594, and below is the complete content of the StartGamePacket

        var startGamePacket = new StartGamePacket();
        startGamePacket.getGamerules().add(GameRule.SHOW_COORDINATES.toNetwork());
        startGamePacket.setUniqueEntityId(playerEntity.getUniqueId());
        startGamePacket.setRuntimeEntityId(playerEntity.getUniqueId());
        startGamePacket.setPlayerGameType(gameType);
        var loc = playerEntity.getLocation();
        var worldSpawn = spawnWorld.getSpawnPosition();
        startGamePacket.setDefaultSpawn(Vector3i.from(worldSpawn.x(), worldSpawn.y(), worldSpawn.z()));
        startGamePacket.setPlayerPosition(Vector3f.from(loc.x(), loc.y(), loc.z()));
        startGamePacket.setRotation(Vector2f.from(loc.pitch(), loc.yaw()));
        startGamePacket.setSeed(0L);
        startGamePacket.setDimensionId(spawnWorld.getDimensionInfo().dimensionId());
        startGamePacket.setGeneratorId(spawnWorld.getWorldGenerator().getType().getId());
        startGamePacket.setLevelGameType(spawnWorld.getWorldGameType());
        startGamePacket.setDifficulty(spawnWorld.getDifficulty().ordinal());
        startGamePacket.setTrustingPlayers(true);
        startGamePacket.setDayCycleStopTime(0);
        startGamePacket.setLevelName(server.getServerSettings().motd());
        //TODO
        startGamePacket.setLevelId("");
        //TODO
        startGamePacket.setDefaultPlayerPermission(PlayerPermission.OPERATOR);
        startGamePacket.setServerChunkTickRange(spawnWorld.getTickingRadius());
        startGamePacket.setVanillaVersion(server.getNetworkServer().getCodec().getMinecraftVersion());
        startGamePacket.setPremiumWorldTemplateId("");
        startGamePacket.setInventoriesServerAuthoritative(true);
        startGamePacket.setItemDefinitions(ItemTypeRegistry.getRegistry().getItemDefinitions());
        startGamePacket.setAuthoritativeMovementMode(AuthoritativeMovementMode.SERVER);
        startGamePacket.setServerAuthoritativeBlockBreaking(true);
        startGamePacket.setCommandsEnabled(true);
        startGamePacket.setMultiplayerGame(true);
        startGamePacket.setBroadcastingToLan(true);
        startGamePacket.setMultiplayerCorrelationId(UUID.randomUUID().toString());
        startGamePacket.setXblBroadcastMode(GamePublishSetting.PUBLIC);
        startGamePacket.setPlatformBroadcastMode(GamePublishSetting.PUBLIC);
        //TODO
        startGamePacket.setCurrentTick(0);
        startGamePacket.setServerEngine("Allay");
        startGamePacket.setBlockRegistryChecksum(0L);
        startGamePacket.setPlayerPropertyData(NbtMap.EMPTY);
        startGamePacket.setWorldTemplateId(new UUID(0, 0));
        startGamePacket.setWorldEditor(false);
        startGamePacket.setChatRestrictionLevel(ChatRestrictionLevel.NONE);
        startGamePacket.setSpawnBiomeType(SpawnBiomeType.DEFAULT);
        startGamePacket.setCustomBiomeName("");
        startGamePacket.setEducationProductionId("");
        startGamePacket.setForceExperimentalGameplay(OptionalBoolean.of(true));
        startGamePacket.setBlockNetworkIdsHashed(true);
        sendPacket(startGamePacket);

When the player enter the server image

CoolLoong commented 10 months ago

Possible useful information: serialize<LevelSettings>::write image serialize<LevelSettings>::read image

smartcmd commented 10 months ago

I'm pretty sure about that :c

smartcmd commented 10 months ago

https://github.com/Sandertv/gophertunnel/commit/9603bd9d001780308c05fb3b666f7d4a605cffa2

Alemiz112 commented 10 months ago

Hi, I have checked it with other people too. What you see there in IDA is an error caused by code optimalization, which in this case IDA strugles to decompile correctly. I am very confident that optional boolean are two serialized booleans if the value is present.

The client crashes are probably caused by something other.

To add more context, overrideForceExperimentalGameplayFlag is only ever set as part of game unit tests. The vanilla itself does not use it from what I can see. The sources also explicitly say this flag should not be used by servers.

CoolLoong commented 10 months ago

Why do you think this is another reason? When I turn on this ForceExperimentalGameplay, the client will encounter an error, and when I turn it off, the client can enter the server

CoolLoong commented 10 months ago

Waiting for me to record a video

CoolLoong commented 10 months ago

https://drive.google.com/file/d/1pjCGrJQVIQdt-mX_bTl-hNXVmzW77mf0/view?usp=drive_link