Skip to content

Commit

Permalink
Add CHAINED_COMMAND and refactor TypeMap#Builder (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alemiz112 authored Nov 6, 2023
2 parents f2491af + 1d956c0 commit 21d1494
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,6 @@ public <O> O readOptional(ByteBuf buffer, O emptyValue, Function<ByteBuf, O> fun
@Override
public <T> void writeOptional(ByteBuf buffer, Predicate<T> isPresent, T object, BiConsumer<ByteBuf, T> consumer) {
checkNotNull(consumer, "read consumer");

boolean exists = isPresent.test(object);
buffer.writeBoolean(exists);
if (exists) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,10 @@ protected CommandParamData readParameter(ByteBuf buffer, BedrockCodecHelper help
param.setEnumData(enums.get(symbol & ~(ARG_FLAG_ENUM | ARG_FLAG_VALID)));
} else {
int parameterTypeId = symbol & ~ARG_FLAG_VALID;
CommandParam type = paramTypeMap.getType(parameterTypeId);
CommandParam type = paramTypeMap.getTypeUnsafe(parameterTypeId);
if (type == null) {
throw new IllegalStateException("Invalid parameter type: " + parameterTypeId);
throw new IllegalStateException("Invalid parameter type: " + parameterTypeId + ", Symbol: " + symbol);
}
param.setType(type);
}
} else {
throw new IllegalStateException("No param type specified: " + param.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import org.cloudburstmc.protocol.bedrock.codec.EntityDataTypeMap;
import org.cloudburstmc.protocol.bedrock.codec.v575.BedrockCodecHelper_v575;
import org.cloudburstmc.protocol.bedrock.codec.v575.Bedrock_v575;
import org.cloudburstmc.protocol.bedrock.codec.v582.Bedrock_v582;
import org.cloudburstmc.protocol.bedrock.codec.v589.Bedrock_v589;
import org.cloudburstmc.protocol.bedrock.codec.v594.serializer.AgentAnimationSerializer_v594;
import org.cloudburstmc.protocol.bedrock.codec.v594.serializer.AvailableCommandsSerializer_v594;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParam;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataFormat;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
Expand All @@ -30,13 +32,18 @@ public class Bedrock_v594 extends Bedrock_v589 {
.update(EntityDataTypes.FLAGS_2, new FlagTransformer(ENTITY_FLAGS, 1))
.build();

protected static final TypeMap<CommandParam> COMMAND_PARAMS = Bedrock_v582.COMMAND_PARAMS.toBuilder()
.insert(134217728, CommandParam.CHAINED_COMMAND)
.build();

@SuppressWarnings("deprecation")
public static final BedrockCodec CODEC = Bedrock_v589.CODEC.toBuilder()
.raknetProtocolVersion(11)
.protocolVersion(594)
.minecraftVersion("1.20.10")
.helper(() -> new BedrockCodecHelper_v575(ENTITY_DATA, GAME_RULE_TYPES, ITEM_STACK_REQUEST_TYPES, CONTAINER_SLOT_TYPES, PLAYER_ABILITIES, TEXT_PROCESSING_ORIGINS))
.deregisterPacket(ScriptCustomEventPacket.class)
.updateSerializer(AvailableCommandsPacket.class, new AvailableCommandsSerializer_v594(COMMAND_PARAMS)) // TODO: chained command deserialization needs more work
.updateSerializer(AvailableCommandsPacket.class, new AvailableCommandsSerializer_v594(COMMAND_PARAMS))
.registerPacket(AgentAnimationPacket::new, new AgentAnimationSerializer_v594(), 304)
.build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public class CommandParam {
public static final CommandParam BLOCK_STATES_CONT = new CommandParam(CommandParamType.BLOCK_STATES_CONT);
public static final CommandParam COMMAND = new CommandParam(CommandParamType.COMMAND);
public static final CommandParam SLASH_COMMAND = new CommandParam(CommandParamType.SLASH_COMMAND);
public static final CommandParam CHAINED_COMMAND = new CommandParam(CommandParamType.CHAINED_COMMAND);

private final CommandParamType paramType;
private final int defaultValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,6 @@ public enum CommandParamType {
BLOCK_STATES,
BLOCK_STATES_CONT, // TODO: unknown - maybe count?
COMMAND,
SLASH_COMMAND
SLASH_COMMAND,
CHAINED_COMMAND
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
Expand All @@ -17,7 +15,8 @@
import java.util.TreeMap;
import java.util.function.BiConsumer;

import static org.cloudburstmc.protocol.common.util.Preconditions.*;
import static org.cloudburstmc.protocol.common.util.Preconditions.checkArgument;
import static org.cloudburstmc.protocol.common.util.Preconditions.checkNotNull;

public final class TypeMap<T> {

Expand Down Expand Up @@ -51,6 +50,10 @@ public T getType(int id) {
return value;
}

public T getTypeUnsafe(int id) {
return toObject.get(id);
}

public Builder<T> toBuilder() {
Builder<T> builder = new Builder<>(type);
this.toObject.forEach(builder::insert);
Expand Down Expand Up @@ -118,26 +121,12 @@ public static <T extends Enum<T>> TypeMap<T> fromEnum(Class<T> clazz, int maxInd
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public static class Builder<T> {
private final String type;
private Object[] types = new Object[0];

private void ensureIndex(int index) {
ensureCapacity(index + 1);
}

private void ensureCapacity(int size) {
if (size > this.types.length) {
int newSize = powerOfTwoCeiling(size + 1);
Object[] newTypes = new Object[newSize];
System.arraycopy(types, 0, newTypes, 0, this.types.length);
this.types = newTypes;
}
}
private final Int2ObjectAVLTreeMap<Object> types = new Int2ObjectAVLTreeMap<>();

public Builder<T> insert(int index, T value) {
checkNotNull(value, "value");
this.ensureIndex(index);
checkArgument(this.types[index] == null, "Cannot insert into non-null value at index " + index);
this.types[index] = value;
checkArgument(this.types.get(index) == null, "Cannot insert into non-null value at index " + index);
this.types.put(index, value);
return this;
}

Expand All @@ -149,28 +138,13 @@ public Builder<T> insert(int index, T value) {
* @return
*/
public Builder<T> shift(int startIndex, int amount) {
return shift(startIndex, amount, this.types.length - startIndex);
}

/**
* Shifts values from a specific start index
*
* @param startIndex
* @param amount
* @param length
* @return
*/
public Builder<T> shift(int startIndex, int amount, int length) {
checkArgument(startIndex < this.types.length, "Start index is out of bounds");
int endIndex = startIndex + length;
checkArgument(endIndex <= this.types.length, "Length exceeds array bounds");
this.ensureCapacity(this.types.length + amount);
System.arraycopy(this.types, startIndex, this.types, startIndex + amount, length);

// Clear old values
for (int i = 0; i < amount; i++) {
this.types[startIndex + i] = null;
Int2ObjectSortedMap<Object> shiftMap = types.tailMap(startIndex);
Int2ObjectArrayMap<Object> tmp = new Int2ObjectArrayMap<>(shiftMap.size());
for (Int2ObjectMap.Entry<Object> entry : shiftMap.int2ObjectEntrySet()) {
tmp.put(entry.getIntKey() + amount, entry.getValue());
types.put(entry.getIntKey(), null);
}
types.putAll(tmp);
return this;
}

Expand All @@ -184,19 +158,16 @@ public Builder<T> shift(int startIndex, int amount, int length) {
*/
public Builder<T> replace(int index, T value) {
checkNotNull(value, "value");
checkArgument(index < this.types.length, "Cannot update out of bounds value");
checkArgument(this.types[index] != null, "Cannot update null value");
this.types[index] = value;
checkArgument(this.types.get(index) != null, "Cannot update null value");
this.types.put(index, value);
return this;
}

public Builder<T> update(int oldIndex, int newIndex, T value) {
checkNotNull(value, "value");
checkArgument(oldIndex < this.types.length, "Cannot update out of bounds value");
checkArgument(this.types[oldIndex] == value, "oldIndex value does not equal expected");
this.ensureIndex(newIndex);
this.types[oldIndex] = null;
this.types[newIndex] = value;
checkArgument(this.types.get(oldIndex) == value, "oldIndex value does not equal expected");
this.types.remove(oldIndex);
this.types.put(newIndex, value);
return this;
}

Expand All @@ -205,16 +176,13 @@ public Builder<T> insert(int offset, TypeMap<? extends T> map) {
map.toObject.forEach((index, value) -> {
int newIndex = index + offset;
checkNotNull(value, "value");
this.ensureIndex(newIndex);
this.types[newIndex] = value;
this.types.put(newIndex, value);
});
return this;
}

public Builder<T> remove(int index) {
checkElementIndex(index, this.types.length);
// checkArgument(this.types[index] != null, "Cannot remove null value");
this.types[index] = null;
this.types.remove(index);
return this;
}

Expand All @@ -224,11 +192,11 @@ public TypeMap<T> build() {
toId.defaultReturnValue(-1);

Int2ObjectMap<T> toObject = new Int2ObjectOpenHashMap<>();
for (int i = 0; i < this.types.length; i++) {
Object type = this.types[i];
for (Int2ObjectMap.Entry<Object> entry : types.int2ObjectEntrySet()) {
Object type = entry.getValue();
if (type != null) {
toId.put((T) type, i);
toObject.put(i, (T) type);
toId.put((T) type, entry.getIntKey());
toObject.put(entry.getIntKey(), (T) type);
}
}
return new TypeMap<>(this.type, toId, toObject);
Expand Down

0 comments on commit 21d1494

Please sign in to comment.