Clean up structure of Mojang API/Util files.

This commit is contained in:
Daniel Scalzi 2020-08-27 21:27:56 -04:00
parent 571b788e25
commit c7b95f3719
No known key found for this signature in database
GPG Key ID: D18EA3FB4B142A57
11 changed files with 270 additions and 261 deletions

View File

@ -1,6 +0,0 @@
export interface Agent {
name: 'Minecraft'
version: number
}

View File

@ -1,11 +0,0 @@
import { Agent } from './Agent'
export interface AuthPayload {
agent: Agent
username: string
password: string
clientToken?: string
requestUser?: boolean
}

View File

@ -0,0 +1,157 @@
/**
* Utility Class to construct a packet conforming to Minecraft's
* protocol. All data types are BE except VarInt and VarLong.
*
* @see https://wiki.vg/Protocol
*/
export class ServerBoundPacket {
private buffer: number[]
protected constructor() {
this.buffer = []
}
public static build(): ServerBoundPacket {
return new ServerBoundPacket()
}
/**
* Packet is prefixed with its data length as a VarInt.
*
* @see https://wiki.vg/Protocol#Packet_format
*/
public toBuffer(): Buffer {
const finalizedPacket = new ServerBoundPacket()
finalizedPacket.writeVarInt(this.buffer.length)
finalizedPacket.writeBytes(...this.buffer)
return Buffer.from(finalizedPacket.buffer)
}
public writeBytes(...bytes: number[]): ServerBoundPacket {
this.buffer.push(...bytes)
return this
}
/**
* @see https://wiki.vg/Protocol#VarInt_and_VarLong
*/
public writeVarInt(value: number): ServerBoundPacket {
do {
let temp = value & 0b01111111
value >>>= 7
if (value != 0) {
temp |= 0b10000000
}
this.writeBytes(temp)
} while (value != 0)
return this
}
/**
* Strings are prefixed with their length as a VarInt.
*
* @see https://wiki.vg/Protocol#Data_types
*/
public writeString(string: string): ServerBoundPacket {
this.writeVarInt(string.length)
for (let i=0; i<string.length; i++) {
this.writeBytes(string.codePointAt(i)!)
}
return this
}
public writeUnsignedShort(short: number): ServerBoundPacket {
const buf = Buffer.alloc(2)
buf.writeUInt16BE(short, 0)
this.writeBytes(...buf)
return this
}
}
/**
* Utility Class to read a client-bound packet conforming to
* Minecraft's protocol. All data types are BE except VarInt
* and VarLong.
*
* @see https://wiki.vg/Protocol
*/
export class ClientBoundPacket {
private buffer: number[]
constructor(buffer: Buffer) {
this.buffer = [...buffer]
}
public append(buffer: Buffer): void {
this.buffer.push(...buffer)
}
public readByte(): number {
return this.buffer.shift()!
}
public readBytes(length: number): number[] {
const value = this.buffer.slice(0, length)
this.buffer.splice(0, length)
return value
}
public readVarInt(): number {
let numRead = 0
let result = 0
let read
do {
read = this.readByte()
const value = (read & 0b01111111)
result |= (value << (7 * numRead))
numRead++
if (numRead > 5) {
throw new Error('VarInt is too big')
}
} while ((read & 0b10000000) != 0)
return result
}
public readString(): string {
const length = this.readVarInt()
const data = this.readBytes(length)
let value = ''
for (let i=0; i<data.length; i++) {
value += String.fromCharCode(data[i])
}
return value
}
}
export class ProtocolUtils {
public static getVarIntSize(value: number): number {
let size = 0
do {
value >>>= 7
size++
} while (value != 0)
return size
}
}

View File

