removed unused code in legacy branch

This commit is contained in:
creeper123123321 2024-07-07 14:37:39 -03:00
parent ba06c0d939
commit 4a6905dc44
338 changed files with 0 additions and 18540 deletions

View File

@ -143,7 +143,6 @@ dependencies {
includeJ8("com.viaversion:viaversion:${rootProject.viaver_version}")
include("org.yaml:snakeyaml:${rootProject.yaml_version}")
//include("com.github.TinfoilMC:ClientCommands:1.1.0")
}
remapJar {
@ -198,9 +197,7 @@ curseforge {
mainArtifact(remapJar) {
displayName = versionNameMsg
relations {
//optionalDependency("fabric-api")
optionalDependency("legacy-fabric-api")
//embeddedLibrary("cotton-client-commands")
}
}
@ -230,7 +227,6 @@ modrinth {
loaders.set(["fabric"])
dependencies {
//optional.project "P7dR8mSH" // fabric api
optional.project "9CJED7xi" // legacy fabric api
embedded.project "P1OZGk5p" // viaversion
}

View File

@ -10,16 +10,6 @@ rootProject.name = "ViaFabric"
include("viafabric-mc189")
include("viafabric-mc1122")
//include("viafabric-mc1144")
//include("viafabric-mc1152")
//include("viafabric-mc1165")
//include("viafabric-mc1171")
//include("viafabric-mc1182")
//include("viafabric-mc1194")
//include("viafabric-mc1201")
//include("viafabric-mc1204")
//include("viafabric-mc1206")
//include("viafabric-mc121")
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"

View File

@ -1,8 +0,0 @@
dependencies {
minecraft("com.mojang:minecraft:1.14.4")
mappings("net.fabricmc:yarn:1.14.4+build.18:v2")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.28.5+1.14")
modImplementation("io.github.prospector:modmenu:1.7.17+build.1")
modImplementation("com.github.TinfoilMC:ClientCommands:1.1.0")
}

View File

@ -1,113 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc1144.commands.VFCommandHandler;
import com.viaversion.fabric.mc1144.platform.FabricPlatform;
import com.viaversion.fabric.mc1144.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.DefaultEventLoop;
import io.netty.channel.EventLoop;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.server.command.CommandSource;
import org.apache.logging.log4j.LogManager;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Logger;
public class ViaFabric implements ModInitializer {
public static final Logger JLOGGER = new JLoggerToLog4j(LogManager.getLogger("ViaFabric"));
public static final ExecutorService ASYNC_EXECUTOR;
public static final EventLoop EVENT_LOOP;
public static final CompletableFuture<Void> INIT_FUTURE = new CompletableFuture<>();
public static VFConfig config;
static {
ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ViaFabric-%d").build();
ASYNC_EXECUTOR = Executors.newFixedThreadPool(8, factory);
EVENT_LOOP = new DefaultEventLoop(factory);
EVENT_LOOP.submit(INIT_FUTURE::join); // https://github.com/ViaVersion/ViaFabric/issues/53 ugly workaround code but works tm
}
public static <S extends CommandSource> LiteralArgumentBuilder<S> command(String commandName) {
return LiteralArgumentBuilder.<S>literal(commandName)
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
public void onInitialize() {
FabricPlatform platform = new FabricPlatform();
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();
ViaManagerImpl manager = (ViaManagerImpl) Via.getManager();
manager.init();
HostnameParserProtocol.INSTANCE.initialize();
HostnameParserProtocol.INSTANCE.register(Via.getManager().getProviders());
ProtocolVersion.register(-2, "AUTO");
FabricLoader.getInstance().getEntrypoints("viafabric:via_api_initialized", Runnable.class).forEach(Runnable::run);
registerCommandsV1();
config = new VFConfig(FabricLoader.getInstance().getConfigDir().resolve("ViaFabric")
.resolve("viafabric.yml").toFile(), JLOGGER);
manager.onServerLoaded();
INIT_FUTURE.complete(null);
}
private void registerCommandsV1() {
try {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("viaversion")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("viaver")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("vvfabric")));
} catch (NoClassDefFoundError ignored) {
JLOGGER.info("Couldn't register command as Fabric Commands V1 isn't installed");
}
}
}

View File

@ -1,83 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.commands;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.util.ComponentUtil;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.server.command.CommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
private final CommandSource source;
public NMSCommandSender(CommandSource source) {
this.source = source;
}
@Override
public boolean hasPermission(String s) {
// https://gaming.stackexchange.com/questions/138602/what-does-op-permission-level-do
return source.hasPermissionLevel(3);
}
public static Text fromLegacy(String legacy) {
return Text.Serializer.fromJson(ComponentUtil.legacyToJsonString(legacy));
}
@Override
public void sendMessage(String s) {
if (source instanceof ServerCommandSource) {
((ServerCommandSource) source).sendFeedback(fromLegacy(s), false);
} else if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT
&& source instanceof ClientCommandSource) {
MinecraftClient.getInstance().player.addChatMessage(fromLegacy(s), false);
}
}
@Override
public UUID getUUID() {
if (source instanceof ServerCommandSource) {
Entity entity = ((ServerCommandSource) source).getEntity();
if (entity != null) return entity.getUuid();
} else if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT
&& source instanceof ClientCommandSource) {
return MinecraftClient.getInstance().player.getUuid();
}
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override
public String getName() {
if (source instanceof ServerCommandSource) {
return ((ServerCommandSource) source).getName();
} else if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT
&& source instanceof ClientCommandSource) {
return MinecraftClient.getInstance().player.getEntityName();
}
return "?";
}
}

View File

@ -1,30 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.commands;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.mojang.brigadier.CommandDispatcher;
import io.github.cottonmc.clientcommands.ClientCommandPlugin;
import io.github.cottonmc.clientcommands.CottonClientCommandSource;
public class VFClientCommands implements ClientCommandPlugin {
@Override
public void registerCommands(CommandDispatcher<CottonClientCommandSource> commandDispatcher) {
commandDispatcher.register(ViaFabric.command("viafabricclient"));
}
}

View File

@ -1,72 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.commands;
import com.viaversion.fabric.common.commands.subs.LeakDetectSubCommand;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.server.command.CommandSource;
import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());
} catch (Exception e) {
e.printStackTrace();
}
}
public int execute(CommandContext<? extends CommandSource> ctx) {
String[] args = new String[0];
try {
args = StringArgumentType.getString(ctx, "args").split(" ");
} catch (IllegalArgumentException ignored) {
}
onCommand(
new NMSCommandSender(ctx.getSource()),
args
);
return 1;
}
public CompletableFuture<Suggestions> suggestion(CommandContext<? extends CommandSource> ctx, SuggestionsBuilder builder) {
String[] args;
try {
args = StringArgumentType.getString(ctx, "args").split(" ", -1);
} catch (IllegalArgumentException ignored) {
args = new String[]{""};
}
String[] pref = args.clone();
pref[pref.length - 1] = "";
String prefix = String.join(" ", pref);
onTabComplete(new NMSCommandSender(ctx.getSource()), args)
.stream()
.map(it -> {
SuggestionsBuilder b = new SuggestionsBuilder(builder.getInput(), prefix.length() + builder.getStart());
b.suggest(it);
return b;
})
.forEach(builder::add);
return builder.buildFuture();
}
}

View File

@ -1,35 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.gui;
import io.github.prospector.modmenu.api.ModMenuApi;
import net.minecraft.client.gui.screen.Screen;
import java.util.function.Function;
public class ModMenuConfig implements ModMenuApi {
@Override
public String getModId() {
return "viafabric";
}
@Override
public Function<Screen, ? extends Screen> getConfigScreenFactory() {
return ViaConfigScreen::new;
}
}

View File

