Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 16:12:46 +01:00
Better handle chat packets sent before login
Dieser Commit ist enthalten in:
Ursprung
691d674f01
Commit
162aff4978
@ -37,7 +37,6 @@ import com.github.steveice10.mc.protocol.MinecraftProtocol;
|
|||||||
import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper;
|
import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper;
|
||||||
import com.github.steveice10.mc.protocol.data.ProtocolState;
|
import com.github.steveice10.mc.protocol.data.ProtocolState;
|
||||||
import com.github.steveice10.mc.protocol.data.UnexpectedEncryptionException;
|
import com.github.steveice10.mc.protocol.data.UnexpectedEncryptionException;
|
||||||
import com.github.steveice10.mc.protocol.data.game.MessageType;
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||||
@ -124,10 +123,12 @@ import org.geysermc.geyser.skin.FloodgateSkinUploader;
|
|||||||
import org.geysermc.geyser.text.ChatTypeEntry;
|
import org.geysermc.geyser.text.ChatTypeEntry;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
import org.geysermc.geyser.text.MinecraftLocale;
|
import org.geysermc.geyser.text.MinecraftLocale;
|
||||||
import org.geysermc.geyser.text.TextDecoration;
|
|
||||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||||
import org.geysermc.geyser.util.*;
|
import org.geysermc.geyser.util.ChunkUtils;
|
||||||
|
import org.geysermc.geyser.util.DimensionUtils;
|
||||||
|
import org.geysermc.geyser.util.LoginEncryptionUtils;
|
||||||
|
import org.geysermc.geyser.util.MathUtils;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
@ -337,7 +338,7 @@ public class GeyserSession implements GeyserConnection, CommandSender {
|
|||||||
*/
|
*/
|
||||||
private final Map<String, JavaDimension> dimensions = new Object2ObjectOpenHashMap<>(3);
|
private final Map<String, JavaDimension> dimensions = new Object2ObjectOpenHashMap<>(3);
|
||||||
|
|
||||||
private final Int2ObjectMap<ChatTypeEntry> chatTypes = new Int2ObjectOpenHashMap<>(7);
|
private final Int2ObjectMap<ChatTypeEntry> chatTypes = new Int2ObjectOpenHashMap<>(8);
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private int breakingBlock;
|
private int breakingBlock;
|
||||||
@ -548,6 +549,8 @@ public class GeyserSession implements GeyserConnection, CommandSender {
|
|||||||
this.playerEntity = new SessionPlayerEntity(this);
|
this.playerEntity = new SessionPlayerEntity(this);
|
||||||
collisionManager.updatePlayerBoundingBox(this.playerEntity.getPosition());
|
collisionManager.updatePlayerBoundingBox(this.playerEntity.getPosition());
|
||||||
|
|
||||||
|
ChatTypeEntry.applyDefaults(chatTypes);
|
||||||
|
|
||||||
this.playerInventory = new PlayerInventory();
|
this.playerInventory = new PlayerInventory();
|
||||||
this.openInventory = null;
|
this.openInventory = null;
|
||||||
this.craftingRecipes = new Int2ObjectOpenHashMap<>();
|
this.craftingRecipes = new Int2ObjectOpenHashMap<>();
|
||||||
|
@ -33,12 +33,15 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class UpstreamSession {
|
public class UpstreamSession {
|
||||||
@Getter private final BedrockServerSession session;
|
@Getter private final BedrockServerSession session;
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
private boolean initialized = false;
|
private boolean initialized = false;
|
||||||
|
private Queue<BedrockPacket> postStartGamePackets = new ArrayDeque<>();
|
||||||
|
|
||||||
public void sendPacket(@NonNull BedrockPacket packet) {
|
public void sendPacket(@NonNull BedrockPacket packet) {
|
||||||
if (!isClosed()) {
|
if (!isClosed()) {
|
||||||
@ -56,6 +59,25 @@ public class UpstreamSession {
|
|||||||
session.disconnect(reason);
|
session.disconnect(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a packet that must be delayed until after login.
|
||||||
|
*/
|
||||||
|
public void queuePostStartGamePacket(BedrockPacket packet) {
|
||||||
|
postStartGamePackets.add(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendPostStartGamePackets() {
|
||||||
|
if (isClosed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BedrockPacket packet;
|
||||||
|
while ((packet = postStartGamePackets.poll()) != null) {
|
||||||
|
session.sendPacket(packet);
|
||||||
|
}
|
||||||
|
postStartGamePackets = null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
return session.isClosed();
|
return session.isClosed();
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,33 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.text;
|
package org.geysermc.geyser.text;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.MessageType;
|
||||||
import com.nukkitx.protocol.bedrock.packet.TextPacket;
|
import com.nukkitx.protocol.bedrock.packet.TextPacket;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public record ChatTypeEntry(@Nonnull TextPacket.Type bedrockChatType, @Nullable TextDecoration textDecoration) {
|
public record ChatTypeEntry(@Nonnull TextPacket.Type bedrockChatType, @Nullable TextDecoration textDecoration) {
|
||||||
|
private static final ChatTypeEntry CHAT = new ChatTypeEntry(TextPacket.Type.CHAT, null);
|
||||||
|
private static final ChatTypeEntry SYSTEM = new ChatTypeEntry(TextPacket.Type.CHAT, null);
|
||||||
|
private static final ChatTypeEntry TIP = new ChatTypeEntry(TextPacket.Type.CHAT, null);
|
||||||
|
private static final ChatTypeEntry RAW = new ChatTypeEntry(TextPacket.Type.CHAT, null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply defaults to a map so it isn't empty in the event a chat message is sent before the login packet.
|
||||||
|
*/
|
||||||
|
public static void applyDefaults(Int2ObjectMap<ChatTypeEntry> chatTypes) {
|
||||||
|
// So the proper way to do this, probably, would be to dump the NBT data from vanilla and load it.
|
||||||
|
// But, the only way this happens is if a chat message is sent to us before the login packet, which is rare.
|
||||||
|
// So we'll just make sure chat ends up in the right place.
|
||||||
|
chatTypes.put(MessageType.CHAT.ordinal(), CHAT);
|
||||||
|
chatTypes.put(MessageType.SYSTEM.ordinal(), SYSTEM);
|
||||||
|
chatTypes.put(MessageType.GAME_INFO.ordinal(), TIP);
|
||||||
|
chatTypes.put(MessageType.SAY_COMMAND.ordinal(), RAW);
|
||||||
|
chatTypes.put(MessageType.MSG_COMMAND.ordinal(), RAW);
|
||||||
|
chatTypes.put(MessageType.TEAM_MSG_COMMAND.ordinal(), RAW);
|
||||||
|
chatTypes.put(MessageType.EMOTE_COMMAND.ordinal(), RAW);
|
||||||
|
chatTypes.put(MessageType.TELLRAW_COMMAND.ordinal(), RAW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,9 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
|||||||
// 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.setDimension(newDimension);
|
session.setDimension(newDimension);
|
||||||
session.connect();
|
session.connect();
|
||||||
|
|
||||||
|
// It is now safe to send these packets
|
||||||
|
session.getUpstream().sendPostStartGamePackets();
|
||||||
}
|
}
|
||||||
|
|
||||||
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
|
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
|
||||||
|
@ -46,6 +46,10 @@ public class JavaSystemChatTranslator extends PacketTranslator<ClientboundSystem
|
|||||||
textPacket.setNeedsTranslation(false);
|
textPacket.setNeedsTranslation(false);
|
||||||
textPacket.setMessage(MessageTranslator.convertMessage(packet.getContent(), session.getLocale()));
|
textPacket.setMessage(MessageTranslator.convertMessage(packet.getContent(), session.getLocale()));
|
||||||
|
|
||||||
session.sendUpstreamPacket(textPacket);
|
if (session.isSentSpawnPacket()) {
|
||||||
|
session.sendUpstreamPacket(textPacket);
|
||||||
|
} else {
|
||||||
|
session.getUpstream().queuePostStartGamePacket(textPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren