Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-03 14:50:30 +01:00
Make CommandBlocks work on BungeeCord with 1.8.8 child servers
Dieser Commit ist enthalten in:
Ursprung
69e444f83d
Commit
cfaded6cf8
@ -12,10 +12,7 @@ import us.myles.ViaVersion.api.remapper.ValueTransformer;
|
|||||||
import us.myles.ViaVersion.api.type.Type;
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
import us.myles.ViaVersion.packets.State;
|
import us.myles.ViaVersion.packets.State;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.packets.*;
|
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.*;
|
||||||
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.storage.*;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.*;
|
||||||
import us.myles.ViaVersion.util.GsonUtil;
|
import us.myles.ViaVersion.util.GsonUtil;
|
||||||
|
|
||||||
@ -95,6 +92,7 @@ public class Protocol1_9TO1_8 extends Protocol {
|
|||||||
protected void register(ViaProviders providers) {
|
protected void register(ViaProviders providers) {
|
||||||
providers.register(HandItemProvider.class, new HandItemProvider());
|
providers.register(HandItemProvider.class, new HandItemProvider());
|
||||||
providers.register(BulkChunkTranslatorProvider.class, new BulkChunkTranslatorProvider());
|
providers.register(BulkChunkTranslatorProvider.class, new BulkChunkTranslatorProvider());
|
||||||
|
providers.register(CommandBlockProvider.class, new CommandBlockProvider());
|
||||||
providers.register(EntityIdProvider.class, new EntityIdProvider());
|
providers.register(EntityIdProvider.class, new EntityIdProvider());
|
||||||
providers.require(MovementTransmitterProvider.class);
|
providers.require(MovementTransmitterProvider.class);
|
||||||
if (Via.getConfig().isStimulatePlayerTick()) {
|
if (Via.getConfig().isStimulatePlayerTick()) {
|
||||||
@ -125,5 +123,7 @@ public class Protocol1_9TO1_8 extends Protocol {
|
|||||||
userConnection.put(new InventoryTracker(userConnection));
|
userConnection.put(new InventoryTracker(userConnection));
|
||||||
// Place block tracker
|
// Place block tracker
|
||||||
userConnection.put(new PlaceBlockTracker(userConnection));
|
userConnection.put(new PlaceBlockTracker(userConnection));
|
||||||
|
// CommandBlock storage
|
||||||
|
userConnection.put(new CommandBlockStorage(userConnection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.Protocol1_9TO1_8;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.ChatRewriter;
|
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.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.ClientChunks;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
|
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
|
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));
|
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());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
|
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
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.Protocol1_9TO1_8;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_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.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.Effect;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||||
@ -121,9 +123,14 @@ public class WorldPackets {
|
|||||||
public void handle(PacketWrapper wrapper) throws Exception {
|
public void handle(PacketWrapper wrapper) throws Exception {
|
||||||
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
|
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
|
||||||
Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.passthrough(new ChunkType(clientChunks));
|
Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.passthrough(new ChunkType(clientChunks));
|
||||||
if (chunk.isUnloadPacket())
|
if (chunk.isUnloadPacket()) {
|
||||||
wrapper.setId(0x1D);
|
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)
|
// eat any other data (Usually happens with unload packets)
|
||||||
wrapper.read(Type.REMAINING_BYTES);
|
wrapper.read(Type.REMAINING_BYTES);
|
||||||
}
|
}
|
||||||
@ -189,6 +196,9 @@ public class WorldPackets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (action == 2) { // Update Command Block
|
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
|
// To prevent window issues don't send updates
|
||||||
wrapper.cancel();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren