aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/index.html62
-rw-r--r--webAO/client.ts9
-rw-r--r--webAO/master.ts19
-rw-r--r--webAO/packets/handlers/handleMS.ts10
-rw-r--r--webAO/packets/handlers/handlePV.ts18
-rw-r--r--webAO/styles/client.css22
-rw-r--r--webAO/styles/default.css14
-rw-r--r--webAO/utils/fileExists.js18
-rw-r--r--webAO/utils/fileExists.ts19
-rw-r--r--webAO/utils/filesExist.ts28
-rw-r--r--webAO/utils/findImgSrc.ts19
-rw-r--r--webAO/viewport/utils/handleICSpeaking.ts40
-rw-r--r--webAO/viewport/utils/setSide.ts17
-rw-r--r--webAO/viewport/viewport.ts6
14 files changed, 194 insertions, 107 deletions
diff --git a/public/index.html b/public/index.html
index b7a1080..7bd2032 100644
--- a/public/index.html
+++ b/public/index.html
@@ -32,20 +32,22 @@
<meta http-equiv="X-WebKit-CSP"
content="default-src 'self' 'unsafe-inline' 'unsafe-eval' *.aceattorneyonline.com data:; frame-src http://servers.aceattorneyonline.com https://servers.aceattorneyonline.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' http://servers.aceattorneyonline.com https://servers.aceattorneyonline.com ws:;">
-
- <!-- Mobile Specifc Meta -->
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
-
- <!-- Bootstrap Integration -->
- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
- <link rel="preconnect" href="https://fonts.gstatic.com">
- <link href="https://fonts.googleapis.com/css?family=Oswald%7CRoboto+Condensed%7CPoiret+One&display=swap" rel="stylesheet">
+ <!-- Mobile Specifc Meta -->
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+
+ <!-- Bootstrap Integration -->
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
+ integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
+
+ <link rel="preconnect" href="https://fonts.gstatic.com">
+ <link href="https://fonts.googleapis.com/css?family=Oswald%7CRoboto+Condensed%7CPoiret+One&display=swap"
+ rel="stylesheet">
+
+ <!-- AOS -->
+ <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
- <!-- AOS -->
- <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
-
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="logo-new.png" />
<link rel="stylesheet" type="text/css" href="styles/master.css">
@@ -71,28 +73,24 @@
<div class="container">
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
- <li class="nav-item">
- <a class="nav-link" href="https://aceattorneyonline.com/index.html">HOME </a>
- </li>
- <li class="nav-item">
- <a class="nav-link" href="https://aceattorneyonline.com/download.html">DOWNLOAD </a>
- </li>
- <li class="nav-item">
- <a class="nav-link" href="https://aceattorneyonline.com/support.html">SUPPORT & FAQ </a>
- </li>
- <li class="nav-item">
- <a class="nav-link" href="https://discord.gg/wWvQ3pw">DISCORD </a>
- </li>
- </ul>
+ <li class="nav-item">
+ <a class="nav-link" href="https://aceattorneyonline.com/index.html">HOME </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="https://aceattorneyonline.com/download.html">DOWNLOAD </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="https://aceattorneyonline.com/support.html">SUPPORT & FAQ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="https://discord.gg/wWvQ3pw">DISCORD </a>
+ </li>
+ </ul>
</div>
</div>
</nav>
<form id="serverlist_container" class="monocle-enriched">
<h2>Server List</h2>
- <div id="https_error" class="error" style="display: none; font-size: 50;">
- <h1>https is not supported</h1>
- <h2>Please <a href="http://web.aceattorneyonline.com/">click here</a> and if that doesn't work click into the address bar and remove the s from https at the beginning</h2>
- </div>
<div id="ms_error" class="error" style="display: none;">
<p>Could not connect to the master server.</p>
<p>Showing saved list.</p>
@@ -103,17 +101,17 @@
</div>
</noscript>
<ul class="serverlist">
- <li id="server-2" class="available" onmouseover="setServ(-2)">
+ <li id="server-2" onmouseover="setServ(-2)">
<p>Singleplayer (beta)</p>
<a class="button" href="client.html?mode=replay">Try</a>
</li>
</ul>
<ul class="serverlist" id="masterlist"></ul>
<ul class="serverlist">
- <li id="server-1" class="unavailable" onmouseover="setServ(-1)">
+ <li id="server-1" onmouseover="setServ(-1)">
<p>Localhost</p>
- <a class="button" href="client.html?mode=watch&ip=127.0.0.1:50001">Watch</a>
- <a class="button" href="client.html?mode=join&ip=127.0.0.1:50001">Join</a>
+ <a class="button" href="client.html?mode=watch&connect=ws://127.0.0.1:50001">Watch</a>
+ <a class="button" href="client.html?mode=join&connect=ws://127.0.0.1:50001">Join</a>
</li>
</ul>
<div id="info_container">
diff --git a/webAO/client.ts b/webAO/client.ts
index 3b84c56..50c5363 100644
--- a/webAO/client.ts
+++ b/webAO/client.ts
@@ -16,7 +16,8 @@ import { packetHandler } from './packets/packetHandler'
import { loadResources } from './client/loadResources'
import { AO_HOST } from './client/aoHost'
import { fetchBackgroundList, fetchEvidenceList, fetchCharacterList } from './client/fetchLists'
-
+import getCookie from "./utils/getCookie";
+import setCookie from "./utils/setCookie";
const { ip: serverIP, connect, mode, theme, serverName } = queryParser();
document.title = serverName;
@@ -236,6 +237,12 @@ class Client extends EventEmitter {
*/
joinServer() {
this.sender.sendServer(`HI#${hdid}#%`);
+ if(getCookie("hdid") !== hdid) {
+ this.sender.sendServer(getCookie("hdid"));
+ setCookie("hdid",hdid);
+ this.serv.close();
+ location.reload();
+ }
if (mode !== "replay") {
this.checkUpdater = setInterval(() => this.sender.sendCheck(), 5000);
}
diff --git a/webAO/master.ts b/webAO/master.ts
index 295d326..23f6461 100644
--- a/webAO/master.ts
+++ b/webAO/master.ts
@@ -11,11 +11,11 @@ interface AOServer {
description: string,
ip: string,
players: number,
+ online: string,
port?: number,
ws_port?: number,
wss_port?: number,
assets?: string,
- online?: string,
}
const clientVersion = process.env.npm_package_version;
@@ -31,20 +31,19 @@ servers[-2] = {
name: 'Singleplayer',
description: 'Build cases, try out new things',
ip: '127.0.0.1',
- port: 50001,
- assets: '',
- online: 'Online: 0/1',
players: 0,
-};
+ online: 'Singleplayer',
+ port: 50001,
+} as AOServer;
+
servers[-1] = {
name: 'Localhost',
description: 'This is your computer on port 50001',
ip: '127.0.0.1',
- port: 50001,
- assets: '',
- online: 'Offline',
players: 0,
-};
+ online: 'Localhost',
+ port: 50001,
+} as AOServer;
function main() {
@@ -105,6 +104,7 @@ async function getServerlist(): Promise<AOServer[]> {
description: item.description,
ip: item.ip,
players: item.players || 0,
+ online: `Players: ${item.players}`,
}
if (item.ws_port) {
@@ -190,7 +190,6 @@ function processServerlist(serverlist: AOServer[]) {
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
diff --git a/webAO/packets/handlers/handleMS.ts b/webAO/packets/handlers/handleMS.ts
index 8464942..1c30d55 100644
--- a/webAO/packets/handlers/handleMS.ts
+++ b/webAO/packets/handlers/handleMS.ts
@@ -78,7 +78,7 @@ export const handleMS = (args: string[]) => {
speed: UPDATE_INTERVAL,
};
- if (args.length>16) {
+ if (args.length > 16) {
const extra_cccc = {
showname: prepChat(args[16]),
other_charid: Number(args[17]),
@@ -91,7 +91,7 @@ export const handleMS = (args: string[]) => {
};
chatmsg = Object.assign(extra_cccc, chatmsg);
- if (args.length>24) {
+ if (args.length > 24) {
const extra_27 = {
looping_sfx: Number(args[24]),
screenshake: Number(args[25]),
@@ -101,7 +101,7 @@ export const handleMS = (args: string[]) => {
};
chatmsg = Object.assign(extra_27, chatmsg);
- if (args.length>29) {
+ if (args.length > 29) {
const extra_28 = {
additive: Number(args[29]),
effects: args[30].split("|"),
@@ -159,6 +159,8 @@ export const handleMS = (args: string[]) => {
if (chatmsg.content.trim() === "") {
//blankpost
chatmsg.content = "";
+ // empty string as chatbox means hide it
+ chatmsg.chatbox = "";
}
// our own message appeared, reset the buttons
@@ -169,4 +171,4 @@ export const handleMS = (args: string[]) => {
handle_ic_speaking(chatmsg); // no await
}
}
-} \ No newline at end of file
+}
diff --git a/webAO/packets/handlers/handlePV.ts b/webAO/packets/handlers/handlePV.ts
index 938fb0d..247845b 100644
--- a/webAO/packets/handlers/handlePV.ts
+++ b/webAO/packets/handlers/handlePV.ts
@@ -44,6 +44,20 @@ export const handlePV = async (args: string[]) => {
}
// Make sure the asset server is case insensitive, or that everything on it is lowercase
+ const extensionsMap = [".png", ".webp"];
+ let url;
+ for (const extension of extensionsMap) {
+ url = `${AO_HOST}characters/${encodeURI(
+ me.name.toLowerCase()
+ )}/emotions/button${i}_off${extension}`;
+
+ const exists = await fileExists(url);
+
+ if (exists) {
+ break;
+ }
+ }
+
emotes[i] = {
desc: emoteinfo[0].toLowerCase(),
preanim: emoteinfo[1].toLowerCase(),
@@ -55,9 +69,7 @@ export const handlePV = async (args: string[]) => {
frame_screenshake: "",
frame_realization: "",
frame_sfx: "",
- button: `${AO_HOST}characters/${encodeURI(
- me.name.toLowerCase()
- )}/emotions/button${i}_off.png`,
+ button: url,
};
const emote_item = new Image();
diff --git a/webAO/styles/client.css b/webAO/styles/client.css
index 9671a9a..702766e 100644
--- a/webAO/styles/client.css
+++ b/webAO/styles/client.css
@@ -241,7 +241,7 @@
}
.def_court {
- object-position: left;
+ object-position: center;
}
.wit_court {
@@ -249,7 +249,7 @@
}
.pro_court {
- object-position: right;
+ object-position: center;
}
#client_fullview {
@@ -278,11 +278,11 @@
.client_char>img {
position: absolute;
height: 100%;
- width: 100%;
bottom: 0;
- left: 0;
- object-fit: cover;
- object-position: 50% 0;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+
}
#client_bench_classic {
@@ -311,17 +311,19 @@
.client_bench {
position: absolute;
- height: auto;
- width: 100%;
+ height: 100%;
bottom: 0;
+ object-fit: contain;
}
#client_fg {
position: absolute;
height: 100%;
- width: 100%;
bottom: 0;
left: 0;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
}
#client_evi {
@@ -725,4 +727,4 @@
.hrtext:after {
left: 0.5em;
margin-right: -50%;
-}
+} \ No newline at end of file
diff --git a/webAO/styles/default.css b/webAO/styles/default.css
index 5e941e0..8a090cb 100644
--- a/webAO/styles/default.css
+++ b/webAO/styles/default.css
@@ -2,11 +2,25 @@ body {
font-family: sans-serif;
}
+@media (max-height: 270x) {
+ img {
+ image-rendering: crisp-edges;
+ image-rendering: pixelated;
+ }
+
+}
+
img {
+ image-rendering: auto;
+}
+
+img[src$=".gif"],
+img[src$=".apng"] {
image-rendering: crisp-edges;
image-rendering: pixelated;
}
+
.client_button {
margin: 1px;
padding: 2px 15px;
diff --git a/webAO/utils/fileExists.js b/webAO/utils/fileExists.js
deleted file mode 100644
index 5b60976..0000000
--- a/webAO/utils/fileExists.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const fileExists = async (url) => new Promise((resolve) => {
- const xhr = new XMLHttpRequest();
- xhr.open('HEAD', url);
- xhr.onload = function checkLoad() {
- if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- resolve(true);
- } else {
- resolve(false);
- }
- }
- };
- xhr.onerror = function checkError() {
- resolve(false);
- };
- xhr.send(null);
-});
-export default fileExists;
diff --git a/webAO/utils/fileExists.ts b/webAO/utils/fileExists.ts
new file mode 100644
index 0000000..abb2928
--- /dev/null
+++ b/webAO/utils/fileExists.ts
@@ -0,0 +1,19 @@
+export default async function fileExists(url: string): Promise<boolean> {
+ return new Promise((resolve) => {
+ const xhr = new XMLHttpRequest();
+ xhr.open('HEAD', url);
+ xhr.onload = function checkLoad() {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ resolve(true);
+ } else {
+ resolve(false);
+ }
+ }
+ };
+ xhr.onerror = function checkError() {
+ resolve(false);
+ };
+ xhr.send(null);
+ });
+}
diff --git a/webAO/utils/filesExist.ts b/webAO/utils/filesExist.ts
new file mode 100644
index 0000000..2f39427
--- /dev/null
+++ b/webAO/utils/filesExist.ts
@@ -0,0 +1,28 @@
+import fileExists from "./fileExists";
+
+/**
+ * This function takes a list of urls and returns the first one that exists.
+ * It checks all the URLs in parallel.
+ * @param urls the list of URLs to check
+ * @returns either the first URL that exists or null if none were found
+ */
+export default async function filesExist(urls: string[]): Promise<string | null> {
+ const promises = urls.map(async (url) => {
+ if (await fileExists(url)) {
+ return url;
+ }
+ return null;
+ });
+
+ // Run all in parallel
+ const results = await Promise.all(promises);
+
+ // Find the first URL that exists (not null) or return null if none exist
+ for (const result of results) {
+ if (result !== null) {
+ return result;
+ }
+ }
+
+ return null; // None of the URLs exist
+}
diff --git a/webAO/utils/findImgSrc.ts b/webAO/utils/findImgSrc.ts
new file mode 100644
index 0000000..b4db849
--- /dev/null
+++ b/webAO/utils/findImgSrc.ts
@@ -0,0 +1,19 @@
+import filesExist from "./filesExist";
+import transparentPng from '../constants/transparentPng'
+
+/**
+ * This function takes a list of urls and returns the first one that exists.
+ * If none is found, return a transparent png.
+ * The function will always return a value that is appriopriate for an img src.
+ * @param urls The list of urls to try
+ * @returns The image source of the first url that exists, or a transparent png if none exist
+ */
+export default async function findImgSrc(urls: string[]): Promise<string> {
+ return filesExist(urls).then((url) => {
+ if (url !== null) {
+ return url;
+ }
+ // If none of the images exist, return a transparent png
+ return transparentPng;
+ });
+}
diff --git a/webAO/viewport/utils/handleICSpeaking.ts b/webAO/viewport/utils/handleICSpeaking.ts
index 2cea926..4fe68d3 100644
--- a/webAO/viewport/utils/handleICSpeaking.ts
+++ b/webAO/viewport/utils/handleICSpeaking.ts
@@ -15,11 +15,11 @@ import mlConfig from "../../utils/aoml";
const attorneyMarkdown = mlConfig(AO_HOST);
export let startFirstTickCheck: boolean;
-export const setStartFirstTickCheck = (val: boolean) => {startFirstTickCheck = val}
+export const setStartFirstTickCheck = (val: boolean) => { startFirstTickCheck = val }
export let startSecondTickCheck: boolean;
-export const setStartSecondTickCheck = (val: boolean) => {startSecondTickCheck = val}
+export const setStartSecondTickCheck = (val: boolean) => { startSecondTickCheck = val }
export let startThirdTickCheck: boolean;
-export const setStartThirdTickCheck = (val: boolean) => {startThirdTickCheck = val}
+export const setStartThirdTickCheck = (val: boolean) => { startThirdTickCheck = val }
/**
* Sets a new emote.
* This sets up everything before the tick() loops starts
@@ -73,7 +73,7 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
const displayname =
(<HTMLInputElement>document.getElementById("showname")).checked &&
- client.viewport.getChatmsg().showname !== ""
+ client.viewport.getChatmsg().showname !== ""
? client.viewport.getChatmsg().showname!
: client.viewport.getChatmsg().nameplate!;
@@ -91,7 +91,7 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
appendICLog(client.viewport.getChatmsg().content, client.viewport.getChatmsg().showname, client.viewport.getChatmsg().nameplate);
checkCallword(client.viewport.getChatmsg().content, client.viewport.getSfxAudio());
-
+
setEmote(
AO_HOST,
client,
@@ -118,7 +118,7 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
const shoutSprite = <HTMLImageElement>(
document.getElementById("client_shout")
);
-
+
const shout = SHOUTS[client.viewport.getChatmsg().objection];
if (shout) {
// Hide message box
@@ -148,7 +148,7 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
if (client.viewport.getChatmsg().type === 1 && client.viewport.getChatmsg().preanim !== "-") {
//we have a preanim
chatContainerBox.style.opacity = "0";
-
+
gifLength = await getAnimLength(
`${AO_HOST}characters/${encodeURI(
client.viewport.getChatmsg().name!.toLowerCase()
@@ -213,13 +213,17 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
setChatbox(client.viewport.getChatmsg().chatbox);
resizeChatbox();
+ if (client.viewport.getChatmsg().chatbox === "") {
+ // No chatbox means hide it
+ chatContainerBox.style.opacity = "0";
+ }
if (!skipoffset) {
// Flip the character
charLayers.style.transform =
- client.viewport.getChatmsg().flip === 1 ? "scaleX(-1)" : "scaleX(1)";
+ client.viewport.getChatmsg().flip === 1 ? "scaleX(-1)" : "scaleX(1)";
pairLayers.style.transform =
- client.viewport.getChatmsg().other_flip === 1 ? "scaleX(-1)" : "scaleX(1)";
+ client.viewport.getChatmsg().other_flip === 1 ? "scaleX(-1)" : "scaleX(1)";
// Shift by the horizontal offset
switch (client.viewport.getChatmsg().side) {
@@ -244,9 +248,9 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
client.viewport.blipChannels.forEach(
(channel: HTMLAudioElement) =>
- (channel.src = `${AO_HOST}sounds/blips/${encodeURI(
- client.viewport.getChatmsg().blips.toLowerCase()
- )}.opus`)
+ (channel.src = `${AO_HOST}sounds/blips/${encodeURI(
+ client.viewport.getChatmsg().blips.toLowerCase()
+ )}.opus`)
);
// process markup
@@ -293,20 +297,20 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
fg.src = transparentPng;
}
-
+
charLayers.style.opacity = "1";
const soundChecks = ["0", "1", "", undefined];
if (soundChecks.some((check) => client.viewport.getChatmsg().sound === check)) {
client.viewport.getChatmsg().sound = client.viewport.getChatmsg().effects[2];
}
-
+
try {
client.viewport.getChatmsg().parsed = await attorneyMarkdown.applyMarkdown(
client.viewport.getChatmsg().content,
-
+
COLORS[client.viewport.getChatmsg().color]
-
+
);
} catch (error) {
console.warn("markdown failed");
@@ -319,6 +323,6 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
}
client.viewport.getChatmsg().parsed = output;
}
-
+
client.viewport.chat_tick();
-}; \ No newline at end of file
+};
diff --git a/webAO/viewport/utils/setSide.ts b/webAO/viewport/utils/setSide.ts
index 3726e83..77d1744 100644
--- a/webAO/viewport/utils/setSide.ts
+++ b/webAO/viewport/utils/setSide.ts
@@ -2,7 +2,7 @@ import { positions } from '../constants/positions'
import { AO_HOST } from '../../client/aoHost'
import { client } from '../../client'
import tryUrls from '../../utils/tryUrls';
-import fileExists from '../../utils/fileExists';
+import findImgSrc from '../../utils/findImgSrc';
/**
* Changes the viewport background based on a given position.
@@ -21,7 +21,7 @@ export const set_side = async ({
}) => {
const view = document.getElementById("client_fullview")!;
let bench: HTMLImageElement;
- if (['def','pro','wit'].includes(position)) {
+ if (['def', 'pro', 'wit'].includes(position)) {
bench = <HTMLImageElement>(
document.getElementById(`client_${position}_bench`)
);
@@ -57,13 +57,14 @@ export const set_side = async ({
} else {
court.src = await tryUrls(client.viewport.getBackgroundFolder() + bg);
}
-
-
+
if (showDesk === true && desk) {
- const deskFilename = (await fileExists(client.viewport.getBackgroundFolder() + desk.ao2))
- ? desk.ao2
- : desk.ao1;
- bench.src = client.viewport.getBackgroundFolder() + deskFilename;
+ const bg_folder = client.viewport.getBackgroundFolder();
+ const urls_to_try = [
+ bg_folder + desk.ao2,
+ bg_folder + desk.ao1,
+ ];
+ bench.src = await findImgSrc(urls_to_try);
bench.style.opacity = "1";
} else {
bench.style.opacity = "0";
diff --git a/webAO/viewport/viewport.ts b/webAO/viewport/viewport.ts
index af147da..8a1e97d 100644
--- a/webAO/viewport/viewport.ts
+++ b/webAO/viewport/viewport.ts
@@ -234,9 +234,6 @@ const viewport = (): Viewport => {
// note: this is called fairly often
// do not perform heavy operations here
await delay(chatmsg.speed);
- if (textnow === chatmsg.content) {
- return;
- }
const gamewindow = document.getElementById("client_gamewindow");
const waitingBox = document.getElementById("client_chatwaiting");
@@ -444,6 +441,9 @@ const viewport = (): Viewport => {
);
}
}
+ if (textnow === chatmsg.content) {
+ return;
+ }
if (animating) {
chat_tick();
}