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.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
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;
|
||||
|
||||
import net.flashii.mcexts.Tools;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.hud.PlayerListHud;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -17,8 +16,6 @@ public abstract class PlayerListHudMixin {
|
|||
)
|
||||
)
|
||||
public boolean isInSinglePlayer(MinecraftClient client) {
|
||||
Tools.Log.info("[FII MIXIN] Redirected isInSingleplayer call in PlayerListHud.render!!!");
|
||||
|
||||
// always enable BL
|
||||
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 net.flashii.mcexts.URLs;
|
||||
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;
|
||||
|
@ -17,8 +16,6 @@ public abstract class TextureUrlCheckerMixin {
|
|||
remap = false
|
||||
)
|
||||
private static void isAllowedTextureDomain(String url, CallbackInfoReturnable<Boolean> cir) {
|
||||
Tools.Log.info("[FII MIXIN] Intercepted TextureUrlChecker.isAllowedTextureDomain!!!");
|
||||
|
||||
if(url == null || url.startsWith(URLs.getTexturesHostPrefix())) {
|
||||
cir.setReturnValue(true);
|
||||
cir.cancel();
|
||||
|
|
|
@ -14,8 +14,10 @@ public abstract class YggdrasilEnvironmentMixin {
|
|||
at = @At(
|
||||
value = "NEW",
|
||||
target = "com/mojang/authlib/Environment",
|
||||
ordinal = 0
|
||||
)
|
||||
ordinal = 0,
|
||||
remap = false
|
||||
),
|
||||
remap = false
|
||||
)
|
||||
private Environment init(String sessionHost, String servicesHost, String name) {
|
||||
return new Environment(URLs.getSessionHost(), servicesHost, name);
|
||||
|
|
|
@ -1,23 +1,82 @@
|
|||
package net.flashii.mcexts.mixin;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
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.yggdrasil.ProfileResult;
|
||||
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.concurrent.CompletableFuture;
|
||||
import net.minecraft.client.util.SkinTextures;
|
||||
import net.flashii.mcexts.ProfileResultCache;
|
||||
import net.flashii.mcexts.Tools;
|
||||
import net.flashii.mcexts.URLs;
|
||||
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.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(YggdrasilMinecraftSessionService.class)
|
||||
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(
|
||||
method = "getPackedTextures(Lcom/mojang/authlib/GameProfile;)Lcom/mojang/authlib/properties/Property;",
|
||||
at = @At("RETURN"),
|
||||
|
@ -25,27 +84,22 @@ public abstract class YggdrasilMinecraftSessionServiceMixin {
|
|||
remap = false
|
||||
)
|
||||
private void getPackedTextures(GameProfile profile, CallbackInfoReturnable<Property> cir) {
|
||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getPackedTextures!!!");
|
||||
Tools.Log.info("[FII MIXIN] {}", profile);
|
||||
|
||||
boolean replace = false;
|
||||
Property prop = cir.getReturnValue();
|
||||
if(prop == null)
|
||||
Tools.Log.info("[FII MIXIN] prop is null");
|
||||
else
|
||||
Tools.Log.info("[FII MIXIN] name:{} value:{} signature:{}", prop.name(), prop.value(), prop.signature());
|
||||
}
|
||||
if(prop == null) {
|
||||
ProfileResult result = getProfileFromMince(profile.getId(), true);
|
||||
if(result == null) {
|
||||
Tools.Log.info("[FII MIXIN] PROFILE RESULT IS NULL!!!!!!!!");
|
||||
} else {
|
||||
replace = true;
|
||||
prop = (Property)Iterables.getFirst(result.profile().getProperties().get("textures"), (Object)null);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "unpackTextures(Lcom/mojang/authlib/properties/Property;)Lcom/mojang/authlib/minecraft/MinecraftProfileTextures;",
|
||||
at = @At("RETURN"),
|
||||
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());
|
||||
if(replace) {
|
||||
cir.setReturnValue(prop);
|
||||
cir.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
|
@ -54,9 +108,7 @@ public abstract class YggdrasilMinecraftSessionServiceMixin {
|
|||
cancellable = true,
|
||||
remap = false
|
||||
)
|
||||
private void getSecurePropertyValue(Property property, CallbackInfoReturnable<String> cir) {
|
||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getSecurePropertyValue!!!");
|
||||
|
||||
public void getSecurePropertyValue(Property property, CallbackInfoReturnable<String> cir) {
|
||||
cir.setReturnValue(property.value());
|
||||
cir.cancel();
|
||||
}
|
||||
|
@ -68,34 +120,21 @@ public abstract class YggdrasilMinecraftSessionServiceMixin {
|
|||
remap = false
|
||||
)
|
||||
private void getPropertySignatureState(Property property, CallbackInfoReturnable<SignatureState> cir) {
|
||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getPropertySignatureState!!!");
|
||||
|
||||
cir.setReturnValue(SignatureState.SIGNED);
|
||||
cir.cancel();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "fetchProfileUncached(Ljava/util/UUID;Z)Lcom/mojang/authlib/yggdrasil/ProfileResult;",
|
||||
at = @At("RETURN"),
|
||||
method = "fetchProfile(Ljava/util/UUID;Z)Lcom/mojang/authlib/yggdrasil/ProfileResult;",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true,
|
||||
remap = false
|
||||
)
|
||||
private void fetchProfileUncached(UUID profileId, boolean requireSecure, CallbackInfoReturnable<ProfileResult> cir) {
|
||||
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.fetchProfileUncached!!!");
|
||||
Tools.Log.info("[FII MIXIN] {}", cir.getReturnValue().profile());
|
||||
}
|
||||
|
||||
@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;
|
||||
public void fetchProfile(UUID profileId, boolean requireSecure, CallbackInfoReturnable<ProfileResult> cir) {
|
||||
ProfileResult result = getProfileFromMince(profileId, !requireSecure);
|
||||
if(result != null) {
|
||||
cir.setReturnValue(result);
|
||||
cir.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"package": "net.flashii.mcexts.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [
|
||||
"PlayerSkinProviderMixin",
|
||||
"PlayerListEntryMixin",
|
||||
"PlayerListHudMixin",
|
||||
"TextureUrlCheckerMixin",
|
||||
"YggdrasilEnvironmentMixin",
|
||||
|
|
Loading…
Reference in a new issue