Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 08:10:11 +01:00
Merge branch 'master' of https://github.com/GeyserMC/Geyser into feature/protocol-3.0
Dieser Commit ist enthalten in:
Commit
4fe9aeca40
@ -17,7 +17,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
|
||||
|
||||
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
|
||||
|
||||
### Currently supporting Minecraft Bedrock 1.19.0 - 1.19.40 and Minecraft Java 1.19.1/1.19.2.
|
||||
### Currently supporting Minecraft Bedrock 1.19.20 - 1.19.51 and Minecraft Java 1.19.3.
|
||||
|
||||
## Setting Up
|
||||
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
|
||||
|
@ -29,7 +29,6 @@ import lombok.Getter;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.geysermc.geyser.dump.BootstrapDumpInfo;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -52,15 +51,17 @@ public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
|
||||
this.plugins = new ArrayList<>();
|
||||
|
||||
for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) {
|
||||
String hostname = listener.getHost().getHostString();
|
||||
if (!AsteriskSerializer.showSensitive && !(hostname.equals("") || hostname.equals("0.0.0.0"))) {
|
||||
hostname = "***";
|
||||
}
|
||||
this.listeners.add(new ListenerInfo(hostname, listener.getHost().getPort()));
|
||||
this.listeners.add(new ListenerInfo(listener.getHost().getHostString(), listener.getHost().getPort()));
|
||||
}
|
||||
|
||||
for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
|
||||
this.plugins.add(new PluginInfo(true, plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), Collections.singletonList(plugin.getDescription().getAuthor())));
|
||||
this.plugins.add(new PluginInfo(
|
||||
true,
|
||||
plugin.getDescription().getName(),
|
||||
plugin.getDescription().getVersion(),
|
||||
plugin.getDescription().getMain(),
|
||||
Collections.singletonList(plugin.getDescription().getAuthor()))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
||||
// Copied from ViaVersion.
|
||||
// https://github.com/ViaVersion/ViaVersion/blob/b8072aad86695cc8ec6f5e4103e43baf3abf6cc5/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java#L43
|
||||
try {
|
||||
ProtocolConstants.class.getField("MINECRAFT_1_19_1");
|
||||
ProtocolConstants.class.getField("MINECRAFT_1_19_3");
|
||||
} catch (NoSuchFieldException e) {
|
||||
getLogger().warning(" / \\");
|
||||
getLogger().warning(" / \\");
|
||||
|
@ -1,8 +1,5 @@
|
||||
plugins {
|
||||
id("fabric-loom") version "1.0-SNAPSHOT"
|
||||
id("maven-publish")
|
||||
id("com.github.johnrengelman.shadow")
|
||||
id("java")
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -25,65 +25,58 @@
|
||||
|
||||
package org.geysermc.geyser.platform.fabric;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||
import net.fabricmc.loader.api.metadata.Person;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.geysermc.geyser.dump.BootstrapDumpInfo;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuppressWarnings("unused") // The way that the dump renders makes them used
|
||||
@Getter
|
||||
public class GeyserFabricDumpInfo extends BootstrapDumpInfo {
|
||||
|
||||
private String platformVersion = null;
|
||||
private final EnvType environmentType;
|
||||
|
||||
@AsteriskSerializer.Asterisk(isIp = true)
|
||||
private final String serverIP;
|
||||
private final int serverPort;
|
||||
private final List<ModInfo> mods;
|
||||
|
||||
public GeyserFabricDumpInfo(MinecraftServer server) {
|
||||
super();
|
||||
for (ModContainer modContainer : FabricLoader.getInstance().getAllMods()) {
|
||||
if (modContainer.getMetadata().getId().equals("fabricloader")) {
|
||||
this.platformVersion = modContainer.getMetadata().getVersion().getFriendlyString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
FabricLoader.getInstance().getModContainer("fabricloader").ifPresent(mod ->
|
||||
this.platformVersion = mod.getMetadata().getVersion().getFriendlyString());
|
||||
|
||||
this.environmentType = FabricLoader.getInstance().getEnvironmentType();
|
||||
if (AsteriskSerializer.showSensitive || (server.getLocalIp() == null || server.getLocalIp().equals("") || server.getLocalIp().equals("0.0.0.0"))) {
|
||||
this.serverIP = server.getLocalIp();
|
||||
} else {
|
||||
this.serverIP = "***";
|
||||
}
|
||||
this.serverIP = server.getLocalIp() == null ? "unknown" : server.getLocalIp();
|
||||
this.serverPort = server.getPort();
|
||||
this.mods = new ArrayList<>();
|
||||
|
||||
for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
|
||||
this.mods.add(new ModInfo(mod));
|
||||
ModMetadata meta = mod.getMetadata();
|
||||
this.mods.add(new ModInfo(
|
||||
FabricLoader.getInstance().isModLoaded(meta.getId()),
|
||||
meta.getId(),
|
||||
meta.getVersion().getFriendlyString(),
|
||||
meta.getAuthors().stream().map(Person::getName).collect(Collectors.toList()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPlatformVersion() {
|
||||
return platformVersion;
|
||||
}
|
||||
|
||||
public EnvType getEnvironmentType() {
|
||||
return environmentType;
|
||||
}
|
||||
|
||||
public String getServerIP() {
|
||||
return this.serverIP;
|
||||
}
|
||||
|
||||
public int getServerPort() {
|
||||
return this.serverPort;
|
||||
}
|
||||
|
||||
public List<ModInfo> getMods() {
|
||||
return this.mods;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class ModInfo {
|
||||
public boolean enabled;
|
||||
public String name;
|
||||
public String version;
|
||||
public List<String> authors;
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +246,10 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap {
|
||||
@Override
|
||||
public InputStream getResourceOrNull(String resource) {
|
||||
// We need to handle this differently, because Fabric shares the classloader across multiple mods
|
||||
Path path = this.mod.getPath(resource);
|
||||
Path path = this.mod.findPath(resource).orElse(null);
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return path.getFileSystem()
|
||||
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 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.platform.fabric;
|
||||
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A wrapper for Fabric mod information to be presented in a Geyser dump
|
||||
*/
|
||||
public class ModInfo {
|
||||
|
||||
private final String name;
|
||||
private final String id;
|
||||
private final String version;
|
||||
private final List<String> authors;
|
||||
|
||||
public ModInfo(ModContainer mod) {
|
||||
this.name = mod.getMetadata().getName();
|
||||
this.id = mod.getMetadata().getId();
|
||||
this.authors = new ArrayList<>();
|
||||
mod.getMetadata().getAuthors().forEach((person) -> this.authors.add(person.getName()));
|
||||
this.version = mod.getMetadata().getVersion().getFriendlyString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public List<String> getAuthors() {
|
||||
return this.authors;
|
||||
}
|
||||
}
|
@ -26,9 +26,9 @@
|
||||
package org.geysermc.geyser.platform.fabric.world;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
|
@ -41,6 +41,8 @@ public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
|
||||
private final String platformVersion;
|
||||
private final String platformAPIVersion;
|
||||
private final boolean onlineMode;
|
||||
|
||||
@AsteriskSerializer.Asterisk(isIp = true)
|
||||
private final String serverIP;
|
||||
private final int serverPort;
|
||||
private final List<PluginInfo> plugins;
|
||||
@ -51,12 +53,7 @@ public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
|
||||
this.platformVersion = Bukkit.getVersion();
|
||||
this.platformAPIVersion = Bukkit.getBukkitVersion();
|
||||
this.onlineMode = Bukkit.getOnlineMode();
|
||||
String ip = Bukkit.getIp();
|
||||
if (AsteriskSerializer.showSensitive || (ip.equals("") || ip.equals("0.0.0.0"))) {
|
||||
this.serverIP = ip;
|
||||
} else {
|
||||
this.serverIP = "***";
|
||||
}
|
||||
this.serverIP = Bukkit.getIp();
|
||||
this.serverPort = Bukkit.getPort();
|
||||
this.plugins = new ArrayList<>();
|
||||
|
||||
|
@ -32,6 +32,7 @@ import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
|
||||
import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
|
||||
protected final SpigotWorldAdapter adapter;
|
||||
@ -49,4 +50,12 @@ public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
|
||||
}
|
||||
return adapter.getBlockAt(player.getWorld(), x, y, z);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String[] getBiomeIdentifiers(boolean withTags) {
|
||||
// Biome identifiers will basically always be the same for one server, since you have to re-send the
|
||||
// ClientboundLoginPacket to change the registry. Therefore, don't bother caching for each player.
|
||||
return adapter.getBiomeSuggestions(withTags);
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,9 @@
|
||||
package org.geysermc.geyser.platform.spigot.world.manager;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
@ -38,7 +38,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.geysermc.geyser.level.GameRule;
|
||||
import org.geysermc.geyser.level.GeyserWorldManager;
|
||||
import org.geysermc.geyser.level.WorldManager;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@ -51,7 +51,7 @@ import java.util.List;
|
||||
/**
|
||||
* The base world manager to use when there is no supported NMS revision
|
||||
*/
|
||||
public class GeyserSpigotWorldManager extends GeyserWorldManager {
|
||||
public class GeyserSpigotWorldManager extends WorldManager {
|
||||
private final Plugin plugin;
|
||||
|
||||
public GeyserSpigotWorldManager(Plugin plugin) {
|
||||
@ -151,12 +151,12 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean getGameRuleBool(GeyserSession session, GameRule gameRule) {
|
||||
public boolean getGameRuleBool(GeyserSession session, GameRule gameRule) {
|
||||
String value = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getGameRuleValue(gameRule.getJavaID());
|
||||
if (!value.isEmpty()) {
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
return (Boolean) gameRule.getDefaultValue();
|
||||
return gameRule.getDefaultBooleanValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -165,7 +165,7 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
|
||||
if (!value.isEmpty()) {
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
return (int) gameRule.getDefaultValue();
|
||||
return gameRule.getDefaultIntValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,6 +45,8 @@ public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
|
||||
private final String platformName;
|
||||
private final String platformVersion;
|
||||
private final boolean onlineMode;
|
||||
|
||||
@AsteriskSerializer.Asterisk(isIp = true)
|
||||
private final String serverIP;
|
||||
private final int serverPort;
|
||||
private final List<PluginInfo> plugins;
|
||||
@ -56,12 +58,7 @@ public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
|
||||
this.platformVersion = platformMeta.version().getQualifier();
|
||||
this.onlineMode = Sponge.server().isOnlineModeEnabled();
|
||||
Optional<InetSocketAddress> socketAddress = Sponge.server().boundAddress();
|
||||
String hostString = socketAddress.map(InetSocketAddress::getHostString).orElse("unknown");
|
||||
if (AsteriskSerializer.showSensitive || (hostString.equals("") || hostString.equals("0.0.0.0") || hostString.equals("unknown"))) {
|
||||
this.serverIP = hostString;
|
||||
} else {
|
||||
this.serverIP = "***";
|
||||
}
|
||||
this.serverIP = socketAddress.map(InetSocketAddress::getHostString).orElse("unknown");
|
||||
this.serverPort = socketAddress.map(InetSocketAddress::getPort).orElse(-1);
|
||||
this.plugins = new ArrayList<>();
|
||||
|
||||
|
@ -41,6 +41,8 @@ public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
|
||||
private final String platformVersion;
|
||||
private final String platformVendor;
|
||||
private final boolean onlineMode;
|
||||
|
||||
@AsteriskSerializer.Asterisk(isIp = true)
|
||||
private final String serverIP;
|
||||
private final int serverPort;
|
||||
private final List<PluginInfo> plugins;
|
||||
@ -51,12 +53,7 @@ public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
|
||||
this.platformVersion = proxy.getVersion().getVersion();
|
||||
this.platformVendor = proxy.getVersion().getVendor();
|
||||
this.onlineMode = proxy.getConfiguration().isOnlineMode();
|
||||
String hostString = proxy.getBoundAddress().getHostString();
|
||||
if (AsteriskSerializer.showSensitive || (hostString.equals("") || hostString.equals("0.0.0.0"))) {
|
||||
this.serverIP = hostString;
|
||||
} else {
|
||||
this.serverIP = "***";
|
||||
}
|
||||
this.serverIP = proxy.getBoundAddress().getHostString();
|
||||
this.serverPort = proxy.getBoundAddress().getPort();
|
||||
this.plugins = new ArrayList<>();
|
||||
|
||||
|
@ -16,11 +16,11 @@ dependencies {
|
||||
|
||||
// Within the gradle plugin classpath, there is a version conflict between loom and some other
|
||||
// plugin for databind. This fixes it: minimum 2.13.2 is required by loom.
|
||||
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")
|
||||
implementation("com.fasterxml.jackson.core:jackson-databind:2.14.0")
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = "16"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,8 @@ public interface GeyserConfiguration {
|
||||
|
||||
boolean isNotifyOnNewBedrockUpdate();
|
||||
|
||||
String getUnusableSpaceBlock();
|
||||
|
||||
IMetricsInfo getMetrics();
|
||||
|
||||
int getPendingAuthenticationTimeout();
|
||||
|
@ -154,6 +154,9 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
||||
@JsonProperty("notify-on-new-bedrock-update")
|
||||
private boolean notifyOnNewBedrockUpdate = true;
|
||||
|
||||
@JsonProperty("unusable-space-block")
|
||||
private String unusableSpaceBlock = "minecraft:barrier";
|
||||
|
||||
private MetricsInfo metrics = new MetricsInfo();
|
||||
|
||||
@JsonProperty("pending-authentication-timeout")
|
||||
|
@ -29,6 +29,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.common.PlatformType;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -53,6 +54,8 @@ public class BootstrapDumpInfo {
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class ListenerInfo {
|
||||
|
||||
@AsteriskSerializer.Asterisk(isIp = true)
|
||||
public String ip;
|
||||
public int port;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ public final class EntityDefinitions {
|
||||
public static final EntityDefinition<BeeEntity> BEE;
|
||||
public static final EntityDefinition<BlazeEntity> BLAZE;
|
||||
public static final EntityDefinition<BoatEntity> BOAT;
|
||||
public static final EntityDefinition<CamelEntity> CAMEL;
|
||||
public static final EntityDefinition<CatEntity> CAT;
|
||||
public static final EntityDefinition<SpiderEntity> CAVE_SPIDER;
|
||||
public static final EntityDefinition<MinecartEntity> CHEST_MINECART;
|
||||
@ -859,6 +860,13 @@ public final class EntityDefinitions {
|
||||
.addTranslator(MetadataType.BYTE, AbstractHorseEntity::setHorseFlags)
|
||||
.addTranslator(null) // UUID of owner
|
||||
.build();
|
||||
CAMEL = EntityDefinition.inherited(CamelEntity::new, abstractHorseEntityBase)
|
||||
.type(EntityType.CAMEL)
|
||||
.identifier("minecraft:llama") // todo 1.20
|
||||
.height(2.375f).width(1.7f)
|
||||
.addTranslator(MetadataType.BOOLEAN, CamelEntity::setDashing)
|
||||
.addTranslator(null) // Last pose change tick
|
||||
.build();
|
||||
HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase)
|
||||
.type(EntityType.HORSE)
|
||||
.height(1.6f).width(1.3965f)
|
||||
|
@ -48,6 +48,8 @@ import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
@ -360,6 +362,7 @@ public class Entity {
|
||||
setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire
|
||||
setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02);
|
||||
setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
|
||||
|
||||
// Swimming is ignored here and instead we rely on the pose
|
||||
setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);
|
||||
|
||||
|
@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||
import org.geysermc.floodgate.util.DeviceOs;
|
||||
|
@ -33,8 +33,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 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.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CamelEntity extends AbstractHorseEntity {
|
||||
|
||||
private static final float SITTING_HEIGHT_DIFFERENCE = 1.43F;
|
||||
|
||||
public CamelEntity(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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeMetadata() {
|
||||
super.initializeMetadata();
|
||||
this.dirtyMetadata.put(EntityDataTypes.VARIANT, 2); // Closest llama colour to camel
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return "cactus".equals(javaIdentifierStripped);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDimensions(Pose pose) {
|
||||
if (pose == Pose.SITTING) {
|
||||
setBoundingBoxWidth(definition.height() - SITTING_HEIGHT_DIFFERENCE);
|
||||
setBoundingBoxWidth(definition.width());
|
||||
} else {
|
||||
super.setDimensions(pose);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDashing(BooleanEntityMetadata entityMetadata) {
|
||||
|
||||
}
|
||||
}
|
@ -25,16 +25,19 @@
|
||||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.OptionalIntMetadataType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EndermanEntity extends MonsterEntity {
|
||||
@ -43,8 +46,15 @@ public class EndermanEntity extends MonsterEntity {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public void setCarriedBlock(IntEntityMetadata entityMetadata) {
|
||||
dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getBedrockBlock(entityMetadata.getPrimitiveValue()));
|
||||
public void setCarriedBlock(EntityMetadata<OptionalInt, OptionalIntMetadataType> entityMetadata) {
|
||||
BlockDefinition bedrockBlockId;
|
||||
if (entityMetadata.getValue().isPresent()) {
|
||||
bedrockBlockId = session.getBlockMappings().getBedrockBlock(entityMetadata.getValue().getAsInt());
|
||||
} else {
|
||||
bedrockBlockId = session.getBlockMappings().getBedrockAir();
|
||||
}
|
||||
|
||||
dirtyMetadata.put(EntityDataTypes.CARRY_BLOCK_STATE, bedrockBlockId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,13 +30,13 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeTyp
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@ -47,7 +47,6 @@ import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The entity class specifically for a {@link GeyserSession}'s player.
|
||||
@ -120,6 +119,16 @@ public class SessionPlayerEntity extends PlayerEntity {
|
||||
refreshSpeed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since 1.19.40, the client must be re-informed of its bounding box on respawn
|
||||
* See https://github.com/GeyserMC/Geyser/issues/3370
|
||||
*/
|
||||
public void updateBoundingBox() {
|
||||
dirtyMetadata.put(EntityDataTypes.HEIGHT, getBoundingBoxHeight());
|
||||
dirtyMetadata.put(EntityDataTypes.WIDTH, getBoundingBoxWidth());
|
||||
updateBedrockMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBoundingBoxHeight(float height) {
|
||||
if (super.setBoundingBoxHeight(height)) {
|
||||
|
@ -76,7 +76,7 @@ public class AnvilContainer extends Container {
|
||||
String originalName = ItemUtils.getCustomName(getInput().getNbt());
|
||||
|
||||
String plainOriginalName = MessageTranslator.convertToPlainText(originalName, session.locale());
|
||||
String plainNewName = MessageTranslator.convertToPlainText(rename, session.locale());
|
||||
String plainNewName = MessageTranslator.convertToPlainText(rename);
|
||||
if (!plainOriginalName.equals(plainNewName)) {
|
||||
// Strip out formatting since Java Edition does not allow it
|
||||
correctRename = plainNewName;
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
@ -30,10 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerActionType
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.MoveToHotbarAction;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
@ -124,12 +121,14 @@ public final class ClickPlan {
|
||||
}
|
||||
|
||||
ItemStack clickedItemStack;
|
||||
if (!planIter.hasNext() && refresh) {
|
||||
clickedItemStack = InventoryUtils.REFRESH_ITEM;
|
||||
if (emulatePost1_16Logic) {
|
||||
// The action must be simulated first as Java expects the new contents of the cursor (as of 1.18.1)
|
||||
clickedItemStack = simulatedCursor.getItemStack();
|
||||
} else {
|
||||
if (emulatePost1_16Logic) {
|
||||
// The action must be simulated first as Java expects the new contents of the cursor (as of 1.18.1)
|
||||
clickedItemStack = simulatedCursor.getItemStack();
|
||||
if (!planIter.hasNext() && refresh) {
|
||||
// Doesn't have the intended effect with state IDs since this won't cause a complete window refresh
|
||||
// (It will eventually once state IDs desync, but this causes more problems than not)
|
||||
clickedItemStack = InventoryUtils.REFRESH_ITEM;
|
||||
} else {
|
||||
if (action.click.actionType == ContainerActionType.DROP_ITEM || action.slot == Click.OUTSIDE_SLOT) {
|
||||
clickedItemStack = null;
|
||||
|
@ -25,9 +25,8 @@
|
||||
|
||||
package org.geysermc.geyser.inventory.holder;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.ContainerClosePacket;
|
||||
@ -39,6 +38,7 @@ import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -63,14 +63,14 @@ public class BlockInventoryHolder extends InventoryHolder {
|
||||
Set<String> validBlocksTemp = new HashSet<>(validBlocks.length + 1);
|
||||
Collections.addAll(validBlocksTemp, validBlocks);
|
||||
validBlocksTemp.add(BlockUtils.getCleanIdentifier(javaBlockIdentifier));
|
||||
this.validBlocks = ImmutableSet.copyOf(validBlocksTemp);
|
||||
this.validBlocks = Set.copyOf(validBlocksTemp);
|
||||
} else {
|
||||
this.validBlocks = Collections.singleton(BlockUtils.getCleanIdentifier(javaBlockIdentifier));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
|
||||
public boolean prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
|
||||
// Check to see if there is an existing block we can use that the player just selected.
|
||||
// First, verify that the player's position has not changed, so we don't try to select a block wildly out of range.
|
||||
// (This could be a virtual inventory that the player is opening)
|
||||
@ -83,13 +83,16 @@ public class BlockInventoryHolder extends InventoryHolder {
|
||||
inventory.setHolderPosition(session.getLastInteractionBlockPosition());
|
||||
((Container) inventory).setUsingRealBlock(true, javaBlockString[0]);
|
||||
setCustomName(session, session.getLastInteractionBlockPosition(), inventory, javaBlockId);
|
||||
return;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, time to conjure up a fake block!
|
||||
Vector3i position = session.getPlayerEntity().getPosition().toInt();
|
||||
position = position.add(Vector3i.UP);
|
||||
Vector3i position = InventoryUtils.findAvailableWorldSpace(session);
|
||||
if (position == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateBlockPacket blockPacket = new UpdateBlockPacket();
|
||||
blockPacket.setDataLayer(0);
|
||||
blockPacket.setBlockPosition(position);
|
||||
@ -99,6 +102,8 @@ public class BlockInventoryHolder extends InventoryHolder {
|
||||
inventory.setHolderPosition(position);
|
||||
|
||||
setCustomName(session, position, inventory, defaultJavaBlockState);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||
|
||||
public abstract class InventoryHolder {
|
||||
public abstract void prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory);
|
||||
public abstract boolean prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory);
|
||||
public abstract void openInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory);
|
||||
public abstract void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory);
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
package org.geysermc.geyser.item.components;
|
||||
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.item.components;
|
||||
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -32,43 +32,41 @@ import lombok.Getter;
|
||||
* It is used to construct the list for the settings menu
|
||||
*/
|
||||
public enum GameRule {
|
||||
ANNOUNCEADVANCEMENTS("announceAdvancements", Boolean.class, true), // JE only
|
||||
COMMANDBLOCKOUTPUT("commandBlockOutput", Boolean.class, true),
|
||||
DISABLEELYTRAMOVEMENTCHECK("disableElytraMovementCheck", Boolean.class, false), // JE only
|
||||
DISABLERAIDS("disableRaids", Boolean.class, false), // JE only
|
||||
DODAYLIGHTCYCLE("doDaylightCycle", Boolean.class, true),
|
||||
DOENTITYDROPS("doEntityDrops", Boolean.class, true),
|
||||
DOFIRETICK("doFireTick", Boolean.class, true),
|
||||
DOIMMEDIATERESPAWN("doImmediateRespawn", Boolean.class, false),
|
||||
DOINSOMNIA("doInsomnia", Boolean.class, true),
|
||||
DOLIMITEDCRAFTING("doLimitedCrafting", Boolean.class, false), // JE only
|
||||
DOMOBLOOT("doMobLoot", Boolean.class, true),
|
||||
DOMOBSPAWNING("doMobSpawning", Boolean.class, true),
|
||||
DOPATROLSPAWNING("doPatrolSpawning", Boolean.class, true), // JE only
|
||||
DOTILEDROPS("doTileDrops", Boolean.class, true),
|
||||
DOTRADERSPAWNING("doTraderSpawning", Boolean.class, true), // JE only
|
||||
DOWEATHERCYCLE("doWeatherCycle", Boolean.class, true),
|
||||
DROWNINGDAMAGE("drowningDamage", Boolean.class, true),
|
||||
FALLDAMAGE("fallDamage", Boolean.class, true),
|
||||
FIREDAMAGE("fireDamage", Boolean.class, true),
|
||||
FREEZEDAMAGE("freezeDamage", Boolean.class, true),
|
||||
FORGIVEDEADPLAYERS("forgiveDeadPlayers", Boolean.class, true), // JE only
|
||||
KEEPINVENTORY("keepInventory", Boolean.class, false),
|
||||
LOGADMINCOMMANDS("logAdminCommands", Boolean.class, true), // JE only
|
||||
MAXCOMMANDCHAINLENGTH("maxCommandChainLength", Integer.class, 65536),
|
||||
MAXENTITYCRAMMING("maxEntityCramming", Integer.class, 24), // JE only
|
||||
MOBGRIEFING("mobGriefing", Boolean.class, true),
|
||||
NATURALREGENERATION("naturalRegeneration", Boolean.class, true),
|
||||
PLAYERSSLEEPINGPERCENTAGE("playersSleepingPercentage", Integer.class, 100), // JE only
|
||||
RANDOMTICKSPEED("randomTickSpeed", Integer.class, 3),
|
||||
REDUCEDDEBUGINFO("reducedDebugInfo", Boolean.class, false), // JE only
|
||||
SENDCOMMANDFEEDBACK("sendCommandFeedback", Boolean.class, true),
|
||||
SHOWDEATHMESSAGES("showDeathMessages", Boolean.class, true),
|
||||
SPAWNRADIUS("spawnRadius", Integer.class, 10),
|
||||
SPECTATORSGENERATECHUNKS("spectatorsGenerateChunks", Boolean.class, true), // JE only
|
||||
UNIVERSALANGER("universalAnger", Boolean.class, false), // JE only
|
||||
|
||||
UNKNOWN("unknown", Object.class);
|
||||
ANNOUNCEADVANCEMENTS("announceAdvancements", true), // JE only
|
||||
COMMANDBLOCKOUTPUT("commandBlockOutput", true),
|
||||
DISABLEELYTRAMOVEMENTCHECK("disableElytraMovementCheck", false), // JE only
|
||||
DISABLERAIDS("disableRaids", false), // JE only
|
||||
DODAYLIGHTCYCLE("doDaylightCycle", true),
|
||||
DOENTITYDROPS("doEntityDrops", true),
|
||||
DOFIRETICK("doFireTick", true),
|
||||
DOIMMEDIATERESPAWN("doImmediateRespawn", false),
|
||||
DOINSOMNIA("doInsomnia", true),
|
||||
DOLIMITEDCRAFTING("doLimitedCrafting", false), // JE only
|
||||
DOMOBLOOT("doMobLoot", true),
|
||||
DOMOBSPAWNING("doMobSpawning", true),
|
||||
DOPATROLSPAWNING("doPatrolSpawning", true), // JE only
|
||||
DOTILEDROPS("doTileDrops", true),
|
||||
DOTRADERSPAWNING("doTraderSpawning", true), // JE only
|
||||
DOWEATHERCYCLE("doWeatherCycle", true),
|
||||
DROWNINGDAMAGE("drowningDamage", true),
|
||||
FALLDAMAGE("fallDamage", true),
|
||||
FIREDAMAGE("fireDamage", true),
|
||||
FREEZEDAMAGE("freezeDamage", true),
|
||||
FORGIVEDEADPLAYERS("forgiveDeadPlayers", true), // JE only
|
||||
KEEPINVENTORY("keepInventory", false),
|
||||
LOGADMINCOMMANDS("logAdminCommands", true), // JE only
|
||||
MAXCOMMANDCHAINLENGTH("maxCommandChainLength", 65536),
|
||||
MAXENTITYCRAMMING("maxEntityCramming", 24), // JE only
|
||||
MOBGRIEFING("mobGriefing", true),
|
||||
NATURALREGENERATION("naturalRegeneration", true),
|
||||
PLAYERSSLEEPINGPERCENTAGE("playersSleepingPercentage", 100), // JE only
|
||||
RANDOMTICKSPEED("randomTickSpeed", 3),
|
||||
REDUCEDDEBUGINFO("reducedDebugInfo", false), // JE only
|
||||
SENDCOMMANDFEEDBACK("sendCommandFeedback", true),
|
||||
SHOWDEATHMESSAGES("showDeathMessages", true),
|
||||
SPAWNRADIUS("spawnRadius", 10),
|
||||
SPECTATORSGENERATECHUNKS("spectatorsGenerateChunks", true), // JE only
|
||||
UNIVERSALANGER("universalAnger", false); // JE only
|
||||
|
||||
public static final GameRule[] VALUES = values();
|
||||
|
||||
@ -78,48 +76,25 @@ public enum GameRule {
|
||||
@Getter
|
||||
private final Class<?> type;
|
||||
|
||||
@Getter
|
||||
private final Object defaultValue;
|
||||
private final int defaultValue;
|
||||
|
||||
GameRule(String javaID, Class<?> type) {
|
||||
this(javaID, type, null);
|
||||
GameRule(String javaID, boolean defaultValue) {
|
||||
this.javaID = javaID;
|
||||
this.type = Boolean.class;
|
||||
this.defaultValue = defaultValue ? 1 : 0;
|
||||
}
|
||||
|
||||
GameRule(String javaID, Class<?> type, Object defaultValue) {
|
||||
GameRule(String javaID, int defaultValue) {
|
||||
this.javaID = javaID;
|
||||
this.type = type;
|
||||
this.type = Integer.class;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to an object of the correct type for the current gamerule
|
||||
*
|
||||
* @param value The string value to convert
|
||||
* @return The converted and formatted value
|
||||
*/
|
||||
public Object convertValue(String value) {
|
||||
if (type.equals(Boolean.class)) {
|
||||
return Boolean.parseBoolean(value);
|
||||
} else if (type.equals(Integer.class)) {
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
|
||||
return null;
|
||||
public boolean getDefaultBooleanValue() {
|
||||
return defaultValue != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a game rule by the given Java ID
|
||||
*
|
||||
* @param id The ID of the gamerule
|
||||
* @return A {@link GameRule} object representing the requested ID or {@link GameRule#UNKNOWN}
|
||||
*/
|
||||
public static GameRule fromJavaID(String id) {
|
||||
for (GameRule gamerule : VALUES) {
|
||||
if (gamerule.javaID.equals(id)) {
|
||||
return gamerule;
|
||||
}
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
public int getDefaultIntValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,8 @@
|
||||
|
||||
package org.geysermc.geyser.level;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
@ -36,11 +34,8 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.ChunkCache;
|
||||
import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class GeyserWorldManager extends WorldManager {
|
||||
|
||||
private static final Object2ObjectMap<String, String> gameruleCache = new Object2ObjectOpenHashMap<>();
|
||||
private final Object2ObjectMap<String, String> gameruleCache = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
@Override
|
||||
public int getBlockAt(GeyserSession session, int x, int y, int z) {
|
||||
@ -82,18 +77,18 @@ public class GeyserWorldManager extends WorldManager {
|
||||
|
||||
@Override
|
||||
public void setGameRule(GeyserSession session, String name, Object value) {
|
||||
session.sendCommand("gamerule " + name + " " + value);
|
||||
super.setGameRule(session, name, value);
|
||||
gameruleCache.put(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getGameRuleBool(GeyserSession session, GameRule gameRule) {
|
||||
public boolean getGameRuleBool(GeyserSession session, GameRule gameRule) {
|
||||
String value = gameruleCache.get(gameRule.getJavaID());
|
||||
if (value != null) {
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
return gameRule.getDefaultValue() != null ? (Boolean) gameRule.getDefaultValue() : false;
|
||||
return gameRule.getDefaultBooleanValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -103,17 +98,7 @@ public class GeyserWorldManager extends WorldManager {
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
|
||||
return gameRule.getDefaultValue() != null ? (int) gameRule.getDefaultValue() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerGameMode(GeyserSession session, GameMode gameMode) {
|
||||
session.sendCommand("gamemode " + gameMode.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDifficulty(GeyserSession session, Difficulty difficulty) {
|
||||
session.sendCommand("difficulty " + difficulty.name().toLowerCase(Locale.ROOT));
|
||||
return gameRule.getDefaultIntValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,9 +28,12 @@ package org.geysermc.geyser.level;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Class that manages or retrieves various information
|
||||
* from the world. Everything in this class should be
|
||||
@ -105,7 +108,9 @@ public abstract class WorldManager {
|
||||
* @param name The gamerule to change
|
||||
* @param value The new value for the gamerule
|
||||
*/
|
||||
public abstract void setGameRule(GeyserSession session, String name, Object value);
|
||||
public void setGameRule(GeyserSession session, String name, Object value) {
|
||||
session.sendCommand("gamerule " + name + " " + value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a gamerule value as a boolean
|
||||
@ -114,7 +119,7 @@ public abstract class WorldManager {
|
||||
* @param gameRule The gamerule to fetch the value of
|
||||
* @return The boolean representation of the value
|
||||
*/
|
||||
public abstract Boolean getGameRuleBool(GeyserSession session, GameRule gameRule);
|
||||
public abstract boolean getGameRuleBool(GeyserSession session, GameRule gameRule);
|
||||
|
||||
/**
|
||||
* Get a gamerule value as an integer
|
||||
@ -131,7 +136,9 @@ public abstract class WorldManager {
|
||||
* @param session The session of the player to change the game mode of
|
||||
* @param gameMode The game mode to change the player to
|
||||
*/
|
||||
public abstract void setPlayerGameMode(GeyserSession session, GameMode gameMode);
|
||||
public void setPlayerGameMode(GeyserSession session, GameMode gameMode) {
|
||||
session.sendCommand("gamemode " + gameMode.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the difficulty of the Java server
|
||||
@ -139,7 +146,9 @@ public abstract class WorldManager {
|
||||
* @param session The session of the user that requested the change
|
||||
* @param difficulty The difficulty to change to
|
||||
*/
|
||||
public abstract void setDifficulty(GeyserSession session, Difficulty difficulty);
|
||||
public void setDifficulty(GeyserSession session, Difficulty difficulty) {
|
||||
session.sendCommand("difficulty " + difficulty.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given session's player has a permission
|
||||
@ -149,4 +158,12 @@ public abstract class WorldManager {
|
||||
* @return True if the player has the requested permission, false if not
|
||||
*/
|
||||
public abstract boolean hasPermission(GeyserSession session, String permission);
|
||||
|
||||
/**
|
||||
* Returns a list of biome identifiers available on the server.
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getBiomeIdentifiers(boolean withTags) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,11 @@ package org.geysermc.geyser.network;
|
||||
import com.github.steveice10.mc.protocol.codec.MinecraftCodec;
|
||||
import com.github.steveice10.mc.protocol.codec.PacketCodec;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v527.Bedrock_v527;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v534.Bedrock_v534;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v545.Bedrock_v545;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v554.Bedrock_v554;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v557.Bedrock_v557;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v560.Bedrock_v560;
|
||||
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
@ -49,7 +48,7 @@ public final class GameProtocol {
|
||||
* Default Bedrock codec that should act as a fallback. Should represent the latest available
|
||||
* release of the game that Geyser supports.
|
||||
*/
|
||||
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v557.CODEC;
|
||||
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v560.CODEC;
|
||||
/**
|
||||
* A list of all supported Bedrock versions that can join Geyser
|
||||
*/
|
||||
@ -62,12 +61,6 @@ public final class GameProtocol {
|
||||
private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC;
|
||||
|
||||
static {
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v527.CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.0/1.19.2")
|
||||
.build());
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v534.CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.10/1.19.11")
|
||||
.build());
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v544.CODEC);
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v545.CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.21/1.19.22")
|
||||
@ -75,7 +68,12 @@ public final class GameProtocol {
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v554.CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.30/1.19.31")
|
||||
.build());
|
||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v557.CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.40/1.19.41")
|
||||
.build());
|
||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.50/1.19.51")
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,11 +92,11 @@ public final class GameProtocol {
|
||||
|
||||
/* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */
|
||||
|
||||
public static boolean supports1_19_10(GeyserSession session) {
|
||||
return session.getUpstream().getProtocolVersion() >= Bedrock_v534.CODEC.getProtocolVersion();
|
||||
public static boolean supports1_19_30(GeyserSession session) {
|
||||
return session.getUpstream().getProtocolVersion() >= Bedrock_v554.CODEC.getProtocolVersion();
|
||||
}
|
||||
|
||||
public static boolean supports1_19_30(GeyserSession session) {
|
||||
public static boolean supports1_19_50(GeyserSession session) {
|
||||
return session.getUpstream().getProtocolVersion() >= Bedrock_v554.CODEC.getProtocolVersion();
|
||||
}
|
||||
|
||||
@ -117,7 +115,7 @@ public final class GameProtocol {
|
||||
* @return the supported Minecraft: Java Edition version names
|
||||
*/
|
||||
public static List<String> getJavaVersions() {
|
||||
return List.of(DEFAULT_JAVA_CODEC.getMinecraftVersion(), "1.19.2");
|
||||
return List.of(DEFAULT_JAVA_CODEC.getMinecraftVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,9 +61,13 @@ import org.geysermc.geyser.util.MathUtils;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
|
||||
private Deque<String> packsToSent = new ArrayDeque<>();
|
||||
|
||||
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
|
||||
super(geyser, session);
|
||||
}
|
||||
@ -186,24 +190,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
break;
|
||||
|
||||
case SEND_PACKS:
|
||||
for(String id : packet.getPackIds()) {
|
||||
ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket();
|
||||
String[] packID = id.split("_");
|
||||
ResourcePack pack = ResourcePack.PACKS.get(packID[0]);
|
||||
ResourcePackManifest.Header header = pack.getManifest().getHeader();
|
||||
|
||||
data.setPackId(header.getUuid());
|
||||
int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE);
|
||||
data.setChunkCount(chunkCount);
|
||||
data.setCompressedPackSize(pack.getFile().length());
|
||||
data.setMaxChunkSize(ResourcePack.CHUNK_SIZE);
|
||||
data.setHash(pack.getSha256());
|
||||
data.setPackVersion(packID[1]);
|
||||
data.setPremium(false);
|
||||
data.setType(ResourcePackType.RESOURCES);
|
||||
|
||||
session.sendUpstreamPacket(data);
|
||||
}
|
||||
packsToSent.addAll(packet.getPackIds());
|
||||
sendPackDataInfo(packsToSent.pop());
|
||||
break;
|
||||
|
||||
case HAVE_ALL_PACKS:
|
||||
@ -296,7 +284,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
data.setPackId(packet.getPackId());
|
||||
|
||||
int offset = packet.getChunkIndex() * ResourcePack.CHUNK_SIZE;
|
||||
byte[] packData = new byte[(int) MathUtils.constrain(pack.getFile().length() - offset, 0, ResourcePack.CHUNK_SIZE)];
|
||||
long remainingSize = pack.getFile().length() - offset;
|
||||
byte[] packData = new byte[(int) MathUtils.constrain(remainingSize, 0, ResourcePack.CHUNK_SIZE)];
|
||||
|
||||
try (InputStream inputStream = new FileInputStream(pack.getFile())) {
|
||||
inputStream.skip(offset);
|
||||
@ -308,6 +297,31 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
data.setData(Unpooled.wrappedBuffer(packData));
|
||||
|
||||
session.sendUpstreamPacket(data);
|
||||
|
||||
// Check if it is the last chunk and send next pack in queue when available.
|
||||
if (remainingSize <= ResourcePack.CHUNK_SIZE && !packsToSent.isEmpty()) {
|
||||
sendPackDataInfo(packsToSent.pop());
|
||||
}
|
||||
|
||||
return PacketSignal.HANDLED;
|
||||
}
|
||||
|
||||
private void sendPackDataInfo(String id) {
|
||||
ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket();
|
||||
String[] packID = id.split("_");
|
||||
ResourcePack pack = ResourcePack.PACKS.get(packID[0]);
|
||||
ResourcePackManifest.Header header = pack.getManifest().getHeader();
|
||||
|
||||
data.setPackId(header.getUuid());
|
||||
int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE);
|
||||
data.setChunkCount(chunkCount);
|
||||
data.setCompressedPackSize(pack.getFile().length());
|
||||
data.setMaxChunkSize(ResourcePack.CHUNK_SIZE);
|
||||
data.setHash(pack.getSha256());
|
||||
data.setPackVersion(packID[1]);
|
||||
data.setPremium(false);
|
||||
data.setType(ResourcePackType.RESOURCES);
|
||||
|
||||
session.sendUpstreamPacket(data);
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +41,6 @@ import io.netty.channel.socket.DatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import org.cloudburstmc.netty.channel.raknet.RakChannelFactory;
|
||||
import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption;
|
||||
import org.cloudburstmc.netty.handler.codec.raknet.common.UnconnectedPingEncoder;
|
||||
import org.cloudburstmc.netty.handler.codec.raknet.common.UnconnectedPongDecoder;
|
||||
import org.cloudburstmc.netty.handler.codec.raknet.common.UnconnectedPongEncoder;
|
||||
import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerOfflineHandler;
|
||||
import org.cloudburstmc.protocol.bedrock.BedrockPong;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
@ -57,7 +54,6 @@ import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class GeyserServer {
|
||||
@ -158,13 +154,9 @@ public final class GeyserServer {
|
||||
pong.subMotd(config.getBedrock().secondaryMotd());
|
||||
}
|
||||
|
||||
if (config.isPassthroughPlayerCounts() && pingInfo != null) {
|
||||
pong.playerCount(pingInfo.getPlayers().getOnline());
|
||||
pong.maximumPlayerCount(pingInfo.getPlayers().getMax());
|
||||
} else {
|
||||
pong.playerCount(geyser.getSessionManager().getSessions().size());
|
||||
pong.maximumPlayerCount(config.getMaxPlayers());
|
||||
}
|
||||
// https://github.com/GeyserMC/Geyser/issues/3388
|
||||
pong.motd(pong.motd().replace(';', ':'));
|
||||
pong.subMotd(pong.subMotd().replace(';', ':'));
|
||||
|
||||
// Fallbacks to prevent errors and allow Bedrock to see the server
|
||||
if (pong.motd() == null || pong.motd().isBlank()) {
|
||||
@ -193,6 +185,14 @@ public final class GeyserServer {
|
||||
}
|
||||
}
|
||||
|
||||
if (config.isPassthroughPlayerCounts() && pingInfo != null) {
|
||||
pong.playerCount(pingInfo.getPlayers().getOnline());
|
||||
pong.maximumPlayerCount(pingInfo.getPlayers().getMax());
|
||||
} else {
|
||||
pong.playerCount(geyser.getSessionManager().getSessions().size());
|
||||
pong.maximumPlayerCount(config.getMaxPlayers());
|
||||
}
|
||||
|
||||
//Bedrock will not even attempt a connection if the client thinks the server is full
|
||||
//so we have to fake it not being full
|
||||
if (pong.playerCount() >= pong.maximumPlayerCount()) {
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.ping;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.nukkitx.nbt.util.VarInts;
|
||||
import org.cloudburstmc.nbt.util.VarInts;
|
||||
import io.netty.handler.codec.haproxy.HAProxyCommand;
|
||||
import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol;
|
||||
import io.netty.util.NetUtil;
|
||||
|
@ -31,15 +31,15 @@ import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType;
|
||||
import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
|
||||
import com.github.steveice10.packetlib.packet.Packet;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.CraftingData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.PotionMixData;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.CraftingData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment;
|
||||
@ -181,12 +181,15 @@ public final class Registries {
|
||||
POTION_MIXES = SimpleRegistry.create(PotionMixRegistryLoader::new);
|
||||
ENCHANTMENTS = SimpleMappedRegistry.create("mappings/enchantments.json", EnchantmentRegistryLoader::new);
|
||||
|
||||
// TEMPORARY FIX TO MAKE OLD BIOMES NBT WORK WITH 1.19.30
|
||||
// Remove unneeded client generation data from NbtMapBuilder
|
||||
NbtMapBuilder biomesNbt = NbtMap.builder();
|
||||
for (Map.Entry<String, Object> entry : BIOMES_NBT.get().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
NbtMapBuilder value = ((NbtMap) entry.getValue()).toBuilder();
|
||||
value.put("name_hash", key);
|
||||
value.remove("minecraft:consolidated_features");
|
||||
value.remove("minecraft:multinoise_generation_rules");
|
||||
value.remove("minecraft:surface_material_adjustments");
|
||||
value.remove( "minecraft:surface_parameters");
|
||||
biomesNbt.put(key, value.build());
|
||||
}
|
||||
BIOMES_NBT.set(biomesNbt.build());
|
||||
|
@ -25,9 +25,9 @@
|
||||
|
||||
package org.geysermc.geyser.registry.loader;
|
||||
|
||||
import com.nukkitx.nbt.NBTInputStream;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtUtils;
|
||||
import org.cloudburstmc.nbt.NBTInputStream;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtUtils;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.registry.loader;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.PotionMixData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.geysermc.geyser.inventory.item.Potion;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
|
@ -28,24 +28,16 @@ package org.geysermc.geyser.registry.populator;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.nukkitx.nbt.NBTInputStream;
|
||||
import com.nukkitx.nbt.NbtList;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectIntPair;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v527.Bedrock_v527;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import org.cloudburstmc.nbt.*;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v560.Bedrock_v560;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleBlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleDefinitionRegistry;
|
||||
import org.cloudburstmc.protocol.common.DefinitionRegistry;
|
||||
import org.cloudburstmc.protocol.common.SimpleDefinitionRegistry;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.physics.PistonBehavior;
|
||||
@ -56,12 +48,7 @@ import org.geysermc.geyser.util.BlockUtils;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
@ -84,13 +71,9 @@ public final class BlockRegistryPopulator {
|
||||
private static void registerBedrockBlocks() {
|
||||
BiFunction<String, NbtMapBuilder, String> emptyMapper = (bedrockIdentifier, statesBuilder) -> null;
|
||||
ImmutableMap<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> blockMappers = ImmutableMap.<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>>builder()
|
||||
.put(ObjectIntPair.of("1_19_0", Bedrock_v527.CODEC.getProtocolVersion()), (bedrockIdentifier, statesBuilder) -> {
|
||||
if (bedrockIdentifier.equals("minecraft:muddy_mangrove_roots")) {
|
||||
statesBuilder.remove("pillar_axis");
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.put(ObjectIntPair.of("1_19_20", Bedrock_v544.CODEC.getProtocolVersion()), emptyMapper).build();
|
||||
.put(ObjectIntPair.of("1_19_20", Bedrock_v544.CODEC.getProtocolVersion()), emptyMapper)
|
||||
.put(ObjectIntPair.of("1_19_50", Bedrock_v560.CODEC.getProtocolVersion()), emptyMapper)
|
||||
.build();
|
||||
|
||||
for (Map.Entry<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> palette : blockMappers.entrySet()) {
|
||||
NbtList<NbtMap> blocksTag;
|
||||
@ -129,7 +112,7 @@ public final class BlockRegistryPopulator {
|
||||
BiFunction<String, NbtMapBuilder, String> stateMapper = blockMappers.getOrDefault(palette.getKey(), emptyMapper);
|
||||
|
||||
BlockDefinition[] javaToBedrockBlocks = new BlockDefinition[BLOCKS_JSON.size()];
|
||||
DefinitionRegistry.Builder<BlockDefinition> registry = SimpleDefinitionRegistry.builder();
|
||||
SimpleDefinitionRegistry.Builder<BlockDefinition> registry = SimpleDefinitionRegistry.builder();
|
||||
|
||||
Map<String, NbtMap> flowerPotBlocks = new Object2ObjectOpenHashMap<>();
|
||||
Map<NbtMap, BlockDefinition> itemFrames = new Object2ObjectOpenHashMap<>();
|
||||
|
@ -26,8 +26,8 @@
|
||||
package org.geysermc.geyser.registry.populator;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtUtils;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtUtils;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
|
@ -26,9 +26,9 @@
|
||||
package org.geysermc.geyser.registry.populator;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
|
||||
@ -174,6 +174,33 @@ public class CustomItemRegistryPopulator {
|
||||
computeArmorProperties(mapping.getArmorType(), mapping.getProtectionValue(), componentBuilder);
|
||||
}
|
||||
|
||||
if (mapping.getFirstBlockRuntimeId() != null) {
|
||||
computeBlockItemProperties(mapping.getBedrockIdentifier(), componentBuilder);
|
||||
}
|
||||
|
||||
if (mapping.isEdible()) {
|
||||
computeConsumableProperties(itemProperties, componentBuilder, 1, false);
|
||||
}
|
||||
|
||||
if (mapping.isEntityPlacer()) {
|
||||
computeEntityPlacerProperties(componentBuilder);
|
||||
}
|
||||
|
||||
switch (mapping.getBedrockIdentifier()) {
|
||||
case "minecraft:fire_charge", "minecraft:flint_and_steel" -> {
|
||||
computeBlockItemProperties("minecraft:fire", componentBuilder);
|
||||
}
|
||||
case "minecraft:bow", "minecraft:crossbow", "minecraft:trident" -> {
|
||||
computeChargeableProperties(itemProperties, componentBuilder);
|
||||
}
|
||||
case "minecraft:honey_bottle", "minecraft:milk_bucket", "minecraft:potion" -> {
|
||||
computeConsumableProperties(itemProperties, componentBuilder, 2, true);
|
||||
}
|
||||
case "minecraft:experience_bottle", "minecraft:egg", "minecraft:ender_pearl", "minecraft:ender_eye", "minecraft:lingering_potion", "minecraft:snowball", "minecraft:splash_potion" -> {
|
||||
computeThrowableProperties(componentBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
computeRenderOffsets(false, customItemData, componentBuilder);
|
||||
|
||||
componentBuilder.putCompound("item_properties", itemProperties.build());
|
||||
@ -310,6 +337,48 @@ public class CustomItemRegistryPopulator {
|
||||
}
|
||||
}
|
||||
|
||||
private static void computeBlockItemProperties(String blockItem, NbtMapBuilder componentBuilder) {
|
||||
// carved pumpkin should be able to be worn and for that we would need to add wearable and armor with protection 0 here
|
||||
// however this would have the side effect of preventing carved pumpkins from working as an attachable on the RP side outside the head slot
|
||||
// it also causes the item to glitch when right clicked to "equip" so this should only be added here later if these issues can be overcome
|
||||
|
||||
// all block items registered should be given this component to prevent double placement
|
||||
componentBuilder.putCompound("minecraft:block_placer", NbtMap.builder().putString("block", blockItem).build());
|
||||
}
|
||||
|
||||
private static void computeChargeableProperties(NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) {
|
||||
// setting high use_duration prevents the consume animation from playing
|
||||
itemProperties.putInt("use_duration", Integer.MAX_VALUE);
|
||||
// display item as tool (mainly for crossbow and bow)
|
||||
itemProperties.putBoolean("hand_equipped", true);
|
||||
// ensure client moves at slow speed while charging (note: this was calculated by hand as the movement modifer value does not seem to scale linearly)
|
||||
componentBuilder.putCompound("minecraft:chargeable", NbtMap.builder().putFloat("movement_modifier", 0.35F).build());
|
||||
}
|
||||
|
||||
private static void computeConsumableProperties(NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, int useAnimation, boolean canAlwaysEat) {
|
||||
// this is the duration of the use animation in ticks; note that in behavior packs this is set as a float in seconds, but over the network it is an int in ticks
|
||||
itemProperties.putInt("use_duration", 32);
|
||||
// this dictates that the item will use the eat or drink animation (in the first person) and play eat or drink sounds
|
||||
// note that in behavior packs this is set as the string "eat" or "drink", but over the network it as an int, with these values being 1 and 2 respectively
|
||||
itemProperties.putInt("use_animation", useAnimation);
|
||||
// this component is required to allow the eat animation to play
|
||||
componentBuilder.putCompound("minecraft:food", NbtMap.builder().putBoolean("can_always_eat", canAlwaysEat).build());
|
||||
}
|
||||
|
||||
private static void computeEntityPlacerProperties(NbtMapBuilder componentBuilder) {
|
||||
// all items registered that place entities should be given this component to prevent double placement
|
||||
// it is okay that the entity here does not match the actual one since we control what entity actually spawns
|
||||
componentBuilder.putCompound("minecraft:entity_placer", NbtMap.builder().putString("entity", "minecraft:minecart").build());
|
||||
}
|
||||
|
||||
private static void computeThrowableProperties(NbtMapBuilder componentBuilder) {
|
||||
// allows item to be thrown when holding down right click (individual presses are required w/o this component)
|
||||
componentBuilder.putCompound("minecraft:throwable", NbtMap.builder().putBoolean("do_swing_animation", true).build());
|
||||
// this must be set to something for the swing animation to play
|
||||
// it is okay that the projectile here does not match the actual one since we control what entity actually spawns
|
||||
componentBuilder.putCompound("minecraft:projectile", NbtMap.builder().putString("projectile_entity", "minecraft:snowball").build());
|
||||
}
|
||||
|
||||
private static void computeRenderOffsets(boolean isHat, CustomItemData customItemData, NbtMapBuilder componentBuilder) {
|
||||
if (isHat) {
|
||||
componentBuilder.remove("minecraft:render_offsets");
|
||||
|
@ -28,30 +28,19 @@ package org.geysermc.geyser.registry.populator;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v527.Bedrock_v527;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v534.Bedrock_v534;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v560.Bedrock_v560;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleDefinitionRegistry;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.common.DefinitionRegistry;
|
||||
import org.cloudburstmc.protocol.common.SimpleDefinitionRegistry;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemData;
|
||||
@ -61,23 +50,12 @@ import org.geysermc.geyser.inventory.item.StoredItemMappings;
|
||||
import org.geysermc.geyser.item.GeyserCustomMappingData;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||
import org.geysermc.geyser.registry.type.GeyserMappingItem;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.NonVanillaItemRegistration;
|
||||
import org.geysermc.geyser.registry.type.PaletteItem;
|
||||
import org.geysermc.geyser.registry.type.*;
|
||||
import org.geysermc.geyser.util.ItemUtils;
|
||||
import org.geysermc.geyser.util.collection.FixedInt2IntMap;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@ -90,10 +68,8 @@ public class ItemRegistryPopulator {
|
||||
|
||||
public static void populate() {
|
||||
Map<String, PaletteVersion> paletteVersions = new Object2ObjectOpenHashMap<>();
|
||||
paletteVersions.put("1_19_0", new PaletteVersion(Bedrock_v527.CODEC.getProtocolVersion(),
|
||||
Collections.singletonMap("minecraft:trader_llama_spawn_egg", "minecraft:llama_spawn_egg")));
|
||||
paletteVersions.put("1_19_10", new PaletteVersion(Bedrock_v534.CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
paletteVersions.put("1_19_20", new PaletteVersion(Bedrock_v544.CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
paletteVersions.put("1_19_50", new PaletteVersion(Bedrock_v560.CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
|
||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||
|
||||
@ -147,7 +123,7 @@ public class ItemRegistryPopulator {
|
||||
int nextFreeBedrockId = 0;
|
||||
List<ComponentItemData> componentItemData = new ObjectArrayList<>();
|
||||
|
||||
DefinitionRegistry.Builder<ItemDefinition> registry = SimpleDefinitionRegistry.builder();
|
||||
SimpleDefinitionRegistry.Builder<ItemDefinition> registry = SimpleDefinitionRegistry.builder();
|
||||
Map<String, ItemDefinition> definitions = new Object2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
for (PaletteItem entry : itemEntries) {
|
||||
|
@ -29,13 +29,13 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
|
||||
import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtUtils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.CraftingData;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtUtils;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.CraftingData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||
@ -50,15 +50,7 @@ import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
import static org.geysermc.geyser.util.InventoryUtils.LAST_RECIPE_NET_ID;
|
||||
|
||||
@ -90,8 +82,6 @@ public class RecipeRegistryPopulator {
|
||||
Collections.singletonList(CraftingData.fromMulti(UUID.fromString("d392b075-4ba1-40ae-8789-af868d56f6ce"), ++LAST_RECIPE_NET_ID)));
|
||||
craftingData.put(RecipeType.CRAFTING_SPECIAL_MAPCLONING,
|
||||
Collections.singletonList(CraftingData.fromMulti(UUID.fromString("85939755-ba10-4d9d-a4cc-efb7a8e943c4"), ++LAST_RECIPE_NET_ID)));
|
||||
craftingData.put(RecipeType.CRAFTING_SPECIAL_BANNERADDPATTERN,
|
||||
Collections.singletonList(CraftingData.fromMulti(UUID.fromString("b5c5d105-75a2-4076-af2b-923ea2bf4bf0"), ++LAST_RECIPE_NET_ID)));
|
||||
|
||||
// https://github.com/pmmp/PocketMine-MP/blob/stable/src/pocketmine/inventory/MultiRecipe.php
|
||||
|
||||
|
@ -25,14 +25,11 @@
|
||||
|
||||
package org.geysermc.geyser.registry.type;
|
||||
|
||||
import com.nukkitx.nbt.NbtList;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.common.DefinitionRegistry;
|
||||
|
||||
import java.util.Map;
|
||||
@ -78,6 +75,6 @@ public class BlockMappings {
|
||||
}
|
||||
|
||||
public boolean isItemFrame(BlockDefinition definition) {
|
||||
return this.itemFrames.containsKey(definition.getState());
|
||||
return this.itemFrames.containsKey(definition.getRuntimeId());
|
||||
}
|
||||
}
|
@ -48,4 +48,6 @@ public class GeyserMappingItem {
|
||||
@JsonProperty("repair_materials") List<String> repairMaterials;
|
||||
@JsonProperty("has_suspicious_stew_effect") boolean hasSuspiciousStewEffect = false;
|
||||
@JsonProperty("dye_color") int dyeColor = -1;
|
||||
@JsonProperty("is_edible") boolean edible = false;
|
||||
@JsonProperty("is_entity_placer") boolean entityPlacer = false;
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package org.geysermc.geyser.session;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsException;
|
||||
import com.github.steveice10.mc.auth.exception.request.RequestException;
|
||||
@ -58,19 +57,13 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.Server
|
||||
import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket;
|
||||
import com.github.steveice10.packetlib.BuiltinFlags;
|
||||
import com.github.steveice10.packetlib.Session;
|
||||
import com.github.steveice10.packetlib.event.session.ConnectedEvent;
|
||||
import com.github.steveice10.packetlib.event.session.DisconnectedEvent;
|
||||
import com.github.steveice10.packetlib.event.session.PacketErrorEvent;
|
||||
import com.github.steveice10.packetlib.event.session.PacketSendingEvent;
|
||||
import com.github.steveice10.packetlib.event.session.SessionAdapter;
|
||||
import com.github.steveice10.packetlib.event.session.*;
|
||||
import com.github.steveice10.packetlib.packet.Packet;
|
||||
import com.github.steveice10.packetlib.tcp.TcpClientSession;
|
||||
import com.github.steveice10.packetlib.tcp.TcpSession;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrays;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
@ -89,23 +82,10 @@ import lombok.experimental.Accessors;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.common.value.qual.IntRange;
|
||||
import org.cloudburstmc.math.GenericMath;
|
||||
import org.cloudburstmc.math.vector.Vector2f;
|
||||
import org.cloudburstmc.math.vector.Vector2i;
|
||||
import org.cloudburstmc.math.vector.Vector3d;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.math.vector.*;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
|
||||
import org.cloudburstmc.protocol.bedrock.data.Ability;
|
||||
import org.cloudburstmc.protocol.bedrock.data.AbilityLayer;
|
||||
import org.cloudburstmc.protocol.bedrock.data.AdventureSetting;
|
||||
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.AuthoritativeMovementMode;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ChatRestrictionLevel;
|
||||
import org.cloudburstmc.protocol.bedrock.data.GamePublishSetting;
|
||||
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.GameType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.PlayerPermission;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.*;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||
@ -137,7 +117,6 @@ import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
|
||||
import org.geysermc.geyser.level.JavaDimension;
|
||||
import org.geysermc.geyser.level.WorldManager;
|
||||
import org.geysermc.geyser.level.physics.CollisionManager;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.network.netty.LocalSession;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||
@ -145,20 +124,7 @@ import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.session.auth.AuthData;
|
||||
import org.geysermc.geyser.session.auth.BedrockClientData;
|
||||
import org.geysermc.geyser.session.cache.AdvancementsCache;
|
||||
import org.geysermc.geyser.session.cache.BookEditCache;
|
||||
import org.geysermc.geyser.session.cache.ChunkCache;
|
||||
import org.geysermc.geyser.session.cache.EntityCache;
|
||||
import org.geysermc.geyser.session.cache.EntityEffectCache;
|
||||
import org.geysermc.geyser.session.cache.FormCache;
|
||||
import org.geysermc.geyser.session.cache.LodestoneCache;
|
||||
import org.geysermc.geyser.session.cache.PistonCache;
|
||||
import org.geysermc.geyser.session.cache.PreferencesCache;
|
||||
import org.geysermc.geyser.session.cache.SkullCache;
|
||||
import org.geysermc.geyser.session.cache.TagCache;
|
||||
import org.geysermc.geyser.session.cache.TeleportCache;
|
||||
import org.geysermc.geyser.session.cache.WorldBorder;
|
||||
import org.geysermc.geyser.session.cache.WorldCache;
|
||||
import org.geysermc.geyser.session.cache.*;
|
||||
import org.geysermc.geyser.skin.FloodgateSkinUploader;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
@ -174,14 +140,7 @@ import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -336,6 +295,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
*/
|
||||
@Setter
|
||||
private String worldName = null;
|
||||
/**
|
||||
* As of Java 1.19.3, the client only uses these for commands.
|
||||
*/
|
||||
@Setter
|
||||
private String[] levels;
|
||||
|
||||
private boolean sneaking;
|
||||
|
||||
@ -656,6 +620,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
creativePacket.setContents(this.itemMappings.getCreativeItems());
|
||||
upstream.sendPacket(creativePacket);
|
||||
|
||||
// Potion mixes are registered by default, as they are needed to be able to put ingredients into the brewing stand.
|
||||
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
|
||||
craftingDataPacket.setCleanRecipes(true);
|
||||
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.get());
|
||||
upstream.sendPacket(craftingDataPacket);
|
||||
|
||||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
||||
upstream.sendPacket(playStatusPacket);
|
||||
@ -1389,14 +1359,14 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
* Sends a chat message to the Java server.
|
||||
*/
|
||||
public void sendChat(String message) {
|
||||
sendDownstreamPacket(new ServerboundChatPacket(message, Instant.now().toEpochMilli(), 0L, ByteArrays.EMPTY_ARRAY, false, Collections.emptyList(), null));
|
||||
sendDownstreamPacket(new ServerboundChatPacket(message, Instant.now().toEpochMilli(), 0L, null, 0, new BitSet()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command to the Java server.
|
||||
*/
|
||||
public void sendCommand(String command) {
|
||||
sendDownstreamPacket(new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyList(), false, Collections.emptyList(), null));
|
||||
sendDownstreamPacket(new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyList(), 0, new BitSet()));
|
||||
}
|
||||
|
||||
public void setServerRenderDistance(int renderDistance) {
|
||||
@ -1454,7 +1424,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
startGamePacket.setRotation(Vector2f.from(1, 1));
|
||||
|
||||
startGamePacket.setSeed(-1L);
|
||||
startGamePacket.setDimensionId(DimensionUtils.javaToBedrock(dimension));
|
||||
startGamePacket.setDimensionId(DimensionUtils.javaToBedrock(chunkCache.getBedrockDimension()));
|
||||
startGamePacket.setGeneratorId(1);
|
||||
startGamePacket.setLevelGameType(GameType.SURVIVAL);
|
||||
startGamePacket.setDifficulty(1);
|
||||
@ -1655,76 +1625,40 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
boolean spectator = gameMode == GameMode.SPECTATOR;
|
||||
boolean worldImmutable = gameMode == GameMode.ADVENTURE || spectator;
|
||||
|
||||
if (GameProtocol.supports1_19_10(this)) {
|
||||
UpdateAdventureSettingsPacket adventureSettingsPacket = new UpdateAdventureSettingsPacket();
|
||||
adventureSettingsPacket.setNoMvP(false);
|
||||
adventureSettingsPacket.setNoPvM(false);
|
||||
adventureSettingsPacket.setImmutableWorld(worldImmutable);
|
||||
adventureSettingsPacket.setShowNameTags(false);
|
||||
adventureSettingsPacket.setAutoJump(true);
|
||||
sendUpstreamPacket(adventureSettingsPacket);
|
||||
UpdateAdventureSettingsPacket adventureSettingsPacket = new UpdateAdventureSettingsPacket();
|
||||
adventureSettingsPacket.setNoMvP(false);
|
||||
adventureSettingsPacket.setNoPvM(false);
|
||||
adventureSettingsPacket.setImmutableWorld(worldImmutable);
|
||||
adventureSettingsPacket.setShowNameTags(false);
|
||||
adventureSettingsPacket.setAutoJump(true);
|
||||
sendUpstreamPacket(adventureSettingsPacket);
|
||||
|
||||
UpdateAbilitiesPacket updateAbilitiesPacket = new UpdateAbilitiesPacket();
|
||||
updateAbilitiesPacket.setUniqueEntityId(bedrockId);
|
||||
updateAbilitiesPacket.setCommandPermission(commandPermission);
|
||||
updateAbilitiesPacket.setPlayerPermission(playerPermission);
|
||||
UpdateAbilitiesPacket updateAbilitiesPacket = new UpdateAbilitiesPacket();
|
||||
updateAbilitiesPacket.setUniqueEntityId(bedrockId);
|
||||
updateAbilitiesPacket.setCommandPermission(commandPermission);
|
||||
updateAbilitiesPacket.setPlayerPermission(playerPermission);
|
||||
|
||||
AbilityLayer abilityLayer = new AbilityLayer();
|
||||
Set<Ability> abilities = abilityLayer.getAbilityValues();
|
||||
if (canFly || spectator) {
|
||||
abilities.add(Ability.MAY_FLY);
|
||||
}
|
||||
|
||||
// Default stuff we have to fill in
|
||||
abilities.add(Ability.BUILD);
|
||||
abilities.add(Ability.MINE);
|
||||
// Needed so you can drop items
|
||||
abilities.add(Ability.DOORS_AND_SWITCHES);
|
||||
if (gameMode == GameMode.CREATIVE) {
|
||||
// Needed so the client doesn't attempt to take away items
|
||||
abilities.add(Ability.INSTABUILD);
|
||||
}
|
||||
|
||||
if (commandPermission == CommandPermission.GAME_DIRECTORS) {
|
||||
// Fixes a bug? since 1.19.11 where the player can change their gamemode in Bedrock settings and
|
||||
// a packet is not sent to the server.
|
||||
// https://github.com/GeyserMC/Geyser/issues/3191
|
||||
abilities.add(Ability.OPERATOR_COMMANDS);
|
||||
}
|
||||
|
||||
if (flying || spectator) {
|
||||
if (spectator && !flying) {
|
||||
// We're "flying locked" in this gamemode
|
||||
flying = true;
|
||||
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(true);
|
||||
sendDownstreamPacket(abilitiesPacket);
|
||||
}
|
||||
abilities.add(Ability.FLYING);
|
||||
}
|
||||
|
||||
if (spectator) {
|
||||
abilities.add(Ability.NO_CLIP);
|
||||
}
|
||||
|
||||
abilityLayer.setLayerType(AbilityLayer.Type.BASE);
|
||||
abilityLayer.setFlySpeed(flySpeed);
|
||||
// https://github.com/GeyserMC/Geyser/issues/3139 as of 1.19.10
|
||||
abilityLayer.setWalkSpeed(walkSpeed == 0f ? 0.01f : walkSpeed);
|
||||
Collections.addAll(abilityLayer.getAbilitiesSet(), USED_ABILITIES);
|
||||
|
||||
updateAbilitiesPacket.getAbilityLayers().add(abilityLayer);
|
||||
sendUpstreamPacket(updateAbilitiesPacket);
|
||||
return;
|
||||
AbilityLayer abilityLayer = new AbilityLayer();
|
||||
Set<Ability> abilities = abilityLayer.getAbilityValues();
|
||||
if (canFly || spectator) {
|
||||
abilities.add(Ability.MAY_FLY);
|
||||
}
|
||||
|
||||
AdventureSettingsPacket adventureSettingsPacket = new AdventureSettingsPacket();
|
||||
adventureSettingsPacket.setUniqueEntityId(bedrockId);
|
||||
adventureSettingsPacket.setCommandPermission(commandPermission);
|
||||
adventureSettingsPacket.setPlayerPermission(playerPermission);
|
||||
// Default stuff we have to fill in
|
||||
abilities.add(Ability.BUILD);
|
||||
abilities.add(Ability.MINE);
|
||||
// Needed so you can drop items
|
||||
abilities.add(Ability.DOORS_AND_SWITCHES);
|
||||
if (gameMode == GameMode.CREATIVE) {
|
||||
// Needed so the client doesn't attempt to take away items
|
||||
abilities.add(Ability.INSTABUILD);
|
||||
}
|
||||
|
||||
Set<AdventureSetting> flags = adventureSettingsPacket.getSettings();
|
||||
if (canFly || spectator) {
|
||||
flags.add(AdventureSetting.MAY_FLY);
|
||||
if (commandPermission == CommandPermission.GAME_DIRECTORS) {
|
||||
// Fixes a bug? since 1.19.11 where the player can change their gamemode in Bedrock settings and
|
||||
// a packet is not sent to the server.
|
||||
// https://github.com/GeyserMC/Geyser/issues/3191
|
||||
abilities.add(Ability.OPERATOR_COMMANDS);
|
||||
}
|
||||
|
||||
if (flying || spectator) {
|
||||
@ -1734,20 +1668,21 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(true);
|
||||
sendDownstreamPacket(abilitiesPacket);
|
||||
}
|
||||
flags.add(AdventureSetting.FLYING);
|
||||
}
|
||||
|
||||
if (worldImmutable) {
|
||||
flags.add(AdventureSetting.WORLD_IMMUTABLE);
|
||||
abilities.add(Ability.FLYING);
|
||||
}
|
||||
|
||||
if (spectator) {
|
||||
flags.add(AdventureSetting.NO_CLIP);
|
||||
abilities.add(Ability.NO_CLIP);
|
||||
}
|
||||
|
||||
flags.add(AdventureSetting.AUTO_JUMP);
|
||||
abilityLayer.setLayerType(AbilityLayer.Type.BASE);
|
||||
abilityLayer.setFlySpeed(flySpeed);
|
||||
// https://github.com/GeyserMC/Geyser/issues/3139 as of 1.19.10
|
||||
abilityLayer.setWalkSpeed(walkSpeed == 0f ? 0.01f : walkSpeed);
|
||||
Collections.addAll(abilityLayer.getAbilitiesSet(), USED_ABILITIES);
|
||||
|
||||
sendUpstreamPacket(adventureSettingsPacket);
|
||||
updateAbilitiesPacket.getAbilityLayers().add(abilityLayer);
|
||||
sendUpstreamPacket(updateAbilitiesPacket);
|
||||
}
|
||||
|
||||
private int getRenderDistance() {
|
||||
|
@ -43,6 +43,8 @@ import java.util.Optional;
|
||||
|
||||
public class AsteriskSerializer extends StdSerializer<Object> implements ContextualSerializer {
|
||||
|
||||
public static final String[] NON_SENSITIVE_ADDRESSES = {"", "0.0.0.0", "localhost", "127.0.0.1", "auto", "unknown"};
|
||||
|
||||
public static boolean showSensitive = false;
|
||||
|
||||
@Target({ElementType.FIELD})
|
||||
@ -91,11 +93,11 @@ public class AsteriskSerializer extends StdSerializer<Object> implements Context
|
||||
}
|
||||
|
||||
private boolean isSensitiveIp(String ip) {
|
||||
if (ip.equalsIgnoreCase("localhost") || ip.equalsIgnoreCase("auto")) {
|
||||
// `auto` should not be shown unless there is an obscure issue with setting the localhost address
|
||||
return false;
|
||||
for (String address : NON_SENSITIVE_ADDRESSES) {
|
||||
if (address.equalsIgnoreCase(ip)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !ip.isEmpty() && !ip.equals("0.0.0.0") && !ip.equals("127.0.0.1");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.text;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.BuiltinChatType;
|
||||
import com.github.steveice10.mc.protocol.data.game.chat.BuiltinChatType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
|
||||
|
@ -65,8 +65,8 @@ public abstract class AbstractBlockInventoryTranslator extends BaseInventoryTran
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
holder.prepareInventory(this, session, inventory);
|
||||
public boolean prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
return holder.prepareInventory(this, session, inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,12 +27,12 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeOptionalStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftRecipeOptionalAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.geysermc.geyser.inventory.AnvilContainer;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
@ -49,27 +49,29 @@ public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
|
||||
return action.getType() == StackRequestActionType.CRAFT_RECIPE_OPTIONAL;
|
||||
protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) {
|
||||
return action.getType() == ItemStackRequestActionType.CRAFT_RECIPE_OPTIONAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
// Guarded by shouldHandleRequestFirst check
|
||||
CraftRecipeOptionalStackRequestActionData data = (CraftRecipeOptionalStackRequestActionData) request.getActions()[0];
|
||||
CraftRecipeOptionalAction data = (CraftRecipeOptionalAction) request.getActions()[0];
|
||||
AnvilContainer container = (AnvilContainer) inventory;
|
||||
|
||||
// Required as of 1.18.30 - FilterTextPackets no longer appear to be sent
|
||||
String name = request.getFilterStrings()[data.getFilteredStringIndex()];
|
||||
if (!Objects.equals(name, container.getNewName())) {
|
||||
container.checkForRename(session, name);
|
||||
if (request.getFilterStrings().length != 0) {
|
||||
// Required as of 1.18.30 - FilterTextPackets no longer appear to be sent
|
||||
String name = request.getFilterStrings()[data.getFilteredStringIndex()];
|
||||
if (!Objects.equals(name, container.getNewName())) { // TODO is this still necessary after pre-1.19.50 support is dropped?
|
||||
container.checkForRename(session, name);
|
||||
}
|
||||
}
|
||||
|
||||
return super.translateRequest(session, inventory, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
case ANVIL_INPUT -> 0;
|
||||
case ANVIL_MATERIAL -> 1;
|
||||
|
@ -27,12 +27,8 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.Container;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
public abstract class BaseInventoryTranslator extends InventoryTranslator {
|
||||
@ -46,7 +42,7 @@ public abstract class BaseInventoryTranslator extends InventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
int slotnum = slotInfoData.getSlot();
|
||||
switch (slotInfoData.getContainer()) {
|
||||
case HOTBAR_AND_INVENTORY:
|
||||
|
@ -27,17 +27,17 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import it.unimi.dsi.fastutil.ints.IntSets;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.BeaconPaymentStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.BeaconPaymentAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
import org.geysermc.geyser.inventory.BeaconContainer;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
@ -105,14 +105,14 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
|
||||
return action.getType() == StackRequestActionType.BEACON_PAYMENT;
|
||||
protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) {
|
||||
return action.getType() == ItemStackRequestActionType.BEACON_PAYMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
// Input a beacon payment
|
||||
BeaconPaymentStackRequestActionData beaconPayment = (BeaconPaymentStackRequestActionData) request.getActions()[0];
|
||||
BeaconPaymentAction beaconPayment = (BeaconPaymentAction) request.getActions()[0];
|
||||
ServerboundSetBeaconPacket packet = new ServerboundSetBeaconPacket(toJava(beaconPayment.getPrimaryEffect()), toJava(beaconPayment.getSecondaryEffect()));
|
||||
session.sendDownstreamPacket(packet);
|
||||
return acceptRequest(request, makeContainerEntries(session, inventory, IntSets.emptySet()));
|
||||
@ -123,7 +123,7 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
if (slotInfoData.getContainer() == ContainerSlotType.BEACON_PAYMENT) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.ContainerSetDataPacket;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
@ -68,7 +68,7 @@ public class BrewingInventoryTranslator extends AbstractBlockInventoryTranslator
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
if (slotInfoData.getContainer() == ContainerSlotType.BREWING_INPUT) {
|
||||
// Ingredient
|
||||
return 3;
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@ -53,7 +53,7 @@ public class CartographyInventoryTranslator extends AbstractBlockInventoryTransl
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
case CARTOGRAPHY_INPUT -> 0;
|
||||
case CARTOGRAPHY_ADDITIONAL -> 1;
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
@ -62,7 +62,7 @@ public class CraftingInventoryTranslator extends AbstractBlockInventoryTranslato
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
if (slotInfoData.getContainer() == ContainerSlotType.CRAFTING_INPUT) {
|
||||
// Java goes from 1 - 9, left to right then up to down
|
||||
// Bedrock is the same, but it starts from 32.
|
||||
|
@ -30,18 +30,14 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.Ser
|
||||
import it.unimi.dsi.fastutil.ints.IntSets;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftRecipeAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.EnchantingContainer;
|
||||
import org.geysermc.geyser.inventory.GeyserEnchantOption;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@ -107,14 +103,14 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
|
||||
return action.getType() == StackRequestActionType.CRAFT_RECIPE;
|
||||
protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) {
|
||||
return action.getType() == ItemStackRequestActionType.CRAFT_RECIPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
// Client has requested an item to be enchanted
|
||||
CraftRecipeStackRequestActionData craftRecipeData = (CraftRecipeStackRequestActionData) request.getActions()[0];
|
||||
CraftRecipeAction craftRecipeData = (CraftRecipeAction) request.getActions()[0];
|
||||
EnchantingContainer enchantingInventory = (EnchantingContainer) inventory;
|
||||
int javaSlot = -1;
|
||||
for (int i = 0; i < enchantingInventory.getEnchantOptions().length; i++) {
|
||||
@ -137,7 +133,7 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
if (slotInfoData.getContainer() == ContainerSlotType.ENCHANTING_INPUT) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
|
||||
@ -37,7 +37,7 @@ public class GrindstoneInventoryTranslator extends AbstractBlockInventoryTransla
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
case GRINDSTONE_INPUT -> 0;
|
||||
case GRINDSTONE_ADDITIONAL -> 1;
|
||||
|
@ -30,18 +30,18 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerEntry;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemEntry;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ResponseStatus;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.*;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.*;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponseContainer;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponseSlot;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponseStatus;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.click.Click;
|
||||
@ -105,13 +105,13 @@ public abstract class InventoryTranslator {
|
||||
|
||||
public final int size;
|
||||
|
||||
public abstract void prepareInventory(GeyserSession session, Inventory inventory);
|
||||
public abstract boolean prepareInventory(GeyserSession session, Inventory inventory);
|
||||
public abstract void openInventory(GeyserSession session, Inventory inventory);
|
||||
public abstract void closeInventory(GeyserSession session, Inventory inventory);
|
||||
public abstract void updateProperty(GeyserSession session, Inventory inventory, int key, int value);
|
||||
public abstract void updateInventory(GeyserSession session, Inventory inventory);
|
||||
public abstract void updateSlot(GeyserSession session, Inventory inventory, int slot);
|
||||
public abstract int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData);
|
||||
public abstract int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData);
|
||||
public abstract int javaSlotToBedrock(int javaSlot);
|
||||
public abstract BedrockContainerSlot javaSlotToBedrockContainer(int javaSlot);
|
||||
public abstract SlotType getSlotType(int javaSlot);
|
||||
@ -141,12 +141,12 @@ public abstract class InventoryTranslator {
|
||||
* Should be overrided if this request matches a certain criteria and shouldn't be treated normally.
|
||||
* E.G. anvil renaming or enchanting
|
||||
*/
|
||||
protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
|
||||
protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link #shouldHandleRequestFirst(StackRequestActionData, Inventory)} returns true, this will be called
|
||||
* If {@link #shouldHandleRequestFirst(ItemStackRequestAction, Inventory)} returns true, this will be called
|
||||
*/
|
||||
protected ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
return rejectRequest(request);
|
||||
@ -158,7 +158,7 @@ public abstract class InventoryTranslator {
|
||||
for (ItemStackRequest request : requests) {
|
||||
ItemStackResponse response;
|
||||
if (request.getActions().length > 0) {
|
||||
StackRequestActionData firstAction = request.getActions()[0];
|
||||
ItemStackRequestAction firstAction = request.getActions()[0];
|
||||
if (shouldHandleRequestFirst(firstAction, inventory)) {
|
||||
// Some special request that shouldn't be processed normally
|
||||
response = translateSpecialRequest(session, inventory, request);
|
||||
@ -176,7 +176,7 @@ public abstract class InventoryTranslator {
|
||||
response = rejectRequest(request);
|
||||
}
|
||||
|
||||
if (response.getResult() != ResponseStatus.OK) {
|
||||
if (response.getResult() != ItemStackResponseStatus.OK) {
|
||||
// Sync our copy of the inventory with Bedrock's to prevent desyncs
|
||||
refresh = true;
|
||||
}
|
||||
@ -197,12 +197,12 @@ public abstract class InventoryTranslator {
|
||||
public ItemStackResponse translateRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
ClickPlan plan = new ClickPlan(session, this, inventory);
|
||||
IntSet affectedSlots = new IntOpenHashSet();
|
||||
for (StackRequestActionData action : request.getActions()) {
|
||||
for (ItemStackRequestAction action : request.getActions()) {
|
||||
GeyserItemStack cursor = session.getPlayerInventory().getCursor();
|
||||
switch (action.getType()) {
|
||||
case TAKE:
|
||||
case PLACE: {
|
||||
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
|
||||
TransferItemStackRequestAction transferAction = (TransferItemStackRequestAction) action;
|
||||
if (!(checkNetId(session, inventory, transferAction.getSource()) && checkNetId(session, inventory, transferAction.getDestination()))) {
|
||||
if (session.getGeyser().getConfig().isDebugMode()) {
|
||||
session.getGeyser().getLogger().error("DEBUG: About to reject TAKE/PLACE request made by " + session.bedrockUsername());
|
||||
@ -290,9 +290,9 @@ public abstract class InventoryTranslator {
|
||||
break;
|
||||
}
|
||||
case SWAP: {
|
||||
SwapStackRequestActionData swapAction = (SwapStackRequestActionData) action;
|
||||
StackRequestSlotInfoData source = swapAction.getSource();
|
||||
StackRequestSlotInfoData destination = swapAction.getDestination();
|
||||
SwapAction swapAction = (SwapAction) action;
|
||||
ItemStackRequestSlotData source = swapAction.getSource();
|
||||
ItemStackRequestSlotData destination = swapAction.getDestination();
|
||||
|
||||
if (!(checkNetId(session, inventory, source) && checkNetId(session, inventory, destination))) {
|
||||
if (session.getGeyser().getConfig().isDebugMode()) {
|
||||
@ -352,7 +352,7 @@ public abstract class InventoryTranslator {
|
||||
break;
|
||||
}
|
||||
case DROP: {
|
||||
DropStackRequestActionData dropAction = (DropStackRequestActionData) action;
|
||||
DropAction dropAction = (DropAction) action;
|
||||
if (!checkNetId(session, inventory, dropAction.getSource()))
|
||||
return rejectRequest(request);
|
||||
|
||||
@ -381,7 +381,7 @@ public abstract class InventoryTranslator {
|
||||
case CONSUME: { // Tends to be called for UI inventories
|
||||
if (inventory instanceof CartographyContainer) {
|
||||
// TODO add this for more inventories? Only seems to glitch out the cartography table, though.
|
||||
ConsumeStackRequestActionData consumeData = (ConsumeStackRequestActionData) action;
|
||||
ConsumeAction consumeData = (ConsumeAction) action;
|
||||
|
||||
int sourceSlot = bedrockSlotToJava(consumeData.getSource());
|
||||
if ((sourceSlot == 0 && inventory.getItem(1).isEmpty()) || (sourceSlot == 1 && inventory.getItem(0).isEmpty())) {
|
||||
@ -436,7 +436,7 @@ public abstract class InventoryTranslator {
|
||||
ClickPlan plan = new ClickPlan(session, this, inventory);
|
||||
// Track all the crafting table slots to report back the contents of the slots after crafting
|
||||
IntSet affectedSlots = new IntOpenHashSet();
|
||||
for (StackRequestActionData action : request.getActions()) {
|
||||
for (ItemStackRequestAction action : request.getActions()) {
|
||||
switch (action.getType()) {
|
||||
case CRAFT_RECIPE: {
|
||||
if (craftState != CraftState.START) {
|
||||
@ -446,7 +446,7 @@ public abstract class InventoryTranslator {
|
||||
break;
|
||||
}
|
||||
case CRAFT_RESULTS_DEPRECATED: {
|
||||
CraftResultsDeprecatedStackRequestActionData deprecatedCraftAction = (CraftResultsDeprecatedStackRequestActionData) action;
|
||||
CraftResultsDeprecatedAction deprecatedCraftAction = (CraftResultsDeprecatedAction) action;
|
||||
if (craftState != CraftState.RECIPE_ID) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -467,12 +467,12 @@ public abstract class InventoryTranslator {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
craftState = CraftState.INGREDIENTS;
|
||||
affectedSlots.add(bedrockSlotToJava(((ConsumeStackRequestActionData) action).getSource()));
|
||||
affectedSlots.add(bedrockSlotToJava(((ConsumeAction) action).getSource()));
|
||||
break;
|
||||
}
|
||||
case TAKE:
|
||||
case PLACE: {
|
||||
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
|
||||
TransferItemStackRequestAction transferAction = (TransferItemStackRequestAction) action;
|
||||
if (craftState != CraftState.INGREDIENTS && craftState != CraftState.TRANSFER) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -556,10 +556,10 @@ public abstract class InventoryTranslator {
|
||||
|
||||
ClickPlan plan = new ClickPlan(session, this, inventory);
|
||||
requestLoop:
|
||||
for (StackRequestActionData action : request.getActions()) {
|
||||
for (ItemStackRequestAction action : request.getActions()) {
|
||||
switch (action.getType()) {
|
||||
case CRAFT_RECIPE_AUTO: {
|
||||
AutoCraftRecipeStackRequestActionData autoCraftAction = (AutoCraftRecipeStackRequestActionData) action;
|
||||
AutoCraftRecipeAction autoCraftAction = (AutoCraftRecipeAction) action;
|
||||
// TODO autoCraftAction#getTimesCrafted 1.17.10 ???
|
||||
if (craftState != CraftState.START) {
|
||||
return rejectRequest(request);
|
||||
@ -601,7 +601,7 @@ public abstract class InventoryTranslator {
|
||||
break;
|
||||
}
|
||||
case CRAFT_RESULTS_DEPRECATED: {
|
||||
CraftResultsDeprecatedStackRequestActionData deprecatedCraftAction = (CraftResultsDeprecatedStackRequestActionData) action;
|
||||
CraftResultsDeprecatedAction deprecatedCraftAction = (CraftResultsDeprecatedAction) action;
|
||||
if (craftState != CraftState.RECIPE_ID) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -618,7 +618,7 @@ public abstract class InventoryTranslator {
|
||||
break;
|
||||
}
|
||||
case CONSUME: {
|
||||
ConsumeStackRequestActionData consumeAction = (ConsumeStackRequestActionData) action;
|
||||
ConsumeAction consumeAction = (ConsumeAction) action;
|
||||
if (craftState != CraftState.DEPRECATED && craftState != CraftState.INGREDIENTS) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -647,7 +647,7 @@ public abstract class InventoryTranslator {
|
||||
}
|
||||
case TAKE:
|
||||
case PLACE: {
|
||||
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
|
||||
TransferItemStackRequestAction transferAction = (TransferItemStackRequestAction) action;
|
||||
if (craftState != CraftState.INGREDIENTS && craftState != CraftState.TRANSFER) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -754,8 +754,8 @@ public abstract class InventoryTranslator {
|
||||
}
|
||||
}
|
||||
|
||||
protected static ItemStackResponse acceptRequest(ItemStackRequest request, List<ContainerEntry> containerEntries) {
|
||||
return new ItemStackResponse(ResponseStatus.OK, request.getRequestId(), containerEntries);
|
||||
protected static ItemStackResponse acceptRequest(ItemStackRequest request, List<ItemStackResponseContainer> containerEntries) {
|
||||
return new ItemStackResponse(ItemStackResponseStatus.OK, request.getRequestId(), containerEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -775,20 +775,20 @@ public abstract class InventoryTranslator {
|
||||
if (throwError && GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
||||
new Throwable("DEBUGGING: ItemStackRequest rejected " + request.toString()).printStackTrace();
|
||||
}
|
||||
return new ItemStackResponse(ResponseStatus.ERROR, request.getRequestId(), Collections.emptyList());
|
||||
return new ItemStackResponse(ItemStackResponseStatus.ERROR, request.getRequestId(), Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out the contents of an ItemStackRequest, should the net ID check fail.
|
||||
*/
|
||||
protected void dumpStackRequestDetails(GeyserSession session, Inventory inventory, StackRequestSlotInfoData source, StackRequestSlotInfoData destination) {
|
||||
protected void dumpStackRequestDetails(GeyserSession session, Inventory inventory, ItemStackRequestSlotData source, ItemStackRequestSlotData destination) {
|
||||
session.getGeyser().getLogger().error("Source: " + source.toString() + " Result: " + checkNetId(session, inventory, source));
|
||||
session.getGeyser().getLogger().error("Destination: " + destination.toString() + " Result: " + checkNetId(session, inventory, destination));
|
||||
session.getGeyser().getLogger().error("Geyser's record of source slot: " + inventory.getItem(bedrockSlotToJava(source)));
|
||||
session.getGeyser().getLogger().error("Geyser's record of destination slot: " + inventory.getItem(bedrockSlotToJava(destination)));
|
||||
}
|
||||
|
||||
public boolean checkNetId(GeyserSession session, Inventory inventory, StackRequestSlotInfoData slotInfoData) {
|
||||
public boolean checkNetId(GeyserSession session, Inventory inventory, ItemStackRequestSlotData slotInfoData) {
|
||||
int netId = slotInfoData.getStackNetworkId();
|
||||
// "In my testing, sometimes the client thinks the netId of an item in the crafting grid is 1, even though we never said it was.
|
||||
// I think it only happens when we manually set the grid but that was my quick fix"
|
||||
@ -846,30 +846,30 @@ public abstract class InventoryTranslator {
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected final List<ContainerEntry> makeContainerEntries(GeyserSession session, Inventory inventory, IntSet affectedSlots) {
|
||||
Map<ContainerSlotType, List<ItemEntry>> containerMap = new HashMap<>();
|
||||
protected final List<ItemStackResponseContainer> makeContainerEntries(GeyserSession session, Inventory inventory, IntSet affectedSlots) {
|
||||
Map<ContainerSlotType, List<ItemStackResponseSlot>> containerMap = new HashMap<>();
|
||||
// Manually call iterator to prevent Integer boxing
|
||||
IntIterator it = affectedSlots.iterator();
|
||||
while (it.hasNext()) {
|
||||
int slot = it.nextInt();
|
||||
BedrockContainerSlot bedrockSlot = javaSlotToBedrockContainer(slot);
|
||||
List<ItemEntry> list = containerMap.computeIfAbsent(bedrockSlot.container(), k -> new ArrayList<>());
|
||||
List<ItemStackResponseSlot> list = containerMap.computeIfAbsent(bedrockSlot.container(), k -> new ArrayList<>());
|
||||
list.add(makeItemEntry(session, bedrockSlot.slot(), inventory.getItem(slot)));
|
||||
}
|
||||
|
||||
List<ContainerEntry> containerEntries = new ArrayList<>();
|
||||
for (Map.Entry<ContainerSlotType, List<ItemEntry>> entry : containerMap.entrySet()) {
|
||||
containerEntries.add(new ContainerEntry(entry.getKey(), entry.getValue()));
|
||||
List<ItemStackResponseContainer> containerEntries = new ArrayList<>();
|
||||
for (Map.Entry<ContainerSlotType, List<ItemStackResponseSlot>> entry : containerMap.entrySet()) {
|
||||
containerEntries.add(new ItemStackResponseContainer(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
ItemEntry cursorEntry = makeItemEntry(session, 0, session.getPlayerInventory().getCursor());
|
||||
containerEntries.add(new ContainerEntry(ContainerSlotType.CURSOR, Collections.singletonList(cursorEntry)));
|
||||
ItemStackResponseSlot cursorEntry = makeItemEntry(session, 0, session.getPlayerInventory().getCursor());
|
||||
containerEntries.add(new ItemStackResponseContainer(ContainerSlotType.CURSOR, Collections.singletonList(cursorEntry)));
|
||||
|
||||
return containerEntries;
|
||||
}
|
||||
|
||||
private static ItemEntry makeItemEntry(GeyserSession session, int bedrockSlot, GeyserItemStack itemStack) {
|
||||
ItemEntry itemEntry;
|
||||
private static ItemStackResponseSlot makeItemEntry(GeyserSession session, int bedrockSlot, GeyserItemStack itemStack) {
|
||||
ItemStackResponseSlot itemEntry;
|
||||
if (!itemStack.isEmpty()) {
|
||||
// As of 1.16.210: Bedrock needs confirmation on what the current item durability is.
|
||||
// If 0 is sent, then Bedrock thinks the item is not damaged
|
||||
@ -881,14 +881,14 @@ public abstract class InventoryTranslator {
|
||||
}
|
||||
}
|
||||
|
||||
itemEntry = new ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) itemStack.getAmount(), itemStack.getNetId(), "", durability);
|
||||
itemEntry = new ItemStackResponseSlot((byte) bedrockSlot, (byte) bedrockSlot, (byte) itemStack.getAmount(), itemStack.getNetId(), "", durability);
|
||||
} else {
|
||||
itemEntry = new ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) 0, 0, "", 0);
|
||||
itemEntry = new ItemStackResponseSlot((byte) bedrockSlot, (byte) bedrockSlot, (byte) 0, 0, "", 0);
|
||||
}
|
||||
return itemEntry;
|
||||
}
|
||||
|
||||
protected static boolean isCursor(StackRequestSlotInfoData slotInfoData) {
|
||||
protected static boolean isCursor(ItemStackRequestSlotData slotInfoData) {
|
||||
return slotInfoData.getContainer() == ContainerSlotType.CURSOR;
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,9 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.Ser
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
@ -55,7 +55,8 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
public boolean prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,19 +28,19 @@ package org.geysermc.geyser.translator.inventory;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftLoomStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftResultsDeprecatedStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftLoomAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftResultsDeprecatedAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
@ -117,19 +117,19 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
|
||||
protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) {
|
||||
// If the LOOM_MATERIAL slot is not empty, we are crafting a pattern that does not come from an item
|
||||
return action.getType() == StackRequestActionType.CRAFT_LOOM && inventory.getItem(2).isEmpty();
|
||||
return action.getType() == ItemStackRequestActionType.CRAFT_LOOM && inventory.getItem(2).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
StackRequestActionData headerData = request.getActions()[0];
|
||||
StackRequestActionData data = request.getActions()[1];
|
||||
if (!(headerData instanceof CraftLoomStackRequestActionData)) {
|
||||
ItemStackRequestAction headerData = request.getActions()[0];
|
||||
ItemStackRequestAction data = request.getActions()[1];
|
||||
if (!(headerData instanceof CraftLoomAction)) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
if (!(data instanceof CraftResultsDeprecatedStackRequestActionData craftData)) {
|
||||
if (!(data instanceof CraftResultsDeprecatedAction craftData)) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
List<NbtMap> newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND);
|
||||
// Get the pattern that the Bedrock client requests - the last pattern in the Patterns list
|
||||
NbtMap pattern = newBlockEntityTag.get(newBlockEntityTag.size() - 1);
|
||||
String bedrockPattern = ((CraftLoomStackRequestActionData) headerData).getPatternId();
|
||||
String bedrockPattern = ((CraftLoomAction) headerData).getPatternId();
|
||||
|
||||
// Get the Java index of this pattern
|
||||
int index = PATTERN_TO_INDEX.getOrDefault(bedrockPattern, -1);
|
||||
@ -181,7 +181,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
case LOOM_INPUT -> 0;
|
||||
case LOOM_DYE -> 1;
|
||||
|
@ -31,19 +31,15 @@ import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.AutoCraftRecipeStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.AutoCraftRecipeAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftRecipeAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.MerchantContainer;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.updater.InventoryUpdater;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@ -80,7 +76,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
case TRADE2_INGREDIENT1 -> 0;
|
||||
case TRADE2_INGREDIENT2 -> 1;
|
||||
@ -98,7 +94,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
public boolean prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
MerchantContainer merchantInventory = (MerchantContainer) inventory;
|
||||
if (merchantInventory.getVillager() == null) {
|
||||
long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet();
|
||||
@ -121,6 +117,8 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
|
||||
|
||||
merchantInventory.setVillager(villager);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -142,7 +140,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
|
||||
// Behavior as of 1.18.10.
|
||||
// We set the net ID to the trade index + 1. This doesn't appear to cause issues and means we don't have to
|
||||
// store a map of net ID to trade index on our end.
|
||||
int tradeChoice = ((CraftRecipeStackRequestActionData) request.getActions()[0]).getRecipeNetworkId() - 1;
|
||||
int tradeChoice = ((CraftRecipeAction) request.getActions()[0]).getRecipeNetworkId() - 1;
|
||||
return handleTrade(session, inventory, request, tradeChoice);
|
||||
}
|
||||
|
||||
@ -151,7 +149,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
|
||||
// 1.18.10 update - seems impossible to call without consoles/controller input
|
||||
// We set the net ID to the trade index + 1. This doesn't appear to cause issues and means we don't have to
|
||||
// store a map of net ID to trade index on our end.
|
||||
int tradeChoice = ((AutoCraftRecipeStackRequestActionData) request.getActions()[0]).getRecipeNetworkId() - 1;
|
||||
int tradeChoice = ((AutoCraftRecipeAction) request.getActions()[0]).getRecipeNetworkId() - 1;
|
||||
return handleTrade(session, inventory, request, tradeChoice);
|
||||
}
|
||||
|
||||
|
@ -36,22 +36,13 @@ import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftCreativeStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.DestroyStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.DropStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.SwapStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.TransferStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.*;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.skin.FakeHeadProvider;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
@ -174,7 +165,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
int slotnum = slotInfoData.getSlot();
|
||||
switch (slotInfoData.getContainer()) {
|
||||
case HOTBAR_AND_INVENTORY:
|
||||
@ -246,10 +237,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
|
||||
PlayerInventory playerInv = session.getPlayerInventory();
|
||||
IntSet affectedSlots = new IntOpenHashSet();
|
||||
for (StackRequestActionData action : request.getActions()) {
|
||||
for (ItemStackRequestAction action : request.getActions()) {
|
||||
switch (action.getType()) {
|
||||
case TAKE, PLACE -> {
|
||||
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
|
||||
TransferItemStackRequestAction transferAction = (TransferItemStackRequestAction ) action;
|
||||
if (!(checkNetId(session, inventory, transferAction.getSource()) && checkNetId(session, inventory, transferAction.getDestination()))) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -296,7 +287,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
}
|
||||
}
|
||||
case SWAP -> {
|
||||
SwapStackRequestActionData swapAction = (SwapStackRequestActionData) action;
|
||||
SwapAction swapAction = (SwapAction) action;
|
||||
if (!(checkNetId(session, inventory, swapAction.getSource()) && checkNetId(session, inventory, swapAction.getDestination()))) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -336,7 +327,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
}
|
||||
}
|
||||
case DROP -> {
|
||||
DropStackRequestActionData dropAction = (DropStackRequestActionData) action;
|
||||
DropAction dropAction = (DropAction) action;
|
||||
if (!checkNetId(session, inventory, dropAction.getSource())) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -364,7 +355,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
}
|
||||
case DESTROY -> {
|
||||
// Only called when a creative client wants to destroy an item... I think - Camotoy
|
||||
DestroyStackRequestActionData destroyAction = (DestroyStackRequestActionData) action;
|
||||
DestroyAction destroyAction = (DestroyAction) action;
|
||||
if (!checkNetId(session, inventory, destroyAction.getSource())) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -403,10 +394,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
ItemStack javaCreativeItem = null;
|
||||
IntSet affectedSlots = new IntOpenHashSet();
|
||||
CraftState craftState = CraftState.START;
|
||||
for (StackRequestActionData action : request.getActions()) {
|
||||
for (ItemStackRequestAction action : request.getActions()) {
|
||||
switch (action.getType()) {
|
||||
case CRAFT_CREATIVE: {
|
||||
CraftCreativeStackRequestActionData creativeAction = (CraftCreativeStackRequestActionData) action;
|
||||
CraftCreativeAction creativeAction = (CraftCreativeAction) action;
|
||||
if (craftState != CraftState.START) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -430,7 +421,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
break;
|
||||
}
|
||||
case DESTROY: {
|
||||
DestroyStackRequestActionData destroyAction = (DestroyStackRequestActionData) action;
|
||||
DestroyAction destroyAction = (DestroyAction) action;
|
||||
if (craftState != CraftState.DEPRECATED) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -442,7 +433,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
}
|
||||
case TAKE:
|
||||
case PLACE: {
|
||||
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
|
||||
TransferItemStackRequestAction transferAction = (TransferItemStackRequestAction) action;
|
||||
if (!(craftState == CraftState.DEPRECATED || craftState == CraftState.TRANSFER)) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -480,7 +471,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
|
||||
DropStackRequestActionData dropAction = (DropStackRequestActionData) action;
|
||||
DropAction dropAction = (DropAction) action;
|
||||
if (dropAction.getSource().getContainer() != ContainerSlotType.CREATIVE_OUTPUT || dropAction.getSource().getSlot() != 50) {
|
||||
return rejectRequest(request);
|
||||
}
|
||||
@ -517,7 +508,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
session.sendDownstreamPacket(creativePacket);
|
||||
}
|
||||
|
||||
private static boolean isCraftingGrid(StackRequestSlotInfoData slotInfoData) {
|
||||
private static boolean isCraftingGrid(ItemStackRequestSlotData slotInfoData) {
|
||||
return slotInfoData.getContainer() == ContainerSlotType.CRAFTING_INPUT;
|
||||
}
|
||||
|
||||
@ -527,7 +518,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
public boolean prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,8 +27,8 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
|
||||
@ -37,7 +37,7 @@ public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslato
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
case SMITHING_TABLE_INPUT -> 0;
|
||||
case SMITHING_TABLE_MATERIAL -> 1;
|
||||
|
@ -29,18 +29,13 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.geysermc.geyser.inventory.StonecutterContainer;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftRecipeAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestActionType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@ -51,14 +46,14 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
|
||||
return action.getType() == StackRequestActionType.CRAFT_RECIPE;
|
||||
protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) {
|
||||
return action.getType() == ItemStackRequestActionType.CRAFT_RECIPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
// Guarded by shouldHandleRequestFirst
|
||||
CraftRecipeStackRequestActionData data = (CraftRecipeStackRequestActionData) request.getActions()[0];
|
||||
CraftRecipeAction data = (CraftRecipeAction) request.getActions()[0];
|
||||
|
||||
// Look up all possible options of cutting from this ID
|
||||
GeyserStonecutterData craftingData = session.getStonecutterRecipes().get(data.getRecipeNetworkId());
|
||||
@ -86,7 +81,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
case STONECUTTER_INPUT -> 0;
|
||||
case STONECUTTER_RESULT, CREATIVE_OUTPUT -> 1;
|
||||
|
@ -26,8 +26,8 @@
|
||||
package org.geysermc.geyser.translator.inventory.chest;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
@ -41,6 +41,7 @@ import org.geysermc.geyser.level.block.DoubleChestValue;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.level.block.entity.DoubleChestBlockEntityTranslator;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
|
||||
public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
|
||||
private final int defaultJavaBlockState;
|
||||
@ -51,7 +52,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
public boolean prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
// See BlockInventoryHolder - same concept there except we're also dealing with a specific block state
|
||||
if (session.getLastInteractionPlayerPosition().equals(session.getPlayerEntity().getPosition())) {
|
||||
int javaBlockId = session.getGeyser().getWorldManager().getBlockAt(session, session.getLastInteractionBlockPosition());
|
||||
@ -77,11 +78,16 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
|
||||
dataPacket.setData(tag.build());
|
||||
dataPacket.setBlockPosition(session.getLastInteractionBlockPosition());
|
||||
session.sendUpstreamPacket(dataPacket);
|
||||
return;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3i position = session.getPlayerEntity().getPosition().toInt().add(Vector3i.UP);
|
||||
Vector3i position = InventoryUtils.findAvailableWorldSpace(session);
|
||||
if (position == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3i pairPosition = position.add(Vector3i.UNIT_X);
|
||||
BlockDefinition definition = session.getBlockMappings().getBedrockBlock(defaultJavaBlockState);
|
||||
|
||||
@ -126,6 +132,8 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
|
||||
session.sendUpstreamPacket(dataPacket);
|
||||
|
||||
inventory.setHolderPosition(position);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,8 +52,8 @@ public class SingleChestInventoryTranslator extends ChestInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
holder.prepareInventory(this, session, inventory);
|
||||
public boolean prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
return holder.prepareInventory(this, session, inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,7 +40,8 @@ public abstract class AbstractHorseInventoryTranslator extends BaseInventoryTran
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
public boolean prepareInventory(GeyserSession session, Inventory inventory) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,7 +28,7 @@ package org.geysermc.geyser.translator.inventory.horse;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
@ -52,7 +52,7 @@ public abstract class ChestedHorseInventoryTranslator extends AbstractHorseInven
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
if (slotInfoData.getContainer() == ContainerSlotType.HORSE_EQUIP) {
|
||||
return this.equipSlot;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
package org.geysermc.geyser.translator.inventory.horse;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
|
||||
public class HorseInventoryTranslator extends AbstractHorseInventoryTranslator {
|
||||
@ -35,7 +35,7 @@ public class HorseInventoryTranslator extends AbstractHorseInventoryTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||
if (slotInfoData.getContainer() == ContainerSlotType.HORSE_EQUIP) {
|
||||
return slotInfoData.getSlot();
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ import com.github.steveice10.opennbt.tag.builtin.LongTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtList;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@ -380,7 +380,7 @@ public abstract class ItemTranslator {
|
||||
if (tag instanceof LongArrayTag) {
|
||||
//Long array tag does not exist in BE
|
||||
//LongArrayTag longArrayTag = (LongArrayTag) tag;
|
||||
//return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
|
||||
//return new org.cloudburstmc.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -26,9 +26,9 @@
|
||||
package org.geysermc.geyser.translator.inventory.item.nbt;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
import com.nukkitx.nbt.NbtList;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
|
@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.translator.inventory.item.nbt.BannerTranslator;
|
||||
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.BEACON)
|
||||
public class BeaconBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.BED)
|
||||
|
@ -26,9 +26,9 @@
|
||||
package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtList;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
|
@ -28,8 +28,8 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
|
||||
/**
|
||||
|
@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
|
||||
|
@ -28,7 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.DoubleChestValue;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
@ -26,7 +26,7 @@
|
||||
package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
|
||||
public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
|
||||
@Override
|
||||
|
@ -30,9 +30,9 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.LongTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtList;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
|
@ -26,8 +26,8 @@
|
||||
package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.JIGSAW)
|
||||
|
@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValue
|
||||
import org.cloudburstmc.math.vector.Vector3d;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
|
@ -26,7 +26,7 @@
|
||||
package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator;
|
||||
|
||||
|
@ -28,11 +28,11 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.SignUtils;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.SIGN)
|
||||
@BlockEntity(type = {BlockEntityType.SIGN, BlockEntityType.HANGING_SIGN})
|
||||
public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||
/**
|
||||
* Maps a color stored in a sign's Color tag to its ARGB value.
|
||||
@ -88,6 +88,7 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||
signWidth += SignUtils.getCharacterWidth(c);
|
||||
}
|
||||
|
||||
// todo 1.20: update for hanging signs (smaller width). Currently OK because bedrock sees hanging signs as normal signs
|
||||
if (signWidth <= SignUtils.BEDROCK_CHARACTER_WIDTH_MAX) {
|
||||
finalSignLine.append(c);
|
||||
} else {
|
||||
|
@ -30,7 +30,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.skin.SkinProvider;
|
||||
|
@ -27,8 +27,9 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
|
||||
@ -68,16 +69,18 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
CompoundTag spawnData = tag.get("SpawnData");
|
||||
if (spawnData != null) {
|
||||
String entityID = (String) ((CompoundTag) spawnData.get("entity"))
|
||||
.get("id")
|
||||
.getValue();
|
||||
builder.put("EntityIdentifier", entityID);
|
||||
StringTag idTag = ((CompoundTag) spawnData.get("entity")).get("id");
|
||||
if (idTag != null) {
|
||||
// As of 1.19.3, spawners can be empty
|
||||
String entityId = idTag.getValue();
|
||||
builder.put("EntityIdentifier", entityId);
|
||||
|
||||
EntityDefinition<?> definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityID);
|
||||
if (definition != null) {
|
||||
builder.put("DisplayEntityWidth", definition.width());
|
||||
builder.put("DisplayEntityHeight", definition.height());
|
||||
builder.put("DisplayEntityScale", 1.0f);
|
||||
EntityDefinition<?> definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityId);
|
||||
if (definition != null) {
|
||||
builder.put("DisplayEntityWidth", definition.width());
|
||||
builder.put("DisplayEntityHeight", definition.height());
|
||||
builder.put("DisplayEntityScale", 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ package org.geysermc.geyser.translator.protocol.bedrock;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetJigsawBlockPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
@ -57,6 +57,10 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator<BlockEnti
|
||||
// This converts the message into the array'd message Java wants
|
||||
for (char character : text.toCharArray()) {
|
||||
widthCount += SignUtils.getCharacterWidth(character);
|
||||
|
||||
// todo 1.20: update for hanging signs (smaller width). Currently bedrock thinks hanging signs are normal,
|
||||
// so it thinks hanging signs have more width than they actually do. Seems like JE just truncates it.
|
||||
|
||||
// If we get a return in Bedrock, or go over the character width max, that signals to use the next line.
|
||||
if (character == '\n' || widthCount > SignUtils.JAVA_CHARACTER_WIDTH_MAX) {
|
||||
// We need to apply some more logic if we went over the character width max
|
||||
|
@ -29,6 +29,7 @@ import org.cloudburstmc.protocol.bedrock.packet.CommandRequestPacket;
|
||||
import org.geysermc.common.PlatformType;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
@ -38,16 +39,14 @@ public class BedrockCommandRequestTranslator extends PacketTranslator<CommandReq
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, CommandRequestPacket packet) {
|
||||
String command = packet.getCommand().replace("/", "");
|
||||
String command = MessageTranslator.convertToPlainText(packet.getCommand());
|
||||
if (!(session.getGeyser().getPlatformType() == PlatformType.STANDALONE
|
||||
&& GeyserImpl.getInstance().commandManager().runCommand(session, command))) {
|
||||
String message = packet.getCommand().trim();
|
||||
|
||||
if (MessageTranslator.isTooLong(message, session)) {
|
||||
&& GeyserImpl.getInstance().commandManager().runCommand(session, command.substring(1)))) {
|
||||
if (MessageTranslator.isTooLong(command, session)) {
|
||||
return;
|
||||
}
|
||||
|
||||
session.sendCommand(message.substring(1));
|
||||
session.sendCommand(command.substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,12 +32,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.*;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
@ -47,10 +42,10 @@ import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.InventoryActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.InventorySource;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.LegacySetItemSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.InventoryActionData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.InventorySource;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.LegacySetItemSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.InventoryTransactionPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
||||
@ -64,7 +59,6 @@ import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.click.Click;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
@ -73,11 +67,7 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.geyser.util.CooldownUtils;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.geyser.util.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -478,10 +468,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
InteractAction.ATTACK, session.isSneaking());
|
||||
session.sendDownstreamPacket(attackPacket);
|
||||
|
||||
if (GameProtocol.supports1_19_10(session)) {
|
||||
// Since 1.19.10, LevelSoundEventPackets are no longer sent by the client when attacking entities
|
||||
CooldownUtils.sendCooldown(session);
|
||||
}
|
||||
// Since 1.19.10, LevelSoundEventPackets are no longer sent by the client when attacking entities
|
||||
CooldownUtils.sendCooldown(session);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -25,9 +25,9 @@
|
||||
|
||||
package org.geysermc.geyser.translator.protocol.bedrock;
|
||||
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
import com.nukkitx.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PositionTrackingDBClientRequestPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PositionTrackingDBServerBroadcastPacket;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
@ -37,21 +37,7 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, TextPacket packet) {
|
||||
String message = packet.getMessage();
|
||||
|
||||
// The order here is important - strip out illegal characters first, then check if it's blank
|
||||
// (in case the message is blank after removing)
|
||||
if (message.indexOf(ChatColor.ESCAPE) != -1) {
|
||||
// Filter out all escape characters - Java doesn't let you type these
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < message.length(); i++) {
|
||||
char c = message.charAt(i);
|
||||
if (c != ChatColor.ESCAPE) {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
message = builder.toString();
|
||||
}
|
||||
String message = MessageTranslator.convertToPlainText(packet.getMessage());
|
||||
|
||||
if (message.isBlank()) {
|
||||
// Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either!
|
||||
|
@ -83,6 +83,9 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||
attributesPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
attributesPacket.getAttributes().addAll(entity.getAttributes().values());
|
||||
session.sendUpstreamPacket(attributesPacket);
|
||||
|
||||
// Bounding box must be sent after a player dies and respawns since 1.19.40
|
||||
entity.updateBoundingBox();
|
||||
break;
|
||||
case START_SWIMMING:
|
||||
if (!entity.getFlag(EntityFlag.SWIMMING)) {
|
||||
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren