Things and støff
This commit is contained in:
@@ -1,19 +1,6 @@
|
||||
import { mustBe, mustBeInteger, mustBeString, mustMatch } from "./mustbe.js";
|
||||
import { mustBe, mustBeString, mustMatch } from "./mustbe.js";
|
||||
|
||||
const colonCommandRegex = /^:([a-z0-9_]+)(:?\s*(.*))?$/;
|
||||
|
||||
/**
|
||||
* Enum-like object holding placeholder tokens.
|
||||
*
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const MsgContext = Object.freeze({
|
||||
PASSWORD: ":password",
|
||||
USERNAME: ":username",
|
||||
});
|
||||
|
||||
export const MsgTtype = Object.freeze({
|
||||
export const MessageType = Object.freeze({
|
||||
/**
|
||||
* Very bad logic error. Player must quit game, refresh page, and log in again.
|
||||
*
|
||||
@@ -28,7 +15,7 @@ export const MsgTtype = Object.freeze({
|
||||
*
|
||||
* Server-->Client-->Player
|
||||
*/
|
||||
MsgContext.ERROR: "E",
|
||||
ERROR: "E",
|
||||
|
||||
/**
|
||||
* Message to be displayed.
|
||||
@@ -42,7 +29,7 @@ export const MsgTtype = Object.freeze({
|
||||
*
|
||||
* Player-->Client-->Server
|
||||
*/
|
||||
MsgContext.REPLY: "R",
|
||||
REPLY: "R",
|
||||
|
||||
/**
|
||||
* Player wants to quit.
|
||||
@@ -93,7 +80,7 @@ export const MsgTtype = Object.freeze({
|
||||
* Represents a message sent to/from client
|
||||
*
|
||||
* @property {string?} command
|
||||
* @property {string?} argLine
|
||||
* @property {any[]} args
|
||||
*/
|
||||
export class WebsocketMessage {
|
||||
/** @protected @type {any[]} _arr The array that contains the message data */
|
||||
@@ -136,22 +123,22 @@ export class WebsocketMessage {
|
||||
this.type = mustBeString(data[0]);
|
||||
|
||||
switch (this.type) {
|
||||
case MsgContext.REPLY: // player ==> client ==> server
|
||||
case MessageType.REPLY: // player ==> client ==> server
|
||||
this.text = mustBeString(data[1]);
|
||||
break;
|
||||
case HELP: // player ==> client ==> server
|
||||
case MessageType.HELP: // player ==> client ==> server
|
||||
this.text = data[1] === undefined ? "" : mustBeString(data[1]).trim();
|
||||
break;
|
||||
case COLON: // player ==> client ==> server
|
||||
case MessageType.COLON: // player ==> client ==> server
|
||||
this.command = mustMatch(data[1], /^[a-z0-9_]+$/);
|
||||
this.argLine = data[2]; // parse??
|
||||
this.args = mustBe(data[2], "any[]");
|
||||
break;
|
||||
case DEBUG: // server ==> client
|
||||
case MsgContext.ERROR: // server ==> client ==> player
|
||||
case QUIT: // player ==> client ==> server
|
||||
case SYSTEM: // client <==> server
|
||||
case PROMPT: // server ==> client ==> player
|
||||
case TEXT: // server ==> client ==> player
|
||||
case MessageType.DEBUG: // server ==> client
|
||||
case MessageType.ERROR: // server ==> client ==> player
|
||||
case MessageType.QUIT: // player ==> client ==> server
|
||||
case MessageType.SYSTEM: // client <==> server
|
||||
case MessageType.PROMPT: // server ==> client ==> player
|
||||
case MessageType.TEXT: // server ==> client ==> player
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown message type: >>${typeof this.type}<<`);
|
||||
@@ -159,27 +146,27 @@ export class WebsocketMessage {
|
||||
}
|
||||
|
||||
isQuit() {
|
||||
return this.type === QUIT;
|
||||
return this.type === MessageType.QUIT;
|
||||
}
|
||||
|
||||
isHelp() {
|
||||
return this.type === HELP;
|
||||
return this.type === MessageType.HELP;
|
||||
}
|
||||
|
||||
isColon() {
|
||||
return this.type === COLON;
|
||||
return this.type === MessageType.COLON;
|
||||
}
|
||||
|
||||
isReply() {
|
||||
return this.type === MsgContext.REPLY;
|
||||
return this.type === MessageType.REPLY;
|
||||
}
|
||||
|
||||
isSysMessage() {
|
||||
return this.type === SYSTEM;
|
||||
return this.type === MessageType.SYSTEM;
|
||||
}
|
||||
|
||||
isDebug() {
|
||||
return this.type === DEBUG;
|
||||
return this.type === MessageType.DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +176,6 @@ export class WebsocketMessage {
|
||||
* @param {string} messageType
|
||||
* @param {...any} args
|
||||
*/
|
||||
export function prepareToSend(messageType, ...args) {
|
||||
export function formatMessage(messageType, ...args) {
|
||||
return JSON.stringify([messageType, ...args]);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,14 @@ export function mustBe(value, ...types) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const isArray = Array.isArray(value);
|
||||
|
||||
if (isArray && (types.includes("any[]") || types.includes("array"))) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// NOTE: only checks first element of array if it's a string.
|
||||
if (types.includes("strings[]") && Array.isArray(value) && (value.length === 0 || typeof value[0] === "string")) {
|
||||
if (isArray && types.includes("strings[]") && (value.length === 0 || typeof value[0] === "string")) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -24,12 +30,6 @@ export function mustBeString(value) {
|
||||
return mustBe(value, "string");
|
||||
}
|
||||
|
||||
export function mustBeInteger(value) {
|
||||
if (typeof value === "number" && Number.isSafeInteger(value)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} str
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
import { mustBeString } from "./mustbe.js";
|
||||
|
||||
/**
|
||||
* Parse a command string into arguments. For use with colon-commands.
|
||||
*
|
||||
* @param {string} cmdString;
|
||||
* @returns {(string|number)[]} Command arguments
|
||||
*/
|
||||
export function parseArgs(cmdString) {
|
||||
mustBeString(cmdString);
|
||||
const args = [];
|
||||
const quoteChars = ["'", '"', "`"];
|
||||
const backslash = "\\";
|
||||
|
||||
let currentArg = ""; // The arg we are currently constructing
|
||||
let inQuotes = false; // are we inside quotes of some kind?
|
||||
let currentQuoteChar = ""; // if were in quotes, which are they?
|
||||
|
||||
const push = (value) => {
|
||||
const n = Number(value);
|
||||
if (Number.isSafeInteger(n)) {
|
||||
args.push(n);
|
||||
} else if (Number.isFinite(n)) {
|
||||
args.push(n);
|
||||
} else {
|
||||
args.push(value);
|
||||
}
|
||||
};
|
||||
|
||||
for (let i = 0; i < cmdString.length; i++) {
|
||||
const char = cmdString[i];
|
||||
const nextChar = cmdString[i + 1];
|
||||
|
||||
if (!inQuotes) {
|
||||
// Not in quotes - look for quote start or whitespace
|
||||
if (quoteChars.includes(char)) {
|
||||
inQuotes = true;
|
||||
currentQuoteChar = char;
|
||||
} else if (char === " " || char === "\t") {
|
||||
// Whitespace - end current arg if it exists
|
||||
if (currentArg) {
|
||||
push(currentArg);
|
||||
currentArg = "";
|
||||
}
|
||||
// Skip multiple whitespace
|
||||
while (cmdString[i + 1] === " " || cmdString[i + 1] === "\t") i++;
|
||||
} else {
|
||||
currentArg += char;
|
||||
}
|
||||
} else {
|
||||
// Inside quotes
|
||||
if (char === currentQuoteChar) {
|
||||
// Found matching quote - end quoted section
|
||||
inQuotes = false;
|
||||
currentQuoteChar = "";
|
||||
} else if (char === backslash && (nextChar === currentQuoteChar || nextChar === backslash)) {
|
||||
// Escape sequence - add the escaped character
|
||||
currentArg += nextChar;
|
||||
//
|
||||
// Todo, maybe add support for \n newlines? Why would I ?
|
||||
//
|
||||
i++; // Skip next character
|
||||
} else {
|
||||
currentArg += char;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add final argument if exists
|
||||
if (currentArg) {
|
||||
push(currentArg);
|
||||
}
|
||||
|
||||
if (currentQuoteChar) {
|
||||
// We allow quotes to not be terminated
|
||||
// It allows players to do stuff like `:say "wolla my lovely friend` and not have the text modified or misinterpreted in any way
|
||||
// May be good for chat where you dont want every word split into individual arguments
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
console.log(parseArgs("\"k1m er '-9 ' `anus pikke`"));
|
||||
@@ -222,7 +222,7 @@ export function frameText(text, options) {
|
||||
let output = "";
|
||||
|
||||
//
|
||||
// GENERATE THE MARGIN SPACE ABOVE THE FRAMED TEXT
|
||||
// GENERATE THE MARGIN SPACE ABOVE THE FRAMED MsgType.TEXT
|
||||
//
|
||||
// ( we insert space characters even though )
|
||||
// ( they wouldn't normally be visible. But )
|
||||
@@ -263,7 +263,7 @@ export function frameText(text, options) {
|
||||
).repeat(options.vPadding);
|
||||
|
||||
//
|
||||
// GENERATE FRAMED TEXT SEGMENT
|
||||
// GENERATE FRAMED MsgType.TEXT SEGMENT
|
||||
//
|
||||
// ║ My pretty ║
|
||||
// ║ text here ║
|
||||
@@ -318,7 +318,7 @@ export function frameText(text, options) {
|
||||
"\n";
|
||||
|
||||
//
|
||||
// GENERATE THE MARGIN SPACE BELOW THE FRAMED TEXT
|
||||
// GENERATE THE MARGIN SPACE BELOW THE FRAMED MsgType.TEXT
|
||||
//
|
||||
// ( we insert space characters even though )
|
||||
// ( they wouldn't normally be visible. But )
|
||||
|
||||
Reference in New Issue
Block a user