mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-25 19:45:21 +01:00
Handle invalid command argument types
The client ignores these presumably for modded servers Fixes #3806
This commit is contained in:
parent
c9733948b3
commit
7ec6888a30
@ -49,17 +49,17 @@ public interface FullMappings extends BiMappings {
|
|||||||
* Returns the unmapped string identifier for the given mapped id.
|
* Returns the unmapped string identifier for the given mapped id.
|
||||||
*
|
*
|
||||||
* @param id unmapped id
|
* @param id unmapped id
|
||||||
* @return unmapped string identifier
|
* @return unmapped string identifier, or null if out of bounds
|
||||||
*/
|
*/
|
||||||
String identifier(int id);
|
@Nullable String identifier(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the mapped string identifier for the given mapped id.
|
* Returns the mapped string identifier for the given mapped id.
|
||||||
*
|
*
|
||||||
* @param mappedId mapped id
|
* @param mappedId mapped id
|
||||||
* @return mapped string identifier
|
* @return mapped string identifier, or null if out of bounds
|
||||||
*/
|
*/
|
||||||
String mappedIdentifier(int mappedId);
|
@Nullable String mappedIdentifier(int mappedId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the mapped string identifier for the given unmapped identifier.
|
* Returns the mapped string identifier for the given unmapped identifier.
|
||||||
|
@ -66,12 +66,20 @@ public class FullMappingsBase implements FullMappings {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String identifier(final int id) {
|
public String identifier(final int id) {
|
||||||
|
if (id < 0 || id >= idToString.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final String identifier = idToString[id];
|
final String identifier = idToString[id];
|
||||||
return Key.namespaced(identifier);
|
return Key.namespaced(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String mappedIdentifier(final int mappedId) {
|
public String mappedIdentifier(final int mappedId) {
|
||||||
|
if (mappedId < 0 || mappedId >= mappedIdToString.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final String identifier = mappedIdToString[mappedId];
|
final String identifier = mappedIdToString[mappedId];
|
||||||
return Key.namespaced(identifier);
|
return Key.namespaced(identifier);
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,14 @@
|
|||||||
package com.viaversion.viaversion.rewriter;
|
package com.viaversion.viaversion.rewriter;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.viaversion.viaversion.api.data.FullMappings;
|
||||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
import com.viaversion.viaversion.api.type.Type;
|
import com.viaversion.viaversion.api.type.Type;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract rewriter for the declare commands packet to handle argument type name and content changes.
|
* Abstract rewriter for the declare commands packet to handle argument type name and content changes.
|
||||||
@ -118,18 +120,25 @@ public class CommandRewriter<C extends ClientboundPacketType> {
|
|||||||
if (nodeType == 2) { // Argument node
|
if (nodeType == 2) { // Argument node
|
||||||
int argumentTypeId = wrapper.read(Type.VAR_INT);
|
int argumentTypeId = wrapper.read(Type.VAR_INT);
|
||||||
String argumentType = argumentType(argumentTypeId);
|
String argumentType = argumentType(argumentTypeId);
|
||||||
|
if (argumentType == null) {
|
||||||
|
// Modded servers may send unknown argument types that are ignored by the client
|
||||||
|
// Adjust the id to the hopefully still assumed out-of-bounds pos...
|
||||||
|
wrapper.write(Type.VAR_INT, mapInvalidArgumentType(argumentTypeId));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String newArgumentType = handleArgumentType(argumentType);
|
String newArgumentType = handleArgumentType(argumentType);
|
||||||
Preconditions.checkNotNull(newArgumentType, "No mapping for argument type %s", argumentType);
|
Preconditions.checkNotNull(newArgumentType, "No mapping for argument type %s", argumentType);
|
||||||
wrapper.write(Type.VAR_INT, mappedArgumentTypeId(newArgumentType));
|
wrapper.write(Type.VAR_INT, mappedArgumentTypeId(newArgumentType));
|
||||||
|
|
||||||
// Always call the handler using the previous name
|
// Always call the handler using the previous name
|
||||||
handleArgument(wrapper, argumentType);
|
handleArgument(wrapper, argumentType);
|
||||||
}
|
|
||||||
|
|
||||||
if ((flags & 0x10) != 0) {
|
if ((flags & 0x10) != 0) {
|
||||||
wrapper.passthrough(Type.STRING); // Suggestion type
|
wrapper.passthrough(Type.STRING); // Suggestion type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wrapper.passthrough(Type.VAR_INT); // Root node index
|
wrapper.passthrough(Type.VAR_INT); // Root node index
|
||||||
});
|
});
|
||||||
@ -148,21 +157,35 @@ public class CommandRewriter<C extends ClientboundPacketType> {
|
|||||||
* @param argumentType argument type
|
* @param argumentType argument type
|
||||||
* @return mapped argument type
|
* @return mapped argument type
|
||||||
*/
|
*/
|
||||||
public String handleArgumentType(String argumentType) {
|
public String handleArgumentType(final String argumentType) {
|
||||||
if (protocol.getMappingData() != null && protocol.getMappingData().getArgumentTypeMappings() != null) {
|
if (protocol.getMappingData() != null && protocol.getMappingData().getArgumentTypeMappings() != null) {
|
||||||
return protocol.getMappingData().getArgumentTypeMappings().mappedIdentifier(argumentType);
|
return protocol.getMappingData().getArgumentTypeMappings().mappedIdentifier(argumentType);
|
||||||
}
|
}
|
||||||
return argumentType;
|
return argumentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String argumentType(int argumentTypeId) {
|
protected @Nullable String argumentType(final int argumentTypeId) {
|
||||||
return protocol.getMappingData().getArgumentTypeMappings().identifier(argumentTypeId);
|
final FullMappings mappings = protocol.getMappingData().getArgumentTypeMappings();
|
||||||
|
final String identifier = mappings.identifier(argumentTypeId);
|
||||||
|
// Allow unknown argument types to be passed through as long as they are actually out of bounds
|
||||||
|
Preconditions.checkArgument(identifier != null || argumentTypeId >= mappings.size(), "Unknown argument type id %s", argumentTypeId);
|
||||||
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int mappedArgumentTypeId(String mappedArgumentType) {
|
protected int mappedArgumentTypeId(final String mappedArgumentType) {
|
||||||
return protocol.getMappingData().getArgumentTypeMappings().mappedId(mappedArgumentType);
|
return protocol.getMappingData().getArgumentTypeMappings().mappedId(mappedArgumentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int mapInvalidArgumentType(final int id) {
|
||||||
|
if (id < 0) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
final FullMappings mappings = protocol.getMappingData().getArgumentTypeMappings();
|
||||||
|
final int idx = id - mappings.size();
|
||||||
|
return mappings.mappedSize() + idx;
|
||||||
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface CommandArgumentConsumer {
|
public interface CommandArgumentConsumer {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user