3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-16 04:50:07 +01:00

Merge branch 'master' into feature/1.21.20

Dieser Commit ist enthalten in:
Kas-tle 2024-08-04 21:45:22 -07:00 committet von GitHub
Commit 7f1b697036
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: B5690EEEBB952194
12 geänderte Dateien mit 76 neuen und 69 gelöschten Zeilen

Datei anzeigen

@ -113,13 +113,15 @@ public class DumpCommand extends GeyserCommand {
source.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collecting", source.locale())); source.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collecting", source.locale()));
String dumpData; String dumpData;
try { try {
DumpInfo dump = new DumpInfo(geyser, addLog);
if (offlineDump) { if (offlineDump) {
DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter(); DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
// Make arrays easier to read // Make arrays easier to read
prettyPrinter.indentArraysWith(new DefaultIndenter(" ", "\n")); prettyPrinter.indentArraysWith(new DefaultIndenter(" ", "\n"));
dumpData = MAPPER.writer(prettyPrinter).writeValueAsString(new DumpInfo(addLog)); dumpData = MAPPER.writer(prettyPrinter).writeValueAsString(dump);
} else { } else {
dumpData = MAPPER.writeValueAsString(new DumpInfo(addLog)); dumpData = MAPPER.writeValueAsString(dump);
} }
} catch (IOException e) { } catch (IOException e) {
source.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collect_error", source.locale())); source.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collect_error", source.locale()));

Datei anzeigen

