diff --git a/settings.json b/settings.json index 47f3d02..4895a04 100644 --- a/settings.json +++ b/settings.json @@ -4,6 +4,7 @@ "gamemode": 1, "enableGamemodeVote": true, "passwordRequired": false, + "password": "", "name": "A Net64+ Server", "domain": "", "description": "The **best** Net64+ server ever\n\n:unicorn_face:", diff --git a/src/Client.spec.ts b/src/Client.spec.ts index 5c14a70..51d1fd7 100644 --- a/src/Client.spec.ts +++ b/src/Client.spec.ts @@ -1,11 +1,18 @@ import * as zlib from 'zlib' import { webSocketServer } from '.' -import { Client, CONNECTION_TIMEOUT, DECOMPRESSION_ERROR, AFK_TIMEOUT, AFK_TIMEOUT_COUNT, MAX_LENGTH_CHAT_MESSAGE } from './Client' +import { Client, CONNECTION_TIMEOUT, DECOMPRESSION_ERROR, AFK_TIMEOUT, AFK_TIMEOUT_COUNT, MAX_LENGTH_CHAT_MESSAGE, NO_PASSWORD_REQUIRED } from './Client' +import { Player } from './Player' import { IClientServerMessage, Compression, ClientServer, ClientServerMessage, Chat } from './proto/ClientServerMessage' -import { IServerClientMessage, ServerClient, ServerClientMessage, ServerMessage, Error as ErrorProto } from './proto/ServerClientMessage' +import { IServerClientMessage, ServerClient, ServerClientMessage, ServerMessage, Error as ErrorProto, Authentication } from './proto/ServerClientMessage' import { - MESSAGES_PER_HALF_MINUTE_THRESHOLD, MESSAGES_PER_HALF_MINUTE_DOS_THRESHOLD, MESSAGE_CHARACTERS_PER_HALF_MINUTE_THRESHOLD, SPAM_NOTIFICATION_MESSAGE, warningLevelMuteMapping, Identity + Identity, + PASSWORD_THROTTLE_INCREASE, + MESSAGE_CHARACTERS_PER_HALF_MINUTE_THRESHOLD, + MESSAGES_PER_HALF_MINUTE_DOS_THRESHOLD, + MESSAGES_PER_HALF_MINUTE_THRESHOLD, + SPAM_NOTIFICATION_MESSAGE, + warningLevelMuteMapping } from './Identity' const addClient = (client: Client) => { @@ -28,7 +35,9 @@ describe('Client', () => { webSocketServer = { clients: [], players: [], - onGlobalChatMessage: jest.fn() + onGlobalChatMessage: jest.fn(), + sendHandshake: jest.fn(), + addPlayer: jest.fn() } as any wsMock = { on: (type: string, callback: () => Promise) => { @@ -127,6 +136,206 @@ describe('Client', () => { }) }) + describe('#onAuthentication', () => { + let username: string + let characterId: number + + beforeEach(() => { + username = 'username' + characterId = 4 + process.env.MAJOR = '0' + process.env.MINOR = '0' + }) + + beforeEach(() => { + expect(client.player).toBeUndefined() + }) + + describe('if password is required', () => { + beforeEach(() => { + // @ts-ignore + webSocketServer.passwordRequired = true + const message: IClientServerMessage = { + compression: Compression.NONE, + data: { + messageType: ClientServer.MessageType.HANDSHAKE, + handshake: { + characterId, + major: 0, + minor: 0, + username + } + } + } + const encodedMessage = ClientServerMessage.encode(ClientServerMessage.fromObject(message)).finish() + + return fnMocks.message(encodedMessage) + }) + + describe('on correct password', () => { + beforeEach(async () => { + const password = 'server-password' + // @ts-ignore + webSocketServer.password = password + const message: IClientServerMessage = { + compression: Compression.NONE, + data: { + messageType: ClientServer.MessageType.AUTHENTICATE, + authenticate: { + password + } + } + } + const encodedMessage = ClientServerMessage.encode(ClientServerMessage.fromObject(message)).finish() + + await fnMocks.message(encodedMessage) + }) + + it('should create player object', () => { + expect(client.player).toBeDefined() + expect(client.player!.username).toEqual(username) + expect(client.player!.characterId).toEqual(characterId) + }) + + it('should add player to server', () => { + expect(webSocketServer.addPlayer).toHaveBeenCalledWith(new Player(client, username, characterId)) + }) + + it('should send password accepted message to client', () => { + const success: IServerClientMessage = { + compression: Compression.NONE, + data: { + messageType: ServerClient.MessageType.SERVER_MESSAGE, + serverMessage: { + messageType: ServerMessage.MessageType.AUTHENTICATION, + authentication: { + status: Authentication.Status.ACCEPTED + } + } + } + } + const successMessage = ServerClientMessage.encode(ServerClientMessage.fromObject(success)).finish() + + expect(wsMock.send).toHaveBeenLastCalledWith(successMessage, { + binary: true + }) + }) + }) + + describe('on incorrect password', () => { + let wrongPasswordMessage: Uint8Array + beforeEach(async () => { + const password = 'server-password' + // @ts-ignore + webSocketServer.password = password + const message: IClientServerMessage = { + compression: Compression.NONE, + data: { + messageType: ClientServer.MessageType.AUTHENTICATE, + authenticate: { + password: 'incorrect-password' + } + } + } + wrongPasswordMessage = ClientServerMessage.encode(ClientServerMessage.fromObject(message)).finish() + + await fnMocks.message(wrongPasswordMessage) + expect(wsMock.send).toHaveBeenCalledTimes(1) + }) + + it('should send message that password was incorrect', () => { + const message: IServerClientMessage = { + compression: Compression.NONE, + data: { + messageType: ServerClient.MessageType.SERVER_MESSAGE, + serverMessage: { + messageType: ServerMessage.MessageType.AUTHENTICATION, + authentication: { + status: Authentication.Status.DENIED, + throttle: PASSWORD_THROTTLE_INCREASE + } + } + } + } + const wrongPasswordMessage = ServerClientMessage.encode(ServerClientMessage.fromObject(message)).finish() + + expect(wsMock.send).toHaveBeenLastCalledWith(wrongPasswordMessage, { + binary: true + }) + }) + + it('should not accept message during throttle phase', async () => { + await fnMocks.message(wrongPasswordMessage) + + expect(wsMock.send).toHaveBeenCalledTimes(1) + }) + + it('should reaccept message after throttling phase', async () => { + jest.advanceTimersByTime(PASSWORD_THROTTLE_INCREASE) + await fnMocks.message(wrongPasswordMessage) + + expect(wsMock.send).toHaveBeenCalledTimes(2) + }) + }) + }) + + describe('if password is not required', () => { + beforeEach(async () => { + // @ts-ignore + webSocketServer.passwordRequired = false + let message: IClientServerMessage = { + compression: Compression.NONE, + data: { + messageType: ClientServer.MessageType.HANDSHAKE, + handshake: { + characterId, + major: 0, + minor: 0, + username + } + } + } + let encodedMessage = ClientServerMessage.encode(ClientServerMessage.fromObject(message)).finish() + + await fnMocks.message(encodedMessage) + + message = { + compression: Compression.NONE, + data: { + messageType: ClientServer.MessageType.AUTHENTICATE, + authenticate: { + password: 'password' + } + } + } + encodedMessage = ClientServerMessage.encode(ClientServerMessage.fromObject(message)).finish() + + await fnMocks.message(encodedMessage) + }) + + it('should send message that password is not required', () => { + const message: IServerClientMessage = { + compression: Compression.NONE, + data: { + messageType: ServerClient.MessageType.SERVER_MESSAGE, + serverMessage: { + messageType: ServerMessage.MessageType.ERROR, + error: { + errorType: ErrorProto.ErrorType.BAD_REQUEST, + message: NO_PASSWORD_REQUIRED + } + } + } + } + const noPassRequiredMessage = ServerClientMessage.encode(ServerClientMessage.fromObject(message)).finish() + + expect(wsMock.send).toHaveBeenLastCalledWith(noPassRequiredMessage, { + binary: true + }) + }) + }) + }) + describe('#onChatMessage', () => { it('should send global chat message', async () => { const message: IClientServerMessage = { diff --git a/src/Client.ts b/src/Client.ts index 5c2ffaa..1230afd 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -5,12 +5,24 @@ import * as zlib from 'zlib' import { webSocketServer } from '.' import { Identity } from './Identity' import { Player, PLAYER_DATA_LENGTH } from './Player' -import { WebSocketServer } from './WebSocketServer' import { ConnectionError } from './models/Connection.model' import { - ServerClientMessage, IServerClientMessage, ServerClient, ServerMessage, ConnectionDenied, Error as ErrorProto + Authentication, + ConnectionDenied, + Error as ErrorProto, + IServerClientMessage, + ServerClient, + ServerClientMessage, + ServerMessage } from './proto/ServerClientMessage' -import { ClientServerMessage, ClientServer, IClientServer, IClientHandshake, Compression, Chat } from './proto/ClientServerMessage' +import { + Chat, + ClientServer, + ClientServerMessage, + Compression, + IClientHandshake, + IClientServer +} from './proto/ClientServerMessage' export const CONNECTION_TIMEOUT = 10000 @@ -20,6 +32,8 @@ export const AFK_TIMEOUT_COUNT = 30 export const DECOMPRESSION_ERROR = 'Your message could not be decompressed' +export const NO_PASSWORD_REQUIRED = 'This server requires no password authentication' + export const MAX_LENGTH_CHAT_MESSAGE = 100 const escapeHTML = require('escape-html') @@ -38,6 +52,10 @@ export class Client { private previousPlayerLocation = 0 + private desiredUsername?: string + + private desiredCharacterId?: number + constructor (public id: number, private ws: WebSocket) { this.id = id this.ws = ws @@ -166,6 +184,9 @@ export class Client { case ClientServer.MessageType.PLAYER_UPDATE: this.onPlayerUpdate(messageData!) break + case ClientServer.MessageType.AUTHENTICATE: + this.onAuthentication(messageData!) + break case ClientServer.MessageType.PLAYER_DATA: this.onPlayerData(messageData!) break @@ -250,14 +271,27 @@ export class Client { this.sendWrongVersionMessage() return } - this.player = new Player(this, username, characterId) - webSocketServer.addPlayer(this.player) this.sendHandshake() + if (webSocketServer.passwordRequired) { + this.desiredUsername = username + this.desiredCharacterId = characterId + return + } + this.createPlayerObject(username, characterId) } catch (err) { console.error(err) } } + private createPlayerObject (username?: string, characterId?: number): void { + username = username || this.desiredUsername + if (!username) throw new Error('Player object could not be created, because username is null') + characterId = characterId || this.desiredCharacterId + if (characterId == null) throw new Error('Player object could not be created, because characterId is null') + this.player = new Player(this, username, characterId) + webSocketServer.addPlayer(this.player) + } + private isClientUsingWrongVersion (handshake: IClientHandshake): boolean { return String(handshake.major) !== process.env.MAJOR || String(handshake.minor) !== process.env.MINOR } @@ -312,10 +346,65 @@ export class Client { } } const playerMessage = ServerClientMessage.encode(ServerClientMessage.fromObject(playerMsg)).finish() - webSocketServer.broadcastMessage(playerMessage) + webSocketServer.broadcastMessageAll(playerMessage) + } + + private onAuthentication (messageData: IClientServer): void { + if (!webSocketServer.passwordRequired) { + this.sendBadRequest(new ConnectionError( + NO_PASSWORD_REQUIRED, + ErrorProto.ErrorType.BAD_REQUEST + )) + return + } + const authenticate = messageData.authenticate + this.checkRequiredObjects(authenticate) + if (!this.identity.canSendPassword) return + const password = authenticate!.password + if (password !== webSocketServer.password) { + this.sendWrongPasswordMessage() + return + } + this.sendSuccessfulAuthenticationMessage() + this.createPlayerObject() + } + + private sendWrongPasswordMessage (): void { + const wrongPassword: IServerClientMessage = { + compression: Compression.NONE, + data: { + messageType: ServerClient.MessageType.SERVER_MESSAGE, + serverMessage: { + messageType: ServerMessage.MessageType.AUTHENTICATION, + authentication: { + status: Authentication.Status.DENIED, + throttle: this.identity.getPasswordThrottle() + } + } + } + } + const wrongPasswordMessage = ServerClientMessage.encode(ServerClientMessage.fromObject(wrongPassword)).finish() + this.sendMessage(wrongPasswordMessage) + } + + private sendSuccessfulAuthenticationMessage (): void { + const success: IServerClientMessage = { + compression: Compression.NONE, + data: { + messageType: ServerClient.MessageType.SERVER_MESSAGE, + serverMessage: { + messageType: ServerMessage.MessageType.AUTHENTICATION, + authentication: { + status: Authentication.Status.ACCEPTED + } + } + } + } + const successMessage = ServerClientMessage.encode(ServerClientMessage.fromObject(success)).finish() + this.sendMessage(successMessage) } - private onPlayerData (messageData: IClientServer) { + private onPlayerData (messageData: IClientServer): void { if (this.connectionTimeout) { clearTimeout(this.connectionTimeout) this.connectionTimeout = undefined diff --git a/src/Identity.spec.ts b/src/Identity.spec.ts new file mode 100644 index 0000000..f2f2727 --- /dev/null +++ b/src/Identity.spec.ts @@ -0,0 +1,73 @@ +import { Identity, PASSWORD_THROTTLE_INCREASE, PASSWORD_THROTTLE_RESET } from './Identity' +import { Client } from './Client' +import { ClientMock } from './Client.mock' + +describe('Identity', () => { + let identity: Identity + let client: Client + + beforeEach(() => { + client = new ClientMock(1, {}, {}) as any + identity = Identity.getIdentity(client, '127.0.0.1') + }) + + beforeEach(() => { + jest.useFakeTimers() + Identity.Identities = {} + }) + + describe('#getPasswordThrottle', () => { + beforeEach(() => { + expect(identity.canSendPassword).toBe(true) + }) + + it('should return password throttle', () => { + const res = identity.getPasswordThrottle() + + expect(res).toEqual(PASSWORD_THROTTLE_INCREASE) + }) + + it('should increase password throttle', () => { + for (let i = 1; i < 5; i++) { + const throttle = identity.getPasswordThrottle() + jest.advanceTimersByTime(throttle) + + expect(throttle).toEqual(PASSWORD_THROTTLE_INCREASE * i) + } + }) + + it('should set #canSendPassword to false', () => { + identity.getPasswordThrottle() + + expect(identity.canSendPassword).toBe(false) + }) + + it('should set #canSendPassword to true after throttling phase', () => { + const throttle = identity.getPasswordThrottle() + jest.advanceTimersByTime(throttle) + + expect(identity.canSendPassword).toBe(true) + }) + + it('should not set #canSendPassword to true after throttling phase is almost over', () => { + const throttle = identity.getPasswordThrottle() + jest.advanceTimersByTime(throttle - 1) + + expect(identity.canSendPassword).toBe(false) + }) + + it('should reset password throttle after reset throttle phase', () => { + identity.getPasswordThrottle() + jest.advanceTimersByTime(PASSWORD_THROTTLE_RESET) + const throttle = identity.getPasswordThrottle() + + expect(throttle).toEqual(PASSWORD_THROTTLE_INCREASE) + }) + + it('should throw error, if called during throttling phase', () => { + identity.getPasswordThrottle() + + expect(identity.getPasswordThrottle).toThrow() + }) + }) +}) diff --git a/src/Identity.ts b/src/Identity.ts index 9f63e46..952e987 100644 --- a/src/Identity.ts +++ b/src/Identity.ts @@ -3,6 +3,10 @@ import { IServerClientMessage, ServerClient, Compression, ServerClientMessage, Chat } from './proto/ServerClientMessage' +export const PASSWORD_THROTTLE_INCREASE = 10 + +export const PASSWORD_THROTTLE_RESET = 120 + export const MESSAGES_PER_HALF_MINUTE_THRESHOLD = 15 export const MESSAGES_PER_HALF_MINUTE_DOS_THRESHOLD = 150 @@ -24,6 +28,17 @@ export class Identity { private static identityDeleteTimeout = 120000 + private passwordThrottle = 0 + + private passwordThrottleReset?: NodeJS.Timer + + private _canSendPassword = true + public get canSendPassword (): boolean { + return this._canSendPassword + } + + private canSendPasswordReset?: NodeJS.Timer + private warningLevel = 0 private warningLevelReset?: NodeJS.Timer @@ -59,6 +74,23 @@ export class Identity { }, Identity.identityDeleteTimeout) } + public getPasswordThrottle (): number { + if (!this._canSendPassword) { + throw new Error('Password throttle was called even though password sending is disabled') + } + this.passwordThrottle += PASSWORD_THROTTLE_INCREASE + this.passwordThrottleReset = setTimeout(() => { + this.passwordThrottle = 0 + delete this.passwordThrottleReset + }, PASSWORD_THROTTLE_RESET) + this._canSendPassword = false + this.canSendPasswordReset = setTimeout(() => { + this._canSendPassword = true + delete this.canSendPasswordReset + }, this.passwordThrottle) + return this.passwordThrottle + } + public chatProtect (message: string): boolean { if (!this.spamProtect(message)) { return false diff --git a/src/WebSocketServer.spec.ts b/src/WebSocketServer.spec.ts index 57a6d59..16fef95 100644 --- a/src/WebSocketServer.spec.ts +++ b/src/WebSocketServer.spec.ts @@ -10,6 +10,7 @@ describe('WebSocketServer', () => { gamemode: 1, enableGamemodeVote: true, passwordRequired: false, + password: '', name: 'A Server', domain: '', description: 'A description' diff --git a/src/WebSocketServer.ts b/src/WebSocketServer.ts index 683fed9..b77a56f 100644 --- a/src/WebSocketServer.ts +++ b/src/WebSocketServer.ts @@ -20,8 +20,7 @@ import { Compression, Chat, Error as ErrorProto, - IMeta, - GameModeType + IMeta } from './proto/ServerClientMessage' let WSServer: typeof WebSocket.Server @@ -60,10 +59,12 @@ export class WebSocketServer { private countryCode: string - private passwordRequired: boolean + public readonly passwordRequired: boolean + + public readonly password: string constructor ( - { port, gamemode, enableGamemodeVote, passwordRequired, name, domain, description }: Settings, + { port, gamemode, enableGamemodeVote, passwordRequired, password, name, domain, description }: Settings, server?: Server ) { this.gameMode = gamemode @@ -74,6 +75,7 @@ export class WebSocketServer { this.description = description this.countryCode = server ? server.countryCode : 'LAN' this.passwordRequired = passwordRequired + this.password = password this.command = new Command(enableGamemodeVote) this.onConnection = this.onConnection.bind(this) this.server = new WSServer({ port: this.port }, () => { @@ -124,7 +126,7 @@ export class WebSocketServer { } } const playerMessage = ServerClientMessage.encode(ServerClientMessage.fromObject(playerMsg)).finish() - this.broadcastMessage(playerMessage) + this.broadcastMessageAll(playerMessage) } private generatePlayerUpdates (): IPlayerUpdate[] { @@ -181,11 +183,30 @@ export class WebSocketServer { } } + /** + * Broadcast message to all authenticate clients. + * + * @param {Uint8Array} message - The message to broadcast + */ public broadcastMessage (message: Uint8Array): void { - for (const i in this.players) { - const player = this.players[i] - player.client.sendMessage(message) - } + this.players + .filter(player => player) + .forEach(({ client }) => { + client.sendMessage(message) + }) + } + + /** + * Broadcast message to all clients. + * + * @param {Uint8Array} message - The message to broadcast + */ + public broadcastMessageAll (message: Uint8Array): void { + this.clients + .filter(client => client) + .forEach(client => { + client.sendMessage(message) + }) } public async broadcastData (): Promise { diff --git a/src/models/Settings.model.ts b/src/models/Settings.model.ts index 5c40f9e..91bf76d 100644 --- a/src/models/Settings.model.ts +++ b/src/models/Settings.model.ts @@ -3,6 +3,7 @@ export interface Settings { gamemode: number enableGamemodeVote: boolean passwordRequired: boolean + password: string name: string domain: string description: string @@ -15,6 +16,7 @@ export const DEFAULT_SETTINGS: Settings = { gamemode: 1, enableGamemodeVote: true, passwordRequired: false, + password: '', name: 'A Net64+ Server', domain: '', description: 'The **best** Net64+ server ever\n\n:unicorn_face:', diff --git a/src/proto/ClientServerMessage.d.ts b/src/proto/ClientServerMessage.d.ts index 23ba875..3c67070 100644 --- a/src/proto/ClientServerMessage.d.ts +++ b/src/proto/ClientServerMessage.d.ts @@ -126,8 +126,8 @@ export interface IClientServer { /** ClientServer player */ player?: (IPlayer|null); - /** ClientServer authentication */ - authentication?: (IAuthentication|null); + /** ClientServer authenticate */ + authenticate?: (IAuthenticate|null); /** ClientServer playerData */ playerData?: (IPlayerData|null); @@ -160,8 +160,8 @@ export class ClientServer implements IClientServer { /** ClientServer player. */ public player?: (IPlayer|null); - /** ClientServer authentication. */ - public authentication?: (IAuthentication|null); + /** ClientServer authenticate. */ + public authenticate?: (IAuthenticate|null); /** ClientServer playerData. */ public playerData?: (IPlayerData|null); @@ -173,7 +173,7 @@ export class ClientServer implements IClientServer { public chat?: (IChat|null); /** ClientServer message. */ - public message?: ("handshake"|"ping"|"player"|"authentication"|"playerData"|"metaData"|"chat"); + public message?: ("handshake"|"ping"|"player"|"authenticate"|"playerData"|"metaData"|"chat"); /** * Creates a new ClientServer instance using the specified properties. @@ -254,7 +254,7 @@ export namespace ClientServer { HANDSHAKE = 2, PING = 3, PLAYER_UPDATE = 6, - AUTHENTICATION = 7, + AUTHENTICATE = 7, PLAYER_DATA = 128, META_DATA = 129, CHAT = 130 @@ -549,91 +549,91 @@ export class Player implements IPlayer { public toJSON(): { [k: string]: any }; } -/** Properties of an Authentication. */ -export interface IAuthentication { +/** Properties of an Authenticate. */ +export interface IAuthenticate { - /** Authentication password */ + /** Authenticate password */ password?: (string|null); } -/** Represents an Authentication. */ -export class Authentication implements IAuthentication { +/** Represents an Authenticate. */ +export class Authenticate implements IAuthenticate { /** - * Constructs a new Authentication. + * Constructs a new Authenticate. * @param [properties] Properties to set */ - constructor(properties?: IAuthentication); + constructor(properties?: IAuthenticate); - /** Authentication password. */ + /** Authenticate password. */ public password: string; /** - * Creates a new Authentication instance using the specified properties. + * Creates a new Authenticate instance using the specified properties. * @param [properties] Properties to set - * @returns Authentication instance + * @returns Authenticate instance */ - public static create(properties?: IAuthentication): Authentication; + public static create(properties?: IAuthenticate): Authenticate; /** - * Encodes the specified Authentication message. Does not implicitly {@link Authentication.verify|verify} messages. - * @param message Authentication message or plain object to encode + * Encodes the specified Authenticate message. Does not implicitly {@link Authenticate.verify|verify} messages. + * @param message Authenticate message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: IAuthentication, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: IAuthenticate, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified Authentication message, length delimited. Does not implicitly {@link Authentication.verify|verify} messages. - * @param message Authentication message or plain object to encode + * Encodes the specified Authenticate message, length delimited. Does not implicitly {@link Authenticate.verify|verify} messages. + * @param message Authenticate message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: IAuthentication, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: IAuthenticate, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes an Authentication message from the specified reader or buffer. + * Decodes an Authenticate message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns Authentication + * @returns Authenticate * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Authentication; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): Authenticate; /** - * Decodes an Authentication message from the specified reader or buffer, length delimited. + * Decodes an Authenticate message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns Authentication + * @returns Authenticate * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Authentication; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): Authenticate; /** - * Verifies an Authentication message. + * Verifies an Authenticate message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates an Authentication message from a plain object. Also converts values to their respective internal types. + * Creates an Authenticate message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns Authentication + * @returns Authenticate */ - public static fromObject(object: { [k: string]: any }): Authentication; + public static fromObject(object: { [k: string]: any }): Authenticate; /** - * Creates a plain object from an Authentication message. Also converts values to other types if specified. - * @param message Authentication + * Creates a plain object from an Authenticate message. Also converts values to other types if specified. + * @param message Authenticate * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: Authentication, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: Authenticate, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this Authentication to JSON. + * Converts this Authenticate to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; diff --git a/src/proto/ClientServerMessage.js b/src/proto/ClientServerMessage.js index a6f577f..e08c4fa 100644 --- a/src/proto/ClientServerMessage.js +++ b/src/proto/ClientServerMessage.js @@ -325,7 +325,7 @@ $root.ClientServer = (function() { * @property {IClientHandshake|null} [handshake] ClientServer handshake * @property {IPing|null} [ping] ClientServer ping * @property {IPlayer|null} [player] ClientServer player - * @property {IAuthentication|null} [authentication] ClientServer authentication + * @property {IAuthenticate|null} [authenticate] ClientServer authenticate * @property {IPlayerData|null} [playerData] ClientServer playerData * @property {IMetaData|null} [metaData] ClientServer metaData * @property {IChat|null} [chat] ClientServer chat @@ -379,12 +379,12 @@ $root.ClientServer = (function() { ClientServer.prototype.player = null; /** - * ClientServer authentication. - * @member {IAuthentication|null|undefined} authentication + * ClientServer authenticate. + * @member {IAuthenticate|null|undefined} authenticate * @memberof ClientServer * @instance */ - ClientServer.prototype.authentication = null; + ClientServer.prototype.authenticate = null; /** * ClientServer playerData. @@ -415,12 +415,12 @@ $root.ClientServer = (function() { /** * ClientServer message. - * @member {"handshake"|"ping"|"player"|"authentication"|"playerData"|"metaData"|"chat"|undefined} message + * @member {"handshake"|"ping"|"player"|"authenticate"|"playerData"|"metaData"|"chat"|undefined} message * @memberof ClientServer * @instance */ Object.defineProperty(ClientServer.prototype, "message", { - get: $util.oneOfGetter($oneOfFields = ["handshake", "ping", "player", "authentication", "playerData", "metaData", "chat"]), + get: $util.oneOfGetter($oneOfFields = ["handshake", "ping", "player", "authenticate", "playerData", "metaData", "chat"]), set: $util.oneOfSetter($oneOfFields) }); @@ -456,8 +456,8 @@ $root.ClientServer = (function() { $root.Ping.encode(message.ping, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); if (message.player != null && message.hasOwnProperty("player")) $root.Player.encode(message.player, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); - if (message.authentication != null && message.hasOwnProperty("authentication")) - $root.Authentication.encode(message.authentication, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + if (message.authenticate != null && message.hasOwnProperty("authenticate")) + $root.Authenticate.encode(message.authenticate, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); if (message.playerData != null && message.hasOwnProperty("playerData")) $root.PlayerData.encode(message.playerData, writer.uint32(/* id 128, wireType 2 =*/1026).fork()).ldelim(); if (message.metaData != null && message.hasOwnProperty("metaData")) @@ -511,7 +511,7 @@ $root.ClientServer = (function() { message.player = $root.Player.decode(reader, reader.uint32()); break; case 7: - message.authentication = $root.Authentication.decode(reader, reader.uint32()); + message.authenticate = $root.Authenticate.decode(reader, reader.uint32()); break; case 128: message.playerData = $root.PlayerData.decode(reader, reader.uint32()); @@ -600,14 +600,14 @@ $root.ClientServer = (function() { return "player." + error; } } - if (message.authentication != null && message.hasOwnProperty("authentication")) { + if (message.authenticate != null && message.hasOwnProperty("authenticate")) { if (properties.message === 1) return "message: multiple values"; properties.message = 1; { - var error = $root.Authentication.verify(message.authentication); + var error = $root.Authenticate.verify(message.authenticate); if (error) - return "authentication." + error; + return "authenticate." + error; } } if (message.playerData != null && message.hasOwnProperty("playerData")) { @@ -672,7 +672,7 @@ $root.ClientServer = (function() { case 6: message.messageType = 6; break; - case "AUTHENTICATION": + case "AUTHENTICATE": case 7: message.messageType = 7; break; @@ -704,10 +704,10 @@ $root.ClientServer = (function() { throw TypeError(".ClientServer.player: object expected"); message.player = $root.Player.fromObject(object.player); } - if (object.authentication != null) { - if (typeof object.authentication !== "object") - throw TypeError(".ClientServer.authentication: object expected"); - message.authentication = $root.Authentication.fromObject(object.authentication); + if (object.authenticate != null) { + if (typeof object.authenticate !== "object") + throw TypeError(".ClientServer.authenticate: object expected"); + message.authenticate = $root.Authenticate.fromObject(object.authenticate); } if (object.playerData != null) { if (typeof object.playerData !== "object") @@ -759,10 +759,10 @@ $root.ClientServer = (function() { if (options.oneofs) object.message = "player"; } - if (message.authentication != null && message.hasOwnProperty("authentication")) { - object.authentication = $root.Authentication.toObject(message.authentication, options); + if (message.authenticate != null && message.hasOwnProperty("authenticate")) { + object.authenticate = $root.Authenticate.toObject(message.authenticate, options); if (options.oneofs) - object.message = "authentication"; + object.message = "authenticate"; } if (message.playerData != null && message.hasOwnProperty("playerData")) { object.playerData = $root.PlayerData.toObject(message.playerData, options); @@ -801,7 +801,7 @@ $root.ClientServer = (function() { * @property {number} HANDSHAKE=2 HANDSHAKE value * @property {number} PING=3 PING value * @property {number} PLAYER_UPDATE=6 PLAYER_UPDATE value - * @property {number} AUTHENTICATION=7 AUTHENTICATION value + * @property {number} AUTHENTICATE=7 AUTHENTICATE value * @property {number} PLAYER_DATA=128 PLAYER_DATA value * @property {number} META_DATA=129 META_DATA value * @property {number} CHAT=130 CHAT value @@ -812,7 +812,7 @@ $root.ClientServer = (function() { values[valuesById[2] = "HANDSHAKE"] = 2; values[valuesById[3] = "PING"] = 3; values[valuesById[6] = "PLAYER_UPDATE"] = 6; - values[valuesById[7] = "AUTHENTICATION"] = 7; + values[valuesById[7] = "AUTHENTICATE"] = 7; values[valuesById[128] = "PLAYER_DATA"] = 128; values[valuesById[129] = "META_DATA"] = 129; values[valuesById[130] = "CHAT"] = 130; @@ -1446,24 +1446,24 @@ $root.Player = (function() { return Player; })(); -$root.Authentication = (function() { +$root.Authenticate = (function() { /** - * Properties of an Authentication. - * @exports IAuthentication - * @interface IAuthentication - * @property {string|null} [password] Authentication password + * Properties of an Authenticate. + * @exports IAuthenticate + * @interface IAuthenticate + * @property {string|null} [password] Authenticate password */ /** - * Constructs a new Authentication. - * @exports Authentication - * @classdesc Represents an Authentication. - * @implements IAuthentication + * Constructs a new Authenticate. + * @exports Authenticate + * @classdesc Represents an Authenticate. + * @implements IAuthenticate * @constructor - * @param {IAuthentication=} [properties] Properties to set + * @param {IAuthenticate=} [properties] Properties to set */ - function Authentication(properties) { + function Authenticate(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -1471,35 +1471,35 @@ $root.Authentication = (function() { } /** - * Authentication password. + * Authenticate password. * @member {string} password - * @memberof Authentication + * @memberof Authenticate * @instance */ - Authentication.prototype.password = ""; + Authenticate.prototype.password = ""; /** - * Creates a new Authentication instance using the specified properties. + * Creates a new Authenticate instance using the specified properties. * @function create - * @memberof Authentication + * @memberof Authenticate * @static - * @param {IAuthentication=} [properties] Properties to set - * @returns {Authentication} Authentication instance + * @param {IAuthenticate=} [properties] Properties to set + * @returns {Authenticate} Authenticate instance */ - Authentication.create = function create(properties) { - return new Authentication(properties); + Authenticate.create = function create(properties) { + return new Authenticate(properties); }; /** - * Encodes the specified Authentication message. Does not implicitly {@link Authentication.verify|verify} messages. + * Encodes the specified Authenticate message. Does not implicitly {@link Authenticate.verify|verify} messages. * @function encode - * @memberof Authentication + * @memberof Authenticate * @static - * @param {IAuthentication} message Authentication message or plain object to encode + * @param {IAuthenticate} message Authenticate message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - Authentication.encode = function encode(message, writer) { + Authenticate.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.password != null && message.hasOwnProperty("password")) @@ -1508,33 +1508,33 @@ $root.Authentication = (function() { }; /** - * Encodes the specified Authentication message, length delimited. Does not implicitly {@link Authentication.verify|verify} messages. + * Encodes the specified Authenticate message, length delimited. Does not implicitly {@link Authenticate.verify|verify} messages. * @function encodeDelimited - * @memberof Authentication + * @memberof Authenticate * @static - * @param {IAuthentication} message Authentication message or plain object to encode + * @param {IAuthenticate} message Authenticate message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - Authentication.encodeDelimited = function encodeDelimited(message, writer) { + Authenticate.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes an Authentication message from the specified reader or buffer. + * Decodes an Authenticate message from the specified reader or buffer. * @function decode - * @memberof Authentication + * @memberof Authenticate * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {Authentication} Authentication + * @returns {Authenticate} Authenticate * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - Authentication.decode = function decode(reader, length) { + Authenticate.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.Authentication(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.Authenticate(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { @@ -1550,30 +1550,30 @@ $root.Authentication = (function() { }; /** - * Decodes an Authentication message from the specified reader or buffer, length delimited. + * Decodes an Authenticate message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof Authentication + * @memberof Authenticate * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {Authentication} Authentication + * @returns {Authenticate} Authenticate * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - Authentication.decodeDelimited = function decodeDelimited(reader) { + Authenticate.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies an Authentication message. + * Verifies an Authenticate message. * @function verify - * @memberof Authentication + * @memberof Authenticate * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - Authentication.verify = function verify(message) { + Authenticate.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.password != null && message.hasOwnProperty("password")) @@ -1583,32 +1583,32 @@ $root.Authentication = (function() { }; /** - * Creates an Authentication message from a plain object. Also converts values to their respective internal types. + * Creates an Authenticate message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof Authentication + * @memberof Authenticate * @static * @param {Object.} object Plain object - * @returns {Authentication} Authentication + * @returns {Authenticate} Authenticate */ - Authentication.fromObject = function fromObject(object) { - if (object instanceof $root.Authentication) + Authenticate.fromObject = function fromObject(object) { + if (object instanceof $root.Authenticate) return object; - var message = new $root.Authentication(); + var message = new $root.Authenticate(); if (object.password != null) message.password = String(object.password); return message; }; /** - * Creates a plain object from an Authentication message. Also converts values to other types if specified. + * Creates a plain object from an Authenticate message. Also converts values to other types if specified. * @function toObject - * @memberof Authentication + * @memberof Authenticate * @static - * @param {Authentication} message Authentication + * @param {Authenticate} message Authenticate * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - Authentication.toObject = function toObject(message, options) { + Authenticate.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; @@ -1620,17 +1620,17 @@ $root.Authentication = (function() { }; /** - * Converts this Authentication to JSON. + * Converts this Authenticate to JSON. * @function toJSON - * @memberof Authentication + * @memberof Authenticate * @instance * @returns {Object.} JSON object */ - Authentication.prototype.toJSON = function toJSON() { + Authenticate.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return Authentication; + return Authenticate; })(); $root.PlayerData = (function() {