Using launcher_accounts.json as new token source

This commit is contained in:
Moondarker 2021-03-13 22:44:42 +03:00
parent e56355a508
commit ae7fd65204

View file

@ -4,6 +4,8 @@ const fs = require('fs').promises
const mcDefaultFolderPath = require('minecraft-folder-path') const mcDefaultFolderPath = require('minecraft-folder-path')
const path = require('path') const path = require('path')
const launcherDataFile = 'launcher_accounts.json'
module.exports = async function (client, options) { module.exports = async function (client, options) {
if (!options.profilesFolder && options.profilesFolder !== false) { // not defined, but not explicitly false. fallback to default if (!options.profilesFolder && options.profilesFolder !== false) { // not defined, but not explicitly false. fallback to default
let mcFolderExists = true let mcFolderExists = true
@ -16,29 +18,27 @@ module.exports = async function (client, options) {
} }
const yggdrasilClient = yggdrasil({ agent: options.agent, host: options.authServer || 'https://authserver.mojang.com' }) const yggdrasilClient = yggdrasil({ agent: options.agent, host: options.authServer || 'https://authserver.mojang.com' })
const clientToken = options.clientToken || (options.session && options.session.clientToken) || (options.profilesFolder && (await getLauncherProfiles()).clientToken) || UUID.v4().toString().replace(/-/g, '') const clientToken = options.clientToken || (options.session && options.session.clientToken) || (options.profilesFolder && (await getLauncherProfiles()).mojangClientToken) || UUID.v4().toString().replace(/-/g, '')
const skipValidation = false || options.skipValidation const skipValidation = false || options.skipValidation
options.accessToken = null options.accessToken = null
options.haveCredentials = !!options.password || (clientToken != null && options.session != null) || (options.profilesFolder && await hasProfileCredentials()) options.haveCredentials = !!options.password || (clientToken != null && options.session != null) || (options.profilesFolder && !!getProfileId(await getLauncherProfiles()))
async function getLauncherProfiles () { // get launcher profiles async function getLauncherProfiles () { // get launcher profiles
try { try {
return JSON.parse(await fs.readFile(path.join(options.profilesFolder, 'launcher_profiles.json'), 'utf8')) return JSON.parse(await fs.readFile(path.join(options.profilesFolder, launcherDataFile), 'utf8'))
} catch (err) { } catch (err) {
await fs.mkdir(options.profilesFolder, { recursive: true }) await fs.mkdir(options.profilesFolder, { recursive: true })
await fs.writeFile(path.join(options.profilesFolder, 'launcher_profiles.json'), '{}') await fs.writeFile(path.join(options.profilesFolder, launcherDataFile), '{}')
return { authenticationDatabase: {} } return { accounts: {} }
} }
} }
async function hasProfileCredentials () { function getProfileId (auths) {
try { try {
const auths = await getLauncherProfiles()
const lowerUsername = options.username.toLowerCase() const lowerUsername = options.username.toLowerCase()
return !!Object.keys(auths.authenticationDatabase).find(key => return Object.keys(auths.accounts).find(key =>
auths.authenticationDatabase[key].username.toLowerCase() === lowerUsername || auths.accounts[key].username.toLowerCase() === lowerUsername ||
Object.values(auths.authenticationDatabase[key].profiles)[0].displayName.toLowerCase() === lowerUsername auths.accounts[key].minecraftProfile.name.toLowerCase() === lowerUsername
) )
} catch (err) { } catch (err) {
return false return false
@ -50,43 +50,39 @@ module.exports = async function (client, options) {
const cb = function (err, session) { const cb = function (err, session) {
if (options.profilesFolder) { if (options.profilesFolder) {
getLauncherProfiles().then((auths) => { getLauncherProfiles().then((auths) => {
if (!auths.authenticationDatabase) auths.authenticationDatabase = [] if (!auths.accounts) auths.accounts = []
try { try {
const lowerUsername = options.username.toLowerCase() const lowerUsername = options.username.toLowerCase()
let profile = Object.keys(auths.authenticationDatabase).find(key => let profile = getProfileId(auths)
auths.authenticationDatabase[key].username.toLowerCase() === lowerUsername ||
Object.values(auths.authenticationDatabase[key].profiles)[0].displayName.toLowerCase() === lowerUsername
)
if (err) { if (err) {
if (profile) { // profile is invalid, remove if (profile) { // profile is invalid, remove
delete auths.authenticationDatabase[profile] delete auths.accounts[profile]
} }
} else { // successful login } else { // successful login
if (!profile) { if (!profile) {
profile = UUID.v4().toString().replace(/-/g, '') // create new profile profile = UUID.v4().toString().replace(/-/g, '') // create new profile
} }
if (!auths.clientToken) { if (!auths.mojangClientToken) {
auths.clientToken = clientToken auths.mojangClientToken = clientToken
} }
if (clientToken === auths.clientToken) { // only do something when we can save a new clienttoken or they match if (clientToken === auths.mojangClientToken) { // only do something when we can save a new clienttoken or they match
const oldProfileObj = auths.authenticationDatabase[profile] const oldProfileObj = auths.accounts[profile]
const newProfileObj = { const newProfileObj = {
accessToken: session.accessToken, accessToken: session.accessToken,
profiles: {}, minecraftProfile: {
properties: oldProfileObj ? (oldProfileObj.properties || []) : [], name: session.selectedProfile.name
},
userProperites: oldProfileObj ? (userProperites.properties || []) : [],
username: options.username username: options.username
} }
newProfileObj.profiles[session.selectedProfile.id] = { auths.accounts[profile] = newProfileObj
displayName: session.selectedProfile.name
}
auths.authenticationDatabase[profile] = newProfileObj
} }
} }
} catch (ignoreErr) { } catch (ignoreErr) {
// again, silently fail, just don't save anything // again, silently fail, just don't save anything
} }
fs.writeFile(path.join(options.profilesFolder, 'launcher_profiles.json'), JSON.stringify(auths, null, 2)).then(() => {}, (ignoreErr) => { fs.writeFile(path.join(options.profilesFolder, launcherDataFile), JSON.stringify(auths, null, 2)).then(() => {}, (ignoreErr) => {
// console.warn("Couldn't save tokens:\n", err) // not any error, we just don't save the file // console.warn("Couldn't save tokens:\n", err) // not any error, we just don't save the file
}) })
}, (ignoreErr) => { }, (ignoreErr) => {
@ -108,25 +104,20 @@ module.exports = async function (client, options) {
if (!options.session && options.profilesFolder) { if (!options.session && options.profilesFolder) {
try { try {
const auths = await getLauncherProfiles() const auths = await getLauncherProfiles()
const profile = getProfileId(auths)
const lowerUsername = options.username.toLowerCase()
const profile = Object.keys(auths.authenticationDatabase).find(key =>
auths.authenticationDatabase[key].username.toLowerCase() === lowerUsername ||
Object.values(auths.authenticationDatabase[key].profiles)[0].displayName.toLowerCase() === lowerUsername
)
if (profile) { if (profile) {
const newUsername = auths.authenticationDatabase[profile].username const newUsername = auths.accounts[profile].username
const uuid = Object.keys(auths.authenticationDatabase[profile].profiles)[0] const displayName = auths.accounts[profile].minecraftProfile.name
const displayName = auths.authenticationDatabase[profile].profiles[uuid].displayName const uuid = auths.accounts[profile].minecraftProfile.id
const newProfile = { const newProfile = {
name: displayName, id: uuid,
id: uuid name: displayName
} }
options.session = { options.session = {
accessToken: auths.authenticationDatabase[profile].accessToken, accessToken: auths.accounts[profile].accessToken,
clientToken: auths.clientToken, clientToken: auths.mojangClientToken,
selectedProfile: newProfile, selectedProfile: newProfile,
availableProfiles: [newProfile] availableProfiles: [newProfile]
} }