Refactor account login handling into the AccountsSubsystem
Now we have a cool way of doing the startup login instead of dealing with funky environment variablesmain
parent
81ef894926
commit
ca66d553bd
|
@ -13,6 +13,8 @@ import codes.som.hibiscus.features.player.NoFallDamage
|
||||||
import codes.som.hibiscus.features.player.NoSprintingPacket
|
import codes.som.hibiscus.features.player.NoSprintingPacket
|
||||||
import codes.som.hibiscus.gui.screens.AccountManagerUIScreen
|
import codes.som.hibiscus.gui.screens.AccountManagerUIScreen
|
||||||
import codes.som.hibiscus.gui.screens.InGameClientUIScreen
|
import codes.som.hibiscus.gui.screens.InGameClientUIScreen
|
||||||
|
import codes.som.hibiscus.mixins.MixinExtMinecraftClient
|
||||||
|
import codes.som.hibiscus.subsystems.accounts.AccountsSubsystem
|
||||||
import codes.som.hibiscus.util.command.ChatCommandListener
|
import codes.som.hibiscus.util.command.ChatCommandListener
|
||||||
import codes.som.hibiscus.util.input.KeybindDispatcher
|
import codes.som.hibiscus.util.input.KeybindDispatcher
|
||||||
import codes.som.hibiscus.util.netmoving.NetworkMovingDispatcher
|
import codes.som.hibiscus.util.netmoving.NetworkMovingDispatcher
|
||||||
|
@ -56,6 +58,18 @@ object Hibiscus : ModInitializer {
|
||||||
bus.register(KeybindDispatcher())
|
bus.register(KeybindDispatcher())
|
||||||
|
|
||||||
defaultConfig()
|
defaultConfig()
|
||||||
|
|
||||||
|
AccountsSubsystem.reload()
|
||||||
|
if (mc.session.accessToken == "FabricMC") { // Launched from IDE
|
||||||
|
try {
|
||||||
|
AccountsSubsystem.getAccounts().firstOrNull()?.let { account ->
|
||||||
|
AccountsSubsystem.signIn(account)
|
||||||
|
?.let(AccountsSubsystem::createSession)
|
||||||
|
?.let((mc as MixinExtMinecraftClient)::setSession)
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shutdown() {
|
fun shutdown() {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package codes.som.hibiscus.gui.screens
|
package codes.som.hibiscus.gui.screens
|
||||||
|
|
||||||
import codes.som.hibiscus.Hibiscus
|
import codes.som.hibiscus.mc
|
||||||
import codes.som.hibiscus.data.MinecraftAccount
|
|
||||||
import codes.som.hibiscus.mixins.MixinExtMinecraftClient
|
import codes.som.hibiscus.mixins.MixinExtMinecraftClient
|
||||||
|
import codes.som.hibiscus.subsystems.accounts.AccountsSubsystem
|
||||||
import imgui.ImGui
|
import imgui.ImGui
|
||||||
import imgui.flag.ImGuiInputTextFlags
|
import imgui.flag.ImGuiInputTextFlags
|
||||||
import imgui.flag.ImGuiWindowFlags
|
import imgui.flag.ImGuiWindowFlags
|
||||||
|
@ -10,30 +10,14 @@ import imgui.type.ImBoolean
|
||||||
import imgui.type.ImInt
|
import imgui.type.ImInt
|
||||||
import imgui.type.ImString
|
import imgui.type.ImString
|
||||||
import net.hycrafthd.minecraft_authenticator.login.Authenticator
|
import net.hycrafthd.minecraft_authenticator.login.Authenticator
|
||||||
import net.hycrafthd.minecraft_authenticator.login.User
|
|
||||||
import net.hycrafthd.minecraft_authenticator.login.file.AuthenticationFile
|
|
||||||
import net.minecraft.client.gui.screen.Screen
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.client.util.Session
|
|
||||||
import net.minecraft.client.util.math.MatrixStack
|
import net.minecraft.client.util.math.MatrixStack
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")) {
|
object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")) {
|
||||||
private var accounts = emptyList<MinecraftAccount>()
|
|
||||||
private val createAccountPanelOpen = ImBoolean(false)
|
private val createAccountPanelOpen = ImBoolean(false)
|
||||||
private var selectedAccountId = -1
|
private var selectedAccountId = -1
|
||||||
|
|
||||||
init {
|
|
||||||
refreshAccounts()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun refreshAccounts() {
|
|
||||||
this.accounts = Hibiscus.data.txn {
|
|
||||||
MinecraftAccount.all().toList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
|
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
|
||||||
renderBackground(matrices)
|
renderBackground(matrices)
|
||||||
|
|
||||||
|
@ -42,13 +26,16 @@ object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawAccountsPanel() {
|
private fun drawAccountsPanel() {
|
||||||
|
val accounts = AccountsSubsystem.getAccounts().toList()
|
||||||
|
|
||||||
if (ImGui.begin("Accounts", ImGuiWindowFlags.AlwaysAutoResize)) {
|
if (ImGui.begin("Accounts", ImGuiWindowFlags.AlwaysAutoResize)) {
|
||||||
ImGui.text("Available accounts: ${accounts.size}")
|
ImGui.text("Available accounts: ${accounts.size}")
|
||||||
ImGui.text("Logged in as: ${client!!.session.username}")
|
ImGui.text("Logged in as: ${mc.session.username}")
|
||||||
|
|
||||||
if (ImGui.button("Add Account")) {
|
if (ImGui.button("Add Account")) {
|
||||||
createAccountPanelOpen.set(true)
|
createAccountPanelOpen.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.sameLine()
|
ImGui.sameLine()
|
||||||
if (ImGui.button("Random")) {
|
if (ImGui.button("Random")) {
|
||||||
selectedAccountId = accounts
|
selectedAccountId = accounts
|
||||||
|
@ -70,11 +57,18 @@ object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")
|
||||||
|
|
||||||
accounts.firstOrNull { it.id.value == selectedAccountId }?.let { account ->
|
accounts.firstOrNull { it.id.value == selectedAccountId }?.let { account ->
|
||||||
if (ImGui.button("Log In")) {
|
if (ImGui.button("Log In")) {
|
||||||
signInToAccount(account)
|
try {
|
||||||
|
val user = AccountsSubsystem.signIn(account)
|
||||||
|
if (user != null) {
|
||||||
|
(mc as MixinExtMinecraftClient).setSession(AccountsSubsystem.createSession(user))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui.sameLine()
|
ImGui.sameLine()
|
||||||
if (ImGui.button("Remove")) {
|
if (ImGui.button("Remove")) {
|
||||||
removeAccount(account)
|
AccountsSubsystem.deleteAccount(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.text("Selected account: ${account.name}")
|
ImGui.text("Selected account: ${account.name}")
|
||||||
|
@ -86,36 +80,6 @@ object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")
|
||||||
ImGui.end()
|
ImGui.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun signInToAccount(account: MinecraftAccount) {
|
|
||||||
try {
|
|
||||||
val loginFile = AuthenticationFile.read(account.loginData.byteInputStream(Charsets.UTF_8))
|
|
||||||
val loginResult = Authenticator.of(loginFile).shouldAuthenticate().run()
|
|
||||||
if (loginResult.user.isPresent) {
|
|
||||||
val user = loginResult.user.get()
|
|
||||||
(client!! as MixinExtMinecraftClient).setSession(user.createSession())
|
|
||||||
|
|
||||||
val loginData = ByteArrayOutputStream()
|
|
||||||
.apply { loginResult.resultFile.write(this) }
|
|
||||||
.toString(Charsets.UTF_8)
|
|
||||||
|
|
||||||
Hibiscus.data.txn {
|
|
||||||
account.lastKnownDisplayName = user.name
|
|
||||||
account.loginData = loginData
|
|
||||||
refreshAccounts()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removeAccount(account: MinecraftAccount) {
|
|
||||||
Hibiscus.data.txn {
|
|
||||||
account.delete()
|
|
||||||
refreshAccounts()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val loginType = ImInt(1)
|
private val loginType = ImInt(1)
|
||||||
private val yggdrasilUsername = ImString(320)
|
private val yggdrasilUsername = ImString(320)
|
||||||
private val yggdrasilPassword = ImString(256)
|
private val yggdrasilPassword = ImString(256)
|
||||||
|
@ -161,35 +125,13 @@ object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")
|
||||||
0 -> Authenticator.ofYggdrasil("-", yggdrasilUsername.get(), yggdrasilPassword.get())
|
0 -> Authenticator.ofYggdrasil("-", yggdrasilUsername.get(), yggdrasilPassword.get())
|
||||||
1 -> Authenticator.ofMicrosoft(microsoftToken.get())
|
1 -> Authenticator.ofMicrosoft(microsoftToken.get())
|
||||||
else -> throw IllegalStateException()
|
else -> throw IllegalStateException()
|
||||||
}.shouldAuthenticate()
|
}
|
||||||
|
|
||||||
try {
|
if (AccountsSubsystem.addAccount(authenticator)) {
|
||||||
val loginResult = authenticator.run()
|
sequenceOf(yggdrasilUsername, yggdrasilPassword, microsoftToken).forEach {
|
||||||
if (loginResult.user.isPresent) {
|
it.set("")
|
||||||
val user = loginResult.user.get()
|
|
||||||
|
|
||||||
yggdrasilUsername.set("")
|
|
||||||
yggdrasilPassword.set("")
|
|
||||||
microsoftToken.set("")
|
|
||||||
|
|
||||||
val loginData = ByteArrayOutputStream()
|
|
||||||
.apply { loginResult.resultFile.write(this) }
|
|
||||||
.toString(Charsets.UTF_8)
|
|
||||||
|
|
||||||
Hibiscus.data.txn {
|
|
||||||
MinecraftAccount.new {
|
|
||||||
this.name = user.name
|
|
||||||
this.lastKnownDisplayName = user.name
|
|
||||||
this.loginData = loginData
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshAccounts()
|
|
||||||
|
|
||||||
(client!! as MixinExtMinecraftClient).setSession(user.createSession())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} else {
|
||||||
e.printStackTrace()
|
|
||||||
// TODO: Display some error
|
// TODO: Display some error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,13 +139,4 @@ object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")
|
||||||
ImGui.end()
|
ImGui.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun User.createSession() = Session(
|
|
||||||
name,
|
|
||||||
uuid,
|
|
||||||
accessToken,
|
|
||||||
Optional.empty(),
|
|
||||||
Optional.empty(),
|
|
||||||
Session.AccountType.byName(type)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package codes.som.hibiscus.subsystems.accounts
|
||||||
|
|
||||||
|
import codes.som.hibiscus.Hibiscus
|
||||||
|
import codes.som.hibiscus.data.MinecraftAccount
|
||||||
|
import codes.som.hibiscus.mc
|
||||||
|
import codes.som.hibiscus.mixins.MixinExtMinecraftClient
|
||||||
|
import net.hycrafthd.minecraft_authenticator.login.Authenticator
|
||||||
|
import net.hycrafthd.minecraft_authenticator.login.User
|
||||||
|
import net.hycrafthd.minecraft_authenticator.login.file.AuthenticationFile
|
||||||
|
import net.minecraft.client.util.Session
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object AccountsSubsystem {
|
||||||
|
private var accounts = emptyList<MinecraftAccount>()
|
||||||
|
|
||||||
|
fun getAccounts(): Sequence<MinecraftAccount> = accounts.asSequence()
|
||||||
|
|
||||||
|
fun addAccount(authenticator: Authenticator.Builder): Boolean {
|
||||||
|
try {
|
||||||
|
val loginResult = authenticator.shouldAuthenticate().run()
|
||||||
|
if (loginResult.user.isPresent) {
|
||||||
|
val user = loginResult.user.get()
|
||||||
|
|
||||||
|
val loginData = ByteArrayOutputStream()
|
||||||
|
.apply { loginResult.resultFile.write(this) }
|
||||||
|
.toString(Charsets.UTF_8)
|
||||||
|
|
||||||
|
Hibiscus.data.txn {
|
||||||
|
val account = MinecraftAccount.new {
|
||||||
|
this.name = user.name
|
||||||
|
this.lastKnownDisplayName = user.name
|
||||||
|
this.loginData = loginData
|
||||||
|
}
|
||||||
|
accounts = accounts + account
|
||||||
|
|
||||||
|
(mc as MixinExtMinecraftClient).setSession(createSession(user))
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteAccount(account: MinecraftAccount) {
|
||||||
|
val id = account.id.value
|
||||||
|
accounts = accounts.filter { it.id.value == id }
|
||||||
|
account.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reload() {
|
||||||
|
this.accounts = Hibiscus.data.txn {
|
||||||
|
MinecraftAccount.all().toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun signIn(account: MinecraftAccount): User? {
|
||||||
|
try {
|
||||||
|
val loginFile = AuthenticationFile.read(account.loginData.byteInputStream(Charsets.UTF_8))
|
||||||
|
val loginResult = Authenticator.of(loginFile).shouldAuthenticate().run()
|
||||||
|
if (loginResult.user.isPresent) {
|
||||||
|
val user = loginResult.user.get()
|
||||||
|
|
||||||
|
val loginData = ByteArrayOutputStream()
|
||||||
|
.apply { loginResult.resultFile.write(this) }
|
||||||
|
.toString(Charsets.UTF_8)
|
||||||
|
|
||||||
|
Hibiscus.data.txn {
|
||||||
|
account.lastKnownDisplayName = user.name
|
||||||
|
account.loginData = loginData
|
||||||
|
}
|
||||||
|
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createSession(user: User) = with(user) {
|
||||||
|
Session(
|
||||||
|
name,
|
||||||
|
uuid,
|
||||||
|
accessToken,
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Session.AccountType.byName(type)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue