sshlogin.js 6.8 KB

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