diff options
| -rw-r--r-- | public/index.html | 62 | ||||
| -rw-r--r-- | webAO/client.ts | 9 | ||||
| -rw-r--r-- | webAO/master.ts | 19 | ||||
| -rw-r--r-- | webAO/packets/handlers/handleMS.ts | 10 | ||||
| -rw-r--r-- | webAO/packets/handlers/handlePV.ts | 18 | ||||
| -rw-r--r-- | webAO/styles/client.css | 22 | ||||
| -rw-r--r-- | webAO/styles/default.css | 14 | ||||
| -rw-r--r-- | webAO/utils/fileExists.js | 18 | ||||
| -rw-r--r-- | webAO/utils/fileExists.ts | 19 | ||||
| -rw-r--r-- | webAO/utils/filesExist.ts | 28 | ||||
| -rw-r--r-- | webAO/utils/findImgSrc.ts | 19 | ||||
| -rw-r--r-- | webAO/viewport/utils/handleICSpeaking.ts | 40 | ||||
| -rw-r--r-- | webAO/viewport/utils/setSide.ts | 17 | ||||
| -rw-r--r-- | webAO/viewport/viewport.ts | 6 |
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(); } |
