mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Merge remote-tracking branch 'origin/master' into dev
Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
This commit is contained in:
commit
377eb07afc
10 changed files with 86 additions and 32 deletions
|
@ -235,7 +235,7 @@ public final class EntityDefinitions {
|
||||||
.addTranslator(MetadataType.BOOLEAN,
|
.addTranslator(MetadataType.BOOLEAN,
|
||||||
(enderCrystalEntity, entityMetadata) -> enderCrystalEntity.setFlag(EntityFlag.SHOW_BOTTOM, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) // There is a base located on the ender crystal
|
(enderCrystalEntity, entityMetadata) -> enderCrystalEntity.setFlag(EntityFlag.SHOW_BOTTOM, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) // There is a base located on the ender crystal
|
||||||
.build();
|
.build();
|
||||||
EXPERIENCE_ORB = EntityDefinition.<ExpOrbEntity>inherited(null, entityBase)
|
EXPERIENCE_ORB = EntityDefinition.inherited(ExpOrbEntity::new, entityBase)
|
||||||
.type(EntityType.EXPERIENCE_ORB)
|
.type(EntityType.EXPERIENCE_ORB)
|
||||||
.identifier("minecraft:xp_orb")
|
.identifier("minecraft:xp_orb")
|
||||||
.build();
|
.build();
|
||||||
|
@ -297,6 +297,7 @@ public final class EntityDefinitions {
|
||||||
TNT = EntityDefinition.inherited(TNTEntity::new, entityBase)
|
TNT = EntityDefinition.inherited(TNTEntity::new, entityBase)
|
||||||
.type(EntityType.TNT)
|
.type(EntityType.TNT)
|
||||||
.heightAndWidth(0.98f)
|
.heightAndWidth(0.98f)
|
||||||
|
.offset(0.49f)
|
||||||
.addTranslator(MetadataType.INT, TNTEntity::setFuseLength)
|
.addTranslator(MetadataType.INT, TNTEntity::setFuseLength)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ import java.util.*;
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class Entity implements GeyserEntity {
|
public class Entity implements GeyserEntity {
|
||||||
|
|
||||||
|
private static final boolean PRINT_ENTITY_SPAWN_DEBUG = Boolean.parseBoolean(System.getProperty("Geyser.PrintEntitySpawnDebug", "false"));
|
||||||
|
|
||||||
protected final GeyserSession session;
|
protected final GeyserSession session;
|
||||||
|
|
||||||
protected int entityId;
|
protected int entityId;
|
||||||
|
@ -181,7 +184,7 @@ public class Entity implements GeyserEntity {
|
||||||
|
|
||||||
flagsDirty = false;
|
flagsDirty = false;
|
||||||
|
|
||||||
if (session.getGeyser().getConfig().isDebugMode()) {
|
if (session.getGeyser().getConfig().isDebugMode() && PRINT_ENTITY_SPAWN_DEBUG) {
|
||||||
EntityType type = definition.entityType();
|
EntityType type = definition.entityType();
|
||||||
String name = type != null ? type.name() : getClass().getSimpleName();
|
String name = type != null ? type.name() : getClass().getSimpleName();
|
||||||
session.getGeyser().getLogger().debug("Spawned entity " + name + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
|
session.getGeyser().getLogger().debug("Spawned entity " + name + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
|
||||||
|
|
|
@ -27,11 +27,18 @@ package org.geysermc.geyser.entity.type;
|
||||||
|
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||||
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ExpOrbEntity extends Entity {
|
public class ExpOrbEntity extends Entity {
|
||||||
|
|
||||||
|
public ExpOrbEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> entityDefinition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
this(session, 1, entityId, geyserId, position);
|
||||||
|
}
|
||||||
|
|
||||||
public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) {
|
public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) {
|
||||||
super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0);
|
super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0);
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,17 @@ public class TNTEntity extends Entity implements Tickable {
|
||||||
private int currentTick;
|
private int currentTick;
|
||||||
|
|
||||||
public TNTEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
public TNTEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
super(session, entityId, geyserId, uuid, definition, position.add(0, definition.offset(), 0), motion, yaw, pitch, headYaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) {
|
||||||
|
super.moveRelative(relX, relY + definition.offset(), relZ, yaw, pitch, isOnGround);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
|
||||||
|
super.moveAbsolute(position.add(Vector3f.from(0, definition.offset(), 0)), yaw, pitch, headYaw, isOnGround, teleported);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFuseLength(IntEntityMetadata entityMetadata) {
|
public void setFuseLength(IntEntityMetadata entityMetadata) {
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||||
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
|
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
|
||||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
|
@ -166,6 +167,31 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
||||||
session.sendUpstreamPacket(addPlayerPacket);
|
session.sendUpstreamPacket(addPlayerPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void despawnEntity() {
|
||||||
|
super.despawnEntity();
|
||||||
|
|
||||||
|
// Since we re-use player entities: Clear flags, held item, etc
|
||||||
|
this.resetMetadata();
|
||||||
|
this.hand = ItemData.AIR;
|
||||||
|
this.offhand = ItemData.AIR;
|
||||||
|
this.boots = ItemData.AIR;
|
||||||
|
this.leggings = ItemData.AIR;
|
||||||
|
this.chestplate = ItemData.AIR;
|
||||||
|
this.helmet = ItemData.AIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetMetadata() {
|
||||||
|
// Reset all metadata to their default values
|
||||||
|
// This is used when a player respawns
|
||||||
|
this.flags.clear();
|
||||||
|
this.initializeMetadata();
|
||||||
|
|
||||||
|
// Explicitly reset all metadata not handled by initializeMetadata
|
||||||
|
setParrot(null, true);
|
||||||
|
setParrot(null, false);
|
||||||
|
}
|
||||||
|
|
||||||
public void sendPlayer() {
|
public void sendPlayer() {
|
||||||
if (session.getEntityCache().getPlayerEntity(uuid) == null)
|
if (session.getEntityCache().getPlayerEntity(uuid) == null)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -230,19 +230,13 @@ public class SessionPlayerEntity extends PlayerEntity {
|
||||||
super.setAbsorptionHearts(entityMetadata);
|
super.setAbsorptionHearts(entityMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void resetMetadata() {
|
public void resetMetadata() {
|
||||||
// Reset all metadata to their default values
|
super.resetMetadata();
|
||||||
// This is used when a player respawns
|
|
||||||
this.flags.clear();
|
|
||||||
this.initializeMetadata();
|
|
||||||
|
|
||||||
// Reset air
|
// Reset air
|
||||||
this.resetAir();
|
this.resetAir();
|
||||||
|
|
||||||
// Explicitly reset all metadata not handled by initializeMetadata
|
|
||||||
setParrot(null, true);
|
|
||||||
setParrot(null, false);
|
|
||||||
|
|
||||||
// Absorption is metadata in java edition
|
// Absorption is metadata in java edition
|
||||||
attributes.remove(GeyserAttributeType.ABSORPTION);
|
attributes.remove(GeyserAttributeType.ABSORPTION);
|
||||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||||
|
|
|
@ -883,6 +883,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||||
this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, resolveSrv);
|
this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, resolveSrv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable automatic creation of a new TcpClientSession when transferring - we don't use that functionality.
|
||||||
|
this.downstream.getSession().setFlag(MinecraftConstants.FOLLOW_TRANSFERS, false);
|
||||||
|
|
||||||
if (geyser.getConfig().getRemote().isUseProxyProtocol()) {
|
if (geyser.getConfig().getRemote().isUseProxyProtocol()) {
|
||||||
downstream.setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
|
downstream.setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
|
||||||
downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
|
downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
|
||||||
|
|
|
@ -91,15 +91,11 @@ public class AdvancementsCache {
|
||||||
builder.validResultHandler((response) -> {
|
builder.validResultHandler((response) -> {
|
||||||
String id = rootAdvancementIds.get(response.clickedButtonId());
|
String id = rootAdvancementIds.get(response.clickedButtonId());
|
||||||
if (!id.equals("")) {
|
if (!id.equals("")) {
|
||||||
if (id.equals(currentAdvancementCategoryId)) {
|
// Send a packet indicating that we are opening this particular advancement window
|
||||||
// The server thinks we are already on this tab
|
ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id);
|
||||||
buildAndShowListForm();
|
session.sendDownstreamGamePacket(packet);
|
||||||
} else {
|
currentAdvancementCategoryId = id;
|
||||||
// Send a packet indicating that we intend to open this particular advancement window
|
buildAndShowListForm();
|
||||||
ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id);
|
|
||||||
session.sendDownstreamGamePacket(packet);
|
|
||||||
// Wait for a response there
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -190,6 +186,10 @@ public class AdvancementsCache {
|
||||||
.content(content)
|
.content(content)
|
||||||
.button(GeyserLocale.getPlayerLocaleString("gui.back", language))
|
.button(GeyserLocale.getPlayerLocaleString("gui.back", language))
|
||||||
.validResultHandler((response) -> buildAndShowListForm())
|
.validResultHandler((response) -> buildAndShowListForm())
|
||||||
|
.closedResultHandler(() -> {
|
||||||
|
// Indicate that we have closed the current advancement tab
|
||||||
|
session.sendDownstreamGamePacket(new ServerboundSeenAdvancementsPacket());
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ package org.geysermc.geyser.session.cache;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
|
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
|
||||||
|
@ -53,11 +52,13 @@ public final class LodestoneCache {
|
||||||
private int id = 1;
|
private int id = 1;
|
||||||
|
|
||||||
public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) {
|
public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) {
|
||||||
GlobalPos position = tracker.getPos();
|
if (!tracker.isTracked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalPos position = tracker.getPos();
|
||||||
if (position == null) {
|
if (position == null) {
|
||||||
GeyserImpl.getInstance().getLogger().error("Position is null. Find out why.");
|
// As of 1.20.6, position can still be null even if tracking is enabled.
|
||||||
Thread.dumpStack();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int x = position.getX();
|
int x = position.getX();
|
||||||
|
@ -84,13 +85,16 @@ public final class LodestoneCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int store(LodestoneTracker tracker) {
|
public int store(LodestoneTracker tracker) {
|
||||||
GlobalPos position = tracker.getPos();
|
if (!tracker.isTracked()) {
|
||||||
|
// No coordinates; nothing to convert
|
||||||
if (position == null) {
|
return 0;
|
||||||
GeyserImpl.getInstance().getLogger().error("Position is null. Find out why.");
|
|
||||||
Thread.dumpStack();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlobalPos position = tracker.getPos();
|
||||||
|
if (position == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int x = position.getX();
|
int x = position.getX();
|
||||||
int y = position.getY();
|
int y = position.getY();
|
||||||
int z = position.getZ();
|
int z = position.getZ();
|
||||||
|
|
|
@ -63,6 +63,13 @@ public class MinecraftTranslationRegistry extends TranslatableComponentRenderer<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// replace single quote instances which get lost in MessageFormat otherwise
|
||||||
|
localeString = localeString.replace("'", "''");
|
||||||
|
|
||||||
|
// Wrap all curly brackets with single quote inserts - fixes https://github.com/GeyserMC/Geyser/issues/4662
|
||||||
|
localeString = localeString.replace("{", "'{")
|
||||||
|
.replace("}", "'}");
|
||||||
|
|
||||||
// Replace the `%s` with numbered inserts `{0}`
|
// Replace the `%s` with numbered inserts `{0}`
|
||||||
Pattern p = stringReplacement;
|
Pattern p = stringReplacement;
|
||||||
Matcher m = p.matcher(localeString);
|
Matcher m = p.matcher(localeString);
|
||||||
|
@ -83,8 +90,7 @@ public class MinecraftTranslationRegistry extends TranslatableComponentRenderer<
|
||||||
}
|
}
|
||||||
m.appendTail(sb);
|
m.appendTail(sb);
|
||||||
|
|
||||||
// replace single quote instances which get lost in MessageFormat otherwise
|
|
||||||
// Locale shouldn't need to be specific - dates for example will not be handled
|
// Locale shouldn't need to be specific - dates for example will not be handled
|
||||||
return new MessageFormat(sb.toString().replace("'", "''"), Locale.ROOT);
|
return new MessageFormat(sb.toString(), Locale.ROOT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue