You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
5.8 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

const WebSocket = require("ws");
const { Client } = require("node-osc");
const ws = new WebSocket(
"wss://relaxed-werewolf.reticulum.io/socket/websocket?vsn=2.0.0"
);
const STATE_STARTING = "starting";
const STATE_JOINING = "joining";
const STATE_CONNECTED = "connected";
let state = STATE_STARTING;
let hubId = "qPxWfFA";
let fullHubId = `hub:${hubId}`;
let receiveId = 1;
let sendId = 1;
let botSessionId;
let vapidPublicKey;
let avatarId = "qPxWfFA";
let displayName = "000";
// Members keyed by session ID.
let members = {};
let chatStates = {};
const oscClient = new Client("127.0.0.1", 3333);
let dialogOptions = [
["START", /(hello|hi)/, "Welcome to the attic, you are getting close.", "START"],
["START", /(shell)/, "One correct!", "SHELL"],
["START", /(mirror)/, "One correct!", "MIRROR"],
["START", /(computer)/, "One correct!", "COMPUTER"],
["SHELL", /(shell)/, "You already said that!!", "SHELL"],
["SHELL", /(mirror)/, "Two correct!", "SHELL_MIRROR"],
["SHELL", /(computer)/, "Two correct!", "SHELL_COMPUTER"],
[ "SHELL_COMPUTER", /(shell|computer)/, "You already said that!", "SHELL_COMPUTER"],
[ "SHELL_COMPUTER", /(mirror)/, "Ahhhhh...... the number of the portal is... 32!", "WIN"],
[ "SHELL_MIRROR", /(shell|mirror)/, "You already said that!", "SHELL_MIRROR"],
[ "SHELL_MIRROR", /(computer)/, "Ahhhhh...... the number of the portal is... 32!", "WIN"],
["MIRROR", /(mirror)/, "You already said that!!", "MIRROR"],
["MIRROR", /(shell)/, "Two correct!", "MIRROR_SHELL"],
["MIRROR", /(computer)/, "Two correct!", "MIRROR_COMPUTER"],
[ "MIRROR_COMPUTER", /(mirror|computer)/, "You already said that!", "MIRROR_COMPUTER"],
[ "MIRROR_COMPUTER", /(shell)/, "Ahhhhh...... the number of the portal is... 32!", "WIN"],
[ "MIRROR_SHELL", /(shell|mirror)/, "You already said that!", "MIRROR_COMPUTER"],
[ "MIRROR_SHELL", /(computer)/, "Ahhhhh...... the number of the portal is... 32!", "WIN"],
["COMPUTER", /(comptuer)/, "You already said that!!", "COMPUTER"],
["COMPUTER", /(mirror)/, "Two correct!", "COMPUTER_MIRROR"],
["COMPUTER", /(shell)/, "Two correct!", "COMPUTER_SHELL"],
[ "COMPUTER_SHELL", /(shell|computer)/, "You already said that!", "COMPUTER_SHELL"],
[ "COMPUTER_SHELL", /(mirror)/, "Ahhhhh...... the number of the portal is... 32!", "WIN"],
[ "COMPUTER_MIRROR", /(computer|mirror)/, "You already said that!", "COMPUTER_MIRROR"],
[ "COMPUTER_MIRROR", /(shell)/, "Ahhhhh...... the number of the portal is... 32!", "WIN"],
// Guessing game
];
function sendMessage(roomId, command, body) {
const message = JSON.stringify([receiveId, sendId, roomId, command, body]);
ws.send(message);
sendId++;
}
function receiveMessage(data) {
const [n1, n2, channel, command, body] = JSON.parse(data);
if (Number.isInteger(n1)) {
receiveId = n1;
}
if (command === "phx_reply" && state === STATE_STARTING) {
if (body.status === "ok") {
console.log("Joining Hubs...");
state = STATE_JOINING;
botSessionId = body.response.session_id;
vapidPublicKey = body.response.vapid_public_key;
sendMessage(fullHubId, "phx_join", {
profile: { avatarId, displayName },
auth_token: null,
perms_token: null,
context: { mobile: false, embed: false },
});
} else {
console.log(`ERROR WHILE STARTING: ${JSON.stringify(body)}`);
}
} else if (command === "phx_reply" && state == STATE_JOINING) {
if (body.status === "ok") {
const hub = body.response.hubs[0];
console.log(`Connected to ${hub.name}.`);
state = STATE_CONNECTED;
setInterval(sendHeartbeat, 30000);
} else {
console.log(`ERROR WHILE JOINING: ${JSON.stringify(body)}`);
}
} else if (command === "message" && state === STATE_CONNECTED) {
console.log(body);
handleChatMessage(body);
} else if (command === "presence_diff") {
for (const sessionId of Object.keys(body.joins)) {
if (sessionId === botSessionId) continue;
const meta =body.joins[sessionId].metas[0];
if (meta.presence !== 'room') continue;
const displayName = meta.profile.displayName;
const message = `Welcome, dear ${displayName}, to my attic..I like to listen here for any sounds from the outside.. So few come in… Stay here among the paintings for a while, you will see there is no way out..But lets play a game! In each of these images, there is one element which you must name… For each image, this will be the most central object. But beware! Name all of the elements, and I shall steal your voice. Lo, I shall join the other world. You shall also be set free, for I shall tell you the secret of the portal...`;
sendMessage(fullHubId, "message", { body: message, type: "chat" });
}
} else {
//console.log(`Unknown command ${command}`);
}
}
function handleChatMessage(message) {
if (message.type !== "chat") return;
// This is the user that sent the message.
const sessionId = message.session_id;
// Ignore messages we sent ourselves.
if (sessionId === botSessionId) return;
const body = message.body.trim();
let chatState = chatStates[sessionId] || "START";
// Find a suitable dialog option.
for (const [startState, input, output, endState] of dialogOptions) {
if (startState !== chatState) continue;
if (body.match(input)) {
console.log(sessionId, chatState, output);
setTimeout(() => {
sendMessage(fullHubId, "message", { body: output, type: "chat" });
chatState = endState;
chatStates[sessionId] = chatState;
if (chatState === 'WIN') {
oscClient.send("/win");
chatStates[sessionId] = 'START';
}
}, 500 + Math.random() * 1000);
break;
}
}
}
function sendHeartbeat() {
sendMessage("phoenix", "heartbeat", {});
}
ws.on("open", function () {
sendMessage("ret", "phx_join", { hub_id: hubId });
});
ws.on("message", receiveMessage);