mirror of
https://github.com/Aizistral-Studios/No-Chat-Restrictions.git
synced 2026-08-24 13:17:16 +08:00
Fix Account Switcher compatibility
Fixes #11 Co-Authored-By: Sw3ys <298241939+sw3ys@users.noreply.github.com>
This commit is contained in:
-102
@@ -1,102 +0,0 @@
|
|||||||
package com.aizistral.nochatrestrictions.core;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.aizistral.nochatrestrictions.config.NCRConfig;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
|
||||||
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 final UserApiService service;
|
|
||||||
private @Nullable UserProperties properties = null;
|
|
||||||
|
|
||||||
public WrappedUserApiService(UserApiService service) {
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserProperties fetchProperties() throws AuthenticationException {
|
|
||||||
if (this.properties != null)
|
|
||||||
return this.properties;
|
|
||||||
|
|
||||||
NCRConfig config = NCRConfig.getInstance();
|
|
||||||
UserProperties properties = this.service.fetchProperties();
|
|
||||||
ImmutableSet.Builder<UserFlag> 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.FRIENDS_ENABLED); // not sure if we need this, but let it be
|
|
||||||
// flags.add(UserFlag.CHAT_FRIENDS_ONLY); // not adding this for obvious reasons
|
|
||||||
|
|
||||||
this.addOptionalFlag(UserFlag.ACCEPT_FRIEND_INVITES, flags, properties); // I assume this is user-controller
|
|
||||||
|
|
||||||
if (config.allowTelemetry()) { // weird flex but ok
|
|
||||||
this.addOptionalFlag(UserFlag.TELEMETRY_ENABLED, flags, properties);
|
|
||||||
this.addOptionalFlag(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE, flags, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.allowProfanityFilter()) { // never seen anyone actually want this, but sure
|
|
||||||
this.addOptionalFlag(UserFlag.PROFANITY_FILTER_ENABLED, flags, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.properties = new UserProperties(flags.build(), Map.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addOptionalFlag(UserFlag flag, ImmutableSet.Builder<UserFlag> builder, UserProperties properties) {
|
|
||||||
if (properties.flag(flag)) {
|
|
||||||
builder.add(flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBlockedPlayer(UUID playerID) {
|
|
||||||
return this.service.isBlockedPlayer(playerID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshBlockList() {
|
|
||||||
this.service.refreshBlockList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TelemetrySession newTelemetrySession(Executor executor) {
|
|
||||||
if (NCRConfig.getInstance().allowTelemetry())
|
|
||||||
return this.service.newTelemetrySession(executor);
|
|
||||||
else
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -5,26 +5,14 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
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.Minecraft;
|
||||||
import net.minecraft.client.main.GameConfig;
|
|
||||||
|
|
||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
public class MixinMinecraft {
|
public class MixinMinecraft {
|
||||||
|
|
||||||
@Inject(method = "createUserApiService", at = @At("RETURN"), cancellable = true)
|
// Removal of multiplayer/chat/telemetry restrictions is handled in
|
||||||
private static void onCreateUserApi(YggdrasilAuthenticationService authService, GameConfig gameConfig,
|
// MixinYggdrasilUserApiService, so that it keeps working after in-game
|
||||||
CallbackInfoReturnable<UserApiService> info) {
|
// account switchers (e.g. IAS) replace the UserApiService instance.
|
||||||
UserApiService returnedService = info.getReturnValue();
|
|
||||||
assert returnedService != null;
|
|
||||||
info.setReturnValue(new WrappedUserApiService(returnedService));
|
|
||||||
|
|
||||||
NCRCore.LOGGER.info("Successfully supplanted UserApiService with a wrapped version.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "isNameBanned", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isNameBanned", at = @At("HEAD"), cancellable = true)
|
||||||
private void onCheckNameBan(CallbackInfoReturnable<Boolean> info) {
|
private void onCheckNameBan(CallbackInfoReturnable<Boolean> info) {
|
||||||
|
|||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
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.Unique;
|
||||||
|
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.config.NCRConfig;
|
||||||
|
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 {
|
||||||
|
|
||||||
|
@Inject(method = "fetchProperties", at = @At("RETURN"), cancellable = true)
|
||||||
|
private void onFetchProperties(CallbackInfoReturnable<UserProperties> info) {
|
||||||
|
UserProperties original = info.getReturnValue();
|
||||||
|
|
||||||
|
if (original == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NCRConfig config = NCRConfig.getInstance();
|
||||||
|
ImmutableSet.Builder<UserFlag> 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.FRIENDS_ENABLED); // not sure if we need this, but let it be
|
||||||
|
// flags.add(UserFlag.CHAT_FRIENDS_ONLY); // not adding this for obvious reasons
|
||||||
|
|
||||||
|
this.addOptionalFlag(UserFlag.ACCEPT_FRIEND_INVITES, flags, original); // I assume this is user-controlled
|
||||||
|
|
||||||
|
if (config.allowTelemetry()) { // weird flex but ok
|
||||||
|
this.addOptionalFlag(UserFlag.TELEMETRY_ENABLED, flags, original);
|
||||||
|
this.addOptionalFlag(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE, flags, original);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.allowProfanityFilter()) { // never seen anyone actually want this, but sure
|
||||||
|
this.addOptionalFlag(UserFlag.PROFANITY_FILTER_ENABLED, flags, original);
|
||||||
|
}
|
||||||
|
|
||||||
|
info.setReturnValue(new UserProperties(flags.build(), Map.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "newTelemetrySession", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onNewTelemetrySession(Executor executor, CallbackInfoReturnable<TelemetrySession> info) {
|
||||||
|
if (!NCRConfig.getInstance().allowTelemetry()) {
|
||||||
|
info.setReturnValue(TelemetrySession.DISABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private void addOptionalFlag(UserFlag flag, ImmutableSet.Builder<UserFlag> builder, UserProperties properties) {
|
||||||
|
if (properties.flag(flag)) {
|
||||||
|
builder.add(flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"mixins": [],
|
"mixins": [],
|
||||||
"client": [
|
"client": [
|
||||||
"MixinMinecraft"
|
"MixinMinecraft",
|
||||||
|
"MixinYggdrasilUserApiService"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
package com.aizistral.nochatrestrictions.core;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.aizistral.nochatrestrictions.config.NCRConfig;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
|
||||||
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 final UserApiService service;
|
|
||||||
private @Nullable UserProperties properties = null;
|
|
||||||
|
|
||||||
public WrappedUserApiService(UserApiService service) {
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserProperties fetchProperties() throws AuthenticationException {
|
|
||||||
if (this.properties != null)
|
|
||||||
return this.properties;
|
|
||||||
|
|
||||||
NCRConfig config = NCRConfig.getInstance();
|
|
||||||
UserProperties properties = this.service.fetchProperties();
|
|
||||||
ImmutableSet.Builder<UserFlag> 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.FRIENDS_ENABLED); // not sure if we need this, but let it be
|
|
||||||
// flags.add(UserFlag.CHAT_FRIENDS_ONLY); // not adding this for obvious reasons
|
|
||||||
|
|
||||||
this.addOptionalFlag(UserFlag.ACCEPT_FRIEND_INVITES, flags, properties); // I assume this is user-controller
|
|
||||||
|
|
||||||
if (config.allowTelemetry()) { // weird flex but ok
|
|
||||||
this.addOptionalFlag(UserFlag.TELEMETRY_ENABLED, flags, properties);
|
|
||||||
this.addOptionalFlag(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE, flags, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.allowProfanityFilter()) { // never seen anyone actually want this, but sure
|
|
||||||
this.addOptionalFlag(UserFlag.PROFANITY_FILTER_ENABLED, flags, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.properties = new UserProperties(flags.build(), Map.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addOptionalFlag(UserFlag flag, ImmutableSet.Builder<UserFlag> builder, UserProperties properties) {
|
|
||||||
if (properties.flag(flag)) {
|
|
||||||
builder.add(flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBlockedPlayer(UUID playerID) {
|
|
||||||
return this.service.isBlockedPlayer(playerID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshBlockList() {
|
|
||||||
this.service.refreshBlockList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TelemetrySession newTelemetrySession(Executor executor) {
|
|
||||||
if (NCRConfig.getInstance().allowTelemetry())
|
|
||||||
return this.service.newTelemetrySession(executor);
|
|
||||||
else
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -5,26 +5,14 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
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.Minecraft;
|
||||||
import net.minecraft.client.main.GameConfig;
|
|
||||||
|
|
||||||
@Mixin(value = Minecraft.class, remap = false)
|
@Mixin(value = Minecraft.class, remap = false)
|
||||||
public class MixinMinecraft {
|
public class MixinMinecraft {
|
||||||
|
|
||||||
@Inject(method = "createUserApiService", at = @At("RETURN"), cancellable = true)
|
// Removal of multiplayer/chat/telemetry restrictions is handled in
|
||||||
private static void onCreateUserApi(YggdrasilAuthenticationService authService, GameConfig gameConfig,
|
// MixinYggdrasilUserApiService, so that it keeps working after in-game
|
||||||
CallbackInfoReturnable<UserApiService> info) {
|
// account switchers (e.g. IAS) replace the UserApiService instance.
|
||||||
UserApiService returnedService = info.getReturnValue();
|
|
||||||
assert returnedService != null;
|
|
||||||
info.setReturnValue(new WrappedUserApiService(returnedService));
|
|
||||||
|
|
||||||
NCRCore.LOGGER.info("Successfully supplanted UserApiService with a wrapped version.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "isNameBanned", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isNameBanned", at = @At("HEAD"), cancellable = true)
|
||||||
private void onCheckNameBan(CallbackInfoReturnable<Boolean> info) {
|
private void onCheckNameBan(CallbackInfoReturnable<Boolean> info) {
|
||||||
|
|||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
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.Unique;
|
||||||
|
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.config.NCRConfig;
|
||||||
|
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 {
|
||||||
|
|
||||||
|
@Inject(method = "fetchProperties", at = @At("RETURN"), cancellable = true)
|
||||||
|
private void onFetchProperties(CallbackInfoReturnable<UserProperties> info) {
|
||||||
|
UserProperties original = info.getReturnValue();
|
||||||
|
|
||||||
|
if (original == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NCRConfig config = NCRConfig.getInstance();
|
||||||
|
ImmutableSet.Builder<UserFlag> 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.FRIENDS_ENABLED); // not sure if we need this, but let it be
|
||||||
|
// flags.add(UserFlag.CHAT_FRIENDS_ONLY); // not adding this for obvious reasons
|
||||||
|
|
||||||
|
this.addOptionalFlag(UserFlag.ACCEPT_FRIEND_INVITES, flags, original); // I assume this is user-controlled
|
||||||
|
|
||||||
|
if (config.allowTelemetry()) { // weird flex but ok
|
||||||
|
this.addOptionalFlag(UserFlag.TELEMETRY_ENABLED, flags, original);
|
||||||
|
this.addOptionalFlag(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE, flags, original);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.allowProfanityFilter()) { // never seen anyone actually want this, but sure
|
||||||
|
this.addOptionalFlag(UserFlag.PROFANITY_FILTER_ENABLED, flags, original);
|
||||||
|
}
|
||||||
|
|
||||||
|
info.setReturnValue(new UserProperties(flags.build(), Map.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "newTelemetrySession", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onNewTelemetrySession(Executor executor, CallbackInfoReturnable<TelemetrySession> info) {
|
||||||
|
if (!NCRConfig.getInstance().allowTelemetry()) {
|
||||||
|
info.setReturnValue(TelemetrySession.DISABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private void addOptionalFlag(UserFlag flag, ImmutableSet.Builder<UserFlag> builder, UserProperties properties) {
|
||||||
|
if (properties.flag(flag)) {
|
||||||
|
builder.add(flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,7 +5,8 @@
|
|||||||
"refmap": "nochatrestrictions.refmap.json",
|
"refmap": "nochatrestrictions.refmap.json",
|
||||||
"mixins": [],
|
"mixins": [],
|
||||||
"client": [
|
"client": [
|
||||||
"MixinMinecraft"
|
"MixinMinecraft",
|
||||||
|
"MixinYggdrasilUserApiService"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|||||||
-102
@@ -1,102 +0,0 @@
|
|||||||
package com.aizistral.nochatrestrictions.core;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.aizistral.nochatrestrictions.config.NCRConfig;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
|
||||||
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 final UserApiService service;
|
|
||||||
private @Nullable UserProperties properties = null;
|
|
||||||
|
|
||||||
public WrappedUserApiService(UserApiService service) {
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserProperties fetchProperties() throws AuthenticationException {
|
|
||||||
if (this.properties != null)
|
|
||||||
return this.properties;
|
|
||||||
|
|
||||||
NCRConfig config = NCRConfig.getInstance();
|
|
||||||
UserProperties properties = this.service.fetchProperties();
|
|
||||||
ImmutableSet.Builder<UserFlag> 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.FRIENDS_ENABLED); // not sure if we need this, but let it be
|
|
||||||
// flags.add(UserFlag.CHAT_FRIENDS_ONLY); // not adding this for obvious reasons
|
|
||||||
|
|
||||||
this.addOptionalFlag(UserFlag.ACCEPT_FRIEND_INVITES, flags, properties); // I assume this is user-controller
|
|
||||||
|
|
||||||
if (config.allowTelemetry()) { // weird flex but ok
|
|
||||||
this.addOptionalFlag(UserFlag.TELEMETRY_ENABLED, flags, properties);
|
|
||||||
this.addOptionalFlag(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE, flags, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.allowProfanityFilter()) { // never seen anyone actually want this, but sure
|
|
||||||
this.addOptionalFlag(UserFlag.PROFANITY_FILTER_ENABLED, flags, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.properties = new UserProperties(flags.build(), Map.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addOptionalFlag(UserFlag flag, ImmutableSet.Builder<UserFlag> builder, UserProperties properties) {
|
|
||||||
if (properties.flag(flag)) {
|
|
||||||
builder.add(flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBlockedPlayer(UUID playerID) {
|
|
||||||
return this.service.isBlockedPlayer(playerID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshBlockList() {
|
|
||||||
this.service.refreshBlockList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TelemetrySession newTelemetrySession(Executor executor) {
|
|
||||||
if (NCRConfig.getInstance().allowTelemetry())
|
|
||||||
return this.service.newTelemetrySession(executor);
|
|
||||||
else
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -5,26 +5,14 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
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.Minecraft;
|
||||||
import net.minecraft.client.main.GameConfig;
|
|
||||||
|
|
||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
public class MixinMinecraft {
|
public class MixinMinecraft {
|
||||||
|
|
||||||
@Inject(method = "createUserApiService", at = @At("RETURN"), cancellable = true)
|
// Removal of multiplayer/chat/telemetry restrictions is handled in
|
||||||
private static void onCreateUserApi(YggdrasilAuthenticationService authService, GameConfig gameConfig,
|
// MixinYggdrasilUserApiService, so that it keeps working after in-game
|
||||||
CallbackInfoReturnable<UserApiService> info) {
|
// account switchers (e.g. IAS) replace the UserApiService instance.
|
||||||
UserApiService returnedService = info.getReturnValue();
|
|
||||||
assert returnedService != null;
|
|
||||||
info.setReturnValue(new WrappedUserApiService(returnedService));
|
|
||||||
|
|
||||||
NCRCore.LOGGER.info("Successfully supplanted UserApiService with a wrapped version.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "isNameBanned", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isNameBanned", at = @At("HEAD"), cancellable = true)
|
||||||
private void onCheckNameBan(CallbackInfoReturnable<Boolean> info) {
|
private void onCheckNameBan(CallbackInfoReturnable<Boolean> info) {
|
||||||
|
|||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
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.Unique;
|
||||||
|
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.config.NCRConfig;
|
||||||
|
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 {
|
||||||
|
|
||||||
|
@Inject(method = "fetchProperties", at = @At("RETURN"), cancellable = true)
|
||||||
|
private void onFetchProperties(CallbackInfoReturnable<UserProperties> info) {
|
||||||
|
UserProperties original = info.getReturnValue();
|
||||||
|
|
||||||
|
if (original == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NCRConfig config = NCRConfig.getInstance();
|
||||||
|
ImmutableSet.Builder<UserFlag> 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.FRIENDS_ENABLED); // not sure if we need this, but let it be
|
||||||
|
// flags.add(UserFlag.CHAT_FRIENDS_ONLY); // not adding this for obvious reasons
|
||||||
|
|
||||||
|
this.addOptionalFlag(UserFlag.ACCEPT_FRIEND_INVITES, flags, original); // I assume this is user-controlled
|
||||||
|
|
||||||
|
if (config.allowTelemetry()) { // weird flex but ok
|
||||||
|
this.addOptionalFlag(UserFlag.TELEMETRY_ENABLED, flags, original);
|
||||||
|
this.addOptionalFlag(UserFlag.OPTIONAL_TELEMETRY_AVAILABLE, flags, original);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.allowProfanityFilter()) { // never seen anyone actually want this, but sure
|
||||||
|
this.addOptionalFlag(UserFlag.PROFANITY_FILTER_ENABLED, flags, original);
|
||||||
|
}
|
||||||
|
|
||||||
|
info.setReturnValue(new UserProperties(flags.build(), Map.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "newTelemetrySession", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onNewTelemetrySession(Executor executor, CallbackInfoReturnable<TelemetrySession> info) {
|
||||||
|
if (!NCRConfig.getInstance().allowTelemetry()) {
|
||||||
|
info.setReturnValue(TelemetrySession.DISABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private void addOptionalFlag(UserFlag flag, ImmutableSet.Builder<UserFlag> builder, UserProperties properties) {
|
||||||
|
if (properties.flag(flag)) {
|
||||||
|
builder.add(flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,7 +5,8 @@
|
|||||||
"refmap": "nochatrestrictions.refmap.json",
|
"refmap": "nochatrestrictions.refmap.json",
|
||||||
"mixins": [],
|
"mixins": [],
|
||||||
"client": [
|
"client": [
|
||||||
"MixinMinecraft"
|
"MixinMinecraft",
|
||||||
|
"MixinYggdrasilUserApiService"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|||||||
Reference in New Issue
Block a user