diff --git a/client.js b/client.js index 9b1f5cc..6a432c8 100644 --- a/client.js +++ b/client.js @@ -1,7 +1,13 @@ const channelSocket = new WebSocket("ws://localhost:9091/connect"); var __messengerjs__sessionID = null; -var __messengerjs__imTheRoomOwner = false; +var __messengerjs__imTheChannelOwner = false; var __messengerjs__myNickname = ""; +var __messengerjs__onloadfunction = null; +var __messengerjs__onloadargs = null; +const __messengerjs__fade = document.createElement("div"); +__messengerjs__fade.style.cssText = "position: absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.75);color:white;text-align:center;font-family:sans-serif;"; +__messengerjs__fade.textContent = "connecting to WebSocket server..."; + const beforeUnloadHandler = function(ev, reason) { Channel_OnAppClose(); channelSocket.send(new TextEncoder("utf8").encode(EncodeCommandString(["disconnect"]))); @@ -64,20 +70,14 @@ const EncodeCommandString = function(sections) { /** window.external **/ window.external.CloseApp = function() { - channelSocket.close(1000, "called CloseApp"); + beforeUnloadHandler(null, "called CloseApp"); } // this is important because things expect it /** window.external.Channel **/ window.external.Channel = {"Data": "", "SendData": null, "Initialize": null, "Error": {"Data": ""}}; // "Type" is a defined property window.external.Channel.SendData = function(d) {channelSocket.send(d)}; // this is dumb but trying to redirect this gives you TypeError's window.external.Channel.Initialize = function() { - if(new URL(location.href).searchParams.get("channel") === null) { - __messengerjs__sessionID = Math.random().toString(36).split('.')[1].substring(0,8); - history.pushState(null, "", `?channel=${__messengerjs__sessionID}`); - } else { - __messengerjs__sessionID = new URL(location.href).searchParams.get("channel"); - } - createWSEventsNowThatImReady(); + // no idea }; Object.defineProperty(window.external.Channel, "Type", { get: function Type() { @@ -116,15 +116,6 @@ Object.defineProperty(window.external.Users, "me", { return window.external.Users.Me; } }); -if(new URL(location.href).searchParams.get("channel") === null) { - window.external.Users.Me = window.external.yellows111_Users[0]; - window.external.Users.Inviter = window.external.yellows111_Users[0]; - document.title = "Initiator: " + document.title; -} else { - window.external.Users.Me = window.external.yellows111_Users[1]; - window.external.Users.Inviter = window.external.yellows111_Users[0]; - document.title = "Target: " + document.title; -} /** websocket stuff **/ channelSocket.binaryType = "arraybuffer"; // the alternative is blob.arrayBuffer(); IT'S A PROMISE CALL AND PROMISES SUXX @@ -147,21 +138,24 @@ channelSocket.onmessage = function(event) { case "connect": { switch(args[1]) { case "0": { - console.error("room is full or not avaliable"); - beforeUnloadHandler(null, "room was not avaliable"); - history.replaceState(null, "", window.location.href.split("?")[0]); - window.location.reload(); // it's jank and probably should just be handled socket side + console.error("channel is full or not avaliable"); + // regenerate channel ID if we get 0'd + __messengerjs__sessionID = Math.random().toString(36).split('.')[1].substring(0,8); + history.pushState(null, "", `?channel=${__messengerjs__sessionID}`); + channelSocket.send(new TextEncoder("utf8").encode(EncodeCommandString(["connect", __messengerjs__sessionID]))); break; } case "1": { - console.log("joined room successfully."); + console.log("joined channel successfully."); + __messengerjs__fade.textContent = "waiting for opponent to join this channel..."; + window.addEventListener("beforeunload", beforeUnloadHandler); if(args[2] === "1") { - __messengerjs__imTheRoomOwner = false; + __messengerjs__imTheChannelOwner = false; } else { - __messengerjs__imTheRoomOwner = true; + __messengerjs__imTheChannelOwner = true; if(window.external.Users.Inviter !== window.external.Users.Me) { - // This room has already been closed. Create a new one. - beforeUnloadHandler(null, "room was empty when expecting host"); + // This channel has already been closed. Create a new one. + beforeUnloadHandler(null, "channel was empty when expecting host"); history.replaceState(null, "", window.location.href.split("?")[0]); window.location.reload(); // it's still jank and probably should just be handled elsewhere } @@ -176,21 +170,38 @@ channelSocket.onmessage = function(event) { break; } case "disconnect": { + // code will never reach here normally (should announce from server on ^C, though) channelSocket.close(1000, "goodbye"); Channel_OnTypeChanged(); } case "adduser": { - if(__messengerjs__imTheRoomOwner === false) { + __messengerjs__fade.style.display = "none"; + if(__messengerjs__imTheChannelOwner === false) { window.external.yellows111_Users[1].Name = __messengerjs__myNickname; + window.external.yellows111_Users[0].Name = args[2]; + } else { + window.external.yellows111_Users[1].Name = args[2]; + window.external.yellows111_Users[0].Name = __messengerjs__myNickname; + } + if(__messengerjs__imTheChannelOwner === true) { + window.external.Users.Me = window.external.yellows111_Users[0]; + window.external.Users.Inviter = window.external.yellows111_Users[0]; + } else { + window.external.Users.Me = window.external.yellows111_Users[1]; + window.external.Users.Inviter = window.external.yellows111_Users[0]; + } + document.title = __messengerjs__myNickname + ": " + document.title; + /** beyond even hack territory **/ + if(typeof __messengerjs__onloadfunction === "function") { + __messengerjs__onloadfunction(__messengerjs__onloadargs); } - window.external.yellows111_Users[0].Name = args[2]; - window.addEventListener("beforeunload", beforeUnloadHandler); Channel_OnRemoteAppLoaded(); Channel_OnTypeChanged(); break; } case "remuser": { - // todo? + __messengerjs__fade.textContent = "opponent (" + args[1] + ") disconnected :("; + __messengerjs__fade.style.display = "revert"; window.removeEventListener("beforeunload", beforeUnloadHandler); Channel_OnRemoteAppClosed(); beforeUnloadHandler(null, "other user disconnected"); // disconnect ourselves @@ -210,11 +221,14 @@ channelSocket.onmessage = function(event) { } channelSocket.onerror = function(ev) { window.external.Channel.Error.Data = "WebSocket generic error"; + __messengerjs__fade.textContent = "encountered a WebSocket error" + __messengerjs__fade.style.display = "revert"; Channel_OnDataError(); } channelSocket.onclose = function() { Channel_OnTypeChanged(); } + function createWSEventsNowThatImReady() { if(channelSocket.readyState === 1) { // if we're already there @@ -225,4 +239,21 @@ function createWSEventsNowThatImReady() { channelSocket.send(new TextEncoder("utf8").encode(EncodeCommandString(["rename"]))); channelSocket.send(new TextEncoder("utf8").encode(EncodeCommandString(["connect", __messengerjs__sessionID]))); } -} \ No newline at end of file +} +/** pure evil **/ +window.onload = function(ev) { + document.body.append(__messengerjs__fade); + if(new URL(location.href).searchParams.get("channel") === null) { + __messengerjs__sessionID = Math.random().toString(36).split('.')[1].substring(0,8); + history.pushState(null, "", `?channel=${__messengerjs__sessionID}`); + } else { + __messengerjs__sessionID = new URL(location.href).searchParams.get("channel"); + } + createWSEventsNowThatImReady(); + __messengerjs__onloadargs = ev; +} +Object.defineProperty(window, "onload", { + set: function onload(fn) { + __messengerjs__onloadfunction = fn; + } +}); \ No newline at end of file diff --git a/server.js b/server.js index 661d22e..80062c4 100644 --- a/server.js +++ b/server.js @@ -3,9 +3,9 @@ var uidcounter = 0; Object.freeze(config); // Config should not be modified after initialization! const ChannelStorage = new Map(); -const UserAttachedChannelStorage = new Map(); -const UserAttachedNameStorage = new Map(); // uid=>username resolve -const ReverseNameToUidStorage = new Map(); +const UserAttachedChannelStorage = new Map(); //uid=>channel resolve +const UserAttachedNameStorage = new Map(); // uid=>username resolve +const ReverseNameToUidStorage = new Map(); // username=>uid resolve /** @section guacamole **/ const ParseCommandString = function(instruction) { @@ -72,10 +72,15 @@ const MessageParser = function(webSocket, message, isBinary) { case "rename": { // todo: make users be able to rename based on parameters given to rename var nickname = `guest${Math.floor(Math.random() * 99999)}`; - // this should probably be a while or something - if(ReverseNameToUidStorage.get(nickname) !== webSocket.getUserData().uid) { + if(nickname.length > 32) { // if it's too long nickname = `guest${Math.floor(Math.random() * 99999)}`; } + // this should probably be a while or something (only do this if the name exists) + if(ReverseNameToUidStorage.has(nickname) === true) { + if(ReverseNameToUidStorage.get(nickname) !== webSocket.getUserData().uid) { + nickname = `guest${Math.floor(Math.random() * 99999)}`; + } + } UserAttachedNameStorage.set(webSocket.getUserData().uid, nickname); ReverseNameToUidStorage.set(nickname, webSocket.getUserData().uid); webSocket.send(EncodeCommandString(["rename", 0, "", nickname]), true); @@ -92,12 +97,12 @@ const MessageParser = function(webSocket, message, isBinary) { webSocket.send(EncodeCommandString(["connect", 0]), true); break; } - if(typeof UserAttachedNameStorage.get(webSocket.getUserData().uid) === "undefined") { + if(UserAttachedNameStorage.has(webSocket.getUserData().uid) === false) { // user doesn't have a username webSocket.send(EncodeCommandString(["connect", 0]), true); break; } - if(typeof ChannelStorage.get(getChannelId) === "undefined") { + if(ChannelStorage.has(getChannelId) === false) { // make the channel right then and there console.log(`creating #${getChannelId}`); ChannelStorage.set(getChannelId, {"owner": webSocket.getUserData().uid}); @@ -107,7 +112,7 @@ const MessageParser = function(webSocket, message, isBinary) { webSocket.send(EncodeCommandString(["connect", 0]), true); break; }; - if(typeof UserAttachedChannelStorage.get(webSocket.getUserData().uid) !== "undefined") { + if(UserAttachedChannelStorage.has(webSocket.getUserData().uid) === true) { // already in a channel that isn't the one we're trying to join webSocket.send(EncodeCommandString(["connect", 0]), true); break; @@ -126,7 +131,7 @@ const MessageParser = function(webSocket, message, isBinary) { break; } case "disconnect": { - if(typeof UserAttachedChannelStorage.get(webSocket.getUserData().uid) !== "undefined") { + if(UserAttachedChannelStorage.has(webSocket.getUserData().uid) === true) { console.log(`user ${UserAttachedNameStorage.get(webSocket.getUserData().uid)} (${webSocket.getUserData().uid}) left #${UserAttachedChannelStorage.get(webSocket.getUserData().uid)}`); webSocket.unsubscribe(`channels/${UserAttachedChannelStorage.get(webSocket.getUserData().uid)}`); webSocket.publish(