aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--webAO/client.ts29
-rw-r--r--webAO/client/aoHost.ts9
-rw-r--r--webAO/master.ts156
-rw-r--r--webAO/utils/queryParser.ts7
4 files changed, 95 insertions, 106 deletions
diff --git a/webAO/client.ts b/webAO/client.ts
index 3170ec8..c49a104 100644
--- a/webAO/client.ts
+++ b/webAO/client.ts
@@ -17,7 +17,7 @@ import { loadResources } from './client/loadResources'
import { AO_HOST } from './client/aoHost'
import { fetchBackgroundList, fetchEvidenceList, fetchCharacterList } from './client/fetchLists'
-const { ip: serverIP, mode, theme, serverName } = queryParser();
+const { ip: serverIP, connect, mode, theme, serverName } = queryParser();
document.title = serverName;
@@ -70,12 +70,27 @@ fpPromise
.then((result) => {
hdid = result.visitorId;
- if (!serverIP) {
- alert("No server IP specified!");
- return;
+ let connectionString = connect;
+
+ if (!connectionString) {
+ if (serverIP) {
+ // if connectionString is not set, try IP
+ // and just guess ws, though it could be wss
+ connectionString = `ws://${serverIP}`;
+ } else {
+ alert("No connection string specified!");
+ return;
+ }
+ }
+
+ if (window.location.protocol === "https:" && connectionString.startsWith("ws://")) {
+ // If protocol is https: and connectionString is ws://
+ // We have a problem, since it's impossible to connect to ws:// from https://
+ // Connection will fail, but at least warn the user
+ alert('Attempted to connect using insecure websockets on https page. Please try removing s from https:// in the URL bar.')
}
- client = new Client(serverIP);
+ client = new Client(connectionString);
client.connect()
isLowMemory();
loadResources();
@@ -117,7 +132,7 @@ class Client extends EventEmitter {
connect: () => void;
loadResources: () => void
isLowMemory: () => void
- constructor(address: string) {
+ constructor(connectionString: string) {
super();
this.connect = () => {
@@ -126,7 +141,7 @@ class Client extends EventEmitter {
this.on("message", this.onMessage.bind(this));
this.on("error", this.onError.bind(this));
if (mode !== "replay") {
- this.serv = new WebSocket(`ws://${address}`);
+ this.serv = new WebSocket(connectionString);
// Assign the websocket events
this.serv.addEventListener("open", this.emit.bind(this, "open"));
this.serv.addEventListener("close", this.emit.bind(this, "close"));
diff --git a/webAO/client/aoHost.ts b/webAO/client/aoHost.ts
index 6cad62a..33e010d 100644
--- a/webAO/client/aoHost.ts
+++ b/webAO/client/aoHost.ts
@@ -3,5 +3,14 @@ import queryParser from '../utils/queryParser'
const { asset } = queryParser();
export let AO_HOST = asset;
export const setAOhost = (val: string) => {
+ const currentProtocol = window.location.protocol;
+ const assetProtocol = val.split(':')[0] + ':';
+
+ if (currentProtocol === 'https:' && assetProtocol === 'http:') {
+ // In this specific case, we need to request assets over HTTPS
+ console.log('Upgrading asset link to https');
+ val = val.replace('http:', 'https:');
+ }
+
AO_HOST = val;
}
diff --git a/webAO/master.ts b/webAO/master.ts
index 336fc5f..295d326 100644
--- a/webAO/master.ts
+++ b/webAO/master.ts
@@ -1,5 +1,3 @@
-import FingerprintJS from '@fingerprintjs/fingerprintjs';
-
import { safeTags } from './encoding';
declare global {
@@ -28,10 +26,6 @@ const protocol = window.location.protocol;
const serverlist_cache_key = 'masterlist';
-let hdid: string;
-
-let selectedServer: number = -1;
-
const servers: AOServer[] = [];
servers[-2] = {
name: 'Singleplayer',
@@ -52,96 +46,29 @@ servers[-1] = {
players: 0,
};
-const fpPromise = FingerprintJS.load();
-fpPromise
- .then((fp) => fp.get())
- .then(async (result) => {
- hdid = result.visitorId;
-
- check_https();
-
- getServerlist().then((serverlist) => {
- processServerlist(serverlist);
- });
- processClientVersion(clientVersion);
+function main() {
+ getServerlist().then((serverlist) => {
+ processServerlist(serverlist);
+ });
- getMasterVersion().then((masterVersion) => {
- processMasterVersion(masterVersion);
- });
+ processClientVersion(clientVersion);
- // i don't need the ms to play alone
- setTimeout(() => checkOnline(-1, '127.0.0.1:50001'), 0);
+ getMasterVersion().then((masterVersion) => {
+ processMasterVersion(masterVersion);
});
-
-export function check_https() {
- if (protocol === 'https:') {
- document.getElementById('https_error').style.display = '';
- setTimeout(() => window.location.replace("http://web.aceattorneyonline.com/"), 5000);
- }
}
-export function setServ(ID: number) {
- selectedServer = ID;
+main();
- if (document.getElementById(`server${ID}`).className === '') { checkOnline(ID, `${servers[ID].ip}:${servers[ID].ws_port}`); }
-
- document.getElementById('serverdescription_content').innerHTML = `<b>${servers[ID].online}</b><br>${safeTags(servers[ID].description)}`;
+export function setServ(ID: number) {
+ const server = servers[ID];
+ const onlineStr = server.online;
+ const serverDesc = safeTags(server.description);
+ document.getElementById('serverdescription_content').innerHTML = `<b>${onlineStr}</b><br>${serverDesc}`;
}
window.setServ = setServ;
-function checkOnline(serverID: number, coIP: string) {
- let serverConnection: WebSocket;
- if (serverID !== -2) {
- try {
- serverConnection = new WebSocket(`ws://${coIP}`);
- } catch (SecurityError) {
- document.getElementById(`server${serverID}`).className = 'unavailable';
- return;
- }
- }
-
- // define what the callbacks do
- function onCOOpen() {
- document.getElementById(`server${serverID}`).className = 'available';
- serverConnection.send(`HI#${hdid}#%`);
- serverConnection.send('ID#webAO#webAO#%');
- }
-
- function onCOMessage(e: MessageEvent) {
- const comsg = e.data;
- const coheader = comsg.split('#', 2)[0];
- const coarguments = comsg.split('#').slice(1);
- if (coheader === 'PN') {
- servers[serverID].online = `Online: ${Number(coarguments[0])}/${Number(coarguments[1])}`;
- serverConnection.close();
- return;
- } if (coheader === 'BD') {
- servers[serverID].online = 'Banned';
- servers[serverID].description = coarguments[0];
- serverConnection.close();
- return;
- }
- if (serverID === selectedServer) {
- document.getElementById('serverdescription_content').innerHTML = `<b>${servers[serverID].online}</b><br>${safeTags(servers[serverID].description)}`;
- }
- }
-
- // assign the callbacks
- serverConnection.onopen = function () {
- onCOOpen();
- };
-
- serverConnection.onmessage = function (evt: MessageEvent) {
- onCOMessage(evt);
- };
-
- serverConnection.onerror = function (_evt: Event) {
- document.getElementById(`server${serverID}`).className = 'unavailable';
- console.error(`Error connecting to ${coIP}`);
- console.error(_evt);
- };
-}
// Fetches the serverlist from the masterserver
// Returns a properly typed list of servers
@@ -209,32 +136,67 @@ function getCachedServerlist(): AOServer[] {
return JSON.parse(cached) as AOServer[];
}
+// Constructs the client URL robustly, independent of domain and path
+function constructClientURL(protocol: string): string {
+ const clientURL = new URL(window.location.href);
+
+ // Use the given protocol
+ clientURL.protocol = protocol;
+
+ // Remove the last part of the pathname (e.g., "index.html")
+ const pathname = clientURL.pathname;
+ const parts = pathname.split('/');
+ parts.pop();
+
+ // Reconstruct the pathname
+ clientURL.pathname = parts.join('/');
+
+ // If clientURL.pathname does not end with a slash, add one
+ if (clientURL.pathname[clientURL.pathname.length - 1] !== '/') {
+ clientURL.pathname += '/'
+ }
+
+ clientURL.pathname += "client.html";
+
+ return clientURL.href;
+}
+
function processServerlist(serverlist: AOServer[]) {
- const host = window.location.host;
- const clientURL: string = `${protocol}//${host}/client.html`;
- for (let i = 0; i < serverlist.length - 1; i++) {
+ for (let i = 0; i < serverlist.length; i++) {
const server = serverlist[i];
- let port = 0;
+ let ws_port = 0;
+ let ws_protocol = '';
+ let http_protocol = '';
if (server.ws_port) {
- port = server.ws_port;
+ ws_port = server.ws_port;
+ ws_protocol = 'ws';
+ http_protocol = 'http';
}
if (server.wss_port) {
- port = server.wss_port;
+ ws_port = server.wss_port;
+ ws_protocol = 'wss';
+ http_protocol = 'https';
}
- if (port === 0) {
+
+ if (ws_port === 0 || ws_protocol === '' || http_protocol === '') {
+ console.warn(`Server ${server.name} has no websocket port, skipping`)
continue;
}
- const ipport = `${server.ip}:${port}`;
+ const clientURL = constructClientURL(http_protocol);
+ const connect = `${ws_protocol}://${server.ip}:${ws_port}`;
const serverName = server.name;
- server.online = 'Offline';
+ const fullClientWatchURL = `${clientURL}?mode=watch&connect=${connect}&serverName=${serverName}`;
+ const fullClientJoinURL = `${clientURL}?mode=join&connect=${connect}&serverName=${serverName}`;
+
+ server.online = `Players: ${server.players}`;
servers.push(server);
document.getElementById('masterlist').innerHTML
+= `<li id="server${i}" onmouseover="setServ(${i})"><p>${safeTags(server.name)} (${server.players})</p>`
- + `<a class="button" href="${clientURL}?mode=watch&ip=${ipport}&serverName=${serverName}">Watch</a>`
- + `<a class="button" href="${clientURL}?mode=join&ip=${ipport}&serverName=${serverName}">Join</a></li>`;
+ + `<a class="button" href="${fullClientWatchURL}" target="_blank">Watch</a>`
+ + `<a class="button" href="${fullClientJoinURL}" target="_blank">Join</a></li>`;
}
}
diff --git a/webAO/utils/queryParser.ts b/webAO/utils/queryParser.ts
index f934ac6..1a3cea6 100644
--- a/webAO/utils/queryParser.ts
+++ b/webAO/utils/queryParser.ts
@@ -2,6 +2,7 @@
interface QueryParams {
ip: string;
+ connect: string;
mode: string;
asset: string;
theme: string;
@@ -9,13 +10,15 @@ interface QueryParams {
}
const queryParser = (): QueryParams => {
+ const protocol = window.location.protocol;
const urlParams = new URLSearchParams(window.location.search);
const queryParams = {
ip: urlParams.get("ip") || "",
+ connect: urlParams.get("connect") || "",
mode: urlParams.get("mode") || "join",
- asset: urlParams.get("asset") || "http://attorneyoffline.de/base/",
+ asset: urlParams.get("asset") || `${protocol}//attorneyoffline.de/base/`,
theme: urlParams.get("theme") || "default",
- serverName: urlParams.get("serverName") || "Attorney Online session"
+ serverName: urlParams.get("serverName") || "Attorney Online session",
}
return queryParams as QueryParams;
};