mirror of
https://github.com/NEZNAMY/TAB.git
synced 2026-11-12 20:22:01 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
484d46252b | ||
|
|
a2e3c67298 | ||
|
|
b2ea05d8dd | ||
|
|
1477f47962 | ||
|
|
273ce49c14 | ||
|
|
96b6790646 | ||
|
|
38227ec878 | ||
|
|
11da632972 | ||
|
|
3721b9fe22 | ||
|
|
ecb697e5fb | ||
|
|
c754772280 | ||
|
|
5f2b4ba0b3 | ||
|
|
0ab60becfc | ||
|
|
1dcfb7d6dc |
No files matched your search
+2
-4
@@ -4,7 +4,7 @@ plugins {
|
||||
|
||||
allprojects {
|
||||
group = "me.neznamy"
|
||||
version = "4.1.0"
|
||||
version = "4.1.2"
|
||||
description = "An all-in-one solution that works"
|
||||
|
||||
ext.set("id", "tab")
|
||||
@@ -19,17 +19,15 @@ val platforms = setOf(
|
||||
projects.sponge7,
|
||||
projects.sponge8,
|
||||
projects.fabric,
|
||||
projects.fabric.v1144,
|
||||
projects.fabric.v1152,
|
||||
projects.fabric.v1165,
|
||||
projects.fabric.v117,
|
||||
projects.fabric.v1171,
|
||||
projects.fabric.v1182,
|
||||
projects.fabric.v1192,
|
||||
projects.fabric.v1193,
|
||||
projects.fabric.v1201,
|
||||
projects.fabric.v1202,
|
||||
projects.fabric.v1203
|
||||
projects.fabric.v1204
|
||||
).map { it.dependencyProject }
|
||||
|
||||
val special = setOf(
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
val minecraftVersion = "1.20.3"
|
||||
|
||||
plugins {
|
||||
id("fabric-loom")
|
||||
}
|
||||
@@ -14,11 +12,11 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
api(projects.shared)
|
||||
minecraft("com.mojang:minecraft:$minecraftVersion")
|
||||
minecraft("com.mojang:minecraft:1.20.4")
|
||||
mappings(loom.officialMojangMappings())
|
||||
modImplementation("me.lucko:fabric-permissions-api:0.2-SNAPSHOT")
|
||||
modImplementation("net.fabricmc:fabric-loader:0.14.17")
|
||||
val version = "0.90.4+1.20.3"
|
||||
val version = "0.91.1+1.20.4"
|
||||
modImplementation(fabricApi.module("fabric-api-base", version))
|
||||
modImplementation(fabricApi.module("fabric-lifecycle-events-v1", version))
|
||||
modImplementation(fabricApi.module("fabric-networking-api-v1", version))
|
||||
|
||||
@@ -13,17 +13,15 @@ public class FabricTAB implements DedicatedServerModInitializer {
|
||||
@Override
|
||||
public void onInitializeServer() {
|
||||
String[] modules = {
|
||||
"v1_14_4",
|
||||
"v1_15_2",
|
||||
"v1_15_2", // 1.14.4, 1.15.2
|
||||
"v1_16_5",
|
||||
"v1_17",
|
||||
"v1_17_1",
|
||||
"v1_17_1", // 1.17, 1.17.1
|
||||
"v1_18_2", // 1.18, 1.18.1, 1.18.2
|
||||
"v1_19_2", // 1.19, 1.19.1, 1.19.2
|
||||
"v1_19_3",
|
||||
"v1_20_1", // 1.19.4, 1.20, 1.20.1
|
||||
"v1_20_2",
|
||||
"v1_20_3"
|
||||
"v1_20_4" // 1.20.3, 1.20.4
|
||||
};
|
||||
for (String module : modules) {
|
||||
try {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"1.17", "1.17.1",
|
||||
"1.18", "1.18.1", "1.18.2",
|
||||
"1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4",
|
||||
"1.20", "1.20.1", "1.20.2", "1.20.3"
|
||||
"1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4"
|
||||
]
|
||||
},
|
||||
"recommends": {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
plugins {
|
||||
id("fabric-loom")
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Gradle doesn't support combining settings and project repositories, so we have to re-declare all the settings repos we need
|
||||
maven("https://jitpack.io") // YamlAssist
|
||||
maven("https://repo.opencollab.dev/maven-snapshots/")
|
||||
maven("https://repo.viaversion.com/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.fabric)
|
||||
minecraft("com.mojang:minecraft:1.14.4")
|
||||
mappings(loom.officialMojangMappings())
|
||||
modImplementation("net.fabricmc:fabric-loader:0.14.17")
|
||||
val fabricApiVersion = "0.28.5+1.14"
|
||||
modImplementation(fabricApi.module("fabric-api-base", fabricApiVersion))
|
||||
modImplementation(fabricApi.module("fabric-lifecycle-events-v1", fabricApiVersion))
|
||||
modImplementation(fabricApi.module("fabric-command-api-v1", fabricApiVersion))
|
||||
}
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
package me.neznamy.tab.platforms.fabric.v1_14_4;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.fabric.FabricTabPlayer;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.TabConstants;
|
||||
import me.neznamy.tab.shared.chat.IChatBaseComponent;
|
||||
import me.neznamy.tab.shared.features.injection.NettyPipelineInjector;
|
||||
import me.neznamy.tab.shared.features.nametags.NameTag;
|
||||
import me.neznamy.tab.shared.features.sorting.Sorting;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket.Action;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket.PlayerUpdate;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetDisplayObjectivePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetObjectivePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class FabricPipelineInjector extends NettyPipelineInjector {
|
||||
|
||||
public FabricPipelineInjector() {
|
||||
super("packet_handler");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@SneakyThrows
|
||||
protected Channel getChannel(@NotNull TabPlayer player) {
|
||||
Connection c = (Connection) ReflectionUtils.getFields(ServerGamePacketListenerImpl.class, Connection.class)
|
||||
.get(0).get(((FabricTabPlayer)player).getPlayer().connection);
|
||||
return (Channel) ReflectionUtils.getFields(Connection.class, Channel.class).get(0).get(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onDisplayObjective(@NotNull TabPlayer player, @NotNull Object packet) {
|
||||
// Getters are client only
|
||||
int slot = ReflectionUtils.getFields(ClientboundSetDisplayObjectivePacket.class, int.class).get(0).getInt(packet);
|
||||
String objective = (String) ReflectionUtils.getFields(ClientboundSetDisplayObjectivePacket.class, String.class).get(0).get(packet);
|
||||
TAB.getInstance().getFeatureManager().onDisplayObjective(player, slot, objective);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onObjective(@NotNull TabPlayer player, @NotNull Object packet) {
|
||||
// Getters are client only
|
||||
int action = ReflectionUtils.getFields(ClientboundSetObjectivePacket.class, int.class).get(0).getInt(packet);
|
||||
String objective = (String) ReflectionUtils.getFields(ClientboundSetObjectivePacket.class, String.class).get(0).get(packet);
|
||||
TAB.getInstance().getFeatureManager().onObjective(player, action, objective);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplayObjective(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundSetDisplayObjectivePacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObjective(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundSetObjectivePacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTeam(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundSetPlayerTeamPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayerInfo(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundPlayerInfoPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onPlayerInfo(@NotNull TabPlayer receiver, @NotNull Object packet) {
|
||||
// Getters are client only
|
||||
Action action = (Action) ReflectionUtils.getFields(ClientboundPlayerInfoPacket.class, Action.class).get(0).get(packet);
|
||||
List<PlayerUpdate> players = (List<PlayerUpdate>) ReflectionUtils.getFields(ClientboundPlayerInfoPacket.class, List.class).get(0).get(packet);
|
||||
for (PlayerUpdate nmsData : players) {
|
||||
GameProfile profile = nmsData.getProfile();
|
||||
Field displayNameField = ReflectionUtils.getFields(PlayerUpdate.class, Component.class).get(0);
|
||||
Field latencyField = ReflectionUtils.getFields(PlayerUpdate.class, int.class).get(0);
|
||||
if (action == Action.UPDATE_DISPLAY_NAME) {
|
||||
IChatBaseComponent newDisplayName = TAB.getInstance().getFeatureManager().onDisplayNameChange(receiver, profile.getId());
|
||||
if (newDisplayName != null) displayNameField.set(nmsData, ((FabricTabPlayer)receiver).getPlatform().toComponent(newDisplayName, receiver.getVersion()));
|
||||
}
|
||||
if (action == Action.UPDATE_LATENCY) {
|
||||
latencyField.set(nmsData, TAB.getInstance().getFeatureManager().onLatencyChange(receiver, profile.getId(), latencyField.getInt(nmsData)));
|
||||
}
|
||||
if (action == Action.ADD_PLAYER) {
|
||||
TAB.getInstance().getFeatureManager().onEntryAdd(receiver, profile.getId(), profile.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogin(@NotNull Object packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
@SuppressWarnings("unchecked")
|
||||
public void modifyPlayers(@NotNull Object teamPacket) {
|
||||
if (TAB.getInstance().getNameTagManager() == null) return;
|
||||
ClientboundSetPlayerTeamPacket packet = (ClientboundSetPlayerTeamPacket) teamPacket;
|
||||
int action = ReflectionUtils.getInstanceFields(ClientboundSetPlayerTeamPacket.class, int.class).get(0).getInt(packet);
|
||||
if (action == 1 || action == 2 || action == 4) return;
|
||||
Field playersField = ReflectionUtils.getFields(ClientboundSetPlayerTeamPacket.class, Collection.class).get(0);
|
||||
Collection<String> players = (Collection<String>) playersField.get(packet);
|
||||
String teamName = String.valueOf(ReflectionUtils.getFields(ClientboundSetPlayerTeamPacket.class, String.class).get(0).get(packet));
|
||||
if (players == null) return;
|
||||
//creating a new list to prevent NoSuchFieldException in minecraft packet encoder when a player is removed
|
||||
Collection<String> newList = new ArrayList<>();
|
||||
for (String entry : players) {
|
||||
TabPlayer p = getPlayer(entry);
|
||||
if (p == null) {
|
||||
newList.add(entry);
|
||||
continue;
|
||||
}
|
||||
Sorting sorting = TAB.getInstance().getFeatureManager().getFeature(TabConstants.Feature.SORTING);
|
||||
String expectedTeam = sorting.getShortTeamName(p);
|
||||
if (expectedTeam == null) {
|
||||
newList.add(entry);
|
||||
continue;
|
||||
}
|
||||
if (!((NameTag)TAB.getInstance().getNameTagManager()).getDisableChecker().isDisabledPlayer(p) &&
|
||||
!TAB.getInstance().getNameTagManager().hasTeamHandlingPaused(p) && !teamName.equals(expectedTeam)) {
|
||||
logTeamOverride(teamName, p.getName(), expectedTeam);
|
||||
} else {
|
||||
newList.add(entry);
|
||||
}
|
||||
}
|
||||
playersField.set(packet, newList);
|
||||
}
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
package me.neznamy.tab.platforms.fabric.v1_14_4;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.fabric.*;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.backend.EntityData;
|
||||
import me.neznamy.tab.shared.backend.Location;
|
||||
import me.neznamy.tab.shared.chat.IChatBaseComponent;
|
||||
import me.neznamy.tab.shared.features.injection.PipelineInjector;
|
||||
import me.neznamy.tab.shared.platform.Scoreboard;
|
||||
import me.neznamy.tab.shared.platform.TabList;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.ServerScoreboard;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.scores.Objective;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FabricTAB implements VersionLoader {
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedVersions() {
|
||||
return Collections.singletonList("1.14.4");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(Level level) {
|
||||
return level.getLevelData().getLevelName() + level.dimension.getType().getFileSuffix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPing(ServerPlayer player) {
|
||||
return player.latency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(ServerPlayer player, Component message) {
|
||||
player.sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabList.Skin propertyToSkin(Property property) {
|
||||
return new TabList.Skin(property.getValue(), property.getSignature());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(CommandSourceStack sender, Component message) {
|
||||
sender.sendSuccess(message, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersion() {
|
||||
return SharedConstants.getCurrentVersion().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMSPT() {
|
||||
return ((FabricPlatform)TAB.getInstance().getPlatform()).getServer().getAverageTickTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component deserialize(String string) {
|
||||
return Component.Serializer.fromJson(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Packet<?> build(TabList.Action action, FabricTabList.Builder entry) {
|
||||
ClientboundPlayerInfoPacket packet = new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.valueOf(action.name()), Collections.emptyList());
|
||||
ReflectionUtils.getFields(ClientboundPlayerInfoPacket.class, List.class).get(0).set(packet,
|
||||
Collections.singletonList(new ClientboundPlayerInfoPacket().new PlayerUpdate(
|
||||
entry.createProfile(),
|
||||
entry.getLatency(),
|
||||
GameType.byId(entry.getGameMode()),
|
||||
entry.getDisplayName()
|
||||
)));
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Level getLevel(ServerPlayer player) {
|
||||
return player.level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSneaking(ServerPlayer player) {
|
||||
return player.isSneaking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityData createDataWatcher(TabPlayer viewer, byte flags, String displayName, boolean nameVisible) {
|
||||
SynchedEntityData data = new SynchedEntityData(null);
|
||||
data.define(new EntityDataAccessor<>(0, EntityDataSerializers.BYTE), flags);
|
||||
data.define(new EntityDataAccessor<>(2, EntityDataSerializers.OPTIONAL_COMPONENT),
|
||||
Optional.of(((FabricTabPlayer)viewer).getPlatform().toComponent(IChatBaseComponent.optimizedComponent(displayName), viewer.getVersion())));
|
||||
data.define(new EntityDataAccessor<>(3, EntityDataSerializers.BOOLEAN), nameVisible);
|
||||
data.define(new EntityDataAccessor<>(13, EntityDataSerializers.BYTE), (byte)16);
|
||||
return () -> data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> spawnEntity(int entityId, UUID id, Object entityType, Location location) {
|
||||
dummyEntity.setId(entityId);
|
||||
dummyEntity.setUUID(id);
|
||||
dummyEntity.setPos(location.getX(), location.getY(), location.getZ());
|
||||
return new ClientboundAddMobPacket(dummyEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> newEntityMetadata(int entityId, EntityData data) {
|
||||
return new ClientboundSetEntityDataPacket(entityId, (SynchedEntityData) data.build(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpawnPlayerPacket(Object packet) {
|
||||
return packet instanceof ClientboundAddPlayerPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public int getSpawnedPlayer(Object spawnPacket) {
|
||||
// Getter is client only
|
||||
return ReflectionUtils.getFields(ClientboundAddPlayerPacket.class, int.class).get(0).getInt(spawnPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public int[] getDestroyedEntities(Object entityDestroyPacket) {
|
||||
// Getter is client only
|
||||
return (int[]) ReflectionUtils.getFields(ClientboundRemoveEntitiesPacket.class, int[].class).get(0).get(entityDestroyPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBundlePacket(Object packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Object> getPackets(Object bundlePacket) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PipelineInjector createPipelineInjector() {
|
||||
return new FabricPipelineInjector();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyEntities(FabricTabPlayer player, int... entities) {
|
||||
player.sendPacket(new ClientboundRemoveEntitiesPacket(entities));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCommandCallback() {
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, $) -> new FabricTabCommand().onRegisterCommands(dispatcher));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Packet<?> newHeaderFooter(Component header, Component footer) {
|
||||
ClientboundTabListPacket packet = new ClientboundTabListPacket();
|
||||
List<Field> fields = ReflectionUtils.getFields(ClientboundTabListPacket.class, Component.class);
|
||||
fields.get(0).set(packet, header);
|
||||
fields.get(1).set(packet, footer);
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> setDisplaySlot(int slot, Objective objective) {
|
||||
return new ClientboundSetDisplayObjectivePacket(slot, objective);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Objective newObjective(String name, Component displayName, ObjectiveCriteria.RenderType renderType,
|
||||
@Nullable Component numberFormat) {
|
||||
return new Objective(dummyScoreboard, name, ObjectiveCriteria.DUMMY, displayName, renderType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> registerTeam(PlayerTeam team) {
|
||||
return new ClientboundSetPlayerTeamPacket(team, Scoreboard.TeamAction.CREATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> unregisterTeam(PlayerTeam team) {
|
||||
return new ClientboundSetPlayerTeamPacket(team, Scoreboard.TeamAction.REMOVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> updateTeam(PlayerTeam team) {
|
||||
return new ClientboundSetPlayerTeamPacket(team, Scoreboard.TeamAction.UPDATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> setScore(String objective, String scoreHolder, int score, Component displayName, @Nullable Component numberFormat) {
|
||||
return new ClientboundSetScorePacket(ServerScoreboard.Method.CHANGE, objective, scoreHolder, score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> removeScore(String objective, String scoreHolder) {
|
||||
return new ClientboundSetScorePacket(ServerScoreboard.Method.REMOVE, objective, scoreHolder, 0);
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public class FabricTAB implements VersionLoader {
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedVersions() {
|
||||
return Collections.singletonList("1.15.2");
|
||||
return Arrays.asList("1.14.4", "1.15.2");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,7 +100,13 @@ public class FabricTAB implements VersionLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public boolean isSneaking(ServerPlayer player) {
|
||||
if (getServerVersion().equals("1.14.4")) {
|
||||
return (boolean) player.getClass().getMethod("method_5715").invoke(player);
|
||||
}
|
||||
|
||||
// 1.15.2
|
||||
return player.isCrouching();
|
||||
}
|
||||
|
||||
@@ -111,7 +117,8 @@ public class FabricTAB implements VersionLoader {
|
||||
data.define(new EntityDataAccessor<>(2, EntityDataSerializers.OPTIONAL_COMPONENT),
|
||||
Optional.of(((FabricTabPlayer)viewer).getPlatform().toComponent(IChatBaseComponent.optimizedComponent(displayName), viewer.getVersion())));
|
||||
data.define(new EntityDataAccessor<>(3, EntityDataSerializers.BOOLEAN), nameVisible);
|
||||
data.define(new EntityDataAccessor<>(14, EntityDataSerializers.BYTE), (byte)16);
|
||||
int markerPosition = viewer.getPlatform().getServerVersion().getMinorVersion() >= 15 ? 14 : 13;
|
||||
data.define(new EntityDataAccessor<>(markerPosition, EntityDataSerializers.BYTE), (byte)16);
|
||||
return () -> data;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
plugins {
|
||||
id("fabric-loom")
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Gradle doesn't support combining settings and project repositories, so we have to re-declare all the settings repos we need
|
||||
maven("https://jitpack.io") // YamlAssist
|
||||
maven("https://repo.opencollab.dev/maven-snapshots/")
|
||||
maven("https://repo.viaversion.com/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.fabric)
|
||||
minecraft("com.mojang:minecraft:1.17")
|
||||
mappings(loom.officialMojangMappings())
|
||||
modImplementation("net.fabricmc:fabric-loader:0.14.17")
|
||||
val fabricApiVersion = "0.46.1+1.17"
|
||||
modImplementation(fabricApi.module("fabric-api-base", fabricApiVersion))
|
||||
modImplementation(fabricApi.module("fabric-lifecycle-events-v1", fabricApiVersion))
|
||||
modImplementation(fabricApi.module("fabric-command-api-v1", fabricApiVersion))
|
||||
}
|
||||
|
||||
tasks {
|
||||
compileJava {
|
||||
options.release.set(17)
|
||||
}
|
||||
}
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
package me.neznamy.tab.platforms.fabric.v1_17;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.fabric.FabricTabPlayer;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.TabConstants;
|
||||
import me.neznamy.tab.shared.chat.IChatBaseComponent;
|
||||
import me.neznamy.tab.shared.features.injection.NettyPipelineInjector;
|
||||
import me.neznamy.tab.shared.features.nametags.NameTag;
|
||||
import me.neznamy.tab.shared.features.sorting.Sorting;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetDisplayObjectivePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetObjectivePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class FabricPipelineInjector extends NettyPipelineInjector {
|
||||
|
||||
public FabricPipelineInjector() {
|
||||
super("packet_handler");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@SneakyThrows
|
||||
protected Channel getChannel(@NotNull TabPlayer player) {
|
||||
Connection c = (Connection) ReflectionUtils.getFields(ServerGamePacketListenerImpl.class, Connection.class)
|
||||
.get(0).get(((FabricTabPlayer)player).getPlayer().connection);
|
||||
return (Channel) ReflectionUtils.getFields(Connection.class, Channel.class).get(0).get(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayObjective(@NotNull TabPlayer player, @NotNull Object packet) {
|
||||
TAB.getInstance().getFeatureManager().onDisplayObjective(player,
|
||||
((ClientboundSetDisplayObjectivePacket) packet).getSlot(),
|
||||
String.valueOf(((ClientboundSetDisplayObjectivePacket)packet).getObjectiveName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onObjective(@NotNull TabPlayer player, @NotNull Object packet) {
|
||||
TAB.getInstance().getFeatureManager().onObjective(player,
|
||||
((ClientboundSetObjectivePacket)packet).getMethod(),
|
||||
((ClientboundSetObjectivePacket)packet).getObjectiveName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplayObjective(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundSetDisplayObjectivePacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObjective(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundSetObjectivePacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTeam(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundSetPlayerTeamPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayerInfo(@NotNull Object packet) {
|
||||
return packet instanceof ClientboundPlayerInfoPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onPlayerInfo(@NotNull TabPlayer receiver, @NotNull Object packet0) {
|
||||
ClientboundPlayerInfoPacket packet = (ClientboundPlayerInfoPacket) packet0;
|
||||
for (ClientboundPlayerInfoPacket.PlayerUpdate nmsData : packet.getEntries()) {
|
||||
GameProfile profile = nmsData.getProfile();
|
||||
Field displayNameField = ReflectionUtils.getFields(ClientboundPlayerInfoPacket.PlayerUpdate.class, Component.class).get(0);
|
||||
Field latencyField = ReflectionUtils.getFields(ClientboundPlayerInfoPacket.PlayerUpdate.class, int.class).get(0);
|
||||
if (packet.getAction() == ClientboundPlayerInfoPacket.Action.UPDATE_DISPLAY_NAME) {
|
||||
IChatBaseComponent newDisplayName = TAB.getInstance().getFeatureManager().onDisplayNameChange(receiver, profile.getId());
|
||||
if (newDisplayName != null) displayNameField.set(nmsData, ((FabricTabPlayer)receiver).getPlatform().toComponent(newDisplayName, receiver.getVersion()));
|
||||
}
|
||||
if (packet.getAction() == ClientboundPlayerInfoPacket.Action.UPDATE_LATENCY) {
|
||||
latencyField.set(nmsData, TAB.getInstance().getFeatureManager().onLatencyChange(receiver, profile.getId(), latencyField.getInt(nmsData)));
|
||||
}
|
||||
if (packet.getAction() == ClientboundPlayerInfoPacket.Action.ADD_PLAYER) {
|
||||
TAB.getInstance().getFeatureManager().onEntryAdd(receiver, profile.getId(), profile.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogin(@NotNull Object packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void modifyPlayers(@NotNull Object teamPacket) {
|
||||
if (TAB.getInstance().getNameTagManager() == null) return;
|
||||
ClientboundSetPlayerTeamPacket packet = (ClientboundSetPlayerTeamPacket) teamPacket;
|
||||
int action = ReflectionUtils.getInstanceFields(ClientboundSetPlayerTeamPacket.class, int.class).get(0).getInt(packet);
|
||||
if (action == 1 || action == 2 || action == 4) return;
|
||||
Collection<String> players = packet.getPlayers();
|
||||
String teamName = packet.getName();
|
||||
if (players == null) return;
|
||||
//creating a new list to prevent NoSuchFieldException in minecraft packet encoder when a player is removed
|
||||
Collection<String> newList = new ArrayList<>();
|
||||
for (String entry : players) {
|
||||
TabPlayer p = getPlayer(entry);
|
||||
if (p == null) {
|
||||
newList.add(entry);
|
||||
continue;
|
||||
}
|
||||
Sorting sorting = TAB.getInstance().getFeatureManager().getFeature(TabConstants.Feature.SORTING);
|
||||
String expectedTeam = sorting.getShortTeamName(p);
|
||||
if (expectedTeam == null) {
|
||||
newList.add(entry);
|
||||
continue;
|
||||
}
|
||||
if (!((NameTag)TAB.getInstance().getNameTagManager()).getDisableChecker().isDisabledPlayer(p) &&
|
||||
!TAB.getInstance().getNameTagManager().hasTeamHandlingPaused(p) && !teamName.equals(expectedTeam)) {
|
||||
logTeamOverride(teamName, p.getName(), expectedTeam);
|
||||
} else {
|
||||
newList.add(entry);
|
||||
}
|
||||
}
|
||||
ReflectionUtils.getFields(ClientboundSetPlayerTeamPacket.class, Collection.class).get(0).set(packet, newList);
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
package me.neznamy.tab.platforms.fabric.v1_17;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.fabric.*;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.backend.EntityData;
|
||||
import me.neznamy.tab.shared.backend.Location;
|
||||
import me.neznamy.tab.shared.chat.IChatBaseComponent;
|
||||
import me.neznamy.tab.shared.features.injection.PipelineInjector;
|
||||
import me.neznamy.tab.shared.platform.TabList;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.ServerScoreboard;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.Objective;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FabricTAB implements VersionLoader {
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedVersions() {
|
||||
return List.of("1.17");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(Level level) {
|
||||
String path = level.dimension().location().getPath();
|
||||
String dimensionSuffix = switch (path) {
|
||||
case "overworld" -> ""; // No suffix for overworld
|
||||
case "the_nether" -> "_nether";
|
||||
default -> "_" + path; // End + default behavior for other dimensions created by mods
|
||||
};
|
||||
return ((ServerLevelData)level.getLevelData()).getLevelName() + dimensionSuffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPing(ServerPlayer player) {
|
||||
return player.latency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(ServerPlayer player, Component message) {
|
||||
player.sendMessage(message, new UUID(0, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabList.Skin propertyToSkin(Property property) {
|
||||
return new TabList.Skin(property.getValue(), property.getSignature());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(CommandSourceStack sender, Component message) {
|
||||
sender.sendSuccess(message, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersion() {
|
||||
return SharedConstants.getCurrentVersion().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMSPT() {
|
||||
return ((FabricPlatform)TAB.getInstance().getPlatform()).getServer().getAverageTickTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component deserialize(String string) {
|
||||
return Component.Serializer.fromJson(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Packet<?> build(TabList.Action action, FabricTabList.Builder entry) {
|
||||
ClientboundPlayerInfoPacket packet = new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.valueOf(action.name()), Collections.emptyList());
|
||||
ReflectionUtils.getFields(ClientboundPlayerInfoPacket.class, List.class).get(0).set(packet,
|
||||
Collections.singletonList(new ClientboundPlayerInfoPacket.PlayerUpdate(
|
||||
entry.createProfile(),
|
||||
entry.getLatency(),
|
||||
GameType.byId(entry.getGameMode()),
|
||||
entry.getDisplayName()
|
||||
)));
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Level getLevel(ServerPlayer player) {
|
||||
return player.level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSneaking(ServerPlayer player) {
|
||||
return player.isCrouching();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityData createDataWatcher(TabPlayer viewer, byte flags, String displayName, boolean nameVisible) {
|
||||
SynchedEntityData data = new SynchedEntityData(null);
|
||||
data.define(new EntityDataAccessor<>(0, EntityDataSerializers.BYTE), flags);
|
||||
data.define(new EntityDataAccessor<>(2, EntityDataSerializers.OPTIONAL_COMPONENT),
|
||||
Optional.of(((FabricTabPlayer)viewer).getPlatform().toComponent(IChatBaseComponent.optimizedComponent(displayName), viewer.getVersion())));
|
||||
data.define(new EntityDataAccessor<>(3, EntityDataSerializers.BOOLEAN), nameVisible);
|
||||
data.define(new EntityDataAccessor<>(15, EntityDataSerializers.BYTE), (byte)16);
|
||||
return () -> data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> spawnEntity(int entityId, UUID id, Object entityType, Location location) {
|
||||
return new ClientboundAddEntityPacket(entityId, id, location.getX(), location.getY(), location.getZ(),
|
||||
0, 0, (EntityType<?>) entityType, 0, Vec3.ZERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> newEntityMetadata(int entityId, EntityData data) {
|
||||
return new ClientboundSetEntityDataPacket(entityId, (SynchedEntityData) data.build(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpawnPlayerPacket(Object packet) {
|
||||
return packet instanceof ClientboundAddPlayerPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpawnedPlayer(Object spawnPacket) {
|
||||
return ((ClientboundAddPlayerPacket) spawnPacket).getEntityId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getDestroyedEntities(Object entityDestroyPacket) {
|
||||
return new int[]{((ClientboundRemoveEntityPacket) entityDestroyPacket).getEntityId()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBundlePacket(Object packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Object> getPackets(Object bundlePacket) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PipelineInjector createPipelineInjector() {
|
||||
return new FabricPipelineInjector();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyEntities(FabricTabPlayer player, int... entities) {
|
||||
for (int entity : entities) {
|
||||
player.sendPacket(new ClientboundRemoveEntityPacket(entity));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCommandCallback() {
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, $) -> new FabricTabCommand().onRegisterCommands(dispatcher));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> newHeaderFooter(Component header, Component footer) {
|
||||
return new ClientboundTabListPacket(header, footer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> setDisplaySlot(int slot, Objective objective) {
|
||||
return new ClientboundSetDisplayObjectivePacket(slot, objective);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Objective newObjective(String name, Component displayName, ObjectiveCriteria.RenderType renderType,
|
||||
@Nullable Component numberFormat) {
|
||||
return new Objective(dummyScoreboard, name, ObjectiveCriteria.DUMMY, displayName, renderType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> registerTeam(PlayerTeam team) {
|
||||
return ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> unregisterTeam(PlayerTeam team) {
|
||||
return ClientboundSetPlayerTeamPacket.createRemovePacket(team);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> updateTeam(PlayerTeam team) {
|
||||
return ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> setScore(String objective, String scoreHolder, int score, Component displayName, @Nullable Component numberFormat) {
|
||||
return new ClientboundSetScorePacket(ServerScoreboard.Method.CHANGE, objective, scoreHolder, score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<?> removeScore(String objective, String scoreHolder) {
|
||||
return new ClientboundSetScorePacket(ServerScoreboard.Method.REMOVE, objective, scoreHolder, 0);
|
||||
}
|
||||
}
|
||||
+19
-3
@@ -41,7 +41,7 @@ public class FabricTAB implements VersionLoader {
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedVersions() {
|
||||
return List.of("1.17.1");
|
||||
return List.of("1.17", "1.17.1");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,8 +147,14 @@ public class FabricTAB implements VersionLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getDestroyedEntities(Object entityDestroyPacket) {
|
||||
return ((ClientboundRemoveEntitiesPacket) entityDestroyPacket).getEntityIds().toIntArray();
|
||||
@SneakyThrows
|
||||
public int[] getDestroyedEntities(Object packet) {
|
||||
if (getServerVersion().equals("1.17")) {
|
||||
return new int[]{(int) ReflectionUtils.getOnlyMethod(packet.getClass(), int.class).invoke(packet)};
|
||||
}
|
||||
|
||||
// 1.17.1
|
||||
return ((ClientboundRemoveEntitiesPacket) packet).getEntityIds().toIntArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,7 +173,17 @@ public class FabricTAB implements VersionLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void destroyEntities(FabricTabPlayer player, int... entities) {
|
||||
if (getServerVersion().equals("1.17")) {
|
||||
for (int entity : entities) {
|
||||
// While the actual packet name is different, fabric-mapped name is the same
|
||||
player.sendPacket(ClientboundRemoveEntitiesPacket.class.getConstructor(int.class).newInstance(entity));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 1.17.1
|
||||
player.sendPacket(new ClientboundRemoveEntitiesPacket(entities));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation(projects.fabric)
|
||||
minecraft("com.mojang:minecraft:1.20.3")
|
||||
minecraft("com.mojang:minecraft:1.20.4")
|
||||
mappings(loom.officialMojangMappings())
|
||||
modImplementation("net.fabricmc:fabric-loader:0.14.17")
|
||||
val fabricApiVersion = "0.90.4+1.20.3"
|
||||
val fabricApiVersion = "0.91.1+1.20.4"
|
||||
modImplementation(fabricApi.module("fabric-api-base", fabricApiVersion))
|
||||
modImplementation(fabricApi.module("fabric-command-api-v2", fabricApiVersion))
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package me.neznamy.tab.platforms.fabric.v1_20_3;
|
||||
package me.neznamy.tab.platforms.fabric.v1_20_4;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.channel.Channel;
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package me.neznamy.tab.platforms.fabric.v1_20_3;
|
||||
package me.neznamy.tab.platforms.fabric.v1_20_4;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import lombok.SneakyThrows;
|
||||
@@ -36,7 +36,7 @@ public class FabricTAB implements VersionLoader {
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedVersions() {
|
||||
return Collections.singletonList("1.20.3");
|
||||
return Arrays.asList("1.20.3", "1.20.4");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -14,17 +14,15 @@ val platforms = setOf(
|
||||
|
||||
val fabrics = setOf(
|
||||
rootProject.projects.fabric,
|
||||
rootProject.projects.fabric.v1144,
|
||||
rootProject.projects.fabric.v1152,
|
||||
rootProject.projects.fabric.v1165,
|
||||
rootProject.projects.fabric.v117,
|
||||
rootProject.projects.fabric.v1171,
|
||||
rootProject.projects.fabric.v1182,
|
||||
rootProject.projects.fabric.v1192,
|
||||
rootProject.projects.fabric.v1193,
|
||||
rootProject.projects.fabric.v1201,
|
||||
rootProject.projects.fabric.v1202,
|
||||
rootProject.projects.fabric.v1203
|
||||
rootProject.projects.fabric.v1204
|
||||
).map { it.dependencyProject }
|
||||
|
||||
tasks {
|
||||
|
||||
+1
-3
@@ -33,15 +33,13 @@ include(":bungeecord")
|
||||
include(":sponge7")
|
||||
include(":sponge8")
|
||||
include(":fabric")
|
||||
include(":fabric:v1_14_4")
|
||||
include(":fabric:v1_15_2")
|
||||
include(":fabric:v1_16_5")
|
||||
include(":fabric:v1_17")
|
||||
include(":fabric:v1_17_1")
|
||||
include(":fabric:v1_18_2")
|
||||
include(":fabric:v1_19_2")
|
||||
include(":fabric:v1_19_3")
|
||||
include(":fabric:v1_20_1")
|
||||
include(":fabric:v1_20_2")
|
||||
include(":fabric:v1_20_3")
|
||||
include(":fabric:v1_20_4")
|
||||
include(":jar")
|
||||
@@ -13,6 +13,7 @@ public enum ProtocolVersion {
|
||||
UNKNOWN_SERVER_VERSION ("Unknown"),
|
||||
UNKNOWN_CLIENT_VERSION ("Unknown"),
|
||||
PROXY ("Proxy"),
|
||||
V1_20_4 (765),
|
||||
V1_20_3 (765),
|
||||
V1_20_2 (764),
|
||||
V1_20_1 (763),
|
||||
|
||||
@@ -11,12 +11,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class MiniMessageFormat implements RGBFormatter {
|
||||
|
||||
@Override
|
||||
public @NotNull String reformat(@NotNull String text) {
|
||||
if (text.contains("<") && !text.contains(EnumChatFormat.COLOR_STRING)) {
|
||||
try {
|
||||
return LegacyComponentSerializer.legacySection().serialize(MiniMessage.miniMessage().deserialize(text));
|
||||
} catch (Throwable ignored) {}
|
||||
@NotNull
|
||||
public String reformat(@NotNull String text) {
|
||||
if (!text.contains("<")) return text; // User did not even attempt to use MiniMessage
|
||||
String modified = text.replace(EnumChatFormat.WHITE.getFormat(), "<white>"); // Forced &f in scoreboard
|
||||
if (modified.contains(EnumChatFormat.COLOR_STRING)) return text;
|
||||
try {
|
||||
return LegacyComponentSerializer.legacySection().serialize(MiniMessage.miniMessage().deserialize(modified));
|
||||
} catch (Throwable ignored) {
|
||||
return text;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ public class ScoreboardImpl extends TabFeature implements me.neznamy.tab.api.sco
|
||||
ScoreboardManagerImpl.OBJECTIVE_NAME,
|
||||
refreshed.getProperty(titleProperty).updateAndGet(),
|
||||
Scoreboard.HealthDisplay.INTEGER,
|
||||
new IChatBaseComponent()
|
||||
new IChatBaseComponent("")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -211,14 +211,14 @@ public abstract class ScoreboardLine extends TabFeature implements Line {
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits text using {@code "|"} symbol, where first part is text to display and
|
||||
* Splits text using {@code "||"} string, where first part is text to display and
|
||||
* second part is number format (optional)
|
||||
*
|
||||
* @param text
|
||||
* Inputted text to categorize
|
||||
*/
|
||||
protected void initializeText(@NotNull String text) {
|
||||
String[] split = text.split("\\|");
|
||||
String[] split = text.split("\\|\\|");
|
||||
this.text = split[0];
|
||||
this.numberFormat = split.length >= 2 ? split[1] : "";
|
||||
}
|
||||
|
||||
@@ -35,9 +35,7 @@ public class ViaVersionHook {
|
||||
if (!installed) return TAB.getInstance().getServerVersion().getNetworkId();
|
||||
int version = Via.getAPI().getPlayerVersion(player);
|
||||
if (version == -1) {
|
||||
TAB.getInstance().getPlatform().logWarn(new IChatBaseComponent("ViaVersion returned protocol version -1 for player " + playerName +
|
||||
". Using server's version (" + TAB.getInstance().getServerVersion().getNetworkId() + " - " +
|
||||
TAB.getInstance().getServerVersion().getFriendlyName() + ")"));
|
||||
// Player got instantly disconnected with a packet error
|
||||
return TAB.getInstance().getServerVersion().getNetworkId();
|
||||
}
|
||||
ProtocolVersion protocol = ProtocolVersion.fromNetworkId(version);
|
||||
|
||||
@@ -114,16 +114,15 @@ scoreboard:
|
||||
- "&7%date%"
|
||||
- "%animation:MyAnimation1%"
|
||||
- "&6Online:"
|
||||
- "* &eOnline&7:|%online%"
|
||||
- "* &eCurrent World&7:|%worldonline%"
|
||||
- "* &eStaff&7:|%staffonline%"
|
||||
- "* &eOnline&7:||%online%"
|
||||
- "* &eCurrent World&7:||%worldonline%"
|
||||
- "* &eStaff&7:||%staffonline%"
|
||||
- ""
|
||||
- "&6Personal Info:"
|
||||
- "* &bRank&7:|%group%"
|
||||
- "* &bPing&7:|%ping%&8ms"
|
||||
- "* &bWorld&7:|%world%"
|
||||
- "* &bRank&7:||%group%"
|
||||
- "* &bPing&7:||%ping%&8ms"
|
||||
- "* &bWorld&7:||%world%"
|
||||
- "%animation:MyAnimation1%"
|
||||
|
||||
scoreboard:
|
||||
title: "<#E0B11E>MyServer</#FF0000>"
|
||||
lines:
|
||||
|
||||
Reference in new issue
Block a user