mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-28 07:20:28 +01:00
Expose emote stuff in API; different secure chat checking
This should fix false flags from secure chat disablers doing funky things.
This commit is contained in:
parent
0521fba1a8
commit
48b796d75e
10 changed files with 115 additions and 54 deletions
|
@ -25,11 +25,31 @@
|
|||
|
||||
package org.geysermc.geyser.api.connection;
|
||||
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.api.connection.Connection;
|
||||
import org.geysermc.geyser.api.command.CommandSource;
|
||||
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Represents a player connection used in Geyser.
|
||||
*/
|
||||
public interface GeyserConnection extends Connection, CommandSource {
|
||||
/**
|
||||
* @param javaId the Java entity ID to look up.
|
||||
* @return a {@link GeyserEntity} if present in this connection's entity tracker.
|
||||
*/
|
||||
@NonNull
|
||||
CompletableFuture<@Nullable GeyserEntity> entityByJavaId(@NonNegative int javaId);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param emoter the player entity emoting.
|
||||
* @param emoteId the emote ID to send to the client.
|
||||
*/
|
||||
void showEmote(@NonNull GeyserPlayerEntity emoter, @NonNull String emoteId);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -23,22 +23,18 @@
|
|||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.translator.protocol.java;
|
||||
package org.geysermc.geyser.api.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundServerDataPacket;
|
||||
import org.geysermc.geyser.api.util.TriState;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
|
||||
@Translator(packet = ClientboundServerDataPacket.class)
|
||||
public class JavaServerDataTranslator extends PacketTranslator<ClientboundServerDataPacket> {
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundServerDataPacket packet) {
|
||||
// We only want to warn about chat maybe not working once
|
||||
if (packet.isEnforcesSecureChat() && session.getWorldCache().getChatWarningSent() == TriState.NOT_SET) {
|
||||
session.getWorldCache().setChatWarningSent(TriState.FALSE);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Represents a unique instance of an entity. Each {@link org.geysermc.geyser.api.connection.GeyserConnection}
|
||||
* have their own sets of entities - no two instances will share the same GeyserEntity instance.
|
||||
*/
|
||||
public interface GeyserEntity {
|
||||
/**
|
||||
* @return the entity ID that the server has assigned to this entity.
|
||||
*/
|
||||
@NonNegative
|
||||
int javaId();
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.api.entity.type.player;
|
||||
|
||||
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||
|
||||
public interface GeyserPlayerEntity extends GeyserEntity {
|
||||
}
|
|
@ -46,6 +46,7 @@ import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
@ -63,7 +64,7 @@ import java.util.UUID;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Entity {
|
||||
public class Entity implements GeyserEntity {
|
||||
protected final GeyserSession session;
|
||||
|
||||
protected int entityId;
|
||||
|
@ -509,6 +510,11 @@ public class Entity {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int javaId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return this.valid;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
|||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.LivingEntity;
|
||||
|
@ -64,7 +65,7 @@ import java.util.UUID;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Getter @Setter
|
||||
public class PlayerEntity extends LivingEntity {
|
||||
public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
||||
public static final float SNEAKING_POSE_HEIGHT = 1.5f;
|
||||
protected static final List<AbilityLayer> BASE_ABILITY_LAYER;
|
||||
|
||||
|
|
|
@ -63,8 +63,6 @@ import com.github.steveice10.packetlib.tcp.TcpSession;
|
|||
import com.nimbusds.jwt.SignedJWT;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
|
@ -75,10 +73,12 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.checkerframework.common.value.qual.IntRange;
|
||||
import org.cloudburstmc.math.vector.*;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -102,6 +102,8 @@ import org.geysermc.floodgate.util.BedrockData;
|
|||
import org.geysermc.geyser.Constants;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.connection.GeyserConnection;
|
||||
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
|
||||
import org.geysermc.geyser.api.network.AuthType;
|
||||
import org.geysermc.geyser.api.network.RemoteServer;
|
||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||
|
@ -1921,6 +1923,26 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CompletableFuture<@Nullable GeyserEntity> entityByJavaId(@NonNegative int javaId) {
|
||||
CompletableFuture<GeyserEntity> future = new CompletableFuture<>();
|
||||
ensureInEventLoop(() -> future.complete(this.entityCache.getEntityByJavaId(javaId)));
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmote(@NonNull GeyserPlayerEntity emoter, @NonNull String emoteId) {
|
||||
Entity entity = (Entity) emoter;
|
||||
if (entity.getSession() != this) {
|
||||
throw new IllegalStateException("Given entity must be from this session!");
|
||||
}
|
||||
|
||||
EmotePacket packet = new EmotePacket();
|
||||
packet.setEmoteId(emoteId);
|
||||
packet.setRuntimeEntityId(entity.getGeyserId());
|
||||
sendUpstreamPacket(packet);
|
||||
}
|
||||
|
||||
public void addCommandEnum(String name, String enums) {
|
||||
softEnumPacket(name, SoftEnumUpdateType.ADD, enums);
|
||||
}
|
||||
|
|
|
@ -26,15 +26,13 @@
|
|||
package org.geysermc.geyser.session.cache;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.api.util.TriState;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket;
|
||||
import org.geysermc.geyser.scoreboard.Scoreboard;
|
||||
import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
@ -63,17 +61,6 @@ public final class WorldCache {
|
|||
private int currentSequence;
|
||||
private final Object2IntMap<Vector3i> unverifiedPredictions = new Object2IntOpenHashMap<>(1);
|
||||
|
||||
/**
|
||||
* <ul>
|
||||
* <li>NOT_SET = not yet triggered</li>
|
||||
* <li>FALSE = enforce-secure-profile is true but player hasn't chatted yet</li>
|
||||
* <li>TRUE = enforce-secure-profile is enabled, and player has chatted and they have seen our message.</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private @NonNull TriState chatWarningSent = TriState.NOT_SET;
|
||||
|
||||
public WorldCache(GeyserSession session) {
|
||||
this.session = session;
|
||||
this.scoreboard = new Scoreboard(session);
|
||||
|
|
|
@ -26,9 +26,7 @@
|
|||
package org.geysermc.geyser.translator.protocol.bedrock;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
|
||||
import org.geysermc.geyser.api.util.TriState;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
|
@ -49,15 +47,6 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (session.getWorldCache().getChatWarningSent() == TriState.FALSE) {
|
||||
if (Boolean.parseBoolean(System.getProperty("Geyser.PrintSecureChatInformation", "true"))) {
|
||||
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_1", session.locale()));
|
||||
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_2", session.locale(), "https://geysermc.link/secure-chat"));
|
||||
}
|
||||
// Never send this message again for this session.
|
||||
session.getWorldCache().setChatWarningSent(TriState.TRUE);
|
||||
}
|
||||
|
||||
session.sendChat(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EmotePacket;
|
|||
import org.geysermc.geyser.api.event.bedrock.ClientEmoteEvent;
|
||||
import org.geysermc.geyser.configuration.EmoteOffhandWorkaroundOption;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
|
@ -61,7 +62,7 @@ public class BedrockEmoteTranslator extends PacketTranslator<EmotePacket> {
|
|||
if (otherSession.getEventLoop().inEventLoop()) {
|
||||
playEmote(otherSession, javaId, packet.getEmoteId());
|
||||
} else {
|
||||
session.executeInEventLoop(() -> playEmote(otherSession, javaId, packet.getEmoteId()));
|
||||
otherSession.executeInEventLoop(() -> playEmote(otherSession, javaId, packet.getEmoteId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,10 +70,7 @@ public class BedrockEmoteTranslator extends PacketTranslator<EmotePacket> {
|
|||
|
||||
private void playEmote(GeyserSession otherSession, int javaId, String emoteId) {
|
||||
Entity otherEntity = otherSession.getEntityCache().getEntityByJavaId(javaId); // Must be ran on same thread
|
||||
if (otherEntity == null) return;
|
||||
EmotePacket otherEmotePacket = new EmotePacket();
|
||||
otherEmotePacket.setEmoteId(emoteId);
|
||||
otherEmotePacket.setRuntimeEntityId(otherEntity.getGeyserId());
|
||||
otherSession.sendUpstreamPacket(otherEmotePacket);
|
||||
if (!(otherEntity instanceof PlayerEntity otherPlayer)) return;
|
||||
otherSession.showEmote(otherPlayer, emoteId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,10 @@
|
|||
package org.geysermc.geyser.translator.protocol.java;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
|
@ -37,6 +39,15 @@ public class JavaSystemChatTranslator extends PacketTranslator<ClientboundSystem
|
|||
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundSystemChatPacket packet) {
|
||||
if (packet.getContent() instanceof TranslatableComponent component && component.key().equals("chat.disabled.missingProfileKey")) {
|
||||
// We likely got this message as a response to a player trying to chat
|
||||
// As there SHOULD be no false flags for this, print every time it shows up in chat.
|
||||
if (Boolean.parseBoolean(System.getProperty("Geyser.PrintSecureChatInformation", "true"))) {
|
||||
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_1", session.locale()));
|
||||
session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.secure_info_2", session.locale(), "https://geysermc.link/secure-chat"));
|
||||
}
|
||||
}
|
||||
|
||||
TextPacket textPacket = new TextPacket();
|
||||
textPacket.setPlatformChatId("");
|
||||
textPacket.setSourceName("");
|
||||
|
|
Loading…
Reference in a new issue