0
0
Fork 0

Add endpoints and game utilities

This commit is contained in:
Oliver Akins 2022-12-25 16:52:15 -06:00
parent 56f2195962
commit 6a174e4d36
No known key found for this signature in database
GPG key ID: 3C2014AF9457AF99
7 changed files with 213 additions and 1 deletions

View file

@ -0,0 +1,33 @@
import { database } from "$/main";
import { addLetter } from "$/utils/game";
import { ServerRoute } from "@hapi/hapi";
import Joi from "joi";
const route: ServerRoute = {
method: `POST`, path: `/{channel}/guess`,
options: {
validate: {
params: Joi.object({
channel: Joi.string().alphanum(),
}),
payload: Joi.object({
guess: Joi.string().length(1),
}),
},
},
async handler(request) {
// @ts-ignore
const guess = request.payload.guess.toUpperCase();
const { channel } = request.params;
let data = await database.getChannel(channel);
console.log(data)
if (data.solution.includes(guess)) {
data.current = addLetter(data.key, data.current, guess);
} else {
data.incorrect++;
};
return `${data.current} (incorrect: ${data.incorrect}/6)`;
},
};
export default route;

33
src/endpoints/new_game.ts Normal file
View file

@ -0,0 +1,33 @@
import { database } from "$/main";
import { anonymizePhrase, convertToKey, spacePhrase } from "$/utils/game";
import { ServerRoute } from "@hapi/hapi";
import Joi from "joi";
const route: ServerRoute = {
method: `POST`, path: `/{channel}/game`,
options: {
validate: {
params: Joi.object({
channel: Joi.string().alphanum(),
}),
},
},
async handler(request) {
const { channel } = request.params;
let data = await database.getChannel(channel);
// TODO: Get the proper phrase
let phrase = "Hello world";
let spaced = spacePhrase(phrase.toUpperCase());
let anonymized = anonymizePhrase(spaced);
data.current = anonymized;
data.solution = spaced;
data.incorrect = 0;
data.key = convertToKey(spaced);
return `${data.current} (incorrect: ${data.incorrect}/6)`;
},
};
export default route;

54
src/endpoints/nightbot.ts Normal file
View file

@ -0,0 +1,54 @@
import { nightbotCustomHeadersSchema } from "$/schemas/nightbot";
import { ServerRoute } from "@hapi/hapi";
import boom from "@hapi/boom";
import Joi from "joi";
const subcommands = {
"start": {
method: `POST`,
modOnly: true,
},
"show": {
method: `GET`,
modOnly: false,
},
};
const route: ServerRoute = {
method: `GET`, path: `/nightbot`,
options: {
validate: {
query: Joi.object({
args: Joi.string().allow("").required(),
msg: Joi.string(),
}),
headers: nightbotCustomHeadersSchema.unknown(),
},
},
async handler(request) {
let args = (<string>request.query.args)
.split(` `)
.filter(x => x.length > 0);
if (args.length < 1) {
return `Not enough arguments`;
};
let channelData = new URLSearchParams(request.headers["nightbot-channel"]);
let channel = channelData.get(`name`);
let userData = new URLSearchParams(request.headers["nightbot-user"]);
let user = userData.get(`name`);
if (!channel) { throw boom.badData(`Missing channel name`) };
if (!user) { throw boom.badData(`Missing user name`) };
// User is guessing a letter
if (args[0].length == 1) {
return (await request.server.inject({
method: `POST`, url: `/${channel}/guess`,
payload: { guess: args[0] }
})).payload;
};
},
};
export default route;

View file

@ -0,0 +1,20 @@
import { database } from "$/main";
import { ServerRoute } from "@hapi/hapi";
import Joi from "joi";
const route: ServerRoute = {
method: `POST`, path: `/channels`,
options: {
validate: {
payload: Joi.object({
channel: Joi.string().alphanum(),
}),
},
},
async handler(request, h) {
// @ts-ignore
await database.createChannel(request.payload.channel);
return h.close;
},
};
export default route;

13
src/schemas/nightbot.ts Normal file
View file

@ -0,0 +1,13 @@
import Joi from "joi";
export const nightbotCustomHeadersSchema = Joi.object({
"nightbot-response-url": Joi
.string()
.uri({ scheme: `https` }),
"nightbot-user": Joi
.string(),
"nightbot-channel": Joi
.string(),
})
.meta({ className: `nightbotCustomHeaders` })
.description(`The custom headers Nightbot makes requests with`);

View file

@ -2,7 +2,7 @@ import { databaseOptions } from "$/types/config";
import fs from "fs";
export class JSONDatabase {
private data = {};
private data: any = {};
private conf: databaseOptions;
constructor(conf: databaseOptions) {
@ -22,4 +22,17 @@ export class JSONDatabase {
public shutdown() {
fs.writeFileSync(this.conf.uri, JSON.stringify(this.data));
};
public async createChannel(name: string) {
this.data[name] = {
current: null,
solution: null,
key: null,
incorrect: 0,
};
};
public async getChannel(name: string) {
return this.data[name];
};
};

46
src/utils/game.ts Normal file
View file

@ -0,0 +1,46 @@
export function addLetter(key: any, current: string, letter: string) {
let indexes = key[letter];
for (const i of indexes) {
current = current.slice(0, i) + letter.toUpperCase() + current.slice(i+1);
};
return current;
};
export function convertToKey(phrase: string) {
let key: {[index: string]: number[]} = {};
for (var i = 0; i < phrase.length; i++) {
let letter = phrase[i].toUpperCase();
if (!letter.match(/[a-zA-Z]/)) { continue };
if (key[letter] == null) {
key[letter] = [];
};
key[letter].push(i);
};
return key;
};
export function anonymizePhrase(phrase: string) {
let anon = ``;
for (const letter of phrase) {
if (letter.match(/[A-Za-z]/)) {
anon += `_`;
} else {
anon += letter;
};
};
return anon;
};
export function spacePhrase(phrase: string) {
let spaced = ``;
for (const letter of phrase) {
if (letter.match(/[A-Za-z]/)) {
spaced += `${letter} `;
} else if (letter == ` `) {
spaced += ``;
} else {
spaced += letter;
};
};
return spaced;
};