@ -1,170 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.gui;
import com.viaversion.fabric.common.config.AbstractViaConfigScreen;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.TranslatableText;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
public class ViaConfigScreen extends Screen implements AbstractViaConfigScreen {
private static CompletableFuture<Void> latestProtocolSave;
private final Screen parent;
private TextFieldWidget protocolVersion;
public ViaConfigScreen(Screen parent) {
super(new TranslatableText(TITLE_TRANSLATE_ID));
this.parent = parent;
}
@Override
protected void init() {
int entries = 0;
this.addButton(new ButtonWidget(calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, getClientSideText().asString(), this::onClickClientSide));
entries++;
this.addButton(new ButtonWidget(calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, getHideViaButtonText().asString(), this::onHideViaButton));
entries++;
protocolVersion = new TextFieldWidget(this.font,
calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, new TranslatableText(VERSION_TRANSLATE_ID).asString());
entries++;
protocolVersion.setTextPredicate(ProtocolUtils::isStartOfProtocolText);
protocolVersion.setChangedListener(this::onChangeVersionField);
int clientSideVersion = ViaFabric.config.getClientSideVersion();
protocolVersion.setText(ProtocolUtils.getProtocolName(clientSideVersion));
this.children.add(protocolVersion);
this.addButton(new ButtonWidget(this.width / 2 - 100, this.height - 40, 200, 20, new TranslatableText("gui.done").asString(), (buttonWidget) -> MinecraftClient.getInstance().openScreen(this.parent)));
}
private void onChangeVersionField(String text) {
protocolVersion.setSuggestion(null);
int newVersion = ViaFabric.config.getClientSideVersion();
Integer parsed = ProtocolUtils.parseProtocolId(text);
boolean validProtocol;
if (parsed != null) {
newVersion = parsed;
validProtocol = true;
} else {
validProtocol = false;
String[] suggestions = ProtocolUtils.getProtocolSuggestions(text);
if (suggestions.length == 1) {
protocolVersion.setSuggestion(suggestions[0].substring(text.length()));
}
}
protocolVersion.setEditableColor(getProtocolTextColor(ProtocolVersion.getProtocol(newVersion), validProtocol));
int finalNewVersion = newVersion;
if (latestProtocolSave == null) latestProtocolSave = CompletableFuture.completedFuture(null);
ViaFabric.config.setClientSideVersion(finalNewVersion);
latestProtocolSave = latestProtocolSave.thenRunAsync(ViaFabric.config::save, ViaFabric.ASYNC_EXECUTOR);
}
private void onClickClientSide(ButtonWidget widget) {
if (!ViaFabric.config.isClientSideEnabled()) {
MinecraftClient.getInstance().openScreen(new ConfirmScreen(
answer -> {
if (answer) {
ViaFabric.config.setClientSideEnabled(true);
ViaFabric.config.setClientSideVersion(-2); // AUTO
ViaFabric.config.save();
widget.setMessage(getClientSideText().asString());
}
MinecraftClient.getInstance().openScreen(this);
},
new TranslatableText("gui.enable_client_side.question"),
new TranslatableText("gui.enable_client_side.warning"),
new TranslatableText("gui.enable_client_side.enable").asString(),
new TranslatableText("gui.cancel").asString()
));
} else {
ViaFabric.config.setClientSideEnabled(false);
ViaFabric.config.save();
}
widget.setMessage(getClientSideText().asString());
}
@Override
public void removed() {
ViaFabric.config.save();
}
@Override
public void onClose() {
MinecraftClient.getInstance().openScreen(this.parent);
}
private TranslatableText getClientSideText() {
return ViaFabric.config.isClientSideEnabled() ?
new TranslatableText("gui.client_side.disable")
: new TranslatableText("gui.client_side.enable");
}
private TranslatableText getHideViaButtonText() {
return ViaFabric.config.isHideButton() ?
new TranslatableText("gui.hide_via_button.disable") : new TranslatableText("gui.hide_via_button.enable");
}
private void onHideViaButton(ButtonWidget widget) {
ViaFabric.config.setHideButton(!ViaFabric.config.isHideButton());
ViaFabric.config.save();
widget.setMessage(getHideViaButtonText().asString());
}
@Override
public void render(int mouseX, int mouseY, float delta) {
this.renderBackground();
drawCenteredString(this.font, this.title.asString(), this.width / 2, 20, 16777215);
super.render(mouseX, mouseY, delta);
protocolVersion.render(mouseX, mouseY, delta);
}
@Override
public void tick() {
super.tick();
protocolVersion.tick();
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(targets = "net.minecraft.client.gui.screen.ConnectScreen$1")
public class MixinConnectScreenThread {
@Redirect(method = "run()V", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
}
}

View File

@ -1,46 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@Shadow
private static String[] resolveSrv(String address) {
throw new AssertionError();
}
@Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;resolveSrv(Ljava/lang/String;)[Ljava/lang/String;"))
private static String[] modifySrvAddr(String address) {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return resolveSrv(address);
}
String[] resolvedSrv = resolveSrv(viaAddr.serverAddress);
resolvedSrv[0] = resolvedSrv[0].replaceAll("\\.$", "") + "." + viaAddr.getSuffixWithOptions();
return resolvedSrv;
}
}

View File

@ -1,42 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.MultiplayerServerListPinger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(MultiplayerServerListPinger.class)
public class MixinServerPinger {
@Redirect(method = "add", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.debug.client;
import io.netty.channel.ChannelHandlerContext;
import net.minecraft.network.ClientConnection;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConnection.class)
public abstract class MixinClientConnection {
@Shadow
@Final
private static Logger LOGGER;
@Inject(method = "exceptionCaught", at = @At("TAIL"))
public void exceptionCaught(ChannelHandlerContext context, Throwable ex, CallbackInfo ci) {
LOGGER.error("Packet error", ex);
}
}

View File

@ -1,29 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.debug.client;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientConnection.class)
public interface MixinClientConnectionAccessor {
@Accessor
Channel getChannel();
}

View File

@ -1,56 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.debug.client;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
import io.netty.channel.ChannelHandler;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.List;
@Mixin(DebugHud.class)
public class MixinDebugHud {
@Inject(at = @At("RETURN"), method = "getLeftText")
protected void getLeftText(CallbackInfoReturnable<List<String>> info) {
String line = "[ViaFabric] I: " + Via.getManager().getConnectionManager().getConnections().size() + " (F: "
+ Via.getManager().getConnectionManager().getConnectedClients().size() + ")";
@SuppressWarnings("ConstantConditions") ChannelHandler viaDecoder = ((MixinClientConnectionAccessor) MinecraftClient.getInstance().getNetworkHandler()
.getConnection()).getChannel().pipeline().get(CommonTransformer.HANDLER_DECODER_NAME);
if (viaDecoder instanceof FabricDecodeHandler) {
UserConnection connection = ((FabricDecodeHandler) viaDecoder).getInfo();
ProtocolInfo protocol = connection.getProtocolInfo();
if (protocol != null) {
ProtocolVersion serverVer = protocol.serverProtocolVersion();
ProtocolVersion clientVer = protocol.protocolVersion();
line += " / C: " + clientVer + " S: " + serverVer + " A: " + connection.isActive();
}
}
info.getReturnValue().add(line);
}
}

View File

@ -1,55 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.gui.client;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.viaversion.fabric.mc1144.gui.ViaConfigScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MultiplayerScreen.class)
public abstract class MixinMultiplayerScreen extends Screen {
protected MixinMultiplayerScreen(Text title, UnsupportedOperationException e) {
super(title);
throw e;
}
@Inject(method = "init", at = @At("TAIL"), remap = false)
private void onInit(CallbackInfo ci) {
ButtonWidget enableClientSideViaVersion = new TexturedButtonWidget(this.width / 2 + 113, 10,
40, 20, // Size
0, 0, // Start pos of texture
20, // v Hover offset
new Identifier("viafabric:textures/gui/widgets.png"),
256, 256, // Texture size
it -> MinecraftClient.getInstance().openScreen(new ViaConfigScreen(this)),
new TranslatableText("gui.via_button").asString());
if (ViaFabric.config.isHideButton()) enableClientSideViaVersion.visible = false;
addButton(enableClientSideViaVersion);
}
}

View File

@ -1,51 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.mc1144.mixin.debug.client.MixinClientConnectionAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.client.network.MultiplayerServerListPinger$1")
public abstract class MixinMultiplayerServerListPingerListener implements ClientQueryPacketListener {
@Accessor
abstract ClientConnection getField_3774(); // Synthetic
@Accessor
abstract ServerInfo getField_3776(); // Synthetic
@Inject(method = "onResponse", at = @At(value = "HEAD"))
private void onResponseCaptureServerInfo(QueryResponseS2CPacket packet, CallbackInfo ci) {
FabricDecodeHandler decoder = ((MixinClientConnectionAccessor) this.getField_3774()).getChannel()
.pipeline().get(FabricDecodeHandler.class);
if (decoder != null) {
((ViaServerInfo) getField_3776()).viaFabric$setTranslating(decoder.getInfo().isActive());
((ViaServerInfo) getField_3776()).viaFabric$setServerVer(decoder.getInfo().getProtocolInfo().getServerProtocolVersion());
}
}
}

View File

@ -1,60 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
public class MixinServerEntry {
@Shadow
@Final
private ServerInfo server;
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/texture/TextureManager;bindTexture(Lnet/minecraft/util/Identifier;)V"))
private void redirectPingIcon(TextureManager textureManager, Identifier identifier) {
if (identifier.equals(DrawableHelper.GUI_ICONS_LOCATION) && ((ViaServerInfo) this.server).viaFabric$translating()) {
textureManager.bindTexture(new Identifier("viafabric:textures/gui/icons.png"));
return;
}
textureManager.bindTexture(identifier);
}
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Ljava/lang/String;)V"))
private void addServerVer(MultiplayerScreen multiplayerScreen, String text) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).viaFabric$getServerVer());
StringBuilder builder = new StringBuilder(text);
builder.append("\n");
builder.append((new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion())).asString());
builder.append("\n");
builder.append(this.server.version);
multiplayerScreen.setTooltip(builder.toString());
}
}

View File

@ -1,52 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import net.minecraft.client.network.ServerInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@Mixin(ServerInfo.class)
public class MixinServerInfo implements ViaServerInfo {
@Unique
private boolean viaFabric$translating;
@Unique
private int viaFabric$serverVer;
@Override
public int viaFabric$getServerVer() {
return viaFabric$serverVer;
}
@Override
public void viaFabric$setServerVer(int ver) {
this.viaFabric$serverVer = ver;
}
@Override
public boolean viaFabric$translating() {
return viaFabric$translating;
}
@Override
public void viaFabric$setTranslating(boolean via) {
this.viaFabric$translating = via;
}
}

View File

@ -1,38 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.pipeline;
import com.viaversion.fabric.common.handler.PipelineReorderEvent;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Shadow
private Channel channel;
@Inject(method = "setCompressionThreshold", at = @At("RETURN"))
private void reorderCompression(int compressionThreshold, CallbackInfo ci) {
channel.pipeline().fireUserEventTriggered(new PipelineReorderEvent());
}
}

View File

@ -1,45 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.pipeline;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.server.ServerNetworkIo$1")
public class MixinServerNetworkIoChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel);
new ProtocolPipelineImpl(user);
channel.pipeline().addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user));
channel.pipeline().addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -1,44 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.pipeline.client;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.viaversion.fabric.mc1144.service.ProtocolAutoDetector;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Inject(method = "connect", at = @At("HEAD"))
private static void onConnect(InetAddress address, int port, boolean shouldUseNativeTransport, CallbackInfoReturnable<ClientConnection> cir) {
try {
if (!ViaFabric.config.isClientSideEnabled()) return;
ProtocolAutoDetector.detectVersion(new InetSocketAddress(address, port)).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
ViaFabric.JLOGGER.log(Level.WARNING, "Could not auto-detect protocol for " + address + " " + e);
}
}
}

View File

@ -1,47 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.pipeline.client;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.network.ClientConnection$1")
public class MixinClientConnectionChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel, true);
new ProtocolPipelineImpl(user).add(HostnameParserProtocol.INSTANCE);
channel.pipeline()
.addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user))
.addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -1,34 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.mixin.shutdown.server;
import com.viaversion.viaversion.ViaManagerImpl;
import com.viaversion.viaversion.api.Via;
import net.minecraft.server.MinecraftServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftServer.class)
public class MixinMinecraftServer {
@Inject(method = "stop", at = @At("TAIL"))
private void onStop(CallbackInfo ci) {
((ViaManagerImpl) Via.getManager()).destroy();
}
}

View File

@ -1,28 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.platform;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import net.minecraft.SharedConstants;
public class FabricNativeVersionProvider implements NativeVersionProvider {
@Override
public int getNativeServerVersion() {
return SharedConstants.getGameVersion().getProtocolVersion();
}
}

View File

@ -1,141 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.platform;
import com.viaversion.fabric.common.commands.UserCommandSender;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import com.viaversion.fabric.common.provider.AbstractFabricPlatform;
import com.viaversion.fabric.common.util.FutureTaskId;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.viaversion.fabric.mc1144.commands.NMSCommandSender;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import io.netty.channel.EventLoop;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.network.MessageType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import java.util.logging.Level;
public class FabricPlatform extends AbstractFabricPlatform {
public static MinecraftServer getServer() {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
return getIntegratedServer();
}
return (MinecraftServer) FabricLoader.getInstance().getGameInstance();
}
@Environment(EnvType.CLIENT)
private static MinecraftServer getIntegratedServer() {
return MinecraftClient.getInstance().getServer();
}
@Override
public FutureTaskId runSync(Runnable runnable) {
if (getServer() != null) {
return runServerSync(runnable);
} else {
return runEventLoop(runnable);
}
}
private FutureTaskId runServerSync(Runnable runnable) {
// Kick task needs to be on main thread, it does already have error logger
return new FutureTaskId(CompletableFuture.runAsync(runnable, getServer()));
}
@Override
public ViaCommandSender[] getOnlinePlayers() {
MinecraftServer server = getServer();
if (server != null && server.isOnThread()) {
return getServerPlayers();
}
return Via.getManager().getConnectionManager().getConnectedClients().values().stream()
.map(UserCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
private ViaCommandSender[] getServerPlayers() {
return getServer().getPlayerManager().getPlayerList().stream()
.map(Entity::getCommandSource)
.map(NMSCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
@Override
public void sendMessage(UUID uuid, String s) {
sendMessageServer(uuid, s);
}
private void sendMessageServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return;
runServerSync(() -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return;
player.sendChatMessage(NMSCommandSender.fromLegacy(s), MessageType.SYSTEM);
});
}
@Override
public boolean kickPlayer(UUID uuid, String s) {
return kickServer(uuid, s);
}
private boolean kickServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return false;
Supplier<Boolean> kickTask = () -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return false;
player.networkHandler.disconnect(NMSCommandSender.fromLegacy(s));
return true;
};
if (server.isOnThread()) {
return kickTask.get();
} else {
ViaFabric.JLOGGER.log(Level.WARNING, "Weird!? Player kicking was called off-thread", new Throwable());
runServerSync(kickTask::get);
}
return false; // Can't know if it worked
}
@Override
protected void installNativeVersionProvider() {
Via.getManager().getProviders().use(NativeVersionProvider.class, new FabricNativeVersionProvider());
}
@Override
protected ExecutorService asyncService() {
return ViaFabric.ASYNC_EXECUTOR;
}
@Override
protected EventLoop eventLoop() {
return ViaFabric.EVENT_LOOP;
}
}

View File

@ -1,51 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.platform;
import com.viaversion.fabric.mc1144.providers.VFHandItemProvider;
import com.viaversion.fabric.mc1144.providers.FabricVersionProvider;
import com.viaversion.fabric.mc1144.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.platform.ViaPlatformLoader;
import com.viaversion.viaversion.api.protocol.version.VersionProvider;
public class VFLoader implements ViaPlatformLoader {
@Override
public void load() {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override
public void unload() {
// Nothing to do
}
}

View File

@ -1,45 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.providers;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.AbstractFabricVersionProvider;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.viaversion.fabric.mc1144.service.ProtocolAutoDetector;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
public class FabricVersionProvider extends AbstractFabricVersionProvider {
@Override
protected Logger getLogger() {
return ViaFabric.JLOGGER;
}
@Override
protected VFConfig getConfig() {
return ViaFabric.config;
}
@Override
protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
return ProtocolAutoDetector.detectVersion(address);
}
}

View File

@ -1,75 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.providers;
import com.viaversion.fabric.common.util.RemappingUtil;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.Identifier;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
public class VFHandItemProvider extends HandItemProvider
{
public Item clientItem = null;
@Override
public Item getHandItem(UserConnection info) {
if (info.isClientSide()) {
return getClientItem();
}
return super.getHandItem(info);
}
private Item getClientItem() {
if (clientItem == null) {
return new DataItem(0, (byte) 0, null);
}
return clientItem.copy();
}
@Environment(EnvType.CLIENT)
public void registerClientTick() {
try {
ClientTickEvents.END_CLIENT_TICK.register(world -> tickClient());
} catch (NoClassDefFoundError ignored2) {
ViaFabric.JLOGGER.info("Fabric Lifecycle V0 isn't installed");
}
}
private void tickClient() {
ClientPlayerEntity p = MinecraftClient.getInstance().player;
if (p != null) {
clientItem = fromNative(p.inventory.getMainHandStack());
}
}
private Item fromNative(ItemStack original) {
Identifier iid = Registry.ITEM.getId(original.getItem());
int id = RemappingUtil.swordId(iid.toString());
return new DataItem(id, (byte) original.getCount(), (short) original.getDamage(), null);
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public BlockPosition getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new BlockPosition(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -1,142 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1144.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
import net.minecraft.network.packet.s2c.query.QueryPongS2CPacket;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@Environment(EnvType.CLIENT)
public class ProtocolAutoDetector {
private static final LoadingCache<InetSocketAddress, CompletableFuture<ProtocolVersion>> SERVER_VER = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.SECONDS)
.build(CacheLoader.from((address) -> {
CompletableFuture<ProtocolVersion> future = new CompletableFuture<>();
try {
final ClientConnection clientConnection = new ClientConnection(NetworkSide.CLIENTBOUND);
ChannelFuture ch = new Bootstrap()
.group(ClientConnection.CLIENT_IO_GROUP.get())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) {
try {
channel.config().setOption(ChannelOption.TCP_NODELAY, true);
channel.config().setOption(ChannelOption.IP_TOS, 0x18); // Stolen from Velocity, low delay, high reliability
} catch (ChannelException ignored) {
}
channel.pipeline()
.addLast("timeout", new ReadTimeoutHandler(30))
.addLast("splitter", new SplitterHandler())
.addLast("decoder", new DecoderHandler(NetworkSide.CLIENTBOUND))
.addLast("prepender", new SizePrepender())
.addLast("encoder", new PacketEncoder(NetworkSide.SERVERBOUND))
.addLast("packet_handler", clientConnection);
}
})
.connect(address);
ch.addListener(future1 -> {
if (!future1.isSuccess()) {
future.completeExceptionally(future1.cause());
} else {
ch.channel().eventLoop().execute(() -> { // needs to execute after channel init
clientConnection.setPacketListener(new ClientQueryPacketListener() {
@Override
public void onResponse(QueryResponseS2CPacket packet) {
ServerMetadata meta = packet.getServerMetadata();
ServerMetadata.Version version;
if (meta != null && (version = meta.getVersion()) != null) {
ProtocolVersion ver = ProtocolVersion.getProtocol(version.getProtocolVersion());
future.complete(ver);
ViaFabric.JLOGGER.info("Auto-detected " + ver + " for " + address);
} else {
future.completeExceptionally(new IllegalArgumentException("Null version in query response"));
}
clientConnection.disconnect(new LiteralText(""));
}
@Override
public void onPong(QueryPongS2CPacket packet) {
clientConnection.disconnect(new LiteralText("Pong not requested!"));
}
@Override
public void onDisconnected(Text reason) {
future.completeExceptionally(new IllegalStateException(reason.asString()));
}
@Override
public ClientConnection getConnection() {
return clientConnection;
}
});
clientConnection.send(new HandshakeC2SPacket(address.getHostString(),
address.getPort(), NetworkState.STATUS));
clientConnection.send(new QueryRequestC2SPacket());
});
}
});
} catch (Throwable throwable) {
future.completeExceptionally(throwable);
}
return future;
}));
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {
ViaFabric.JLOGGER.log(Level.WARNING, "Protocol auto detector error: ", e);
return CompletableFuture.completedFuture(null);
}
}
}

View File

@ -1,80 +0,0 @@
{
"schemaVersion": 1,
"id": "viafabric-mc1144",
"name": "ViaFabric for 1.14",
"version": "${version}",
"description": "${description}",
"license": "GPL-3.0",
"contact": {
"homepage": "https://viaversion.com/fabric",
"issues": "https://github.com/ViaVersion/ViaFabric/issues",
"sources": "https://github.com/ViaVersion/ViaFabric"
},
"environment": "*",
"authors": [
{
"name": "creeper123123321",
"contact": {
"homepage": "https://creeper123123321.github.io/"
}
},
{
"name": "FlorianMichael/EnZaXD",
"contact": {
"homepage": "https://github.com/FlorianMichael"
}
},
{
"name": "kennytv",
"contact": {
"homepage": "https://kennytv.eu"
}
},
{
"name": "Kichura",
"contact": {
"homepage": "https://github.com/Kichura"
}
}
],
"contributors": [
{
"name": "GitHub contributors",
"contact": {
"homepage": "https://github.com/ViaVersion/ViaFabric/graphs/contributors"
}
}
],
"entrypoints": {
"main": [
"com.viaversion.fabric.mc1144.ViaFabric"
],
"cotton-client-commands": [
"com.viaversion.fabric.mc1144.commands.VFClientCommands"
],
"modmenu": [
"com.viaversion.fabric.mc1144.gui.ModMenuConfig"
]
},
"depends": {
"fabric-resource-loader-v0": "*",
"minecraft": "1.14.4",
"viafabric": "*"
},
"recommends": {
"fabric-command-api-v1": "*",
"cotton-client-commands": "*"
},
"mixins": [
"mixins.viafabric1144.address.json",
"mixins.viafabric1144.gui.json",
"mixins.viafabric1144.debug.json",
"mixins.viafabric1144.pipeline.json",
"mixins.viafabric1144.shutdown.json"
],
"custom": {
"modmenu": {
"parent": "viafabric"
}
}
}

View File

@ -1,15 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1144.mixin.address",
"mixins": [
],
"client": [
"client.MixinConnectScreenThread",
"client.MixinServerAddress",
"client.MixinServerPinger"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,15 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1144.mixin.debug",
"mixins": [
],
"client": [
"client.MixinClientConnectionAccessor",
"client.MixinDebugHud",
"client.MixinClientConnection"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,16 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1144.mixin.gui",
"mixins": [
"client.MixinMultiplayerServerListPingerListener"
],
"client": [
"client.MixinMultiplayerScreen",
"client.MixinServerEntry",
"client.MixinServerInfo"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,16 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1144.mixin.pipeline",
"mixins": [
"MixinClientConnection",
"MixinServerNetworkIoChInit"
],
"client": [
"client.MixinClientConnection",
"client.MixinClientConnectionChInit"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@ -1,13 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1144.mixin.shutdown",
"mixins": [
],
"server": [
"server.MixinMinecraftServer"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,8 +0,0 @@
dependencies {
minecraft("com.mojang:minecraft:1.15.2")
mappings("net.fabricmc:yarn:1.15.2+build.17:v2")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.28.5+1.15")
modImplementation("io.github.prospector:modmenu:1.10.4+build.1")
modImplementation("com.github.TinfoilMC:ClientCommands:1.1.0")
}

View File

@ -1,113 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc1152.commands.VFCommandHandler;
import com.viaversion.fabric.mc1152.platform.FabricPlatform;
import com.viaversion.fabric.mc1152.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.DefaultEventLoop;
import io.netty.channel.EventLoop;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.server.command.CommandSource;
import org.apache.logging.log4j.LogManager;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Logger;
public class ViaFabric implements ModInitializer {
public static final Logger JLOGGER = new JLoggerToLog4j(LogManager.getLogger("ViaFabric"));
public static final ExecutorService ASYNC_EXECUTOR;
public static final EventLoop EVENT_LOOP;
public static final CompletableFuture<Void> INIT_FUTURE = new CompletableFuture<>();
public static VFConfig config;
static {
ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ViaFabric-%d").build();
ASYNC_EXECUTOR = Executors.newFixedThreadPool(8, factory);
EVENT_LOOP = new DefaultEventLoop(factory);
EVENT_LOOP.submit(INIT_FUTURE::join); // https://github.com/ViaVersion/ViaFabric/issues/53 ugly workaround code but works tm
}
public static <S extends CommandSource> LiteralArgumentBuilder<S> command(String commandName) {
return LiteralArgumentBuilder.<S>literal(commandName)
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
public void onInitialize() {
FabricPlatform platform = new FabricPlatform();
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();
ViaManagerImpl manager = (ViaManagerImpl) Via.getManager();
manager.init();
HostnameParserProtocol.INSTANCE.initialize();
HostnameParserProtocol.INSTANCE.register(Via.getManager().getProviders());
ProtocolVersion.register(-2, "AUTO");
FabricLoader.getInstance().getEntrypoints("viafabric:via_api_initialized", Runnable.class).forEach(Runnable::run);
registerCommandsV1();
config = new VFConfig(FabricLoader.getInstance().getConfigDir().resolve("ViaFabric")
.resolve("viafabric.yml").toFile(), JLOGGER);
manager.onServerLoaded();
INIT_FUTURE.complete(null);
}
private void registerCommandsV1() {
try {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("viaversion")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("viaver")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("vvfabric")));
} catch (NoClassDefFoundError ignored) {
JLOGGER.info("Couldn't register command as Fabric Commands V1 isn't installed");
}
}
}

View File

@ -1,80 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.commands;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.util.ComponentUtil;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.server.command.CommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
private final CommandSource source;
public NMSCommandSender(CommandSource source) {
this.source = source;
}
@Override
public boolean hasPermission(String s) {
// https://gaming.stackexchange.com/questions/138602/what-does-op-permission-level-do
return source.hasPermissionLevel(3);
}
public static Text fromLegacy(String legacy) {
return Text.Serializer.fromJson(ComponentUtil.legacyToJsonString(legacy));
}
@Override
public void sendMessage(String s) {
if (source instanceof ServerCommandSource) {
((ServerCommandSource) source).sendFeedback(fromLegacy(s), false);
} else if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && source instanceof ClientCommandSource) {
MinecraftClient.getInstance().player.addChatMessage(fromLegacy(s), false);
}
}
@Override
public UUID getUUID() {
if (source instanceof ServerCommandSource) {
Entity entity = ((ServerCommandSource) source).getEntity();
if (entity != null) return entity.getUuid();
} else if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && source instanceof ClientCommandSource) {
return MinecraftClient.getInstance().player.getUuid();
}
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override
public String getName() {
if (source instanceof ServerCommandSource) {
return ((ServerCommandSource) source).getName();
} else if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && source instanceof ClientCommandSource) {
return MinecraftClient.getInstance().player.getEntityName();
}
return "?";
}
}

View File

@ -1,30 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.commands;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.mojang.brigadier.CommandDispatcher;
import io.github.cottonmc.clientcommands.ClientCommandPlugin;
import io.github.cottonmc.clientcommands.CottonClientCommandSource;
public class VFClientCommands implements ClientCommandPlugin {
@Override
public void registerCommands(CommandDispatcher<CottonClientCommandSource> commandDispatcher) {
commandDispatcher.register(ViaFabric.command("viafabricclient"));
}
}

View File

@ -1,72 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.commands;
import com.viaversion.fabric.common.commands.subs.LeakDetectSubCommand;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.server.command.CommandSource;
import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());
} catch (Exception e) {
e.printStackTrace();
}
}
public int execute(CommandContext<? extends CommandSource> ctx) {
String[] args = new String[0];
try {
args = StringArgumentType.getString(ctx, "args").split(" ");
} catch (IllegalArgumentException ignored) {
}
onCommand(
new NMSCommandSender(ctx.getSource()),
args
);
return 1;
}
public CompletableFuture<Suggestions> suggestion(CommandContext<? extends CommandSource> ctx, SuggestionsBuilder builder) {
String[] args;
try {
args = StringArgumentType.getString(ctx, "args").split(" ", -1);
} catch (IllegalArgumentException ignored) {
args = new String[]{""};
}
String[] pref = args.clone();
pref[pref.length - 1] = "";
String prefix = String.join(" ", pref);
onTabComplete(new NMSCommandSender(ctx.getSource()), args)
.stream()
.map(it -> {
SuggestionsBuilder b = new SuggestionsBuilder(builder.getInput(), prefix.length() + builder.getStart());
b.suggest(it);
return b;
})
.forEach(builder::add);
return builder.buildFuture();
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.gui;
import com.google.common.collect.ImmutableMap;
import io.github.prospector.modmenu.api.ConfigScreenFactory;
import io.github.prospector.modmenu.api.ModMenuApi;
import java.util.Map;
public class ModMenuConfig implements ModMenuApi {
@Override
public String getModId() {
return "viafabric";
}
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return ViaConfigScreen::new;
}
@Override
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
return ImmutableMap.of("viafabric", getModConfigScreenFactory());
}
}

View File

@ -1,170 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.gui;
import com.viaversion.fabric.common.config.AbstractViaConfigScreen;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.TranslatableText;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
public class ViaConfigScreen extends Screen implements AbstractViaConfigScreen {
private static CompletableFuture<Void> latestProtocolSave;
private final Screen parent;
private TextFieldWidget protocolVersion;
public ViaConfigScreen(Screen parent) {
super(new TranslatableText(TITLE_TRANSLATE_ID));
this.parent = parent;
}
@Override
protected void init() {
int entries = 0;
this.addButton(new ButtonWidget(calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, getClientSideText().asString(), this::onClickClientSide));
entries++;
this.addButton(new ButtonWidget(calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, getHideViaButtonText().asString(), this::onHideViaButton));
entries++;
protocolVersion = new TextFieldWidget(this.font,
calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, new TranslatableText(VERSION_TRANSLATE_ID).asString());
entries++;
protocolVersion.setTextPredicate(ProtocolUtils::isStartOfProtocolText);
protocolVersion.setChangedListener(this::onChangeVersionField);
int clientSideVersion = ViaFabric.config.getClientSideVersion();
protocolVersion.setText(ProtocolUtils.getProtocolName(clientSideVersion));
this.children.add(protocolVersion);
this.addButton(new ButtonWidget(this.width / 2 - 100, this.height - 40, 200, 20, new TranslatableText("gui.done").asString(), (buttonWidget) -> MinecraftClient.getInstance().openScreen(this.parent)));
}
private void onChangeVersionField(String text) {
protocolVersion.setSuggestion(null);
int newVersion = ViaFabric.config.getClientSideVersion();
Integer parsed = ProtocolUtils.parseProtocolId(text);
boolean validProtocol;
if (parsed != null) {
newVersion = parsed;
validProtocol = true;
} else {
validProtocol = false;
String[] suggestions = ProtocolUtils.getProtocolSuggestions(text);
if (suggestions.length == 1) {
protocolVersion.setSuggestion(suggestions[0].substring(text.length()));
}
}
protocolVersion.setEditableColor(getProtocolTextColor(ProtocolVersion.getProtocol(newVersion), validProtocol));
int finalNewVersion = newVersion;
if (latestProtocolSave == null) latestProtocolSave = CompletableFuture.completedFuture(null);
ViaFabric.config.setClientSideVersion(finalNewVersion);
latestProtocolSave = latestProtocolSave.thenRunAsync(ViaFabric.config::save, ViaFabric.ASYNC_EXECUTOR);
}
private void onClickClientSide(ButtonWidget widget) {
if (!ViaFabric.config.isClientSideEnabled()) {
MinecraftClient.getInstance().openScreen(new ConfirmScreen(
answer -> {
if (answer) {
ViaFabric.config.setClientSideEnabled(true);
ViaFabric.config.setClientSideVersion(-2); // AUTO
ViaFabric.config.save();
widget.setMessage(getClientSideText().asString());
}
MinecraftClient.getInstance().openScreen(this);
},
new TranslatableText("gui.enable_client_side.question"),
new TranslatableText("gui.enable_client_side.warning"),
new TranslatableText("gui.enable_client_side.enable").asString(),
new TranslatableText("gui.cancel").asString()
));
} else {
ViaFabric.config.setClientSideEnabled(false);
ViaFabric.config.save();
}
widget.setMessage(getClientSideText().asString());
}
@Override
public void removed() {
ViaFabric.config.save();
}
@Override
public void onClose() {
MinecraftClient.getInstance().openScreen(this.parent);
}
private TranslatableText getClientSideText() {
return ViaFabric.config.isClientSideEnabled() ?
new TranslatableText("gui.client_side.disable")
: new TranslatableText("gui.client_side.enable");
}
private TranslatableText getHideViaButtonText() {
return ViaFabric.config.isHideButton() ?
new TranslatableText("gui.hide_via_button.disable") : new TranslatableText("gui.hide_via_button.enable");
}
private void onHideViaButton(ButtonWidget widget) {
ViaFabric.config.setHideButton(!ViaFabric.config.isHideButton());
ViaFabric.config.save();
widget.setMessage(getHideViaButtonText().asString());
}
@Override
public void render(int mouseX, int mouseY, float delta) {
this.renderBackground();
drawCenteredString(this.font, this.title.asString(), this.width / 2, 20, 16777215);
super.render(mouseX, mouseY, delta);
protocolVersion.render(mouseX, mouseY, delta);
}
@Override
public void tick() {
super.tick();
protocolVersion.tick();
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(targets = "net.minecraft.client.gui.screen.ConnectScreen$1")
public class MixinConnectScreenThread {
@Redirect(method = "run()V", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
}
}

View File

@ -1,46 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@Shadow
private static String[] resolveSrv(String address) {
throw new AssertionError();
}
@Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;resolveSrv(Ljava/lang/String;)[Ljava/lang/String;"))
private static String[] modifySrvAddr(String address) {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return resolveSrv(address);
}
String[] resolvedSrv = resolveSrv(viaAddr.serverAddress);
resolvedSrv[0] = resolvedSrv[0].replaceAll("\\.$", "") + "." + viaAddr.getSuffixWithOptions();
return resolvedSrv;
}
}

View File

@ -1,42 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.MultiplayerServerListPinger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(MultiplayerServerListPinger.class)
public class MixinServerPinger {
@Redirect(method = "add", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.debug.client;
import io.netty.channel.ChannelHandlerContext;
import net.minecraft.network.ClientConnection;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConnection.class)
public abstract class MixinClientConnection {
@Shadow
@Final
private static Logger LOGGER;
@Inject(method = "exceptionCaught", at = @At("TAIL"))
public void exceptionCaught(ChannelHandlerContext context, Throwable ex, CallbackInfo ci) {
LOGGER.error("Packet error", ex);
}
}

View File

@ -1,29 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.debug.client;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientConnection.class)
public interface MixinClientConnectionAccessor {
@Accessor
Channel getChannel();
}

View File

@ -1,56 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.debug.client;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
import io.netty.channel.ChannelHandler;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.List;
@Mixin(DebugHud.class)
public class MixinDebugHud {
@Inject(at = @At("RETURN"), method = "getLeftText")
protected void getLeftText(CallbackInfoReturnable<List<String>> info) {
String line = "[ViaFabric] I: " + Via.getManager().getConnectionManager().getConnections().size() + " (F: "
+ Via.getManager().getConnectionManager().getConnectedClients().size() + ")";
@SuppressWarnings("ConstantConditions") ChannelHandler viaDecoder = ((MixinClientConnectionAccessor) MinecraftClient.getInstance().getNetworkHandler()
.getConnection()).getChannel().pipeline().get(CommonTransformer.HANDLER_DECODER_NAME);
if (viaDecoder instanceof FabricDecodeHandler) {
UserConnection connection = ((FabricDecodeHandler) viaDecoder).getInfo();
ProtocolInfo protocol = connection.getProtocolInfo();
if (protocol != null) {
ProtocolVersion serverVer = protocol.serverProtocolVersion();
ProtocolVersion clientVer = protocol.protocolVersion();
line += " / C: " + clientVer + " S: " + serverVer + " A: " + connection.isActive();
}
}
info.getReturnValue().add(line);
}
}

View File

@ -1,55 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.gui.client;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.viaversion.fabric.mc1152.gui.ViaConfigScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MultiplayerScreen.class)
public abstract class MixinMultiplayerScreen extends Screen {
protected MixinMultiplayerScreen(Text title, UnsupportedOperationException e) {
super(title);
throw e;
}
@Inject(method = "init", at = @At("TAIL"), remap = false)
private void onInit(CallbackInfo ci) {
ButtonWidget enableClientSideViaVersion = new TexturedButtonWidget(this.width / 2 + 113, 10,
40, 20, // Size
0, 0, // Start pos of texture
20, // v Hover offset
new Identifier("viafabric:textures/gui/widgets.png"),
256, 256, // Texture size
it -> MinecraftClient.getInstance().openScreen(new ViaConfigScreen(this)),
new TranslatableText("gui.via_button").asString());
if (ViaFabric.config.isHideButton()) enableClientSideViaVersion.visible = false;
addButton(enableClientSideViaVersion);
}
}

