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 20:52:34 +02:00
|
|
|
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2;
|
2018-07-18 19:10:43 +02:00
|
|
|
|
2020-06-25 09:57:26 +02:00
|
|
|
import com.google.common.collect.Sets;
|
2020-08-16 10:18:08 +02:00
|
|
|
import com.google.common.primitives.Ints;
|
2018-07-21 02:51:07 +02:00
|
|
|
import com.google.gson.JsonObject;
|
|
|
|
import com.google.gson.JsonParseException;
|
2021-04-26 21:16:10 +02:00
|
|
|
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.api.Via;
|
2021-04-26 21:35:29 +02:00
|
|
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
2021-04-26 21:16:10 +02:00
|
|
|
import com.viaversion.viaversion.api.minecraft.entities.Entity1_13Types;
|
2021-04-26 20:52:34 +02:00
|
|
|
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.Protocol;
|
2021-04-26 21:16:10 +02:00
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
|
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.ValueCreator;
|
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
|
|
|
|
import com.viaversion.viaversion.rewriter.MetadataRewriter;
|
|
|
|
import com.viaversion.viaversion.rewriter.SoundRewriter;
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.api.type.Type;
|
2021-04-26 21:16:10 +02:00
|
|
|
import com.viaversion.viaversion.api.protocol.packet.State;
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers.PacketBlockConnectionProvider;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.BlockIdData;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.MappingData;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.RecipeData;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.StatisticData;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.StatisticMappings;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.metadata.MetadataRewriter1_13To1_12_2;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.EntityPackets;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.WorldPackets;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PaintingProvider;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockConnectionStorage;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.EntityTracker1_13;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.TabCompleteTracker;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
|
|
|
import com.viaversion.viaversion.util.ChatColorUtil;
|
|
|
|
import com.viaversion.viaversion.util.GsonUtil;
|
2018-07-18 19:10:43 +02:00
|
|
|
|
2020-08-16 16:24:06 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
2018-07-18 19:10:43 +02:00
|
|
|
|
2020-06-06 09:45:43 +02:00
|
|
|
public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, ClientboundPackets1_13, ServerboundPackets1_12_1, ServerboundPackets1_13> {
|
2018-07-18 19:10:43 +02:00
|
|
|
|
2020-08-16 16:24:06 +02:00
|
|
|
public static final MappingData MAPPINGS = new MappingData();
|
2020-11-23 17:28:07 +01:00
|
|
|
// These are arbitrary rewrite values, it just needs an invalid color code character.
|
|
|
|
private static final Map<Character, Character> SCOREBOARD_TEAM_NAME_REWRITE = new HashMap<>();
|
|
|
|
private static final Set<Character> FORMATTING_CODES = Sets.newHashSet('k', 'l', 'm', 'n', 'o', 'r');
|
|
|
|
|
|
|
|
static {
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('0', 'g');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('1', 'h');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('2', 'i');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('3', 'j');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('4', 'p');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('5', 'q');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('6', 's');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('7', 't');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('8', 'u');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('9', 'v');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('a', 'w');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('b', 'x');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('c', 'y');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('d', 'z');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('e', '!');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('f', '?');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('k', '#');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('l', '(');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('m', ')');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('n', ':');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('o', ';');
|
|
|
|
SCOREBOARD_TEAM_NAME_REWRITE.put('r', '/');
|
|
|
|
}
|
2020-08-16 16:24:06 +02:00
|
|
|
|
2020-03-23 01:23:17 +01:00
|
|
|
public Protocol1_13To1_12_2() {
|
2020-08-16 16:24:06 +02:00
|
|
|
super(ClientboundPackets1_12_1.class, ClientboundPackets1_13.class, ServerboundPackets1_12_1.class, ServerboundPackets1_13.class);
|
2020-03-23 01:23:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public static final PacketHandler POS_TO_3_INT = wrapper -> {
|
|
|
|
Position position = wrapper.read(Type.POSITION);
|
|
|
|
wrapper.write(Type.INT, position.getX());
|
2020-12-03 11:14:46 +01:00
|
|
|
wrapper.write(Type.INT, position.getY());
|
2020-03-23 01:23:17 +01:00
|
|
|
wrapper.write(Type.INT, position.getZ());
|
2018-07-18 19:10:43 +02:00
|
|
|
};
|
|
|
|
|
2020-08-16 16:24:06 +02:00
|
|
|
private static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS =
|
|
|
|
w -> {
|
|
|
|
// Send fake declare commands
|
|
|
|
w.create(0x11, new ValueCreator() {
|
|
|
|
@Override
|
|
|
|
public void write(PacketWrapper wrapper) {
|
|
|
|
wrapper.write(Type.VAR_INT, 2); // Size
|
|
|
|
// Write root node
|
2021-02-05 12:18:28 +01:00
|
|
|
wrapper.write(Type.BYTE, (byte) 0); // Mark as command
|
2021-04-02 14:15:30 +02:00
|
|
|
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{1}); // 1 child at index 1
|
2020-08-16 16:24:06 +02:00
|
|
|
|
|
|
|
// Write arg node
|
2021-02-05 12:18:28 +01:00
|
|
|
wrapper.write(Type.BYTE, (byte) (0x02 | 0x04 | 0x10)); // Mark as command
|
|
|
|
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[0]); // No children
|
2020-08-16 16:24:06 +02:00
|
|
|
// Extra data
|
|
|
|
wrapper.write(Type.STRING, "args"); // Arg name
|
|
|
|
wrapper.write(Type.STRING, "brigadier:string");
|
|
|
|
wrapper.write(Type.VAR_INT, 2); // Greedy
|
|
|
|
wrapper.write(Type.STRING, "minecraft:ask_server"); // Ask server
|
|
|
|
|
|
|
|
wrapper.write(Type.VAR_INT, 0); // Root node index
|
|
|
|
}
|
|
|
|
}).send(Protocol1_13To1_12_2.class);
|
|
|
|
|
|
|
|
// Send tags packet
|
|
|
|
w.create(0x55, new ValueCreator() {
|
|
|
|
@Override
|
|
|
|
public void write(PacketWrapper wrapper) throws Exception {
|
|
|
|
wrapper.write(Type.VAR_INT, MAPPINGS.getBlockTags().size()); // block tags
|
|
|
|
for (Map.Entry<String, Integer[]> tag : MAPPINGS.getBlockTags().entrySet()) {
|
|
|
|
wrapper.write(Type.STRING, tag.getKey());
|
|
|
|
// Needs copy as other protocols may modify it
|
|
|
|
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
|
2018-11-04 11:56:22 +01:00
|
|
|
}
|
2020-08-16 16:24:06 +02:00
|
|
|
wrapper.write(Type.VAR_INT, MAPPINGS.getItemTags().size()); // item tags
|
|
|
|
for (Map.Entry<String, Integer[]> tag : MAPPINGS.getItemTags().entrySet()) {
|
|
|
|
wrapper.write(Type.STRING, tag.getKey());
|
|
|
|
// Needs copy as other protocols may modify it
|
|
|
|
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
|
2018-11-04 11:56:22 +01:00
|
|
|
}
|
2020-08-16 16:24:06 +02:00
|
|
|
wrapper.write(Type.VAR_INT, MAPPINGS.getFluidTags().size()); // fluid tags
|
|
|
|
for (Map.Entry<String, Integer[]> tag : MAPPINGS.getFluidTags().entrySet()) {
|
|
|
|
wrapper.write(Type.STRING, tag.getKey());
|
|
|
|
// Needs copy as other protocols may modify it
|
|
|
|
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).send(Protocol1_13To1_12_2.class);
|
2018-11-04 11:56:22 +01:00
|
|
|
};
|
2018-07-18 19:10:43 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void registerPackets() {
|
2020-08-16 16:24:06 +02:00
|
|
|
MetadataRewriter metadataRewriter = new MetadataRewriter1_13To1_12_2(this);
|
2019-05-09 14:43:48 +02:00
|
|
|
|
2018-07-18 19:10:43 +02:00
|
|
|
// Register grouped packet changes
|
|
|
|
EntityPackets.register(this);
|
|
|
|
WorldPackets.register(this);
|
|
|
|
InventoryPackets.register(this);
|
|
|
|
|
2018-11-08 19:10:45 +01:00
|
|
|
registerOutgoing(State.LOGIN, 0x0, 0x0, new PacketRemapper() {
|
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-25 16:22:53 +02:00
|
|
|
handler(wrapper -> ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT)));
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-07-21 02:51:07 +02:00
|
|
|
registerOutgoing(State.STATUS, 0x00, 0x00, new PacketRemapper() {
|
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.STRING);
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
String response = wrapper.get(Type.STRING, 0);
|
|
|
|
try {
|
|
|
|
JsonObject json = GsonUtil.getGson().fromJson(response, JsonObject.class);
|
|
|
|
if (json.has("favicon")) {
|
|
|
|
json.addProperty("favicon", json.get("favicon").getAsString().replace("\n", ""));
|
|
|
|
}
|
|
|
|
wrapper.set(Type.STRING, 0, GsonUtil.getGson().toJson(json));
|
|
|
|
} catch (JsonParseException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-07-18 19:10:43 +02:00
|
|
|
// New packet 0x04 - Login Plugin Message
|
|
|
|
|
|
|
|
// Statistics
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.STATISTICS, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
2020-08-12 16:39:01 +02:00
|
|
|
int size = wrapper.read(Type.VAR_INT);
|
2020-08-12 17:16:50 +02:00
|
|
|
List<StatisticData> remappedStats = new ArrayList<>();
|
2020-01-15 21:51:33 +01:00
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
String name = wrapper.read(Type.STRING);
|
|
|
|
String[] split = name.split("\\.");
|
|
|
|
int categoryId = 0;
|
2020-08-12 16:39:01 +02:00
|
|
|
int newId = -1;
|
|
|
|
int value = wrapper.read(Type.VAR_INT);
|
2020-01-15 21:51:33 +01:00
|
|
|
if (split.length == 2) {
|
|
|
|
// Custom types
|
|
|
|
categoryId = 8;
|
2020-08-12 16:39:01 +02:00
|
|
|
Integer newIdRaw = StatisticMappings.CUSTOM_STATS.get(name);
|
2020-01-15 21:51:33 +01:00
|
|
|
if (newIdRaw != null) {
|
|
|
|
newId = newIdRaw;
|
2020-08-12 16:39:01 +02:00
|
|
|
} else {
|
|
|
|
Via.getPlatform().getLogger().warning("Could not find 1.13 -> 1.12.2 statistic mapping for " + name);
|
2020-01-15 21:51:33 +01:00
|
|
|
}
|
2020-12-11 02:08:34 +01:00
|
|
|
} else if (split.length > 2) {
|
2020-01-15 21:51:33 +01:00
|
|
|
String category = split[1];
|
|
|
|
//TODO convert string ids (blocks, items, entities)
|
|
|
|
switch (category) {
|
|
|
|
case "mineBlock":
|
|
|
|
categoryId = 0;
|
|
|
|
break;
|
|
|
|
case "craftItem":
|
|
|
|
categoryId = 1;
|
|
|
|
break;
|
|
|
|
case "useItem":
|
|
|
|
categoryId = 2;
|
|
|
|
break;
|
|
|
|
case "breakItem":
|
|
|
|
categoryId = 3;
|
|
|
|
break;
|
|
|
|
case "pickup":
|
|
|
|
categoryId = 4;
|
|
|
|
break;
|
|
|
|
case "drop":
|
|
|
|
categoryId = 5;
|
|
|
|
break;
|
|
|
|
case "killEntity":
|
|
|
|
categoryId = 6;
|
|
|
|
break;
|
|
|
|
case "entityKilledBy":
|
|
|
|
categoryId = 7;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-08-12 16:39:01 +02:00
|
|
|
if (newId != -1)
|
2020-08-12 17:16:50 +02:00
|
|
|
remappedStats.add(new StatisticData(categoryId, newId, value));
|
2020-08-12 16:39:01 +02:00
|
|
|
}
|
2020-01-15 21:51:33 +01:00
|
|
|
|
2020-08-12 16:39:01 +02:00
|
|
|
wrapper.write(Type.VAR_INT, remappedStats.size()); // size
|
2020-08-12 17:16:50 +02:00
|
|
|
for (StatisticData stat : remappedStats) {
|
|
|
|
wrapper.write(Type.VAR_INT, stat.getCategoryId()); // category id
|
|
|
|
wrapper.write(Type.VAR_INT, stat.getNewId()); // statistics id
|
|
|
|
wrapper.write(Type.VAR_INT, stat.getValue()); // value
|
2020-01-15 21:51:33 +01:00
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.BOSSBAR, new PacketRemapper() {
|
2018-11-08 19:10:45 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.UUID);
|
|
|
|
map(Type.VAR_INT);
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
int action = wrapper.get(Type.VAR_INT, 0);
|
|
|
|
if (action == 0 || action == 3) {
|
2020-06-25 16:22:53 +02:00
|
|
|
ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT));
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.CHAT_MESSAGE, new PacketRemapper() {
|
2018-11-08 19:10:45 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-25 16:22:53 +02:00
|
|
|
handler(wrapper -> ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT)));
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.TAB_COMPLETE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
create(new ValueCreator() {
|
|
|
|
@Override
|
|
|
|
public void write(PacketWrapper wrapper) throws Exception {
|
|
|
|
wrapper.write(Type.VAR_INT, wrapper.user().get(TabCompleteTracker.class).getTransactionId());
|
|
|
|
|
|
|
|
String input = wrapper.user().get(TabCompleteTracker.class).getInput();
|
|
|
|
// Start & End
|
|
|
|
int index;
|
|
|
|
int length;
|
|
|
|
// If no input or new word (then it's the start)
|
2020-04-27 14:41:57 +02:00
|
|
|
if (input.endsWith(" ") || input.isEmpty()) {
|
2018-07-18 19:10:43 +02:00
|
|
|
index = input.length();
|
|
|
|
length = 0;
|
|
|
|
} else {
|
|
|
|
// Otherwise find the last space (+1 as we include it)
|
2020-04-27 14:41:57 +02:00
|
|
|
int lastSpace = input.lastIndexOf(' ') + 1;
|
2018-07-18 19:10:43 +02:00
|
|
|
index = lastSpace;
|
|
|
|
length = input.length() - lastSpace;
|
|
|
|
}
|
|
|
|
// Write index + length
|
|
|
|
wrapper.write(Type.VAR_INT, index);
|
|
|
|
wrapper.write(Type.VAR_INT, length);
|
|
|
|
|
|
|
|
int count = wrapper.passthrough(Type.VAR_INT);
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
String suggestion = wrapper.read(Type.STRING);
|
|
|
|
// If we're at the start then handle removing slash
|
|
|
|
if (suggestion.startsWith("/") && index == 0) {
|
|
|
|
suggestion = suggestion.substring(1);
|
|
|
|
}
|
|
|
|
wrapper.write(Type.STRING, suggestion);
|
|
|
|
wrapper.write(Type.BOOLEAN, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.OPEN_WINDOW, new PacketRemapper() {
|
2018-11-08 19:10:45 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.UNSIGNED_BYTE); // Id
|
|
|
|
map(Type.STRING); // Window type
|
2020-06-25 16:22:53 +02:00
|
|
|
handler(wrapper -> ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT))); // Title
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
});
|
2020-02-08 21:33:44 +01:00
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.COOLDOWN, new PacketRemapper() {
|
2018-11-10 11:41:22 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
int item = wrapper.read(Type.VAR_INT);
|
|
|
|
int ticks = wrapper.read(Type.VAR_INT);
|
|
|
|
wrapper.cancel();
|
|
|
|
if (item == 383) { // Spawn egg
|
|
|
|
for (int i = 0; i < 44; i++) {
|
2020-08-16 16:24:06 +02:00
|
|
|
Integer newItem = getMappingData().getItemMappings().get(item << 16 | i);
|
2018-11-10 11:41:22 +01:00
|
|
|
if (newItem != null) {
|
|
|
|
PacketWrapper packet = wrapper.create(0x18);
|
|
|
|
packet.write(Type.VAR_INT, newItem);
|
|
|
|
packet.write(Type.VAR_INT, ticks);
|
|
|
|
packet.send(Protocol1_13To1_12_2.class);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < 16; i++) {
|
2020-08-16 16:24:06 +02:00
|
|
|
int newItem = getMappingData().getItemMappings().get(item << 4 | i);
|
2020-06-08 23:54:24 +02:00
|
|
|
if (newItem != -1) {
|
2018-11-10 11:41:22 +01:00
|
|
|
PacketWrapper packet = wrapper.create(0x18);
|
|
|
|
packet.write(Type.VAR_INT, newItem);
|
|
|
|
packet.write(Type.VAR_INT, ticks);
|
|
|
|
packet.send(Protocol1_13To1_12_2.class);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
|
|
|
|
registerOutgoing(ClientboundPackets1_12_1.DISCONNECT, new PacketRemapper() {
|
2018-11-08 19:10:45 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-25 16:22:53 +02:00
|
|
|
handler(wrapper -> ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT)));
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
|
|
|
|
registerOutgoing(ClientboundPackets1_12_1.EFFECT, new PacketRemapper() {
|
2018-07-22 20:15:40 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.INT); // Effect Id
|
|
|
|
map(Type.POSITION); // Location
|
|
|
|
map(Type.INT); // Data
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
int id = wrapper.get(Type.INT, 0);
|
|
|
|
int data = wrapper.get(Type.INT, 1);
|
|
|
|
if (id == 1010) { // Play record
|
2020-08-16 16:24:06 +02:00
|
|
|
wrapper.set(Type.INT, 1, getMappingData().getItemMappings().get(data << 4));
|
2018-07-22 20:15:40 +02:00
|
|
|
} else if (id == 2001) { // Block break + block break sound
|
2018-07-24 15:55:08 +02:00
|
|
|
int blockId = data & 0xFFF;
|
2018-07-22 21:24:38 +02:00
|
|
|
int blockData = data >> 12;
|
2019-05-27 18:50:08 +02:00
|
|
|
wrapper.set(Type.INT, 1, WorldPackets.toNewId(blockId << 4 | blockData));
|
2018-07-22 20:15:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.JOIN_GAME, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.INT); // 0 - Entity ID
|
|
|
|
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
|
|
|
|
map(Type.INT); // 2 - Dimension
|
|
|
|
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
// Store the player
|
|
|
|
int entityId = wrapper.get(Type.INT, 0);
|
2019-05-08 12:14:41 +02:00
|
|
|
wrapper.user().get(EntityTracker1_13.class).addEntity(entityId, Entity1_13Types.EntityType.PLAYER);
|
2018-07-18 19:10:43 +02:00
|
|
|
|
|
|
|
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
|
|
|
|
int dimensionId = wrapper.get(Type.INT, 1);
|
|
|
|
clientChunks.setEnvironment(dimensionId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
handler(SEND_DECLARE_COMMANDS_AND_TAGS);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
|
|
|
|
registerOutgoing(ClientboundPackets1_12_1.CRAFT_RECIPE_RESPONSE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2018-12-10 13:11:56 +01:00
|
|
|
map(Type.BYTE);
|
2020-06-05 22:33:48 +02:00
|
|
|
handler(wrapper -> wrapper.write(Type.STRING, "viaversion:legacy/" + wrapper.read(Type.VAR_INT)));
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.COMBAT_EVENT, new PacketRemapper() {
|
2018-11-08 19:10:45 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.VAR_INT); // Event
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
if (wrapper.get(Type.VAR_INT, 0) == 2) { // Entity dead
|
|
|
|
wrapper.passthrough(Type.VAR_INT); // Player id
|
|
|
|
wrapper.passthrough(Type.INT); // Entity id
|
2020-06-25 16:22:53 +02:00
|
|
|
ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
registerOutgoing(ClientboundPackets1_12_1.MAP_DATA, new PacketRemapper() {
|
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.VAR_INT); // 0 - Map id
|
|
|
|
map(Type.BYTE); // 1 - Scale
|
|
|
|
map(Type.BOOLEAN); // 2 - Tracking Position
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
int iconCount = wrapper.passthrough(Type.VAR_INT);
|
|
|
|
for (int i = 0; i < iconCount; i++) {
|
|
|
|
byte directionAndType = wrapper.read(Type.BYTE);
|
|
|
|
int type = (directionAndType & 0xF0) >> 4;
|
|
|
|
wrapper.write(Type.VAR_INT, type);
|
|
|
|
wrapper.passthrough(Type.BYTE); // Icon X
|
|
|
|
wrapper.passthrough(Type.BYTE); // Icon Z
|
|
|
|
byte direction = (byte) (directionAndType & 0x0F);
|
|
|
|
wrapper.write(Type.BYTE, direction);
|
|
|
|
wrapper.write(Type.OPTIONAL_COMPONENT, null); // Display Name
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.UNLOCK_RECIPES, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2018-12-10 13:11:56 +01:00
|
|
|
map(Type.VAR_INT); // action
|
|
|
|
map(Type.BOOLEAN); // crafting book open
|
|
|
|
map(Type.BOOLEAN); // crafting filter active
|
|
|
|
create(new ValueCreator() {
|
|
|
|
@Override
|
|
|
|
public void write(PacketWrapper wrapper) throws Exception {
|
|
|
|
wrapper.write(Type.BOOLEAN, false); // smelting book open
|
|
|
|
wrapper.write(Type.BOOLEAN, false); // smelting filter active
|
|
|
|
}
|
|
|
|
});
|
2018-07-18 19:10:43 +02:00
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
2018-12-10 13:11:56 +01:00
|
|
|
int action = wrapper.get(Type.VAR_INT, 0);
|
|
|
|
for (int i = 0; i < (action == 0 ? 2 : 1); i++) {
|
2019-11-02 14:00:27 +01:00
|
|
|
int[] ids = wrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
|
2018-12-10 13:11:56 +01:00
|
|
|
String[] stringIds = new String[ids.length];
|
|
|
|
for (int j = 0; j < ids.length; j++) {
|
|
|
|
stringIds[j] = "viaversion:legacy/" + ids[j];
|
|
|
|
}
|
|
|
|
wrapper.write(Type.STRING_ARRAY, stringIds);
|
|
|
|
}
|
2018-12-10 15:50:03 +01:00
|
|
|
if (action == 0) {
|
|
|
|
wrapper.create(0x54, new ValueCreator() { // Declare recipes
|
|
|
|
@Override
|
|
|
|
public void write(PacketWrapper wrapper) throws Exception {
|
|
|
|
wrapper.write(Type.VAR_INT, RecipeData.recipes.size());
|
|
|
|
for (Map.Entry<String, RecipeData.Recipe> entry : RecipeData.recipes.entrySet()) {
|
|
|
|
wrapper.write(Type.STRING, entry.getKey()); // Id
|
|
|
|
wrapper.write(Type.STRING, entry.getValue().getType());
|
|
|
|
switch (entry.getValue().getType()) {
|
|
|
|
case "crafting_shapeless": {
|
|
|
|
wrapper.write(Type.STRING, entry.getValue().getGroup());
|
|
|
|
wrapper.write(Type.VAR_INT, entry.getValue().getIngredients().length);
|
|
|
|
for (Item[] ingredient : entry.getValue().getIngredients()) {
|
|
|
|
Item[] clone = ingredient.clone(); // Clone because array and item is mutable
|
|
|
|
for (int i = 0; i < clone.length; i++) {
|
|
|
|
if (clone[i] == null) continue;
|
2019-11-27 20:38:42 +01:00
|
|
|
clone[i] = new Item(clone[i]);
|
2018-12-10 15:50:03 +01:00
|
|
|
}
|
|
|
|
wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, clone);
|
|
|
|
}
|
2019-11-22 19:13:02 +01:00
|
|
|
wrapper.write(Type.FLAT_ITEM, new Item(entry.getValue().getResult()));
|
2018-12-10 15:50:03 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "crafting_shaped": {
|
|
|
|
wrapper.write(Type.VAR_INT, entry.getValue().getWidth());
|
|
|
|
wrapper.write(Type.VAR_INT, entry.getValue().getHeight());
|
|
|
|
wrapper.write(Type.STRING, entry.getValue().getGroup());
|
|
|
|
for (Item[] ingredient : entry.getValue().getIngredients()) {
|
|
|
|
Item[] clone = ingredient.clone(); // Clone because array and item is mutable
|
|
|
|
for (int i = 0; i < clone.length; i++) {
|
|
|
|
if (clone[i] == null) continue;
|
2019-11-27 20:38:42 +01:00
|
|
|
clone[i] = new Item(clone[i]);
|
2018-12-10 15:50:03 +01:00
|
|
|
}
|
|
|
|
wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, clone);
|
|
|
|
}
|
2019-11-22 19:13:02 +01:00
|
|
|
wrapper.write(Type.FLAT_ITEM, new Item(entry.getValue().getResult()));
|
2018-12-10 15:50:03 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "smelting": {
|
|
|
|
wrapper.write(Type.STRING, entry.getValue().getGroup());
|
|
|
|
Item[] clone = entry.getValue().getIngredient().clone(); // Clone because array and item is mutable
|
|
|
|
for (int i = 0; i < clone.length; i++) {
|
|
|
|
if (clone[i] == null) continue;
|
2019-11-22 19:13:02 +01:00
|
|
|
clone[i] = new Item(clone[i]);
|
2018-12-10 15:50:03 +01:00
|
|
|
}
|
|
|
|
wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, clone);
|
2019-11-22 19:13:02 +01:00
|
|
|
wrapper.write(Type.FLAT_ITEM, new Item(entry.getValue().getResult()));
|
2018-12-10 15:50:03 +01:00
|
|
|
wrapper.write(Type.FLOAT, entry.getValue().getExperience());
|
|
|
|
wrapper.write(Type.VAR_INT, entry.getValue().getCookingTime());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).send(Protocol1_13To1_12_2.class, true, true);
|
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.RESPAWN, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.INT); // 0 - Dimension ID
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
|
|
|
int dimensionId = wrapper.get(Type.INT, 0);
|
|
|
|
clientWorld.setEnvironment(dimensionId);
|
2018-11-17 15:45:37 +01:00
|
|
|
|
|
|
|
if (Via.getConfig().isServersideBlockConnections()) {
|
|
|
|
ConnectionData.clearBlockStorage(wrapper.user());
|
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
handler(SEND_DECLARE_COMMANDS_AND_TAGS);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.SCOREBOARD_OBJECTIVE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.STRING); // 0 - Objective name
|
|
|
|
map(Type.BYTE); // 1 - Mode
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
byte mode = wrapper.get(Type.BYTE, 0);
|
|
|
|
// On create or update
|
|
|
|
if (mode == 0 || mode == 2) {
|
|
|
|
String value = wrapper.read(Type.STRING); // Value
|
2020-06-25 16:22:53 +02:00
|
|
|
wrapper.write(Type.COMPONENT, ChatRewriter.legacyTextToJson(value));
|
2018-07-18 19:10:43 +02:00
|
|
|
|
|
|
|
String type = wrapper.read(Type.STRING);
|
|
|
|
// integer or hearts
|
|
|
|
wrapper.write(Type.VAR_INT, type.equals("integer") ? 0 : 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.TEAMS, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.STRING); // 0 - Team Name
|
|
|
|
map(Type.BYTE); // 1 - Mode
|
|
|
|
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
byte action = wrapper.get(Type.BYTE, 0);
|
|
|
|
|
|
|
|
if (action == 0 || action == 2) {
|
|
|
|
String displayName = wrapper.read(Type.STRING); // Display Name
|
2020-06-25 16:22:53 +02:00
|
|
|
wrapper.write(Type.COMPONENT, ChatRewriter.legacyTextToJson(displayName));
|
2018-07-18 19:10:43 +02:00
|
|
|
|
|
|
|
String prefix = wrapper.read(Type.STRING); // Prefix moved
|
|
|
|
String suffix = wrapper.read(Type.STRING); // Suffix moved
|
|
|
|
|
|
|
|
wrapper.passthrough(Type.BYTE); // Flags
|
|
|
|
|
|
|
|
wrapper.passthrough(Type.STRING); // Name Tag Visibility
|
|
|
|
wrapper.passthrough(Type.STRING); // Collision rule
|
|
|
|
|
|
|
|
// Handle new colors
|
2018-07-20 22:21:24 +02:00
|
|
|
int colour = wrapper.read(Type.BYTE).intValue();
|
|
|
|
if (colour == -1) {
|
|
|
|
colour = 21; // -1 changed to 21
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Via.getConfig().is1_13TeamColourFix()) {
|
2020-11-23 17:28:07 +01:00
|
|
|
char lastColorChar = getLastColorChar(prefix);
|
|
|
|
colour = ChatColorUtil.getColorOrdinal(lastColorChar);
|
|
|
|
suffix = ChatColorUtil.COLOR_CHAR + Character.toString(lastColorChar) + suffix;
|
2018-07-20 22:21:24 +02:00
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
|
2018-07-20 22:21:24 +02:00
|
|
|
wrapper.write(Type.VAR_INT, colour);
|
2018-07-18 19:10:43 +02:00
|
|
|
|
2020-06-25 16:22:53 +02:00
|
|
|
wrapper.write(Type.COMPONENT, ChatRewriter.legacyTextToJson(prefix)); // Prefix
|
|
|
|
wrapper.write(Type.COMPONENT, ChatRewriter.legacyTextToJson(suffix)); // Suffix
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
2018-10-21 22:56:11 +02:00
|
|
|
|
|
|
|
if (action == 0 || action == 3 || action == 4) {
|
|
|
|
String[] names = wrapper.read(Type.STRING_ARRAY); // Entities
|
|
|
|
for (int i = 0; i < names.length; i++) {
|
|
|
|
names[i] = rewriteTeamMemberName(names[i]);
|
|
|
|
}
|
|
|
|
wrapper.write(Type.STRING_ARRAY, names);
|
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.UPDATE_SCORE, new PacketRemapper() {
|
2018-10-21 22:56:11 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
String displayName = wrapper.read(Type.STRING); // Display Name
|
|
|
|
displayName = rewriteTeamMemberName(displayName);
|
|
|
|
wrapper.write(Type.STRING, displayName);
|
|
|
|
|
|
|
|
byte action = wrapper.read(Type.BYTE);
|
|
|
|
wrapper.write(Type.BYTE, action);
|
|
|
|
wrapper.passthrough(Type.STRING); // Objective Name
|
|
|
|
if (action != 1) {
|
|
|
|
wrapper.passthrough(Type.VAR_INT); // Value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
|
|
|
|
registerOutgoing(ClientboundPackets1_12_1.TITLE, new PacketRemapper() {
|
2018-11-08 19:10:45 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.VAR_INT); // Action
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
int action = wrapper.get(Type.VAR_INT, 0);
|
|
|
|
if (action >= 0 && action <= 2) {
|
2020-06-25 16:22:53 +02:00
|
|
|
ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT));
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2018-07-18 19:10:43 +02:00
|
|
|
// New 0x4C - Stop Sound
|
|
|
|
|
2020-08-16 16:24:06 +02:00
|
|
|
new SoundRewriter(this).registerSound(ClientboundPackets1_12_1.SOUND);
|
2018-07-18 19:10:43 +02:00
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerOutgoing(ClientboundPackets1_12_1.TAB_LIST, new PacketRemapper() {
|
2018-11-08 19:10:45 +01:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
2020-06-25 16:22:53 +02:00
|
|
|
ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT));
|
|
|
|
ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT));
|
2018-11-08 19:10:45 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
|
|
|
|
registerOutgoing(ClientboundPackets1_12_1.ADVANCEMENTS, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
2018-07-22 22:58:18 +02:00
|
|
|
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
|
|
|
|
int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
|
|
|
|
|
|
|
|
for (int i = 0; i < size; i++) {
|
2018-07-22 22:06:43 +02:00
|
|
|
wrapper.passthrough(Type.STRING); // Identifier
|
2018-07-22 22:58:18 +02:00
|
|
|
|
|
|
|
// Parent
|
|
|
|
if (wrapper.passthrough(Type.BOOLEAN))
|
|
|
|
wrapper.passthrough(Type.STRING);
|
|
|
|
|
|
|
|
// Display data
|
|
|
|
if (wrapper.passthrough(Type.BOOLEAN)) {
|
2020-06-25 16:22:53 +02:00
|
|
|
ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT)); // Title
|
|
|
|
ChatRewriter.processTranslate(wrapper.passthrough(Type.COMPONENT)); // Description
|
2018-07-23 00:11:29 +02:00
|
|
|
Item icon = wrapper.read(Type.ITEM);
|
|
|
|
InventoryPackets.toClient(icon);
|
|
|
|
wrapper.write(Type.FLAT_ITEM, icon); // Translate item to flat item
|
2018-07-22 22:06:43 +02:00
|
|
|
wrapper.passthrough(Type.VAR_INT); // Frame type
|
|
|
|
int flags = wrapper.passthrough(Type.INT); // Flags
|
2020-06-25 16:22:53 +02:00
|
|
|
if ((flags & 1) != 0) {
|
2018-07-22 22:58:18 +02:00
|
|
|
wrapper.passthrough(Type.STRING); // Background texture
|
2020-06-25 16:22:53 +02:00
|
|
|
}
|
2018-07-22 22:58:18 +02:00
|
|
|
wrapper.passthrough(Type.FLOAT); // X
|
|
|
|
wrapper.passthrough(Type.FLOAT); // Y
|
2018-07-22 22:06:43 +02:00
|
|
|
}
|
2018-07-22 22:58:18 +02:00
|
|
|
|
|
|
|
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
|
2018-07-22 22:06:43 +02:00
|
|
|
}
|
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
// Incoming packets
|
2018-07-18 19:10:43 +02:00
|
|
|
// New packet 0x02 - Login Plugin Message
|
2019-10-02 11:17:55 +02:00
|
|
|
cancelIncoming(State.LOGIN, 0x02);
|
2018-07-18 19:10:43 +02:00
|
|
|
|
|
|
|
// New 0x01 - Query Block NBT
|
2020-06-05 22:33:48 +02:00
|
|
|
cancelIncoming(ServerboundPackets1_13.QUERY_BLOCK_NBT);
|
2018-07-18 19:10:43 +02:00
|
|
|
|
|
|
|
// Tab-Complete
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.TAB_COMPLETE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
2018-09-01 08:53:36 +02:00
|
|
|
// Disable auto-complete if configured
|
|
|
|
if (Via.getConfig().isDisable1_13AutoComplete()) {
|
|
|
|
wrapper.cancel();
|
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
int tid = wrapper.read(Type.VAR_INT);
|
|
|
|
// Save transaction id
|
|
|
|
wrapper.user().get(TabCompleteTracker.class).setTransactionId(tid);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// Prepend /
|
|
|
|
map(Type.STRING, new ValueTransformer<String, String>(Type.STRING) {
|
|
|
|
@Override
|
|
|
|
public String transform(PacketWrapper wrapper, String inputValue) {
|
|
|
|
wrapper.user().get(TabCompleteTracker.class).setInput(inputValue);
|
|
|
|
return "/" + inputValue;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// Fake the end of the packet
|
|
|
|
create(new ValueCreator() {
|
|
|
|
@Override
|
2019-01-23 20:25:08 +01:00
|
|
|
public void write(PacketWrapper wrapper) throws Exception {
|
2018-07-18 19:10:43 +02:00
|
|
|
wrapper.write(Type.BOOLEAN, false);
|
|
|
|
wrapper.write(Type.OPTIONAL_POSITION, null);
|
2019-01-23 20:25:08 +01:00
|
|
|
if (!wrapper.isCancelled() && Via.getConfig().get1_13TabCompleteDelay() > 0) {
|
|
|
|
TabCompleteTracker tracker = wrapper.user().get(TabCompleteTracker.class);
|
|
|
|
wrapper.cancel();
|
2020-06-05 22:33:48 +02:00
|
|
|
tracker.setTimeToSend(System.currentTimeMillis() + Via.getConfig().get1_13TabCompleteDelay() * 50L);
|
2019-02-07 17:07:30 +01:00
|
|
|
tracker.setLastTabComplete(wrapper.get(Type.STRING, 0));
|
2019-01-23 20:25:08 +01:00
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// New 0x0A - Edit book -> Plugin Message
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.EDIT_BOOK, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
Item item = wrapper.read(Type.FLAT_ITEM);
|
|
|
|
boolean isSigning = wrapper.read(Type.BOOLEAN);
|
|
|
|
|
|
|
|
InventoryPackets.toServer(item);
|
|
|
|
|
|
|
|
wrapper.write(Type.STRING, isSigning ? "MC|BSign" : "MC|BEdit"); // Channel
|
|
|
|
wrapper.write(Type.ITEM, item);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
|
2018-07-18 19:10:43 +02:00
|
|
|
// New 0x0C - Query Entity NBT
|
2020-06-05 22:33:48 +02:00
|
|
|
cancelIncoming(ServerboundPackets1_13.ENTITY_NBT_REQUEST);
|
|
|
|
|
2018-07-18 19:10:43 +02:00
|
|
|
// New 0x15 - Pick Item -> Plugin Message
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.PICK_ITEM, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
create(new ValueCreator() {
|
|
|
|
@Override
|
|
|
|
public void write(PacketWrapper wrapper) throws Exception {
|
|
|
|
wrapper.write(Type.STRING, "MC|PickItem"); // Channel
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.CRAFT_RECIPE_REQUEST, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2018-12-10 15:53:21 +01:00
|
|
|
map(Type.BYTE); // Window id
|
2020-08-31 11:59:19 +02:00
|
|
|
|
|
|
|
handler(wrapper -> {
|
|
|
|
String s = wrapper.read(Type.STRING);
|
|
|
|
Integer id;
|
|
|
|
if (s.length() < 19 || (id = Ints.tryParse(s.substring(18))) == null) {
|
|
|
|
wrapper.cancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapper.write(Type.VAR_INT, id);
|
|
|
|
});
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.RECIPE_BOOK_DATA, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
map(Type.VAR_INT); // 0 - Type
|
|
|
|
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
int type = wrapper.get(Type.VAR_INT, 0);
|
|
|
|
|
2018-12-10 13:11:56 +01:00
|
|
|
if (type == 0) {
|
2020-08-27 09:37:51 +02:00
|
|
|
String s = wrapper.read(Type.STRING);
|
|
|
|
Integer id;
|
2020-08-16 10:18:08 +02:00
|
|
|
// Custom recipes
|
2020-08-27 09:37:51 +02:00
|
|
|
if (s.length() < 19 || (id = Ints.tryParse(s.substring(18))) == null) {
|
2020-08-16 10:18:08 +02:00
|
|
|
wrapper.cancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapper.write(Type.INT, id);
|
2018-12-10 15:53:21 +01:00
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
if (type == 1) {
|
|
|
|
wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Book Open
|
|
|
|
wrapper.passthrough(Type.BOOLEAN); // Crafting Recipe Filter Active
|
|
|
|
wrapper.read(Type.BOOLEAN); // Smelting Recipe Book Open | IGNORE NEW 1.13 FIELD
|
|
|
|
wrapper.read(Type.BOOLEAN); // Smelting Recipe Filter Active | IGNORE NEW 1.13 FIELD
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// New 0x1C - Name Item -> Plugin Message
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.RENAME_ITEM, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-05 22:33:48 +02:00
|
|
|
create(wrapper -> {
|
|
|
|
wrapper.write(Type.STRING, "MC|ItemName"); // Channel
|
2018-07-18 19:10:43 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// New 0x1F - Select Trade -> Plugin Message
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.SELECT_TRADE, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-05 22:33:48 +02:00
|
|
|
create(wrapper -> {
|
|
|
|
wrapper.write(Type.STRING, "MC|TrSel"); // Channel
|
2018-07-18 19:10:43 +02:00
|
|
|
});
|
|
|
|
map(Type.VAR_INT, Type.INT); // Slot
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
|
2018-07-18 19:10:43 +02:00
|
|
|
// New 0x20 - Set Beacon Effect -> Plugin Message
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.SET_BEACON_EFFECT, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-05 22:33:48 +02:00
|
|
|
create(wrapper -> {
|
|
|
|
wrapper.write(Type.STRING, "MC|Beacon"); // Channel
|
2018-07-18 19:10:43 +02:00
|
|
|
});
|
|
|
|
map(Type.VAR_INT, Type.INT); // Primary Effect
|
|
|
|
map(Type.VAR_INT, Type.INT); // Secondary Effect
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// New 0x22 - Update Command Block -> Plugin Message
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.UPDATE_COMMAND_BLOCK, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-25 16:22:53 +02:00
|
|
|
create(wrapper -> wrapper.write(Type.STRING, "MC|AutoCmd"));
|
2018-07-18 19:10:43 +02:00
|
|
|
handler(POS_TO_3_INT);
|
|
|
|
map(Type.STRING); // Command
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
int mode = wrapper.read(Type.VAR_INT);
|
|
|
|
byte flags = wrapper.read(Type.BYTE);
|
|
|
|
|
|
|
|
String stringMode = mode == 0 ? "SEQUENCE"
|
|
|
|
: mode == 1 ? "AUTO"
|
|
|
|
: "REDSTONE";
|
|
|
|
|
|
|
|
wrapper.write(Type.BOOLEAN, (flags & 0x1) != 0); // Track output
|
|
|
|
wrapper.write(Type.STRING, stringMode);
|
|
|
|
wrapper.write(Type.BOOLEAN, (flags & 0x2) != 0); // Is conditional
|
|
|
|
wrapper.write(Type.BOOLEAN, (flags & 0x4) != 0); // Automatic
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2020-06-05 22:33:48 +02:00
|
|
|
|
2018-07-18 19:10:43 +02:00
|
|
|
// New 0x23 - Update Command Block Minecart -> Plugin Message
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.UPDATE_COMMAND_BLOCK_MINECART, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
|
|
|
create(new ValueCreator() {
|
|
|
|
@Override
|
|
|
|
public void write(PacketWrapper wrapper) throws Exception {
|
|
|
|
wrapper.write(Type.STRING, "MC|AdvCmd");
|
|
|
|
wrapper.write(Type.BYTE, (byte) 1); // Type 1 for Entity
|
|
|
|
}
|
|
|
|
});
|
|
|
|
map(Type.VAR_INT, Type.INT); // Entity Id
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// 0x1B -> 0x24 in InventoryPackets
|
|
|
|
|
|
|
|
// New 0x25 - Update Structure Block -> Message Channel
|
2020-06-05 22:33:48 +02:00
|
|
|
registerIncoming(ServerboundPackets1_13.UPDATE_STRUCTURE_BLOCK, ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void registerMap() {
|
2020-06-05 22:33:48 +02:00
|
|
|
create(wrapper -> {
|
|
|
|
wrapper.write(Type.STRING, "MC|Struct"); // Channel
|
2018-07-18 19:10:43 +02:00
|
|
|
});
|
|
|
|
handler(POS_TO_3_INT);
|
|
|
|
map(Type.VAR_INT, new ValueTransformer<Integer, Byte>(Type.BYTE) { // Action
|
|
|
|
@Override
|
|
|
|
public Byte transform(PacketWrapper wrapper, Integer action) throws Exception {
|
|
|
|
return (byte) (action + 1);
|
|
|
|
}
|
|
|
|
}); // Action
|
|
|
|
map(Type.VAR_INT, new ValueTransformer<Integer, String>(Type.STRING) {
|
|
|
|
@Override
|
|
|
|
public String transform(PacketWrapper wrapper, Integer mode) throws Exception {
|
|
|
|
return mode == 0 ? "SAVE"
|
|
|
|
: mode == 1 ? "LOAD"
|
|
|
|
: mode == 2 ? "CORNER"
|
|
|
|
: "DATA";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
map(Type.STRING); // Name
|
|
|
|
map(Type.BYTE, Type.INT); // Offset X
|
|
|
|
map(Type.BYTE, Type.INT); // Offset Y
|
|
|
|
map(Type.BYTE, Type.INT); // Offset Z
|
|
|
|
map(Type.BYTE, Type.INT); // Size X
|
|
|
|
map(Type.BYTE, Type.INT); // Size Y
|
|
|
|
map(Type.BYTE, Type.INT); // Size Z
|
|
|
|
map(Type.VAR_INT, new ValueTransformer<Integer, String>(Type.STRING) { // Mirror
|
|
|
|
@Override
|
|
|
|
public String transform(PacketWrapper wrapper, Integer mirror) throws Exception {
|
|
|
|
return mirror == 0 ? "NONE"
|
|
|
|
: mirror == 1 ? "LEFT_RIGHT"
|
|
|
|
: "FRONT_BACK";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
map(Type.VAR_INT, new ValueTransformer<Integer, String>(Type.STRING) { // Rotation
|
|
|
|
@Override
|
|
|
|
public String transform(PacketWrapper wrapper, Integer rotation) throws Exception {
|
|
|
|
return rotation == 0 ? "NONE"
|
|
|
|
: rotation == 1 ? "CLOCKWISE_90"
|
|
|
|
: rotation == 2 ? "CLOCKWISE_180"
|
|
|
|
: "COUNTERCLOCKWISE_90";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
map(Type.STRING);
|
|
|
|
handler(new PacketHandler() {
|
|
|
|
@Override
|
|
|
|
public void handle(PacketWrapper wrapper) throws Exception {
|
|
|
|
float integrity = wrapper.read(Type.FLOAT);
|
|
|
|
long seed = wrapper.read(Type.VAR_LONG);
|
|
|
|
byte flags = wrapper.read(Type.BYTE);
|
|
|
|
|
|
|
|
wrapper.write(Type.BOOLEAN, (flags & 0x1) != 0); // Ignore Entities
|
|
|
|
wrapper.write(Type.BOOLEAN, (flags & 0x2) != 0); // Show air
|
|
|
|
wrapper.write(Type.BOOLEAN, (flags & 0x4) != 0); // Show bounding box
|
|
|
|
wrapper.write(Type.FLOAT, integrity);
|
|
|
|
wrapper.write(Type.VAR_LONG, seed);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-03-23 01:23:17 +01:00
|
|
|
@Override
|
2020-08-16 16:24:06 +02:00
|
|
|
protected void onMappingDataLoaded() {
|
2020-03-23 01:23:17 +01:00
|
|
|
ConnectionData.init();
|
|
|
|
RecipeData.init();
|
|
|
|
BlockIdData.init();
|
|
|
|
}
|
|
|
|
|
2018-07-18 19:10:43 +02:00
|
|
|
@Override
|
|
|
|
public void init(UserConnection userConnection) {
|
2019-05-08 12:14:41 +02:00
|
|
|
userConnection.put(new EntityTracker1_13(userConnection));
|
2018-07-18 19:10:43 +02:00
|
|
|
userConnection.put(new TabCompleteTracker(userConnection));
|
|
|
|
if (!userConnection.has(ClientWorld.class))
|
|
|
|
userConnection.put(new ClientWorld(userConnection));
|
|
|
|
userConnection.put(new BlockStorage(userConnection));
|
2018-12-03 09:21:07 +01:00
|
|
|
if (Via.getConfig().isServersideBlockConnections()) {
|
|
|
|
if (Via.getManager().getProviders().get(BlockConnectionProvider.class) instanceof PacketBlockConnectionProvider) {
|
|
|
|
userConnection.put(new BlockConnectionStorage(userConnection));
|
|
|
|
}
|
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-04-26 21:16:10 +02:00
|
|
|
public void register(ViaProviders providers) {
|
2018-07-18 19:10:43 +02:00
|
|
|
providers.register(BlockEntityProvider.class, new BlockEntityProvider());
|
|
|
|
providers.register(PaintingProvider.class, new PaintingProvider());
|
|
|
|
}
|
|
|
|
|
2018-07-20 22:21:24 +02:00
|
|
|
// Based on method from https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/ChatColor.java
|
2020-11-23 17:28:07 +01:00
|
|
|
public char getLastColorChar(String input) {
|
2018-07-20 22:21:24 +02:00
|
|
|
int length = input.length();
|
|
|
|
for (int index = length - 1; index > -1; index--) {
|
|
|
|
char section = input.charAt(index);
|
2020-11-23 17:28:07 +01:00
|
|
|
if (section == ChatColorUtil.COLOR_CHAR && index < length - 1) {
|
2018-07-20 22:21:24 +02:00
|
|
|
char c = input.charAt(index + 1);
|
2020-11-23 17:28:07 +01:00
|
|
|
if (ChatColorUtil.isColorCode(c) && !FORMATTING_CODES.contains(c)) {
|
|
|
|
return c;
|
2018-07-20 22:21:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-23 17:28:07 +01:00
|
|
|
return 'r';
|
2018-07-20 22:21:24 +02:00
|
|
|
}
|
2018-10-21 22:56:11 +02:00
|
|
|
|
|
|
|
protected String rewriteTeamMemberName(String name) {
|
|
|
|
// The Display Name is just colours which overwrites the suffix
|
|
|
|
// It also overwrites for ANY colour in name but most plugins
|
|
|
|
// will just send colour as 'invisible' character
|
2020-11-23 17:28:07 +01:00
|
|
|
if (ChatColorUtil.stripColor(name).isEmpty()) {
|
2018-10-21 23:19:54 +02:00
|
|
|
StringBuilder newName = new StringBuilder();
|
2018-11-04 11:56:22 +01:00
|
|
|
for (int i = 1; i < name.length(); i += 2) {
|
|
|
|
char colorChar = name.charAt(i);
|
2020-11-23 17:28:07 +01:00
|
|
|
Character rewrite = SCOREBOARD_TEAM_NAME_REWRITE.get(colorChar);
|
2018-11-04 11:56:22 +01:00
|
|
|
if (rewrite == null) {
|
|
|
|
rewrite = colorChar;
|
2018-10-21 23:19:54 +02:00
|
|
|
}
|
2020-11-23 17:28:07 +01:00
|
|
|
newName.append(ChatColorUtil.COLOR_CHAR).append(rewrite);
|
2018-10-21 22:56:11 +02:00
|
|
|
}
|
2018-10-21 23:19:54 +02:00
|
|
|
name = newName.toString();
|
2018-10-21 22:56:11 +02:00
|
|
|
}
|
|
|
|
return name;
|
|
|
|
}
|
2019-11-02 14:00:27 +01:00
|
|
|
|
|
|
|
public static int[] toPrimitive(Integer[] array) {
|
|
|
|
int[] prim = new int[array.length];
|
|
|
|
for (int i = 0; i < array.length; i++) {
|
|
|
|
prim[i] = array[i];
|
|
|
|
}
|
|
|
|
return prim;
|
|
|
|
}
|
2020-08-16 16:24:06 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public MappingData getMappingData() {
|
|
|
|
return MAPPINGS;
|
|
|
|
}
|
2018-07-18 19:10:43 +02:00
|
|
|
}
|