sshlogin.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. module.exports = class SSHLogin {
  2. constructor(socket) {
  3. this.socket = socket;
  4. this.awaitUsername = false;
  5. this.awaitPassword = false;
  6. this.username = "";
  7. this.password = "";
  8. this.loggedIn = false;
  9. this.player = null;
  10. this.failCount = 0;
  11. this.inputBuffer = [];
  12. this.inputHistory = [];
  13. this.isReconnecting = false;
  14. this.reconnectLogin = null;
  15. this.cursorPos = 0;
  16. this.historyPos = 0;
  17. }
  18. attach(userData) {
  19. this.socket.write(config.welcomeBanner.replace(/\n/g, "\r\n") + "\r\n");
  20. world.mud_playerLoad(this, userData);
  21. this.loggedIn = true;
  22. }
  23. receive(data) {
  24. if(this.handleSpecialKeys(data)) {
  25. return;
  26. }
  27. //typing output
  28. if(data == "\x7f") { //backspace
  29. this.inputBuffer.splice(--this.cursorPos, 1);
  30. this.socket.write("\r" + " ".repeat(80));
  31. } else if(data == "\x1b\x5b\x33\x7e") { //delete
  32. this.inputBuffer.splice(this.cursorPos, 1);
  33. this.socket.write("\r" + " ".repeat(80));
  34. } else if(data == "\x0d") {
  35. //mute return
  36. this.inputBuffer.push(data.toString());
  37. } else {
  38. this.inputBuffer[this.cursorPos++] = data.toString();
  39. }
  40. this.socket.write("\r");
  41. this.socket.write(this.inputBuffer.join(""));
  42. this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos));
  43. if(!(this.inputBuffer.join("").indexOf("\r\n") != -1 || this.inputBuffer.join("").indexOf("\n") != -1 || this.inputBuffer.join("").indexOf("\r") != -1)) {
  44. //did not see a return char, keep building buffer
  45. return;
  46. }
  47. this.inputBuffer = this.inputBuffer.join("").replace("\r", "").split("");
  48. this.inputBuffer = this.inputBuffer.join("").replace("\n", "").split("");
  49. var input = this.inputBuffer.join("").toString().trim().split(" ");
  50. this.inputHistory.push(""+input.join(" "));
  51. this.historyPos = this.inputHistory.length;
  52. this.inputBuffer = [];
  53. //local echo
  54. this.socket.write(this.inputBuffer.join("") + "\r\n");
  55. this.receivePlayer(input);
  56. this.cursorPos = 0;
  57. }
  58. handleSpecialKeys(data) {
  59. if(data == "\x03") { //ctrl + c
  60. this.logout();
  61. return true;
  62. }
  63. if(data == "\x1b\x5b\x41") { //up
  64. this.historyPos = Math.max(0, this.historyPos-1);
  65. this.inputBuffer = this.inputHistory[this.historyPos].split("");
  66. this.cursorPos = this.inputBuffer.length;
  67. this.socket.write("\r" + " ".repeat(80));
  68. this.socket.write("\r");
  69. this.socket.write(this.inputBuffer.join(""));
  70. this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos));
  71. return true;
  72. }
  73. if(data == "\x1b\x5b\x42") { //down
  74. this.historyPos = Math.min(this.inputHistory.length, this.historyPos+1);
  75. if(this.historyPos < this.inputHistory.length) {
  76. this.inputBuffer = this.inputHistory[this.historyPos].split("");
  77. } else {
  78. this.inputBuffer = [];
  79. }
  80. this.cursorPos = this.inputBuffer.length;
  81. this.socket.write("\r" + " ".repeat(80));
  82. this.socket.write("\r");
  83. this.socket.write(this.inputBuffer.join(""));
  84. this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos));
  85. return true;
  86. }
  87. if(data == "\x1b\x5b\x44") { //left
  88. this.cursorPos = Math.max(0, this.cursorPos-1);
  89. this.socket.write("\b");
  90. return true;
  91. }
  92. if(data == "\x1b\x5b\x43") { //right
  93. this.cursorPos = Math.min(this.inputBuffer.length, this.cursorPos+1);
  94. this.socket.write(this.inputBuffer[this.cursorPos-1]);
  95. return true;
  96. }
  97. if(data == "\x1b\x5b\x48") {//home
  98. this.cursorPos = 0;
  99. return true;
  100. }
  101. if(data == "\x1b\x5b\x46") {//end
  102. this.cursorPos = this.inputBuffer.length;
  103. return true;
  104. }
  105. return false;
  106. }
  107. sendMessage(message){
  108. var terminalWidthPreference = (!this.player.hasOwnProperty("terminalWidthPreference") || this.player.terminalWidthPreference == null) ? 78 : this.player.terminalWidthPreference;
  109. var hintColor = (!this.player.hasOwnProperty("hintColor") || this.player.hintColor == null) ? libs.Color.FgMagenta : libs.Color[this.player.hintColor];
  110. var simpleMessage = message.replace(/\{.*?\}/g, "");
  111. message = libs.Color.Reset + message;
  112. message = message.replace(/\{hint\}/g, hintColor);
  113. message = message.replace(/\{\/hint\}/g, libs.Color.Reset);
  114. message = message.replace(/\{mobile\}/g, libs.Color.FgYellow);
  115. message = message.replace(/\{\/mobile\}/g, libs.Color.Reset);
  116. message = message.replace(/\{item\}/g, libs.Color.FgGreen);
  117. message = message.replace(/\{\/item\}/g, libs.Color.Reset);
  118. message = message.replace(/\{error\}/g, libs.Color.FgRed);
  119. message = message.replace(/\{\/error\}/g, libs.Color.Reset);
  120. message = message.replace(/\{global\}/g, libs.Color.FgCyan);
  121. message = message.replace(/\{\/global\}/g, libs.Color.Reset);
  122. message = message.replace(/\{red\}/g, libs.Color.FgRed);
  123. message = message.replace(/\{\/red\}/g, libs.Color.Reset);
  124. message = message.replace(/\{green\}/g, libs.Color.FgGreen);
  125. message = message.replace(/\{\/green\}/g, libs.Color.Reset);
  126. message = message.replace(/\{yellow\}/g, libs.Color.FgYellow);
  127. message = message.replace(/\{\/yellow\}/g, libs.Color.Reset);
  128. message = message.replace(/\{blue\}/g, libs.Color.FgBlue);
  129. message = message.replace(/\{\/blue\}/g, libs.Color.Reset);
  130. message = message.replace(/\{magenta\}/g, libs.Color.FgMagenta);
  131. message = message.replace(/\{\/magenta\}/g, libs.Color.Reset);
  132. message = message.replace(/\{cyan\}/g, libs.Color.FgCyan);
  133. message = message.replace(/\{\/cyan\}/g, libs.Color.Reset);
  134. message = message.replace(/\{.*?\}/g, "");
  135. var buffer = [], colorBuffer = [];
  136. buffer = simpleMessage.split(" ");
  137. colorBuffer = message.split(" ");
  138. while(buffer.length > 0) {
  139. var wrapString = buffer.shift();
  140. var displayString = colorBuffer.shift();
  141. if(buffer.length > 0) {
  142. while(wrapString.length + buffer[0].length < terminalWidthPreference) {
  143. wrapString += " " + buffer.shift();
  144. displayString += " " + colorBuffer.shift();
  145. if(buffer.length == 0) {
  146. break;
  147. }
  148. }
  149. }
  150. this.socket.write(displayString + "\r\n");
  151. }
  152. //this.socket.write("\r");
  153. //this.socket.write(this.inputBuffer.join(""));
  154. //this.socket.write("\b".repeat(this.inputBuffer.length - this.cursorPos));
  155. }
  156. disconnect() {
  157. if(this.isReconnecting) {
  158. this.player.login = this.reconnectLogin;
  159. this.isReconnecting = false;
  160. this.socket = null;
  161. this.loggedIn = false;
  162. libs.Output.toMobile(this.player.id, "Reconnecting to existing session...");
  163. world.mud_handleInput(this.player.roomId, this.player.id, ["look"]);
  164. return;
  165. }
  166. if(this.loggedIn) {
  167. world.mud_playerQuit(this.player);
  168. this.socket = null;
  169. this.loggedIn = false;
  170. }
  171. }
  172. receivePlayer(input) {
  173. if(this.isReconnecting || !this.loggedIn) {
  174. return;
  175. }
  176. world.mud_handleInput(this.player.roomId, this.player.id, input);
  177. }
  178. setConnectionTimeout(time) {
  179. //this.socket.setTimeout(time);
  180. }
  181. logout() {
  182. this.socket.close();
  183. }
  184. reconnect(newLogin) {
  185. this.socket.close();
  186. this.isReconnecting = true;
  187. this.reconnectLogin = newLogin;
  188. }
  189. };