Update adapters to support 1.19.3 and add biome command completions

This commit is contained in:
Camotoy 2022-12-13 13:53:28 -05:00
parent 6876a90c3b
commit 7c26036906
No known key found for this signature in database
GPG Key ID: 7EEFB66FE798081F
6 changed files with 98 additions and 22 deletions

View File

@ -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);
}
}

View File

@ -31,6 +31,7 @@ import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap;
import org.geysermc.geyser.session.GeyserSession;
import javax.annotation.Nullable;
import java.util.Locale;
/**
@ -157,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;
}
}

View File

@ -296,6 +296,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;

View File

@ -44,6 +44,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
import lombok.Getter;
import lombok.ToString;
import net.kyori.adventure.text.format.NamedTextColor;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.event.downstream.ServerDefineCommandsEvent;
import org.geysermc.geyser.command.GeyserCommandManager;
@ -198,7 +199,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
if (commandNode.getChildIndices().length >= 1) {
// Create the root param node and build all the children
ParamInfo rootParam = new ParamInfo(commandNode, null);
rootParam.buildChildren(session, allNodes);
rootParam.buildChildren(new CommandBuilderContext(session), allNodes);
List<CommandParamData[]> treeData = rootParam.getTree();
@ -211,11 +212,11 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
/**
* Convert Java edition command types to Bedrock edition
*
* @param session the session
* @param context the session's command context
* @param node Command type to convert
* @return Bedrock parameter data type
*/
private static Object mapCommandType(GeyserSession session, CommandNode node) {
private static Object mapCommandType(CommandBuilderContext context, CommandNode node) {
CommandParser parser = node.getParser();
if (parser == null) {
return CommandParam.STRING;
@ -232,21 +233,24 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
case RESOURCE_LOCATION, FUNCTION -> CommandParam.FILE_PATH;
case BOOL -> ENUM_BOOLEAN;
case OPERATION -> CommandParam.OPERATOR; // ">=", "==", etc
case BLOCK_STATE -> BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.get().keySet().toArray(new String[0]);
case ITEM_STACK -> session.getItemMappings().getItemNames();
case BLOCK_STATE -> context.getBlockStates();
case ITEM_STACK -> context.session.getItemMappings().getItemNames();
case COLOR -> VALID_COLORS;
case SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS;
case RESOURCE, RESOURCE_OR_TAG -> {
String resource = ((ResourceProperties) node.getProperties()).getRegistryKey();
yield switch (resource) {
// minecraft:worldgen/biome is also valid but we currently don't cache biome IDs
case "minecraft:attribute" -> ATTRIBUTES;
case "minecraft:enchantment" -> Enchantment.JavaEnchantment.ALL_JAVA_IDENTIFIERS;
case "minecraft:entity_type" -> Registries.JAVA_ENTITY_IDENTIFIERS.get().keySet().toArray(new String[0]);
case "minecraft:mob_effect" -> ALL_EFFECT_IDENTIFIERS;
default -> CommandParam.STRING;
};
}
case RESOURCE -> handleResource(context, ((ResourceProperties) node.getProperties()).getRegistryKey(), false);
case RESOURCE_OR_TAG -> handleResource(context, ((ResourceProperties) node.getProperties()).getRegistryKey(), true);
case DIMENSION -> context.session.getLevels();
default -> CommandParam.STRING;
};
}
private static Object handleResource(CommandBuilderContext context, String resource, boolean tags) {
return switch (resource) {
case "minecraft:attribute" -> ATTRIBUTES;
case "minecraft:enchantment" -> Enchantment.JavaEnchantment.ALL_JAVA_IDENTIFIERS;
case "minecraft:entity_type" -> context.getEntityTypes();
case "minecraft:mob_effect" -> ALL_EFFECT_IDENTIFIERS;
case "minecraft:worldgen/biome" -> tags ? context.getBiomesWithTags() : context.getBiomes();
default -> CommandParam.STRING;
};
}
@ -254,7 +258,55 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
/**
* Stores the command description and parameter data for best optimizing the Bedrock commands packet.
*/
private static record BedrockCommandInfo(String name, String description, CommandParamData[][] paramData) implements ServerDefineCommandsEvent.CommandInfo {
private record BedrockCommandInfo(String name, String description, CommandParamData[][] paramData) implements ServerDefineCommandsEvent.CommandInfo {
}
/**
* Stores command completions so we don't have to rebuild the same values multiple times.
*/
@MonotonicNonNull
private static class CommandBuilderContext {
private final GeyserSession session;
private Object biomesWithTags;
private Object biomesNoTags;
private String[] blockStates;
private String[] entityTypes;
CommandBuilderContext(GeyserSession session) {
this.session = session;
}
private Object getBiomes() {
if (biomesNoTags != null) {
return biomesNoTags;
}
String[] identifiers = session.getGeyser().getWorldManager().getBiomeIdentifiers(false);
return (biomesNoTags = identifiers != null ? identifiers : CommandParam.STRING);
}
private Object getBiomesWithTags() {
if (biomesWithTags != null) {
return biomesWithTags;
}
String[] identifiers = session.getGeyser().getWorldManager().getBiomeIdentifiers(true);
return (biomesWithTags = identifiers != null ? identifiers : CommandParam.STRING);
}
private String[] getBlockStates() {
if (blockStates != null) {
return blockStates;
}
return (blockStates = BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.get().keySet().toArray(new String[0]));
}
private String[] getEntityTypes() {
if (entityTypes != null) {
return entityTypes;
}
return (entityTypes = Registries.JAVA_ENTITY_IDENTIFIERS.get().keySet().toArray(new String[0]));
}
}
@Getter
@ -279,10 +331,10 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
/**
* Build the array of all the child parameters (recursive)
*
* @param session the session
* @param context the session's command builder context
* @param allNodes Every command node
*/
public void buildChildren(GeyserSession session, CommandNode[] allNodes) {
public void buildChildren(CommandBuilderContext context, CommandNode[] allNodes) {
for (int paramID : paramNode.getChildIndices()) {
CommandNode paramNode = allNodes[paramID];
@ -320,7 +372,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
}
} else {
// Put the non-enum param into the list
Object mappedType = mapCommandType(session, paramNode);
Object mappedType = mapCommandType(context, paramNode);
CommandEnumData enumData = null;
CommandParam type = null;
boolean optional = this.paramNode.isExecutable();
@ -343,7 +395,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
// Recursively build all child options
for (ParamInfo child : children) {
child.buildChildren(session, allNodes);
child.buildChildren(context, allNodes);
}
}

View File

@ -87,6 +87,7 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
session.getWorldCache().removeScoreboard();
}
session.setWorldName(packet.getWorldName());
session.setLevels(packet.getWorldNames());
BiomeTranslator.loadServerBiomes(session, packet.getRegistry());
session.getTagCache().clear();

View File

@ -21,7 +21,7 @@ jline = "3.21.0"
terminalconsoleappender = "1.2.0"
paper = "1.19-R0.1-SNAPSHOT"
viaversion = "4.0.0"
adapters = "1.5-SNAPSHOT"
adapters = "1.6-SNAPSHOT"
commodore = "2.2"
bungeecord = "a7c6ede"
velocity = "3.0.0"