View File

@ -1,51 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.mc1152.mixin.debug.client.MixinClientConnectionAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.client.network.MultiplayerServerListPinger$1")
public abstract class MixinMultiplayerServerListPingerListener implements ClientQueryPacketListener {
@Accessor
abstract ClientConnection getField_3774(); // Synthetic
@Accessor
abstract ServerInfo getField_3776(); // Synthetic
@Inject(method = "onResponse", at = @At(value = "HEAD"))
private void onResponseCaptureServerInfo(QueryResponseS2CPacket packet, CallbackInfo ci) {
FabricDecodeHandler decoder = ((MixinClientConnectionAccessor) this.getField_3774()).getChannel()
.pipeline().get(FabricDecodeHandler.class);
if (decoder != null) {
((ViaServerInfo) getField_3776()).viaFabric$setTranslating(decoder.getInfo().isActive());
((ViaServerInfo) getField_3776()).viaFabric$setServerVer(decoder.getInfo().getProtocolInfo().getServerProtocolVersion());
}
}
}

View File

@ -1,60 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
public class MixinServerEntry {
@Shadow
@Final
private ServerInfo server;
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/texture/TextureManager;bindTexture(Lnet/minecraft/util/Identifier;)V"))
private void redirectPingIcon(TextureManager textureManager, Identifier identifier) {
if (identifier.equals(DrawableHelper.GUI_ICONS_LOCATION) && ((ViaServerInfo) this.server).viaFabric$translating()) {
textureManager.bindTexture(new Identifier("viafabric:textures/gui/icons.png"));
return;
}
textureManager.bindTexture(identifier);
}
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Ljava/lang/String;)V"))
private void addServerVer(MultiplayerScreen multiplayerScreen, String text) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).viaFabric$getServerVer());
StringBuilder builder = new StringBuilder(text);
builder.append("\n");
builder.append((new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion())).asString());
builder.append("\n");
builder.append(this.server.version);
multiplayerScreen.setTooltip(builder.toString());
}
}

View File

@ -1,52 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import net.minecraft.client.network.ServerInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@Mixin(ServerInfo.class)
public class MixinServerInfo implements ViaServerInfo {
@Unique
private boolean viaFabric$translating;
@Unique
private int viaFabric$serverVer;
@Override
public int viaFabric$getServerVer() {
return viaFabric$serverVer;
}
@Override
public void viaFabric$setServerVer(int ver) {
this.viaFabric$serverVer = ver;
}
@Override
public boolean viaFabric$translating() {
return viaFabric$translating;
}
@Override
public void viaFabric$setTranslating(boolean via) {
this.viaFabric$translating = via;
}
}

View File

@ -1,39 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.pipeline;
import com.viaversion.fabric.common.handler.PipelineReorderEvent;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Shadow
private Channel channel;
@Inject(method = "setCompressionThreshold", at = @At("RETURN"))
private void reorderCompression(int compressionThreshold, CallbackInfo ci) {
channel.pipeline().fireUserEventTriggered(new PipelineReorderEvent());
}
}

View File

@ -1,45 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.pipeline;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.server.ServerNetworkIo$1")
public class MixinServerNetworkIoChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel);
new ProtocolPipelineImpl(user);
channel.pipeline().addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user));
channel.pipeline().addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -1,44 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.pipeline.client;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.viaversion.fabric.mc1152.service.ProtocolAutoDetector;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Inject(method = "connect", at = @At("HEAD"))
private static void onConnect(InetAddress address, int port, boolean shouldUseNativeTransport, CallbackInfoReturnable<ClientConnection> cir) {
try {
if (!ViaFabric.config.isClientSideEnabled()) return;
ProtocolAutoDetector.detectVersion(new InetSocketAddress(address, port)).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
ViaFabric.JLOGGER.log(Level.WARNING, "Could not auto-detect protocol for " + address + " " + e);
}
}
}

View File

@ -1,47 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.pipeline.client;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.network.ClientConnection$1")
public class MixinClientConnectionChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel, true);
new ProtocolPipelineImpl(user).add(HostnameParserProtocol.INSTANCE);
channel.pipeline()
.addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user))
.addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -1,34 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.mixin.shutdown.server;
import com.viaversion.viaversion.ViaManagerImpl;
import com.viaversion.viaversion.api.Via;
import net.minecraft.server.MinecraftServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftServer.class)
public class MixinMinecraftServer {
@Inject(method = "stop", at = @At("TAIL"))
private void onStop(CallbackInfo ci) {
((ViaManagerImpl) Via.getManager()).destroy();
}
}

View File

@ -1,28 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.platform;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import net.minecraft.SharedConstants;
public class FabricNativeVersionProvider implements NativeVersionProvider {
@Override
public int getNativeServerVersion() {
return SharedConstants.getGameVersion().getProtocolVersion();
}
}

View File

@ -1,141 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.platform;
import com.viaversion.fabric.common.commands.UserCommandSender;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import com.viaversion.fabric.common.provider.AbstractFabricPlatform;
import com.viaversion.fabric.common.util.FutureTaskId;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.viaversion.fabric.mc1152.commands.NMSCommandSender;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import io.netty.channel.EventLoop;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.network.MessageType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import java.util.logging.Level;
public class FabricPlatform extends AbstractFabricPlatform {
public static MinecraftServer getServer() {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
return getIntegratedServer();
}
return (MinecraftServer) FabricLoader.getInstance().getGameInstance();
}
@Environment(EnvType.CLIENT)
private static MinecraftServer getIntegratedServer() {
return MinecraftClient.getInstance().getServer();
}
@Override
protected void installNativeVersionProvider() {
Via.getManager().getProviders().use(NativeVersionProvider.class, new FabricNativeVersionProvider());
}
@Override
protected ExecutorService asyncService() {
return ViaFabric.ASYNC_EXECUTOR;
}
@Override
protected EventLoop eventLoop() {
return ViaFabric.EVENT_LOOP;
}
@Override
public FutureTaskId runSync(Runnable runnable) {
if (getServer() != null) {
return runServerSync(runnable);
} else {
return runEventLoop(runnable);
}
}
private FutureTaskId runServerSync(Runnable runnable) {
// Kick task needs to be on main thread, it does already have error logger
return new FutureTaskId(CompletableFuture.runAsync(runnable, getServer()));
}
@Override
public ViaCommandSender[] getOnlinePlayers() {
MinecraftServer server = getServer();
if (server != null && server.isOnThread()) {
return getServerPlayers();
}
return Via.getManager().getConnectionManager().getConnectedClients().values().stream()
.map(UserCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
private ViaCommandSender[] getServerPlayers() {
return getServer().getPlayerManager().getPlayerList().stream()
.map(Entity::getCommandSource)
.map(NMSCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
@Override
public void sendMessage(UUID uuid, String s) {
sendMessageServer(uuid, s);
}
private void sendMessageServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return;
runServerSync(() -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return;
player.sendChatMessage(NMSCommandSender.fromLegacy(s), MessageType.SYSTEM);
});
}
@Override
public boolean kickPlayer(UUID uuid, String s) {
return kickServer(uuid, s);
}
private boolean kickServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return false;
Supplier<Boolean> kickTask = () -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return false;
player.networkHandler.disconnect(NMSCommandSender.fromLegacy(s));
return true;
};
if (server.isOnThread()) {
return kickTask.get();
} else {
ViaFabric.JLOGGER.log(Level.WARNING, "Weird!? Player kicking was called off-thread", new Throwable());
runServerSync(kickTask::get);
}
return false; // Can't know if it worked
}
}

View File