@ -81,7 +81,7 @@ public class DumpInfo {
private final FlagsInfo flagsInfo; private final FlagsInfo flagsInfo;
private final List<ExtensionInfo> extensionInfo; private final List<ExtensionInfo> extensionInfo;
public DumpInfo(boolean addLog) { public DumpInfo(GeyserImpl geyser, boolean addLog) {
this.versionInfo = new VersionInfo(); this.versionInfo = new VersionInfo();
this.cpuCount = Runtime.getRuntime().availableProcessors(); this.cpuCount = Runtime.getRuntime().availableProcessors();
@ -91,7 +91,7 @@ public class DumpInfo {
this.gitInfo = new GitInfo(GeyserImpl.BUILD_NUMBER, GeyserImpl.COMMIT.substring(0, 7), GeyserImpl.COMMIT, GeyserImpl.BRANCH, GeyserImpl.REPOSITORY); this.gitInfo = new GitInfo(GeyserImpl.BUILD_NUMBER, GeyserImpl.COMMIT.substring(0, 7), GeyserImpl.COMMIT, GeyserImpl.BRANCH, GeyserImpl.REPOSITORY);
this.config = GeyserImpl.getInstance().getConfig(); this.config = geyser.getConfig();
this.floodgate = new Floodgate(); this.floodgate = new Floodgate();
String md5Hash = "unknown"; String md5Hash = "unknown";
@ -107,7 +107,7 @@ public class DumpInfo {
//noinspection UnstableApiUsage //noinspection UnstableApiUsage
sha256Hash = byteSource.hash(Hashing.sha256()).toString(); sha256Hash = byteSource.hash(Hashing.sha256()).toString();
} catch (Exception e) { } catch (Exception e) {
if (GeyserImpl.getInstance().getConfig().isDebugMode()) { if (this.config.isDebugMode()) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -116,18 +116,22 @@ public class DumpInfo {
this.ramInfo = new RamInfo(); this.ramInfo = new RamInfo();
if (addLog) { if (addLog) {
this.logsInfo = new LogsInfo(); this.logsInfo = new LogsInfo(geyser);
} }
this.userPlatforms = new Object2IntOpenHashMap<>(); this.userPlatforms = new Object2IntOpenHashMap<>();
for (GeyserSession session : GeyserImpl.getInstance().getSessionManager().getAllSessions()) { for (GeyserSession session : geyser.getSessionManager().getAllSessions()) {
DeviceOs device = session.getClientData().getDeviceOs(); DeviceOs device = session.getClientData().getDeviceOs();
userPlatforms.put(device, userPlatforms.getOrDefault(device, 0) + 1); userPlatforms.put(device, userPlatforms.getOrDefault(device, 0) + 1);
} }
this.connectionAttempts = GeyserImpl.getInstance().getGeyserServer().getConnectionAttempts(); if (geyser.getGeyserServer() != null) {
this.connectionAttempts = geyser.getGeyserServer().getConnectionAttempts();
} else {
this.connectionAttempts = 0; // Fallback if Geyser failed to fully startup
}
this.bootstrapInfo = GeyserImpl.getInstance().getBootstrap().getDumpInfo(); this.bootstrapInfo = geyser.getBootstrap().getDumpInfo();
this.flagsInfo = new FlagsInfo(); this.flagsInfo = new FlagsInfo();
@ -244,10 +248,10 @@ public class DumpInfo {
public static class LogsInfo { public static class LogsInfo {
private String link; private String link;
public LogsInfo() { public LogsInfo(GeyserImpl geyser) {
try { try {
Map<String, String> fields = new HashMap<>(); Map<String, String> fields = new HashMap<>();
fields.put("content", FileUtils.readAllLines(GeyserImpl.getInstance().getBootstrap().getLogsPath()).collect(Collectors.joining("\n"))); fields.put("content", FileUtils.readAllLines(geyser.getBootstrap().getLogsPath()).collect(Collectors.joining("\n")));
JsonNode logData = GeyserImpl.JSON_MAPPER.readTree(WebUtils.postForm("https://api.mclo.gs/1/log", fields)); JsonNode logData = GeyserImpl.JSON_MAPPER.readTree(WebUtils.postForm("https://api.mclo.gs/1/log", fields));

Datei anzeigen

@ -321,7 +321,7 @@ public class SessionPlayerEntity extends PlayerEntity {
public int voidFloorPosition() { public int voidFloorPosition() {
// The void floor is offset about 40 blocks below the bottom of the world // The void floor is offset about 40 blocks below the bottom of the world
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension(); BedrockDimension bedrockDimension = session.getBedrockDimension();
return bedrockDimension.minY() - 40; return bedrockDimension.minY() - 40;
} }

Datei anzeigen

@ -34,6 +34,9 @@ import org.geysermc.geyser.util.DimensionUtils;
* Represents the information we store from the current Java dimension * Represents the information we store from the current Java dimension
* @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension. * @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension.
* This controls if they have the shaking effect applied in the dimension. * This controls if they have the shaking effect applied in the dimension.
* @param bedrockId the Bedrock dimension ID of this dimension.
* As a Java dimension can be null in some login cases (e.g. GeyserConnect), make sure the player
* is logged in before utilizing this field.
*/ */
public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale, int bedrockId, boolean isNetherLike) { public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale, int bedrockId, boolean isNetherLike) {
@ -46,7 +49,7 @@ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double world
// Set if piglins/hoglins should shake // Set if piglins/hoglins should shake
boolean piglinSafe = dimension.getBoolean("piglin_safe"); boolean piglinSafe = dimension.getBoolean("piglin_safe");
// Load world coordinate scale for the world border // Load world coordinate scale for the world border
double coordinateScale = dimension.getDouble("coordinate_scale"); double coordinateScale = dimension.getNumber("coordinate_scale").doubleValue(); // FIXME see if we can change this in the NBT library itself.
boolean isNetherLike; boolean isNetherLike;
// Cache the Bedrock version of this dimension, and base it off the ID - THE ID CAN CHANGE!!! // Cache the Bedrock version of this dimension, and base it off the ID - THE ID CAN CHANGE!!!

Datei anzeigen

@ -137,6 +137,7 @@ import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.BlockItem; import org.geysermc.geyser.item.type.BlockItem;
import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.level.physics.CollisionManager; import org.geysermc.geyser.level.physics.CollisionManager;
import org.geysermc.geyser.network.netty.LocalSession; import org.geysermc.geyser.network.netty.LocalSession;
@ -386,6 +387,13 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
@MonotonicNonNull @MonotonicNonNull
@Setter @Setter
private JavaDimension dimensionType = null; private JavaDimension dimensionType = null;
/**
* Which dimension Bedrock understands themselves to be in.
* This should only be set after the ChangeDimensionPacket is sent, or
* right before the StartGamePacket is sent.
*/
@Setter
private BedrockDimension bedrockDimension = BedrockDimension.OVERWORLD;
@Setter @Setter
private int breakingBlock; private int breakingBlock;
@ -1547,7 +1555,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
startGamePacket.setRotation(Vector2f.from(1, 1)); startGamePacket.setRotation(Vector2f.from(1, 1));
startGamePacket.setSeed(-1L); startGamePacket.setSeed(-1L);
startGamePacket.setDimensionId(DimensionUtils.javaToBedrock(chunkCache.getBedrockDimension())); startGamePacket.setDimensionId(DimensionUtils.javaToBedrock(bedrockDimension));
startGamePacket.setGeneratorId(1); startGamePacket.setGeneratorId(1);
startGamePacket.setLevelGameType(GameType.SURVIVAL); startGamePacket.setLevelGameType(GameType.SURVIVAL);
startGamePacket.setDifficulty(1); startGamePacket.setDifficulty(1);

Datei anzeigen

@ -25,17 +25,14 @@
package org.geysermc.geyser.session.cache; package org.geysermc.geyser.session.cache;
import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.chunk.GeyserChunk; import org.geysermc.geyser.level.chunk.GeyserChunk;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.MathUtils; import org.geysermc.geyser.util.MathUtils;
import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette;
public class ChunkCache { public class ChunkCache {
private final boolean cache; private final boolean cache;
@ -46,13 +43,6 @@ public class ChunkCache {
@Setter @Setter
private int heightY; private int heightY;
/**
* Which dimension Bedrock understands themselves to be in.
*/
@Getter
@Setter
private BedrockDimension bedrockDimension = BedrockDimension.OVERWORLD;
public ChunkCache(GeyserSession session) { public ChunkCache(GeyserSession session) {
this.cache = !session.getGeyser().getWorldManager().hasOwnChunkCache(); // To prevent Spigot from initializing this.cache = !session.getGeyser().getWorldManager().hasOwnChunkCache(); // To prevent Spigot from initializing
chunks = cache ? new Long2ObjectOpenHashMap<>() : null; chunks = cache ? new Long2ObjectOpenHashMap<>() : null;

Datei anzeigen

@ -64,14 +64,17 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo(); PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension()); JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
boolean forceDimSwitch = false;
// If the player is already initialized and a join game packet is sent, they // If the player is already initialized and a join game packet is sent, they
// are swapping servers // are swapping servers
if (session.isSpawned()) { if (session.isSpawned()) {
int fakeDim = DimensionUtils.getTemporaryDimension(session.getDimensionType().bedrockId(), newDimension.bedrockId()); int fakeDim = DimensionUtils.getTemporaryDimension(DimensionUtils.javaToBedrock(session.getBedrockDimension()), newDimension.bedrockId());
if (fakeDim != newDimension.bedrockId()) {
// The player's current dimension and new dimension are the same
// We want a dimension switch to clear old chunks out, so switch to a dimension that isn't the one we're currently in.
// Another dimension switch will be required to switch back
DimensionUtils.fastSwitchDimension(session, fakeDim); DimensionUtils.fastSwitchDimension(session, fakeDim);
forceDimSwitch = true; }
session.getWorldCache().removeScoreboard(); session.getWorldCache().removeScoreboard();
@ -80,15 +83,9 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
// Remove extra hearts, hunger, etc. // Remove extra hearts, hunger, etc.
entity.resetAttributes(); entity.resetAttributes();
entity.resetMetadata(); entity.resetMetadata();
} else if (session.getUpstream().isInitialized()) {
if (newDimension.bedrockId() == 0) {
// A dimension switch will not happen, so make sure we initialized the dimension choice.
// Otherwise, the dimension switch will fill these values in.
session.setDimensionType(newDimension);
DimensionUtils.setBedrockDimension(session, newDimension.bedrockId());
}
} }
session.setDimensionType(newDimension);
session.setWorldName(spawnInfo.getWorldName()); session.setWorldName(spawnInfo.getWorldName());
session.setLevels(Arrays.stream(packet.getWorldNames()).map(Key::asString).toArray(String[]::new)); session.setLevels(Arrays.stream(packet.getWorldNames()).map(Key::asString).toArray(String[]::new));
session.setGameMode(spawnInfo.getGameMode()); session.setGameMode(spawnInfo.getGameMode());
@ -96,7 +93,6 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
boolean needsSpawnPacket = !session.isSentSpawnPacket(); boolean needsSpawnPacket = !session.isSentSpawnPacket();
if (needsSpawnPacket) { if (needsSpawnPacket) {
// The player has yet to spawn so let's do that using some of the information in this Java packet // The player has yet to spawn so let's do that using some of the information in this Java packet
session.setDimensionType(newDimension);
DimensionUtils.setBedrockDimension(session, newDimension.bedrockId()); DimensionUtils.setBedrockDimension(session, newDimension.bedrockId());
session.connect(); session.connect();
@ -131,7 +127,7 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
} }
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(register, Constants.PLUGIN_MESSAGE.getBytes(StandardCharsets.UTF_8))); session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(register, Constants.PLUGIN_MESSAGE.getBytes(StandardCharsets.UTF_8)));
if (newDimension != session.getDimensionType() || forceDimSwitch) { if (DimensionUtils.javaToBedrock(session.getBedrockDimension()) != newDimension.bedrockId()) {
DimensionUtils.switchDimension(session, newDimension); DimensionUtils.switchDimension(session, newDimension);
} else if (DimensionUtils.isCustomBedrockNetherId() && newDimension.isNetherLike()) { } else if (DimensionUtils.isCustomBedrockNetherId() && newDimension.isNetherLike()) {
// If the player is spawning into the "fake" nether, send them some fog // If the player is spawning into the "fake" nether, send them some fog

Datei anzeigen

@ -25,6 +25,8 @@
package org.geysermc.geyser.translator.protocol.java.inventory; package org.geysermc.geyser.translator.protocol.java.inventory;
import org.geysermc.geyser.entity.type.living.animal.horse.SkeletonHorseEntity;
import org.geysermc.geyser.entity.type.living.animal.horse.ZombieHorseEntity;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundHorseScreenOpenPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundHorseScreenOpenPacket;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
@ -140,8 +142,10 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator<ClientboundH
} else { } else {
inventoryTranslator = new HorseInventoryTranslator(slotCount); inventoryTranslator = new HorseInventoryTranslator(slotCount);
slots.add(SADDLE_SLOT); slots.add(SADDLE_SLOT);
if (!(entity instanceof SkeletonHorseEntity || entity instanceof ZombieHorseEntity)) {
slots.add(ARMOR_SLOT); slots.add(ARMOR_SLOT);
} }
}
// Build the NbtMap that sets the icons for Bedrock (e.g. sets the saddle outline on the saddle slot) // Build the NbtMap that sets the icons for Bedrock (e.g. sets the saddle outline on the saddle slot)
builder.putList("slots", NbtType.COMPOUND, slots); builder.putList("slots", NbtType.COMPOUND, slots);

Datei anzeigen

@ -99,7 +99,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
BitSet waterloggedPaletteIds = new BitSet(); BitSet waterloggedPaletteIds = new BitSet();
BitSet bedrockOnlyBlockEntityIds = new BitSet(); BitSet bedrockOnlyBlockEntityIds = new BitSet();
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension(); BedrockDimension bedrockDimension = session.getBedrockDimension();
int maxBedrockSectionY = (bedrockDimension.height() >> 4) - 1; int maxBedrockSectionY = (bedrockDimension.height() >> 4) - 1;
int sectionCount; int sectionCount;
@ -509,7 +509,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
levelChunkPacket.setChunkX(packet.getX()); levelChunkPacket.setChunkX(packet.getX());
levelChunkPacket.setChunkZ(packet.getZ()); levelChunkPacket.setChunkZ(packet.getZ());
levelChunkPacket.setData(Unpooled.wrappedBuffer(payload)); levelChunkPacket.setData(Unpooled.wrappedBuffer(payload));
levelChunkPacket.setDimension(DimensionUtils.javaToBedrock(session.getChunkCache().getBedrockDimension())); levelChunkPacket.setDimension(DimensionUtils.javaToBedrock(session.getBedrockDimension()));
session.sendUpstreamPacket(levelChunkPacket); session.sendUpstreamPacket(levelChunkPacket);
for (Map.Entry<Vector3i, ItemFrameEntity> entry : session.getItemFrameCache().entrySet()) { for (Map.Entry<Vector3i, ItemFrameEntity> entry : session.getItemFrameCache().entrySet()) {

Datei anzeigen

@ -149,7 +149,7 @@ public class ChunkUtils {
} }
public static void sendEmptyChunk(GeyserSession session, int chunkX, int chunkZ, boolean forceUpdate) { public static void sendEmptyChunk(GeyserSession session, int chunkX, int chunkZ, boolean forceUpdate) {
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension(); BedrockDimension bedrockDimension = session.getBedrockDimension();
int bedrockSubChunkCount = bedrockDimension.height() >> 4; int bedrockSubChunkCount = bedrockDimension.height() >> 4;
byte[] payload; byte[] payload;
@ -167,7 +167,7 @@ public class ChunkUtils {
byteBuf.readBytes(payload); byteBuf.readBytes(payload);
LevelChunkPacket data = new LevelChunkPacket(); LevelChunkPacket data = new LevelChunkPacket();
data.setDimension(DimensionUtils.javaToBedrock(session.getChunkCache().getBedrockDimension())); data.setDimension(DimensionUtils.javaToBedrock(session.getBedrockDimension()));
data.setChunkX(chunkX); data.setChunkX(chunkX);
data.setChunkZ(chunkZ); data.setChunkZ(chunkZ);
data.setSubChunksLength(0); data.setSubChunksLength(0);
@ -214,7 +214,7 @@ public class ChunkUtils {
throw new RuntimeException("Maximum Y must be a multiple of 16!"); throw new RuntimeException("Maximum Y must be a multiple of 16!");
} }
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension(); BedrockDimension bedrockDimension = session.getBedrockDimension();
// Yell in the console if the world height is too height in the current scenario // Yell in the console if the world height is too height in the current scenario
// The constraints change depending on if the player is in the overworld or not, and if experimental height is enabled // The constraints change depending on if the player is in the overworld or not, and if experimental height is enabled
// (Ignore this for the Nether. We can't change that at the moment without the workaround. :/ ) // (Ignore this for the Nether. We can't change that at the moment without the workaround. :/ )

Datei anzeigen

@ -179,7 +179,7 @@ public class DimensionUtils {
} }
public static void setBedrockDimension(GeyserSession session, int bedrockDimension) { public static void setBedrockDimension(GeyserSession session, int bedrockDimension) {
session.getChunkCache().setBedrockDimension(switch (bedrockDimension) { session.setBedrockDimension(switch (bedrockDimension) {
case BEDROCK_END_ID -> BedrockDimension.THE_END; case BEDROCK_END_ID -> BedrockDimension.THE_END;
case BEDROCK_DEFAULT_NETHER_ID -> BedrockDimension.THE_NETHER; // JavaDimension *should* be set to BEDROCK_END_ID if the Nether workaround is enabled. case BEDROCK_DEFAULT_NETHER_ID -> BedrockDimension.THE_NETHER; // JavaDimension *should* be set to BEDROCK_END_ID if the Nether workaround is enabled.
default -> BedrockDimension.OVERWORLD; default -> BedrockDimension.OVERWORLD;

Datei anzeigen

@ -159,7 +159,7 @@ public class InventoryUtils {
@Nullable @Nullable
public static Vector3i findAvailableWorldSpace(GeyserSession session) { public static Vector3i findAvailableWorldSpace(GeyserSession session) {
// Check if a fake block can be placed, either above the player or beneath. // Check if a fake block can be placed, either above the player or beneath.
BedrockDimension dimension = session.getChunkCache().getBedrockDimension(); BedrockDimension dimension = session.getBedrockDimension();
int minY = dimension.minY(), maxY = minY + dimension.height(); int minY = dimension.minY(), maxY = minY + dimension.height();
Vector3i flatPlayerPosition = session.getPlayerEntity().getPosition().toInt(); Vector3i flatPlayerPosition = session.getPlayerEntity().getPosition().toInt();
Vector3i position = flatPlayerPosition.add(Vector3i.UP); Vector3i position = flatPlayerPosition.add(Vector3i.UP);