From 381a61f932a93f207f5e5918ef7e85b0f4e20f32 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sun, 19 Mar 2023 21:22:59 +0100 Subject: [PATCH] commands: add offline, login to microsoft account, Closes #83 --- .../selector/AccountTargetProperties.kt | 1 + .../account/selector/StateProperty.kt | 46 +++++++++++++++++++ .../minosoft/data/accounts/AccountStates.kt | 8 ++++ .../terminal/commands/AccountManageCommand.kt | 33 +++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/StateProperty.kt diff --git a/src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/AccountTargetProperties.kt b/src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/AccountTargetProperties.kt index 8aaac165e..a149e3888 100644 --- a/src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/AccountTargetProperties.kt +++ b/src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/AccountTargetProperties.kt @@ -20,5 +20,6 @@ object AccountTargetProperties : TargetProperties() { init { register(TypeProperty) + register(StateProperty) } } diff --git a/src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/StateProperty.kt b/src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/StateProperty.kt new file mode 100644 index 000000000..8ca3921f7 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/commands/parser/minosoft/account/selector/StateProperty.kt @@ -0,0 +1,46 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.commands.parser.minosoft.account.selector + +import de.bixilon.minosoft.commands.errors.ExpectedArgumentError +import de.bixilon.minosoft.commands.parser.minosoft.enums.EnumParser +import de.bixilon.minosoft.commands.parser.selector.TargetProperty +import de.bixilon.minosoft.commands.parser.selector.TargetPropertyFactory +import de.bixilon.minosoft.commands.util.CommandReader +import de.bixilon.minosoft.data.accounts.Account +import de.bixilon.minosoft.data.accounts.AccountStates + +class StateProperty( + val state: AccountStates, + val negated: Boolean, +) : TargetProperty { + + override fun passes(value: Account): Boolean { + val state = value.state + if (negated) { + return state != this.state + } + return state == this.state + } + + companion object : TargetPropertyFactory { + private val parser = EnumParser(AccountStates) + override val name: String = "state" + + override fun read(reader: CommandReader): StateProperty { + val (word, negated) = reader.readNegateable { parser.parse(reader) } ?: throw ExpectedArgumentError(reader) + return StateProperty(word, negated) + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/AccountStates.kt b/src/main/java/de/bixilon/minosoft/data/accounts/AccountStates.kt index 5f4ba9373..c4ee26e82 100644 --- a/src/main/java/de/bixilon/minosoft/data/accounts/AccountStates.kt +++ b/src/main/java/de/bixilon/minosoft/data/accounts/AccountStates.kt @@ -13,6 +13,8 @@ package de.bixilon.minosoft.data.accounts +import de.bixilon.kutil.enums.EnumUtil +import de.bixilon.kutil.enums.ValuesEnum import de.bixilon.minosoft.data.language.translate.Translatable import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.util.KUtil.toResourceLocation @@ -55,4 +57,10 @@ enum class AccountStates : Translatable { ; override val translationKey: ResourceLocation = "minosoft:main.account.state.${name.lowercase()}".toResourceLocation() + + + companion object : ValuesEnum { + override val VALUES: Array = values() + override val NAME_MAP: Map = EnumUtil.getEnumValues(VALUES) + } } diff --git a/src/main/java/de/bixilon/minosoft/terminal/commands/AccountManageCommand.kt b/src/main/java/de/bixilon/minosoft/terminal/commands/AccountManageCommand.kt index 489e533aa..dd58efcb7 100644 --- a/src/main/java/de/bixilon/minosoft/terminal/commands/AccountManageCommand.kt +++ b/src/main/java/de/bixilon/minosoft/terminal/commands/AccountManageCommand.kt @@ -13,15 +13,20 @@ package de.bixilon.minosoft.terminal.commands +import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.minosoft.commands.nodes.ArgumentNode import de.bixilon.minosoft.commands.nodes.CommandNode import de.bixilon.minosoft.commands.nodes.LiteralNode +import de.bixilon.minosoft.commands.parser.brigadier.string.StringParser import de.bixilon.minosoft.commands.parser.minosoft.account.AccountParser import de.bixilon.minosoft.commands.parser.selector.AbstractTarget import de.bixilon.minosoft.commands.stack.CommandStack import de.bixilon.minosoft.config.profile.profiles.account.AccountProfileManager import de.bixilon.minosoft.data.accounts.Account +import de.bixilon.minosoft.data.accounts.types.offline.OfflineAccount +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.KUtil.table +import de.bixilon.minosoft.util.account.microsoft.MicrosoftOAuthUtils object AccountManageCommand : Command { override var node = LiteralNode("account") @@ -47,6 +52,34 @@ object AccountManageCommand : Command { stack.print.print("Selected $account") } }, + LiteralNode("add").addChild( + LiteralNode("offline").addChild(ArgumentNode("username", StringParser(), executor = { stack -> + val name = stack.get("username")!! + if (!ProtocolDefinition.MINECRAFT_NAME_VALIDATOR.matcher(name).matches()) throw CommandException("Invalid username: $name") + val profile = AccountProfileManager.selected + if (profile.entries.containsKey(name)) throw CommandException("Account does already exist!") + val account = OfflineAccount(name) + profile.entries[account.id] = account + profile.selected = account + stack.print.print("Successfully created and selected offline account ${account.username}!") + })), + LiteralNode("microsoft", executor = { stack -> + stack.print.print("Obtaining device code...") + DefaultThreadPool += { + MicrosoftOAuthUtils.obtainDeviceCodeAsync({ + stack.print.print("§fPlease open §e${it.verificationURI}§f and enter the following code §e${it.userCode}§f and login into your microsoft account.") + }, { it.printStackTrace() }, { + stack.print.print("Logging in into microsoft account...") + val account = MicrosoftOAuthUtils.loginToMicrosoftAccount(it) + val profile = AccountProfileManager.selected + profile.entries[account.id] = account + profile.selected = account + + stack.print.print("Successfully logged in and selected microsoft account ${account.username}!") + }) + } + }), + ), )