@ -1,51 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.platform;
import com.viaversion.fabric.mc1152.providers.VFHandItemProvider;
import com.viaversion.fabric.mc1152.providers.FabricVersionProvider;
import com.viaversion.fabric.mc1152.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.platform.ViaPlatformLoader;
import com.viaversion.viaversion.api.protocol.version.VersionProvider;
public class VFLoader implements ViaPlatformLoader {
@Override
public void load() {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override
public void unload() {
// Nothing to do
}
}

View File

@ -1,54 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.providers;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.AbstractFabricVersionProvider;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.viaversion.fabric.mc1152.service.ProtocolAutoDetector;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.ChannelPipeline;
import net.minecraft.network.ClientConnection;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
public class FabricVersionProvider extends AbstractFabricVersionProvider {
@Override
protected Logger getLogger() {
return ViaFabric.JLOGGER;
}
@Override
protected VFConfig getConfig() {
return ViaFabric.config;
}
@Override
protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
return ProtocolAutoDetector.detectVersion(address);
}
@Override
protected boolean isMulticonnectHandler(ChannelPipeline pipe) {
return pipe.get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect");
}
}

View File

@ -1,74 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.providers;
import com.viaversion.fabric.common.util.RemappingUtil;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override
public Item getHandItem(UserConnection info) {
if (info.isClientSide()) {
return getClientItem();
}
return super.getHandItem(info);
}
private Item getClientItem() {
if (clientItem == null) {
return new DataItem(0, (byte) 0, null);
}
return clientItem.copy();
}
@Environment(EnvType.CLIENT)
public void registerClientTick() {
try {
ClientTickEvents.END_WORLD_TICK.register(clientWorld -> tickClient());
} catch (NoClassDefFoundError ignored) {
ViaFabric.JLOGGER.info("Fabric Lifecycle V1 isn't installed");
}
}
private void tickClient() {
ClientPlayerEntity p = MinecraftClient.getInstance().player;
if (p != null) {
clientItem = fromNative(p.inventory.getMainHandStack());
}
}
private Item fromNative(ItemStack original) {
Identifier iid = Registry.ITEM.getId(original.getItem());
int id = RemappingUtil.swordId(iid.toString());
return new DataItem(id, (byte) original.getCount(), (short) original.getDamage(), null);
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public BlockPosition getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new BlockPosition(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -1,142 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1152.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
import net.minecraft.network.packet.s2c.query.QueryPongS2CPacket;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@Environment(EnvType.CLIENT)
public class ProtocolAutoDetector {
private static final LoadingCache<InetSocketAddress, CompletableFuture<ProtocolVersion>> SERVER_VER = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.SECONDS)
.build(CacheLoader.from((address) -> {
CompletableFuture<ProtocolVersion> future = new CompletableFuture<>();
try {
final ClientConnection clientConnection = new ClientConnection(NetworkSide.CLIENTBOUND);
ChannelFuture ch = new Bootstrap()
.group(ClientConnection.CLIENT_IO_GROUP.get())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) {
try {
channel.config().setOption(ChannelOption.TCP_NODELAY, true);
channel.config().setOption(ChannelOption.IP_TOS, 0x18); // Stolen from Velocity, low delay, high reliability
} catch (ChannelException ignored) {
}
channel.pipeline()
.addLast("timeout", new ReadTimeoutHandler(30))
.addLast("splitter", new SplitterHandler())
.addLast("decoder", new DecoderHandler(NetworkSide.CLIENTBOUND))
.addLast("prepender", new SizePrepender())
.addLast("encoder", new PacketEncoder(NetworkSide.SERVERBOUND))
.addLast("packet_handler", clientConnection);
}
})
.connect(address);
ch.addListener(future1 -> {
if (!future1.isSuccess()) {
future.completeExceptionally(future1.cause());
} else {
ch.channel().eventLoop().execute(() -> { // needs to execute after channel init
clientConnection.setPacketListener(new ClientQueryPacketListener() {
@Override
public void onResponse(QueryResponseS2CPacket packet) {
ServerMetadata meta = packet.getServerMetadata();
ServerMetadata.Version version;
if (meta != null && (version = meta.getVersion()) != null) {
ProtocolVersion ver = ProtocolVersion.getProtocol(version.getProtocolVersion());
future.complete(ver);
ViaFabric.JLOGGER.info("Auto-detected " + ver + " for " + address);
} else {
future.completeExceptionally(new IllegalArgumentException("Null version in query response"));
}
clientConnection.disconnect(new LiteralText(""));
}
@Override
public void onPong(QueryPongS2CPacket packet) {
clientConnection.disconnect(new LiteralText("Pong not requested!"));
}
@Override
public void onDisconnected(Text reason) {
future.completeExceptionally(new IllegalStateException(reason.asString()));
}
@Override
public ClientConnection getConnection() {
return clientConnection;
}
});
clientConnection.send(new HandshakeC2SPacket(address.getHostString(),
address.getPort(), NetworkState.STATUS));
clientConnection.send(new QueryRequestC2SPacket());
});
}
});
} catch (Throwable throwable) {
future.completeExceptionally(throwable);
}
return future;
}));
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {
ViaFabric.JLOGGER.log(Level.WARNING, "Protocol auto detector error: ", e);
return CompletableFuture.completedFuture(null);
}
}
}

View File

@ -1,80 +0,0 @@
{
"schemaVersion": 1,
"id": "viafabric-mc1152",
"name": "ViaFabric for 1.15",
"version": "${version}",
"description": "${description}",
"license": "GPL-3.0",
"contact": {
"homepage": "https://viaversion.com/fabric",
"issues": "https://github.com/ViaVersion/ViaFabric/issues",
"sources": "https://github.com/ViaVersion/ViaFabric"
},
"environment": "*",
"authors": [
{
"name": "creeper123123321",
"contact": {
"homepage": "https://creeper123123321.github.io/"
}
},
{
"name": "FlorianMichael/EnZaXD",
"contact": {
"homepage": "https://github.com/FlorianMichael"
}
},
{
"name": "kennytv",
"contact": {
"homepage": "https://kennytv.eu"
}
},
{
"name": "Kichura",
"contact": {
"homepage": "https://github.com/Kichura"
}
}
],
"contributors": [
{
"name": "GitHub contributors",
"contact": {
"homepage": "https://github.com/ViaVersion/ViaFabric/graphs/contributors"
}
}
],
"entrypoints": {
"main": [
"com.viaversion.fabric.mc1152.ViaFabric"
],
"cotton-client-commands": [
"com.viaversion.fabric.mc1152.commands.VFClientCommands"
],
"modmenu": [
"com.viaversion.fabric.mc1152.gui.ModMenuConfig"
]
},
"depends": {
"fabric-resource-loader-v0": "*",
"minecraft": "1.15.2",
"viafabric": "*"
},
"recommends": {
"fabric-command-api-v1": "*",
"cotton-client-commands": "*"
},
"mixins": [
"mixins.viafabric1152.address.json",
"mixins.viafabric1152.gui.json",
"mixins.viafabric1152.debug.json",
"mixins.viafabric1152.pipeline.json",
"mixins.viafabric1152.shutdown.json"
],
"custom": {
"modmenu": {
"parent": "viafabric"
}
}
}

View File

@ -1,15 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1152.mixin.address",
"mixins": [
],
"client": [
"client.MixinConnectScreenThread",
"client.MixinServerAddress",
"client.MixinServerPinger"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,15 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1152.mixin.debug",
"mixins": [
],
"client": [
"client.MixinClientConnectionAccessor",
"client.MixinDebugHud",
"client.MixinClientConnection"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,16 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1152.mixin.gui",
"mixins": [
"client.MixinMultiplayerServerListPingerListener"
],
"client": [
"client.MixinMultiplayerScreen",
"client.MixinServerEntry",
"client.MixinServerInfo"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,16 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1152.mixin.pipeline",
"mixins": [
"MixinClientConnection",
"MixinServerNetworkIoChInit"
],
"client": [
"client.MixinClientConnection",
"client.MixinClientConnectionChInit"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@ -1,13 +0,0 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc1152.mixin.shutdown",
"mixins": [
],
"server": [
"server.MixinMinecraftServer"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -1,7 +0,0 @@
dependencies {
minecraft("com.mojang:minecraft:1.16.5")
mappings("net.fabricmc:yarn:1.16.5+build.10:v2")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.42.0+1.16")
modImplementation("com.terraformersmc:modmenu:1.16.23")
}

View File

@ -1,118 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc1165.commands.VFCommandHandler;
import com.viaversion.fabric.mc1165.platform.FabricPlatform;
import com.viaversion.fabric.mc1165.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.DefaultEventLoop;
import io.netty.channel.EventLoop;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.command.CommandSource;
import org.apache.logging.log4j.LogManager;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Logger;
public class ViaFabric implements ModInitializer {
public static final Logger JLOGGER = new JLoggerToLog4j(LogManager.getLogger("ViaFabric"));
public static final ExecutorService ASYNC_EXECUTOR;
public static final EventLoop EVENT_LOOP;
public static final CompletableFuture<Void> INIT_FUTURE = new CompletableFuture<>();
public static VFConfig config;
static {
ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ViaFabric-%d").build();
ASYNC_EXECUTOR = Executors.newFixedThreadPool(8, factory);
EVENT_LOOP = new DefaultEventLoop(factory);
EVENT_LOOP.submit(INIT_FUTURE::join); // https://github.com/ViaVersion/ViaFabric/issues/53 ugly workaround code but works tm
}
public static <S extends CommandSource> LiteralArgumentBuilder<S> command(String commandName) {
return LiteralArgumentBuilder.<S>literal(commandName)
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
public void onInitialize() {
FabricPlatform platform = new FabricPlatform();
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();
ViaManagerImpl manager = (ViaManagerImpl) Via.getManager();
manager.init();
HostnameParserProtocol.INSTANCE.initialize();
HostnameParserProtocol.INSTANCE.register(Via.getManager().getProviders());
ProtocolVersion.register(-2, "AUTO");
FabricLoader.getInstance().getEntrypoints("viafabric:via_api_initialized", Runnable.class).forEach(Runnable::run);
registerCommandsV1();
config = new VFConfig(FabricLoader.getInstance().getConfigDir().resolve("ViaFabric")
.resolve("viafabric.yml").toFile(), JLOGGER);
manager.onServerLoaded();
INIT_FUTURE.complete(null);
}
private void registerCommandsV1() {
try {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("viaversion")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("viaver")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(command("vvfabric")));
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
ClientCommandManager.DISPATCHER.register(command("viafabricclient"));
}
} catch (NoClassDefFoundError ignored) {
JLOGGER.info("Couldn't register command as Fabric Commands V1 isn't installed");
}
}
}

View File

@ -1,77 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.commands;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.util.ComponentUtil;
import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
private final CommandSource source;
public NMSCommandSender(CommandSource source) {
this.source = source;
}
@Override
public boolean hasPermission(String s) {
// https://gaming.stackexchange.com/questions/138602/what-does-op-permission-level-do
return source.hasPermissionLevel(3);
}
public static Text fromLegacy(String legacy) {
return Text.Serializer.fromJson(ComponentUtil.legacyToJsonString(legacy));
}
@Override
public void sendMessage(String s) {
if (source instanceof ServerCommandSource) {
((ServerCommandSource) source).sendFeedback(fromLegacy(s), false);
} else if (source instanceof FabricClientCommandSource) {
((FabricClientCommandSource) source).sendFeedback(fromLegacy(s));
}
}
@Override
public UUID getUUID() {
if (source instanceof ServerCommandSource) {
Entity entity = ((ServerCommandSource) source).getEntity();
if (entity != null) return entity.getUuid();
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getUuid();
}
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override
public String getName() {
if (source instanceof ServerCommandSource) {
return ((ServerCommandSource) source).getName();
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getEntityName();
}
return "?";
}
}

View File

@ -1,72 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.commands;
import com.viaversion.fabric.common.commands.subs.LeakDetectSubCommand;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.command.CommandSource;
import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());
} catch (Exception e) {
e.printStackTrace();
}
}
public int execute(CommandContext<? extends CommandSource> ctx) {
String[] args = new String[0];
try {
args = StringArgumentType.getString(ctx, "args").split(" ");
} catch (IllegalArgumentException ignored) {
}
onCommand(
new NMSCommandSender(ctx.getSource()),
args
);
return 1;
}
public CompletableFuture<Suggestions> suggestion(CommandContext<? extends CommandSource> ctx, SuggestionsBuilder builder) {
String[] args;
try {
args = StringArgumentType.getString(ctx, "args").split(" ", -1);
} catch (IllegalArgumentException ignored) {
args = new String[]{""};
}
String[] pref = args.clone();
pref[pref.length - 1] = "";
String prefix = String.join(" ", pref);
onTabComplete(new NMSCommandSender(ctx.getSource()), args)
.stream()
.map(it -> {
SuggestionsBuilder b = new SuggestionsBuilder(builder.getInput(), prefix.length() + builder.getStart());
b.suggest(it);
return b;
})
.forEach(builder::add);
return builder.buildFuture();
}
}

