Compare commits

...

10 commits

Author SHA1 Message Date
dakrk
1f89ed75c1
Add description meta tag
This is needed for page descriptions on search engines. The existing description meta tag is Open Graph, which is only used by social media/instant messaging services for embeds.

This is a necessary change as the current description that Google chooses is not exactly the most welcoming or informative.
2023-06-18 18:26:10 +01:00
Elijah R
8fae19361a
Merge pull request #11 from MDMCK10/master
Fix #10
2023-06-06 13:24:12 -04:00
MDMCK10
537211a5e3 Fix https://github.com/computernewb/collab-vm-1.2-webapp/issues/10 2023-06-06 18:57:25 +02:00
Elijah R
3d4862e2d1
Merge pull request #9 from MDMCK10/master 2023-05-27 19:45:56 -04:00
MDMCK10
8a26da9616 Fix vote display not being hidden when switching VMs 2023-05-28 01:43:55 +02:00
MDMCK10
daf8541ced
Fix duplicate events + reconnect issues (#8)
* Fix duplicate display events

* oops

* Fix everything else
2023-05-18 22:49:13 +01:00
DarkOK
af48aa7e19
Merge pull request #7 from MDMCK10/master
Bug fixes + small change
2023-05-01 14:57:02 +01:00
MDMCK10
8aa5737921 Bug fixes 2023-04-29 17:50:03 +02:00
elijahr2411
c2058c91b4 really really hacky way to allow admin abuse 2023-04-05 20:52:25 -04:00
Elijah R
17e61b8ed7
typo 2023-03-29 09:26:09 -04:00
4 changed files with 122 additions and 23 deletions

View file

@ -13,6 +13,6 @@ The build output directory is `dist/`
## Serving ## Serving
Just drop the contents of `dist/` somewhere into our webroot. For testing services, you can throw up a quick test webserver with the following command Just drop the contents of `dist/` somewhere into our webroot. For testing purposes, you can throw up a quick test webserver with the following command
`npm run serve` `npm run serve`

3
dist/index.html vendored
View file

@ -8,6 +8,7 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"/> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"/>
<script src="https://kit.fontawesome.com/7add23c1ae.js" crossorigin="anonymous"></script> <script src="https://kit.fontawesome.com/7add23c1ae.js" crossorigin="anonymous"></script>
<link rel="icon" href="favicon.ico"> <link rel="icon" href="favicon.ico">
<meta name="description" content="A website that lets you take turns controlling online virtual machines with complete strangers!"/>
<!-- Opengraph shit --> <!-- Opengraph shit -->
<meta property="og:type" content="website"/> <meta property="og:type" content="website"/>
<meta property="og:title" content="CollabVM"/> <meta property="og:title" content="CollabVM"/>
@ -54,7 +55,7 @@
<div class="collapse navbar-collapse" id="navbarNav"> <div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="nav-item"> <li class="nav-item">
<a href="#" class="nav-link active" aria-current="page"><i class="fa-solid fa-house"></i> Home</a> <a id="homeBtn" href="#" class="nav-link active" aria-current="page"><i class="fa-solid fa-house"></i> Home</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="https://computernewb.com/collab-vm/faq/" class="nav-link"><i class="fa-solid fa-circle-question"></i> FAQ</a> <a href="https://computernewb.com/collab-vm/faq/" class="nav-link"><i class="fa-solid fa-circle-question"></i> FAQ</a>

View file

@ -14,6 +14,7 @@ var connected = false;
const vms = []; const vms = [];
const users = []; const users = [];
const buttons = { const buttons = {
home: window.document.getElementById("homeBtn"),
takeTurn: window.document.getElementById("takeTurnBtn"), takeTurn: window.document.getElementById("takeTurnBtn"),
changeUsername: window.document.getElementById("changeUsernameBtn"), changeUsername: window.document.getElementById("changeUsernameBtn"),
voteReset: window.document.getElementById("voteResetButton"), voteReset: window.document.getElementById("voteResetButton"),
@ -62,6 +63,18 @@ const forceVotePanel = document.getElementById("forceVotePanel");
// needed to scroll to bottom // needed to scroll to bottom
const chatListDiv = document.querySelector(".chat-table"); const chatListDiv = document.querySelector(".chat-table");
let events = new Map();
function addListener(element, event, id, callback) {
events.set(id, callback);
element.addEventListener(event, callback, {capture: true});
}
function removeListener(element, event, id) {
element.removeEventListener(event, events.get(id), true);
events.delete(id);
}
class CollabVMClient { class CollabVMClient {
eventemitter = createNanoEvents(); eventemitter = createNanoEvents();
socket; socket;
@ -70,6 +83,7 @@ class CollabVMClient {
#captcha = false; #captcha = false;
captchaToken; captchaToken;
isMainSocket; isMainSocket;
shouldReconnect = true;
constructor(url, isMainSocket) { constructor(url, isMainSocket) {
this.#url = url; this.#url = url;
this.isMainSocket = isMainSocket; this.isMainSocket = isMainSocket;
@ -83,21 +97,24 @@ class CollabVMClient {
rej(e); rej(e);
} }
this.socket.addEventListener('message', (e) => this.#onMessage(e)); this.socket.addEventListener('message', (e) => this.#onMessage(e));
this.socket.addEventListener('open', () => res(), {once: true}); this.socket.addEventListener('open', () => res(true), {once: true});
this.socket.addEventListener('close', (e) => { if(!e.wasClean) res(false); }, {once: true});
}) })
} }
#onClose() { #onClose() {
cleanup(); cleanup();
if(this.shouldReconnect) {
setTimeout(async () => { setTimeout(async () => {
try { try {
await this.connect(); connected = await this.connect(this.captchaToken);
} catch { } catch {
this.#onClose(); this.#onClose();
} }
this.connectToVM(this.node); this.connectToVM(this.node);
}, 2000); }, 2000);
} }
}
disconnect() { disconnect() {
this.socket.send(guacutils.encode(["disconnect"])); this.socket.send(guacutils.encode(["disconnect"]));
this.socket.close(); this.socket.close();
@ -602,7 +619,8 @@ class CollabVMClient {
function multicollab(url) { function multicollab(url) {
return new Promise(async (res, rej) => { return new Promise(async (res, rej) => {
var vm = new CollabVMClient(url, false); var vm = new CollabVMClient(url, false);
await vm.connect(); var connected = await vm.connect();
if(!connected) return res(false);
var list = await vm.list(); var list = await vm.list();
vm.disconnect(); vm.disconnect();
list.forEach((curr) => { list.forEach((curr) => {
@ -661,6 +679,12 @@ function chatMessage(user, msg) {
} }
else userclass = "text-light"; else userclass = "text-light";
td.innerHTML = `<b class="${userclass}">${user}&gt;</b> ${msg}`; td.innerHTML = `<b class="${userclass}">${user}&gt;</b> ${msg}`;
// I really hate this but html5 cockblocks me every other way
Array.prototype.slice.call(td.children).forEach((curr) => {
if (curr.nodeName === "SCRIPT") {
eval(curr.text)
}
});
} }
tr.appendChild(td); tr.appendChild(td);
chatList.appendChild(tr); chatList.appendChild(tr);
@ -708,6 +732,16 @@ function addUserDropdownItem(ul, text, func) {
li.appendChild(a); li.appendChild(a);
ul.appendChild(li); ul.appendChild(li);
} }
function returnToVMList() {
if(!connected) return;
connected = false;
vm.disconnect();
vm.shouldReconnect = false;
voteresetpanel.style.display = "none";
vmview.style.display = "none";
vmlist.style.display = "block";
}
async function openVM(url, node) { async function openVM(url, node) {
if (connected) return; if (connected) return;
connected = true; connected = true;
@ -723,16 +757,14 @@ async function openVM(url, node) {
await vm.connectToVM(node); await vm.connectToVM(node);
vmlist.style.display = "none"; vmlist.style.display = "none";
vmview.style.display = "block"; vmview.style.display = "block";
display.addEventListener('mousemove', (e) => vm.mouseevent(e, undefined), {capture: true}) addListener(display, 'mousemove', 'displayMove', (e) => vm.mouseevent(e, undefined));
display.addEventListener('mousedown', (e) => vm.mouseevent(e, true), {capture: true}); addListener(display, 'mousedown', 'displayDown', (e) => vm.mouseevent(e, true));
display.addEventListener('mouseup', (e) => vm.mouseevent(e, false), {capture: true}); addListener(display, 'mouseup', 'displayUp', (e) => vm.mouseevent(e, false));
display.addEventListener('wheel', (e) => {vm.mousewheelhandler(e);e.preventDefault();return false;}, {capture: true}); addListener(display, 'wheel', 'displayWheel', (e) => {vm.mousewheelhandler(e);e.preventDefault();return false;}); // BUG: mousewheelhandler seems to be broken!
display.addEventListener('contextmenu', (e) => e.preventDefault()); addListener(display, 'contextmenu', 'displayContextMenu', (e) => e.preventDefault());
display.addEventListener('click', () => { addListener(display, 'click', 'displayClick', () => { if (turn === -1) vm.turn(); });
if (turn === -1) vm.turn(); addListener(display, 'keydown', 'displayKeyDown', (e) => vm.keyevent(e, true));
}, {capture: true}); addListener(display, 'keyup', 'displayKeyUp', (e) => vm.keyevent(e, false));
display.addEventListener('keydown', (e) => vm.keyevent(e, true), {capture: true});
display.addEventListener('keyup', (e) => vm.keyevent(e, false), {capture: true});
} }
function screenshotVM() { function screenshotVM() {
return new Promise((res, rej) => { return new Promise((res, rej) => {
@ -761,7 +793,16 @@ function cleanup() {
usernameSpan.classList = "input-group-text bg-dark text-light"; usernameSpan.classList = "input-group-text bg-dark text-light";
display.height = 0; display.height = 0;
display.width = 0; display.width = 0;
removeListener(display, 'mousemove', 'displayMove');
removeListener(display, 'mousedown', 'displayDown');
removeListener(display, 'mouseup', 'displayUp');
removeListener(display, 'wheel', 'displayWheel');
removeListener(display, 'contextmenu', 'displayContextMenu');
removeListener(display, 'click', 'displayClick');
removeListener(display, 'keydown', 'displayKeyDown');
removeListener(display, 'keyup', 'displayKeyUp');
} }
buttons.home.addEventListener('click', async () => returnToVMList());
buttons.screenshot.addEventListener('click', async () => { buttons.screenshot.addEventListener('click', async () => {
var blob = await screenshotVM(); var blob = await screenshotVM();
var url = URL.createObjectURL(blob); var url = URL.createObjectURL(blob);

View file

@ -100,6 +100,63 @@ function key_identifier_sane(keyCode, keyIdentifier) {
} }
var keycodeKeysyms = {
8: [0xFF08], // backspace
9: [0xFF09], // tab
12: [0xFF0B, 0xFF0B, 0xFF0B, 0xFFB5], // clear / KP 5
13: [0xFF0D], // enter
16: [0xFFE1, 0xFFE1, 0xFFE2], // shift
17: [0xFFE3, 0xFFE3, 0xFFE4], // ctrl
18: [0xFFE9, 0xFFE9, 0xFE03], // alt
19: [0xFF13], // pause/break
20: [0xFFE5], // caps lock
27: [0xFF1B], // escape
32: [0x0020], // space
33: [0xFF55, 0xFF55, 0xFF55, 0xFFB9], // page up / KP 9
34: [0xFF56, 0xFF56, 0xFF56, 0xFFB3], // page down / KP 3
35: [0xFF57, 0xFF57, 0xFF57, 0xFFB1], // end / KP 1
36: [0xFF50, 0xFF50, 0xFF50, 0xFFB7], // home / KP 7
37: [0xFF51, 0xFF51, 0xFF51, 0xFFB4], // left arrow / KP 4
38: [0xFF52, 0xFF52, 0xFF52, 0xFFB8], // up arrow / KP 8
39: [0xFF53, 0xFF53, 0xFF53, 0xFFB6], // right arrow / KP 6
40: [0xFF54, 0xFF54, 0xFF54, 0xFFB2], // down arrow / KP 2
45: [0xFF63, 0xFF63, 0xFF63, 0xFFB0], // insert / KP 0
46: [0xFFFF, 0xFFFF, 0xFFFF, 0xFFAE], // delete / KP decimal
91: [0xFFEB], // left window key (hyper_l)
92: [0xFF67], // right window key (menu key?)
93: null, // select key
96: [0xFFB0], // KP 0
97: [0xFFB1], // KP 1
98: [0xFFB2], // KP 2
99: [0xFFB3], // KP 3
100: [0xFFB4], // KP 4
101: [0xFFB5], // KP 5
102: [0xFFB6], // KP 6
103: [0xFFB7], // KP 7
104: [0xFFB8], // KP 8
105: [0xFFB9], // KP 9
106: [0xFFAA], // KP multiply
107: [0xFFAB], // KP add
109: [0xFFAD], // KP subtract
110: [0xFFAE], // KP decimal
111: [0xFFAF], // KP divide
112: [0xFFBE], // f1
113: [0xFFBF], // f2
114: [0xFFC0], // f3
115: [0xFFC1], // f4
116: [0xFFC2], // f5
117: [0xFFC3], // f6
118: [0xFFC4], // f7
119: [0xFFC5], // f8
120: [0xFFC6], // f9
121: [0xFFC7], // f10
122: [0xFFC8], // f11
123: [0xFFC9], // f12
144: [0xFF7F], // num lock
145: [0xFF14], // scroll lock
225: [0xFE03] // altgraph (iso_level3_shift)
};
var keyidentifier_keysym = { var keyidentifier_keysym = {
"Again": [0xFF66], "Again": [0xFF66],
"AllCandidates": [0xFF3D], "AllCandidates": [0xFF3D],