2021-03-22 23:06:40 +01:00
|
|
|
/*
|
|
|
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
|
|
|
* Copyright (C) 2016-2021 ViaVersion 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/>.
|
|
|
|
*/
|
2021-04-26 21:16:10 +02:00
|
|
|
package com.viaversion.viaversion.rewriter;
|
2019-10-04 13:01:33 +02:00
|
|
|
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.api.data.ParticleMappings;
|
|
|
|
import com.viaversion.viaversion.api.minecraft.item.Item;
|
|
|
|
import com.viaversion.viaversion.api.protocol.Protocol;
|
2021-04-27 13:41:39 +02:00
|
|
|
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
2021-04-26 21:16:10 +02:00
|
|
|
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
|
2021-06-04 12:15:14 +02:00
|
|
|
import com.viaversion.viaversion.api.rewriter.RewriterBase;
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.api.type.Type;
|
2021-06-04 12:15:14 +02:00
|
|
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
2019-10-04 13:01:33 +02:00
|
|
|
|
2021-06-04 12:15:14 +02:00
|
|
|
public abstract class ItemRewriter<T extends Protocol> extends RewriterBase<T> implements com.viaversion.viaversion.api.rewriter.ItemRewriter<T> {
|
2019-10-04 13:01:33 +02:00
|
|
|
|
2021-06-04 12:15:14 +02:00
|
|
|
public ItemRewriter(T protocol) {
|
|
|
|
super(protocol);
|
|
|
|
}
|
|
|
|
|
|
|
|
// These two methods always return the same item instance *for now*
|
|
|
|
// It is made this way so it's easy to handle new instance creation/implementation changes
|
|
|
|
@Override
|
|
|
|
public @Nullable Item handleItemToClient(@Nullable Item item) {
|
|
|
|
if (item == null) return null;
|
|
|
|
if (protocol.getMappingData() != null && protocol.getMappingData().getItemMappings() != null) {
|
|
|
|
item.setIdentifier(protocol.getMappingData().getNewItemId(item.identifier()));
|
|
|
|
}
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public @Nullable Item handleItemToServer(@Nullable Item item) {
|
|
|
|
if (item == null) return null;
|
|
|
|
if (protocol.getMappingData() != null && protocol.getMappingData().getItemMappings() != null) {
|
|
|
|
item.setIdentifier(protocol.getMappingData().getOldItemId(item.identifier()));
|
|
|
|
}
|
|
|
|
return item;
|
2019-10-04 13:01:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-05 23:06:00 +02:00
|
|
|
public void registerWindowItems(ClientboundPacketType packetType, Type<Item[]> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2019-10-04 13:01:33 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.UNSIGNED_BYTE); // 0 - Window ID
|
|
|
|
map(type); // 1 - Window Values
|
|
|
|
|
|
|
|
handler(itemArrayHandler(type));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-05 23:06:00 +02:00
|
|
|
public void registerSetSlot(ClientboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2019-10-04 13:01:33 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.BYTE); // 0 - Window ID
|
|
|
|
map(Type.SHORT); // 1 - Slot ID
|
|
|
|
map(type); // 2 - Slot Value
|
|
|
|
|
|
|
|
handler(itemToClientHandler(type));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-16 18:38:16 +02:00
|
|
|
// Sub 1.16
|
2020-06-05 23:06:00 +02:00
|
|
|
public void registerEntityEquipment(ClientboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2019-10-04 13:01:33 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.VAR_INT); // 0 - Entity ID
|
|
|
|
map(Type.VAR_INT); // 1 - Slot ID
|
|
|
|
map(type); // 2 - Item
|
|
|
|
|
|
|
|
handler(itemToClientHandler(type));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-16 18:38:16 +02:00
|
|
|
// 1.16+
|
|
|
|
public void registerEntityEquipmentArray(ClientboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2020-06-16 18:38:16 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.VAR_INT); // 0 - Entity ID
|
|
|
|
|
|
|
|
handler(wrapper -> {
|
|
|
|
byte slot;
|
|
|
|
do {
|
2020-06-16 21:04:29 +02:00
|
|
|
slot = wrapper.passthrough(Type.BYTE);
|
2020-07-02 00:18:33 +02:00
|
|
|
// & 0x7F into an extra variable if slot is needed
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToClient(wrapper.passthrough(type));
|
2020-06-16 18:38:16 +02:00
|
|
|
} while ((slot & 0xFFFFFF80) != 0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-05 23:06:00 +02:00
|
|
|
public void registerCreativeInvAction(ServerboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerServerbound(packetType, new PacketRemapper() {
|
2019-10-04 13:01:33 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.SHORT); // 0 - Slot
|
|
|
|
map(type); // 1 - Clicked Item
|
|
|
|
|
|
|
|
handler(itemToServerHandler(type));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-05 23:06:00 +02:00
|
|
|
public void registerClickWindow(ServerboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerServerbound(packetType, new PacketRemapper() {
|
2019-10-04 13:01:33 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.UNSIGNED_BYTE); // 0 - Window ID
|
|
|
|
map(Type.SHORT); // 1 - Slot
|
|
|
|
map(Type.BYTE); // 2 - Button
|
|
|
|
map(Type.SHORT); // 3 - Action number
|
|
|
|
map(Type.VAR_INT); // 4 - Mode
|
|
|
|
map(type); // 5 - Clicked Item
|
|
|
|
|
|
|
|
handler(itemToServerHandler(type));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-03-10 17:55:50 +01:00
|
|
|
public void registerClickWindow1_17(ServerboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerServerbound(packetType, new PacketRemapper() {
|
2021-03-10 17:55:50 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.UNSIGNED_BYTE); // Window Id
|
|
|
|
map(Type.SHORT); // Slot
|
|
|
|
map(Type.BYTE); // Button
|
|
|
|
map(Type.VAR_INT); // Mode
|
|
|
|
|
|
|
|
handler(wrapper -> {
|
|
|
|
// Affected items
|
|
|
|
int length = wrapper.passthrough(Type.VAR_INT);
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
wrapper.passthrough(Type.SHORT); // Slot
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToServer(wrapper.passthrough(type));
|
2021-03-10 17:55:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Carried item
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToServer(wrapper.passthrough(type));
|
2021-03-10 17:55:50 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-08-16 16:24:06 +02:00
|
|
|
public void registerSetCooldown(ClientboundPacketType packetType) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2019-11-27 12:56:20 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(wrapper -> {
|
|
|
|
int itemId = wrapper.read(Type.VAR_INT);
|
2020-08-16 16:24:06 +02:00
|
|
|
wrapper.write(Type.VAR_INT, protocol.getMappingData().getNewItemId(itemId));
|
2019-11-27 12:56:20 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-07-02 00:18:33 +02:00
|
|
|
// 1.14.4+
|
|
|
|
public void registerTradeList(ClientboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2020-07-02 00:18:33 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.passthrough(Type.VAR_INT);
|
|
|
|
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
|
|
|
|
for (int i = 0; i < size; i++) {
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToClient(wrapper.passthrough(type)); // Input
|
|
|
|
handleItemToClient(wrapper.passthrough(type)); // Output
|
2020-07-02 00:18:33 +02:00
|
|
|
|
|
|
|
if (wrapper.passthrough(Type.BOOLEAN)) { // Has second item
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToClient(wrapper.passthrough(type)); // Second Item
|
2020-07-02 00:18:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
|
|
|
|
wrapper.passthrough(Type.INT); // Number of tools uses
|
|
|
|
wrapper.passthrough(Type.INT); // Maximum number of trade uses
|
|
|
|
|
|
|
|
wrapper.passthrough(Type.INT); // XP
|
|
|
|
wrapper.passthrough(Type.INT); // Special price
|
|
|
|
wrapper.passthrough(Type.FLOAT); // Price multiplier
|
|
|
|
wrapper.passthrough(Type.INT); // Demand
|
|
|
|
}
|
|
|
|
//...
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void registerAdvancements(ClientboundPacketType packetType, Type<Item> type) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2020-07-02 00:18:33 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(wrapper -> {
|
|
|
|
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
|
|
|
|
int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
wrapper.passthrough(Type.STRING); // Identifier
|
|
|
|
|
|
|
|
// Parent
|
|
|
|
if (wrapper.passthrough(Type.BOOLEAN))
|
|
|
|
wrapper.passthrough(Type.STRING);
|
|
|
|
|
|
|
|
// Display data
|
|
|
|
if (wrapper.passthrough(Type.BOOLEAN)) {
|
|
|
|
wrapper.passthrough(Type.COMPONENT); // Title
|
|
|
|
wrapper.passthrough(Type.COMPONENT); // Description
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToClient(wrapper.passthrough(type)); // Icon
|
2020-07-02 00:18:33 +02:00
|
|
|
wrapper.passthrough(Type.VAR_INT); // Frame type
|
|
|
|
int flags = wrapper.passthrough(Type.INT); // Flags
|
|
|
|
if ((flags & 1) != 0) {
|
|
|
|
wrapper.passthrough(Type.STRING); // Background texture
|
|
|
|
}
|
|
|
|
wrapper.passthrough(Type.FLOAT); // X
|
|
|
|
wrapper.passthrough(Type.FLOAT); // Y
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapper.passthrough(Type.STRING_ARRAY); // Criteria
|
|
|
|
|
|
|
|
int arrayLength = wrapper.passthrough(Type.VAR_INT);
|
|
|
|
for (int array = 0; array < arrayLength; array++) {
|
|
|
|
wrapper.passthrough(Type.STRING_ARRAY); // String array
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-09-21 09:53:04 +02:00
|
|
|
// Not the very best place for this, but has to stay here until *everything* is abstracted
|
|
|
|
public void registerSpawnParticle(ClientboundPacketType packetType, Type<Item> itemType, Type<?> coordType) {
|
2021-04-28 12:59:37 +02:00
|
|
|
protocol.registerClientbound(packetType, new PacketRemapper() {
|
2020-09-21 09:53:04 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.INT); // 0 - Particle ID
|
|
|
|
map(Type.BOOLEAN); // 1 - Long Distance
|
|
|
|
map(coordType); // 2 - X
|
|
|
|
map(coordType); // 3 - Y
|
|
|
|
map(coordType); // 4 - Z
|
|
|
|
map(Type.FLOAT); // 5 - Offset X
|
|
|
|
map(Type.FLOAT); // 6 - Offset Y
|
|
|
|
map(Type.FLOAT); // 7 - Offset Z
|
|
|
|
map(Type.FLOAT); // 8 - Particle Data
|
|
|
|
map(Type.INT); // 9 - Particle Count
|
2020-12-17 11:51:51 +01:00
|
|
|
handler(getSpawnParticleHandler(itemType));
|
2020-09-21 09:53:04 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-12-17 11:51:51 +01:00
|
|
|
public PacketHandler getSpawnParticleHandler(Type<Item> itemType) {
|
2020-12-09 11:03:40 +01:00
|
|
|
return wrapper -> {
|
|
|
|
int id = wrapper.get(Type.INT, 0);
|
|
|
|
if (id == -1) return;
|
|
|
|
|
|
|
|
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
|
|
|
|
if (id == mappings.getBlockId() || id == mappings.getFallingDustId()) {
|
|
|
|
int data = wrapper.passthrough(Type.VAR_INT);
|
|
|
|
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(data));
|
|
|
|
} else if (id == mappings.getItemId()) {
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToClient(wrapper.passthrough(itemType));
|
2020-12-09 11:03:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int newId = protocol.getMappingData().getNewParticleId(id);
|
|
|
|
if (newId != id) {
|
|
|
|
wrapper.set(Type.INT, 0, newId);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-10-04 13:01:33 +02:00
|
|
|
// Only sent to the client
|
|
|
|
public PacketHandler itemArrayHandler(Type<Item[]> type) {
|
|
|
|
return wrapper -> {
|
|
|
|
Item[] items = wrapper.get(type, 0);
|
|
|
|
for (Item item : items) {
|
2021-06-04 12:15:14 +02:00
|
|
|
handleItemToClient(item);
|
2019-10-04 13:01:33 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
public PacketHandler itemToClientHandler(Type<Item> type) {
|
2021-06-04 12:15:14 +02:00
|
|
|
return wrapper -> handleItemToClient(wrapper.get(type, 0));
|
2019-10-04 13:01:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public PacketHandler itemToServerHandler(Type<Item> type) {
|
2021-06-04 12:15:14 +02:00
|
|
|
return wrapper -> handleItemToServer(wrapper.get(type, 0));
|
2019-10-04 13:01:33 +02:00
|
|
|
}
|
|
|
|
}
|