3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-09-08 22:02:50 +02:00

Make CommandBlocks work on BungeeCord with 1.8.8 child servers

Dieser Commit ist enthalten in:
Matsv 2016-11-02 18:14:57 +01:00
Ursprung 69e444f83d
Commit cfaded6cf8
5 geänderte Dateien mit 193 neuen und 5 gelöschten Zeilen

Datei anzeigen

@ -12,10 +12,7 @@ import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.packets.*;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.*;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.*;
import us.myles.ViaVersion.util.GsonUtil;
@ -95,6 +92,7 @@ public class Protocol1_9TO1_8 extends Protocol {
protected void register(ViaProviders providers) {
providers.register(HandItemProvider.class, new HandItemProvider());
providers.register(BulkChunkTranslatorProvider.class, new BulkChunkTranslatorProvider());
providers.register(CommandBlockProvider.class, new CommandBlockProvider());
providers.register(EntityIdProvider.class, new EntityIdProvider());
providers.require(MovementTransmitterProvider.class);
if (Via.getConfig().isStimulatePlayerTick()) {
@ -125,5 +123,7 @@ public class Protocol1_9TO1_8 extends Protocol {
userConnection.put(new InventoryTracker(userConnection));
// Place block tracker
userConnection.put(new PlaceBlockTracker(userConnection));
// CommandBlock storage
userConnection.put(new CommandBlockStorage(userConnection));
}
}

Datei anzeigen

@ -18,6 +18,7 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.PlayerMovementMapper;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.ChatRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.GameMode;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.CommandBlockProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
@ -183,6 +184,16 @@ public class PlayerPackets {
tracker.setGameMode(GameMode.getById(wrapper.get(Type.UNSIGNED_BYTE, 0))); //Set player gamemode
}
});
// Gotta fake their op
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
provider.sendPermission(wrapper.user());
}
}
);
}
});
@ -323,6 +334,15 @@ public class PlayerPackets {
wrapper.user().get(EntityTracker.class).setGameMode(GameMode.getById(gamemode));
}
});
// Fake permissions to get Commandblocks working
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
provider.sendPermission(wrapper.user());
}
});
}
});

Datei anzeigen

@ -1,5 +1,6 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
import com.google.common.base.Optional;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
@ -18,6 +19,7 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.CommandBlockProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
@ -121,9 +123,14 @@ public class WorldPackets {
public void handle(PacketWrapper wrapper) throws Exception {
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.passthrough(new ChunkType(clientChunks));
if (chunk.isUnloadPacket())
if (chunk.isUnloadPacket()) {
wrapper.setId(0x1D);
// Remove commandBlocks on chunk unload
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
provider.unloadChunk(wrapper.user(), chunk.getX(), chunk.getZ());
}
// eat any other data (Usually happens with unload packets)
wrapper.read(Type.REMAINING_BYTES);
}
@ -189,6 +196,9 @@ public class WorldPackets {
}
}
if (action == 2) { // Update Command Block
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
provider.addOrUpdateBlock(wrapper.user(), wrapper.get(Type.POSITION, 0), wrapper.get(Type.NBT, 0));
// To prevent window issues don't send updates
wrapper.cancel();
}
@ -388,6 +398,27 @@ public class WorldPackets {
}
});
// Handle CommandBlocks
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
Position pos = wrapper.get(Type.POSITION, 0);
Optional<CompoundTag> tag = provider.get(wrapper.user(), pos);
// Send the Update Block Entity packet if present
if (tag.isPresent()) {
PacketWrapper updateBlockEntity = new PacketWrapper(0x09, null, wrapper.user());
updateBlockEntity.write(Type.POSITION, pos);
updateBlockEntity.write(Type.UNSIGNED_BYTE, (short) 2);
updateBlockEntity.write(Type.NBT, tag.get());
updateBlockEntity.send(Protocol1_9TO1_8.class);
}
}
});
}
});
}

