That should do the trick!
This commit is contained in:
parent
552bd63c1a
commit
21a5d0062b
9 changed files with 129 additions and 102 deletions
19
src/main/java/net/flashii/mcexts/ProfileResultCache.java
Normal file
19
src/main/java/net/flashii/mcexts/ProfileResultCache.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package net.flashii.mcexts;
|
||||||
|
|
||||||
|
import com.mojang.authlib.yggdrasil.ProfileResult;
|
||||||
|
|
||||||
|
public class ProfileResultCache {
|
||||||
|
private static final long CACHE_TIMEOUT = 21600000;
|
||||||
|
|
||||||
|
public long readTime;
|
||||||
|
public ProfileResult value;
|
||||||
|
|
||||||
|
public ProfileResultCache(ProfileResult value) {
|
||||||
|
this.readTime = System.currentTimeMillis();
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean needsRefresh() {
|
||||||
|
return readTime < System.currentTimeMillis() - CACHE_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package net.flashii.mcexts.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.network.PlayerListEntry;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
|
@Mixin(PlayerListEntry.class)
|
||||||
|
public abstract class PlayerListEntryMixin {
|
||||||
|
@ModifyVariable(
|
||||||
|
method = "texturesSupplier(Lcom/mojang/authlib/GameProfile;)Ljava/util/function/Supplier;",
|
||||||
|
at = @At("STORE"),
|
||||||
|
ordinal = 0
|
||||||
|
)
|
||||||
|
private static boolean texturesSupplier(boolean bl) {
|
||||||
|
// always enable BL
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package net.flashii.mcexts.mixin;
|
package net.flashii.mcexts.mixin;
|
||||||
|
|
||||||
import net.flashii.mcexts.Tools;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.hud.PlayerListHud;
|
import net.minecraft.client.gui.hud.PlayerListHud;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -17,8 +16,6 @@ public abstract class PlayerListHudMixin {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
public boolean isInSinglePlayer(MinecraftClient client) {
|
public boolean isInSinglePlayer(MinecraftClient client) {
|
||||||
Tools.Log.info("[FII MIXIN] Redirected isInSingleplayer call in PlayerListHud.render!!!");
|
|
||||||
|
|
||||||
// always enable BL
|
// always enable BL
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
package net.flashii.mcexts.mixin;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import net.minecraft.client.texture.PlayerSkinProvider;
|
|
||||||
import net.minecraft.client.util.SkinTextures;
|
|
||||||
import net.flashii.mcexts.Tools;
|
|
||||||
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;
|
|
||||||
|
|
||||||
@Mixin(PlayerSkinProvider.class)
|
|
||||||
public abstract class PlayerSkinProviderMixin {
|
|
||||||
@Inject(
|
|
||||||
method = "fetchSkinTextures(Lcom/mojang/authlib/GameProfile;)Ljava/util/concurrent/CompletableFuture;",
|
|
||||||
at = @At("RETURN"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
private void fetchSkinTextures(GameProfile profile, CallbackInfoReturnable<CompletableFuture<SkinTextures>> cir) {
|
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted PlayerSkinProvider.fetchSkinTextures!!!");
|
|
||||||
|
|
||||||
CompletableFuture<SkinTextures> future = cir.getReturnValue();
|
|
||||||
cir.setReturnValue(future.thenApply(st -> {
|
|
||||||
Tools.Log.info(
|
|
||||||
"[FII MIXIN] future texture:{} textureUrl:{} capeTexture:{} elytraTexture:{} model:{} secure:{}",
|
|
||||||
st.texture(),
|
|
||||||
st.textureUrl(),
|
|
||||||
st.capeTexture(),
|
|
||||||
st.elytraTexture(),
|
|
||||||
st.model(),
|
|
||||||
st.secure()
|
|
||||||
);
|
|
||||||
return new SkinTextures(
|
|
||||||
st.texture(),
|
|
||||||
st.textureUrl(),
|
|
||||||
st.capeTexture(),
|
|
||||||
st.elytraTexture(),
|
|
||||||
st.model(),
|
|
||||||
st.secure()
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
cir.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@ package net.flashii.mcexts.mixin;
|
||||||
|
|
||||||
import com.mojang.authlib.yggdrasil.TextureUrlChecker;
|
import com.mojang.authlib.yggdrasil.TextureUrlChecker;
|
||||||
import net.flashii.mcexts.URLs;
|
import net.flashii.mcexts.URLs;
|
||||||
import net.flashii.mcexts.Tools;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
@ -17,8 +16,6 @@ public abstract class TextureUrlCheckerMixin {
|
||||||
remap = false
|
remap = false
|
||||||
)
|
)
|
||||||
private static void isAllowedTextureDomain(String url, CallbackInfoReturnable<Boolean> cir) {
|
private static void isAllowedTextureDomain(String url, CallbackInfoReturnable<Boolean> cir) {
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted TextureUrlChecker.isAllowedTextureDomain!!!");
|
|
||||||
|
|
||||||
if(url == null || url.startsWith(URLs.getTexturesHostPrefix())) {
|
if(url == null || url.startsWith(URLs.getTexturesHostPrefix())) {
|
||||||
cir.setReturnValue(true);
|
cir.setReturnValue(true);
|
||||||
cir.cancel();
|
cir.cancel();
|
||||||
|
|
|
@ -14,8 +14,10 @@ public abstract class YggdrasilEnvironmentMixin {
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "NEW",
|
value = "NEW",
|
||||||
target = "com/mojang/authlib/Environment",
|
target = "com/mojang/authlib/Environment",
|
||||||
ordinal = 0
|
ordinal = 0,
|
||||||
)
|
remap = false
|
||||||
|
),
|
||||||
|
remap = false
|
||||||
)
|
)
|
||||||
private Environment init(String sessionHost, String servicesHost, String name) {
|
private Environment init(String sessionHost, String servicesHost, String name) {
|
||||||
return new Environment(URLs.getSessionHost(), servicesHost, name);
|
return new Environment(URLs.getSessionHost(), servicesHost, name);
|
||||||
|
|
|
@ -1,23 +1,82 @@
|
||||||
package net.flashii.mcexts.mixin;
|
package net.flashii.mcexts.mixin;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.authlib.SignatureState;
|
import com.mojang.authlib.SignatureState;
|
||||||
import com.mojang.authlib.minecraft.MinecraftProfileTextures;
|
import com.mojang.authlib.minecraft.client.ObjectMapper;
|
||||||
import com.mojang.authlib.properties.Property;
|
import com.mojang.authlib.properties.Property;
|
||||||
import com.mojang.authlib.yggdrasil.ProfileResult;
|
import com.mojang.authlib.yggdrasil.ProfileResult;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
|
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
|
||||||
|
import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse;
|
||||||
|
import com.mojang.util.UndashedUuid;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import net.flashii.mcexts.ProfileResultCache;
|
||||||
import net.minecraft.client.util.SkinTextures;
|
|
||||||
import net.flashii.mcexts.Tools;
|
import net.flashii.mcexts.Tools;
|
||||||
|
import net.flashii.mcexts.URLs;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
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.ModifyArg;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
@Mixin(YggdrasilMinecraftSessionService.class)
|
@Mixin(YggdrasilMinecraftSessionService.class)
|
||||||
public abstract class YggdrasilMinecraftSessionServiceMixin {
|
public abstract class YggdrasilMinecraftSessionServiceMixin {
|
||||||
|
private static ObjectMapper objectMapper = ObjectMapper.create();
|
||||||
|
private static HashMap<UUID, ProfileResultCache> profileCache = new HashMap<>();
|
||||||
|
|
||||||
|
private static ProfileResult getProfileFromMince(UUID profileId, boolean allowCache) {
|
||||||
|
if(allowCache && profileCache.containsKey(profileId)) {
|
||||||
|
ProfileResultCache cachedProfile = profileCache.get(profileId);
|
||||||
|
if(!cachedProfile.needsRefresh())
|
||||||
|
return cachedProfile.value;
|
||||||
|
|
||||||
|
Tools.Log.info("[FII MIXIN] Cache expired!!!!!!!");
|
||||||
|
} else {
|
||||||
|
Tools.Log.info("[FII MIXIN] Forcing new fetch!!!!!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileResult profileResult = null;
|
||||||
|
try {
|
||||||
|
// this should probably have caching idk at what frequency this will get called
|
||||||
|
URI url;
|
||||||
|
try {
|
||||||
|
url = new URI(String.format("%s/session/minecraft/profile/%s", URLs.getSessionHost(), UndashedUuid.toString(profileId)));
|
||||||
|
} catch(URISyntaxException ex) {
|
||||||
|
Tools.Log.info("[FII MIXIN] INCORRECTLY FORMATTED PROFILE URL!!!!!!!!!!");
|
||||||
|
return profileResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
HttpRequest request = HttpRequest.newBuilder().uri(url).GET().build();
|
||||||
|
HttpResponse<String> response;
|
||||||
|
try {
|
||||||
|
response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
} catch(IOException | InterruptedException ex) {
|
||||||
|
Tools.Log.info("[FII MIXIN] FAILED TO SEND PROFILE REQUEST!!!!!!!!!!");
|
||||||
|
return profileResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(response.statusCode() != 200) {
|
||||||
|
Tools.Log.info("[FII MIXIN] NON-200 PROFILE RESPONSE CODE!!!!!!!!!!");
|
||||||
|
return profileResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftProfilePropertiesResponse profileResponse = objectMapper.readValue(response.body(), MinecraftProfilePropertiesResponse.class);
|
||||||
|
if(profileResponse != null)
|
||||||
|
profileResult = new ProfileResult(profileResponse.toProfile());
|
||||||
|
} finally {
|
||||||
|
profileCache.put(profileId, new ProfileResultCache(profileResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
return profileResult;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "getPackedTextures(Lcom/mojang/authlib/GameProfile;)Lcom/mojang/authlib/properties/Property;",
|
method = "getPackedTextures(Lcom/mojang/authlib/GameProfile;)Lcom/mojang/authlib/properties/Property;",
|
||||||
at = @At("RETURN"),
|
at = @At("RETURN"),
|
||||||
|
@ -25,27 +84,22 @@ public abstract class YggdrasilMinecraftSessionServiceMixin {
|
||||||
remap = false
|
remap = false
|
||||||
)
|
)
|
||||||
private void getPackedTextures(GameProfile profile, CallbackInfoReturnable<Property> cir) {
|
private void getPackedTextures(GameProfile profile, CallbackInfoReturnable<Property> cir) {
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getPackedTextures!!!");
|
boolean replace = false;
|
||||||
Tools.Log.info("[FII MIXIN] {}", profile);
|
|
||||||
|
|
||||||
Property prop = cir.getReturnValue();
|
Property prop = cir.getReturnValue();
|
||||||
if(prop == null)
|
if(prop == null) {
|
||||||
Tools.Log.info("[FII MIXIN] prop is null");
|
ProfileResult result = getProfileFromMince(profile.getId(), true);
|
||||||
else
|
if(result == null) {
|
||||||
Tools.Log.info("[FII MIXIN] name:{} value:{} signature:{}", prop.name(), prop.value(), prop.signature());
|
Tools.Log.info("[FII MIXIN] PROFILE RESULT IS NULL!!!!!!!!");
|
||||||
}
|
} else {
|
||||||
|
replace = true;
|
||||||
|
prop = (Property)Iterables.getFirst(result.profile().getProperties().get("textures"), (Object)null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(
|
if(replace) {
|
||||||
method = "unpackTextures(Lcom/mojang/authlib/properties/Property;)Lcom/mojang/authlib/minecraft/MinecraftProfileTextures;",
|
cir.setReturnValue(prop);
|
||||||
at = @At("RETURN"),
|
cir.cancel();
|
||||||
cancellable = true,
|
}
|
||||||
remap = false
|
|
||||||
)
|
|
||||||
private void unpackTextures(Property packedTextures, CallbackInfoReturnable<MinecraftProfileTextures> cir) {
|
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.unpackTextures!!!");
|
|
||||||
|
|
||||||
MinecraftProfileTextures textures = cir.getReturnValue();
|
|
||||||
Tools.Log.info("[FII MIXIN] skin:{} cape:{} elytra:{} signature:{}", textures.skin(), textures.cape(), textures.elytra(), textures.signatureState());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
|
@ -54,9 +108,7 @@ public abstract class YggdrasilMinecraftSessionServiceMixin {
|
||||||
cancellable = true,
|
cancellable = true,
|
||||||
remap = false
|
remap = false
|
||||||
)
|
)
|
||||||
private void getSecurePropertyValue(Property property, CallbackInfoReturnable<String> cir) {
|
public void getSecurePropertyValue(Property property, CallbackInfoReturnable<String> cir) {
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getSecurePropertyValue!!!");
|
|
||||||
|
|
||||||
cir.setReturnValue(property.value());
|
cir.setReturnValue(property.value());
|
||||||
cir.cancel();
|
cir.cancel();
|
||||||
}
|
}
|
||||||
|
@ -68,34 +120,21 @@ public abstract class YggdrasilMinecraftSessionServiceMixin {
|
||||||
remap = false
|
remap = false
|
||||||
)
|
)
|
||||||
private void getPropertySignatureState(Property property, CallbackInfoReturnable<SignatureState> cir) {
|
private void getPropertySignatureState(Property property, CallbackInfoReturnable<SignatureState> cir) {
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getPropertySignatureState!!!");
|
|
||||||
|
|
||||||
cir.setReturnValue(SignatureState.SIGNED);
|
cir.setReturnValue(SignatureState.SIGNED);
|
||||||
cir.cancel();
|
cir.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "fetchProfileUncached(Ljava/util/UUID;Z)Lcom/mojang/authlib/yggdrasil/ProfileResult;",
|
method = "fetchProfile(Ljava/util/UUID;Z)Lcom/mojang/authlib/yggdrasil/ProfileResult;",
|
||||||
at = @At("RETURN"),
|
at = @At("HEAD"),
|
||||||
cancellable = true,
|
cancellable = true,
|
||||||
remap = false
|
remap = false
|
||||||
)
|
)
|
||||||
private void fetchProfileUncached(UUID profileId, boolean requireSecure, CallbackInfoReturnable<ProfileResult> cir) {
|
public void fetchProfile(UUID profileId, boolean requireSecure, CallbackInfoReturnable<ProfileResult> cir) {
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.fetchProfileUncached!!!");
|
ProfileResult result = getProfileFromMince(profileId, !requireSecure);
|
||||||
Tools.Log.info("[FII MIXIN] {}", cir.getReturnValue().profile());
|
if(result != null) {
|
||||||
}
|
cir.setReturnValue(result);
|
||||||
|
cir.cancel();
|
||||||
@ModifyArg(
|
}
|
||||||
method = "fetchProfile",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lcom/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService;fetchProfileUncached(Ljava/util/UUID;Z)Lcom/mojang/authlib/yggdrasil/ProfileResult;"
|
|
||||||
),
|
|
||||||
index = 1,
|
|
||||||
remap = false
|
|
||||||
)
|
|
||||||
private boolean modifyFetchProfileUncachedArg(boolean requireSecure) {
|
|
||||||
Tools.Log.info("[FII MIXIN] Intercepted requireSecure argument for YggdrasilMinecraftSessionService.fetchProfileUncached in fetchProfile!!!");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"package": "net.flashii.mcexts.mixin",
|
"package": "net.flashii.mcexts.mixin",
|
||||||
"compatibilityLevel": "JAVA_21",
|
"compatibilityLevel": "JAVA_21",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"PlayerSkinProviderMixin",
|
"PlayerListEntryMixin",
|
||||||
"PlayerListHudMixin",
|
"PlayerListHudMixin",
|
||||||
"TextureUrlCheckerMixin",
|
"TextureUrlCheckerMixin",
|
||||||
"YggdrasilEnvironmentMixin",
|
"YggdrasilEnvironmentMixin",
|
||||||
|
|
Loading…
Reference in a new issue