From b9c00e334bc0c5307ca9228d3fe5e8476b0d7e43 Mon Sep 17 00:00:00 2001 From: Sw3ys Date: Tue, 30 Jun 2026 12:53:52 +0100 Subject: [PATCH] Create MixinYggdrasilUserApiService to remove restrictions This mixin modifies the YggdrasilUserApiService to remove chat and multiplayer restrictions by injecting custom user properties. It ensures that all instances of the service return permissive properties regardless of how they are created. --- .../mixins/MixinYggdrasilUserApiService.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java diff --git a/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java b/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java new file mode 100644 index 0000000..6c968b3 --- /dev/null +++ b/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java @@ -0,0 +1,51 @@ +package com.aizistral.nochatrestrictions.mixins; + +import java.util.Map; +import java.util.concurrent.Executor; + +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.google.common.collect.ImmutableSet; +import com.mojang.authlib.minecraft.TelemetrySession; +import com.mojang.authlib.minecraft.UserApiService.UserFlag; +import com.mojang.authlib.minecraft.UserApiService.UserProperties; +import com.mojang.authlib.yggdrasil.YggdrasilUserApiService; + +/** + * Applies the chat/multiplayer restriction removal directly on the concrete + * service class instead of wrapping it once at {@code Minecraft.createUserApiService}. + * + * In-game account switchers (e.g. IAS) build a brand new {@link YggdrasilUserApiService} + * and swap it onto the Minecraft instance without going through the original wrapping + * path, which is why restrictions used to come back after switching accounts. By hooking + * the service class itself, every instance the game ever uses returns permissive + * properties, regardless of who created it or when. + */ +@Mixin(value = YggdrasilUserApiService.class, remap = false) +public class MixinYggdrasilUserApiService { + private static final UserProperties FORCED_PROPERTIES; + + static { + ImmutableSet.Builder flags = ImmutableSet.builder(); + + flags.add(UserFlag.CHAT_ALLOWED); // always let the player access chat + flags.add(UserFlag.SERVERS_ALLOWED); // always let the player open multiplayer menu + flags.add(UserFlag.REALMS_ALLOWED); // always let the player open Realms menu + + FORCED_PROPERTIES = new UserProperties(flags.build(), Map.of()); + } + + @Inject(method = "fetchProperties", at = @At("RETURN"), cancellable = true) + private void onFetchProperties(CallbackInfoReturnable info) { + info.setReturnValue(FORCED_PROPERTIES); + } + + @Inject(method = "newTelemetrySession", at = @At("HEAD"), cancellable = true) + private void onNewTelemetrySession(Executor executor, CallbackInfoReturnable info) { + info.setReturnValue(TelemetrySession.DISABLED); + } + +}