View File

@ -1,36 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.gui;
import com.google.common.collect.ImmutableMap;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import java.util.Map;
public class ModMenuConfig implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return ViaConfigScreen::new;
}
@Override
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
return ImmutableMap.of("viafabric", getModConfigScreenFactory());
}
}

View File

@ -1,172 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.gui;
import com.viaversion.fabric.common.config.AbstractViaConfigScreen;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ScreenTexts;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
public class ViaConfigScreen extends Screen implements AbstractViaConfigScreen {
private static CompletableFuture<Void> latestProtocolSave;
private final Screen parent;
private TextFieldWidget protocolVersion;
public ViaConfigScreen(Screen parent) {
super(new TranslatableText(TITLE_TRANSLATE_ID));
this.parent = parent;
}
@Override
protected void init() {
int entries = 0;
this.addButton(new ButtonWidget(calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, getClientSideText(), this::onClickClientSide));
entries++;
this.addButton(new ButtonWidget(calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, getHideViaButtonText(), this::onHideViaButton));
entries++;
protocolVersion = new TextFieldWidget(this.textRenderer,
calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150,
20, new TranslatableText(VERSION_TRANSLATE_ID));
entries++;
protocolVersion.setTextPredicate(ProtocolUtils::isStartOfProtocolText);
protocolVersion.setChangedListener(this::onChangeVersionField);
int clientSideVersion = ViaFabric.config.getClientSideVersion();
protocolVersion.setText(ProtocolUtils.getProtocolName(clientSideVersion));
this.children.add(protocolVersion);
this.addButton(new ButtonWidget(this.width / 2 - 100, this.height - 40, 200, 20, ScreenTexts.DONE, (buttonWidget) -> this.client.openScreen(this.parent)));
}
private void onChangeVersionField(String text) {
protocolVersion.setSuggestion(null);
int newVersion = ViaFabric.config.getClientSideVersion();
Integer parsed = ProtocolUtils.parseProtocolId(text);
boolean validProtocol;
if (parsed != null) {
newVersion = parsed;
validProtocol = true;
} else {
validProtocol = false;
String[] suggestions = ProtocolUtils.getProtocolSuggestions(text);
if (suggestions.length == 1) {
protocolVersion.setSuggestion(suggestions[0].substring(text.length()));
}
}
protocolVersion.setEditableColor(getProtocolTextColor(ProtocolVersion.getProtocol(newVersion), validProtocol));
int finalNewVersion = newVersion;
if (latestProtocolSave == null) latestProtocolSave = CompletableFuture.completedFuture(null);
ViaFabric.config.setClientSideVersion(finalNewVersion);
latestProtocolSave = latestProtocolSave.thenRunAsync(ViaFabric.config::save, ViaFabric.ASYNC_EXECUTOR);
}
private void onClickClientSide(ButtonWidget widget) {
if (!ViaFabric.config.isClientSideEnabled()) {
MinecraftClient.getInstance().openScreen(new ConfirmScreen(
answer -> {
if (answer) {
ViaFabric.config.setClientSideEnabled(true);
ViaFabric.config.setClientSideVersion(-2); // AUTO
ViaFabric.config.save();
widget.setMessage(getClientSideText());
}
MinecraftClient.getInstance().openScreen(this);
},
new TranslatableText("gui.enable_client_side.question"),
new TranslatableText("gui.enable_client_side.warning"),
new TranslatableText("gui.enable_client_side.enable"),
new TranslatableText("gui.cancel")
));
} else {
ViaFabric.config.setClientSideEnabled(false);
ViaFabric.config.save();
}
widget.setMessage(getClientSideText());
}
@Override
public void removed() {
ViaFabric.config.save();
}
@Override
public void onClose() {
this.client.openScreen(this.parent);
}
private TranslatableText getClientSideText() {
return ViaFabric.config.isClientSideEnabled() ?
new TranslatableText("gui.client_side.disable")
: new TranslatableText("gui.client_side.enable");
}
private TranslatableText getHideViaButtonText() {
return ViaFabric.config.isHideButton() ?
new TranslatableText("gui.hide_via_button.disable") : new TranslatableText("gui.hide_via_button.enable");
}
private void onHideViaButton(ButtonWidget widget) {
ViaFabric.config.setHideButton(!ViaFabric.config.isHideButton());
ViaFabric.config.save();
widget.setMessage(getHideViaButtonText());
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices);
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 20, 16777215);
super.render(matrices, mouseX, mouseY, delta);
protocolVersion.render(matrices, mouseX, mouseY, delta);
}
@Override
public void tick() {
super.tick();
protocolVersion.tick();
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(targets = "net.minecraft.client.gui.screen.ConnectScreen$1")
public class MixinConnectScreenThread {
@Redirect(method = "run()V", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
}
}

View File

@ -1,44 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.address.client;
import com.mojang.datafixers.util.Pair;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@Shadow
private static Pair<String, Integer> resolveServer(String address) {
throw new AssertionError();
}
@Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;resolveServer(Ljava/lang/String;)Lcom/mojang/datafixers/util/Pair;"))
private static Pair<String, Integer> modifySrvAddr(String address) {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return resolveServer(address);
}
return resolveServer(viaAddr.serverAddress).mapFirst(it -> it.replaceAll("\\.$", "") + "." + viaAddr.getSuffixWithOptions());
}
}

View File

@ -1,42 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.MultiplayerServerListPinger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(MultiplayerServerListPinger.class)
public class MixinServerPinger {
@Redirect(method = "add", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.debug.client;
import io.netty.channel.ChannelHandlerContext;
import net.minecraft.network.ClientConnection;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConnection.class)
public abstract class MixinClientConnection {
@Shadow
@Final
private static Logger LOGGER;
@Inject(method = "exceptionCaught", at = @At("TAIL"))
public void exceptionCaught(ChannelHandlerContext context, Throwable ex, CallbackInfo ci) {
LOGGER.error("Packet error", ex);
}
}

View File

@ -1,29 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.debug.client;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientConnection.class)
public interface MixinClientConnectionAccessor {
@Accessor
Channel getChannel();
}

View File

@ -1,56 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.debug.client;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
import io.netty.channel.ChannelHandler;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.List;
@Mixin(DebugHud.class)
public class MixinDebugHud {
@Inject(at = @At("RETURN"), method = "getLeftText")
protected void getLeftText(CallbackInfoReturnable<List<String>> info) {
String line = "[ViaFabric] I: " + Via.getManager().getConnectionManager().getConnections().size() + " (F: "
+ Via.getManager().getConnectionManager().getConnectedClients().size() + ")";
@SuppressWarnings("ConstantConditions") ChannelHandler viaDecoder = ((MixinClientConnectionAccessor) MinecraftClient.getInstance().getNetworkHandler()
.getConnection()).getChannel().pipeline().get(CommonTransformer.HANDLER_DECODER_NAME);
if (viaDecoder instanceof FabricDecodeHandler) {
UserConnection connection = ((FabricDecodeHandler) viaDecoder).getInfo();
ProtocolInfo protocol = connection.getProtocolInfo();
if (protocol != null) {
ProtocolVersion serverVer = protocol.serverProtocolVersion();
ProtocolVersion clientVer = protocol.protocolVersion();
line += " / C: " + clientVer + " S: " + serverVer + " A: " + connection.isActive();
}
}
info.getReturnValue().add(line);
}
}

View File

@ -1,55 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.gui.client;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.viaversion.fabric.mc1165.gui.ViaConfigScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MultiplayerScreen.class)
public abstract class MixinMultiplayerScreen extends Screen {
protected MixinMultiplayerScreen(Text title, UnsupportedOperationException e) {
super(title);
throw e;
}
@Inject(method = "init", at = @At("TAIL"))
private void onInit(CallbackInfo ci) {
ButtonWidget enableClientSideViaVersion = new TexturedButtonWidget(this.width / 2 + 113, 10,
40, 20, // Size
0, 0, // Start pos of texture
20, // v Hover offset
new Identifier("viafabric:textures/gui/widgets.png"),
256, 256, // Texture size
it -> MinecraftClient.getInstance().openScreen(new ViaConfigScreen(this)),
new TranslatableText("gui.via_button"));
if (ViaFabric.config.isHideButton()) enableClientSideViaVersion.visible = false;
addButton(enableClientSideViaVersion);
}
}

