Эх сурвалжийг харах

Clean up structure of Mojang API/Util files.

Daniel Scalzi 5 жил өмнө
parent
commit
c7b95f3719

+ 0 - 6
src/common/mojang/model/auth/Agent.ts

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

+ 0 - 11
src/common/mojang/model/auth/AuthPayload.ts

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

+ 157 - 0
src/common/mojang/net/Protocol.ts

@@ -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
+    }
+
+}

+ 10 - 156
src/common/util/ServerStatusUtil.ts → src/common/mojang/net/ServerStatusAPI.ts

@@ -1,6 +1,7 @@
 /* eslint-disable no-control-regex */
 import { connect } from 'net'
 import { LoggerUtil } from 'common/logging/loggerutil'
+import { ServerBoundPacket, ClientBoundPacket, ProtocolUtils } from './Protocol'
 
 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.
  * 
@@ -217,7 +63,15 @@ function getRequestPacket(): Buffer {
         .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 {
+    // Some servers don't wrap their description in a text object.
     if(typeof resp.description === 'string') {
         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.
-            bytesLeft = packetLength + getVarIntSize(packetLength)
+            bytesLeft = packetLength + ProtocolUtils.getVarIntSize(packetLength)
 
             // Listener to keep reading until we have read all the bytes into the buffer.
             const packetReadListener = (nextData: Buffer, doAppend: boolean) => {

+ 17 - 0
src/common/mojang/model/auth/Session.ts → src/common/mojang/rest/Auth.ts

@@ -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 {
 
     accessToken: string

+ 44 - 46
src/common/mojang/mojang.ts → src/common/mojang/rest/MojangRestAPI.ts

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

+ 0 - 0
src/common/mojang/model/internal/MojangResponse.ts → src/common/mojang/rest/internal/MojangResponse.ts


+ 3 - 3
src/common/mojang/model/internal/Status.ts → src/common/mojang/rest/internal/MojangStatus.ts

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

+ 2 - 2
src/renderer/components/Application.tsx

@@ -18,7 +18,7 @@ import Overlay from './overlay/Overlay'
 import { OverlayPushAction, OverlayActionDispatch } from '../redux/actions/overlayActions'
 
 import { DistributionAPI } from 'common/distribution/distribution'
-import { getServerStatus } from 'common/util/ServerStatusUtil'
+import { getServerStatus } from 'common/mojang/net/ServerStatusAPI'
 
 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 x = await distro.testLoad()
                             console.log(x)
-                            const serverStatus = await getServerStatus(47, 'mc.westeroscraft.com', 25565)
+                            const serverStatus = await getServerStatus(47, 'play.hypixel.net', 25565)
                             console.log(serverStatus)
                         }
                     })

+ 17 - 17
src/renderer/components/landing/Landing.tsx

@@ -1,15 +1,15 @@
 import * as React from 'react'
 
-import { Status, StatusColor } from 'common/mojang/model/internal/Status'
-import { MojangResponse } from 'common/mojang/model/internal/MojangResponse'
-import { Mojang } from 'common/mojang/mojang'
+import { MojangStatus, MojangStatusColor } from 'common/mojang/rest/internal/MojangStatus'
+import { MojangResponse } from 'common/mojang/rest/internal/MojangResponse'
+import { MojangRestAPI } from 'common/mojang/rest/MojangRestAPI'
 import { RestResponseStatus } from 'common/got/RestResponse'
 import { LoggerUtil } from 'common/logging/loggerutil'
 
 import './Landing.css'
 
 interface LandingState {
-    mojangStatuses: Status[]
+    mojangStatuses: MojangStatus[]
 }
 
 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> => {
-        const response: MojangResponse<Status[]> = await Mojang.status()
+        const response: MojangResponse<MojangStatus[]> = await MojangRestAPI.status()
 
         if(response.responseStatus !== RestResponseStatus.SUCCESS) {
             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
         for(const status of statuses) {
             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)
 
         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(essential.filter(s => s.status === StatusColor.RED).length > 0) {
-            return Mojang.statusToHex(StatusColor.RED)
+        if(essential.filter(s => s.status === MojangStatusColor.RED).length > 0) {
+            return MojangRestAPI.statusToHex(MojangStatusColor.RED)
         }
         // If any essential are yellow, it's yellow.
-        if(essential.filter(s => s.status === StatusColor.YELLOW).length > 0) {
-            return Mojang.statusToHex(StatusColor.YELLOW)
+        if(essential.filter(s => s.status === MojangStatusColor.YELLOW).length > 0) {
+            return MojangRestAPI.statusToHex(MojangStatusColor.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) {
-            return Mojang.statusToHex(StatusColor.YELLOW)
+        if(this.state.mojangStatuses.filter(s => s.status !== MojangStatusColor.GREEN && s.status !== MojangStatusColor.GREY).length > 0) {
+            return MojangRestAPI.statusToHex(MojangStatusColor.YELLOW)
         }
         // if all are grey, return grey.
-        if(this.state.mojangStatuses.filter(s => s.status === StatusColor.GREY).length === this.state.mojangStatuses.length) {
-            return Mojang.statusToHex(StatusColor.GREY)
+        if(this.state.mojangStatuses.filter(s => s.status === MojangStatusColor.GREY).length === this.state.mojangStatuses.length) {
+            return MojangRestAPI.statusToHex(MojangStatusColor.GREY)
         }
 
-        return Mojang.statusToHex(StatusColor.GREEN)
+        return MojangRestAPI.statusToHex(MojangStatusColor.GREEN)
     }
 
     private getMojangStatusesAsJSX = (essential: boolean): JSX.Element[] => {
@@ -101,7 +101,7 @@ export default class Landing extends React.Component<unknown, LandingState> {
             statuses.push(
                 <>
                     <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>
                     </div>
                 </>

+ 20 - 20
test/mojang/mojangTest.ts

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