Datei anzeigen

@ -0,0 +1,65 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.providers;
import com.google.common.base.Optional;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.platform.providers.Provider;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.CommandBlockStorage;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
public class CommandBlockProvider implements Provider {
public void addOrUpdateBlock(UserConnection user, Position position, CompoundTag tag) throws Exception {
checkPermission(user);
if (isEnabled())
getStorage(user).addOrUpdateBlock(position, tag);
}
public Optional<CompoundTag> get(UserConnection user, Position position) throws Exception {
checkPermission(user);
if (isEnabled())
return getStorage(user).getCommandBlock(position);
return Optional.absent();
}
public void unloadChunk(UserConnection user, int x, int z) throws Exception {
checkPermission(user);
if (isEnabled())
getStorage(user).unloadChunk(x, z);
}
private CommandBlockStorage getStorage(UserConnection connection) {
return connection.get(CommandBlockStorage.class);
}
public void sendPermission(UserConnection user) throws Exception {
if (!isEnabled())
return;
PacketWrapper wrapper = new PacketWrapper(0x1B, null, user); // Entity status
wrapper.write(Type.INT, user.get(EntityTracker.class).getProvidedEntityId()); // Entity ID
wrapper.write(Type.BYTE, (byte) 26); // Hardcoded op permission level
wrapper.send(Protocol1_9TO1_8.class);
user.get(CommandBlockStorage.class).setPermissions(true);
}
// Fix for Bungee since the join game is not sent after the first one
private void checkPermission(UserConnection user) throws Exception {
if (!isEnabled())
return;
CommandBlockStorage storage = getStorage(user);
if (!storage.isPermissions()) {
sendPermission(user);
}
}
public boolean isEnabled() {
return true;
}
}

Datei anzeigen

@ -0,0 +1,72 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.storage;
import com.google.common.base.Optional;
import lombok.Getter;
import lombok.Setter;
import org.spacehq.opennbt.tag.builtin.ByteTag;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CommandBlockStorage extends StoredObject {
private Map<Pair<Integer, Integer>, Map<Position, CompoundTag>> storedCommandBlocks = new ConcurrentHashMap<>();
@Setter
@Getter
private boolean permissions = false;
public CommandBlockStorage(UserConnection user) {
super(user);
}
public void unloadChunk(int x, int z) {
Pair<Integer, Integer> chunkPos = new Pair<>(x, z);
if (storedCommandBlocks.containsKey(chunkPos))
storedCommandBlocks.remove(chunkPos);
}
public void addOrUpdateBlock(Position position, CompoundTag tag) {
Pair<Integer, Integer> chunkPos = getChunkCoords(position);
if (!storedCommandBlocks.containsKey(chunkPos))
storedCommandBlocks.put(chunkPos, new ConcurrentHashMap<Position, CompoundTag>());
Map<Position, CompoundTag> blocks = storedCommandBlocks.get(chunkPos);
if (blocks.containsKey(position))
if (blocks.get(position).equals(tag))
return;
blocks.put(position, tag);
}
private Pair<Integer, Integer> getChunkCoords(Position position) {
int chunkX = (int) Math.floor(position.getX() / 16);
int chunkZ = (int) Math.floor(position.getZ() / 16);
return new Pair<>(chunkX, chunkZ);
}
public Optional<CompoundTag> getCommandBlock(Position position) {
Pair<Integer, Integer> chunkCoords = getChunkCoords(position);
if (!storedCommandBlocks.containsKey(chunkCoords))
return Optional.absent();
Map<Position, CompoundTag> blocks = storedCommandBlocks.get(chunkCoords);
if (!blocks.containsKey(position))
return Optional.absent();
CompoundTag tag = blocks.get(position).clone();
tag.put(new ByteTag("powered", (byte) 0));
tag.put(new ByteTag("auto", (byte) 0));
tag.put(new ByteTag("conditionMet", (byte) 0));
return Optional.of(tag);
}
}