View File

@ -1,51 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.mc1165.mixin.debug.client.MixinClientConnectionAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.client.network.MultiplayerServerListPinger$1")
public abstract class MixinMultiplayerServerListPingerListener implements ClientQueryPacketListener {
@Accessor
abstract ClientConnection getField_3774(); // Synthetic
@Accessor
abstract ServerInfo getField_3776(); // Synthetic
@Inject(method = "onResponse", at = @At(value = "HEAD"))
private void onResponseCaptureServerInfo(QueryResponseS2CPacket packet, CallbackInfo ci) {
FabricDecodeHandler decoder = ((MixinClientConnectionAccessor) this.getField_3774()).getChannel()
.pipeline().get(FabricDecodeHandler.class);
if (decoder != null) {
((ViaServerInfo) getField_3776()).viaFabric$setTranslating(decoder.getInfo().isActive());
((ViaServerInfo) getField_3776()).viaFabric$setServerVer(decoder.getInfo().getProtocolInfo().getServerProtocolVersion());
}
}
}

View File

@ -1,62 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.ArrayList;
import java.util.List;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
public class MixinServerEntry {
@Shadow
@Final
private ServerInfo server;
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/texture/TextureManager;bindTexture(Lnet/minecraft/util/Identifier;)V"))
private void redirectPingIcon(TextureManager textureManager, Identifier identifier) {
if (identifier.equals(DrawableHelper.GUI_ICONS_TEXTURE) && ((ViaServerInfo) this.server).viaFabric$translating()) {
textureManager.bindTexture(new Identifier("viafabric:textures/gui/icons.png"));
return;
}
textureManager.bindTexture(identifier);
}
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Ljava/util/List;)V"))
private void addServerVer(MultiplayerScreen multiplayerScreen, List<Text> tooltipText) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).viaFabric$getServerVer());
List<Text> lines = new ArrayList<>(tooltipText);
lines.add(new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion()));
lines.add(this.server.version.copy());
multiplayerScreen.setTooltip(lines);
}
}

View File

@ -1,52 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import net.minecraft.client.network.ServerInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@Mixin(ServerInfo.class)
public class MixinServerInfo implements ViaServerInfo {
@Unique
private boolean viaFabric$translating;
@Unique
private int viaFabric$serverVer;
@Override
public int viaFabric$getServerVer() {
return viaFabric$serverVer;
}
@Override
public void viaFabric$setServerVer(int ver) {
this.viaFabric$serverVer = ver;
}
@Override
public boolean viaFabric$translating() {
return viaFabric$translating;
}
@Override
public void viaFabric$setTranslating(boolean via) {
this.viaFabric$translating = via;
}
}

View File

@ -1,39 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.pipeline;
import com.viaversion.fabric.common.handler.PipelineReorderEvent;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Shadow
private Channel channel;
@Inject(method = "setCompressionThreshold", at = @At("RETURN"))
private void reorderCompression(int compressionThreshold, CallbackInfo ci) {
channel.pipeline().fireUserEventTriggered(new PipelineReorderEvent());
}
}

View File

@ -1,45 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.pipeline;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.server.ServerNetworkIo$1")
public class MixinServerNetworkIoChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel);
new ProtocolPipelineImpl(user);
channel.pipeline().addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user));
channel.pipeline().addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -1,44 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.pipeline.client;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.viaversion.fabric.mc1165.service.ProtocolAutoDetector;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Inject(method = "connect", at = @At("HEAD"))
private static void onConnect(InetAddress address, int port, boolean shouldUseNativeTransport, CallbackInfoReturnable<ClientConnection> cir) {
try {
if (!ViaFabric.config.isClientSideEnabled()) return;
ProtocolAutoDetector.detectVersion(new InetSocketAddress(address, port)).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
ViaFabric.JLOGGER.log(Level.WARNING, "Could not auto-detect protocol for " + address + " " + e);
}
}
}

View File

@ -1,47 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.pipeline.client;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.network.ClientConnection$1")
public class MixinClientConnectionChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel, true);
new ProtocolPipelineImpl(user).add(HostnameParserProtocol.INSTANCE);
channel.pipeline()
.addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user))
.addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -1,34 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.mixin.shutdown.server;
import com.viaversion.viaversion.ViaManagerImpl;
import com.viaversion.viaversion.api.Via;
import net.minecraft.server.MinecraftServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftServer.class)
public class MixinMinecraftServer {
@Inject(method = "stop", at = @At("TAIL"))
private void onStop(CallbackInfo ci) {
((ViaManagerImpl) Via.getManager()).destroy();
}
}

View File

@ -1,28 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.platform;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import net.minecraft.SharedConstants;
public class FabricNativeVersionProvider implements NativeVersionProvider {
@Override
public int getNativeServerVersion() {
return SharedConstants.getGameVersion().getProtocolVersion();
}
}

View File

@ -1,140 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.platform;
import com.viaversion.fabric.common.commands.UserCommandSender;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import com.viaversion.fabric.common.provider.AbstractFabricPlatform;
import com.viaversion.fabric.common.util.FutureTaskId;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.viaversion.fabric.mc1165.commands.NMSCommandSender;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import io.netty.channel.EventLoop;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import java.util.logging.Level;
public class FabricPlatform extends AbstractFabricPlatform {
public static MinecraftServer getServer() {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
return getIntegratedServer();
}
return (MinecraftServer) FabricLoader.getInstance().getGameInstance();
}
@Environment(EnvType.CLIENT)
private static MinecraftServer getIntegratedServer() {
return MinecraftClient.getInstance().getServer();
}
@Override
protected void installNativeVersionProvider() {
Via.getManager().getProviders().use(NativeVersionProvider.class, new FabricNativeVersionProvider());
}
@Override
protected ExecutorService asyncService() {
return ViaFabric.ASYNC_EXECUTOR;
}
@Override
protected EventLoop eventLoop() {
return ViaFabric.EVENT_LOOP;
}
@Override
public FutureTaskId runSync(Runnable runnable) {
if (getServer() != null) {
return runServerSync(runnable);
} else {
return runEventLoop(runnable);
}
}
private FutureTaskId runServerSync(Runnable runnable) {
// Kick task needs to be on main thread, it does already have error logger
return new FutureTaskId(CompletableFuture.runAsync(runnable, getServer()));
}
@Override
public ViaCommandSender[] getOnlinePlayers() {
MinecraftServer server = getServer();
if (server != null && server.isOnThread()) {
return getServerPlayers();
}
return Via.getManager().getConnectionManager().getConnectedClients().values().stream()
.map(UserCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
private ViaCommandSender[] getServerPlayers() {
return getServer().getPlayerManager().getPlayerList().stream()
.map(Entity::getCommandSource)
.map(NMSCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
@Override
public void sendMessage(UUID uuid, String s) {
sendMessageServer(uuid, s);
}
private void sendMessageServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return;
runServerSync(() -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return;
player.sendMessage(NMSCommandSender.fromLegacy(s), false);
});
}
@Override
public boolean kickPlayer(UUID uuid, String s) {
return kickServer(uuid, s);
}
private boolean kickServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return false;
Supplier<Boolean> kickTask = () -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return false;
player.networkHandler.disconnect(NMSCommandSender.fromLegacy(s));
return true;
};
if (server.isOnThread()) {
return kickTask.get();
} else {
ViaFabric.JLOGGER.log(Level.WARNING, "Weird!? Player kicking was called off-thread", new Throwable());
runServerSync(kickTask::get);
}
return false; // Can't know if it worked
}
}

View File

@ -1,54 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.platform;
import com.viaversion.fabric.mc1165.providers.VFHandItemProvider;
import com.viaversion.fabric.mc1165.providers.FabricVersionProvider;
import com.viaversion.fabric.mc1165.providers.VFPlayerAbilitiesProvider;
import com.viaversion.fabric.mc1165.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.provider.PlayerAbilitiesProvider;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.platform.ViaPlatformLoader;
import com.viaversion.viaversion.api.protocol.version.VersionProvider;
public class VFLoader implements ViaPlatformLoader {
@Override
public void load() {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerAbilitiesProvider.class, new VFPlayerAbilitiesProvider());
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override
public void unload() {
// Nothing to do
}
}

View File

@ -1,54 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.providers;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.AbstractFabricVersionProvider;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.viaversion.fabric.mc1165.service.ProtocolAutoDetector;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.ChannelPipeline;
import net.minecraft.network.ClientConnection;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
public class FabricVersionProvider extends AbstractFabricVersionProvider {
@Override
protected Logger getLogger() {
return ViaFabric.JLOGGER;
}
@Override
protected VFConfig getConfig() {
return ViaFabric.config;
}
@Override
protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
return ProtocolAutoDetector.detectVersion(address);
}
@Override
protected boolean isMulticonnectHandler(ChannelPipeline pipe) {
return pipe.get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect");
}
}

View File

@ -1,74 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.providers;
import com.viaversion.fabric.common.util.RemappingUtil;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override
public Item getHandItem(UserConnection info) {
if (info.isClientSide()) {
return getClientItem();
}
return super.getHandItem(info);
}
private Item getClientItem() {
if (clientItem == null) {
return new DataItem(0, (byte) 0, null);
}
return clientItem.copy();
}
@Environment(EnvType.CLIENT)
public void registerClientTick() {
try {
ClientTickEvents.END_WORLD_TICK.register(clientWorld -> tickClient());
} catch (NoClassDefFoundError ignored) {
ViaFabric.JLOGGER.info("Fabric Lifecycle V1 isn't installed");
}
}
private void tickClient() {
ClientPlayerEntity p = MinecraftClient.getInstance().player;
if (p != null) {
clientItem = fromNative(p.inventory.getMainHandStack());
}
}
private Item fromNative(ItemStack original) {
Identifier iid = Registry.ITEM.getId(original.getItem());
int id = RemappingUtil.swordId(iid.toString());
return new DataItem(id, (byte) original.getCount(), (short) original.getDamage(), null);
}
}

View File

@ -1,39 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.provider.PlayerAbilitiesProvider;
import net.minecraft.client.MinecraftClient;
public class VFPlayerAbilitiesProvider extends PlayerAbilitiesProvider {
@Override
public float getFlyingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getFlyingSpeed(connection);
return MinecraftClient.getInstance().player.abilities.getFlySpeed();
}
@Override
public float getWalkingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getWalkingSpeed(connection);
return MinecraftClient.getInstance().player.abilities.getWalkSpeed();
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 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/>.
*/
package com.viaversion.fabric.mc1165.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public BlockPosition getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new BlockPosition(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

Some files were not shown because too many files have changed in this diff Show More