Things and støff
This commit is contained in:
@@ -2,10 +2,10 @@ import { PasswordPrompt } from "./passwordPrompt.js";
|
||||
import { Player } from "../../models/player.js";
|
||||
import { Scene } from "../scene.js";
|
||||
import { UsernamePrompt } from "./usernamePrompt.js";
|
||||
import { CreateUsernamePrompt } from "../playerCreation/createUsernamePrompt.js";
|
||||
|
||||
/** @property {Session} session */
|
||||
export class AuthenticationScene extends Scene {
|
||||
|
||||
introText = [
|
||||
"= Welcome", //
|
||||
];
|
||||
@@ -15,13 +15,13 @@ export class AuthenticationScene extends Scene {
|
||||
|
||||
onReady() {
|
||||
// current prompt
|
||||
this.doPrompt(new UsernamePrompt(this));
|
||||
this.show(UsernamePrompt);
|
||||
}
|
||||
|
||||
/** @param {Player} player */
|
||||
usernameAccepted(player) {
|
||||
this.player = player;
|
||||
this.doPrompt(new PasswordPrompt(this));
|
||||
this.show(PasswordPrompt);
|
||||
}
|
||||
|
||||
passwordAccepted() {
|
||||
@@ -34,4 +34,8 @@ export class AuthenticationScene extends Scene {
|
||||
this.session.setScene("new JustLoggedInScene");
|
||||
}
|
||||
}
|
||||
|
||||
createPlayer() {
|
||||
scene.session.setScene(new PlayerCreationScene(this.scene));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Prompt } from "../prompt.js";
|
||||
import * as security from "../../utils/security.js";
|
||||
import { Config } from "../../config.js";
|
||||
import { context } from "../../utils/messages.js";
|
||||
|
||||
export class PasswordPrompt extends Prompt {
|
||||
//
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { Player } from "../../models/player.js";
|
||||
import { Prompt } from "../prompt.js";
|
||||
import * as security from "../../utils/security.js";
|
||||
import { context } from "../../utils/messages.js";
|
||||
import { gGame } from "../../models/globals.js";
|
||||
import { PlayerCreationScene } from "../playerCreation/playerCreationSene.js";
|
||||
import { Config } from "../../config.js";
|
||||
import { AuthenticationScene } from "./authenticationScene.js";
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
* @property {AuthenticationScene} scene
|
||||
*/
|
||||
export class UsernamePrompt extends Prompt {
|
||||
//
|
||||
promptText = [
|
||||
@@ -24,17 +29,14 @@ export class UsernamePrompt extends Prompt {
|
||||
// Let the client know that we're asking for a username
|
||||
promptOptions = { username: true };
|
||||
|
||||
//
|
||||
// User entered ":create"
|
||||
onColon_create() {
|
||||
// User creation scene.
|
||||
this.scene.session.setScene(new PlayerCreationScene(this.scene));
|
||||
/** @returns {AuthenticationScene} */
|
||||
get scene() {
|
||||
return this._scene;
|
||||
}
|
||||
|
||||
//
|
||||
// User replied to our prompt
|
||||
onReply(text) {
|
||||
|
||||
//
|
||||
// do basic syntax checks on usernames
|
||||
if (!security.isUsernameSane(text)) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Prompt } from "../prompt.js";
|
||||
import * as security from "../../utils/security.js";
|
||||
import { Config } from "../../config.js";
|
||||
import { context } from "../../utils/messages.js";
|
||||
|
||||
export class CreatePasswordPrompt extends Prompt {
|
||||
//
|
||||
|
||||
@@ -19,7 +19,7 @@ export class PlayerCreationScene extends Scene {
|
||||
this.session.calamity("Server is full, no more players can be created");
|
||||
}
|
||||
|
||||
this.doPrompt(new CreateUsernamePrompt(this));
|
||||
this.showPrompt(new CreateUsernamePrompt(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,13 +27,13 @@ export class PlayerCreationScene extends Scene {
|
||||
*
|
||||
* @param {string} username
|
||||
*/
|
||||
onUsernameAccepted(username) {
|
||||
usernameAccepted(username) {
|
||||
const player = gGame.createPlayer(username);
|
||||
this.player = player;
|
||||
|
||||
this.session.sendSystemMessage("salt", player.salt);
|
||||
this.session.sendText(`Username _*${username}*_ is available, and I've reserved it for you :)`);
|
||||
this.doPrompt("new passwordprompt");
|
||||
this.showPrompt("new passwordprompt");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,9 +42,15 @@ export class PlayerCreationScene extends Scene {
|
||||
*
|
||||
* @param {string} password
|
||||
*/
|
||||
onPasswordAccepted(password) {
|
||||
passwordAccepted(password) {
|
||||
this.password = password;
|
||||
this.session.sendText("*_Success_* ✅ You will now be asked to log in again, sorry for that ;)");
|
||||
this.player.setPasswordHash(security.generateHash(this.password));
|
||||
}
|
||||
|
||||
//
|
||||
// User entered ":create"
|
||||
onColon__create() {
|
||||
this.scene.createPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import figlet from "figlet";
|
||||
import { gGame } from "../models/globals.js";
|
||||
import * as msg from "../utils/messages.js";
|
||||
import { Session } from "../models/session.js";
|
||||
import { Scene } from "./scene.js";
|
||||
import { WebsocketMessage } from "../utils/messages.js";
|
||||
import { MessageType, WebsocketMessage } from "../utils/messages.js";
|
||||
import { mustBe, mustBeString } from "../utils/mustbe.js";
|
||||
import { sprintf } from "sprintf-js";
|
||||
|
||||
/**
|
||||
* @typedef {object} PromptMethods
|
||||
@@ -19,8 +19,13 @@ import { mustBe, mustBeString } from "../utils/mustbe.js";
|
||||
* - onColon(...)
|
||||
*/
|
||||
export class Prompt {
|
||||
/** @protected @readonly @constant @type {Scene} */
|
||||
scene;
|
||||
/** @private @readonly @type {Scene} */
|
||||
_scene;
|
||||
|
||||
/** @type {Scene} */
|
||||
get scene() {
|
||||
return this._scene;
|
||||
}
|
||||
|
||||
//
|
||||
// Extra info about the prompt we send to the client.
|
||||
@@ -58,7 +63,7 @@ export class Prompt {
|
||||
if (!(scene instanceof Scene)) {
|
||||
throw new Error("Expected an instance of >>Scene<< but got " + typeof scene);
|
||||
}
|
||||
this.scene = scene;
|
||||
this._scene = scene;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,24 +97,42 @@ export class Prompt {
|
||||
* Triggered when a user types a :command that begins with a colon
|
||||
*
|
||||
* @param {string} command
|
||||
* @param {string} argLine
|
||||
* @param {any[]} args
|
||||
*/
|
||||
onColon(command, argLine) {
|
||||
const methodName = "onColon_" + command;
|
||||
const method = this[methodName];
|
||||
if (typeof method === "function") {
|
||||
method.call(this, argLine);
|
||||
|
||||
onColon(command, args) {
|
||||
const methodName = "onColon__" + command;
|
||||
const property = this[methodName];
|
||||
|
||||
//
|
||||
// Default: we have no handler for the Foo command,
|
||||
// So let's see if daddy can handle it.
|
||||
if (property === undefined) {
|
||||
return this.scene.onColon(command, args);
|
||||
}
|
||||
|
||||
//
|
||||
// If the prompt has a method called onColon_foo() =>
|
||||
if (typeof property === "function") {
|
||||
property.call(this, args);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// For static "denial of commands" such as :inv ==> "you cannot access your inventory right now"
|
||||
if (typeof method === "string") {
|
||||
this.sendText(method);
|
||||
// If the prompt has a _string_ called onColon_foo =>
|
||||
if (typeof property === "string") {
|
||||
this.sendText(property);
|
||||
return;
|
||||
}
|
||||
|
||||
// :inv ==> you cannot INV right now
|
||||
this.sendError(`You cannot ${command.toUpperCase()} right now`);
|
||||
//
|
||||
// We found a property that has the right name but the wrong type.
|
||||
throw new Error(
|
||||
[
|
||||
`Logic error. Prompt has a handler for a command called ${command}`,
|
||||
`but it is neither a function or a string, but a ${typeof property}`,
|
||||
].join(" "),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +190,7 @@ export class Prompt {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} systemMessageType
|
||||
* @param {string} systemMessageType The subtype of the system message (dev, salt, username, etc.)
|
||||
* @param {any?} value
|
||||
*/
|
||||
sendSystemMessage(...args) {
|
||||
@@ -184,13 +207,6 @@ export class Prompt {
|
||||
|
||||
//
|
||||
// Easter ægg
|
||||
onColon_pull_out_wand = "You cannot pull out your wand right now! But thanks for trying 😘🍌🍆";
|
||||
|
||||
//
|
||||
// Easter ægg2
|
||||
onColon_imperial(argLine) {
|
||||
const n = Number(argLine);
|
||||
|
||||
this.sendText(`${n} centimeters is only ${n / 2.54} inches. This is why americans have such small wands`);
|
||||
}
|
||||
// Example of having a string as a colon-handler
|
||||
onColon__pull_out_wand = "You cannot pull out your wand right now! But thanks for trying 😘🍌🍆";
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { Session } from "../models/session.js";
|
||||
import { Prompt } from "./prompt.js";
|
||||
const MsgContext.ERROR_INSANE_PASSWORD = "Invalid password.";
|
||||
const MsgContext.ERROR_INCORRECT_PASSWOD = "Incorrect password.";
|
||||
|
||||
/**
|
||||
* Scene - a class for showing one or more prompts in a row.
|
||||
*
|
||||
* Scenes are mostly there to keep track of which prompt to show,
|
||||
* and to store data for subsequent prompts to access.
|
||||
*
|
||||
* The prompts themselves are responsible for data validation and
|
||||
* interpretation.
|
||||
*
|
||||
* @abstract
|
||||
* @method onReady
|
||||
*/
|
||||
export class Scene {
|
||||
/**
|
||||
@@ -31,8 +36,7 @@ export class Scene {
|
||||
return this._prompt;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
/** @param {Session} session */
|
||||
execute(session) {
|
||||
@@ -51,8 +55,73 @@ export class Scene {
|
||||
/**
|
||||
* @param {Prompt} prompt
|
||||
*/
|
||||
doPrompt(prompt) {
|
||||
showPrompt(prompt) {
|
||||
this._prompt = prompt;
|
||||
prompt.execute();
|
||||
}
|
||||
|
||||
/** @param {new (scene: Scene) => Prompt} promptClassReference */
|
||||
show(promptClassReference) {
|
||||
this.showPrompt(new promptClassReference(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when a user types a :command that begins with a colon
|
||||
* and the current Prompt cannot handle that command.
|
||||
*
|
||||
* @param {string} command
|
||||
* @param {any[]} args
|
||||
*/
|
||||
onColon(command, args) {
|
||||
const propertyName = "onColon__" + command;
|
||||
const property = this[propertyName];
|
||||
|
||||
//
|
||||
// Default: we have no handler for the Foo command
|
||||
if (property === undefined) {
|
||||
this.session.sendError(`You cannot ${command.toUpperCase()} right now`, { verbatim: true }); // :foo ==> you cannot FOO right now
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If the prompt has a method called onColon_foo() =>
|
||||
if (typeof property === "function") {
|
||||
property.call(this, args);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If the prompt has a _string_ called onColon_foo =>
|
||||
if (typeof property === "string") {
|
||||
this.session.sendText(property);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// We found a property that has the right name but the wrong type.
|
||||
throw new Error(
|
||||
[
|
||||
`Logic error. Scene has a handler for a command called ${command}`,
|
||||
`but it is neither a function or a string, but a ${typeof property}`,
|
||||
].join(" "),
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Easter ægg
|
||||
// Example dynamic colon handler
|
||||
/** @param {any[]} args */
|
||||
onColon__imperial(args) {
|
||||
if (args.length === 0) {
|
||||
this.session.sendText("The imperial system is the freeest system ever. Also the least good");
|
||||
}
|
||||
|
||||
const n = Number(args[0]);
|
||||
|
||||
this.session.sendText(
|
||||
sprintf("%.2f centimeters is only %.2f inches. This is american wands are so short!", n, n / 2.54),
|
||||
);
|
||||
}
|
||||
|
||||
onColon__hi = "Hoe";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user