@ -1,6 +1,7 @@
/* eslint-disable no-control-regex */ /* eslint-disable no-control-regex */
import { connect } from 'net' import { connect } from 'net'
import { LoggerUtil } from 'common/logging/loggerutil' import { LoggerUtil } from 'common/logging/loggerutil'
import { ServerBoundPacket, ClientBoundPacket, ProtocolUtils } from './Protocol'
const logger = LoggerUtil.getLogger('ServerStatusUtil') const logger = LoggerUtil.getLogger('ServerStatusUtil')
@ -30,161 +31,6 @@ export interface ServerStatus {
} }
} }
/**
* Utility Class to construct a packet conforming to Minecraft's
* protocol. All data types are BE except VarInt and VarLong.
*
* @see https://wiki.vg/Protocol
*/
class ServerBoundPacket {
private buffer: number[]
protected constructor() {
this.buffer = []
}
public static build(): ServerBoundPacket {
return new ServerBoundPacket()
}
/**
* Packet is prefixed with its data length as a VarInt.
*
* @see https://wiki.vg/Protocol#Packet_format
*/
public toBuffer(): Buffer {
const finalizedPacket = new ServerBoundPacket()
finalizedPacket.writeVarInt(this.buffer.length)
finalizedPacket.writeBytes(...this.buffer)
return Buffer.from(finalizedPacket.buffer)
}
public writeBytes(...bytes: number[]): ServerBoundPacket {
this.buffer.push(...bytes)
return this
}
/**
* @see https://wiki.vg/Protocol#VarInt_and_VarLong
*/
public writeVarInt(value: number): ServerBoundPacket {
do {
let temp = value & 0b01111111
value >>>= 7
if (value != 0) {
temp |= 0b10000000
}
this.writeBytes(temp)
} while (value != 0)
return this
}
/**
* Strings are prefixed with their length as a VarInt.
*
* @see https://wiki.vg/Protocol#Data_types
*/
public writeString(string: string): ServerBoundPacket {
this.writeVarInt(string.length)
for (let i=0; i<string.length; i++) {
this.writeBytes(string.codePointAt(i)!)
}
return this
}
public writeUnsignedShort(short: number): ServerBoundPacket {
const buf = Buffer.alloc(2)
buf.writeUInt16BE(short, 0)
this.writeBytes(...buf)
return this
}
}
/**
* Utility Class to read a client-bound packet conforming to
* Minecraft's protocol. All data types are BE except VarInt
* and VarLong.
*
* @see https://wiki.vg/Protocol
*/
class ClientBoundPacket {
private buffer: number[]
constructor(buffer: Buffer) {
this.buffer = [...buffer]
}
public append(buffer: Buffer): void {
this.buffer.push(...buffer)
}
public readByte(): number {
return this.buffer.shift()!
}
public readBytes(length: number): number[] {
const value = this.buffer.slice(0, length)
this.buffer.splice(0, length)
return value
}
public readVarInt(): number {
let numRead = 0
let result = 0
let read
do {
read = this.readByte()
const value = (read & 0b01111111)
result |= (value << (7 * numRead))
numRead++
if (numRead > 5) {
throw new Error('VarInt is too big')
}
} while ((read & 0b10000000) != 0)
return result
}
public readString(): string {
const length = this.readVarInt()
const data = this.readBytes(length)
let value = ''
for (let i=0; i<data.length; i++) {
value += String.fromCharCode(data[i])
}
return value
}
}
export function getVarIntSize(value: number): number {
let size = 0
do {
value >>>= 7
size++
} while (value != 0)
return size
}
/** /**
* Get the handshake packet. * Get the handshake packet.
* *
@ -217,7 +63,15 @@ function getRequestPacket(): Buffer {
.toBuffer() .toBuffer()
} }
/**
* Some servers do not return the same status object. Unify
* the response so that the caller need only worry about
* handling a single format.
*
* @param resp The servevr status response.
*/
function unifyStatusResponse(resp: ServerStatus): ServerStatus { function unifyStatusResponse(resp: ServerStatus): ServerStatus {
// Some servers don't wrap their description in a text object.
if(typeof resp.description === 'string') { if(typeof resp.description === 'string') {
resp.description = { resp.description = {
text: resp.description text: resp.description
@ -261,7 +115,7 @@ export function getServerStatus(protocol: number, address: string, port = 25565)
} }
// Size of packetLength VarInt is not included in the packetLength. // Size of packetLength VarInt is not included in the packetLength.
bytesLeft = packetLength + getVarIntSize(packetLength) bytesLeft = packetLength + ProtocolUtils.getVarIntSize(packetLength)
// Listener to keep reading until we have read all the bytes into the buffer. // Listener to keep reading until we have read all the bytes into the buffer.
const packetReadListener = (nextData: Buffer, doAppend: boolean) => { const packetReadListener = (nextData: Buffer, doAppend: boolean) => {

View File

@ -1,3 +1,20 @@
export interface Agent {
name: 'Minecraft'
version: number
}
export interface AuthPayload {
agent: Agent
username: string
password: string
clientToken?: string
requestUser?: boolean
}
export interface Session { export interface Session {
accessToken: string accessToken: string

View File

@ -1,13 +1,11 @@
import { LoggerUtil } from '../logging/loggerutil' import { LoggerUtil } from '../../logging/loggerutil'
import { Agent } from './model/auth/Agent' import { MojangStatus, MojangStatusColor } from './internal/MojangStatus'
import { Status, StatusColor } from './model/internal/Status'
import got, { RequestError, HTTPError } from 'got' import got, { RequestError, HTTPError } from 'got'
import { Session } from './model/auth/Session' import { MojangResponse, MojangErrorCode, decipherErrorCode, isInternalError, MojangErrorBody } from './internal/MojangResponse'
import { AuthPayload } from './model/auth/AuthPayload'
import { MojangResponse, MojangErrorCode, decipherErrorCode, isInternalError, MojangErrorBody } from './model/internal/MojangResponse'
import { RestResponseStatus, handleGotError } from 'common/got/RestResponse' import { RestResponseStatus, handleGotError } from 'common/got/RestResponse'
import { Agent, AuthPayload, Session } from './Auth'
export class Mojang { export class MojangRestAPI {
private static readonly logger = LoggerUtil.getLogger('Mojang') private static readonly logger = LoggerUtil.getLogger('Mojang')
@ -17,12 +15,12 @@ export class Mojang {
public static readonly STATUS_ENDPOINT = 'https://status.mojang.com' public static readonly STATUS_ENDPOINT = 'https://status.mojang.com'
private static authClient = got.extend({ private static authClient = got.extend({
prefixUrl: Mojang.AUTH_ENDPOINT, prefixUrl: MojangRestAPI.AUTH_ENDPOINT,
responseType: 'json', responseType: 'json',
retry: 0 retry: 0
}) })
private static statusClient = got.extend({ private static statusClient = got.extend({
prefixUrl: Mojang.STATUS_ENDPOINT, prefixUrl: MojangRestAPI.STATUS_ENDPOINT,
responseType: 'json', responseType: 'json',
retry: 0 retry: 0
}) })
@ -32,40 +30,40 @@ export class Mojang {
version: 1 version: 1
} }
protected static statuses: Status[] = [ protected static statuses: MojangStatus[] = [
{ {
service: 'sessionserver.mojang.com', service: 'sessionserver.mojang.com',
status: StatusColor.GREY, status: MojangStatusColor.GREY,
name: 'Multiplayer Session Service', name: 'Multiplayer Session Service',
essential: true essential: true
}, },
{ {
service: 'authserver.mojang.com', service: 'authserver.mojang.com',
status: StatusColor.GREY, status: MojangStatusColor.GREY,
name: 'Authentication Service', name: 'Authentication Service',
essential: true essential: true
}, },
{ {
service: 'textures.minecraft.net', service: 'textures.minecraft.net',
status: StatusColor.GREY, status: MojangStatusColor.GREY,
name: 'Minecraft Skins', name: 'Minecraft Skins',
essential: false essential: false
}, },
{ {
service: 'api.mojang.com', service: 'api.mojang.com',
status: StatusColor.GREY, status: MojangStatusColor.GREY,
name: 'Public API', name: 'Public API',
essential: false essential: false
}, },
{ {
service: 'minecraft.net', service: 'minecraft.net',
status: StatusColor.GREY, status: MojangStatusColor.GREY,
name: 'Minecraft.net', name: 'Minecraft.net',
essential: false essential: false
}, },
{ {
service: 'account.mojang.com', service: 'account.mojang.com',
status: StatusColor.GREY, status: MojangStatusColor.GREY,
name: 'Mojang Accounts Website', name: 'Mojang Accounts Website',
essential: false essential: false
} }
@ -78,13 +76,13 @@ export class Mojang {
*/ */
public static statusToHex(status: string): string { public static statusToHex(status: string): string {
switch(status.toLowerCase()){ switch(status.toLowerCase()){
case StatusColor.GREEN: case MojangStatusColor.GREEN:
return '#a5c325' return '#a5c325'
case StatusColor.YELLOW: case MojangStatusColor.YELLOW:
return '#eac918' return '#eac918'
case StatusColor.RED: case MojangStatusColor.RED:
return '#c32625' return '#c32625'
case StatusColor.GREY: case MojangStatusColor.GREY:
default: default:
return '#848484' return '#848484'
} }
@ -92,7 +90,7 @@ export class Mojang {
private static handleGotError<T>(operation: string, error: RequestError, dataProvider: () => T): MojangResponse<T> { private static handleGotError<T>(operation: string, error: RequestError, dataProvider: () => T): MojangResponse<T> {
const response: MojangResponse<T> = handleGotError(operation, error, Mojang.logger, dataProvider) const response: MojangResponse<T> = handleGotError(operation, error, MojangRestAPI.logger, dataProvider)
if(error instanceof HTTPError) { if(error instanceof HTTPError) {
response.mojangErrorCode = decipherErrorCode(error.response.body as MojangErrorBody) response.mojangErrorCode = decipherErrorCode(error.response.body as MojangErrorBody)
@ -106,7 +104,7 @@ export class Mojang {
private static expectSpecificSuccess(operation: string, expected: number, actual: number) { private static expectSpecificSuccess(operation: string, expected: number, actual: number) {
if(actual !== expected) { if(actual !== expected) {
Mojang.logger.warn(`${operation} expected ${expected} response, recieved ${actual}.`) MojangRestAPI.logger.warn(`${operation} expected ${expected} response, recieved ${actual}.`)
} }
} }
@ -118,35 +116,35 @@ export class Mojang {
* *
* @see http://wiki.vg/Mojang_API#API_Status * @see http://wiki.vg/Mojang_API#API_Status
*/ */
public static async status(): Promise<MojangResponse<Status[]>>{ public static async status(): Promise<MojangResponse<MojangStatus[]>>{
try { try {
const res = await Mojang.statusClient.get<{[service: string]: StatusColor}[]>('check') const res = await MojangRestAPI.statusClient.get<{[service: string]: MojangStatusColor}[]>('check')
Mojang.expectSpecificSuccess('Mojang Status', 200, res.statusCode) MojangRestAPI.expectSpecificSuccess('Mojang Status', 200, res.statusCode)
res.body.forEach(status => { res.body.forEach(status => {
const entry = Object.entries(status)[0] const entry = Object.entries(status)[0]
for(let i=0; i<Mojang.statuses.length; i++) { for(let i=0; i<MojangRestAPI.statuses.length; i++) {
if(Mojang.statuses[i].service === entry[0]) { if(MojangRestAPI.statuses[i].service === entry[0]) {
Mojang.statuses[i].status = entry[1] MojangRestAPI.statuses[i].status = entry[1]
break break
} }
} }
}) })
return { return {
data: Mojang.statuses, data: MojangRestAPI.statuses,
responseStatus: RestResponseStatus.SUCCESS responseStatus: RestResponseStatus.SUCCESS
} }
} catch(error) { } catch(error) {
return Mojang.handleGotError('Mojang Status', error, () => { return MojangRestAPI.handleGotError('Mojang Status', error, () => {
for(let i=0; i<Mojang.statuses.length; i++){ for(let i=0; i<MojangRestAPI.statuses.length; i++){
Mojang.statuses[i].status = StatusColor.GREY MojangRestAPI.statuses[i].status = MojangStatusColor.GREY
} }
return Mojang.statuses return MojangRestAPI.statuses
}) })
} }
@ -168,7 +166,7 @@ export class Mojang {
password: string, password: string,
clientToken: string | null, clientToken: string | null,
requestUser = true, requestUser = true,
agent: Agent = Mojang.MINECRAFT_AGENT agent: Agent = MojangRestAPI.MINECRAFT_AGENT
): Promise<MojangResponse<Session | null>> { ): Promise<MojangResponse<Session | null>> {
try { try {
@ -183,15 +181,15 @@ export class Mojang {
json.clientToken = clientToken json.clientToken = clientToken
} }
const res = await Mojang.authClient.post<Session>('authenticate', { json, responseType: 'json' }) const res = await MojangRestAPI.authClient.post<Session>('authenticate', { json, responseType: 'json' })
Mojang.expectSpecificSuccess('Mojang Authenticate', 200, res.statusCode) MojangRestAPI.expectSpecificSuccess('Mojang Authenticate', 200, res.statusCode)
return { return {
data: res.body, data: res.body,
responseStatus: RestResponseStatus.SUCCESS responseStatus: RestResponseStatus.SUCCESS
} }
} catch(err) { } catch(err) {
return Mojang.handleGotError('Mojang Authenticate', err, () => null) return MojangRestAPI.handleGotError('Mojang Authenticate', err, () => null)
} }
} }
@ -214,8 +212,8 @@ export class Mojang {
clientToken clientToken
} }
const res = await Mojang.authClient.post('validate', { json }) const res = await MojangRestAPI.authClient.post('validate', { json })
Mojang.expectSpecificSuccess('Mojang Validate', 204, res.statusCode) MojangRestAPI.expectSpecificSuccess('Mojang Validate', 204, res.statusCode)
return { return {
data: res.statusCode === 204, data: res.statusCode === 204,
@ -229,7 +227,7 @@ export class Mojang {
responseStatus: RestResponseStatus.SUCCESS responseStatus: RestResponseStatus.SUCCESS
} }
} }
return Mojang.handleGotError('Mojang Validate', err, () => false) return MojangRestAPI.handleGotError('Mojang Validate', err, () => false)
} }
} }
@ -252,8 +250,8 @@ export class Mojang {
clientToken clientToken
} }
const res = await Mojang.authClient.post('invalidate', { json }) const res = await MojangRestAPI.authClient.post('invalidate', { json })
Mojang.expectSpecificSuccess('Mojang Invalidate', 204, res.statusCode) MojangRestAPI.expectSpecificSuccess('Mojang Invalidate', 204, res.statusCode)
return { return {
data: undefined, data: undefined,
@ -261,7 +259,7 @@ export class Mojang {
} }
} catch(err) { } catch(err) {
return Mojang.handleGotError('Mojang Invalidate', err, () => undefined) return MojangRestAPI.handleGotError('Mojang Invalidate', err, () => undefined)
} }
} }
@ -287,8 +285,8 @@ export class Mojang {
requestUser requestUser
} }
const res = await Mojang.authClient.post<Session>('refresh', { json, responseType: 'json' }) const res = await MojangRestAPI.authClient.post<Session>('refresh', { json, responseType: 'json' })
Mojang.expectSpecificSuccess('Mojang Refresh', 200, res.statusCode) MojangRestAPI.expectSpecificSuccess('Mojang Refresh', 200, res.statusCode)
return { return {
data: res.body, data: res.body,
@ -296,7 +294,7 @@ export class Mojang {
} }
} catch(err) { } catch(err) {
return Mojang.handleGotError('Mojang Refresh', err, () => null) return MojangRestAPI.handleGotError('Mojang Refresh', err, () => null)
} }
} }

View File

@ -1,14 +1,14 @@
export enum StatusColor { export enum MojangStatusColor {
RED = 'red', RED = 'red',
YELLOW = 'yellow', YELLOW = 'yellow',
GREEN = 'green', GREEN = 'green',
GREY = 'grey' GREY = 'grey'
} }
export interface Status { export interface MojangStatus {
service: string service: string
status: StatusColor status: MojangStatusColor
name: string name: string
essential: boolean essential: boolean

View File

@ -18,7 +18,7 @@ import Overlay from './overlay/Overlay'
import { OverlayPushAction, OverlayActionDispatch } from '../redux/actions/overlayActions' import { OverlayPushAction, OverlayActionDispatch } from '../redux/actions/overlayActions'
import { DistributionAPI } from 'common/distribution/distribution' import { DistributionAPI } from 'common/distribution/distribution'
import { getServerStatus } from 'common/util/ServerStatusUtil' import { getServerStatus } from 'common/mojang/net/ServerStatusAPI'
import './Application.css' import './Application.css'
@ -130,7 +130,7 @@ class Application extends React.Component<ApplicationProps & typeof mapDispatch,
const distro = new DistributionAPI('C:\\Users\\user\\AppData\\Roaming\\Helios Launcher') const distro = new DistributionAPI('C:\\Users\\user\\AppData\\Roaming\\Helios Launcher')
const x = await distro.testLoad() const x = await distro.testLoad()
console.log(x) console.log(x)
const serverStatus = await getServerStatus(47, 'mc.westeroscraft.com', 25565) const serverStatus = await getServerStatus(47, 'play.hypixel.net', 25565)
console.log(serverStatus) console.log(serverStatus)
} }
}) })

View File

@ -1,15 +1,15 @@
import * as React from 'react' import * as React from 'react'
import { Status, StatusColor } from 'common/mojang/model/internal/Status' import { MojangStatus, MojangStatusColor } from 'common/mojang/rest/internal/MojangStatus'
import { MojangResponse } from 'common/mojang/model/internal/MojangResponse' import { MojangResponse } from 'common/mojang/rest/internal/MojangResponse'
import { Mojang } from 'common/mojang/mojang' import { MojangRestAPI } from 'common/mojang/rest/MojangRestAPI'
import { RestResponseStatus } from 'common/got/RestResponse' import { RestResponseStatus } from 'common/got/RestResponse'
import { LoggerUtil } from 'common/logging/loggerutil' import { LoggerUtil } from 'common/logging/loggerutil'
import './Landing.css' import './Landing.css'
interface LandingState { interface LandingState {
mojangStatuses: Status[] mojangStatuses: MojangStatus[]
} }
export default class Landing extends React.Component<unknown, LandingState> { export default class Landing extends React.Component<unknown, LandingState> {
@ -45,7 +45,7 @@ export default class Landing extends React.Component<unknown, LandingState> {
} }
private loadMojangStatuses = async (): Promise<void> => { private loadMojangStatuses = async (): Promise<void> => {
const response: MojangResponse<Status[]> = await Mojang.status() const response: MojangResponse<MojangStatus[]> = await MojangRestAPI.status()
if(response.responseStatus !== RestResponseStatus.SUCCESS) { if(response.responseStatus !== RestResponseStatus.SUCCESS) {
Landing.logger.warn('Failed to retrieve Mojang Statuses.') Landing.logger.warn('Failed to retrieve Mojang Statuses.')
@ -56,7 +56,7 @@ export default class Landing extends React.Component<unknown, LandingState> {
const statuses = response.data const statuses = response.data
for(const status of statuses) { for(const status of statuses) {
if(status.service === 'sessionserver.mojang.com' || status.service === 'minecraft.net') { if(status.service === 'sessionserver.mojang.com' || status.service === 'minecraft.net') {
status.status = StatusColor.GREEN status.status = MojangStatusColor.GREEN
} }
} }
@ -71,27 +71,27 @@ export default class Landing extends React.Component<unknown, LandingState> {
const essential = this.state.mojangStatuses.filter(s => s.essential) const essential = this.state.mojangStatuses.filter(s => s.essential)
if(this.state.mojangStatuses.length === 0) { if(this.state.mojangStatuses.length === 0) {
return Mojang.statusToHex(StatusColor.GREY) return MojangRestAPI.statusToHex(MojangStatusColor.GREY)
} }
// If any essential are red, it's red. // If any essential are red, it's red.
if(essential.filter(s => s.status === StatusColor.RED).length > 0) { if(essential.filter(s => s.status === MojangStatusColor.RED).length > 0) {
return Mojang.statusToHex(StatusColor.RED) return MojangRestAPI.statusToHex(MojangStatusColor.RED)
} }
// If any essential are yellow, it's yellow. // If any essential are yellow, it's yellow.
if(essential.filter(s => s.status === StatusColor.YELLOW).length > 0) { if(essential.filter(s => s.status === MojangStatusColor.YELLOW).length > 0) {
return Mojang.statusToHex(StatusColor.YELLOW) return MojangRestAPI.statusToHex(MojangStatusColor.YELLOW)
} }
// If any non-essential are not green, return yellow. // If any non-essential are not green, return yellow.
if(this.state.mojangStatuses.filter(s => s.status !== StatusColor.GREEN && s.status !== StatusColor.GREY).length > 0) { if(this.state.mojangStatuses.filter(s => s.status !== MojangStatusColor.GREEN && s.status !== MojangStatusColor.GREY).length > 0) {
return Mojang.statusToHex(StatusColor.YELLOW) return MojangRestAPI.statusToHex(MojangStatusColor.YELLOW)
} }
// if all are grey, return grey. // if all are grey, return grey.
if(this.state.mojangStatuses.filter(s => s.status === StatusColor.GREY).length === this.state.mojangStatuses.length) { if(this.state.mojangStatuses.filter(s => s.status === MojangStatusColor.GREY).length === this.state.mojangStatuses.length) {
return Mojang.statusToHex(StatusColor.GREY) return MojangRestAPI.statusToHex(MojangStatusColor.GREY)
} }
return Mojang.statusToHex(StatusColor.GREEN) return MojangRestAPI.statusToHex(MojangStatusColor.GREEN)
} }
private getMojangStatusesAsJSX = (essential: boolean): JSX.Element[] => { private getMojangStatusesAsJSX = (essential: boolean): JSX.Element[] => {
@ -101,7 +101,7 @@ export default class Landing extends React.Component<unknown, LandingState> {
statuses.push( statuses.push(
<> <>
<div className="mojangStatusContainer"> <div className="mojangStatusContainer">
<span className="mojangStatusIcon" style={{color: Mojang.statusToHex(status.status)}}>&#8226;</span> <span className="mojangStatusIcon" style={{color: MojangRestAPI.statusToHex(status.status)}}>&#8226;</span>
<span className="mojangStatusName">{status.name}</span> <span className="mojangStatusName">{status.name}</span>
</div> </div>
</> </>

View File

@ -1,9 +1,9 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import { Mojang } from 'common/mojang/mojang' import { MojangRestAPI } from 'common/mojang/rest/MojangRestAPI'
import { expect } from 'chai' import { expect } from 'chai'
import nock from 'nock' import nock from 'nock'
import { Session } from 'common/mojang/model/auth/Session' import { Session } from 'common/mojang/rest/Auth'
import { MojangErrorCode, MojangResponse } from 'common/mojang/model/internal/MojangResponse' import { MojangErrorCode, MojangResponse } from 'common/mojang/rest/internal/MojangResponse'
import { RestResponseStatus, RestResponse } from 'common/got/RestResponse' import { RestResponseStatus, RestResponse } from 'common/got/RestResponse'
function assertResponse(res: RestResponse<unknown>) { function assertResponse(res: RestResponse<unknown>) {
@ -39,13 +39,13 @@ describe('Mojang Errors', () => {
it('Status (Offline)', async () => { it('Status (Offline)', async () => {
const defStatusHack = Mojang['statuses'] const defStatusHack = MojangRestAPI['statuses']
nock(Mojang.STATUS_ENDPOINT) nock(MojangRestAPI.STATUS_ENDPOINT)
.get('/check') .get('/check')
.reply(500, 'Service temprarily offline.') .reply(500, 'Service temprarily offline.')
const res = await Mojang.status() const res = await MojangRestAPI.status()
expectFailure(res) expectFailure(res)
expect(res.data).to.be.an('array') expect(res.data).to.be.an('array')
expect(res.data).to.deep.equal(defStatusHack) expect(res.data).to.deep.equal(defStatusHack)
@ -54,7 +54,7 @@ describe('Mojang Errors', () => {
it('Authenticate (Invalid Credentials)', async () => { it('Authenticate (Invalid Credentials)', async () => {
nock(Mojang.AUTH_ENDPOINT) nock(MojangRestAPI.AUTH_ENDPOINT)
.post('/authenticate') .post('/authenticate')
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
.reply(403, (uri, requestBody: unknown): { error: string, errorMessage: string } => { .reply(403, (uri, requestBody: unknown): { error: string, errorMessage: string } => {
@ -64,7 +64,7 @@ describe('Mojang Errors', () => {
} }
}) })
const res = await Mojang.authenticate('user', 'pass', 'xxx', true) const res = await MojangRestAPI.authenticate('user', 'pass', 'xxx', true)
expectMojangResponse(res, MojangErrorCode.ERROR_INVALID_CREDENTIALS) expectMojangResponse(res, MojangErrorCode.ERROR_INVALID_CREDENTIALS)
expect(res.data).to.be.a('null') expect(res.data).to.be.a('null')
expect(res.error).to.not.be.a('null') expect(res.error).to.not.be.a('null')
@ -76,13 +76,13 @@ describe('Mojang Status', () => {
it('Status (Online)', async () => { it('Status (Online)', async () => {
const defStatusHack = Mojang['statuses'] const defStatusHack = MojangRestAPI['statuses']
nock(Mojang.STATUS_ENDPOINT) nock(MojangRestAPI.STATUS_ENDPOINT)
.get('/check') .get('/check')
.reply(200, defStatusHack) .reply(200, defStatusHack)
const res = await Mojang.status() const res = await MojangRestAPI.status()
expectSuccess(res) expectSuccess(res)
expect(res.data).to.be.an('array') expect(res.data).to.be.an('array')
expect(res.data).to.deep.equal(defStatusHack) expect(res.data).to.deep.equal(defStatusHack)
@ -95,7 +95,7 @@ describe('Mojang Auth', () => {
it('Authenticate', async () => { it('Authenticate', async () => {
nock(Mojang.AUTH_ENDPOINT) nock(MojangRestAPI.AUTH_ENDPOINT)
.post('/authenticate') .post('/authenticate')
.reply(200, (uri, requestBody: any): Session => { .reply(200, (uri, requestBody: any): Session => {
const mockResponse: Session = { const mockResponse: Session = {
@ -117,7 +117,7 @@ describe('Mojang Auth', () => {
return mockResponse return mockResponse
}) })
const res = await Mojang.authenticate('user', 'pass', 'xxx', true) const res = await MojangRestAPI.authenticate('user', 'pass', 'xxx', true)
expectSuccess(res) expectSuccess(res)
expect(res.data!.clientToken).to.equal('xxx') expect(res.data!.clientToken).to.equal('xxx')
expect(res.data).to.have.property('user') expect(res.data).to.have.property('user')
@ -126,7 +126,7 @@ describe('Mojang Auth', () => {
it('Validate', async () => { it('Validate', async () => {
nock(Mojang.AUTH_ENDPOINT) nock(MojangRestAPI.AUTH_ENDPOINT)
.post('/validate') .post('/validate')
.times(2) .times(2)
.reply((uri, requestBody: any) => { .reply((uri, requestBody: any) => {
@ -135,13 +135,13 @@ describe('Mojang Auth', () => {
] ]
}) })
const res = await Mojang.validate('abc', 'def') const res = await MojangRestAPI.validate('abc', 'def')
expectSuccess(res) expectSuccess(res)
expect(res.data).to.be.a('boolean') expect(res.data).to.be.a('boolean')
expect(res.data).to.equal(true) expect(res.data).to.equal(true)
const res2 = await Mojang.validate('def', 'def') const res2 = await MojangRestAPI.validate('def', 'def')
expectSuccess(res2) expectSuccess(res2)
expect(res2.data).to.be.a('boolean') expect(res2.data).to.be.a('boolean')
@ -151,11 +151,11 @@ describe('Mojang Auth', () => {
it('Invalidate', async () => { it('Invalidate', async () => {
nock(Mojang.AUTH_ENDPOINT) nock(MojangRestAPI.AUTH_ENDPOINT)
.post('/invalidate') .post('/invalidate')
.reply(204) .reply(204)
const res = await Mojang.invalidate('adc', 'def') const res = await MojangRestAPI.invalidate('adc', 'def')
expectSuccess(res) expectSuccess(res)
@ -163,7 +163,7 @@ describe('Mojang Auth', () => {
it('Refresh', async () => { it('Refresh', async () => {
nock(Mojang.AUTH_ENDPOINT) nock(MojangRestAPI.AUTH_ENDPOINT)
.post('/refresh') .post('/refresh')
.reply(200, (uri, requestBody: any): Session => { .reply(200, (uri, requestBody: any): Session => {
const mockResponse: Session = { const mockResponse: Session = {
@ -185,7 +185,7 @@ describe('Mojang Auth', () => {
return mockResponse return mockResponse
}) })
const res = await Mojang.refresh('gfd', 'xxx', true) const res = await MojangRestAPI.refresh('gfd', 'xxx', true)
expectSuccess(res) expectSuccess(res)
expect(res.data!.clientToken).to.equal('xxx') expect(res.data!.clientToken).to.equal('xxx')
expect(res.data).to.have.property('user') expect(res.data).to.have.property('user')