chore: Restructure keyboard reading.
This commit is contained in:
parent
c25e7badcd
commit
41d37048d2
1 changed files with 81 additions and 70 deletions
143
lom/src/index.ts
143
lom/src/index.ts
|
@ -18,6 +18,66 @@ const axios = baseAxios.create({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function readFromKeyboard(stream: ssh2.ServerChannel): Promise<any> {
|
||||||
|
let line = "";
|
||||||
|
let lineIndex = 0;
|
||||||
|
let isReady = false;
|
||||||
|
|
||||||
|
async function eventLoop(): Promise<any> {
|
||||||
|
const readStreamData = stream.read();
|
||||||
|
if (readStreamData == null) return setTimeout(eventLoop, 5);
|
||||||
|
|
||||||
|
if (readStreamData.includes("\r") || readStreamData.includes("\n")) {
|
||||||
|
line = line.replace("\r", "");
|
||||||
|
isReady = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (readStreamData.includes("\x7F")) {
|
||||||
|
// \x7F = Ascii escape code for backspace (client side)
|
||||||
|
if (line == "" || line == "\r") return setTimeout(eventLoop, 5);
|
||||||
|
|
||||||
|
line = line.substring(0, line.length - 1);
|
||||||
|
|
||||||
|
// Ascii escape code for backspace (server side)
|
||||||
|
stream.write("\u0008 \u0008");
|
||||||
|
} else if (readStreamData.includes("\x1B")) {
|
||||||
|
const leftEscape = "\x1B[D";
|
||||||
|
const rightEscape = "\x1B[C";
|
||||||
|
|
||||||
|
if (readStreamData.includes(rightEscape)) {
|
||||||
|
if (lineIndex + 1 > line.length) return setTimeout(eventLoop, 5);
|
||||||
|
lineIndex += 1;
|
||||||
|
} else if (readStreamData.includes(leftEscape)) {
|
||||||
|
if (lineIndex - 1 < 0) return setTimeout(eventLoop, 5);
|
||||||
|
lineIndex -= 1;
|
||||||
|
} else {
|
||||||
|
return setTimeout(eventLoop, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.write(readStreamData);
|
||||||
|
} else {
|
||||||
|
lineIndex += readStreamData.length;
|
||||||
|
|
||||||
|
// There isn't a splice method for String prototypes. So, ugh:
|
||||||
|
line = line.substring(0, lineIndex - 1) + readStreamData + line.substring(lineIndex + readStreamData.length, line.length);
|
||||||
|
stream.write(readStreamData);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(eventLoop, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yes, this is bad practice. Currently, I don't care.
|
||||||
|
return new Promise(async(resolve) => {
|
||||||
|
eventLoop();
|
||||||
|
|
||||||
|
while (!isReady) {
|
||||||
|
await new Promise((i) => setTimeout(i, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(line);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
keyFile = await readFile("../keys/host.key");
|
keyFile = await readFile("../keys/host.key");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -77,83 +137,34 @@ server.on("connection", client => {
|
||||||
"Welcome to NextNet LOM. Run 'help' to see commands.\r\n\r\n~$ ",
|
"Welcome to NextNet LOM. Run 'help' to see commands.\r\n\r\n~$ ",
|
||||||
);
|
);
|
||||||
|
|
||||||
let line = "";
|
|
||||||
let lineIndex = 0;
|
|
||||||
|
|
||||||
function println(...str: string[]) {
|
function println(...str: string[]) {
|
||||||
stream.write(str.join(" ").replace("\n", "\r\n"));
|
stream.write(str.join(" ").replace("\n", "\r\n"));
|
||||||
}
|
};
|
||||||
|
|
||||||
async function eventLoop(): Promise<any> {
|
while (true) {
|
||||||
const readStreamData = stream.read();
|
const line = await readFromKeyboard(stream);
|
||||||
if (readStreamData == null) return setTimeout(eventLoop, 5);
|
stream.write("\r\n");
|
||||||
|
|
||||||
if (readStreamData.includes("\r") || readStreamData.includes("\n")) {
|
if (line == "") continue;
|
||||||
line = line.replace("\r", "");
|
const argv = parseArgsStringToArgv(line);
|
||||||
|
|
||||||
if (line == "") {
|
if (argv[0] == "exit") {
|
||||||
stream.write(`\r\n~$ `);
|
stream.close();
|
||||||
return setTimeout(eventLoop, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
const argv = parseArgsStringToArgv(line);
|
|
||||||
line = "";
|
|
||||||
lineIndex = 0;
|
|
||||||
|
|
||||||
if (argv[0] == "exit") {
|
|
||||||
stream.close();
|
|
||||||
} else {
|
|
||||||
stream.write("\r\n");
|
|
||||||
const command = commands.find(i => i.name == argv[0]);
|
|
||||||
|
|
||||||
if (!command) {
|
|
||||||
stream.write(
|
|
||||||
`Unknown command ${argv[0]}. Run 'help' to see commands.\r\n~$ `,
|
|
||||||
);
|
|
||||||
return setTimeout(eventLoop, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
await command.run(argv, println, axios, token);
|
|
||||||
stream.write(`~$ `);
|
|
||||||
}
|
|
||||||
} else if (readStreamData.includes("\x7F")) {
|
|
||||||
// \x7F = Ascii escape code for backspace (client side)
|
|
||||||
if (line == "" || line == "\r") return setTimeout(eventLoop, 5);
|
|
||||||
|
|
||||||
line = line.substring(0, line.length - 1);
|
|
||||||
|
|
||||||
// Ascii escape code for backspace (server side)
|
|
||||||
stream.write("\u0008 \u0008");
|
|
||||||
} else if (readStreamData.includes("\x1B")) {
|
|
||||||
const leftEscape = "\x1B[D";
|
|
||||||
const rightEscape = "\x1B[C";
|
|
||||||
|
|
||||||
if (readStreamData.includes(rightEscape)) {
|
|
||||||
if (lineIndex + 1 > line.length) return setTimeout(eventLoop, 5);
|
|
||||||
lineIndex += 1;
|
|
||||||
} else if (readStreamData.includes(leftEscape)) {
|
|
||||||
if (lineIndex - 1 < 0) return setTimeout(eventLoop, 5);
|
|
||||||
lineIndex -= 1;
|
|
||||||
} else {
|
|
||||||
return setTimeout(eventLoop, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.write(readStreamData);
|
|
||||||
} else {
|
} else {
|
||||||
lineIndex += readStreamData.length;
|
const command = commands.find(i => i.name == argv[0]);
|
||||||
|
|
||||||
// There isn't a splice method for String prototypes. So, ugh:
|
if (!command) {
|
||||||
line = line.substring(0, lineIndex - 1) + readStreamData + line.substring(lineIndex + readStreamData.length, line.length);
|
stream.write(
|
||||||
|
`Unknown command ${argv[0]}. Run 'help' to see commands.\r\n~$ `,
|
||||||
|
);
|
||||||
|
|
||||||
console.log(line);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
stream.write(readStreamData);
|
await command.run(argv, println, axios, token);
|
||||||
|
stream.write(`~$ `);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(eventLoop, 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eventLoop();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue