diff --git a/Fabric/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java b/Fabric/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java deleted file mode 100644 index e3e367d..0000000 --- a/Fabric/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.aizistral.nochatrestrictions.core; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.Executor; - -import com.google.common.collect.ImmutableSet; -import com.mojang.authlib.minecraft.TelemetrySession; -import com.mojang.authlib.minecraft.UserApiService; -import com.mojang.authlib.minecraft.report.AbuseReportLimits; -import com.mojang.authlib.yggdrasil.request.AbuseReportRequest; -import com.mojang.authlib.yggdrasil.response.KeyPairResponse; - -public class WrappedUserApiService implements UserApiService { - 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 - // flags.add(UserFlag.TELEMETRY_ENABLED); // not adding this for obvious reasons - // flags.add(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE); // thanks but no thanks - // flags.add(UserFlag.PROFANITY_FILTER_ENABLED) // not adding this one either - - FORCED_PROPERTIES = new UserProperties(flags.build(), Map.of()); - } - - private final UserApiService service; - - public WrappedUserApiService(UserApiService service) { - this.service = service; - } - - @Override - public UserProperties fetchProperties() { - return FORCED_PROPERTIES; - } - - @Override - public boolean isBlockedPlayer(UUID playerID) { - return this.service.isBlockedPlayer(playerID); - } - - @Override - public void refreshBlockList() { - this.service.refreshBlockList(); - } - - @Override - public TelemetrySession newTelemetrySession(Executor executor) { - return TelemetrySession.DISABLED; - } - - // Methods below primarily concern chat reporting. Not doing anything with them - // here as that's out of scope for this mod, it's more of a No Chat Reports thing - - @Override - public KeyPairResponse getKeyPair() { - return this.service.getKeyPair(); - } - - @Override - public void reportAbuse(AbuseReportRequest request) { - this.service.reportAbuse(request); - } - - @Override - public boolean canSendReports() { - return this.service.canSendReports(); - } - - @Override - public AbuseReportLimits getAbuseReportLimits() { - return this.service.getAbuseReportLimits(); - } - -} diff --git a/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java b/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java index eb2cebe..5e9761a 100644 --- a/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java +++ b/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java @@ -5,26 +5,14 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.aizistral.nochatrestrictions.core.NCRCore; -import com.aizistral.nochatrestrictions.core.WrappedUserApiService; -import com.mojang.authlib.minecraft.UserApiService; -import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; - import net.minecraft.client.Minecraft; -import net.minecraft.client.main.GameConfig; @Mixin(Minecraft.class) public class MixinMinecraft { - @Inject(method = { "m_193585_", "createUserApiService" }, at = @At("RETURN"), cancellable = true) - public void onCreateUserApi(YggdrasilAuthenticationService authService, GameConfig gameConfig, - CallbackInfoReturnable info) { - UserApiService returnedService = info.getReturnValue(); - assert returnedService != null; - info.setReturnValue(new WrappedUserApiService(returnedService)); - - NCRCore.LOGGER.info("Successfully supplanted UserApiService with a wrapped version."); - } + // Removal of multiplayer/chat/telemetry restrictions is handled in + // MixinYggdrasilUserApiService, so that it keeps working after in-game + // account switchers (e.g. IAS) replace the UserApiService instance. @Inject(method = { "m_294837_", "isNameBanned" }, at = @At("HEAD"), cancellable = true) public void onCheckNameBan(CallbackInfoReturnable info) { 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..eda55bd --- /dev/null +++ b/Fabric/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java @@ -0,0 +1,54 @@ +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 + // flags.add(UserFlag.TELEMETRY_ENABLED); // not adding this for obvious reasons + // flags.add(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE); // thanks but no thanks + // flags.add(UserFlag.PROFANITY_FILTER_ENABLED) // not adding this one either + + 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); + } + +} diff --git a/Fabric/src/main/resources/nochatrestrictions.mixins.json b/Fabric/src/main/resources/nochatrestrictions.mixins.json index fca6bc9..1e741e9 100644 --- a/Fabric/src/main/resources/nochatrestrictions.mixins.json +++ b/Fabric/src/main/resources/nochatrestrictions.mixins.json @@ -5,7 +5,8 @@ "minVersion": "0.8", "mixins": [], "client": [ - "MixinMinecraft" + "MixinMinecraft", + "MixinYggdrasilUserApiService" ], "injectors": { "defaultRequire": 1 diff --git a/Forge/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java b/Forge/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java deleted file mode 100644 index e3e367d..0000000 --- a/Forge/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.aizistral.nochatrestrictions.core; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.Executor; - -import com.google.common.collect.ImmutableSet; -import com.mojang.authlib.minecraft.TelemetrySession; -import com.mojang.authlib.minecraft.UserApiService; -import com.mojang.authlib.minecraft.report.AbuseReportLimits; -import com.mojang.authlib.yggdrasil.request.AbuseReportRequest; -import com.mojang.authlib.yggdrasil.response.KeyPairResponse; - -public class WrappedUserApiService implements UserApiService { - 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 - // flags.add(UserFlag.TELEMETRY_ENABLED); // not adding this for obvious reasons - // flags.add(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE); // thanks but no thanks - // flags.add(UserFlag.PROFANITY_FILTER_ENABLED) // not adding this one either - - FORCED_PROPERTIES = new UserProperties(flags.build(), Map.of()); - } - - private final UserApiService service; - - public WrappedUserApiService(UserApiService service) { - this.service = service; - } - - @Override - public UserProperties fetchProperties() { - return FORCED_PROPERTIES; - } - - @Override - public boolean isBlockedPlayer(UUID playerID) { - return this.service.isBlockedPlayer(playerID); - } - - @Override - public void refreshBlockList() { - this.service.refreshBlockList(); - } - - @Override - public TelemetrySession newTelemetrySession(Executor executor) { - return TelemetrySession.DISABLED; - } - - // Methods below primarily concern chat reporting. Not doing anything with them - // here as that's out of scope for this mod, it's more of a No Chat Reports thing - - @Override - public KeyPairResponse getKeyPair() { - return this.service.getKeyPair(); - } - - @Override - public void reportAbuse(AbuseReportRequest request) { - this.service.reportAbuse(request); - } - - @Override - public boolean canSendReports() { - return this.service.canSendReports(); - } - - @Override - public AbuseReportLimits getAbuseReportLimits() { - return this.service.getAbuseReportLimits(); - } - -} diff --git a/Forge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java b/Forge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java index e470410..ffc0934 100644 --- a/Forge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java +++ b/Forge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java @@ -5,26 +5,14 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.aizistral.nochatrestrictions.core.NCRCore; -import com.aizistral.nochatrestrictions.core.WrappedUserApiService; -import com.mojang.authlib.minecraft.UserApiService; -import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; - import net.minecraft.client.Minecraft; -import net.minecraft.client.main.GameConfig; @Mixin(value = Minecraft.class, remap = false) public class MixinMinecraft { - @Inject(method = { "m_193585_", "createUserApiService" }, at = @At("RETURN"), cancellable = true) - public void onCreateUserApi(YggdrasilAuthenticationService authService, GameConfig gameConfig, - CallbackInfoReturnable info) { - UserApiService returnedService = info.getReturnValue(); - assert returnedService != null; - info.setReturnValue(new WrappedUserApiService(returnedService)); - - NCRCore.LOGGER.info("Successfully supplanted UserApiService with a wrapped version."); - } + // Removal of multiplayer/chat/telemetry restrictions is handled in + // MixinYggdrasilUserApiService, so that it keeps working after in-game + // account switchers (e.g. IAS) replace the UserApiService instance. @Inject(method = { "m_294837_", "isNameBanned" }, at = @At("HEAD"), cancellable = true) public void onCheckNameBan(CallbackInfoReturnable info) { diff --git a/Forge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java b/Forge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java new file mode 100644 index 0000000..eda55bd --- /dev/null +++ b/Forge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java @@ -0,0 +1,54 @@ +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 + // flags.add(UserFlag.TELEMETRY_ENABLED); // not adding this for obvious reasons + // flags.add(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE); // thanks but no thanks + // flags.add(UserFlag.PROFANITY_FILTER_ENABLED) // not adding this one either + + 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); + } + +} diff --git a/Forge/src/main/resources/nochatrestrictions.mixins.json b/Forge/src/main/resources/nochatrestrictions.mixins.json index c9e96c5..c74587e 100644 --- a/Forge/src/main/resources/nochatrestrictions.mixins.json +++ b/Forge/src/main/resources/nochatrestrictions.mixins.json @@ -5,7 +5,8 @@ "refmap": "nochatrestrictions.refmap.json", "mixins": [], "client": [ - "MixinMinecraft" + "MixinMinecraft", + "MixinYggdrasilUserApiService" ], "injectors": { "defaultRequire": 1 diff --git a/NeoForge/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java b/NeoForge/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java deleted file mode 100644 index e3e367d..0000000 --- a/NeoForge/src/main/java/com/aizistral/nochatrestrictions/core/WrappedUserApiService.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.aizistral.nochatrestrictions.core; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.Executor; - -import com.google.common.collect.ImmutableSet; -import com.mojang.authlib.minecraft.TelemetrySession; -import com.mojang.authlib.minecraft.UserApiService; -import com.mojang.authlib.minecraft.report.AbuseReportLimits; -import com.mojang.authlib.yggdrasil.request.AbuseReportRequest; -import com.mojang.authlib.yggdrasil.response.KeyPairResponse; - -public class WrappedUserApiService implements UserApiService { - 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 - // flags.add(UserFlag.TELEMETRY_ENABLED); // not adding this for obvious reasons - // flags.add(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE); // thanks but no thanks - // flags.add(UserFlag.PROFANITY_FILTER_ENABLED) // not adding this one either - - FORCED_PROPERTIES = new UserProperties(flags.build(), Map.of()); - } - - private final UserApiService service; - - public WrappedUserApiService(UserApiService service) { - this.service = service; - } - - @Override - public UserProperties fetchProperties() { - return FORCED_PROPERTIES; - } - - @Override - public boolean isBlockedPlayer(UUID playerID) { - return this.service.isBlockedPlayer(playerID); - } - - @Override - public void refreshBlockList() { - this.service.refreshBlockList(); - } - - @Override - public TelemetrySession newTelemetrySession(Executor executor) { - return TelemetrySession.DISABLED; - } - - // Methods below primarily concern chat reporting. Not doing anything with them - // here as that's out of scope for this mod, it's more of a No Chat Reports thing - - @Override - public KeyPairResponse getKeyPair() { - return this.service.getKeyPair(); - } - - @Override - public void reportAbuse(AbuseReportRequest request) { - this.service.reportAbuse(request); - } - - @Override - public boolean canSendReports() { - return this.service.canSendReports(); - } - - @Override - public AbuseReportLimits getAbuseReportLimits() { - return this.service.getAbuseReportLimits(); - } - -} diff --git a/NeoForge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java b/NeoForge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java index eb2cebe..5e9761a 100644 --- a/NeoForge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java +++ b/NeoForge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinMinecraft.java @@ -5,26 +5,14 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.aizistral.nochatrestrictions.core.NCRCore; -import com.aizistral.nochatrestrictions.core.WrappedUserApiService; -import com.mojang.authlib.minecraft.UserApiService; -import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; - import net.minecraft.client.Minecraft; -import net.minecraft.client.main.GameConfig; @Mixin(Minecraft.class) public class MixinMinecraft { - @Inject(method = { "m_193585_", "createUserApiService" }, at = @At("RETURN"), cancellable = true) - public void onCreateUserApi(YggdrasilAuthenticationService authService, GameConfig gameConfig, - CallbackInfoReturnable info) { - UserApiService returnedService = info.getReturnValue(); - assert returnedService != null; - info.setReturnValue(new WrappedUserApiService(returnedService)); - - NCRCore.LOGGER.info("Successfully supplanted UserApiService with a wrapped version."); - } + // Removal of multiplayer/chat/telemetry restrictions is handled in + // MixinYggdrasilUserApiService, so that it keeps working after in-game + // account switchers (e.g. IAS) replace the UserApiService instance. @Inject(method = { "m_294837_", "isNameBanned" }, at = @At("HEAD"), cancellable = true) public void onCheckNameBan(CallbackInfoReturnable info) { diff --git a/NeoForge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java b/NeoForge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java new file mode 100644 index 0000000..eda55bd --- /dev/null +++ b/NeoForge/src/main/java/com/aizistral/nochatrestrictions/mixins/MixinYggdrasilUserApiService.java @@ -0,0 +1,54 @@ +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 + // flags.add(UserFlag.TELEMETRY_ENABLED); // not adding this for obvious reasons + // flags.add(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE); // thanks but no thanks + // flags.add(UserFlag.PROFANITY_FILTER_ENABLED) // not adding this one either + + 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); + } + +} diff --git a/NeoForge/src/main/resources/nochatrestrictions.mixins.json b/NeoForge/src/main/resources/nochatrestrictions.mixins.json index 8cdf752..c6f2888 100644 --- a/NeoForge/src/main/resources/nochatrestrictions.mixins.json +++ b/NeoForge/src/main/resources/nochatrestrictions.mixins.json @@ -6,7 +6,8 @@ "refmap": "nochatrestrictions.refmap.json", "mixins": [], "client": [ - "MixinMinecraft" + "MixinMinecraft", + "MixinYggdrasilUserApiService" ], "injectors": { "defaultRequire": 1