Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yggdrasil Login #229

Merged
merged 1 commit into from
Mar 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@
- `Random Teleport, Hit Chance, Random Delay` (Removed from Meteor in [8722e](https://github.com/MeteorDevelopment/meteor-client/commit/8722ef565afa02ca4b6d9710a20fc9fcfd97bf05))
- AimAssist
- `Fov filter`
- Alts
- `Yggdrasil Login`

## Commands
- `.center`
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/anticope/rejects/mixin/MinecraftClientAccessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package anticope.rejects.mixin;

import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.minecraft.UserApiService;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.SocialInteractionsManager;
import net.minecraft.client.report.AbuseReportContext;
import net.minecraft.client.texture.PlayerSkinProvider;
import net.minecraft.client.util.ProfileKeys;
import net.minecraft.client.util.Session;
import net.minecraft.network.encryption.SignatureVerifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(MinecraftClient.class)
public interface MinecraftClientAccessor {
@Mutable
@Accessor("session")
void setSession(Session session);

@Mutable
@Accessor("sessionService")
void setSessionService(MinecraftSessionService sessionService);

@Mutable
@Accessor("authenticationService")
void setAuthenticationService(YggdrasilAuthenticationService authenticationService);

@Mutable
@Accessor("servicesSignatureVerifier")
void setServicesSignatureVerifier(SignatureVerifier servicesSignatureVerifier);

@Mutable
@Accessor("skinProvider")
void setSkinProvider(PlayerSkinProvider skinProvider);

@Mutable
@Accessor("socialInteractionsManager")
void setSocialInteractionsManager(SocialInteractionsManager socialInteractionsManager);

@Mutable
@Accessor("userApiService")
void setUserApiService(UserApiService userApiService);

@Mutable
@Accessor("abuseReportContext")
void setAbuseReportContext(AbuseReportContext abuseReportContext);

@Mutable
@Accessor("profileKeys")
void setProfileKeys(ProfileKeys profileKeys);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package anticope.rejects.mixin;

import net.minecraft.client.texture.PlayerSkinProvider;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

import java.io.File;

@Mixin(PlayerSkinProvider.class)
public interface PlayerSkinProviderAccessor {
@Accessor("skinCacheDir")
File getSkinCacheDir();
}
16 changes: 16 additions & 0 deletions src/main/java/anticope/rejects/mixin/meteor/AccountMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package anticope.rejects.mixin.meteor;

import anticope.rejects.utils.accounts.CustomYggdrasilAccount;
import meteordevelopment.meteorclient.systems.accounts.Account;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;

@Mixin(value = Account.class, remap = false)
public class AccountMixin {
@ModifyArg(method = "toTag", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/NbtCompound;putString(Ljava/lang/String;Ljava/lang/String;)V", ordinal = 0), index = 1)
private String putString(String key) {
if ((Object) this instanceof CustomYggdrasilAccount) return "Yggdrasil";
return key;
}
}
23 changes: 23 additions & 0 deletions src/main/java/anticope/rejects/mixin/meteor/AccountsMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package anticope.rejects.mixin.meteor;

import anticope.rejects.utils.accounts.CustomYggdrasilAccount;
import meteordevelopment.meteorclient.systems.accounts.Account;
import meteordevelopment.meteorclient.systems.accounts.Accounts;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
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 org.spongepowered.asm.mixin.injection.callback.LocalCapture;

@Mixin(value = Accounts.class, remap = false)
public class AccountsMixin {
@Inject(method = "lambda$fromTag$0", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/NbtCompound;getString(Ljava/lang/String;)Ljava/lang/String;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
private static void onFromTag(NbtElement tag1, CallbackInfoReturnable<Account<?>> cir, NbtCompound t) {
if (t.getString("type").equals("Yggdrasil")) {
Account<CustomYggdrasilAccount> account = new CustomYggdrasilAccount(null, null, null).fromTag(t);
if (account.fetchInfo()) cir.setReturnValue(account);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package anticope.rejects.mixin.meteor;

import anticope.rejects.utils.accounts.AddCustomYggdrasilAccountScreen;
import meteordevelopment.meteorclient.gui.GuiTheme;
import meteordevelopment.meteorclient.gui.WindowScreen;
import meteordevelopment.meteorclient.gui.screens.AccountsScreen;
import meteordevelopment.meteorclient.gui.widgets.WWidget;
import meteordevelopment.meteorclient.gui.widgets.containers.WContainer;
import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

import static meteordevelopment.meteorclient.MeteorClient.mc;

@Mixin(value = AccountsScreen.class, remap = false)
public abstract class AccountsScreenMixin extends WindowScreen {
public AccountsScreenMixin(GuiTheme theme, WWidget icon, String title) {
super(theme, icon, title);
}

@Shadow
protected abstract void addButton(WContainer c, String text, Runnable action);

@Inject(method = "initWidgets", at = @At(value = "INVOKE", target = "Lmeteordevelopment/meteorclient/gui/screens/AccountsScreen;addButton(Lmeteordevelopment/meteorclient/gui/widgets/containers/WContainer;Ljava/lang/String;Ljava/lang/Runnable;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
private void afterAddCrackedButton(CallbackInfo info, WHorizontalList l) {
addButton(l, "Yggdrasil", () -> mc.setScreen(new AddCustomYggdrasilAccountScreen(theme, (AccountsScreen) (Object) this)));
}
}
21 changes: 21 additions & 0 deletions src/main/java/anticope/rejects/mixin/meteor/WAccountMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package anticope.rejects.mixin.meteor;

import anticope.rejects.utils.accounts.CustomYggdrasilAccount;
import meteordevelopment.meteorclient.gui.widgets.WAccount;
import meteordevelopment.meteorclient.systems.accounts.Account;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;

@Mixin(value = WAccount.class, remap = false)
public class WAccountMixin {
@Shadow @Final private Account<?> account;

@ModifyArg(method = "init", at = @At(value = "INVOKE", target = "Lmeteordevelopment/meteorclient/gui/GuiTheme;label(Ljava/lang/String;)Lmeteordevelopment/meteorclient/gui/widgets/WLabel;",ordinal = 1))
private String accountName(String text) {
if (account instanceof CustomYggdrasilAccount) return "(Yggdrasil)";
return text;
}
}
45 changes: 45 additions & 0 deletions src/main/java/anticope/rejects/utils/accounts/AccountUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package anticope.rejects.utils.accounts;

import anticope.rejects.mixin.MinecraftClientAccessor;
import anticope.rejects.mixin.PlayerSkinProviderAccessor;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.minecraft.UserApiService;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.minecraft.client.network.SocialInteractionsManager;
import net.minecraft.client.report.AbuseReportContext;
import net.minecraft.client.report.ReporterEnvironment;
import net.minecraft.client.texture.PlayerSkinProvider;
import net.minecraft.client.util.ProfileKeys;
import net.minecraft.client.util.Session;
import net.minecraft.network.encryption.SignatureVerifier;

import java.io.File;

import static meteordevelopment.meteorclient.MeteorClient.mc;

public class AccountUtils {
public static MinecraftSessionService applyLoginEnvironment(YggdrasilAuthenticationService authService, MinecraftSessionService sessService, Session session) {
File skinDir = ((PlayerSkinProviderAccessor) mc.getSkinProvider()).getSkinCacheDir();
((MinecraftClientAccessor) mc).setSession(session);
((MinecraftClientAccessor) mc).setAuthenticationService(authService);
((MinecraftClientAccessor) mc).setSessionService(sessService);
((MinecraftClientAccessor) mc).setServicesSignatureVerifier(SignatureVerifier.create(authService.getServicesKey()));
((MinecraftClientAccessor) mc).setSkinProvider(new PlayerSkinProvider(mc.getTextureManager(), skinDir, sessService));
UserApiService apiService = createUserApiService(authService, session);
((MinecraftClientAccessor) mc).setUserApiService(apiService);
((MinecraftClientAccessor) mc).setSocialInteractionsManager(new SocialInteractionsManager(mc, apiService));
((MinecraftClientAccessor) mc).setProfileKeys(ProfileKeys.create(apiService, session, mc.runDirectory.toPath()));
((MinecraftClientAccessor) mc).setAbuseReportContext(AbuseReportContext.create(ReporterEnvironment.ofIntegratedServer(), apiService));
return sessService;
}

public static UserApiService createUserApiService(YggdrasilAuthenticationService authService, Session session) {
try {
return authService.createUserApiService(session.getAccessToken());
} catch (AuthenticationException e) {
return UserApiService.OFFLINE;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package anticope.rejects.utils.accounts;

import meteordevelopment.meteorclient.gui.GuiTheme;
import meteordevelopment.meteorclient.gui.screens.AccountsScreen;
import meteordevelopment.meteorclient.gui.screens.AddAccountScreen;
import meteordevelopment.meteorclient.gui.widgets.containers.WTable;
import meteordevelopment.meteorclient.gui.widgets.input.WTextBox;
import meteordevelopment.meteorclient.systems.accounts.Accounts;

public class AddCustomYggdrasilAccountScreen extends AddAccountScreen {
public AddCustomYggdrasilAccountScreen(GuiTheme theme, AccountsScreen parent) {
super(theme, "Add Yggdrasil Account", parent);
}

@Override
public void initWidgets() {
WTable t = add(theme.table()).widget();

// Email
t.add(theme.label("Username / Email: "));
WTextBox username = t.add(theme.textBox("")).minWidth(400).expandX().widget();
username.setFocused(true);
t.row();

// Password
t.add(theme.label("Password: "));
WTextBox password = t.add(theme.textBox("")).minWidth(400).expandX().widget();
t.row();

// Password
t.add(theme.label("Server: "));
WTextBox server = t.add(theme.textBox("")).minWidth(400).expandX().widget();
t.row();

// Add
add = t.add(theme.button("Add")).expandX().widget();
add.action = () -> {
CustomYggdrasilAccount account = new CustomYggdrasilAccount(username.get(), password.get(), server.get());
if (!username.get().isEmpty() && !password.get().isEmpty() && !Accounts.get().exists(account)) {
AccountsScreen.addAccount(this, parent, account);
}
};

enterAction = add.action;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package anticope.rejects.utils.accounts;

import com.mojang.authlib.exceptions.AuthenticationException;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.mixin.MinecraftClientAccessor;
import meteordevelopment.meteorclient.systems.accounts.Account;
import meteordevelopment.meteorclient.systems.accounts.AccountType;
import meteordevelopment.meteorclient.utils.misc.NbtException;
import net.minecraft.client.util.Session;
import net.minecraft.nbt.NbtCompound;

import static meteordevelopment.meteorclient.MeteorClient.mc;

public class CustomYggdrasilAccount extends Account<CustomYggdrasilAccount> {
private String password, server;

public CustomYggdrasilAccount(String name, String password, String server) {
super(AccountType.Cracked, name);
this.password = password;
this.server = server;
}

@Override
public boolean fetchInfo() {
try {
Session session = CustomYggdrasilLogin.login(name, password, server);

cache.username = session.getUsername();
cache.uuid = session.getUuid();

return true;
} catch (AuthenticationException e) {
return false;
}
}

@Override
public boolean login() {
try {
Session session = CustomYggdrasilLogin.login(name, password, server);
CustomYggdrasilLogin.LocalYggdrasilAuthenticationService service = new CustomYggdrasilLogin.LocalYggdrasilAuthenticationService(((MinecraftClientAccessor) mc).getProxy(), server);
CustomYggdrasilLogin.applyYggdrasilAccount(service, session);
cache.username = session.getUsername();
cache.loadHead();
return true;
} catch (AuthenticationException e) {
if (e.getMessage().contains("Invalid username or password") || e.getMessage().contains("account migrated"))
MeteorClient.LOG.error("Wrong password.");
else MeteorClient.LOG.error("Failed to contact the authentication server.");
return false;
}
}

@Override
public NbtCompound toTag() {
NbtCompound tag = super.toTag();

tag.putString("password", password);
tag.putString("server", server);

return tag;
}

@Override
public CustomYggdrasilAccount fromTag(NbtCompound tag) {
super.fromTag(tag);
if (!tag.contains("password")) throw new NbtException();

password = tag.getString("password");
server = tag.getString("server");

return this;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof CustomYggdrasilAccount)) return false;
return ((CustomYggdrasilAccount) o).name.equals(this.name);
}
}
Loading