module.exports = class SSHLogin { constructor() { this.awaitUsername = false; this.awaitPassword = false; this.username = ""; this.password = ""; this.loggedIn = false; this.player = null; this.failCount = 0; this.inputBuffer = []; this.inputHistory = []; this.isReconnecting = false; this.reconnectLogin = null; this.cursorPos = 0; this.historyPos = 0; } attachChannel(channel) { this.socket = channel; } attach(userData) { this.socket.write(config.welcomeBanner.replace(/\n/g, "\r\n") + "\r\n"); world.mud_playerLoad(this, userData); this.loggedIn = true; } receive(data) { if(this.handleSpecialKeys(data)) { return; } //typing output if(data == "\x7f") { //backspace this.inputBuffer.splice(--this.cursorPos, 1); this.socket.write("\r" + " ".repeat(80)); } else if(data == "\x1b\x5b\x33\x7e") { //delete this.inputBuffer.splice(this.cursorPos, 1); this.socket.write("\r" + " ".repeat(80)); } else if(data == "\x0d") { //mute return this.inputBuffer.push(data.toString()); } else { this.inputBuffer[this.cursorPos++] = data.toString(); } this.socket.write("\r"); this.socket.write(this.inputBuffer.join("")); this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos)); if(!(this.inputBuffer.join("").indexOf("\r\n") != -1 || this.inputBuffer.join("").indexOf("\n") != -1 || this.inputBuffer.join("").indexOf("\r") != -1)) { //did not see a return char, keep building buffer return; } this.inputBuffer = this.inputBuffer.join("").replace("\r", "").split(""); this.inputBuffer = this.inputBuffer.join("").replace("\n", "").split(""); var input = this.inputBuffer.join("").toString().trim().split(" "); this.inputHistory.push(""+input.join(" ")); this.historyPos = this.inputHistory.length; this.inputBuffer = []; //local echo this.socket.write(this.inputBuffer.join("") + "\r\n"); this.receivePlayer(input); this.cursorPos = 0; } handleSpecialKeys(data) { if(data == "\x03") { //ctrl + c this.logout(); return true; } if(data == "\x1b\x5b\x41") { //up this.historyPos = Math.max(0, this.historyPos-1); this.inputBuffer = this.inputHistory[this.historyPos].split(""); this.cursorPos = this.inputBuffer.length; this.socket.write("\r" + " ".repeat(80)); this.socket.write("\r"); this.socket.write(this.inputBuffer.join("")); this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos)); return true; } if(data == "\x1b\x5b\x42") { //down this.historyPos = Math.min(this.inputHistory.length, this.historyPos+1); if(this.historyPos < this.inputHistory.length) { this.inputBuffer = this.inputHistory[this.historyPos].split(""); } else { this.inputBuffer = []; } this.cursorPos = this.inputBuffer.length; this.socket.write("\r" + " ".repeat(80)); this.socket.write("\r"); this.socket.write(this.inputBuffer.join("")); this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos)); return true; } if(data == "\x1b\x5b\x44") { //left this.cursorPos = Math.max(0, this.cursorPos-1); this.socket.write("\b"); return true; } if(data == "\x1b\x5b\x43") { //right this.cursorPos = Math.min(this.inputBuffer.length, this.cursorPos+1); this.socket.write(this.inputBuffer[this.cursorPos-1]); return true; } if(data == "\x1b\x5b\x48") {//home this.cursorPos = 0; return true; } if(data == "\x1b\x5b\x46") {//end this.cursorPos = this.inputBuffer.length; return true; } return false; } sendMessage(message){ var terminalWidthPreference = (!this.player.hasOwnProperty("terminalWidthPreference") || this.player.terminalWidthPreference == null) ? 78 : this.player.terminalWidthPreference; var hintColor = (!this.player.hasOwnProperty("hintColor") || this.player.hintColor == null) ? libs.Color.FgMagenta : libs.Color[this.player.hintColor]; var simpleMessage = message.replace(/\{.*?\}/g, ""); message = libs.Color.Reset + message; message = message.replace(/\{hint\}/g, hintColor); message = message.replace(/\{\/hint\}/g, libs.Color.Reset); message = message.replace(/\{mobile\}/g, libs.Color.FgYellow); message = message.replace(/\{\/mobile\}/g, libs.Color.Reset); message = message.replace(/\{item\}/g, libs.Color.FgGreen); message = message.replace(/\{\/item\}/g, libs.Color.Reset); message = message.replace(/\{error\}/g, libs.Color.FgRed); message = message.replace(/\{\/error\}/g, libs.Color.Reset); message = message.replace(/\{global\}/g, libs.Color.FgCyan); message = message.replace(/\{\/global\}/g, libs.Color.Reset); message = message.replace(/\{red\}/g, libs.Color.FgRed); message = message.replace(/\{\/red\}/g, libs.Color.Reset); message = message.replace(/\{green\}/g, libs.Color.FgGreen); message = message.replace(/\{\/green\}/g, libs.Color.Reset); message = message.replace(/\{yellow\}/g, libs.Color.FgYellow); message = message.replace(/\{\/yellow\}/g, libs.Color.Reset); message = message.replace(/\{blue\}/g, libs.Color.FgBlue); message = message.replace(/\{\/blue\}/g, libs.Color.Reset); message = message.replace(/\{magenta\}/g, libs.Color.FgMagenta); message = message.replace(/\{\/magenta\}/g, libs.Color.Reset); message = message.replace(/\{cyan\}/g, libs.Color.FgCyan); message = message.replace(/\{\/cyan\}/g, libs.Color.Reset); message = message.replace(/\{.*?\}/g, ""); var buffer = [], colorBuffer = []; buffer = simpleMessage.split(" "); colorBuffer = message.split(" "); while(buffer.length > 0) { var wrapString = buffer.shift(); var displayString = colorBuffer.shift(); if(buffer.length > 0) { while(wrapString.length + buffer[0].length < terminalWidthPreference) { wrapString += " " + buffer.shift(); displayString += " " + colorBuffer.shift(); if(buffer.length == 0) { break; } } } this.socket.write(displayString + "\r\n"); } //this.socket.write("\r"); //this.socket.write(this.inputBuffer.join("")); //this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos)); } disconnect() { if(this.isReconnecting) { this.player.login = this.reconnectLogin; this.isReconnecting = false; this.socket = null; this.loggedIn = false; libs.Output.toMobile(this.player.id, "Reconnecting to existing session..."); world.mud_handleInput(this.player.roomId, this.player.id, ["look"]); return; } if(this.loggedIn) { world.mud_playerQuit(this.player); this.socket = null; this.loggedIn = false; } } receivePlayer(input) { if(this.isReconnecting || !this.loggedIn) { return; } world.mud_handleInput(this.player.roomId, this.player.id, input); } setConnectionTimeout(time) { //this.socket.setTimeout(time); } logout() { this.socket.close(); } reconnect(newLogin) { this.socket.close(); this.isReconnecting = true; this.reconnectLogin = newLogin; } disconnect() { } };