2023-01-11 20:53:59 +01:00
|
|
|
/*
|
2023-01-14 14:33:05 +01:00
|
|
|
* This file is part of ViaLegacy - https://github.com/RaphiMC/ViaLegacy
|
2023-01-11 20:53:59 +01:00
|
|
|
* Copyright (C) 2023 RK_01/RaphiMC and contributors
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2023-01-03 23:54:35 +01:00
|
|
|
package net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30;
|
|
|
|
|
|
|
|
import com.viaversion.viaversion.api.Via;
|
|
|
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
|
|
|
import com.viaversion.viaversion.api.minecraft.Position;
|
|
|
|
import com.viaversion.viaversion.api.minecraft.item.Item;
|
|
|
|
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
|
|
|
|
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
|
|
|
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
|
|
|
import com.viaversion.viaversion.api.protocol.packet.State;
|
2023-02-12 14:42:08 +01:00
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
2023-01-03 23:54:35 +01:00
|
|
|
import com.viaversion.viaversion.api.type.Type;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
2023-01-10 21:53:22 +01:00
|
|
|
import net.raphimc.vialegacy.api.data.BlockList1_6;
|
|
|
|
import net.raphimc.vialegacy.api.model.ChunkCoord;
|
|
|
|
import net.raphimc.vialegacy.api.model.IdAndData;
|
|
|
|
import net.raphimc.vialegacy.api.splitter.PreNettySplitter;
|
|
|
|
import net.raphimc.vialegacy.api.util.BlockFaceUtil;
|
2023-01-03 23:54:35 +01:00
|
|
|
import net.raphimc.vialegacy.protocols.alpha.protocola1_0_16_2toa1_0_15.ClientboundPacketsa1_0_15;
|
|
|
|
import net.raphimc.vialegacy.protocols.alpha.protocola1_0_16_2toa1_0_15.ServerboundPacketsa1_0_15;
|
|
|
|
import net.raphimc.vialegacy.protocols.alpha.protocola1_0_17_1_0_17_4toa1_0_16_2.storage.TimeLockStorage;
|
|
|
|
import net.raphimc.vialegacy.protocols.alpha.protocola1_1_0_1_1_2_1toa1_0_17_1_0_17_4.Protocola1_1_0_1_1_2_1toa1_0_17_1_0_17_4;
|
|
|
|
import net.raphimc.vialegacy.protocols.alpha.protocola1_2_0_1_2_1_1toa1_1_0_1_1_2_1.ClientboundPacketsa1_1_0;
|
|
|
|
import net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.providers.AlphaInventoryProvider;
|
|
|
|
import net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.storage.AlphaInventoryTracker;
|
|
|
|
import net.raphimc.vialegacy.protocols.beta.protocol1_0_0_1tob1_8_0_1.ClientboundPacketsb1_8;
|
|
|
|
import net.raphimc.vialegacy.protocols.beta.protocolb1_3_0_1tob1_2_0_2.storage.BlockDigStorage;
|
|
|
|
import net.raphimc.vialegacy.protocols.beta.protocolb1_6_0_6tob1_5_0_2.Protocolb1_6_0_6tob1_5_0_2;
|
|
|
|
import net.raphimc.vialegacy.protocols.beta.protocolb1_8_0_1tob1_7_0_3.ClientboundPacketsb1_7;
|
|
|
|
import net.raphimc.vialegacy.protocols.beta.protocolb1_8_0_1tob1_7_0_3.Protocolb1_8_0_1tob1_7_0_3;
|
|
|
|
import net.raphimc.vialegacy.protocols.beta.protocolb1_8_0_1tob1_7_0_3.types.Typesb1_7_0_3;
|
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.data.ClassicBlocks;
|
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.model.ClassicLevel;
|
2023-01-10 21:53:22 +01:00
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicCustomCommandProvider;
|
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicMPPassProvider;
|
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicWorldHeightProvider;
|
2023-01-03 23:54:35 +01:00
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.storage.*;
|
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.types.Typesc0_30;
|
2023-01-10 21:53:22 +01:00
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.Protocolc0_30toc0_30cpe;
|
2023-01-03 23:54:35 +01:00
|
|
|
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtBlockPermissionsStorage;
|
|
|
|
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.Protocol1_8to1_7_6_10;
|
|
|
|
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.types.Types1_7_6;
|
|
|
|
|
|
|
|
public class Protocola1_0_15toc0_30 extends AbstractProtocol<ClientboundPacketsc0_28, ClientboundPacketsa1_0_15, ServerboundPacketsc0_28, ServerboundPacketsa1_0_15> {
|
|
|
|
|
|
|
|
public Protocola1_0_15toc0_30() {
|
|
|
|
super(ClientboundPacketsc0_28.class, ClientboundPacketsa1_0_15.class, ServerboundPacketsc0_28.class, ServerboundPacketsa1_0_15.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void registerPackets() {
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(State.LOGIN, ClientboundPacketsc0_28.DISCONNECT.getId(), ClientboundPacketsa1_0_15.DISCONNECT.getId(), new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Typesc0_30.STRING, Typesb1_7_0_3.STRING, s -> s.replace("&", "§")); // reason
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.JOIN_GAME, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
read(Type.BYTE); // protocol id
|
|
|
|
handler(wrapper -> {
|
|
|
|
final String title = wrapper.read(Typesc0_30.STRING).replace("&", "§"); // title
|
|
|
|
final String motd = wrapper.read(Typesc0_30.STRING).replace("&", "§"); // motd
|
|
|
|
final byte opLevel = wrapper.read(Type.BYTE); // op level
|
|
|
|
wrapper.user().put(new ClassicServerTitleStorage(wrapper.user(), title, motd));
|
|
|
|
wrapper.user().get(ClassicOpLevelStorage.class).setOpLevel(opLevel);
|
|
|
|
|
|
|
|
wrapper.write(Type.INT, wrapper.user().getProtocolInfo().getUsername().hashCode()); // entity id
|
|
|
|
wrapper.write(Typesb1_7_0_3.STRING, wrapper.user().getProtocolInfo().getUsername()); // username
|
|
|
|
wrapper.write(Typesb1_7_0_3.STRING, ""); // password
|
|
|
|
|
|
|
|
if (wrapper.user().has(ClassicLevelStorage.class)) { // World already loaded
|
|
|
|
wrapper.cancel();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wrapper.user().getProtocolInfo().getPipeline().contains(Protocol1_8to1_7_6_10.class)) {
|
|
|
|
final PacketWrapper tabList = PacketWrapper.create(ClientboundPackets1_8.TAB_LIST, wrapper.user());
|
|
|
|
tabList.write(Type.STRING, Protocol1_8to1_7_6_10.LEGACY_TO_JSON.transform(wrapper, "§6" + title + "\n")); // header
|
|
|
|
tabList.write(Type.STRING, Protocol1_8to1_7_6_10.LEGACY_TO_JSON.transform(wrapper, "\n§b" + motd)); // footer
|
|
|
|
tabList.send(Protocol1_8to1_7_6_10.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
final ClassicProgressStorage classicProgressStorage = wrapper.user().get(ClassicProgressStorage.class);
|
|
|
|
classicProgressStorage.progress = 1;
|
|
|
|
classicProgressStorage.upperBound = 2;
|
|
|
|
classicProgressStorage.status = "Waiting for server...";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.LEVEL_INIT, null, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.cancel();
|
|
|
|
|
|
|
|
if (wrapper.user().has(ClassicLevelStorage.class)) { // Switch world
|
|
|
|
if (wrapper.user().getProtocolInfo().getPipeline().contains(Protocolb1_6_0_6tob1_5_0_2.class)) {
|
|
|
|
final PacketWrapper fakeRespawn = PacketWrapper.create(ClientboundPacketsb1_7.RESPAWN, wrapper.user());
|
|
|
|
fakeRespawn.write(Type.BYTE, (byte) -1); // dimension id
|
|
|
|
fakeRespawn.send(Protocolb1_6_0_6tob1_5_0_2.class);
|
|
|
|
final PacketWrapper respawn = PacketWrapper.create(ClientboundPacketsb1_7.RESPAWN, wrapper.user());
|
|
|
|
respawn.write(Type.BYTE, (byte) 0); // dimension id
|
|
|
|
respawn.send(Protocolb1_6_0_6tob1_5_0_2.class);
|
|
|
|
wrapper.user().get(ClassicPositionTracker.class).spawned = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (wrapper.user().getProtocolInfo().getPipeline().contains(Protocolb1_8_0_1tob1_7_0_3.class)) {
|
|
|
|
final PacketWrapper gameEvent = PacketWrapper.create(ClientboundPacketsb1_8.GAME_EVENT, wrapper.user());
|
|
|
|
gameEvent.write(Type.BYTE, (byte) 3); // reason (game mode)
|
|
|
|
gameEvent.write(Type.BYTE, (byte) 1); // value (creative)
|
|
|
|
gameEvent.send(Protocolb1_8_0_1tob1_7_0_3.class);
|
|
|
|
}
|
2023-02-21 21:30:00 +01:00
|
|
|
wrapper.user().get(ClassicOpLevelStorage.class).updateAbilities();
|
2023-01-03 23:54:35 +01:00
|
|
|
|
|
|
|
wrapper.user().put(new ClassicLevelStorage(wrapper.user()));
|
|
|
|
|
|
|
|
final ClassicProgressStorage classicProgressStorage = wrapper.user().get(ClassicProgressStorage.class);
|
|
|
|
classicProgressStorage.progress = 2;
|
|
|
|
classicProgressStorage.upperBound = 2;
|
|
|
|
classicProgressStorage.status = "Waiting for server...";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.LEVEL_DATA, null, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.cancel();
|
|
|
|
final short partSize = wrapper.read(Type.SHORT); // part size
|
|
|
|
final byte[] data = wrapper.read(Typesc0_30.BYTE_ARRAY); // data
|
|
|
|
final byte progress = wrapper.read(Type.BYTE); // progress
|
|
|
|
|
|
|
|
wrapper.user().get(ClassicLevelStorage.class).addDataPart(data, partSize);
|
|
|
|
|
|
|
|
final ClassicProgressStorage classicProgressStorage = wrapper.user().get(ClassicProgressStorage.class);
|
|
|
|
classicProgressStorage.upperBound = 100;
|
|
|
|
classicProgressStorage.progress = progress;
|
|
|
|
classicProgressStorage.status = "Receiving level... §7" + progress + "%";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.LEVEL_FINALIZE, null, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.cancel();
|
|
|
|
final short sizeX = wrapper.read(Type.SHORT);
|
|
|
|
final short sizeY = wrapper.read(Type.SHORT);
|
|
|
|
final short sizeZ = wrapper.read(Type.SHORT);
|
|
|
|
|
|
|
|
final ClassicProgressStorage classicProgressStorage = wrapper.user().get(ClassicProgressStorage.class);
|
|
|
|
final ClassicLevelStorage levelStorage = wrapper.user().get(ClassicLevelStorage.class);
|
|
|
|
final short maxChunkSectionCount = Via.getManager().getProviders().get(ClassicWorldHeightProvider.class).getMaxChunkSectionCount(wrapper.user());
|
|
|
|
|
|
|
|
classicProgressStorage.upperBound = 2;
|
|
|
|
classicProgressStorage.progress = 0;
|
|
|
|
classicProgressStorage.status = "Finishing level... §7Decompressing";
|
|
|
|
levelStorage.finish(sizeX, sizeY, sizeZ);
|
|
|
|
levelStorage.sendChunk(new ChunkCoord(0, 0));
|
|
|
|
|
|
|
|
if (wrapper.user().getProtocolInfo().getPipeline().contains(Protocol1_8to1_7_6_10.class)) {
|
|
|
|
final PacketWrapper worldBorder = PacketWrapper.create(ClientboundPackets1_8.WORLD_BORDER, wrapper.user());
|
|
|
|
worldBorder.write(Type.VAR_INT, 3); // action (INITIALIZE)
|
|
|
|
worldBorder.write(Type.DOUBLE, sizeX / 2D); // centerX
|
|
|
|
worldBorder.write(Type.DOUBLE, sizeZ / 2D); // centerZ
|
|
|
|
worldBorder.write(Type.DOUBLE, 0.0D); // diameter
|
|
|
|
worldBorder.write(Type.DOUBLE, (double) Math.max(sizeX, sizeZ)); // target size
|
|
|
|
worldBorder.write(Type.VAR_LONG, 0L); // time until target size
|
|
|
|
worldBorder.write(Type.VAR_INT, Math.max(sizeX, sizeZ)); // size
|
|
|
|
worldBorder.write(Type.VAR_INT, 0); // warning distance
|
|
|
|
worldBorder.write(Type.VAR_INT, 0); // warning time
|
|
|
|
worldBorder.send(Protocol1_8to1_7_6_10.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
sendChatMessage(wrapper.user(), "§aWorld dimensions: §6" + sizeX + "§ax§6" + sizeY + "§ax§6" + sizeZ);
|
|
|
|
if (sizeY > (maxChunkSectionCount << 4)) {
|
|
|
|
sendChatMessage(wrapper.user(), "§cThis server has a world higher than " + (maxChunkSectionCount << 4) + " blocks! Expect world errors");
|
|
|
|
}
|
|
|
|
|
|
|
|
classicProgressStorage.progress = 1;
|
|
|
|
classicProgressStorage.status = "Finishing level... §7Waiting for server";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.BLOCK_CHANGE, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Typesc0_30.POSITION, Types1_7_6.POSITION_UBYTE); // position
|
|
|
|
handler(wrapper -> {
|
|
|
|
final ClassicLevelStorage levelStorage = wrapper.user().get(ClassicLevelStorage.class);
|
|
|
|
if (levelStorage == null || !levelStorage.hasReceivedLevel()) {
|
|
|
|
wrapper.cancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
final ClassicBlockRemapper remapper = wrapper.user().get(ClassicBlockRemapper.class);
|
|
|
|
final Position pos = wrapper.get(Types1_7_6.POSITION_UBYTE, 0);
|
|
|
|
final byte blockId = wrapper.read(Type.BYTE); // block id
|
|
|
|
levelStorage.getClassicLevel().setBlock(pos, blockId);
|
|
|
|
if (!levelStorage.isChunkLoaded(pos)) {
|
|
|
|
wrapper.cancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
final IdAndData mappedBlock = remapper.getMapper().get(blockId);
|
|
|
|
wrapper.write(Type.UNSIGNED_BYTE, (short) mappedBlock.id); // block id
|
|
|
|
wrapper.write(Type.UNSIGNED_BYTE, (short) mappedBlock.data); // block data
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.SPAWN_PLAYER, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Type.BYTE, Type.INT); // entity id
|
|
|
|
map(Typesc0_30.STRING, Typesb1_7_0_3.STRING, n -> n.replace("&", "§")); // username
|
|
|
|
map(Type.SHORT, Type.INT); // x
|
|
|
|
map(Type.SHORT, Type.INT); // y
|
|
|
|
map(Type.SHORT, Type.INT); // z
|
|
|
|
map(Type.BYTE, Type.BYTE, yaw -> (byte) (yaw + 128)); // yaw
|
|
|
|
map(Type.BYTE); // pitch
|
|
|
|
create(Type.UNSIGNED_SHORT, 0); // item
|
|
|
|
handler(wrapper -> {
|
|
|
|
if (wrapper.get(Type.INT, 0) < 0) { // client player
|
|
|
|
wrapper.cancel();
|
|
|
|
final int x = wrapper.get(Type.INT, 1);
|
|
|
|
final int y = wrapper.get(Type.INT, 2);
|
|
|
|
final int z = wrapper.get(Type.INT, 3);
|
|
|
|
final byte yaw = wrapper.get(Type.BYTE, 0);
|
|
|
|
final byte pitch = wrapper.get(Type.BYTE, 1);
|
|
|
|
|
|
|
|
final ClassicProgressStorage classicProgressStorage = wrapper.user().get(ClassicProgressStorage.class);
|
|
|
|
classicProgressStorage.progress = 2;
|
|
|
|
classicProgressStorage.status = "Finishing level... §7Loading spawn chunks";
|
|
|
|
|
|
|
|
final ClassicPositionTracker classicPositionTracker = wrapper.user().get(ClassicPositionTracker.class);
|
|
|
|
classicPositionTracker.posX = (x / 32.0F);
|
|
|
|
classicPositionTracker.stance = (y / 32.0F) + 0.714F;
|
|
|
|
classicPositionTracker.posZ = (z / 32.0F);
|
|
|
|
classicPositionTracker.yaw = yaw * 360 / 256.0F;
|
|
|
|
classicPositionTracker.pitch = pitch * 360 / 256.0F;
|
|
|
|
wrapper.user().get(ClassicLevelStorage.class).sendChunks(classicPositionTracker.getChunkPosition(), 1);
|
|
|
|
|
|
|
|
if (wrapper.user().getProtocolInfo().getPipeline().contains(Protocola1_1_0_1_1_2_1toa1_0_17_1_0_17_4.class)) {
|
|
|
|
final PacketWrapper spawnPosition = PacketWrapper.create(ClientboundPacketsa1_1_0.SPAWN_POSITION, wrapper.user());
|
|
|
|
spawnPosition.write(Types1_7_6.POSITION_INT, new Position((int) classicPositionTracker.posX, (int) (classicPositionTracker.stance), (int) classicPositionTracker.posZ));
|
|
|
|
spawnPosition.send(Protocola1_1_0_1_1_2_1toa1_0_17_1_0_17_4.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
final PacketWrapper playerPosition = PacketWrapper.create(ClientboundPacketsa1_0_15.PLAYER_POSITION, wrapper.user());
|
|
|
|
playerPosition.write(Type.DOUBLE, classicPositionTracker.posX); // x
|
|
|
|
playerPosition.write(Type.DOUBLE, classicPositionTracker.stance); // stance
|
|
|
|
playerPosition.write(Type.DOUBLE, classicPositionTracker.stance - 1.62F); // y
|
|
|
|
playerPosition.write(Type.DOUBLE, classicPositionTracker.posZ); // z
|
|
|
|
playerPosition.write(Type.FLOAT, classicPositionTracker.yaw); // yaw
|
|
|
|
playerPosition.write(Type.FLOAT, classicPositionTracker.pitch); // pitch
|
|
|
|
playerPosition.write(Type.BOOLEAN, true); // onGround
|
|
|
|
playerPosition.send(Protocola1_0_15toc0_30.class);
|
|
|
|
classicPositionTracker.spawned = true;
|
|
|
|
} else {
|
|
|
|
wrapper.set(Type.INT, 2, wrapper.get(Type.INT, 2) - Float.valueOf(1.62F * 32).intValue());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.ENTITY_TELEPORT, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Type.BYTE, Type.INT); // entity id
|
|
|
|
map(Type.SHORT, Type.INT); // x
|
|
|
|
map(Type.SHORT, Type.INT); // y
|
|
|
|
map(Type.SHORT, Type.INT); // z
|
|
|
|
map(Type.BYTE, Type.BYTE, yaw -> (byte) (yaw + 128)); // yaw
|
|
|
|
map(Type.BYTE); // pitch
|
|
|
|
handler(wrapper -> {
|
|
|
|
if (wrapper.get(Type.INT, 0) < 0) { // client player
|
|
|
|
wrapper.set(Type.INT, 2, wrapper.get(Type.INT, 2) - 29);
|
|
|
|
wrapper.set(Type.INT, 0, wrapper.user().getProtocolInfo().getUsername().hashCode());
|
|
|
|
} else {
|
|
|
|
wrapper.set(Type.INT, 2, wrapper.get(Type.INT, 2) - Float.valueOf(1.62F * 32).intValue());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.ENTITY_POSITION_AND_ROTATION, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Type.BYTE, Type.INT); // entity id
|
|
|
|
map(Type.BYTE); // x
|
|
|
|
map(Type.BYTE); // y
|
|
|
|
map(Type.BYTE); // z
|
|
|
|
map(Type.BYTE, Type.BYTE, yaw -> (byte) (yaw + 128)); // yaw
|
|
|
|
map(Type.BYTE); // pitch
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.ENTITY_POSITION, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Type.BYTE, Type.INT); // entity id
|
|
|
|
map(Type.BYTE); // x
|
|
|
|
map(Type.BYTE); // y
|
|
|
|
map(Type.BYTE); // z
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.ENTITY_ROTATION, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Type.BYTE, Type.INT); // entity id
|
|
|
|
map(Type.BYTE, Type.BYTE, yaw -> (byte) (yaw + 128)); // yaw
|
|
|
|
map(Type.BYTE); // pitch
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.DESTROY_ENTITIES, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Type.BYTE, Type.INT); // entity id
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.CHAT_MESSAGE, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(packetWrapper -> {
|
|
|
|
final byte senderId = packetWrapper.read(Type.BYTE); // sender id
|
|
|
|
String message = packetWrapper.read(Typesc0_30.STRING).replace("&", "§"); // message
|
|
|
|
if (senderId < 0) {
|
|
|
|
message = "§e" + message;
|
|
|
|
}
|
|
|
|
packetWrapper.write(Typesb1_7_0_3.STRING, message);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.DISCONNECT, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Typesc0_30.STRING, Typesb1_7_0_3.STRING, s -> s.replace("&", "§")); // reason
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerClientbound(ClientboundPacketsc0_28.OP_LEVEL_UPDATE, null, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.cancel();
|
2023-02-21 21:30:00 +01:00
|
|
|
final ClassicOpLevelStorage opLevelStorage = wrapper.user().get(ClassicOpLevelStorage.class);
|
2023-01-03 23:54:35 +01:00
|
|
|
final byte opLevel = wrapper.read(Type.BYTE); // op level
|
2023-02-21 21:30:00 +01:00
|
|
|
opLevelStorage.setOpLevel(opLevel);
|
2023-01-03 23:54:35 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-02-12 21:05:15 +01:00
|
|
|
this.registerServerbound(State.LOGIN, ServerboundPacketsa1_0_15.LOGIN.getId(), ServerboundPacketsc0_28.LOGIN.getId(), new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
map(Type.INT, Type.BYTE); // protocol id
|
|
|
|
map(Typesb1_7_0_3.STRING, Typesc0_30.STRING); // username
|
|
|
|
read(Typesb1_7_0_3.STRING); // password
|
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.write(Typesc0_30.STRING, Via.getManager().getProviders().get(ClassicMPPassProvider.class).getMpPass(wrapper.user())); // mp pass
|
|
|
|
wrapper.write(Type.BYTE, (byte) 0); // op level
|
|
|
|
|
|
|
|
final ClassicProgressStorage classicProgressStorage = wrapper.user().get(ClassicProgressStorage.class);
|
|
|
|
classicProgressStorage.upperBound = 2;
|
|
|
|
classicProgressStorage.status = "Logging in...";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerServerbound(ServerboundPacketsa1_0_15.CHAT_MESSAGE, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
final String message = wrapper.read(Typesb1_7_0_3.STRING); // message
|
|
|
|
wrapper.write(Type.BYTE, (byte) 0); // sender id
|
|
|
|
wrapper.write(Typesc0_30.STRING, message); // message
|
|
|
|
if (Via.getManager().getProviders().get(ClassicCustomCommandProvider.class).handleChatMessage(wrapper.user(), message)) {
|
|
|
|
wrapper.cancel();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerServerbound(ServerboundPacketsa1_0_15.PLAYER_MOVEMENT, ServerboundPacketsc0_28.PLAYER_POSITION_AND_ROTATION, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
read(Type.BOOLEAN); // onGround
|
|
|
|
handler(wrapper -> {
|
|
|
|
final ClassicPositionTracker positionTracker = wrapper.user().get(ClassicPositionTracker.class);
|
|
|
|
final ClassicLevelStorage levelStorage = wrapper.user().get(ClassicLevelStorage.class);
|
|
|
|
positionTracker.writeToPacket(wrapper);
|
|
|
|
if (levelStorage != null) levelStorage.tickChunks(positionTracker.getChunkPosition());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerServerbound(ServerboundPacketsa1_0_15.PLAYER_POSITION, ServerboundPacketsc0_28.PLAYER_POSITION_AND_ROTATION, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
final ClassicPositionTracker positionTracker = wrapper.user().get(ClassicPositionTracker.class);
|
|
|
|
final ClassicLevelStorage levelStorage = wrapper.user().get(ClassicLevelStorage.class);
|
|
|
|
positionTracker.posX = wrapper.read(Type.DOUBLE); // x
|
|
|
|
wrapper.read(Type.DOUBLE); // y
|
|
|
|
positionTracker.stance = wrapper.read(Type.DOUBLE); // stance
|
|
|
|
positionTracker.posZ = wrapper.read(Type.DOUBLE); // z
|
|
|
|
wrapper.read(Type.BOOLEAN); // onGround
|
|
|
|
|
|
|
|
positionTracker.writeToPacket(wrapper);
|
|
|
|
if (levelStorage != null) levelStorage.tickChunks(positionTracker.getChunkPosition());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerServerbound(ServerboundPacketsa1_0_15.PLAYER_ROTATION, ServerboundPacketsc0_28.PLAYER_POSITION_AND_ROTATION, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
final ClassicPositionTracker positionTracker = wrapper.user().get(ClassicPositionTracker.class);
|
|
|
|
final ClassicLevelStorage levelStorage = wrapper.user().get(ClassicLevelStorage.class);
|
|
|
|
positionTracker.yaw = wrapper.read(Type.FLOAT); // yaw
|
|
|
|
positionTracker.pitch = wrapper.read(Type.FLOAT); // pitch
|
|
|
|
wrapper.read(Type.BOOLEAN); // onGround
|
|
|
|
|
|
|
|
positionTracker.writeToPacket(wrapper);
|
|
|
|
if (levelStorage != null) levelStorage.tickChunks(positionTracker.getChunkPosition());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerServerbound(ServerboundPacketsa1_0_15.PLAYER_POSITION_AND_ROTATION, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
final ClassicPositionTracker positionTracker = wrapper.user().get(ClassicPositionTracker.class);
|
|
|
|
final ClassicLevelStorage levelStorage = wrapper.user().get(ClassicLevelStorage.class);
|
|
|
|
positionTracker.posX = wrapper.read(Type.DOUBLE); // x
|
|
|
|
wrapper.read(Type.DOUBLE); // y
|
|
|
|
positionTracker.stance = wrapper.read(Type.DOUBLE); // stance
|
|
|
|
positionTracker.posZ = wrapper.read(Type.DOUBLE); // z
|
|
|
|
positionTracker.yaw = wrapper.read(Type.FLOAT); // yaw
|
|
|
|
positionTracker.pitch = wrapper.read(Type.FLOAT); // pitch
|
|
|
|
wrapper.read(Type.BOOLEAN); // onGround
|
|
|
|
|
|
|
|
positionTracker.writeToPacket(wrapper);
|
|
|
|
if (levelStorage != null) levelStorage.tickChunks(positionTracker.getChunkPosition());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerServerbound(ServerboundPacketsa1_0_15.PLAYER_DIGGING, ServerboundPacketsc0_28.PLAYER_BLOCK_PLACEMENT, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.user().getStoredObjects().remove(BlockDigStorage.class);
|
|
|
|
final ClassicLevel level = wrapper.user().get(ClassicLevelStorage.class).getClassicLevel();
|
|
|
|
final ClassicOpLevelStorage opTracker = wrapper.user().get(ClassicOpLevelStorage.class);
|
|
|
|
final boolean extendedVerification = wrapper.user().has(ExtBlockPermissionsStorage.class);
|
|
|
|
|
|
|
|
final short status = wrapper.read(Type.UNSIGNED_BYTE); // status
|
|
|
|
final Position pos = wrapper.read(Types1_7_6.POSITION_UBYTE); // position
|
|
|
|
wrapper.read(Type.UNSIGNED_BYTE); // direction
|
|
|
|
final int blockId = level.getBlock(pos);
|
|
|
|
|
|
|
|
final boolean hasCreative = wrapper.user().getProtocolInfo().getPipeline().contains(Protocolb1_8_0_1tob1_7_0_3.class);
|
|
|
|
if ((status == 0 && hasCreative) || (status == 2 && !hasCreative)) {
|
|
|
|
if (!extendedVerification && blockId == ClassicBlocks.BEDROCK && opTracker.getOpLevel() < 100) {
|
|
|
|
wrapper.cancel();
|
|
|
|
sendChatMessage(wrapper.user(), "§cOnly op players can break bedrock!");
|
|
|
|
sendBlockChange(wrapper.user(), pos, new IdAndData(BlockList1_6.bedrock.blockID, 0));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!extendedVerification) {
|
|
|
|
level.setBlock(pos, ClassicBlocks.AIR);
|
|
|
|
sendBlockChange(wrapper.user(), pos, new IdAndData(0, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapper.write(Typesc0_30.POSITION, pos); // position
|
|
|
|
wrapper.write(Type.BOOLEAN, false); // place block
|
|
|
|
wrapper.write(Type.BYTE, (byte) ClassicBlocks.STONE); // block id
|
|
|
|
} else {
|
|
|
|
wrapper.cancel();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2023-02-12 14:42:08 +01:00
|
|
|
this.registerServerbound(ServerboundPacketsa1_0_15.PLAYER_BLOCK_PLACEMENT, new PacketHandlers() {
|
2023-01-03 23:54:35 +01:00
|
|
|
@Override
|
2023-02-12 14:42:08 +01:00
|
|
|
public void register() {
|
2023-01-03 23:54:35 +01:00
|
|
|
handler(wrapper -> {
|
|
|
|
final ClassicLevel level = wrapper.user().get(ClassicLevelStorage.class).getClassicLevel();
|
|
|
|
final ClassicBlockRemapper remapper = wrapper.user().get(ClassicBlockRemapper.class);
|
|
|
|
final boolean extendedVerification = wrapper.user().has(ExtBlockPermissionsStorage.class);
|
|
|
|
|
|
|
|
wrapper.read(Type.SHORT); // item id (is useless because it has no item damage)
|
|
|
|
Position pos = wrapper.read(Types1_7_6.POSITION_UBYTE); // position
|
|
|
|
final short direction = wrapper.read(Type.UNSIGNED_BYTE); // direction
|
|
|
|
|
|
|
|
final Item item = Via.getManager().getProviders().get(AlphaInventoryProvider.class).getHandItem(wrapper.user());
|
|
|
|
if (item == null || direction == 255) {
|
|
|
|
wrapper.cancel();
|
|
|
|
return;
|
|
|
|
}
|
2023-01-10 21:53:22 +01:00
|
|
|
pos = pos.getRelative(BlockFaceUtil.getFace(direction));
|
2023-01-03 23:54:35 +01:00
|
|
|
|
|
|
|
if (pos.y() >= level.getSizeY()) {
|
|
|
|
wrapper.cancel();
|
|
|
|
sendChatMessage(wrapper.user(), "§cHeight limit for building is " + level.getSizeY() + " blocks");
|
|
|
|
sendBlockChange(wrapper.user(), pos, new IdAndData(0, 0));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final byte classicBlock = (byte) remapper.getReverseMapper().getInt(new IdAndData(item.identifier(), item.data() & 15));
|
|
|
|
|
|
|
|
if (!extendedVerification) {
|
|
|
|
level.setBlock(pos, classicBlock);
|
|
|
|
sendBlockChange(wrapper.user(), pos, remapper.getMapper().get(classicBlock));
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapper.write(Typesc0_30.POSITION, pos); // position
|
|
|
|
wrapper.write(Type.BOOLEAN, true); // place block
|
|
|
|
wrapper.write(Type.BYTE, classicBlock); // block id
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.cancelServerbound(ServerboundPacketsa1_0_15.KEEP_ALIVE);
|
|
|
|
this.cancelServerbound(ServerboundPacketsa1_0_15.HELD_ITEM_CHANGE);
|
|
|
|
this.cancelServerbound(ServerboundPacketsa1_0_15.ANIMATION);
|
|
|
|
this.cancelServerbound(ServerboundPacketsa1_0_15.SPAWN_ITEM);
|
|
|
|
this.cancelServerbound(ServerboundPacketsa1_0_15.DISCONNECT);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void sendChatMessage(final UserConnection user, final String msg) throws Exception {
|
|
|
|
final PacketWrapper message = PacketWrapper.create(ClientboundPacketsa1_0_15.CHAT_MESSAGE, user);
|
|
|
|
message.write(Typesb1_7_0_3.STRING, msg); // message
|
|
|
|
message.send(Protocola1_0_15toc0_30.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void sendBlockChange(final UserConnection user, final Position pos, final IdAndData block) throws Exception {
|
|
|
|
final PacketWrapper blockChange = PacketWrapper.create(ClientboundPacketsa1_0_15.BLOCK_CHANGE, user);
|
|
|
|
blockChange.write(Types1_7_6.POSITION_UBYTE, pos); // position
|
|
|
|
blockChange.write(Type.UNSIGNED_BYTE, (short) block.id); // block id
|
|
|
|
blockChange.write(Type.UNSIGNED_BYTE, (short) block.data); // block data
|
|
|
|
blockChange.send(Protocola1_0_15toc0_30.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void register(ViaProviders providers) {
|
|
|
|
providers.register(ClassicWorldHeightProvider.class, new ClassicWorldHeightProvider());
|
|
|
|
providers.register(ClassicMPPassProvider.class, new ClassicMPPassProvider());
|
|
|
|
providers.register(ClassicCustomCommandProvider.class, new ClassicCustomCommandProvider());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void init(UserConnection userConnection) {
|
|
|
|
userConnection.put(new PreNettySplitter(userConnection, Protocola1_0_15toc0_30.class, ClientboundPacketsc0_28::getPacket));
|
|
|
|
|
|
|
|
userConnection.put(new ClassicPositionTracker(userConnection));
|
|
|
|
userConnection.put(new ClassicOpLevelStorage(userConnection));
|
|
|
|
userConnection.put(new ClassicProgressStorage(userConnection));
|
|
|
|
userConnection.put(new ClassicBlockRemapper(userConnection, i -> ClassicBlocks.MAPPING.get(i), o -> {
|
|
|
|
int block = ClassicBlocks.REVERSE_MAPPING.getInt(o);
|
|
|
|
|
2023-01-10 21:53:22 +01:00
|
|
|
if (!userConnection.getProtocolInfo().getPipeline().contains(Protocolc0_30toc0_30cpe.class)) {
|
2023-01-03 23:54:35 +01:00
|
|
|
if (block == ClassicBlocks.GRASS) block = ClassicBlocks.DIRT;
|
|
|
|
else if (block == ClassicBlocks.BEDROCK) block = ClassicBlocks.STONE;
|
|
|
|
else if (block == ClassicBlocks.STATIONARY_WATER) block = ClassicBlocks.BLUE_WOOL;
|
|
|
|
else if (block == ClassicBlocks.STATIONARY_LAVA) block = ClassicBlocks.ORANGE_WOOL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}));
|
|
|
|
|
|
|
|
if (userConnection.has(AlphaInventoryTracker.class)) userConnection.get(AlphaInventoryTracker.class).setCreativeMode(true);
|
|
|
|
if (userConnection.has(TimeLockStorage.class)) userConnection.get(TimeLockStorage.class).setTime(6000L);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|