UNPKG

iron-golem

Version:

A robust Minecraft bot built upon mineflayer

151 lines (129 loc) 3.78 kB
const fs = require('fs'); const mojang = require('mojang'); async function mojangCall(call, ...args) { let res; try { res = await mojang[call](...args); } catch (e) { throw e; } if (res.errorMessage) { throw new Error(res.errorMessage); } if (res.error) { throw new Error(res.error); } return res; } async function create(username, password) { try { const {accessToken, clientToken, selectedProfile} = await mojangCall('auth', username, password, null, {name: 'Minecraft', version: 1}); return {accessToken, clientToken, selectedProfile}; } catch (e) { throw e; } } async function validate(session) { try { await mojangCall('validate', session.accessToken, session.clientToken); // It worked, so yay return true; } catch (e) { // Return true if empty response (which is what mojang sends on success), // false if anything else. return (e.message || e || '').toLowerCase().includes('no data received'); } } async function refresh(session) { return mojangCall('refresh', session.accessToken, session.clientToken, session.selectedProfile); } /** * Save a session to a file. * @param {object} session - The session to save. * @param {string} name - A name to append to the file name. * @returns {Promise} */ async function save(session, name) { return new Promise((resolve, reject) => { fs.writeFile(`./session${name ? `-${name.toLowerCase()}` : ''}.json`, JSON.stringify(session), function (err) { if (err) { reject(err); return; } resolve(); }); }); } /** * Attempt to load the sessions file. * @param {string} name - A name to append to the file. * @returns {Promise} */ async function load(name) { return new Promise((resolve, reject) => { fs.readFile(`./session${name ? `-${name.toLowerCase()}` : ''}.json`, 'utf8', function (err, data) { if (err) { reject(err); return; } let session; try { session = JSON.parse(data); } catch (e) { reject(e); return; } resolve(session); }); }); } /** * Attempt to get a session from local file storage. * <p> * If the session exists in local storage, it will * be validated, and refreshed as needed. * <p> * If the file does not exist, or refresh fails, * an error is thrown. * @param {string} name - The name used to save the file. * @returns {Promise.<*>} */ async function getSessionFromSaved(name) { let session; try { session = await load(name); } catch (loadErr) { throw loadErr; } const isValid = await validate(session); if (!isValid) { try { session = await refresh(session); } catch (refreshErr) { throw refreshErr; } } // Returns a saved and validated session, // or a refreshed session. return session; } async function getValidSession(username, password, name) { let session; try { session = await getSessionFromSaved(name); } catch (retrieveErr) { // If it can't be retrieved, make a new one try { session = await create(username, password); } catch (e) { throw e; } } try { await save(session, name); } catch (e) { throw e; } return session; } module.exports = getValidSession;