I'm out of tolerance for Java for today, it still doesn't work.

This commit is contained in:
flash 2024-07-10 21:37:14 +02:00
parent 38794109c8
commit 552bd63c1a
9 changed files with 150 additions and 8 deletions

View file

@ -22,6 +22,7 @@ import java.util.Map;
import java.util.UUID;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.flashii.mcexts.Tools;
public class RPC {
private static final String DEFAULT_SECRET = "meow";
@ -74,6 +75,9 @@ public class RPC {
throws GeneralSecurityException, IOException, InterruptedException {
boolean hasBody = bodyStr != null;
String time = getRequestTimestamp();
Tools.Log.info("[FII RPC] {} {} @ {}", hasBody ? "POST" : "GET", path, time);
String hash = createRequestSignature(time, URLs.getRpcPath(path), sigStr);
URI url;

View file

@ -0,0 +1,8 @@
package net.flashii.mcexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tools {
public static final Logger Log = LoggerFactory.getLogger("fiiexts");
}

View file

@ -1,5 +1,6 @@
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;
@ -15,7 +16,9 @@ public abstract class PlayerListHudMixin {
target = "Lnet/minecraft/client/MinecraftClient;isInSingleplayer()Z"
)
)
public boolean redirectIsInSinglePlayer(MinecraftClient client) {
public boolean isInSinglePlayer(MinecraftClient client) {
Tools.Log.info("[FII MIXIN] Redirected isInSingleplayer call in PlayerListHud.render!!!");
// always enable BL
return true;
}

View file

@ -6,6 +6,7 @@ import java.security.GeneralSecurityException;
import com.mojang.authlib.GameProfile;
import net.flashii.mcexts.RPC;
import net.flashii.mcexts.RPCPayload;
import net.flashii.mcexts.Tools;
import net.minecraft.server.PlayerManager;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@ -29,13 +30,15 @@ public abstract class PlayerManagerMixin {
if(!payload.is("auth:ok")) {
if(payload.is("error")) {
authText = Text.literal(
payload.getAttrStr(payload.hasAttr("text") ? "text" : "code")
).formatted(Formatting.RED);
String errorCode = payload.getAttrStr("code");
String errorText = payload.hasAttr("text") ? payload.getAttrStr("text") : errorCode;
Tools.Log.info("[FII AUTH] <{}:{}:{}> Error: {} {}", profile.getId(), profile.getName(), sockAddr, errorCode, errorText);
authText = Text.literal(errorText).formatted(Formatting.RED);
} else if(payload.is("auth:authorise")) {
String userName = payload.getAttrStr("user_name");
int userColour = payload.hasAttr("user_colour") ? payload.getAttrInt("user_colour") : 0xFFFFFF;
String url = payload.getAttrStr("url");
Tools.Log.info("[FII AUTH] <{}:{}:{}> Authorising: {} {} {}", profile.getId(), profile.getName(), sockAddr, userName, userColour, url);
authText = Text.literal("Welcome back, ")
.append(Text.literal(userName).styled(style -> style.withColor(userColour).withBold(true)))
@ -47,6 +50,7 @@ public abstract class PlayerManagerMixin {
} else if(payload.is("auth:link")) {
String code = payload.getAttrStr("code");
String url = payload.getAttrStr("url");
Tools.Log.info("[FII AUTH] <{}:{}:{}> Linking: {} {}", profile.getId(), profile.getName(), sockAddr, code, url);
authText = Text.literal("This seems to be the first time you're connecting!\n")
.append(Text.literal("Visit "))
@ -55,16 +59,22 @@ public abstract class PlayerManagerMixin {
.append(Text.literal(code).formatted(Formatting.LIGHT_PURPLE))
.append(Text.literal("\n\nAfter you've approved the attempt, connect to the server again and you should be good to go."));
} else {
Tools.Log.info("[FII AUTH] <{}:{}:{}> Unknown response: {}", profile.getId(), profile.getName(), sockAddr, payload.getName());
authText = Text.literal("Flashii authentication server returned an unknown response, yell at flashwave about this.").formatted(Formatting.RED);
}
} else {
Tools.Log.info("[FII AUTH] <{}:{}:{}> Authentication successful!", profile.getId(), profile.getName(), sockAddr);
}
} catch(IOException ex) {
Tools.Log.error("[FII AUTH] <{}:{}:{}> IOException!!", profile.getId(), profile.getName(), sockAddr);
authText = Text.literal("Flashii authentication server failed to respond, yell at flashwave about this.").formatted(Formatting.RED);
ex.printStackTrace();
} catch(GeneralSecurityException ex) {
Tools.Log.error("[FII AUTH] <{}:{}:{}> GeneralSecurityException!!", profile.getId(), profile.getName(), sockAddr);
authText = Text.literal("Problem with request verification, yell at flashwave about this.").formatted(Formatting.RED);
ex.printStackTrace();
} catch(InterruptedException ex) {
Tools.Log.error("[FII AUTH] <{}:{}:{}> InterruptedException!!", profile.getId(), profile.getName(), sockAddr);
authText = Text.literal("Problem with connecting to the Flashii authentication server, yell at flashwave about this.").formatted(Formatting.RED);
ex.printStackTrace();
}

View file

@ -4,6 +4,7 @@ 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;
@ -16,16 +17,27 @@ public abstract class PlayerSkinProviderMixin {
at = @At("RETURN"),
cancellable = true
)
private void modifyFetchSkinTexturesReturn(GameProfile profile, CallbackInfoReturnable<CompletableFuture<SkinTextures>> cir) {
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(),
true
st.secure()
);
}));
cir.cancel();

View file

@ -2,6 +2,7 @@ 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;
@ -16,6 +17,8 @@ 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();

View file

@ -17,7 +17,7 @@ public abstract class YggdrasilEnvironmentMixin {
ordinal = 0
)
)
private Environment redirectEnvironmentCreation(String sessionHost, String servicesHost, String name) {
private Environment init(String sessionHost, String servicesHost, String name) {
return new Environment(URLs.getSessionHost(), servicesHost, name);
}
}

View file

@ -0,0 +1,101 @@
package net.flashii.mcexts.mixin;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.SignatureState;
import com.mojang.authlib.minecraft.MinecraftProfileTextures;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.ProfileResult;
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
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.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(YggdrasilMinecraftSessionService.class)
public abstract class YggdrasilMinecraftSessionServiceMixin {
@Inject(
method = "getPackedTextures(Lcom/mojang/authlib/GameProfile;)Lcom/mojang/authlib/properties/Property;",
at = @At("RETURN"),
cancellable = true,
remap = false
)
private void getPackedTextures(GameProfile profile, CallbackInfoReturnable<Property> cir) {
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getPackedTextures!!!");
Tools.Log.info("[FII MIXIN] {}", profile);
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());
}
@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());
}
@Inject(
method = "getSecurePropertyValue(Lcom/mojang/authlib/properties/Property;)Ljava/lang/String;",
at = @At("HEAD"),
cancellable = true,
remap = false
)
private void getSecurePropertyValue(Property property, CallbackInfoReturnable<String> cir) {
Tools.Log.info("[FII MIXIN] Intercepted YggdrasilMinecraftSessionService.getSecurePropertyValue!!!");
cir.setReturnValue(property.value());
cir.cancel();
}
@Inject(
method = "getPropertySignatureState(Lcom/mojang/authlib/properties/Property;)Lcom/mojang/authlib/SignatureState;",
at = @At("HEAD"),
cancellable = true,
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"),
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;
}
}

View file

@ -6,7 +6,8 @@
"PlayerSkinProviderMixin",
"PlayerListHudMixin",
"TextureUrlCheckerMixin",
"YggdrasilEnvironmentMixin"
"YggdrasilEnvironmentMixin",
"YggdrasilMinecraftSessionServiceMixin"
],
"server": [
"PlayerManagerMixin",