From ce9ced5c8beb4590b95051930a9bacf83b21762a Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 28 Mar 2022 21:25:07 +0200 Subject: add button (it's ugly) --- public/client.html | 40 +++++++++++++++++++++++++++++----------- webAO/styles/client.css | 6 +++++- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/public/client.html b/public/client.html index 28a0bf1..34c2aa1 100644 --- a/public/client.html +++ b/public/client.html @@ -20,13 +20,14 @@ - + @@ -37,10 +38,8 @@ - - - - + + @@ -50,8 +49,27 @@

Having trouble? Join us on Discord

+

Choose your character

+
+

You need to authorize to continue

+
+
+ +

diff --git a/webAO/styles/client.css b/webAO/styles/client.css index 4e0712e..3bcc493 100644 --- a/webAO/styles/client.css +++ b/webAO/styles/client.css @@ -68,6 +68,10 @@ animation: error_blink 3s ease-in-out infinite; } +#client_secondfactor { + display: block; +} + #client_loading { display: block; flex-direction: column; @@ -703,4 +707,4 @@ .hrtext:after { left: 0.5em; margin-right: -50%; -} \ No newline at end of file +} -- cgit From 268f3fb063c241f3df13bac5bd189fb6d2c42e9a Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 28 Mar 2022 22:03:10 +0200 Subject: whoops --- public/client.html | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/public/client.html b/public/client.html index 34c2aa1..dd0ed18 100644 --- a/public/client.html +++ b/public/client.html @@ -49,27 +49,27 @@

Having trouble? Join us on Discord

-

Choose your character

-
-

You need to authorize to continue

-
-
+

-- cgit From 1285a83a3bac725423c24eb248ef54747ad005f5 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 28 Mar 2022 22:03:26 +0200 Subject: send the token and handle a token request --- webAO/client.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/webAO/client.ts b/webAO/client.ts index ac34334..fc54026 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -237,7 +237,7 @@ class Client extends EventEmitter { this.on('FM', this.handleFM.bind(this)); this.on('FA', this.handleFA.bind(this)); this.on('SM', this.handleSM.bind(this)); - this.on('MM', this.handleMM.bind(this)); + this.on('2F', this.handle2F.bind(this)); this.on('BD', this.handleBD.bind(this)); this.on('BB', this.handleBB.bind(this)); this.on('KB', this.handleKB.bind(this)); @@ -493,8 +493,9 @@ class Client extends EventEmitter { * to the server. */ joinServer() { - this.sendServer(`HI#${hdid}#%`); this.sendServer('ID#webAO#webAO#%'); + this.sendServer(`HI#${hdid}#%`); + this.sendServer(`2T#${getCookie('g_csrf_token')}#%`); if (mode !== 'replay') { this.checkUpdater = setInterval(() => this.sendCheck(), 5000); } } @@ -1284,11 +1285,11 @@ class Client extends EventEmitter { } /** - * Handles the "MusicMode" packet + * Handles 2 factor auth * @param {Array} args packet arguments */ - handleMM(_args: string[]) { - // It's unused nowadays, as preventing people from changing the music is now serverside + handle2F(_args: string[]) { + document.getElementById('client_secondfactor').style.display = 'block'; } /** -- cgit From 8bbd4a50ce90173949f56e9ed85856267471a992 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 28 Mar 2022 23:12:48 +0200 Subject: popup and callback works best --- public/client.html | 10 ++++++---- webAO/client.ts | 10 ++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/public/client.html b/public/client.html index dd0ed18..af76bdc 100644 --- a/public/client.html +++ b/public/client.html @@ -56,10 +56,12 @@
-
+ data-ux_mode="popup" + data-callback="handleCredentialResponse" + data-nonce="" + data-auto_select="true"> +
+ -
-

Choose your character

- +
+

Choose your character



-- cgit From 1e3f34e03c9dd8fda7e2b24e4533e23fcb7e1de7 Mon Sep 17 00:00:00 2001 From: Caleb Date: Fri, 9 Sep 2022 18:12:48 -0400 Subject: Moved more functions out of client --- webAO/client.ts | 113 +++--------------------------------------- webAO/client/appendICLog.ts | 57 +++++++++++++++++++++ webAO/client/checkCallword.ts | 17 +++++++ webAO/client/isLowMemory.ts | 10 ++++ webAO/client/resetICParams.ts | 21 ++++++++ 5 files changed, 111 insertions(+), 107 deletions(-) create mode 100644 webAO/client/appendICLog.ts create mode 100644 webAO/client/checkCallword.ts create mode 100644 webAO/client/isLowMemory.ts create mode 100644 webAO/client/resetICParams.ts diff --git a/webAO/client.ts b/webAO/client.ts index e92489c..9588812 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -3,14 +3,13 @@ * made by sD, refactored by oldmud0 and Qubrick * credits to aleks for original idea and source */ - +import {isLowMemory} from './client/isLowMemory' import FingerprintJS from "@fingerprintjs/fingerprintjs"; import vanilla_background_arr from "./constants/backgrounds.js"; import vanilla_evidence_arr from "./constants/evidence.js"; import {sender, ISender} from './client/sender/index' import iniParse from "./iniParse"; import getCookie from "./utils/getCookie"; -import setCookie from "./utils/setCookie"; import fileExists from "./utils/fileExists.js"; import queryParser from "./utils/queryParser"; import getResources from "./utils/getResources.js"; @@ -19,7 +18,7 @@ import masterViewport, { Viewport } from "./viewport"; import { EventEmitter } from "events"; import { area_click } from './dom/areaClick' import { onReplayGo } from './dom/onReplayGo' -import { escapeChat, safeTags, unescapeChat } from "./encoding"; +import { safeTags, unescapeChat } from "./encoding"; import { setChatbox } from "./dom/setChatbox"; import { request } from "./services/request.js"; import { @@ -77,20 +76,8 @@ export const setBanned = (val: boolean) => { } let hdid: string; -function isLowMemory() { - if ( - /webOS|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|PlayStation|Nintendo|Opera Mini/i.test( - navigator.userAgent - ) - ) { - oldLoading = true; - } -} - const fpPromise = FingerprintJS.load(); -const connect = (address: string) => { -} fpPromise .then((fp) => fp.get()) .then((result) => { @@ -100,15 +87,16 @@ fpPromise // Create the new client and connect it client = new Client(serverIP); client.connect() - isLowMemory(); client.loadResources(); }); export const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); -let lastICMessageTime = new Date(0); - +export let lastICMessageTime = new Date(0); +export const setLastICMessageTime = (val: Date) => { + lastICMessageTime = val +} class Client extends EventEmitter { serv: any; hp: number[]; @@ -335,7 +323,6 @@ class Client extends EventEmitter { packetHandler.has(packetHeader) ? packetHandler.get(packetHeader)(splitPacket) : console.warn(`Invalid packet header ${packetHeader}`); - } /** @@ -353,7 +340,6 @@ class Client extends EventEmitter { */ cleanup() { clearInterval(this.checkUpdater); - this.serv.close(); } @@ -653,93 +639,6 @@ class Client extends EventEmitter { } } -/** - * Resets the IC parameters for the player to enter a new chat message. - * This should only be called when the player's previous chat message - * was successfully sent/presented. - */ -export function resetICParams() { - (document.getElementById("client_inputbox")).value = ""; - document.getElementById("button_flash").className = "client_button"; - document.getElementById("button_shake").className = "client_button"; - - (document.getElementById("sendpreanim")).checked = false; - (document.getElementById("sendsfx")).checked = false; - - if (selectedShout) { - document.getElementById(`button_${selectedShout}`).className = - "client_button"; - selectedShout = 0; - } -} -/** - * Appends a message to the in-character chat log. - * @param {string} msg the string to be added - * @param {string} name the name of the sender - */ -export function appendICLog( - msg: string, - showname = "", - nameplate = "", - time = new Date() -) { - const entry = document.createElement("p"); - const shownameField = document.createElement("span"); - const nameplateField = document.createElement("span"); - const textField = document.createElement("span"); - nameplateField.className = "iclog_name iclog_nameplate"; - nameplateField.appendChild(document.createTextNode(nameplate)); - - shownameField.className = "iclog_name iclog_showname"; - if (showname === "" || !showname) { - shownameField.appendChild(document.createTextNode(nameplate)); - } else { - shownameField.appendChild(document.createTextNode(showname)); - } - - textField.className = "iclog_text"; - textField.appendChild(document.createTextNode(msg)); - - entry.appendChild(shownameField); - entry.appendChild(nameplateField); - entry.appendChild(textField); - - // Only put a timestamp if the minute has changed. - if (lastICMessageTime.getMinutes() !== time.getMinutes()) { - const timeStamp = document.createElement("span"); - timeStamp.className = "iclog_time"; - timeStamp.innerText = time.toLocaleTimeString(undefined, { - hour: "numeric", - minute: "2-digit", - }); - entry.appendChild(timeStamp); - } - - const clientLog = document.getElementById("client_log"); - clientLog.appendChild(entry); - - /* This is a little buggy - some troubleshooting might be desirable */ - if (clientLog.scrollTop > clientLog.scrollHeight - 800) { - clientLog.scrollTop = clientLog.scrollHeight; - } - - lastICMessageTime = new Date(); -} - -/** - * check if the message contains an entry on our callword list - * @param {string} message - */ -export function checkCallword(message: string, sfxAudio: HTMLAudioElement) { - client.callwords.forEach(testCallword); - function testCallword(item: string) { - if (item !== "" && message.toLowerCase().includes(item.toLowerCase())) { - sfxAudio.pause(); - sfxAudio.src = `${AO_HOST}sounds/general/sfx-gallery.opus`; - sfxAudio.play(); - } - } -} export default Client; \ No newline at end of file diff --git a/webAO/client/appendICLog.ts b/webAO/client/appendICLog.ts new file mode 100644 index 0000000..f8b7852 --- /dev/null +++ b/webAO/client/appendICLog.ts @@ -0,0 +1,57 @@ +import { lastICMessageTime, setLastICMessageTime } from "../client"; + + + +/** + * Appends a message to the in-character chat log. + * @param {string} msg the string to be added + * @param {string} name the name of the sender + */ +export function appendICLog( + msg: string, + showname = "", + nameplate = "", + time = new Date() +) { + const entry = document.createElement("p"); + const shownameField = document.createElement("span"); + const nameplateField = document.createElement("span"); + const textField = document.createElement("span"); + nameplateField.className = "iclog_name iclog_nameplate"; + nameplateField.appendChild(document.createTextNode(nameplate)); + + shownameField.className = "iclog_name iclog_showname"; + if (showname === "" || !showname) { + shownameField.appendChild(document.createTextNode(nameplate)); + } else { + shownameField.appendChild(document.createTextNode(showname)); + } + + textField.className = "iclog_text"; + textField.appendChild(document.createTextNode(msg)); + + entry.appendChild(shownameField); + entry.appendChild(nameplateField); + entry.appendChild(textField); + + // Only put a timestamp if the minute has changed. + if (lastICMessageTime.getMinutes() !== time.getMinutes()) { + const timeStamp = document.createElement("span"); + timeStamp.className = "iclog_time"; + timeStamp.innerText = time.toLocaleTimeString(undefined, { + hour: "numeric", + minute: "2-digit", + }); + entry.appendChild(timeStamp); + } + + const clientLog = document.getElementById("client_log")!; + clientLog.appendChild(entry); + + /* This is a little buggy - some troubleshooting might be desirable */ + if (clientLog.scrollTop > clientLog.scrollHeight - 800) { + clientLog.scrollTop = clientLog.scrollHeight; + } + + setLastICMessageTime(new Date()); +} \ No newline at end of file diff --git a/webAO/client/checkCallword.ts b/webAO/client/checkCallword.ts new file mode 100644 index 0000000..f6cffbc --- /dev/null +++ b/webAO/client/checkCallword.ts @@ -0,0 +1,17 @@ +import { client } from "../client"; +import { AO_HOST } from "./aoHost"; + +/** + * check if the message contains an entry on our callword list + * @param {string} message + */ +export function checkCallword(message: string, sfxAudio: HTMLAudioElement) { + client.callwords.forEach(testCallword); + function testCallword(item: string) { + if (item !== "" && message.toLowerCase().includes(item.toLowerCase())) { + sfxAudio.pause(); + sfxAudio.src = `${AO_HOST}sounds/general/sfx-gallery.opus`; + sfxAudio.play(); + } + } +} \ No newline at end of file diff --git a/webAO/client/isLowMemory.ts b/webAO/client/isLowMemory.ts new file mode 100644 index 0000000..caa6784 --- /dev/null +++ b/webAO/client/isLowMemory.ts @@ -0,0 +1,10 @@ +import { setOldLoading } from '../client' +export const isLowMemory = () => { + if ( + /webOS|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|PlayStation|Nintendo|Opera Mini/i.test( + navigator.userAgent + ) + ) { + setOldLoading(true); + } +} diff --git a/webAO/client/resetICParams.ts b/webAO/client/resetICParams.ts new file mode 100644 index 0000000..414da27 --- /dev/null +++ b/webAO/client/resetICParams.ts @@ -0,0 +1,21 @@ +import { selectedShout, setSelectedShout } from "../client"; + +/** + * Resets the IC parameters for the player to enter a new chat message. + * This should only be called when the player's previous chat message + * was successfully sent/presented. + */ +export function resetICParams() { + (document.getElementById("client_inputbox")).value = ""; + document.getElementById("button_flash")!.className = "client_button"; + document.getElementById("button_shake")!.className = "client_button"; + + (document.getElementById("sendpreanim")).checked = false; + (document.getElementById("sendsfx")).checked = false; + + if (selectedShout) { + document.getElementById(`button_${selectedShout}`)!.className = + "client_button"; + setSelectedShout(0); + } +} \ No newline at end of file -- cgit From e50167a8077b0ada769cdf785971972c3ad865f7 Mon Sep 17 00:00:00 2001 From: Caleb Date: Fri, 9 Sep 2022 18:30:07 -0400 Subject: Pulled out everything I wanted --- webAO/client.ts | 369 ++---------------------------------- webAO/client/addTrack.ts | 15 ++ webAO/client/createArea.ts | 30 +++ webAO/client/fetchLists.ts | 60 ++++++ webAO/client/fixLastArea.ts | 14 ++ webAO/client/handleBans.ts | 17 ++ webAO/client/handleCharacterInfo.ts | 105 ++++++++++ webAO/client/isAudio.ts | 6 + webAO/client/loadResources.ts | 79 ++++++++ webAO/client/saveChatLogHandle.ts | 26 +++ webAO/dom/showNameClick.ts | 2 +- 11 files changed, 364 insertions(+), 359 deletions(-) create mode 100644 webAO/client/addTrack.ts create mode 100644 webAO/client/createArea.ts create mode 100644 webAO/client/fetchLists.ts create mode 100644 webAO/client/fixLastArea.ts create mode 100644 webAO/client/handleBans.ts create mode 100644 webAO/client/handleCharacterInfo.ts create mode 100644 webAO/client/isAudio.ts create mode 100644 webAO/client/loadResources.ts create mode 100644 webAO/client/saveChatLogHandle.ts diff --git a/webAO/client.ts b/webAO/client.ts index 9588812..8b2f691 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -3,35 +3,18 @@ * made by sD, refactored by oldmud0 and Qubrick * credits to aleks for original idea and source */ -import {isLowMemory} from './client/isLowMemory' +import { isLowMemory } from './client/isLowMemory' import FingerprintJS from "@fingerprintjs/fingerprintjs"; -import vanilla_background_arr from "./constants/backgrounds.js"; -import vanilla_evidence_arr from "./constants/evidence.js"; -import {sender, ISender} from './client/sender/index' -import iniParse from "./iniParse"; -import getCookie from "./utils/getCookie"; -import fileExists from "./utils/fileExists.js"; +import { sender, ISender } from './client/sender/index' import queryParser from "./utils/queryParser"; import getResources from "./utils/getResources.js"; -import downloadFile from "./services/downloadFile"; import masterViewport, { Viewport } from "./viewport"; import { EventEmitter } from "events"; -import { area_click } from './dom/areaClick' import { onReplayGo } from './dom/onReplayGo' -import { safeTags, unescapeChat } from "./encoding"; -import { setChatbox } from "./dom/setChatbox"; -import { request } from "./services/request.js"; -import { - changeShoutVolume, - changeSFXVolume, - changeTestimonyVolume, -} from "./dom/changeVolume.js"; -import { getFilenameFromPath } from "./utils/paths"; import { packetHandler } from './packets/packetHandler' -import { showname_click } from './dom/showNameClick' +import { loadResources } from './client/loadResources' import { AO_HOST } from './client/aoHost' - -const version = process.env.npm_package_version; +import { fetchBackgroundList, fetchEvidenceList } from './client/fetchLists' let { ip: serverIP, mode, theme } = queryParser(); let THEME: string = theme || "default"; @@ -82,12 +65,10 @@ fpPromise .then((fp) => fp.get()) .then((result) => { hdid = result.visitorId; - console.log("NEW CLIENT"); - // Create the new client and connect it client = new Client(serverIP); client.connect() - isLowMemory(); + client.isLowMemory(); client.loadResources(); }); @@ -122,6 +103,8 @@ class Client extends EventEmitter { _lastTimeICReceived: any; viewport: Viewport; connect: () => void; + loadResources: () => void + isLowMemory: () => void constructor(address: string) { super(); @@ -163,6 +146,8 @@ class Client extends EventEmitter { this.sender = sender this.viewport = masterViewport(this); this._lastTimeICReceived = new Date(0); + loadResources + isLowMemory } /** @@ -188,8 +173,6 @@ class Client extends EventEmitter { : 0; } - - /** * Hook for sending messages to the client * @param {string} message the message to send @@ -204,7 +187,6 @@ class Client extends EventEmitter { * to the server. */ joinServer() { - console.log(this.sender) this.sender.sendServer(`HI#${hdid}#%`); this.sender.sendServer("ID#webAO#webAO#%"); if (mode !== "replay") { @@ -212,78 +194,6 @@ class Client extends EventEmitter { } } - /** - * Load game resources and stored settings. - */ - loadResources() { - document.getElementById("client_version").innerText = `version ${version}`; - - // Load background array to select - const background_select = ( - document.getElementById("bg_select") - ); - background_select.add(new Option("Custom", "0")); - vanilla_background_arr.forEach((background) => { - background_select.add(new Option(background)); - }); - - // Load evidence array to select - const evidence_select = ( - document.getElementById("evi_select") - ); - evidence_select.add(new Option("Custom", "0")); - vanilla_evidence_arr.forEach((evidence) => { - evidence_select.add(new Option(evidence)); - }); - - // Read cookies and set the UI to its values - (document.getElementById("OOC_name")).value = - getCookie("OOC_name") || - `web${String(Math.round(Math.random() * 100 + 10))}`; - - // Read cookies and set the UI to its values - const cookietheme = getCookie("theme") || "default"; - - (( - document.querySelector(`#client_themeselect [value="${cookietheme}"]`) - )).selected = true; - this.viewport.reloadTheme(); - - const cookiechatbox = getCookie("chatbox") || "dynamic"; - - (( - document.querySelector(`#client_chatboxselect [value="${cookiechatbox}"]`) - )).selected = true; - setChatbox(cookiechatbox); - - (document.getElementById("client_mvolume")).value = - getCookie("musicVolume") || "1"; - this.viewport.changeMusicVolume(); - (document.getElementById("client_sfxaudio")).volume = - Number(getCookie("sfxVolume")) || 1; - changeSFXVolume(); - (document.getElementById("client_shoutaudio")).volume = - Number(getCookie("shoutVolume")) || 1; - changeShoutVolume(); - (( - document.getElementById("client_testimonyaudio") - )).volume = Number(getCookie("testimonyVolume")) || 1; - changeTestimonyVolume(); - (document.getElementById("client_bvolume")).value = - getCookie("blipVolume") || "1"; - this.viewport.changeBlipVolume(); - - (document.getElementById("ic_chat_name")).value = - getCookie("ic_chat_name"); - (document.getElementById("showname")).checked = Boolean( - getCookie("showname") - ); - showname_click(null); - - (document.getElementById("client_callwords")).value = - getCookie("callwords"); - } - /** * Triggered when a connection is established to the server. */ @@ -369,129 +279,6 @@ class Client extends EventEmitter { } } - saveChatlogHandle = async () => { - const clientLog = document.getElementById("client_log"); - const icMessageLogs = clientLog.getElementsByTagName("p"); - const messages = []; - - for (let i = 0; i < icMessageLogs.length; i++) { - const SHOWNAME_POSITION = 0; - const TEXT_POSITION = 2; - const showname = icMessageLogs[i].children[SHOWNAME_POSITION].innerHTML; - const text = icMessageLogs[i].children[TEXT_POSITION].innerHTML; - const message = `${showname}: ${text}`; - messages.push(message); - } - const d = new Date(); - let ye = new Intl.DateTimeFormat("en", { year: "numeric" }).format(d); - let mo = new Intl.DateTimeFormat("en", { month: "short" }).format(d); - let da = new Intl.DateTimeFormat("en", { day: "2-digit" }).format(d); - - const filename = `chatlog-${da}-${mo}-${ye}`.toLowerCase(); - downloadFile(messages.join("\n"), filename); - - // Reset Chatbox to Empty - (document.getElementById("client_inputbox")).value = ""; - }; - - /** - * Handles the incoming character information, and downloads the sprite + ini for it - * @param {Array} chargs packet arguments - * @param {Number} charid character ID - */ - async handleCharacterInfo(chargs: string[], charid: number) { - const img = document.getElementById(`demo_${charid}`); - if (chargs[0]) { - let cini: any = {}; - const getCharIcon = async () => { - const extensions = [".png", ".webp"]; - img.alt = chargs[0]; - const charIconBaseUrl = `${AO_HOST}characters/${encodeURI( - chargs[0].toLowerCase() - )}/char_icon`; - for (let i = 0; i < extensions.length; i++) { - const fileUrl = charIconBaseUrl + extensions[i]; - const exists = await fileExists(fileUrl); - if (exists) { - img.alt = chargs[0]; - img.title = chargs[0]; - img.src = fileUrl; - return; - } - } - }; - getCharIcon(); - - // If the ini doesn't exist on the server this will throw an error - try { - const cinidata = await request( - `${AO_HOST}characters/${encodeURI(chargs[0].toLowerCase())}/char.ini` - ); - cini = iniParse(cinidata); - } catch (err) { - cini = {}; - img.classList.add("noini"); - console.warn(`character ${chargs[0]} is missing from webAO`); - // If it does, give the user a visual indication that the character is unusable - } - - const mute_select = ( - document.getElementById("mute_select") - ); - mute_select.add(new Option(safeTags(chargs[0]), String(charid))); - const pair_select = ( - document.getElementById("pair_select") - ); - pair_select.add(new Option(safeTags(chargs[0]), String(charid))); - - // sometimes ini files lack important settings - const default_options = { - name: chargs[0], - showname: chargs[0], - side: "def", - blips: "male", - chat: "", - category: "", - }; - cini.options = Object.assign(default_options, cini.options); - - // sometimes ini files lack important settings - const default_emotions = { - number: 0, - }; - cini.emotions = Object.assign(default_emotions, cini.emotions); - - this.chars[charid] = { - name: safeTags(chargs[0]), - showname: safeTags(cini.options.showname), - desc: safeTags(chargs[1]), - blips: safeTags(cini.options.blips).toLowerCase(), - gender: safeTags(cini.options.gender).toLowerCase(), - side: safeTags(cini.options.side).toLowerCase(), - chat: - cini.options.chat === "" - ? safeTags(cini.options.category).toLowerCase() - : safeTags(cini.options.chat).toLowerCase(), - evidence: chargs[3], - icon: img.src, - inifile: cini, - muted: false, - }; - - if ( - this.chars[charid].blips === "male" && - this.chars[charid].gender !== "male" && - this.chars[charid].gender !== "" - ) { - this.chars[charid].blips = this.chars[charid].gender; - } - - } else { - console.warn(`missing charid ${charid}`); - img.style.display = "none"; - } - } - resetMusicList() { this.musics = []; document.getElementById("client_musiclist").innerHTML = ""; @@ -501,144 +288,10 @@ class Client extends EventEmitter { this.areas = []; document.getElementById("areas").innerHTML = ""; - this.fetchBackgroundList(); - this.fetchEvidenceList(); - } - - async fetchBackgroundList() { - try { - const bgdata = await request(`${AO_HOST}backgrounds.json`); - const bg_array = JSON.parse(bgdata); - // the try catch will fail before here when there is no file - - const bg_select = document.getElementById("bg_select"); - bg_select.innerHTML = ""; - - bg_select.add(new Option("Custom", "0")); - bg_array.forEach((background: string) => { - bg_select.add(new Option(background)); - }); - } catch (err) { - console.warn("there was no backgrounds.json file"); - } - } - - async fetchCharacterList() { - try { - const chardata = await request(`${AO_HOST}characters.json`); - const char_array = JSON.parse(chardata); - // the try catch will fail before here when there is no file - - const char_select = ( - document.getElementById("client_ininame") - ); - char_select.innerHTML = ""; - - char_array.forEach((character: string) => { - char_select.add(new Option(character)); - }); - } catch (err) { - console.warn("there was no characters.json file"); - } - } - - async fetchEvidenceList() { - try { - const evidata = await request(`${AO_HOST}evidence.json`); - const evi_array = JSON.parse(evidata); - // the try catch will fail before here when there is no file - - const evi_select = ( - document.getElementById("evi_select") - ); - evi_select.innerHTML = ""; - - evi_array.forEach((evi: string) => { - evi_select.add(new Option(evi)); - }); - evi_select.add(new Option("Custom", "0")); - } catch (err) { - console.warn("there was no evidence.json file"); - } - } - - isAudio(trackname: string) { - const audioEndings = [".wav", ".mp3", ".ogg", ".opus"]; - return ( - audioEndings.filter((ending) => trackname.endsWith(ending)).length === 1 - ); - } - - addTrack(trackname: string) { - const newentry = document.createElement("OPTION"); - const songName = getFilenameFromPath(trackname); - newentry.text = unescapeChat(songName); - newentry.value = trackname; - (( - document.getElementById("client_musiclist") - )).options.add(newentry); - this.musics.push(trackname); + fetchBackgroundList(); + fetchEvidenceList(); } - createArea(id: number, name: string) { - const thisarea = { - name, - players: 0, - status: "IDLE", - cm: "", - locked: "FREE", - }; - - this.areas.push(thisarea); - - // Create area button - const newarea = document.createElement("SPAN"); - newarea.className = "area-button area-default"; - newarea.id = `area${id}`; - newarea.innerText = thisarea.name; - newarea.title = - `Players: ${thisarea.players}\n` + - `Status: ${thisarea.status}\n` + - `CM: ${thisarea.cm}\n` + - `Area lock: ${thisarea.locked}`; - newarea.onclick = function () { - area_click(newarea); - }; - - document.getElementById("areas").appendChild(newarea); - } - - /** - * Area list fuckery - */ - fix_last_area() { - if (this.areas.length > 0) { - const malplaced = this.areas.pop().name; - const areas = document.getElementById("areas"); - areas.removeChild(areas.lastChild); - this.addTrack(malplaced); - } - } - - /** - * Handles the kicked packet - * @param {string} type is it a kick or a ban - * @param {string} reason why - */ - handleBans(type: string, reason: string) { - document.getElementById("client_error").style.display = "flex"; - document.getElementById( - "client_errortext" - ).innerHTML = `${type}:
${reason.replace(/\n/g, "
")}`; - (( - document.getElementsByClassName("client_reconnect")[0] - )).style.display = "none"; - (( - document.getElementsByClassName("client_reconnect")[1] - )).style.display = "none"; - } } - - export default Client; \ No newline at end of file diff --git a/webAO/client/addTrack.ts b/webAO/client/addTrack.ts new file mode 100644 index 0000000..247f07e --- /dev/null +++ b/webAO/client/addTrack.ts @@ -0,0 +1,15 @@ +import { client } from "../client"; +import { unescapeChat } from "../encoding"; +import { getFilenameFromPath } from "../utils/paths"; + + +export const addTrack = (trackname: string) => { + const newentry = document.createElement("OPTION"); + const songName = getFilenameFromPath(trackname); + newentry.text = unescapeChat(songName); + newentry.value = trackname; + (( + document.getElementById("client_musiclist") + )).options.add(newentry); + client.musics.push(trackname); +} \ No newline at end of file diff --git a/webAO/client/createArea.ts b/webAO/client/createArea.ts new file mode 100644 index 0000000..63af644 --- /dev/null +++ b/webAO/client/createArea.ts @@ -0,0 +1,30 @@ +import { client } from "../client"; +import { area_click } from "../dom/areaClick"; + +export const createArea = (id: number, name: string) => { + const thisarea = { + name, + players: 0, + status: "IDLE", + cm: "", + locked: "FREE", + }; + + client.areas.push(thisarea); + + // Create area button + const newarea = document.createElement("SPAN"); + newarea.className = "area-button area-default"; + newarea.id = `area${id}`; + newarea.innerText = thisarea.name; + newarea.title = + `Players: ${thisarea.players}\n` + + `Status: ${thisarea.status}\n` + + `CM: ${thisarea.cm}\n` + + `Area lock: ${thisarea.locked}`; + newarea.onclick = function () { + area_click(newarea); + }; + + document.getElementById("areas")!.appendChild(newarea); +} \ No newline at end of file diff --git a/webAO/client/fetchLists.ts b/webAO/client/fetchLists.ts new file mode 100644 index 0000000..e9772cb --- /dev/null +++ b/webAO/client/fetchLists.ts @@ -0,0 +1,60 @@ +import { AO_HOST } from "./aoHost"; +import { request } from "../services/request.js"; + +export const fetchBackgroundList = async () => { + try { + const bgdata = await request(`${AO_HOST}backgrounds.json`); + const bg_array = JSON.parse(bgdata); + // the try catch will fail before here when there is no file + + const bg_select = document.getElementById("bg_select"); + bg_select.innerHTML = ""; + + bg_select.add(new Option("Custom", "0")); + bg_array.forEach((background: string) => { + bg_select.add(new Option(background)); + }); + } catch (err) { + console.warn("there was no backgrounds.json file"); + } +} + +export const fetchCharacterList = async () => { + try { + const chardata = await request(`${AO_HOST}characters.json`); + const char_array = JSON.parse(chardata); + // the try catch will fail before here when there is no file + + const char_select = ( + document.getElementById("client_ininame") + ); + char_select.innerHTML = ""; + + char_array.forEach((character: string) => { + char_select.add(new Option(character)); + }); + } catch (err) { + console.warn("there was no characters.json file"); + } +} + + +export const fetchEvidenceList = async () => { + try { + const evidata = await request(`${AO_HOST}evidence.json`); + const evi_array = JSON.parse(evidata); + // the try catch will fail before here when there is no file + + const evi_select = ( + document.getElementById("evi_select") + ); + evi_select.innerHTML = ""; + + evi_array.forEach((evi: string) => { + evi_select.add(new Option(evi)); + }); + evi_select.add(new Option("Custom", "0")); + } catch (err) { + console.warn("there was no evidence.json file"); + } +} \ No newline at end of file diff --git a/webAO/client/fixLastArea.ts b/webAO/client/fixLastArea.ts new file mode 100644 index 0000000..e4d8725 --- /dev/null +++ b/webAO/client/fixLastArea.ts @@ -0,0 +1,14 @@ +import { client } from "../client"; + + +/** + * Area list fuckery + */ +export const fix_last_area = () => { + if (client.areas.length > 0) { + const malplaced = client.areas.pop().name; + const areas = document.getElementById("areas")!; + areas.removeChild(areas.lastChild); + client.addTrack(malplaced); + } +} \ No newline at end of file diff --git a/webAO/client/handleBans.ts b/webAO/client/handleBans.ts new file mode 100644 index 0000000..b977fc8 --- /dev/null +++ b/webAO/client/handleBans.ts @@ -0,0 +1,17 @@ +/** + * Handles the kicked packet + * @param {string} type is it a kick or a ban + * @param {string} reason why + */ +export const handleBans = (type: string, reason: string) => { + document.getElementById("client_error")!.style.display = "flex"; + document.getElementById( + "client_errortext" + )!.innerHTML = `${type}:
${reason.replace(/\n/g, "
")}`; + (( + document.getElementsByClassName("client_reconnect")[0] + )).style.display = "none"; + (( + document.getElementsByClassName("client_reconnect")[1] + )).style.display = "none"; +} \ No newline at end of file diff --git a/webAO/client/handleCharacterInfo.ts b/webAO/client/handleCharacterInfo.ts new file mode 100644 index 0000000..9d74a8b --- /dev/null +++ b/webAO/client/handleCharacterInfo.ts @@ -0,0 +1,105 @@ +import { client } from "../client"; +import { safeTags } from "../encoding"; +import iniParse from "../iniParse"; +import request from "../services/request"; +import fileExists from "../utils/fileExists"; +import { AO_HOST } from "./aoHost"; + + +/** + * Handles the incoming character information, and downloads the sprite + ini for it + * @param {Array} chargs packet arguments + * @param {Number} charid character ID + */ +export const handleCharacterInfo = async (chargs: string[], charid: number) => { + const img = document.getElementById(`demo_${charid}`); + if (chargs[0]) { + let cini: any = {}; + const getCharIcon = async () => { + const extensions = [".png", ".webp"]; + img.alt = chargs[0]; + const charIconBaseUrl = `${AO_HOST}characters/${encodeURI( + chargs[0].toLowerCase() + )}/char_icon`; + for (let i = 0; i < extensions.length; i++) { + const fileUrl = charIconBaseUrl + extensions[i]; + const exists = await fileExists(fileUrl); + if (exists) { + img.alt = chargs[0]; + img.title = chargs[0]; + img.src = fileUrl; + return; + } + } + }; + getCharIcon(); + + // If the ini doesn't exist on the server this will throw an error + try { + const cinidata = await request( + `${AO_HOST}characters/${encodeURI(chargs[0].toLowerCase())}/char.ini` + ); + cini = iniParse(cinidata); + } catch (err) { + cini = {}; + img.classList.add("noini"); + console.warn(`character ${chargs[0]} is missing from webAO`); + // If it does, give the user a visual indication that the character is unusable + } + + const mute_select = ( + document.getElementById("mute_select") + ); + mute_select.add(new Option(safeTags(chargs[0]), String(charid))); + const pair_select = ( + document.getElementById("pair_select") + ); + pair_select.add(new Option(safeTags(chargs[0]), String(charid))); + + // sometimes ini files lack important settings + const default_options = { + name: chargs[0], + showname: chargs[0], + side: "def", + blips: "male", + chat: "", + category: "", + }; + cini.options = Object.assign(default_options, cini.options); + + // sometimes ini files lack important settings + const default_emotions = { + number: 0, + }; + cini.emotions = Object.assign(default_emotions, cini.emotions); + + client.chars[charid] = { + name: safeTags(chargs[0]), + showname: safeTags(cini.options.showname), + desc: safeTags(chargs[1]), + blips: safeTags(cini.options.blips).toLowerCase(), + gender: safeTags(cini.options.gender).toLowerCase(), + side: safeTags(cini.options.side).toLowerCase(), + chat: + cini.options.chat === "" + ? safeTags(cini.options.category).toLowerCase() + : safeTags(cini.options.chat).toLowerCase(), + evidence: chargs[3], + icon: img.src, + inifile: cini, + muted: false, + }; + + if ( + client.chars[charid].blips === "male" && + client.chars[charid].gender !== "male" && + client.chars[charid].gender !== "" + ) { + client.chars[charid].blips = client.chars[charid].gender; + } + + } else { + console.warn(`missing charid ${charid}`); + img.style.display = "none"; + } +} \ No newline at end of file diff --git a/webAO/client/isAudio.ts b/webAO/client/isAudio.ts new file mode 100644 index 0000000..430f543 --- /dev/null +++ b/webAO/client/isAudio.ts @@ -0,0 +1,6 @@ +export const isAudio = (trackname: string) => { + const audioEndings = [".wav", ".mp3", ".ogg", ".opus"]; + return ( + audioEndings.filter((ending) => trackname.endsWith(ending)).length === 1 + ); +} \ No newline at end of file diff --git a/webAO/client/loadResources.ts b/webAO/client/loadResources.ts new file mode 100644 index 0000000..7039333 --- /dev/null +++ b/webAO/client/loadResources.ts @@ -0,0 +1,79 @@ +import getCookie from "../utils/getCookie"; +import vanilla_evidence_arr from "../constants/evidence.js"; +import vanilla_background_arr from "../constants/backgrounds.js"; +import { client } from "../client"; +import { setChatbox } from "../dom/setChatbox"; +import { changeSFXVolume, changeShoutVolume, changeTestimonyVolume } from "../dom/changeVolume"; +import { showname_click } from "../dom/showNameClick"; + +const version = process.env.npm_package_version; +/** + * Load game resources and stored settings. + */ +export const loadResources = () => { + document.getElementById("client_version")!.innerText = `version ${version}`; + // Load background array to select + const background_select = ( + document.getElementById("bg_select") + ); + background_select.add(new Option("Custom", "0")); + vanilla_background_arr.forEach((background) => { + background_select.add(new Option(background)); + }); + + // Load evidence array to select + const evidence_select = ( + document.getElementById("evi_select") + ); + evidence_select.add(new Option("Custom", "0")); + vanilla_evidence_arr.forEach((evidence) => { + evidence_select.add(new Option(evidence)); + }); + + // Read cookies and set the UI to its values + (document.getElementById("OOC_name")).value = + getCookie("OOC_name") || + `web${String(Math.round(Math.random() * 100 + 10))}`; + + // Read cookies and set the UI to its values + const cookietheme = getCookie("theme") || "default"; + + (( + document.querySelector(`#client_themeselect [value="${cookietheme}"]`) + )).selected = true; + client.viewport.reloadTheme(); + + const cookiechatbox = getCookie("chatbox") || "dynamic"; + + (( + document.querySelector(`#client_chatboxselect [value="${cookiechatbox}"]`) + )).selected = true; + setChatbox(cookiechatbox); + + (document.getElementById("client_mvolume")).value = + getCookie("musicVolume") || "1"; + client.viewport.changeMusicVolume(); + (document.getElementById("client_sfxaudio")).volume = + Number(getCookie("sfxVolume")) || 1; + changeSFXVolume(); + (document.getElementById("client_shoutaudio")).volume = + Number(getCookie("shoutVolume")) || 1; + changeShoutVolume(); + (( + document.getElementById("client_testimonyaudio") + )).volume = Number(getCookie("testimonyVolume")) || 1; + changeTestimonyVolume(); + (document.getElementById("client_bvolume")).value = + getCookie("blipVolume") || "1"; + client.viewport.changeBlipVolume(); + + (document.getElementById("ic_chat_name")).value = + getCookie("ic_chat_name"); + (document.getElementById("showname")).checked = Boolean( + getCookie("showname") + ); + showname_click(null); + + (document.getElementById("client_callwords")).value = + getCookie("callwords"); +} \ No newline at end of file diff --git a/webAO/client/saveChatLogHandle.ts b/webAO/client/saveChatLogHandle.ts new file mode 100644 index 0000000..bcc1075 --- /dev/null +++ b/webAO/client/saveChatLogHandle.ts @@ -0,0 +1,26 @@ +import downloadFile from "../services/downloadFile"; + +export const saveChatlogHandle = async () => { + const clientLog = document.getElementById("client_log")!; + const icMessageLogs = clientLog.getElementsByTagName("p"); + const messages: string[] = []; + + for (let i = 0; i < icMessageLogs.length; i++) { + const SHOWNAME_POSITION = 0; + const TEXT_POSITION = 2; + const showname = icMessageLogs[i].children[SHOWNAME_POSITION].innerHTML; + const text = icMessageLogs[i].children[TEXT_POSITION].innerHTML; + const message = `${showname}: ${text}`; + messages.push(message); + } + const d = new Date(); + let ye = new Intl.DateTimeFormat("en", { year: "numeric" }).format(d); + let mo = new Intl.DateTimeFormat("en", { month: "short" }).format(d); + let da = new Intl.DateTimeFormat("en", { day: "2-digit" }).format(d); + + const filename = `chatlog-${da}-${mo}-${ye}`.toLowerCase(); + downloadFile(messages.join("\n"), filename); + + // Reset Chatbox to Empty + (document.getElementById("client_inputbox")).value = ""; +}; \ No newline at end of file diff --git a/webAO/dom/showNameClick.ts b/webAO/dom/showNameClick.ts index 265f6c8..3e48b70 100644 --- a/webAO/dom/showNameClick.ts +++ b/webAO/dom/showNameClick.ts @@ -5,7 +5,7 @@ import setCookie from "../utils/setCookie"; * Triggered when the showname checkboc is clicked * @param {MouseEvent} event */ -export function showname_click(_event: Event) { +export function showname_click(_event: Event | null) { setCookie( "showname", String((document.getElementById("showname")).checked) -- cgit From 93979636fb5d1c60f0da3290e80eb3ca9ead992f Mon Sep 17 00:00:00 2001 From: Caleb Date: Fri, 9 Sep 2022 18:46:42 -0400 Subject: Migrated functions --- webAO/client/fixLastArea.ts | 3 +- webAO/client/sender/sendOOC.ts | 4 +- webAO/dom/iniEdit.ts | 3 +- webAO/packets/handlers/handleBD.ts | 5 +- webAO/packets/handlers/handleCI.ts | 3 +- webAO/packets/handlers/handleEM.ts | 14 ++- webAO/packets/handlers/handleFA.ts | 3 +- webAO/packets/handlers/handleFM.ts | 4 +- webAO/packets/handlers/handleKB.ts | 5 +- webAO/packets/handlers/handleKK.ts | 5 +- webAO/packets/handlers/handleMC.ts | 3 +- webAO/packets/handlers/handleMS.ts | 226 +++++++++++++++++----------------- webAO/packets/handlers/handleSC.ts | 3 +- webAO/packets/handlers/handleSM.ts | 15 ++- webAO/packets/handlers/handleackMS.ts | 2 +- webAO/viewport.ts | 25 ++-- 16 files changed, 171 insertions(+), 152 deletions(-) diff --git a/webAO/client/fixLastArea.ts b/webAO/client/fixLastArea.ts index e4d8725..f1aa99f 100644 --- a/webAO/client/fixLastArea.ts +++ b/webAO/client/fixLastArea.ts @@ -1,4 +1,5 @@ import { client } from "../client"; +import { addTrack } from "./addTrack"; /** @@ -9,6 +10,6 @@ export const fix_last_area = () => { const malplaced = client.areas.pop().name; const areas = document.getElementById("areas")!; areas.removeChild(areas.lastChild); - client.addTrack(malplaced); + addTrack(malplaced); } } \ No newline at end of file diff --git a/webAO/client/sender/sendOOC.ts b/webAO/client/sender/sendOOC.ts index a410b5f..9674ad9 100644 --- a/webAO/client/sender/sendOOC.ts +++ b/webAO/client/sender/sendOOC.ts @@ -1,7 +1,7 @@ import { client } from '../../client' import { escapeChat } from '../../encoding'; import setCookie from '../../utils/setCookie'; - +import { saveChatlogHandle } from '../../client/saveChatLogHandle' /** * Sends an out-of-character chat message. * @param {string} message the message to send @@ -17,7 +17,7 @@ export const sendOOC = (message: string) => { const oocMessage = `${escapeChat(message)}`; const commands = { - "/save_chatlog": client.saveChatlogHandle, + "/save_chatlog": saveChatlogHandle, }; const commandsMap = new Map(Object.entries(commands)); diff --git a/webAO/dom/iniEdit.ts b/webAO/dom/iniEdit.ts index 359a226..0710de9 100644 --- a/webAO/dom/iniEdit.ts +++ b/webAO/dom/iniEdit.ts @@ -1,4 +1,5 @@ import { client } from "../client"; +import { handleCharacterInfo } from "../client/handleCharacterInfo"; import { packetHandler } from "../packets/packetHandler"; /** @@ -8,7 +9,7 @@ export async function iniedit() { const ininame = (document.getElementById("client_ininame")) .value; const inicharID = client.charID; - await client.handleCharacterInfo(ininame.split("&"), inicharID); + await handleCharacterInfo(ininame.split("&"), inicharID); packetHandler.get("PV")!(`PV#0#CID#${inicharID}`.split("#")); } window.iniedit = iniedit; diff --git a/webAO/packets/handlers/handleBD.ts b/webAO/packets/handlers/handleBD.ts index 4ec291e..dbfb54b 100644 --- a/webAO/packets/handlers/handleBD.ts +++ b/webAO/packets/handlers/handleBD.ts @@ -1,5 +1,6 @@ -import { client, setBanned } from "../../client"; +import { setBanned } from "../../client"; import { safeTags } from "../../encoding"; +import { handleBans } from '../../client/handleBans' /** @@ -8,6 +9,6 @@ import { safeTags } from "../../encoding"; * @param {Array} args ban reason */ export const handleBD = (args: string[]) => { - client.handleBans("Banned", safeTags(args[1])); + handleBans("Banned", safeTags(args[1])); setBanned(true); } \ No newline at end of file diff --git a/webAO/packets/handlers/handleCI.ts b/webAO/packets/handlers/handleCI.ts index 53e42f7..cb693bc 100644 --- a/webAO/packets/handlers/handleCI.ts +++ b/webAO/packets/handlers/handleCI.ts @@ -1,4 +1,5 @@ import { client } from '../../client' +import { handleCharacterInfo } from '../../client/handleCharacterInfo' /** * Handles incoming character information, bundling multiple characters * per packet. @@ -18,7 +19,7 @@ export const handleCI = (args: string[]) => { (( document.getElementById("client_loadingbar") )).value = charid; - setTimeout(() => client.handleCharacterInfo(chargs, charid), 500); + setTimeout(() => handleCharacterInfo(chargs, charid), 500); } } // Request the next pack diff --git a/webAO/packets/handlers/handleEM.ts b/webAO/packets/handlers/handleEM.ts index 9f3cb87..5e49ea4 100644 --- a/webAO/packets/handlers/handleEM.ts +++ b/webAO/packets/handlers/handleEM.ts @@ -1,4 +1,8 @@ import { client } from '../../client' +import { addTrack } from '../../client/addTrack'; +import { createArea } from '../../client/createArea'; +import { fix_last_area } from '../../client/fixLastArea'; +import { isAudio } from '../../client/isAudio'; import { safeTags } from '../../encoding'; /** @@ -23,13 +27,13 @@ export const handleEM = (args: string[]) => { )).value = client.char_list_length + client.evidence_list_length + trackindex; if (client.musics_time) { - client.addTrack(trackname); - } else if (client.isAudio(trackname)) { + addTrack(trackname); + } else if (isAudio(trackname)) { client.musics_time = true; - client.fix_last_area(); - client.addTrack(trackname); + fix_last_area(); + addTrack(trackname); } else { - client.createArea(trackindex, trackname); + createArea(trackindex, trackname); } } } diff --git a/webAO/packets/handlers/handleFA.ts b/webAO/packets/handlers/handleFA.ts index ccfe923..7a373e8 100644 --- a/webAO/packets/handlers/handleFA.ts +++ b/webAO/packets/handlers/handleFA.ts @@ -1,4 +1,5 @@ import { client } from '../../client' +import { createArea } from '../../client/createArea'; import { safeTags } from '../../encoding'; /** @@ -9,6 +10,6 @@ export const handleFA = (args: string[]) => { client.resetAreaList(); for (let i = 1; i < args.length - 1; i++) { - client.createArea(i - 1, safeTags(args[i])); + createArea(i - 1, safeTags(args[i])); } } diff --git a/webAO/packets/handlers/handleFM.ts b/webAO/packets/handlers/handleFM.ts index 630477b..fce10e3 100644 --- a/webAO/packets/handlers/handleFM.ts +++ b/webAO/packets/handlers/handleFM.ts @@ -1,7 +1,7 @@ import { client } from "../../client"; +import { addTrack } from "../../client/addTrack"; import { safeTags } from "../../encoding"; - /** * Handles updated music list * @param {Array} args packet arguments @@ -11,6 +11,6 @@ export const handleFM = (args: string[]) => { for (let i = 1; i < args.length - 1; i++) { // Check when found the song for the first time - client.addTrack(safeTags(args[i])); + addTrack(safeTags(args[i])); } } diff --git a/webAO/packets/handlers/handleKB.ts b/webAO/packets/handlers/handleKB.ts index 8705b83..b0aa2b2 100644 --- a/webAO/packets/handlers/handleKB.ts +++ b/webAO/packets/handlers/handleKB.ts @@ -1,5 +1,6 @@ -import { client, setBanned } from "../../client"; +import { setBanned } from "../../client"; import { safeTags } from "../../encoding"; +import { handleBans } from '../../client/handleBans' /** * Handles the banned packet @@ -7,6 +8,6 @@ import { safeTags } from "../../encoding"; * @param {Array} args ban reason */ export const handleKB = (args: string[]) => { - client.handleBans("Banned", safeTags(args[1])); + handleBans("Banned", safeTags(args[1])); setBanned(true); } diff --git a/webAO/packets/handlers/handleKK.ts b/webAO/packets/handlers/handleKK.ts index fd9a88c..c8a97b1 100644 --- a/webAO/packets/handlers/handleKK.ts +++ b/webAO/packets/handlers/handleKK.ts @@ -1,11 +1,10 @@ -import { client } from "../../client"; import { safeTags } from "../../encoding"; - +import { handleBans } from '../../client/handleBans' /** * Handles the kicked packet * @param {Array} args kick reason */ export const handleKK = (args: string[]) => { - client.handleBans("Kicked", safeTags(args[1])); + handleBans("Kicked", safeTags(args[1])); } diff --git a/webAO/packets/handlers/handleMC.ts b/webAO/packets/handlers/handleMC.ts index bf60eb9..aeb178d 100644 --- a/webAO/packets/handlers/handleMC.ts +++ b/webAO/packets/handlers/handleMC.ts @@ -1,6 +1,7 @@ import { prepChat } from "../../encoding"; -import { appendICLog, client } from '../../client' +import { client } from '../../client' import { AO_HOST } from "../../client/aoHost"; +import { appendICLog } from '../../client/appendICLog' /** * Handles a music change to an arbitrary resource. diff --git a/webAO/packets/handlers/handleMS.ts b/webAO/packets/handlers/handleMS.ts index 0aad19a..1256900 100644 --- a/webAO/packets/handlers/handleMS.ts +++ b/webAO/packets/handlers/handleMS.ts @@ -1,4 +1,6 @@ -import { client, extrafeatures, resetICParams, UPDATE_INTERVAL } from "../../client"; +import { client, extrafeatures, UPDATE_INTERVAL } from "../../client"; +import { handleCharacterInfo } from "../../client/handleCharacterInfo"; +import { resetICParams } from "../../client/resetICParams"; import { prepChat, safeTags } from "../../encoding"; /** @@ -6,119 +8,104 @@ import { prepChat, safeTags } from "../../encoding"; * @param {*} args packet arguments */ export const handleMS = (args: string[]) => { - // TODO: this if-statement might be a bug. - if (args[4] !== client.viewport.chatmsg.content) { - document.getElementById("client_inner_chat")!.innerHTML = ""; + // TODO: this if-statement might be a bug. + if (args[4] !== client.viewport.chatmsg.content) { + document.getElementById("client_inner_chat")!.innerHTML = ""; - const char_id = Number(args[9]); - const char_name = safeTags(args[3]); + const char_id = Number(args[9]); + const char_name = safeTags(args[3]); - let msg_nameplate = args[3]; - let msg_blips = "male"; - let char_chatbox = "default"; - let char_muted = false; + let msg_nameplate = args[3]; + let msg_blips = "male"; + let char_chatbox = "default"; + let char_muted = false; - if (char_id < client.char_list_length && char_id >= 0) { - if(client.chars[char_id].name !== char_name) { + if (char_id < client.char_list_length && char_id >= 0) { + if (client.chars[char_id].name !== char_name) { console.info( `${client.chars[char_id].name} is iniediting to ${char_name}` ); const chargs = (`${char_name}&` + "iniediter").split("&"); - client.handleCharacterInfo(chargs, char_id); - } + handleCharacterInfo(chargs, char_id); } + } - try { - msg_nameplate = client.chars[char_id].showname; - } catch (e) { - msg_nameplate = args[3]; - } + try { + msg_nameplate = client.chars[char_id].showname; + } catch (e) { + msg_nameplate = args[3]; + } - try { - msg_blips = client.chars[char_id].blips; - } catch (e) {} + try { + msg_blips = client.chars[char_id].blips; + } catch (e) { } - try { - char_chatbox = client.chars[char_id].chat; - } catch (e) { - char_chatbox = "default"; - } + try { + char_chatbox = client.chars[char_id].chat; + } catch (e) { + char_chatbox = "default"; + } - try { - char_muted = client.chars[char_id].muted; - } catch (e) { - char_muted = false; - console.error("we're still missing some character data"); - } + try { + char_muted = client.chars[char_id].muted; + } catch (e) { + char_muted = false; + console.error("we're still missing some character data"); + } + + if (char_muted === false) { + let chatmsg = { + deskmod: safeTags(args[1]).toLowerCase(), + preanim: safeTags(args[2]).toLowerCase(), // get preanim + nameplate: msg_nameplate, + chatbox: char_chatbox, + name: char_name, + sprite: safeTags(args[4]).toLowerCase(), + content: prepChat(args[5]), // Escape HTML tags + side: args[6].toLowerCase(), + sound: safeTags(args[7]).toLowerCase(), + blips: safeTags(msg_blips), + type: Number(args[8]), + charid: char_id, + snddelay: Number(args[10]), + objection: Number(args[11]), + evidence: safeTags(args[12]), + flip: Number(args[13]), + flash: Number(args[14]), + color: Number(args[15]), + speed: UPDATE_INTERVAL, + }; - if (char_muted === false) { - let chatmsg = { - deskmod: safeTags(args[1]).toLowerCase(), - preanim: safeTags(args[2]).toLowerCase(), // get preanim - nameplate: msg_nameplate, - chatbox: char_chatbox, - name: char_name, - sprite: safeTags(args[4]).toLowerCase(), - content: prepChat(args[5]), // Escape HTML tags - side: args[6].toLowerCase(), - sound: safeTags(args[7]).toLowerCase(), - blips: safeTags(msg_blips), - type: Number(args[8]), - charid: char_id, - snddelay: Number(args[10]), - objection: Number(args[11]), - evidence: safeTags(args[12]), - flip: Number(args[13]), - flash: Number(args[14]), - color: Number(args[15]), - speed: UPDATE_INTERVAL, + if (extrafeatures.includes("cccc_ic_support")) { + const extra_cccc = { + showname: safeTags(args[16]), + other_charid: Number(args[17]), + other_name: safeTags(args[18]), + other_emote: safeTags(args[19]), + self_offset: args[20].split(""), // HACK: here as well, client is fucked and uses this instead of & + other_offset: args[21].split(""), + other_flip: Number(args[22]), + noninterrupting_preanim: Number(args[23]), }; + chatmsg = Object.assign(extra_cccc, chatmsg); - if (extrafeatures.includes("cccc_ic_support")) { - const extra_cccc = { - showname: safeTags(args[16]), - other_charid: Number(args[17]), - other_name: safeTags(args[18]), - other_emote: safeTags(args[19]), - self_offset: args[20].split(""), // HACK: here as well, client is fucked and uses this instead of & - other_offset: args[21].split(""), - other_flip: Number(args[22]), - noninterrupting_preanim: Number(args[23]), + if (extrafeatures.includes("looping_sfx")) { + const extra_27 = { + looping_sfx: Number(args[24]), + screenshake: Number(args[25]), + frame_screenshake: safeTags(args[26]), + frame_realization: safeTags(args[27]), + frame_sfx: safeTags(args[28]), }; - chatmsg = Object.assign(extra_cccc, chatmsg); + chatmsg = Object.assign(extra_27, chatmsg); - if (extrafeatures.includes("looping_sfx")) { - const extra_27 = { - looping_sfx: Number(args[24]), - screenshake: Number(args[25]), - frame_screenshake: safeTags(args[26]), - frame_realization: safeTags(args[27]), - frame_sfx: safeTags(args[28]), + if (extrafeatures.includes("effects")) { + const extra_28 = { + additive: Number(args[29]), + effects: args[30].split("|"), }; - chatmsg = Object.assign(extra_27, chatmsg); - - if (extrafeatures.includes("effects")) { - const extra_28 = { - additive: Number(args[29]), - effects: args[30].split("|"), - }; - chatmsg = Object.assign(extra_28, chatmsg); - } else { - const extra_28 = { - additive: 0, - effects: ["", "", ""], - }; - chatmsg = Object.assign(extra_28, chatmsg); - } + chatmsg = Object.assign(extra_28, chatmsg); } else { - const extra_27 = { - looping_sfx: 0, - screenshake: 0, - frame_screenshake: "", - frame_realization: "", - frame_sfx: "", - }; - chatmsg = Object.assign(extra_27, chatmsg); const extra_28 = { additive: 0, effects: ["", "", ""], @@ -126,17 +113,6 @@ export const handleMS = (args: string[]) => { chatmsg = Object.assign(extra_28, chatmsg); } } else { - const extra_cccc = { - showname: "", - other_charid: 0, - other_name: "", - other_emote: "", - self_offset: [0, 0], - other_offset: [0, 0], - other_flip: 0, - noninterrupting_preanim: 0, - }; - chatmsg = Object.assign(extra_cccc, chatmsg); const extra_27 = { looping_sfx: 0, screenshake: 0, @@ -151,12 +127,38 @@ export const handleMS = (args: string[]) => { }; chatmsg = Object.assign(extra_28, chatmsg); } + } else { + const extra_cccc = { + showname: "", + other_charid: 0, + other_name: "", + other_emote: "", + self_offset: [0, 0], + other_offset: [0, 0], + other_flip: 0, + noninterrupting_preanim: 0, + }; + chatmsg = Object.assign(extra_cccc, chatmsg); + const extra_27 = { + looping_sfx: 0, + screenshake: 0, + frame_screenshake: "", + frame_realization: "", + frame_sfx: "", + }; + chatmsg = Object.assign(extra_27, chatmsg); + const extra_28 = { + additive: 0, + effects: ["", "", ""], + }; + chatmsg = Object.assign(extra_28, chatmsg); + } - // our own message appeared, reset the buttons - if (chatmsg.charid === client.charID) { - resetICParams(); - } - client.viewport.handle_ic_speaking(chatmsg); // no await + // our own message appeared, reset the buttons + if (chatmsg.charid === client.charID) { + resetICParams(); } + client.viewport.handle_ic_speaking(chatmsg); // no await } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/webAO/packets/handlers/handleSC.ts b/webAO/packets/handlers/handleSC.ts index f4953e0..b42a4cd 100644 --- a/webAO/packets/handlers/handleSC.ts +++ b/webAO/packets/handlers/handleSC.ts @@ -1,6 +1,7 @@ import queryParser from "../../utils/queryParser"; import { client } from '../../client' +import { handleCharacterInfo } from "../../client/handleCharacterInfo"; let { mode } = queryParser(); /** @@ -30,7 +31,7 @@ export const handleSC = async (args: string[]) => { document.getElementById("client_loadingbar") )).value = charid; await sleep(0.1); // TODO: Too many network calls without this. net::ERR_INSUFFICIENT_RESOURCES - client.handleCharacterInfo(chargs, charid); + handleCharacterInfo(chargs, charid); } // We're done with the characters, request the music client.sender.sendServer("RM#%"); diff --git a/webAO/packets/handlers/handleSM.ts b/webAO/packets/handlers/handleSM.ts index 48f9cd9..08bf7e0 100644 --- a/webAO/packets/handlers/handleSM.ts +++ b/webAO/packets/handlers/handleSM.ts @@ -1,4 +1,8 @@ import { client } from '../../client' +import { addTrack } from '../../client/addTrack' +import { isAudio } from '../../client/isAudio' +import { fix_last_area } from '../../client/fixLastArea' +import { createArea } from '../../client/createArea' /** * Handles incoming music information, containing all music in one packet. * @param {Array} args packet arguments @@ -21,14 +25,15 @@ export const handleSM = (args: string[]) => { document.getElementById("client_loadingbar") )).value = client.char_list_length + client.evidence_list_length + i; if (client.musics_time) { - client.addTrack(trackname); - } else if (client.isAudio(trackname)) { + addTrack(trackname); + } else if (isAudio(trackname)) { client.musics_time = true; - client.fix_last_area(); - client.addTrack(trackname); + fix_last_area(); + addTrack(trackname); } else { - client.createArea(trackindex, trackname); + createArea(trackindex, trackname); } + } // Music done, carry on diff --git a/webAO/packets/handlers/handleackMS.ts b/webAO/packets/handlers/handleackMS.ts index 2b971b0..dcca118 100644 --- a/webAO/packets/handlers/handleackMS.ts +++ b/webAO/packets/handlers/handleackMS.ts @@ -1,4 +1,4 @@ -import { resetICParams } from "../../client"; +import { resetICParams } from '../../client/resetICParams' /** * server got our message diff --git a/webAO/viewport.ts b/webAO/viewport.ts index 6c39784..7716409 100644 --- a/webAO/viewport.ts +++ b/webAO/viewport.ts @@ -1,19 +1,20 @@ import tryUrls from "./utils/tryUrls"; import fileExists from "./utils/fileExists"; import Client, { delay } from "./client"; -import {opusCheck} from './dom/opusCheck' +import { opusCheck } from './dom/opusCheck' import { UPDATE_INTERVAL } from "./client"; import { setChatbox } from "./dom/setChatbox"; import { resizeChatbox } from "./dom/resizeChatbox"; import transparentPng from "./constants/transparentPng"; import mlConfig from "./utils/aoml"; -import { appendICLog } from "./client"; -import { checkCallword } from "./client"; import setEmote from "./client/setEmote"; import getAnimLength from "./utils/getAnimLength"; import { safeTags } from "./encoding"; import setCookie from "./utils/setCookie"; import { AO_HOST } from "./client/aoHost"; +import { appendICLog } from "./client/appendICLog"; +import { checkCallword } from './client/checkCallword' + interface ChatMsg { content: string; objection: number; @@ -449,7 +450,7 @@ const viewport = (masterClient: Client): Viewport => { const displayname = (document.getElementById("showname")).checked && - chatmsg.showname !== "" + chatmsg.showname !== "" ? chatmsg.showname : chatmsg.nameplate; @@ -620,9 +621,9 @@ const viewport = (masterClient: Client): Viewport => { blipChannels.forEach( (channel: HTMLAudioElement) => - (channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI( - chatmsg.blips.toLowerCase() - )}.opus`) + (channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI( + chatmsg.blips.toLowerCase() + )}.opus`) ); // process markup @@ -637,15 +638,15 @@ const viewport = (masterClient: Client): Viewport => { fg.style.animation = ""; const effectName = chatmsg.effects[0].toLowerCase(); const badEffects = ["", "-", "none"]; - if (effectName.startsWith("rain") ) { + if (effectName.startsWith("rain")) { (document.getElementById("effect_css")).href = "styles/effects/rain.css"; let intensity = 200; - if(effectName.endsWith("weak")) { + if (effectName.endsWith("weak")) { intensity = 100; } else if (effectName.endsWith("strong")) { intensity = 400; } - if ( intensity < fg.childElementCount) + if (intensity < fg.childElementCount) fg.innerHTML = ''; else intensity = intensity - fg.childElementCount; @@ -653,9 +654,9 @@ const viewport = (masterClient: Client): Viewport => { for (let i = 0; i < intensity; i++) { let drop = document.createElement("p"); drop.style.left = (Math.random() * 100) + "%"; - drop.style.animationDelay = String(Math.random())+"s"; + drop.style.animationDelay = String(Math.random()) + "s"; fg.appendChild(drop) - } + } } else if ( chatmsg.effects[0] && !badEffects.includes(effectName) -- cgit From 108636666d474119892c4b3a2f3beadb767b006e Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 10 Sep 2022 11:09:49 -0400 Subject: Structured viewport a little differently --- tsconfig.json | 2 +- webAO/client.ts | 3 +- webAO/client/loadResources.ts | 4 +- webAO/dom/changeBlipVolume.ts | 15 + webAO/viewport.ts | 1092 -------------------------- webAO/viewport/constants/colors.ts | 11 + webAO/viewport/constants/defaultChatMsg.ts | 15 + webAO/viewport/constants/positions.ts | 45 ++ webAO/viewport/constants/shouts.ts | 1 + webAO/viewport/interfaces/ChatMsg.ts | 34 + webAO/viewport/interfaces/Desk.ts | 4 + webAO/viewport/interfaces/Position.ts | 7 + webAO/viewport/interfaces/Positions.ts | 5 + webAO/viewport/interfaces/Testimony.ts | 3 + webAO/viewport/interfaces/Viewport.ts | 24 + webAO/viewport/utils/createBlipChannels.ts | 15 + webAO/viewport/utils/createMusic.ts | 13 + webAO/viewport/utils/createSfxAudio.ts | 9 + webAO/viewport/utils/createShoutAudio.ts | 9 + webAO/viewport/utils/createTestimonyAudio.ts | 9 + webAO/viewport/viewport.ts | 901 +++++++++++++++++++++ 21 files changed, 1125 insertions(+), 1096 deletions(-) create mode 100644 webAO/dom/changeBlipVolume.ts delete mode 100644 webAO/viewport.ts create mode 100644 webAO/viewport/constants/colors.ts create mode 100644 webAO/viewport/constants/defaultChatMsg.ts create mode 100644 webAO/viewport/constants/positions.ts create mode 100644 webAO/viewport/constants/shouts.ts create mode 100644 webAO/viewport/interfaces/ChatMsg.ts create mode 100644 webAO/viewport/interfaces/Desk.ts create mode 100644 webAO/viewport/interfaces/Position.ts create mode 100644 webAO/viewport/interfaces/Positions.ts create mode 100644 webAO/viewport/interfaces/Testimony.ts create mode 100644 webAO/viewport/interfaces/Viewport.ts create mode 100644 webAO/viewport/utils/createBlipChannels.ts create mode 100644 webAO/viewport/utils/createMusic.ts create mode 100644 webAO/viewport/utils/createSfxAudio.ts create mode 100644 webAO/viewport/utils/createShoutAudio.ts create mode 100644 webAO/viewport/utils/createTestimonyAudio.ts create mode 100644 webAO/viewport/viewport.ts diff --git a/tsconfig.json b/tsconfig.json index 9422b00..1a2dd33 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,5 +8,5 @@ "strictNullChecks": false, //document.getElementBy "downlevelIteration": true }, - "include": ["./webAO/*"] + "include": ["./webAO/*", "webAO/viewport/viewport.ts"] } \ No newline at end of file diff --git a/webAO/client.ts b/webAO/client.ts index 8b2f691..b908b62 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -8,7 +8,8 @@ import FingerprintJS from "@fingerprintjs/fingerprintjs"; import { sender, ISender } from './client/sender/index' import queryParser from "./utils/queryParser"; import getResources from "./utils/getResources.js"; -import masterViewport, { Viewport } from "./viewport"; +import masterViewport from "./viewport/viewport"; +import { Viewport } from './viewport/interfaces/Viewport'; import { EventEmitter } from "events"; import { onReplayGo } from './dom/onReplayGo' import { packetHandler } from './packets/packetHandler' diff --git a/webAO/client/loadResources.ts b/webAO/client/loadResources.ts index 7039333..65d0895 100644 --- a/webAO/client/loadResources.ts +++ b/webAO/client/loadResources.ts @@ -5,7 +5,7 @@ import { client } from "../client"; import { setChatbox } from "../dom/setChatbox"; import { changeSFXVolume, changeShoutVolume, changeTestimonyVolume } from "../dom/changeVolume"; import { showname_click } from "../dom/showNameClick"; - +import { changeBlipVolume } from '../dom/changeBlipVolume' const version = process.env.npm_package_version; /** * Load game resources and stored settings. @@ -65,7 +65,7 @@ export const loadResources = () => { changeTestimonyVolume(); (document.getElementById("client_bvolume")).value = getCookie("blipVolume") || "1"; - client.viewport.changeBlipVolume(); + changeBlipVolume(); (document.getElementById("ic_chat_name")).value = getCookie("ic_chat_name"); diff --git a/webAO/dom/changeBlipVolume.ts b/webAO/dom/changeBlipVolume.ts new file mode 100644 index 0000000..572f389 --- /dev/null +++ b/webAO/dom/changeBlipVolume.ts @@ -0,0 +1,15 @@ +import setCookie from "../utils/setCookie"; +import { client } from '../client' +/** + * Triggered by the blip volume slider. + */ +export const changeBlipVolume = () => { + const blipVolume = (( + document.getElementById("client_bvolume") + )).value; + client.viewport.blipChannels.forEach( + (channel: HTMLAudioElement) => (channel.volume = Number(blipVolume)) + ); + setCookie("blipVolume", blipVolume); +} +window.changeBlipVolume = changeBlipVolume; diff --git a/webAO/viewport.ts b/webAO/viewport.ts deleted file mode 100644 index 7716409..0000000 --- a/webAO/viewport.ts +++ /dev/null @@ -1,1092 +0,0 @@ -import tryUrls from "./utils/tryUrls"; -import fileExists from "./utils/fileExists"; -import Client, { delay } from "./client"; -import { opusCheck } from './dom/opusCheck' -import { UPDATE_INTERVAL } from "./client"; -import { setChatbox } from "./dom/setChatbox"; -import { resizeChatbox } from "./dom/resizeChatbox"; -import transparentPng from "./constants/transparentPng"; -import mlConfig from "./utils/aoml"; -import setEmote from "./client/setEmote"; -import getAnimLength from "./utils/getAnimLength"; -import { safeTags } from "./encoding"; -import setCookie from "./utils/setCookie"; -import { AO_HOST } from "./client/aoHost"; -import { appendICLog } from "./client/appendICLog"; -import { checkCallword } from './client/checkCallword' - -interface ChatMsg { - content: string; - objection: number; - sound: string; - startpreanim: boolean; - startspeaking: boolean; - side: any; - color: number; - snddelay: number; - preanimdelay: number; - speed: number; - blips: string; - self_offset?: number[]; - other_offset?: number[]; - showname?: string; - nameplate?: string; - flip?: number; - other_flip?: number; - effects?: string[]; - deskmod?: number; - preanim?: string; - other_name?: string; - sprite?: string; - name?: string; - chatbox?: string; - other_emote?: string; - parsed?: HTMLSpanElement[]; - screenshake?: number; - flash?: number; - type?: number; - evidence?: number; - looping_sfx?: boolean; - noninterrupting_preanim?: number; -} -interface Testimony { - [key: number]: string; -} -export interface Viewport { - chat_tick: Function; - changeMusicVolume: Function; - changeBlipVolume: Function; - reloadTheme: Function; - playSFX: Function; - set_side: Function; - initTestimonyUpdater: Function; - updateTestimony: Function; - disposeTestimony: Function; - handle_ic_speaking: Function; - handleTextTick: Function; - theme: string; - chatmsg: ChatMsg; - setSfxAudio: Function; - getSfxAudio: Function; - getBackgroundFolder: Function; - blipChannels: HTMLAudioElement[]; - music: any; - musicVolume: number; - setBackgroundName: Function; - lastChar: string; - getBackgroundName: Function; -} -const SHOUTS = [undefined, "holdit", "objection", "takethat", "custom"]; - -const COLORS = [ - "white", - "green", - "red", - "orange", - "blue", - "yellow", - "pink", - "cyan", - "grey", -]; -const createMusic = () => { - const audioChannels = document.getElementsByClassName( - "audioChannel" - ) as HTMLCollectionOf; - let music = [...audioChannels]; - music.forEach((channel: HTMLAudioElement) => (channel.volume = 0.5)); - music.forEach( - (channel: HTMLAudioElement) => (channel.onerror = opusCheck(channel)) - ); - return music; -}; -const createTestimonyAudio = () => { - const testimonyAudio = document.getElementById( - "client_testimonyaudio" - ) as HTMLAudioElement; - testimonyAudio.src = `${AO_HOST}sounds/general/sfx-guilty.opus`; - return testimonyAudio; -}; - -const createShoutAudio = () => { - const shoutAudio = document.getElementById( - "client_shoutaudio" - ) as HTMLAudioElement; - shoutAudio.src = `${AO_HOST}misc/default/objection.opus`; - return shoutAudio; -}; -const createSfxAudio = () => { - const sfxAudio = document.getElementById( - "client_sfxaudio" - ) as HTMLAudioElement; - sfxAudio.src = `${AO_HOST}sounds/general/sfx-realization.opus`; - return sfxAudio; -}; -const createBlipsChannels = () => { - const blipSelectors = document.getElementsByClassName( - "blipSound" - ) as HTMLCollectionOf; - - const blipChannels = [...blipSelectors]; - // Allocate multiple blip audio channels to make blips less jittery - blipChannels.forEach((channel: HTMLAudioElement) => (channel.volume = 0.5)); - blipChannels.forEach( - (channel: HTMLAudioElement) => (channel.onerror = opusCheck(channel)) - ); - return blipChannels; -}; -const defaultChatMsg = { - content: "", - objection: 0, - sound: "", - startpreanim: true, - startspeaking: false, - side: null, - color: 0, - snddelay: 0, - preanimdelay: 0, - speed: UPDATE_INTERVAL, -} as ChatMsg; -interface Desk { - ao2?: string; - ao1?: string; -} -interface Position { - bg?: string; - desk?: Desk; - speedLines: string; -} - -interface Positions { - [key: string]: Position; -} - -const positions: Positions = { - def: { - bg: "defenseempty", - desk: { ao2: "defensedesk.png", ao1: "bancodefensa.png" } as Desk, - speedLines: "defense_speedlines.gif", - }, - pro: { - bg: "prosecutorempty", - desk: { ao2: "prosecutiondesk.png", ao1: "bancoacusacion.png" } as Desk, - speedLines: "prosecution_speedlines.gif", - }, - hld: { - bg: "helperstand", - desk: null as Desk, - speedLines: "defense_speedlines.gif", - }, - hlp: { - bg: "prohelperstand", - desk: null as Desk, - speedLines: "prosecution_speedlines.gif", - }, - wit: { - bg: "witnessempty", - desk: { ao2: "stand.png", ao1: "estrado.png" } as Desk, - speedLines: "prosecution_speedlines.gif", - }, - jud: { - bg: "judgestand", - desk: { ao2: "judgedesk.png", ao1: "judgedesk.gif" } as Desk, - speedLines: "prosecution_speedlines.gif", - }, - jur: { - bg: "jurystand", - desk: { ao2: "jurydesk.png", ao1: "estrado.png" } as Desk, - speedLines: "defense_speedlines.gif", - }, - sea: { - bg: "seancestand", - desk: { ao2: "seancedesk.png", ao1: "estrado.png" } as Desk, - speedLines: "prosecution_speedlines.gif", - }, -}; -const viewport = (masterClient: Client): Viewport => { - let animating = false; - let attorneyMarkdown = mlConfig(AO_HOST); - let blipChannels = createBlipsChannels(); - let chatmsg = defaultChatMsg; - let client = masterClient; - let currentBlipChannel = 0; - let lastChar = ""; - let lastEvi = 0; - let music = createMusic(); - let musicVolume = 0; - let sfxAudio = createSfxAudio(); - let sfxplayed = 0; - let shoutTimer = 0; - let shoutaudio = createShoutAudio(); - let startFirstTickCheck: boolean; - let startSecondTickCheck: boolean; - let startThirdTickCheck: boolean; - let testimonyAudio = createTestimonyAudio(); - let testimonyTimer = 0; - let testimonyUpdater: any; - let textnow = ""; - let theme: string; - let tickTimer = 0; - let updater: any; - let backgroundName = ""; - const getSfxAudio = () => sfxAudio; - const setSfxAudio = (value: HTMLAudioElement) => (sfxAudio = value); - const getBackgroundName = () => backgroundName; - const setBackgroundName = (value: string) => (backgroundName = value); - const getBackgroundFolder = () => - `${AO_HOST}background/${encodeURI(backgroundName.toLowerCase())}/`; - - const playSFX = async (sfxname: string, looping: boolean) => { - sfxAudio.pause(); - sfxAudio.loop = looping; - sfxAudio.src = sfxname; - sfxAudio.play(); - }; - - /** - * Changes the viewport background based on a given position. - * - * Valid positions: `def, pro, hld, hlp, wit, jud, jur, sea` - * @param {string} position the position to change into - */ - const set_side = async ({ - position, - showSpeedLines, - showDesk, - }: { - position: string; - showSpeedLines: boolean; - showDesk: boolean; - }) => { - const view = document.getElementById("client_fullview"); - - let bench: HTMLImageElement; - if ("def,pro,wit".includes(position)) { - bench = ( - document.getElementById(`client_${position}_bench`) - ); - } else { - bench = document.getElementById("client_bench_classic"); - } - - let court: HTMLImageElement; - if ("def,pro,wit".includes(position)) { - court = ( - document.getElementById(`client_court_${position}`) - ); - } else { - court = document.getElementById("client_court_classic"); - } - - let bg; - let desk; - let speedLines; - - if ("def,pro,hld,hlp,wit,jud,jur,sea".includes(position)) { - bg = positions[position].bg; - desk = positions[position].desk; - speedLines = positions[position].speedLines; - } else { - bg = `${position}`; - desk = { ao2: `${position}_overlay.png`, ao1: "_overlay.png" }; - speedLines = "defense_speedlines.gif"; - } - - if (showSpeedLines === true) { - court.src = `${AO_HOST}themes/default/${encodeURI(speedLines)}`; - } else { - court.src = await tryUrls(getBackgroundFolder() + bg); - } - - if (showDesk === true && desk) { - const deskFilename = (await fileExists(getBackgroundFolder() + desk.ao2)) - ? desk.ao2 - : desk.ao1; - bench.src = getBackgroundFolder() + deskFilename; - bench.style.opacity = "1"; - } else { - bench.style.opacity = "0"; - } - - if ("def,pro,wit".includes(position)) { - view.style.display = ""; - document.getElementById("client_classicview").style.display = "none"; - switch (position) { - case "def": - view.style.left = "0"; - break; - case "wit": - view.style.left = "-200%"; - break; - case "pro": - view.style.left = "-400%"; - break; - } - } else { - view.style.display = "none"; - document.getElementById("client_classicview").style.display = ""; - } - }; - - /** - * Intialize testimony updater - */ - const initTestimonyUpdater = () => { - const testimonyFilenames: Testimony = { - 1: "witnesstestimony", - 2: "crossexamination", - 3: "notguilty", - 4: "guilty", - }; - - const testimony = testimonyFilenames[masterClient.testimonyID]; - if (!testimony) { - console.warn(`Invalid testimony ID ${masterClient.testimonyID}`); - return; - } - - testimonyAudio.src = masterClient.resources[testimony].sfx; - testimonyAudio.play(); - - const testimonyOverlay = ( - document.getElementById("client_testimony") - ); - testimonyOverlay.src = masterClient.resources[testimony].src; - testimonyOverlay.style.opacity = "1"; - - testimonyTimer = 0; - testimonyUpdater = setTimeout(() => updateTestimony(), UPDATE_INTERVAL); - }; - - /** - * Updates the testimony overaly - */ - const updateTestimony = () => { - const testimonyFilenames: Testimony = { - 1: "witnesstestimony", - 2: "crossexamination", - 3: "notguilty", - 4: "guilty", - }; - - // Update timer - testimonyTimer += UPDATE_INTERVAL; - - const testimony = testimonyFilenames[masterClient.testimonyID]; - const resource = masterClient.resources[testimony]; - if (!resource) { - disposeTestimony(); - return; - } - - if (testimonyTimer >= resource.duration) { - disposeTestimony(); - } else { - testimonyUpdater = setTimeout(() => updateTestimony(), UPDATE_INTERVAL); - } - }; - - /** - * Dispose the testimony overlay - */ - const disposeTestimony = () => { - masterClient.testimonyID = 0; - testimonyTimer = 0; - document.getElementById("client_testimony").style.opacity = "0"; - clearTimeout(testimonyUpdater); - }; - - /** - * Sets a new emote. - * This sets up everything before the tick() loops starts - * a lot of things can probably be moved here, like starting the shout animation if there is one - * TODO: the preanim logic, on the other hand, should probably be moved to tick() - * @param {object} chatmsg the new chat message - */ - const handle_ic_speaking = async (playerChatMsg: ChatMsg) => { - chatmsg = playerChatMsg; - client.viewport.chatmsg = playerChatMsg; - - textnow = ""; - sfxplayed = 0; - tickTimer = 0; - animating = true; - startFirstTickCheck = true; - startSecondTickCheck = false; - startThirdTickCheck = false; - let charLayers = document.getElementById("client_char"); - let pairLayers = document.getElementById("client_pair_char"); - // stop updater - clearTimeout(updater); - - // stop last sfx from looping any longer - sfxAudio.loop = false; - - const fg = document.getElementById("client_fg"); - const gamewindow = document.getElementById("client_gamewindow"); - const waitingBox = document.getElementById("client_chatwaiting"); - - // Reset CSS animation - gamewindow.style.animation = ""; - waitingBox.style.opacity = "0"; - - const eviBox = document.getElementById("client_evi"); - - if (lastEvi !== chatmsg.evidence) { - eviBox.style.opacity = "0"; - eviBox.style.height = "0%"; - } - lastEvi = chatmsg.evidence; - - const validSides: string[] = ["def", "pro", "wit"]; // these are for the full view pan, the other positions use 'client_char' - if (validSides.includes(chatmsg.side)) { - charLayers = document.getElementById(`client_${chatmsg.side}_char`); - pairLayers = document.getElementById(`client_${chatmsg.side}_pair_char`); - } - - const chatContainerBox = document.getElementById("client_chatcontainer"); - const nameBoxInner = document.getElementById("client_inner_name"); - const chatBoxInner = document.getElementById("client_inner_chat"); - - const displayname = - (document.getElementById("showname")).checked && - chatmsg.showname !== "" - ? chatmsg.showname - : chatmsg.nameplate; - - // Clear out the last message - chatBoxInner.innerText = textnow; - nameBoxInner.innerText = displayname; - - if (lastChar !== chatmsg.name) { - charLayers.style.opacity = "0"; - pairLayers.style.opacity = "0"; - } - - lastChar = chatmsg.name; - client.viewport.lastChar = chatmsg.name; - - appendICLog(chatmsg.content, chatmsg.showname, chatmsg.nameplate); - - checkCallword(chatmsg.content, sfxAudio); - - setEmote( - AO_HOST, - client, - chatmsg.name.toLowerCase(), - chatmsg.sprite, - "(a)", - false, - chatmsg.side - ); - - if (chatmsg.other_name) { - setEmote( - AO_HOST, - client, - chatmsg.other_name.toLowerCase(), - chatmsg.other_emote, - "(a)", - false, - chatmsg.side - ); - } - - // gets which shout shall played - const shoutSprite = ( - document.getElementById("client_shout") - ); - const shout = SHOUTS[chatmsg.objection]; - if (shout) { - // Hide message box - chatContainerBox.style.opacity = "0"; - if (chatmsg.objection === 4) { - shoutSprite.src = `${AO_HOST}characters/${encodeURI( - chatmsg.name.toLowerCase() - )}/custom.gif`; - } else { - shoutSprite.src = masterClient.resources[shout].src; - shoutSprite.style.animation = "bubble 700ms steps(10, jump-both)"; - } - shoutSprite.style.opacity = "1"; - - shoutaudio.src = `${AO_HOST}characters/${encodeURI( - chatmsg.name.toLowerCase() - )}/${shout}.opus`; - shoutaudio.play(); - shoutTimer = masterClient.resources[shout].duration; - } else { - shoutTimer = 0; - } - - chatmsg.startpreanim = true; - let gifLength = 0; - - if (chatmsg.type === 1 && chatmsg.preanim !== "-") { - //we have a preanim - chatContainerBox.style.opacity = "0"; - gifLength = await getAnimLength( - `${AO_HOST}characters/${encodeURI( - chatmsg.name.toLowerCase() - )}/${encodeURI(chatmsg.preanim)}` - ); - console.debug("preanim is " + gifLength + " long"); - chatmsg.startspeaking = false; - } else { - chatmsg.startspeaking = true; - if (chatmsg.content !== "") chatContainerBox.style.opacity = "1"; - } - chatmsg.preanimdelay = gifLength; - const setAside = { - position: chatmsg.side, - showSpeedLines: false, - showDesk: false, - }; - let skipoffset: boolean = false; - if (chatmsg.type === 5) { - setAside.showSpeedLines = true; - setAside.showDesk = false; - set_side(setAside); - } else { - switch (Number(chatmsg.deskmod)) { - case 0: //desk is hidden - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - break; - case 1: //desk is shown - setAside.showSpeedLines = false; - setAside.showDesk = true; - set_side(setAside); - break; - case 2: //desk is hidden during preanim, but shown during idle/talk - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - break; - case 3: //opposite of 2 - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - break; - case 4: //desk is hidden, character offset is ignored, pair character is hidden during preanim, normal behavior during idle/talk - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - skipoffset = true; - break; - case 5: //opposite of 4 - setAside.showSpeedLines = false; - setAside.showDesk = true; - set_side(setAside); - break; - default: - setAside.showSpeedLines = false; - setAside.showDesk = true; - set_side(setAside); - break; - } - } - - setChatbox(chatmsg.chatbox); - resizeChatbox(); - - if (!skipoffset) { - // Flip the character - charLayers.style.transform = - chatmsg.flip === 1 ? "scaleX(-1)" : "scaleX(1)"; - pairLayers.style.transform = - chatmsg.other_flip === 1 ? "scaleX(-1)" : "scaleX(1)"; - - // Shift by the horizontal offset - switch (chatmsg.side) { - case "wit": - pairLayers.style.left = `${200 + Number(chatmsg.other_offset[0])}%`; - charLayers.style.left = `${200 + Number(chatmsg.self_offset[0])}%`; - break; - case "pro": - pairLayers.style.left = `${400 + Number(chatmsg.other_offset[0])}%`; - charLayers.style.left = `${400 + Number(chatmsg.self_offset[0])}%`; - break; - default: - pairLayers.style.left = `${Number(chatmsg.other_offset[0])}%`; - charLayers.style.left = `${Number(chatmsg.self_offset[0])}%`; - break; - } - - // New vertical offsets - pairLayers.style.top = `${Number(chatmsg.other_offset[1])}%`; - charLayers.style.top = `${Number(chatmsg.self_offset[1])}%`; - } - - blipChannels.forEach( - (channel: HTMLAudioElement) => - (channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI( - chatmsg.blips.toLowerCase() - )}.opus`) - ); - - // process markup - if (chatmsg.content.startsWith("~~")) { - chatBoxInner.style.textAlign = "center"; - chatmsg.content = chatmsg.content.substring(2, chatmsg.content.length); - } else { - chatBoxInner.style.textAlign = "inherit"; - } - - // apply effects - fg.style.animation = ""; - const effectName = chatmsg.effects[0].toLowerCase(); - const badEffects = ["", "-", "none"]; - if (effectName.startsWith("rain")) { - (document.getElementById("effect_css")).href = "styles/effects/rain.css"; - let intensity = 200; - if (effectName.endsWith("weak")) { - intensity = 100; - } else if (effectName.endsWith("strong")) { - intensity = 400; - } - if (intensity < fg.childElementCount) - fg.innerHTML = ''; - else - intensity = intensity - fg.childElementCount; - - for (let i = 0; i < intensity; i++) { - let drop = document.createElement("p"); - drop.style.left = (Math.random() * 100) + "%"; - drop.style.animationDelay = String(Math.random()) + "s"; - fg.appendChild(drop) - } - } else if ( - chatmsg.effects[0] && - !badEffects.includes(effectName) - ) { - (document.getElementById("effect_css")).href = ""; - fg.innerHTML = ''; - const baseEffectUrl = `${AO_HOST}themes/default/effects/`; - fg.src = `${baseEffectUrl}${encodeURI(effectName)}.webp`; - } else { - fg.innerHTML = ''; - fg.src = transparentPng; - } - - charLayers.style.opacity = "1"; - - const soundChecks = ["0", "1", "", undefined]; - if (soundChecks.some((check) => chatmsg.sound === check)) { - chatmsg.sound = chatmsg.effects[2]; - } - chatmsg.parsed = await attorneyMarkdown.applyMarkdown( - chatmsg.content, - COLORS[chatmsg.color] - ); - chat_tick(); - }; - - const handleTextTick = async (charLayers: HTMLImageElement) => { - const chatBox = document.getElementById("client_chat"); - const waitingBox = document.getElementById("client_chatwaiting"); - const chatBoxInner = document.getElementById("client_inner_chat"); - const charName = chatmsg.name.toLowerCase(); - const charEmote = chatmsg.sprite.toLowerCase(); - - if (chatmsg.content.charAt(textnow.length) !== " ") { - blipChannels[currentBlipChannel].play(); - currentBlipChannel++; - currentBlipChannel %= blipChannels.length; - } - textnow = chatmsg.content.substring(0, textnow.length + 1); - const characterElement = chatmsg.parsed[textnow.length - 1]; - if (characterElement) { - const COMMAND_IDENTIFIER = "\\"; - - const nextCharacterElement = chatmsg.parsed[textnow.length]; - const flash = async () => { - const effectlayer = document.getElementById("client_fg"); - playSFX(`${AO_HOST}sounds/general/sfx-realization.opus`, false); - effectlayer.style.animation = "flash 0.4s 1"; - await delay(400); - effectlayer.style.removeProperty("animation"); - }; - - const shake = async () => { - const gamewindow = document.getElementById("client_gamewindow"); - playSFX(`${AO_HOST}sounds/general/sfx-stab.opus`, false); - gamewindow.style.animation = "shake 0.2s 1"; - await delay(200); - gamewindow.style.removeProperty("animation"); - }; - - const commands = new Map( - Object.entries({ - s: shake, - f: flash, - }) - ); - const textSpeeds = new Set(["{", "}"]); - - // Changing Text Speed - if (textSpeeds.has(characterElement.innerHTML)) { - // Grab them all in a row - const MAX_SLOW_CHATSPEED = 120; - for (let i = textnow.length; i < chatmsg.content.length; i++) { - const currentCharacter = chatmsg.parsed[i - 1].innerHTML; - if (currentCharacter === "}") { - if (chatmsg.speed > 0) { - chatmsg.speed -= 20; - } - } else if (currentCharacter === "{") { - if (chatmsg.speed < MAX_SLOW_CHATSPEED) { - chatmsg.speed += 20; - } - } else { - // No longer at a speed character - textnow = chatmsg.content.substring(0, i); - break; - } - } - } - - if ( - characterElement.innerHTML === COMMAND_IDENTIFIER && - commands.has(nextCharacterElement?.innerHTML) - ) { - textnow = chatmsg.content.substring(0, textnow.length + 1); - await commands.get(nextCharacterElement.innerHTML)(); - } else { - chatBoxInner.appendChild(chatmsg.parsed[textnow.length - 1]); - } - } - // scroll to bottom - chatBox.scrollTop = chatBox.scrollHeight; - - if (textnow === chatmsg.content) { - animating = false; - setEmote( - AO_HOST, - client, - charName, - charEmote, - "(a)", - false, - chatmsg.side - ); - charLayers.style.opacity = "1"; - waitingBox.style.opacity = "1"; - clearTimeout(updater); - } - }; - /** - * Updates the chatbox based on the given text. - * - * OK, here's the documentation on how this works: - * - * 1 _animating - * If we're not done with this characters animation, i.e. his text isn't fully there, set a timeout for the next tick/step to happen - * - * 2 startpreanim - * If the shout timer is over it starts with the preanim - * The first thing it checks for is the shake effect (TODO on client this is handled by the @ symbol and not a flag ) - * Then is the flash/realization effect - * After that, the shout image set to be transparent - * and the main characters preanim gif is loaded - * If pairing is supported the paired character will just stand around with his idle sprite - * - * 3 preanimdelay over - * this animates the evidence popup and finally shows the character name and message box - * it sets the text color and the character speaking sprite - * - * 4 textnow != content - * this adds a character to the textbox and stops the animations if the entire message is present in the textbox - * - * 5 sfx - * independent of the stuff above, this will play any sound effects specified by the emote the character sent. - * happens after the shout delay + an sfx delay that comes with the message packet - * - * XXX: This relies on a global variable `chatmsg`! - */ - const chat_tick = async () => { - // 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"); - const eviBox = document.getElementById("client_evi"); - const shoutSprite = ( - document.getElementById("client_shout") - ); - const effectlayer = document.getElementById("client_fg"); - const chatBoxInner = document.getElementById("client_inner_chat"); - let charLayers = document.getElementById("client_char"); - let pairLayers = ( - document.getElementById("client_pair_char") - ); - - const validSides: string[] = ["def", "pro", "wit"]; // these are for the full view pan, the other positions use 'client_char' - if (validSides.includes(chatmsg.side)) { - charLayers = ( - document.getElementById(`client_${chatmsg.side}_char`) - ); - pairLayers = ( - document.getElementById(`client_${chatmsg.side}_pair_char`) - ); - } - - const charName = chatmsg.name.toLowerCase(); - const charEmote = chatmsg.sprite.toLowerCase(); - - const pairName = chatmsg.other_name.toLowerCase(); - const pairEmote = chatmsg.other_emote.toLowerCase(); - - // TODO: preanims sometimes play when they're not supposed to - const isShoutOver = tickTimer >= shoutTimer; - const isShoutAndPreanimOver = - tickTimer >= shoutTimer + chatmsg.preanimdelay; - if (isShoutOver && startFirstTickCheck) { - // Effect stuff - if (chatmsg.screenshake === 1) { - // Shake screen - playSFX(`${AO_HOST}sounds/general/sfx-stab.opus`, false); - gamewindow.style.animation = "shake 0.2s 1"; - } - if (chatmsg.flash === 1) { - // Flash screen - playSFX(`${AO_HOST}sounds/general/sfx-realization.opus`, false); - effectlayer.style.animation = "flash 0.4s 1"; - } - - // Pre-animation stuff - if (chatmsg.preanimdelay > 0) { - shoutSprite.style.opacity = "0"; - shoutSprite.style.animation = ""; - const preanim = chatmsg.preanim.toLowerCase(); - setEmote(AO_HOST, client, charName, preanim, "", false, chatmsg.side); - } - - if (chatmsg.other_name) { - pairLayers.style.opacity = "1"; - } else { - pairLayers.style.opacity = "0"; - } - // Done with first check, move to second - startFirstTickCheck = false; - startSecondTickCheck = true; - - chatmsg.startpreanim = false; - chatmsg.startspeaking = true; - } - - const hasNonInterruptingPreAnim = chatmsg.noninterrupting_preanim === 1; - if (textnow !== chatmsg.content && hasNonInterruptingPreAnim) { - const chatContainerBox = document.getElementById("client_chatcontainer"); - chatContainerBox.style.opacity = "1"; - await handleTextTick(charLayers); - } else if (isShoutAndPreanimOver && startSecondTickCheck) { - if (chatmsg.startspeaking) { - chatmsg.startspeaking = false; - - // Evidence Bullshit - if (chatmsg.evidence > 0) { - // Prepare evidence - eviBox.src = safeTags( - masterClient.evidences[chatmsg.evidence - 1].icon - ); - - eviBox.style.width = "auto"; - eviBox.style.height = "36.5%"; - eviBox.style.opacity = "1"; - - testimonyAudio.src = `${AO_HOST}sounds/general/sfx-evidenceshoop.opus`; - testimonyAudio.play(); - - if (chatmsg.side === "def") { - // Only def show evidence on right - eviBox.style.right = "1em"; - eviBox.style.left = "initial"; - } else { - eviBox.style.right = "initial"; - eviBox.style.left = "1em"; - } - } - chatBoxInner.className = `text_${COLORS[chatmsg.color]}`; - - if (chatmsg.preanimdelay === 0) { - shoutSprite.style.opacity = "0"; - shoutSprite.style.animation = ""; - } - - switch (Number(chatmsg.deskmod)) { - case 2: - set_side({ - position: chatmsg.side, - showSpeedLines: false, - showDesk: true, - }); - break; - case 3: - set_side({ - position: chatmsg.side, - showSpeedLines: false, - showDesk: false, - }); - break; - case 4: - set_side({ - position: chatmsg.side, - showSpeedLines: false, - showDesk: true, - }); - break; - case 5: - set_side({ - position: chatmsg.side, - showSpeedLines: false, - showDesk: false, - }); - break; - } - - if (chatmsg.other_name) { - setEmote( - AO_HOST, - client, - pairName, - pairEmote, - "(a)", - true, - chatmsg.side - ); - pairLayers.style.opacity = "1"; - } else { - pairLayers.style.opacity = "0"; - } - - setEmote( - AO_HOST, - client, - charName, - charEmote, - "(b)", - false, - chatmsg.side - ); - charLayers.style.opacity = "1"; - - if (textnow === chatmsg.content) { - setEmote( - AO_HOST, - client, - charName, - charEmote, - "(a)", - false, - chatmsg.side - ); - charLayers.style.opacity = "1"; - waitingBox.style.opacity = "1"; - animating = false; - clearTimeout(updater); - return; - } - } else if (textnow !== chatmsg.content) { - const chatContainerBox = document.getElementById( - "client_chatcontainer" - ); - chatContainerBox.style.opacity = "1"; - await handleTextTick(charLayers); - } - } - - if (!sfxplayed && chatmsg.snddelay + shoutTimer >= tickTimer) { - sfxplayed = 1; - if ( - chatmsg.sound !== "0" && - chatmsg.sound !== "1" && - chatmsg.sound !== "" && - chatmsg.sound !== undefined && - (chatmsg.type == 1 || chatmsg.type == 2 || chatmsg.type == 6) - ) { - playSFX( - `${AO_HOST}sounds/general/${encodeURI( - chatmsg.sound.toLowerCase() - )}.opus`, - chatmsg.looping_sfx - ); - } - } - if (animating) { - chat_tick(); - } - tickTimer += UPDATE_INTERVAL; - }; - /** - * Triggered by the theme selector. - */ - function reloadTheme() { - theme = (document.getElementById("client_themeselect")) - .value; - - setCookie("theme", theme); - (( - document.getElementById("client_theme") - )).href = `styles/${theme}.css`; - } - window.reloadTheme = reloadTheme; - /** - * Triggered by the blip volume slider. - */ - function changeBlipVolume() { - const blipVolume = (( - document.getElementById("client_bvolume") - )).value; - blipChannels.forEach( - (channel: HTMLAudioElement) => (channel.volume = Number(blipVolume)) - ); - setCookie("blipVolume", blipVolume); - } - window.changeBlipVolume = changeBlipVolume; - - const changeMusicVolume = (volume: number = -1) => { - const clientVolume = Number( - (document.getElementById("client_mvolume")).value - ); - let musicVolume = volume === -1 ? clientVolume : volume; - music.forEach( - (channel: HTMLAudioElement) => (channel.volume = musicVolume) - ); - setCookie("musicVolume", String(musicVolume)); - }; - window.changeMusicVolume = changeMusicVolume; - - return { - chat_tick, - changeMusicVolume, - changeBlipVolume, - reloadTheme, - playSFX, - set_side, - setBackgroundName, - initTestimonyUpdater, - updateTestimony, - disposeTestimony, - handle_ic_speaking, - handleTextTick, - getBackgroundFolder, - getBackgroundName, - getSfxAudio, - setSfxAudio, - theme, - chatmsg, - blipChannels, - lastChar, - music, - musicVolume, - }; -}; - -export default viewport; diff --git a/webAO/viewport/constants/colors.ts b/webAO/viewport/constants/colors.ts new file mode 100644 index 0000000..aad3530 --- /dev/null +++ b/webAO/viewport/constants/colors.ts @@ -0,0 +1,11 @@ +export const COLORS = [ + "white", + "green", + "red", + "orange", + "blue", + "yellow", + "pink", + "cyan", + "grey", + ]; \ No newline at end of file diff --git a/webAO/viewport/constants/defaultChatMsg.ts b/webAO/viewport/constants/defaultChatMsg.ts new file mode 100644 index 0000000..8a5db6b --- /dev/null +++ b/webAO/viewport/constants/defaultChatMsg.ts @@ -0,0 +1,15 @@ +import { UPDATE_INTERVAL } from "../../client"; +import { ChatMsg } from "../interfaces/ChatMsg"; + +export const defaultChatMsg = { + content: "", + objection: 0, + sound: "", + startpreanim: true, + startspeaking: false, + side: null, + color: 0, + snddelay: 0, + preanimdelay: 0, + speed: UPDATE_INTERVAL, + } as ChatMsg; \ No newline at end of file diff --git a/webAO/viewport/constants/positions.ts b/webAO/viewport/constants/positions.ts new file mode 100644 index 0000000..1712ac6 --- /dev/null +++ b/webAO/viewport/constants/positions.ts @@ -0,0 +1,45 @@ +import { Positions } from '../interfaces/Positions' +import { Desk } from '../interfaces/Desk'; + +export const positions: Positions = { + def: { + bg: "defenseempty", + desk: { ao2: "defensedesk.png", ao1: "bancodefensa.png" } as Desk, + speedLines: "defense_speedlines.gif", + }, + pro: { + bg: "prosecutorempty", + desk: { ao2: "prosecutiondesk.png", ao1: "bancoacusacion.png" } as Desk, + speedLines: "prosecution_speedlines.gif", + }, + hld: { + bg: "helperstand", + desk: {} as Desk, + speedLines: "defense_speedlines.gif", + }, + hlp: { + bg: "prohelperstand", + desk: {} as Desk, + speedLines: "prosecution_speedlines.gif", + }, + wit: { + bg: "witnessempty", + desk: { ao2: "stand.png", ao1: "estrado.png" } as Desk, + speedLines: "prosecution_speedlines.gif", + }, + jud: { + bg: "judgestand", + desk: { ao2: "judgedesk.png", ao1: "judgedesk.gif" } as Desk, + speedLines: "prosecution_speedlines.gif", + }, + jur: { + bg: "jurystand", + desk: { ao2: "jurydesk.png", ao1: "estrado.png" } as Desk, + speedLines: "defense_speedlines.gif", + }, + sea: { + bg: "seancestand", + desk: { ao2: "seancedesk.png", ao1: "estrado.png" } as Desk, + speedLines: "prosecution_speedlines.gif", + }, +}; \ No newline at end of file diff --git a/webAO/viewport/constants/shouts.ts b/webAO/viewport/constants/shouts.ts new file mode 100644 index 0000000..eddd6d3 --- /dev/null +++ b/webAO/viewport/constants/shouts.ts @@ -0,0 +1 @@ +export const SHOUTS = [undefined, "holdit", "objection", "takethat", "custom"]; diff --git a/webAO/viewport/interfaces/ChatMsg.ts b/webAO/viewport/interfaces/ChatMsg.ts new file mode 100644 index 0000000..293a774 --- /dev/null +++ b/webAO/viewport/interfaces/ChatMsg.ts @@ -0,0 +1,34 @@ +export interface ChatMsg { + content: string; + objection: number; + sound: string; + startpreanim: boolean; + startspeaking: boolean; + side: any; + color: number; + snddelay: number; + preanimdelay: number; + speed: number; + blips: string; + self_offset?: number[]; + other_offset?: number[]; + showname?: string; + nameplate?: string; + flip?: number; + other_flip?: number; + effects?: string[]; + deskmod?: number; + preanim?: string; + other_name?: string; + sprite?: string; + name?: string; + chatbox?: string; + other_emote?: string; + parsed?: HTMLSpanElement[]; + screenshake?: number; + flash?: number; + type?: number; + evidence?: number; + looping_sfx?: boolean; + noninterrupting_preanim?: number; + } \ No newline at end of file diff --git a/webAO/viewport/interfaces/Desk.ts b/webAO/viewport/interfaces/Desk.ts new file mode 100644 index 0000000..872426a --- /dev/null +++ b/webAO/viewport/interfaces/Desk.ts @@ -0,0 +1,4 @@ +export interface Desk { + ao2?: string; + ao1?: string; +} \ No newline at end of file diff --git a/webAO/viewport/interfaces/Position.ts b/webAO/viewport/interfaces/Position.ts new file mode 100644 index 0000000..dea7238 --- /dev/null +++ b/webAO/viewport/interfaces/Position.ts @@ -0,0 +1,7 @@ +import { Desk } from './Desk' + +export interface Position { + bg?: string; + desk?: Desk; + speedLines: string; +} \ No newline at end of file diff --git a/webAO/viewport/interfaces/Positions.ts b/webAO/viewport/interfaces/Positions.ts new file mode 100644 index 0000000..0644962 --- /dev/null +++ b/webAO/viewport/interfaces/Positions.ts @@ -0,0 +1,5 @@ +import { Position } from './Position' + +export interface Positions { + [key: string]: Position; +} \ No newline at end of file diff --git a/webAO/viewport/interfaces/Testimony.ts b/webAO/viewport/interfaces/Testimony.ts new file mode 100644 index 0000000..61a7491 --- /dev/null +++ b/webAO/viewport/interfaces/Testimony.ts @@ -0,0 +1,3 @@ +export interface Testimony { + [key: number]: string; +} \ No newline at end of file diff --git a/webAO/viewport/interfaces/Viewport.ts b/webAO/viewport/interfaces/Viewport.ts new file mode 100644 index 0000000..3ffbcc8 --- /dev/null +++ b/webAO/viewport/interfaces/Viewport.ts @@ -0,0 +1,24 @@ +import { ChatMsg } from "./ChatMsg"; +export interface Viewport { + chat_tick: Function; + changeMusicVolume: Function; + reloadTheme: Function; + playSFX: Function; + set_side: Function; + initTestimonyUpdater: Function; + updateTestimony: Function; + disposeTestimony: Function; + handle_ic_speaking: Function; + handleTextTick: Function; + theme: string; + chatmsg: ChatMsg; + setSfxAudio: Function; + getSfxAudio: Function; + getBackgroundFolder: Function; + blipChannels: HTMLAudioElement[]; + music: any; + musicVolume: number; + setBackgroundName: Function; + lastChar: string; + getBackgroundName: Function; +} \ No newline at end of file diff --git a/webAO/viewport/utils/createBlipChannels.ts b/webAO/viewport/utils/createBlipChannels.ts new file mode 100644 index 0000000..6296b3b --- /dev/null +++ b/webAO/viewport/utils/createBlipChannels.ts @@ -0,0 +1,15 @@ +import { opusCheck } from "../../dom/opusCheck"; + +export const createBlipsChannels = () => { + const blipSelectors = document.getElementsByClassName( + "blipSound" + ) as HTMLCollectionOf; + + const blipChannels = [...blipSelectors]; + // Allocate multiple blip audio channels to make blips less jittery + blipChannels.forEach((channel: HTMLAudioElement) => (channel.volume = 0.5)); + blipChannels.forEach( + (channel: HTMLAudioElement) => (channel.onerror = opusCheck(channel)) + ); + return blipChannels; +}; \ No newline at end of file diff --git a/webAO/viewport/utils/createMusic.ts b/webAO/viewport/utils/createMusic.ts new file mode 100644 index 0000000..9bf5240 --- /dev/null +++ b/webAO/viewport/utils/createMusic.ts @@ -0,0 +1,13 @@ +import { opusCheck } from '../../dom/opusCheck' + +export const createMusic = () => { + const audioChannels = document.getElementsByClassName( + "audioChannel" + ) as HTMLCollectionOf; + let music = [...audioChannels]; + music.forEach((channel: HTMLAudioElement) => (channel.volume = 0.5)); + music.forEach( + (channel: HTMLAudioElement) => (channel.onerror = opusCheck(channel)) + ); + return music; +}; \ No newline at end of file diff --git a/webAO/viewport/utils/createSfxAudio.ts b/webAO/viewport/utils/createSfxAudio.ts new file mode 100644 index 0000000..7e03563 --- /dev/null +++ b/webAO/viewport/utils/createSfxAudio.ts @@ -0,0 +1,9 @@ +import { AO_HOST } from "../../client/aoHost"; + +export const createSfxAudio = () => { + const sfxAudio = document.getElementById( + "client_sfxaudio" + ) as HTMLAudioElement; + sfxAudio.src = `${AO_HOST}sounds/general/sfx-realization.opus`; + return sfxAudio; +}; \ No newline at end of file diff --git a/webAO/viewport/utils/createShoutAudio.ts b/webAO/viewport/utils/createShoutAudio.ts new file mode 100644 index 0000000..8211116 --- /dev/null +++ b/webAO/viewport/utils/createShoutAudio.ts @@ -0,0 +1,9 @@ +import { AO_HOST } from "../../client/aoHost"; + +export const createShoutAudio = () => { + const shoutAudio = document.getElementById( + "client_shoutaudio" + ) as HTMLAudioElement; + shoutAudio.src = `${AO_HOST}misc/default/objection.opus`; + return shoutAudio; +}; \ No newline at end of file diff --git a/webAO/viewport/utils/createTestimonyAudio.ts b/webAO/viewport/utils/createTestimonyAudio.ts new file mode 100644 index 0000000..2ff98f6 --- /dev/null +++ b/webAO/viewport/utils/createTestimonyAudio.ts @@ -0,0 +1,9 @@ +import { AO_HOST } from '../../client/aoHost' + +export const createTestimonyAudio = () => { + const testimonyAudio = document.getElementById( + "client_testimonyaudio" + ) as HTMLAudioElement; + testimonyAudio.src = `${AO_HOST}sounds/general/sfx-guilty.opus`; + return testimonyAudio; +}; \ No newline at end of file diff --git a/webAO/viewport/viewport.ts b/webAO/viewport/viewport.ts new file mode 100644 index 0000000..9772796 --- /dev/null +++ b/webAO/viewport/viewport.ts @@ -0,0 +1,901 @@ +import tryUrls from "../utils/tryUrls"; +import fileExists from "../utils/fileExists"; +import Client, { delay } from "../client"; +import { UPDATE_INTERVAL } from "../client"; +import { setChatbox } from "../dom/setChatbox"; +import { resizeChatbox } from "../dom/resizeChatbox"; +import transparentPng from "../constants/transparentPng"; +import mlConfig from "../utils/aoml"; +import setEmote from "../client/setEmote"; +import getAnimLength from "../utils/getAnimLength"; +import { safeTags } from "../encoding"; +import setCookie from "../utils/setCookie"; +import { AO_HOST } from "../client/aoHost"; +import { appendICLog } from "../client/appendICLog"; +import { checkCallword } from '../client/checkCallword' +import { Viewport } from './interfaces/Viewport' +import { createBlipsChannels } from './utils/createBlipChannels' +import { defaultChatMsg } from './constants/defaultChatMsg' +import { createMusic } from './utils/createMusic' +import { createSfxAudio } from './utils/createSfxAudio' +import { createShoutAudio } from './utils/createShoutAudio' +import { createTestimonyAudio } from './utils/createTestimonyAudio' +import { ChatMsg } from "./interfaces/ChatMsg"; +import { Testimony } from './interfaces/Testimony' +import { COLORS } from './constants/colors' +import { SHOUTS } from './constants/shouts' +import { positions } from './constants/positions' + +const viewport = (masterClient: Client): Viewport => { + let animating = false; + let attorneyMarkdown = mlConfig(AO_HOST); + let blipChannels = createBlipsChannels(); + let chatmsg = defaultChatMsg; + let client = masterClient; + let currentBlipChannel = 0; + let lastChar = ""; + let lastEvi = 0; + let music = createMusic(); + let musicVolume = 0; + let sfxAudio = createSfxAudio(); + let sfxplayed = 0; + let shoutTimer = 0; + let shoutaudio = createShoutAudio(); + let startFirstTickCheck: boolean; + let startSecondTickCheck: boolean; + let startThirdTickCheck: boolean; + let testimonyAudio = createTestimonyAudio(); + let testimonyTimer = 0; + let testimonyUpdater: any; + let textnow = ""; + let theme: string; + let tickTimer = 0; + let updater: any; + let backgroundName = ""; + const getSfxAudio = () => sfxAudio; + const setSfxAudio = (value: HTMLAudioElement) => { sfxAudio = value }; + const getBackgroundName = () => backgroundName; + const setBackgroundName = (value: string) => { backgroundName = value }; + const getBackgroundFolder = () => + `${AO_HOST}background/${encodeURI(backgroundName.toLowerCase())}/`; + + const playSFX = async (sfxname: string, looping: boolean) => { + sfxAudio.pause(); + sfxAudio.loop = looping; + sfxAudio.src = sfxname; + sfxAudio.play(); + }; + + /** + * Changes the viewport background based on a given position. + * + * Valid positions: `def, pro, hld, hlp, wit, jud, jur, sea` + * @param {string} position the position to change into + */ + const set_side = async ({ + position, + showSpeedLines, + showDesk, + }: { + position: string; + showSpeedLines: boolean; + showDesk: boolean; + }) => { + const view = document.getElementById("client_fullview"); + + let bench: HTMLImageElement; + if ("def,pro,wit".includes(position)) { + bench = ( + document.getElementById(`client_${position}_bench`) + ); + } else { + bench = document.getElementById("client_bench_classic"); + } + + let court: HTMLImageElement; + if ("def,pro,wit".includes(position)) { + court = ( + document.getElementById(`client_court_${position}`) + ); + } else { + court = document.getElementById("client_court_classic"); + } + + let bg; + let desk; + let speedLines; + + if ("def,pro,hld,hlp,wit,jud,jur,sea".includes(position)) { + bg = positions[position].bg; + desk = positions[position].desk; + speedLines = positions[position].speedLines; + } else { + bg = `${position}`; + desk = { ao2: `${position}_overlay.png`, ao1: "_overlay.png" }; + speedLines = "defense_speedlines.gif"; + } + + if (showSpeedLines === true) { + court.src = `${AO_HOST}themes/default/${encodeURI(speedLines)}`; + } else { + court.src = await tryUrls(getBackgroundFolder() + bg); + } + + if (showDesk === true && desk) { + const deskFilename = (await fileExists(getBackgroundFolder() + desk.ao2)) + ? desk.ao2 + : desk.ao1; + bench.src = getBackgroundFolder() + deskFilename; + bench.style.opacity = "1"; + } else { + bench.style.opacity = "0"; + } + + if ("def,pro,wit".includes(position)) { + view.style.display = ""; + document.getElementById("client_classicview").style.display = "none"; + switch (position) { + case "def": + view.style.left = "0"; + break; + case "wit": + view.style.left = "-200%"; + break; + case "pro": + view.style.left = "-400%"; + break; + } + } else { + view.style.display = "none"; + document.getElementById("client_classicview").style.display = ""; + } + }; + + /** + * Intialize testimony updater + */ + const initTestimonyUpdater = () => { + const testimonyFilenames: Testimony = { + 1: "witnesstestimony", + 2: "crossexamination", + 3: "notguilty", + 4: "guilty", + }; + + const testimony = testimonyFilenames[masterClient.testimonyID]; + if (!testimony) { + console.warn(`Invalid testimony ID ${masterClient.testimonyID}`); + return; + } + + testimonyAudio.src = masterClient.resources[testimony].sfx; + testimonyAudio.play(); + + const testimonyOverlay = ( + document.getElementById("client_testimony") + ); + testimonyOverlay.src = masterClient.resources[testimony].src; + testimonyOverlay.style.opacity = "1"; + + testimonyTimer = 0; + testimonyUpdater = setTimeout(() => updateTestimony(), UPDATE_INTERVAL); + }; + + /** + * Updates the testimony overaly + */ + const updateTestimony = () => { + const testimonyFilenames: Testimony = { + 1: "witnesstestimony", + 2: "crossexamination", + 3: "notguilty", + 4: "guilty", + }; + + // Update timer + testimonyTimer += UPDATE_INTERVAL; + + const testimony = testimonyFilenames[masterClient.testimonyID]; + const resource = masterClient.resources[testimony]; + if (!resource) { + disposeTestimony(); + return; + } + + if (testimonyTimer >= resource.duration) { + disposeTestimony(); + } else { + testimonyUpdater = setTimeout(() => updateTestimony(), UPDATE_INTERVAL); + } + }; + + /** + * Dispose the testimony overlay + */ + const disposeTestimony = () => { + masterClient.testimonyID = 0; + testimonyTimer = 0; + document.getElementById("client_testimony").style.opacity = "0"; + clearTimeout(testimonyUpdater); + }; + + /** + * Sets a new emote. + * This sets up everything before the tick() loops starts + * a lot of things can probably be moved here, like starting the shout animation if there is one + * TODO: the preanim logic, on the other hand, should probably be moved to tick() + * @param {object} chatmsg the new chat message + */ + const handle_ic_speaking = async (playerChatMsg: ChatMsg) => { + chatmsg = playerChatMsg; + client.viewport.chatmsg = playerChatMsg; + + textnow = ""; + sfxplayed = 0; + tickTimer = 0; + animating = true; + startFirstTickCheck = true; + startSecondTickCheck = false; + startThirdTickCheck = false; + let charLayers = document.getElementById("client_char"); + let pairLayers = document.getElementById("client_pair_char"); + // stop updater + clearTimeout(updater); + + // stop last sfx from looping any longer + sfxAudio.loop = false; + + const fg = document.getElementById("client_fg"); + const gamewindow = document.getElementById("client_gamewindow"); + const waitingBox = document.getElementById("client_chatwaiting"); + + // Reset CSS animation + gamewindow.style.animation = ""; + waitingBox.style.opacity = "0"; + + const eviBox = document.getElementById("client_evi"); + + if (lastEvi !== chatmsg.evidence) { + eviBox.style.opacity = "0"; + eviBox.style.height = "0%"; + } + lastEvi = chatmsg.evidence; + + const validSides: string[] = ["def", "pro", "wit"]; // these are for the full view pan, the other positions use 'client_char' + if (validSides.includes(chatmsg.side)) { + charLayers = document.getElementById(`client_${chatmsg.side}_char`); + pairLayers = document.getElementById(`client_${chatmsg.side}_pair_char`); + } + + const chatContainerBox = document.getElementById("client_chatcontainer"); + const nameBoxInner = document.getElementById("client_inner_name"); + const chatBoxInner = document.getElementById("client_inner_chat"); + + const displayname = + (document.getElementById("showname")).checked && + chatmsg.showname !== "" + ? chatmsg.showname + : chatmsg.nameplate; + + // Clear out the last message + chatBoxInner.innerText = textnow; + nameBoxInner.innerText = displayname; + + if (lastChar !== chatmsg.name) { + charLayers.style.opacity = "0"; + pairLayers.style.opacity = "0"; + } + + lastChar = chatmsg.name; + client.viewport.lastChar = chatmsg.name; + + appendICLog(chatmsg.content, chatmsg.showname, chatmsg.nameplate); + + checkCallword(chatmsg.content, sfxAudio); + + setEmote( + AO_HOST, + client, + chatmsg.name.toLowerCase(), + chatmsg.sprite, + "(a)", + false, + chatmsg.side + ); + + if (chatmsg.other_name) { + setEmote( + AO_HOST, + client, + chatmsg.other_name.toLowerCase(), + chatmsg.other_emote, + "(a)", + false, + chatmsg.side + ); + } + + // gets which shout shall played + const shoutSprite = ( + document.getElementById("client_shout") + ); + const shout = SHOUTS[chatmsg.objection]; + if (shout) { + // Hide message box + chatContainerBox.style.opacity = "0"; + if (chatmsg.objection === 4) { + shoutSprite.src = `${AO_HOST}characters/${encodeURI( + chatmsg.name.toLowerCase() + )}/custom.gif`; + } else { + shoutSprite.src = masterClient.resources[shout].src; + shoutSprite.style.animation = "bubble 700ms steps(10, jump-both)"; + } + shoutSprite.style.opacity = "1"; + + shoutaudio.src = `${AO_HOST}characters/${encodeURI( + chatmsg.name.toLowerCase() + )}/${shout}.opus`; + shoutaudio.play(); + shoutTimer = masterClient.resources[shout].duration; + } else { + shoutTimer = 0; + } + + chatmsg.startpreanim = true; + let gifLength = 0; + + if (chatmsg.type === 1 && chatmsg.preanim !== "-") { + //we have a preanim + chatContainerBox.style.opacity = "0"; + gifLength = await getAnimLength( + `${AO_HOST}characters/${encodeURI( + chatmsg.name.toLowerCase() + )}/${encodeURI(chatmsg.preanim)}` + ); + console.debug("preanim is " + gifLength + " long"); + chatmsg.startspeaking = false; + } else { + chatmsg.startspeaking = true; + if (chatmsg.content !== "") chatContainerBox.style.opacity = "1"; + } + chatmsg.preanimdelay = gifLength; + const setAside = { + position: chatmsg.side, + showSpeedLines: false, + showDesk: false, + }; + let skipoffset: boolean = false; + if (chatmsg.type === 5) { + setAside.showSpeedLines = true; + setAside.showDesk = false; + set_side(setAside); + } else { + switch (Number(chatmsg.deskmod)) { + case 0: //desk is hidden + setAside.showSpeedLines = false; + setAside.showDesk = false; + set_side(setAside); + break; + case 1: //desk is shown + setAside.showSpeedLines = false; + setAside.showDesk = true; + set_side(setAside); + break; + case 2: //desk is hidden during preanim, but shown during idle/talk + setAside.showSpeedLines = false; + setAside.showDesk = false; + set_side(setAside); + break; + case 3: //opposite of 2 + setAside.showSpeedLines = false; + setAside.showDesk = false; + set_side(setAside); + break; + case 4: //desk is hidden, character offset is ignored, pair character is hidden during preanim, normal behavior during idle/talk + setAside.showSpeedLines = false; + setAside.showDesk = false; + set_side(setAside); + skipoffset = true; + break; + case 5: //opposite of 4 + setAside.showSpeedLines = false; + setAside.showDesk = true; + set_side(setAside); + break; + default: + setAside.showSpeedLines = false; + setAside.showDesk = true; + set_side(setAside); + break; + } + } + + setChatbox(chatmsg.chatbox); + resizeChatbox(); + + if (!skipoffset) { + // Flip the character + charLayers.style.transform = + chatmsg.flip === 1 ? "scaleX(-1)" : "scaleX(1)"; + pairLayers.style.transform = + chatmsg.other_flip === 1 ? "scaleX(-1)" : "scaleX(1)"; + + // Shift by the horizontal offset + switch (chatmsg.side) { + case "wit": + pairLayers.style.left = `${200 + Number(chatmsg.other_offset[0])}%`; + charLayers.style.left = `${200 + Number(chatmsg.self_offset[0])}%`; + break; + case "pro": + pairLayers.style.left = `${400 + Number(chatmsg.other_offset[0])}%`; + charLayers.style.left = `${400 + Number(chatmsg.self_offset[0])}%`; + break; + default: + pairLayers.style.left = `${Number(chatmsg.other_offset[0])}%`; + charLayers.style.left = `${Number(chatmsg.self_offset[0])}%`; + break; + } + + // New vertical offsets + pairLayers.style.top = `${Number(chatmsg.other_offset[1])}%`; + charLayers.style.top = `${Number(chatmsg.self_offset[1])}%`; + } + + blipChannels.forEach( + (channel: HTMLAudioElement) => + (channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI( + chatmsg.blips.toLowerCase() + )}.opus`) + ); + + // process markup + if (chatmsg.content.startsWith("~~")) { + chatBoxInner.style.textAlign = "center"; + chatmsg.content = chatmsg.content.substring(2, chatmsg.content.length); + } else { + chatBoxInner.style.textAlign = "inherit"; + } + + // apply effects + fg.style.animation = ""; + const effectName = chatmsg.effects[0].toLowerCase(); + const badEffects = ["", "-", "none"]; + if (effectName.startsWith("rain")) { + (document.getElementById("effect_css")).href = "styles/effects/rain.css"; + let intensity = 200; + if (effectName.endsWith("weak")) { + intensity = 100; + } else if (effectName.endsWith("strong")) { + intensity = 400; + } + if (intensity < fg.childElementCount) + fg.innerHTML = ''; + else + intensity = intensity - fg.childElementCount; + + for (let i = 0; i < intensity; i++) { + let drop = document.createElement("p"); + drop.style.left = (Math.random() * 100) + "%"; + drop.style.animationDelay = String(Math.random()) + "s"; + fg.appendChild(drop) + } + } else if ( + chatmsg.effects[0] && + !badEffects.includes(effectName) + ) { + (document.getElementById("effect_css")).href = ""; + fg.innerHTML = ''; + const baseEffectUrl = `${AO_HOST}themes/default/effects/`; + fg.src = `${baseEffectUrl}${encodeURI(effectName)}.webp`; + } else { + fg.innerHTML = ''; + fg.src = transparentPng; + } + + charLayers.style.opacity = "1"; + + const soundChecks = ["0", "1", "", undefined]; + if (soundChecks.some((check) => chatmsg.sound === check)) { + chatmsg.sound = chatmsg.effects[2]; + } + chatmsg.parsed = await attorneyMarkdown.applyMarkdown( + chatmsg.content, + COLORS[chatmsg.color] + ); + chat_tick(); + }; + + const handleTextTick = async (charLayers: HTMLImageElement) => { + const chatBox = document.getElementById("client_chat"); + const waitingBox = document.getElementById("client_chatwaiting"); + const chatBoxInner = document.getElementById("client_inner_chat"); + const charName = chatmsg.name.toLowerCase(); + const charEmote = chatmsg.sprite.toLowerCase(); + + if (chatmsg.content.charAt(textnow.length) !== " ") { + blipChannels[currentBlipChannel].play(); + currentBlipChannel++; + currentBlipChannel %= blipChannels.length; + } + textnow = chatmsg.content.substring(0, textnow.length + 1); + const characterElement = chatmsg.parsed[textnow.length - 1]; + if (characterElement) { + const COMMAND_IDENTIFIER = "\\"; + + const nextCharacterElement = chatmsg.parsed[textnow.length]; + const flash = async () => { + const effectlayer = document.getElementById("client_fg"); + playSFX(`${AO_HOST}sounds/general/sfx-realization.opus`, false); + effectlayer.style.animation = "flash 0.4s 1"; + await delay(400); + effectlayer.style.removeProperty("animation"); + }; + + const shake = async () => { + const gamewindow = document.getElementById("client_gamewindow"); + playSFX(`${AO_HOST}sounds/general/sfx-stab.opus`, false); + gamewindow.style.animation = "shake 0.2s 1"; + await delay(200); + gamewindow.style.removeProperty("animation"); + }; + + const commands = new Map( + Object.entries({ + s: shake, + f: flash, + }) + ); + const textSpeeds = new Set(["{", "}"]); + + // Changing Text Speed + if (textSpeeds.has(characterElement.innerHTML)) { + // Grab them all in a row + const MAX_SLOW_CHATSPEED = 120; + for (let i = textnow.length; i < chatmsg.content.length; i++) { + const currentCharacter = chatmsg.parsed[i - 1].innerHTML; + if (currentCharacter === "}") { + if (chatmsg.speed > 0) { + chatmsg.speed -= 20; + } + } else if (currentCharacter === "{") { + if (chatmsg.speed < MAX_SLOW_CHATSPEED) { + chatmsg.speed += 20; + } + } else { + // No longer at a speed character + textnow = chatmsg.content.substring(0, i); + break; + } + } + } + + if ( + characterElement.innerHTML === COMMAND_IDENTIFIER && + commands.has(nextCharacterElement?.innerHTML) + ) { + textnow = chatmsg.content.substring(0, textnow.length + 1); + await commands.get(nextCharacterElement.innerHTML)(); + } else { + chatBoxInner.appendChild(chatmsg.parsed[textnow.length - 1]); + } + } + // scroll to bottom + chatBox.scrollTop = chatBox.scrollHeight; + + if (textnow === chatmsg.content) { + animating = false; + setEmote( + AO_HOST, + client, + charName, + charEmote, + "(a)", + false, + chatmsg.side + ); + charLayers.style.opacity = "1"; + waitingBox.style.opacity = "1"; + clearTimeout(updater); + } + }; + /** + * Updates the chatbox based on the given text. + * + * OK, here's the documentation on how this works: + * + * 1 _animating + * If we're not done with this characters animation, i.e. his text isn't fully there, set a timeout for the next tick/step to happen + * + * 2 startpreanim + * If the shout timer is over it starts with the preanim + * The first thing it checks for is the shake effect (TODO on client this is handled by the @ symbol and not a flag ) + * Then is the flash/realization effect + * After that, the shout image set to be transparent + * and the main characters preanim gif is loaded + * If pairing is supported the paired character will just stand around with his idle sprite + * + * 3 preanimdelay over + * this animates the evidence popup and finally shows the character name and message box + * it sets the text color and the character speaking sprite + * + * 4 textnow != content + * this adds a character to the textbox and stops the animations if the entire message is present in the textbox + * + * 5 sfx + * independent of the stuff above, this will play any sound effects specified by the emote the character sent. + * happens after the shout delay + an sfx delay that comes with the message packet + * + * XXX: This relies on a global variable `chatmsg`! + */ + const chat_tick = async () => { + // 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"); + const eviBox = document.getElementById("client_evi"); + const shoutSprite = ( + document.getElementById("client_shout") + ); + const effectlayer = document.getElementById("client_fg"); + const chatBoxInner = document.getElementById("client_inner_chat"); + let charLayers = document.getElementById("client_char"); + let pairLayers = ( + document.getElementById("client_pair_char") + ); + + const validSides: string[] = ["def", "pro", "wit"]; // these are for the full view pan, the other positions use 'client_char' + if (validSides.includes(chatmsg.side)) { + charLayers = ( + document.getElementById(`client_${chatmsg.side}_char`) + ); + pairLayers = ( + document.getElementById(`client_${chatmsg.side}_pair_char`) + ); + } + + const charName = chatmsg.name.toLowerCase(); + const charEmote = chatmsg.sprite.toLowerCase(); + + const pairName = chatmsg.other_name.toLowerCase(); + const pairEmote = chatmsg.other_emote.toLowerCase(); + + // TODO: preanims sometimes play when they're not supposed to + const isShoutOver = tickTimer >= shoutTimer; + const isShoutAndPreanimOver = + tickTimer >= shoutTimer + chatmsg.preanimdelay; + if (isShoutOver && startFirstTickCheck) { + // Effect stuff + if (chatmsg.screenshake === 1) { + // Shake screen + playSFX(`${AO_HOST}sounds/general/sfx-stab.opus`, false); + gamewindow.style.animation = "shake 0.2s 1"; + } + if (chatmsg.flash === 1) { + // Flash screen + playSFX(`${AO_HOST}sounds/general/sfx-realization.opus`, false); + effectlayer.style.animation = "flash 0.4s 1"; + } + + // Pre-animation stuff + if (chatmsg.preanimdelay > 0) { + shoutSprite.style.opacity = "0"; + shoutSprite.style.animation = ""; + const preanim = chatmsg.preanim.toLowerCase(); + setEmote(AO_HOST, client, charName, preanim, "", false, chatmsg.side); + } + + if (chatmsg.other_name) { + pairLayers.style.opacity = "1"; + } else { + pairLayers.style.opacity = "0"; + } + // Done with first check, move to second + startFirstTickCheck = false; + startSecondTickCheck = true; + + chatmsg.startpreanim = false; + chatmsg.startspeaking = true; + } + + const hasNonInterruptingPreAnim = chatmsg.noninterrupting_preanim === 1; + if (textnow !== chatmsg.content && hasNonInterruptingPreAnim) { + const chatContainerBox = document.getElementById("client_chatcontainer"); + chatContainerBox.style.opacity = "1"; + await handleTextTick(charLayers); + } else if (isShoutAndPreanimOver && startSecondTickCheck) { + if (chatmsg.startspeaking) { + chatmsg.startspeaking = false; + + // Evidence Bullshit + if (chatmsg.evidence > 0) { + // Prepare evidence + eviBox.src = safeTags( + masterClient.evidences[chatmsg.evidence - 1].icon + ); + + eviBox.style.width = "auto"; + eviBox.style.height = "36.5%"; + eviBox.style.opacity = "1"; + + testimonyAudio.src = `${AO_HOST}sounds/general/sfx-evidenceshoop.opus`; + testimonyAudio.play(); + + if (chatmsg.side === "def") { + // Only def show evidence on right + eviBox.style.right = "1em"; + eviBox.style.left = "initial"; + } else { + eviBox.style.right = "initial"; + eviBox.style.left = "1em"; + } + } + chatBoxInner.className = `text_${COLORS[chatmsg.color]}`; + + if (chatmsg.preanimdelay === 0) { + shoutSprite.style.opacity = "0"; + shoutSprite.style.animation = ""; + } + + switch (Number(chatmsg.deskmod)) { + case 2: + set_side({ + position: chatmsg.side, + showSpeedLines: false, + showDesk: true, + }); + break; + case 3: + set_side({ + position: chatmsg.side, + showSpeedLines: false, + showDesk: false, + }); + break; + case 4: + set_side({ + position: chatmsg.side, + showSpeedLines: false, + showDesk: true, + }); + break; + case 5: + set_side({ + position: chatmsg.side, + showSpeedLines: false, + showDesk: false, + }); + break; + } + + if (chatmsg.other_name) { + setEmote( + AO_HOST, + client, + pairName, + pairEmote, + "(a)", + true, + chatmsg.side + ); + pairLayers.style.opacity = "1"; + } else { + pairLayers.style.opacity = "0"; + } + + setEmote( + AO_HOST, + client, + charName, + charEmote, + "(b)", + false, + chatmsg.side + ); + charLayers.style.opacity = "1"; + + if (textnow === chatmsg.content) { + setEmote( + AO_HOST, + client, + charName, + charEmote, + "(a)", + false, + chatmsg.side + ); + charLayers.style.opacity = "1"; + waitingBox.style.opacity = "1"; + animating = false; + clearTimeout(updater); + return; + } + } else if (textnow !== chatmsg.content) { + const chatContainerBox = document.getElementById( + "client_chatcontainer" + ); + chatContainerBox.style.opacity = "1"; + await handleTextTick(charLayers); + } + } + + if (!sfxplayed && chatmsg.snddelay + shoutTimer >= tickTimer) { + sfxplayed = 1; + if ( + chatmsg.sound !== "0" && + chatmsg.sound !== "1" && + chatmsg.sound !== "" && + chatmsg.sound !== undefined && + (chatmsg.type == 1 || chatmsg.type == 2 || chatmsg.type == 6) + ) { + playSFX( + `${AO_HOST}sounds/general/${encodeURI( + chatmsg.sound.toLowerCase() + )}.opus`, + chatmsg.looping_sfx + ); + } + } + if (animating) { + chat_tick(); + } + tickTimer += UPDATE_INTERVAL; + }; + /** + * Triggered by the theme selector. + */ + function reloadTheme() { + theme = (document.getElementById("client_themeselect")) + .value; + + setCookie("theme", theme); + (( + document.getElementById("client_theme") + )).href = `styles/${theme}.css`; + } + window.reloadTheme = reloadTheme; + + const changeMusicVolume = (volume: number = -1) => { + const clientVolume = Number( + (document.getElementById("client_mvolume")).value + ); + let musicVolume = volume === -1 ? clientVolume : volume; + music.forEach( + (channel: HTMLAudioElement) => (channel.volume = musicVolume) + ); + setCookie("musicVolume", String(musicVolume)); + }; + window.changeMusicVolume = changeMusicVolume; + + return { + chat_tick, + changeMusicVolume, + reloadTheme, + playSFX, + set_side, + setBackgroundName, + initTestimonyUpdater, + updateTestimony, + disposeTestimony, + handle_ic_speaking, + handleTextTick, + getBackgroundFolder, + getBackgroundName, + getSfxAudio, + setSfxAudio, + theme, + chatmsg, + blipChannels, + lastChar, + music, + musicVolume, + }; +}; + +export default viewport; -- cgit From 7c67d6e8009fd054466b26f33b63b7c9c74606f9 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 15:41:30 -0400 Subject: Viewport can import client --- webAO/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webAO/client.ts b/webAO/client.ts index b908b62..f3711e9 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -145,7 +145,7 @@ class Client extends EventEmitter { this.selectedEvidence = 0; this.checkUpdater = null; this.sender = sender - this.viewport = masterViewport(this); + this.viewport = masterViewport(); this._lastTimeICReceived = new Date(0); loadResources isLowMemory -- cgit From ac66008a36f58d564a13e8e1fb31a0cd965f165a Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 15:41:54 -0400 Subject: Viewport no longer has specific functions --- webAO/client/loadResources.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/webAO/client/loadResources.ts b/webAO/client/loadResources.ts index 65d0895..4954966 100644 --- a/webAO/client/loadResources.ts +++ b/webAO/client/loadResources.ts @@ -1,12 +1,14 @@ import getCookie from "../utils/getCookie"; import vanilla_evidence_arr from "../constants/evidence.js"; import vanilla_background_arr from "../constants/backgrounds.js"; -import { client } from "../client"; +import { changeMusicVolume } from '../dom/changeMusicVolume' import { setChatbox } from "../dom/setChatbox"; import { changeSFXVolume, changeShoutVolume, changeTestimonyVolume } from "../dom/changeVolume"; import { showname_click } from "../dom/showNameClick"; import { changeBlipVolume } from '../dom/changeBlipVolume' +import { reloadTheme } from '../dom/reloadTheme' const version = process.env.npm_package_version; + /** * Load game resources and stored settings. */ @@ -41,7 +43,7 @@ export const loadResources = () => { (( document.querySelector(`#client_themeselect [value="${cookietheme}"]`) )).selected = true; - client.viewport.reloadTheme(); + reloadTheme(); const cookiechatbox = getCookie("chatbox") || "dynamic"; @@ -52,7 +54,7 @@ export const loadResources = () => { (document.getElementById("client_mvolume")).value = getCookie("musicVolume") || "1"; - client.viewport.changeMusicVolume(); + changeMusicVolume(); (document.getElementById("client_sfxaudio")).volume = Number(getCookie("sfxVolume")) || 1; changeSFXVolume(); -- cgit From 766bef212c09dc85a7afda085cbb9690f985ed8f Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 15:42:34 -0400 Subject: Music volume moved out of viewport --- webAO/dom/changeMusicVolume.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 webAO/dom/changeMusicVolume.ts diff --git a/webAO/dom/changeMusicVolume.ts b/webAO/dom/changeMusicVolume.ts new file mode 100644 index 0000000..9e5d51a --- /dev/null +++ b/webAO/dom/changeMusicVolume.ts @@ -0,0 +1,14 @@ +import { client } from '../client' +import setCookie from '../utils/setCookie'; + +export const changeMusicVolume = (volume: number = -1) => { + const clientVolume = Number( + (document.getElementById("client_mvolume")).value + ); + let musicVolume = volume === -1 ? clientVolume : volume; + client.viewport.music.forEach( + (channel: HTMLAudioElement) => (channel.volume = musicVolume) + ); + setCookie("musicVolume", String(musicVolume)); +}; +window.changeMusicVolume = changeMusicVolume; \ No newline at end of file -- cgit From 383991dd82af6bd867ef29af37fb694d64c28450 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 15:42:52 -0400 Subject: Typechecking changed --- webAO/packets/handlers/handleMS.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/webAO/packets/handlers/handleMS.ts b/webAO/packets/handlers/handleMS.ts index 1256900..22bbab6 100644 --- a/webAO/packets/handlers/handleMS.ts +++ b/webAO/packets/handlers/handleMS.ts @@ -2,7 +2,7 @@ import { client, extrafeatures, UPDATE_INTERVAL } from "../../client"; import { handleCharacterInfo } from "../../client/handleCharacterInfo"; import { resetICParams } from "../../client/resetICParams"; import { prepChat, safeTags } from "../../encoding"; - +import { handle_ic_speaking } from '../../viewport/utils/handleICSpeaking' /** * Handles an in-character chat message. * @param {*} args packet arguments @@ -55,7 +55,7 @@ export const handleMS = (args: string[]) => { if (char_muted === false) { let chatmsg = { - deskmod: safeTags(args[1]).toLowerCase(), + deskmod: Number(safeTags(args[1]).toLowerCase()), preanim: safeTags(args[2]).toLowerCase(), // get preanim nameplate: msg_nameplate, chatbox: char_chatbox, @@ -69,7 +69,7 @@ export const handleMS = (args: string[]) => { charid: char_id, snddelay: Number(args[10]), objection: Number(args[11]), - evidence: safeTags(args[12]), + evidence: Number(safeTags(args[12])), flip: Number(args[13]), flash: Number(args[14]), color: Number(args[15]), @@ -158,7 +158,8 @@ export const handleMS = (args: string[]) => { if (chatmsg.charid === client.charID) { resetICParams(); } - client.viewport.handle_ic_speaking(chatmsg); // no await + + handle_ic_speaking(chatmsg); // no await } } } \ No newline at end of file -- cgit From b3229eb72ba04152f1df97cd3800e1bc17c5646c Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 15:43:05 -0400 Subject: Function movement --- webAO/packets/handlers/handleRT.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webAO/packets/handlers/handleRT.ts b/webAO/packets/handlers/handleRT.ts index 5bbf2b2..62ebb1e 100644 --- a/webAO/packets/handlers/handleRT.ts +++ b/webAO/packets/handlers/handleRT.ts @@ -1,5 +1,5 @@ import { client } from "../../client"; - +import { initTestimonyUpdater } from '../../viewport/utils/initTestimonyUpdater' /** * Handles a testimony states. @@ -21,5 +21,5 @@ export const handleRT = (args: string[]) => { default: console.warn("Invalid testimony"); } - client.viewport.initTestimonyUpdater(); + initTestimonyUpdater(); } \ No newline at end of file -- cgit From a2cc1596e1dbacbb6d4a478c17fcc1f16964ce4b Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 15:43:16 -0400 Subject: Typechecking change --- webAO/viewport/interfaces/ChatMsg.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webAO/viewport/interfaces/ChatMsg.ts b/webAO/viewport/interfaces/ChatMsg.ts index 293a774..6b96c6e 100644 --- a/webAO/viewport/interfaces/ChatMsg.ts +++ b/webAO/viewport/interfaces/ChatMsg.ts @@ -2,12 +2,12 @@ export interface ChatMsg { content: string; objection: number; sound: string; - startpreanim: boolean; - startspeaking: boolean; + startpreanim?: boolean; + startspeaking?: boolean; side: any; color: number; snddelay: number; - preanimdelay: number; + preanimdelay?: number; speed: number; blips: string; self_offset?: number[]; -- cgit From c5c277c8d8264dadd8a9e4171764698dd02d136a Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 15:43:37 -0400 Subject: Setting side moved out --- webAO/viewport/utils/setSide.ts | 91 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 webAO/viewport/utils/setSide.ts diff --git a/webAO/viewport/utils/setSide.ts b/webAO/viewport/utils/setSide.ts new file mode 100644 index 0000000..15cb7c6 --- /dev/null +++ b/webAO/viewport/utils/setSide.ts @@ -0,0 +1,91 @@ +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'; + +/** + * Changes the viewport background based on a given position. + * + * Valid positions: `def, pro, hld, hlp, wit, jud, jur, sea` + * @param {string} position the position to change into + */ +export const set_side = async ({ + position, + showSpeedLines, + showDesk, +}: { + position: string; + showSpeedLines: boolean; + showDesk: boolean; +}) => { + const view = document.getElementById("client_fullview")!; + console.log(position) + let bench: HTMLImageElement; + if (['def','pro','wit'].includes(position)) { + bench = ( + document.getElementById(`client_${position}_bench`) + ); + } else { + bench = document.getElementById("client_bench_classic"); + } + + let court: HTMLImageElement; + if ("def,pro,wit".includes(position)) { + court = ( + document.getElementById(`client_court_${position}`) + ); + } else { + court = document.getElementById("client_court_classic"); + } + + let bg; + let desk; + let speedLines; + + if ("def,pro,hld,hlp,wit,jud,jur,sea".includes(position)) { + bg = positions[position].bg; + desk = positions[position].desk; + speedLines = positions[position].speedLines; + } else { + bg = `${position}`; + desk = { ao2: `${position}_overlay.png`, ao1: "_overlay.png" }; + speedLines = "defense_speedlines.gif"; + } + + if (showSpeedLines === true) { + court.src = `${AO_HOST}themes/default/${encodeURI(speedLines)}`; + } 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; + bench.style.opacity = "1"; + } else { + bench.style.opacity = "0"; + } + + if ("def,pro,wit".includes(position)) { + view.style.display = ""; + document.getElementById("client_classicview")!.style.display = "none"; + switch (position) { + case "def": + view.style.left = "0"; + break; + case "wit": + view.style.left = "-200%"; + break; + case "pro": + view.style.left = "-400%"; + break; + } + } else { + view.style.display = "none"; + document.getElementById("client_classicview").style.display = ""; + } +}; -- cgit From 9272ecb2a5e154029e9eef08133386a4eedecb83 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 16:24:43 -0400 Subject: Refactor with getter --- webAO/client/setEmote.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webAO/client/setEmote.ts b/webAO/client/setEmote.ts index 161eb51..f4fbdbb 100644 --- a/webAO/client/setEmote.ts +++ b/webAO/client/setEmote.ts @@ -28,7 +28,7 @@ const setEmote = async ( for (const extension of extensionsMap) { // Hides all sprites before creating a new sprite - if (client.viewport.lastChar !== client.viewport.chatmsg.name) { + if (client.viewport.getLastCharacter() !== client.viewport.getChatmsg().name) { emoteSelector.src = transparentPng; } let url; -- cgit From 3929d4cc4c217738cdda8ec02d1668d0fea20935 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 16:26:37 -0400 Subject: Refactor theme --- webAO/dom/reloadTheme.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 webAO/dom/reloadTheme.ts diff --git a/webAO/dom/reloadTheme.ts b/webAO/dom/reloadTheme.ts new file mode 100644 index 0000000..bfa46b6 --- /dev/null +++ b/webAO/dom/reloadTheme.ts @@ -0,0 +1,16 @@ +import { client } from '../client' +import setCookie from '../utils/setCookie'; + +/** + * Triggered by the theme selector. + */ +export const reloadTheme = () => { + client.viewport.setTheme((document.getElementById("client_themeselect")) + .value); + + setCookie("theme", client.viewport.getTheme()); + (( + document.getElementById("client_theme") + )).href = `styles/${client.viewport.getTheme()}.css`; +} +window.reloadTheme = reloadTheme; \ No newline at end of file -- cgit From 3bc1d8ca5bc74f40d96c9f4edf7f5b1adee188a4 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 16:26:49 -0400 Subject: Refactor getChatmsg --- webAO/packets/handlers/handleMS.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webAO/packets/handlers/handleMS.ts b/webAO/packets/handlers/handleMS.ts index 22bbab6..92d65db 100644 --- a/webAO/packets/handlers/handleMS.ts +++ b/webAO/packets/handlers/handleMS.ts @@ -9,7 +9,7 @@ import { handle_ic_speaking } from '../../viewport/utils/handleICSpeaking' */ export const handleMS = (args: string[]) => { // TODO: this if-statement might be a bug. - if (args[4] !== client.viewport.chatmsg.content) { + if (args[4] !== client.viewport.getChatmsg().content) { document.getElementById("client_inner_chat")!.innerHTML = ""; const char_id = Number(args[9]); -- cgit From f8e8ab1b0d0edcddc55f57df76ee81fa14a1e5e8 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 11 Sep 2022 16:31:04 -0400 Subject: Finishing of refactor --- webAO/viewport/interfaces/Viewport.ts | 35 +- webAO/viewport/utils/handleICSpeaking.ts | 312 ++++++++++++++++ webAO/viewport/utils/initTestimonyUpdater.ts | 31 ++ webAO/viewport/viewport.ts | 529 ++++----------------------- 4 files changed, 433 insertions(+), 474 deletions(-) create mode 100644 webAO/viewport/utils/handleICSpeaking.ts create mode 100644 webAO/viewport/utils/initTestimonyUpdater.ts diff --git a/webAO/viewport/interfaces/Viewport.ts b/webAO/viewport/interfaces/Viewport.ts index 3ffbcc8..5b428c1 100644 --- a/webAO/viewport/interfaces/Viewport.ts +++ b/webAO/viewport/interfaces/Viewport.ts @@ -1,17 +1,35 @@ import { ChatMsg } from "./ChatMsg"; + export interface Viewport { + getTextNow: Function; + setTextNow: Function; + getChatmsg: Function; + setChatmsg: Function; + getSfxPlayed: Function; + setSfxPlayed: Function; + setTickTimer: Function; + getTickTimer: Function; + getAnimating: Function; + setAnimating: Function; + getLastEvidence: Function; + setLastEvidence: Function; + setLastCharacter: Function; + getLastCharacter: Function; + setShoutTimer: Function; + getShoutTimer: Function; + setTestimonyTimer: Function; + getTestimonyTimer: Function; + setTestimonyUpdater: Function; + getTestimonyUpdater: Function; + getTheme: Function; + setTheme: Function; + testimonyAudio: HTMLAudioElement; chat_tick: Function; - changeMusicVolume: Function; - reloadTheme: Function; playSFX: Function; set_side: Function; - initTestimonyUpdater: Function; updateTestimony: Function; disposeTestimony: Function; - handle_ic_speaking: Function; handleTextTick: Function; - theme: string; - chatmsg: ChatMsg; setSfxAudio: Function; getSfxAudio: Function; getBackgroundFolder: Function; @@ -19,6 +37,7 @@ export interface Viewport { music: any; musicVolume: number; setBackgroundName: Function; - lastChar: string; getBackgroundName: Function; -} \ No newline at end of file + shoutaudio: HTMLAudioElement; + updater: any; +} diff --git a/webAO/viewport/utils/handleICSpeaking.ts b/webAO/viewport/utils/handleICSpeaking.ts new file mode 100644 index 0000000..c396093 --- /dev/null +++ b/webAO/viewport/utils/handleICSpeaking.ts @@ -0,0 +1,312 @@ +import { ChatMsg } from "../interfaces/ChatMsg"; +import { client } from "../../client"; +import { appendICLog } from "../../client/appendICLog"; +import { checkCallword } from "../../client/checkCallword"; +import setEmote from "../../client/setEmote"; +import { AO_HOST } from "../../client/aoHost"; +import { SHOUTS } from "../constants/shouts"; +import getAnimLength from "../../utils/getAnimLength"; +import { setChatbox } from "../../dom/setChatbox"; +import { resizeChatbox } from "../../dom/resizeChatbox"; +import transparentPng from "../../constants/transparentPng"; +import { COLORS } from "../constants/colors"; +import mlConfig from "../../utils/aoml"; + +const attorneyMarkdown = mlConfig(AO_HOST); + +export let startFirstTickCheck: boolean; +export const setStartFirstTickCheck = (val: boolean) => {startFirstTickCheck = val} +export let startSecondTickCheck: boolean; +export const setStartSecondTickCheck = (val: boolean) => {startSecondTickCheck = val} +export let startThirdTickCheck: boolean; +export const setStartThirdTickCheck = (val: boolean) => {startThirdTickCheck = val} +/** + * Sets a new emote. + * This sets up everything before the tick() loops starts + * a lot of things can probably be moved here, like starting the shout animation if there is one + * TODO: the preanim logic, on the other hand, should probably be moved to tick() + * @param {object} chatmsg the new chat message + */ +export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => { + client.viewport.setChatmsg(playerChatMsg); + client.viewport.setTextNow(""); + client.viewport.setSfxPlayed(0); + client.viewport.setTickTimer(0); + client.viewport.setAnimating(true); + + startFirstTickCheck = true; + startSecondTickCheck = false; + startThirdTickCheck = false; + let charLayers = document.getElementById("client_char")!; + let pairLayers = document.getElementById("client_pair_char")!; + // stop updater + clearTimeout(client.viewport.updater); + + // stop last sfx from looping any longer + client.viewport.getSfxAudio().loop = false; + + const fg = document.getElementById("client_fg"); + const gamewindow = document.getElementById("client_gamewindow")!; + const waitingBox = document.getElementById("client_chatwaiting")!; + + // Reset CSS animation + gamewindow.style.animation = ""; + waitingBox.style.opacity = "0"; + + const eviBox = document.getElementById("client_evi")!; + + if (client.viewport.getLastEvidence() !== client.viewport.getChatmsg().evidence) { + eviBox.style.opacity = "0"; + eviBox.style.height = "0%"; + } + client.viewport.setLastEvidence(client.viewport.getChatmsg().evidence); + + const validSides: string[] = ["def", "pro", "wit"]; // these are for the full view pan, the other positions use 'client_char' + if (validSides.includes(client.viewport.getChatmsg().side)) { + charLayers = document.getElementById(`client_${client.viewport.getChatmsg().side}_char`); + pairLayers = document.getElementById(`client_${client.viewport.getChatmsg().side}_pair_char`); + } + + const chatContainerBox = document.getElementById("client_chatcontainer")!; + const nameBoxInner = document.getElementById("client_inner_name")!; + const chatBoxInner = document.getElementById("client_inner_chat")!; + + const displayname = + (document.getElementById("showname")).checked && + client.viewport.getChatmsg().showname !== "" + ? client.viewport.getChatmsg().showname! + : client.viewport.getChatmsg().nameplate!; + + // Clear out the last message + chatBoxInner.innerText = client.viewport.getTextNow(); + nameBoxInner.innerText = displayname; + + if (client.viewport.getLastCharacter() !== client.viewport.getChatmsg().name) { + charLayers.style.opacity = "0"; + pairLayers.style.opacity = "0"; + } + + client.viewport.setLastCharacter(client.viewport.getChatmsg().name); + + 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, + client.viewport.getChatmsg().name!.toLowerCase(), + client.viewport.getChatmsg().sprite!, + "(a)", + false, + client.viewport.getChatmsg().side + ); + + if (client.viewport.getChatmsg().other_name) { + setEmote( + AO_HOST, + client, + client.viewport.getChatmsg().other_name.toLowerCase(), + client.viewport.getChatmsg().other_emote!, + "(a)", + false, + client.viewport.getChatmsg().side + ); + } + + // gets which shout shall played + const shoutSprite = ( + document.getElementById("client_shout") + ); + + const shout = SHOUTS[client.viewport.getChatmsg().objection]; + if (shout) { + // Hide message box + chatContainerBox.style.opacity = "0"; + if (client.viewport.getChatmsg().objection === 4) { + shoutSprite.src = `${AO_HOST}characters/${encodeURI( + client.viewport.getChatmsg().name!.toLowerCase() + )}/custom.gif`; + } else { + shoutSprite.src = client.resources[shout].src; + shoutSprite.style.animation = "bubble 700ms steps(10, jump-both)"; + } + shoutSprite.style.opacity = "1"; + + client.viewport.shoutaudio.src = `${AO_HOST}characters/${encodeURI( + client.viewport.getChatmsg().name.toLowerCase() + )}/${shout}.opus`; + client.viewport.shoutaudio.play(); + client.viewport.setShoutTimer(client.resources[shout].duration); + } else { + client.viewport.setShoutTimer(0); + } + + client.viewport.getChatmsg().startpreanim = true; + let gifLength = 0; + + 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() + )}/${encodeURI(client.viewport.getChatmsg().preanim)}` + ); + console.debug("preanim is " + gifLength + " long"); + client.viewport.getChatmsg().startspeaking = false; + } else { + client.viewport.getChatmsg().startspeaking = true; + if (client.viewport.getChatmsg().content !== "") chatContainerBox.style.opacity = "1"; + } + client.viewport.getChatmsg().preanimdelay = gifLength; + const setAside = { + position: client.viewport.getChatmsg().side, + showSpeedLines: false, + showDesk: false, + }; + let skipoffset: boolean = false; + if (client.viewport.getChatmsg().type === 5) { + setAside.showSpeedLines = true; + setAside.showDesk = false; + client.viewport.set_side(setAside); + } else { + switch (Number(client.viewport.getChatmsg().deskmod)) { + case 0: //desk is hidden + setAside.showSpeedLines = false; + setAside.showDesk = false; + client.viewport.set_side(setAside); + break; + case 1: //desk is shown + setAside.showSpeedLines = false; + setAside.showDesk = true; + client.viewport.set_side(setAside); + break; + case 2: //desk is hidden during preanim, but shown during idle/talk + setAside.showSpeedLines = false; + setAside.showDesk = false; + client.viewport.set_side(setAside); + break; + case 3: //opposite of 2 + setAside.showSpeedLines = false; + setAside.showDesk = false; + client.viewport.set_side(setAside); + break; + case 4: //desk is hidden, character offset is ignored, pair character is hidden during preanim, normal behavior during idle/talk + setAside.showSpeedLines = false; + setAside.showDesk = false; + client.viewport.set_side(setAside); + skipoffset = true; + break; + case 5: //opposite of 4 + setAside.showSpeedLines = false; + setAside.showDesk = true; + client.viewport.set_side(setAside); + break; + default: + setAside.showSpeedLines = false; + setAside.showDesk = true; + client.viewport.set_side(setAside); + break; + } + } + + setChatbox(client.viewport.getChatmsg().chatbox); + resizeChatbox(); + + if (!skipoffset) { + // Flip the character + charLayers.style.transform = + client.viewport.getChatmsg().flip === 1 ? "scaleX(-1)" : "scaleX(1)"; + pairLayers.style.transform = + client.viewport.getChatmsg().other_flip === 1 ? "scaleX(-1)" : "scaleX(1)"; + + // Shift by the horizontal offset + switch (client.viewport.getChatmsg().side) { + case "wit": + pairLayers.style.left = `${200 + Number(client.viewport.getChatmsg().other_offset[0])}%`; + charLayers.style.left = `${200 + Number(client.viewport.getChatmsg().self_offset[0])}%`; + break; + case "pro": + pairLayers.style.left = `${400 + Number(client.viewport.getChatmsg().other_offset[0])}%`; + charLayers.style.left = `${400 + Number(client.viewport.getChatmsg().self_offset[0])}%`; + break; + default: + pairLayers.style.left = `${Number(client.viewport.getChatmsg().other_offset[0])}%`; + charLayers.style.left = `${Number(client.viewport.getChatmsg().self_offset[0])}%`; + break; + } + + // New vertical offsets + pairLayers.style.top = `${Number(client.viewport.getChatmsg().other_offset[1])}%`; + charLayers.style.top = `${Number(client.viewport.getChatmsg().self_offset[1])}%`; + } + + client.viewport.blipChannels.forEach( + (channel: HTMLAudioElement) => + (channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI( + client.viewport.getChatmsg().blips.toLowerCase() + )}.opus`) + ); + + // process markup + if (client.viewport.getChatmsg().content.startsWith("~~")) { + chatBoxInner.style.textAlign = "center"; + client.viewport.getChatmsg().content = client.viewport.getChatmsg().content.substring(2, client.viewport.getChatmsg().content.length); + } else { + chatBoxInner.style.textAlign = "inherit"; + } + + // apply effects + fg.style.animation = ""; + const effectName = client.viewport.getChatmsg().effects[0].toLowerCase(); + const badEffects = ["", "-", "none"]; + if (effectName.startsWith("rain")) { + (document.getElementById("effect_css")).href = "styles/effects/rain.css"; + let intensity = 200; + if (effectName.endsWith("weak")) { + intensity = 100; + } else if (effectName.endsWith("strong")) { + intensity = 400; + } + if (intensity < fg.childElementCount) + fg.innerHTML = ''; + else + intensity = intensity - fg.childElementCount; + + for (let i = 0; i < intensity; i++) { + let drop = document.createElement("p"); + drop.style.left = (Math.random() * 100) + "%"; + drop.style.animationDelay = String(Math.random()) + "s"; + fg.appendChild(drop) + } + } else if ( + client.viewport.getChatmsg().effects[0] && + !badEffects.includes(effectName) + ) { + (document.getElementById("effect_css")).href = ""; + fg.innerHTML = ''; + const baseEffectUrl = `${AO_HOST}themes/default/effects/`; + fg.src = `${baseEffectUrl}${encodeURI(effectName)}.webp`; + } else { + fg.innerHTML = ''; + 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]; + } + + client.viewport.getChatmsg().parsed = await attorneyMarkdown.applyMarkdown( + client.viewport.getChatmsg().content, + + COLORS[client.viewport.getChatmsg().color] + + ); + client.viewport.chat_tick(); +}; \ No newline at end of file diff --git a/webAO/viewport/utils/initTestimonyUpdater.ts b/webAO/viewport/utils/initTestimonyUpdater.ts new file mode 100644 index 0000000..e6f6e9d --- /dev/null +++ b/webAO/viewport/utils/initTestimonyUpdater.ts @@ -0,0 +1,31 @@ +import { Testimony } from '../interfaces/Testimony' +import { client, UPDATE_INTERVAL } from '../../client' +/** + * Intialize testimony updater + */ +export const initTestimonyUpdater = () => { + const testimonyFilenames: Testimony = { + 1: "witnesstestimony", + 2: "crossexamination", + 3: "notguilty", + 4: "guilty", + }; + + const testimony = testimonyFilenames[client.testimonyID]; + if (!testimony) { + console.warn(`Invalid testimony ID ${client.testimonyID}`); + return; + } + + client.viewport.testimonyAudio.src = client.resources[testimony].sfx; + client.viewport.testimonyAudio.play(); + + const testimonyOverlay = ( + document.getElementById("client_testimony") + ); + testimonyOverlay.src = client.resources[testimony].src; + testimonyOverlay.style.opacity = "1"; + + client.viewport.setTestimonyTimer(0); + client.viewport.setTestimonyUpdater(setTimeout(() => client.viewport.updateTestimony(), UPDATE_INTERVAL)); +}; \ No newline at end of file diff --git a/webAO/viewport/viewport.ts b/webAO/viewport/viewport.ts index 9772796..9ac6e96 100644 --- a/webAO/viewport/viewport.ts +++ b/webAO/viewport/viewport.ts @@ -1,18 +1,8 @@ -import tryUrls from "../utils/tryUrls"; -import fileExists from "../utils/fileExists"; -import Client, { delay } from "../client"; +import { client, delay } from "../client"; import { UPDATE_INTERVAL } from "../client"; -import { setChatbox } from "../dom/setChatbox"; -import { resizeChatbox } from "../dom/resizeChatbox"; -import transparentPng from "../constants/transparentPng"; -import mlConfig from "../utils/aoml"; import setEmote from "../client/setEmote"; -import getAnimLength from "../utils/getAnimLength"; import { safeTags } from "../encoding"; -import setCookie from "../utils/setCookie"; import { AO_HOST } from "../client/aoHost"; -import { appendICLog } from "../client/appendICLog"; -import { checkCallword } from '../client/checkCallword' import { Viewport } from './interfaces/Viewport' import { createBlipsChannels } from './utils/createBlipChannels' import { defaultChatMsg } from './constants/defaultChatMsg' @@ -20,18 +10,16 @@ import { createMusic } from './utils/createMusic' import { createSfxAudio } from './utils/createSfxAudio' import { createShoutAudio } from './utils/createShoutAudio' import { createTestimonyAudio } from './utils/createTestimonyAudio' -import { ChatMsg } from "./interfaces/ChatMsg"; import { Testimony } from './interfaces/Testimony' import { COLORS } from './constants/colors' -import { SHOUTS } from './constants/shouts' -import { positions } from './constants/positions' +import { set_side } from './utils/setSide' +import { ChatMsg } from "./interfaces/ChatMsg"; +import { setStartFirstTickCheck, setStartSecondTickCheck, startFirstTickCheck, startSecondTickCheck } from "./utils/handleICSpeaking"; -const viewport = (masterClient: Client): Viewport => { +const viewport = (): Viewport => { let animating = false; - let attorneyMarkdown = mlConfig(AO_HOST); let blipChannels = createBlipsChannels(); let chatmsg = defaultChatMsg; - let client = masterClient; let currentBlipChannel = 0; let lastChar = ""; let lastEvi = 0; @@ -41,9 +29,6 @@ const viewport = (masterClient: Client): Viewport => { let sfxplayed = 0; let shoutTimer = 0; let shoutaudio = createShoutAudio(); - let startFirstTickCheck: boolean; - let startSecondTickCheck: boolean; - let startThirdTickCheck: boolean; let testimonyAudio = createTestimonyAudio(); let testimonyTimer = 0; let testimonyUpdater: any; @@ -58,129 +43,34 @@ const viewport = (masterClient: Client): Viewport => { const setBackgroundName = (value: string) => { backgroundName = value }; const getBackgroundFolder = () => `${AO_HOST}background/${encodeURI(backgroundName.toLowerCase())}/`; - + const getTextNow = () => {return textnow} + const setTextNow = (val: string) => {textnow = val} + const getChatmsg = () => {return chatmsg} + const setChatmsg = (val: ChatMsg) => {chatmsg = val} + const getSfxPlayed = () => sfxplayed + const setSfxPlayed = (val: number) => {sfxplayed = val} + const getTickTimer = () => tickTimer + const setTickTimer = (val: number) => {tickTimer = val} + const getAnimating = () => animating + const setAnimating = (val: boolean) => {animating = val} + const getLastEvidence = () => lastEvi + const setLastEvidence = (val: number) => {lastEvi = val} + const setLastCharacter = (val: string) => {lastChar = val} + const getLastCharacter = () => lastChar + const getShoutTimer = () => shoutTimer + const setShoutTimer = (val: number) => {shoutTimer = val} + const getTheme = () => theme + const setTheme = (val: string) => {theme = val} + const getTestimonyTimer = () => testimonyTimer; + const setTestimonyTimer = (val: number) => {testimonyTimer = val} + const setTestimonyUpdater = (val: any) => {testimonyUpdater = val} + const getTestimonyUpdater = () => testimonyUpdater const playSFX = async (sfxname: string, looping: boolean) => { sfxAudio.pause(); sfxAudio.loop = looping; sfxAudio.src = sfxname; sfxAudio.play(); }; - - /** - * Changes the viewport background based on a given position. - * - * Valid positions: `def, pro, hld, hlp, wit, jud, jur, sea` - * @param {string} position the position to change into - */ - const set_side = async ({ - position, - showSpeedLines, - showDesk, - }: { - position: string; - showSpeedLines: boolean; - showDesk: boolean; - }) => { - const view = document.getElementById("client_fullview"); - - let bench: HTMLImageElement; - if ("def,pro,wit".includes(position)) { - bench = ( - document.getElementById(`client_${position}_bench`) - ); - } else { - bench = document.getElementById("client_bench_classic"); - } - - let court: HTMLImageElement; - if ("def,pro,wit".includes(position)) { - court = ( - document.getElementById(`client_court_${position}`) - ); - } else { - court = document.getElementById("client_court_classic"); - } - - let bg; - let desk; - let speedLines; - - if ("def,pro,hld,hlp,wit,jud,jur,sea".includes(position)) { - bg = positions[position].bg; - desk = positions[position].desk; - speedLines = positions[position].speedLines; - } else { - bg = `${position}`; - desk = { ao2: `${position}_overlay.png`, ao1: "_overlay.png" }; - speedLines = "defense_speedlines.gif"; - } - - if (showSpeedLines === true) { - court.src = `${AO_HOST}themes/default/${encodeURI(speedLines)}`; - } else { - court.src = await tryUrls(getBackgroundFolder() + bg); - } - - if (showDesk === true && desk) { - const deskFilename = (await fileExists(getBackgroundFolder() + desk.ao2)) - ? desk.ao2 - : desk.ao1; - bench.src = getBackgroundFolder() + deskFilename; - bench.style.opacity = "1"; - } else { - bench.style.opacity = "0"; - } - - if ("def,pro,wit".includes(position)) { - view.style.display = ""; - document.getElementById("client_classicview").style.display = "none"; - switch (position) { - case "def": - view.style.left = "0"; - break; - case "wit": - view.style.left = "-200%"; - break; - case "pro": - view.style.left = "-400%"; - break; - } - } else { - view.style.display = "none"; - document.getElementById("client_classicview").style.display = ""; - } - }; - - /** - * Intialize testimony updater - */ - const initTestimonyUpdater = () => { - const testimonyFilenames: Testimony = { - 1: "witnesstestimony", - 2: "crossexamination", - 3: "notguilty", - 4: "guilty", - }; - - const testimony = testimonyFilenames[masterClient.testimonyID]; - if (!testimony) { - console.warn(`Invalid testimony ID ${masterClient.testimonyID}`); - return; - } - - testimonyAudio.src = masterClient.resources[testimony].sfx; - testimonyAudio.play(); - - const testimonyOverlay = ( - document.getElementById("client_testimony") - ); - testimonyOverlay.src = masterClient.resources[testimony].src; - testimonyOverlay.style.opacity = "1"; - - testimonyTimer = 0; - testimonyUpdater = setTimeout(() => updateTestimony(), UPDATE_INTERVAL); - }; - /** * Updates the testimony overaly */ @@ -195,8 +85,8 @@ const viewport = (masterClient: Client): Viewport => { // Update timer testimonyTimer += UPDATE_INTERVAL; - const testimony = testimonyFilenames[masterClient.testimonyID]; - const resource = masterClient.resources[testimony]; + const testimony = testimonyFilenames[client.testimonyID]; + const resource = client.resources[testimony]; if (!resource) { disposeTestimony(); return; @@ -208,304 +98,15 @@ const viewport = (masterClient: Client): Viewport => { testimonyUpdater = setTimeout(() => updateTestimony(), UPDATE_INTERVAL); } }; - /** * Dispose the testimony overlay */ const disposeTestimony = () => { - masterClient.testimonyID = 0; + client.testimonyID = 0; testimonyTimer = 0; document.getElementById("client_testimony").style.opacity = "0"; clearTimeout(testimonyUpdater); }; - - /** - * Sets a new emote. - * This sets up everything before the tick() loops starts - * a lot of things can probably be moved here, like starting the shout animation if there is one - * TODO: the preanim logic, on the other hand, should probably be moved to tick() - * @param {object} chatmsg the new chat message - */ - const handle_ic_speaking = async (playerChatMsg: ChatMsg) => { - chatmsg = playerChatMsg; - client.viewport.chatmsg = playerChatMsg; - - textnow = ""; - sfxplayed = 0; - tickTimer = 0; - animating = true; - startFirstTickCheck = true; - startSecondTickCheck = false; - startThirdTickCheck = false; - let charLayers = document.getElementById("client_char"); - let pairLayers = document.getElementById("client_pair_char"); - // stop updater - clearTimeout(updater); - - // stop last sfx from looping any longer - sfxAudio.loop = false; - - const fg = document.getElementById("client_fg"); - const gamewindow = document.getElementById("client_gamewindow"); - const waitingBox = document.getElementById("client_chatwaiting"); - - // Reset CSS animation - gamewindow.style.animation = ""; - waitingBox.style.opacity = "0"; - - const eviBox = document.getElementById("client_evi"); - - if (lastEvi !== chatmsg.evidence) { - eviBox.style.opacity = "0"; - eviBox.style.height = "0%"; - } - lastEvi = chatmsg.evidence; - - const validSides: string[] = ["def", "pro", "wit"]; // these are for the full view pan, the other positions use 'client_char' - if (validSides.includes(chatmsg.side)) { - charLayers = document.getElementById(`client_${chatmsg.side}_char`); - pairLayers = document.getElementById(`client_${chatmsg.side}_pair_char`); - } - - const chatContainerBox = document.getElementById("client_chatcontainer"); - const nameBoxInner = document.getElementById("client_inner_name"); - const chatBoxInner = document.getElementById("client_inner_chat"); - - const displayname = - (document.getElementById("showname")).checked && - chatmsg.showname !== "" - ? chatmsg.showname - : chatmsg.nameplate; - - // Clear out the last message - chatBoxInner.innerText = textnow; - nameBoxInner.innerText = displayname; - - if (lastChar !== chatmsg.name) { - charLayers.style.opacity = "0"; - pairLayers.style.opacity = "0"; - } - - lastChar = chatmsg.name; - client.viewport.lastChar = chatmsg.name; - - appendICLog(chatmsg.content, chatmsg.showname, chatmsg.nameplate); - - checkCallword(chatmsg.content, sfxAudio); - - setEmote( - AO_HOST, - client, - chatmsg.name.toLowerCase(), - chatmsg.sprite, - "(a)", - false, - chatmsg.side - ); - - if (chatmsg.other_name) { - setEmote( - AO_HOST, - client, - chatmsg.other_name.toLowerCase(), - chatmsg.other_emote, - "(a)", - false, - chatmsg.side - ); - } - - // gets which shout shall played - const shoutSprite = ( - document.getElementById("client_shout") - ); - const shout = SHOUTS[chatmsg.objection]; - if (shout) { - // Hide message box - chatContainerBox.style.opacity = "0"; - if (chatmsg.objection === 4) { - shoutSprite.src = `${AO_HOST}characters/${encodeURI( - chatmsg.name.toLowerCase() - )}/custom.gif`; - } else { - shoutSprite.src = masterClient.resources[shout].src; - shoutSprite.style.animation = "bubble 700ms steps(10, jump-both)"; - } - shoutSprite.style.opacity = "1"; - - shoutaudio.src = `${AO_HOST}characters/${encodeURI( - chatmsg.name.toLowerCase() - )}/${shout}.opus`; - shoutaudio.play(); - shoutTimer = masterClient.resources[shout].duration; - } else { - shoutTimer = 0; - } - - chatmsg.startpreanim = true; - let gifLength = 0; - - if (chatmsg.type === 1 && chatmsg.preanim !== "-") { - //we have a preanim - chatContainerBox.style.opacity = "0"; - gifLength = await getAnimLength( - `${AO_HOST}characters/${encodeURI( - chatmsg.name.toLowerCase() - )}/${encodeURI(chatmsg.preanim)}` - ); - console.debug("preanim is " + gifLength + " long"); - chatmsg.startspeaking = false; - } else { - chatmsg.startspeaking = true; - if (chatmsg.content !== "") chatContainerBox.style.opacity = "1"; - } - chatmsg.preanimdelay = gifLength; - const setAside = { - position: chatmsg.side, - showSpeedLines: false, - showDesk: false, - }; - let skipoffset: boolean = false; - if (chatmsg.type === 5) { - setAside.showSpeedLines = true; - setAside.showDesk = false; - set_side(setAside); - } else { - switch (Number(chatmsg.deskmod)) { - case 0: //desk is hidden - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - break; - case 1: //desk is shown - setAside.showSpeedLines = false; - setAside.showDesk = true; - set_side(setAside); - break; - case 2: //desk is hidden during preanim, but shown during idle/talk - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - break; - case 3: //opposite of 2 - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - break; - case 4: //desk is hidden, character offset is ignored, pair character is hidden during preanim, normal behavior during idle/talk - setAside.showSpeedLines = false; - setAside.showDesk = false; - set_side(setAside); - skipoffset = true; - break; - case 5: //opposite of 4 - setAside.showSpeedLines = false; - setAside.showDesk = true; - set_side(setAside); - break; - default: - setAside.showSpeedLines = false; - setAside.showDesk = true; - set_side(setAside); - break; - } - } - - setChatbox(chatmsg.chatbox); - resizeChatbox(); - - if (!skipoffset) { - // Flip the character - charLayers.style.transform = - chatmsg.flip === 1 ? "scaleX(-1)" : "scaleX(1)"; - pairLayers.style.transform = - chatmsg.other_flip === 1 ? "scaleX(-1)" : "scaleX(1)"; - - // Shift by the horizontal offset - switch (chatmsg.side) { - case "wit": - pairLayers.style.left = `${200 + Number(chatmsg.other_offset[0])}%`; - charLayers.style.left = `${200 + Number(chatmsg.self_offset[0])}%`; - break; - case "pro": - pairLayers.style.left = `${400 + Number(chatmsg.other_offset[0])}%`; - charLayers.style.left = `${400 + Number(chatmsg.self_offset[0])}%`; - break; - default: - pairLayers.style.left = `${Number(chatmsg.other_offset[0])}%`; - charLayers.style.left = `${Number(chatmsg.self_offset[0])}%`; - break; - } - - // New vertical offsets - pairLayers.style.top = `${Number(chatmsg.other_offset[1])}%`; - charLayers.style.top = `${Number(chatmsg.self_offset[1])}%`; - } - - blipChannels.forEach( - (channel: HTMLAudioElement) => - (channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI( - chatmsg.blips.toLowerCase() - )}.opus`) - ); - - // process markup - if (chatmsg.content.startsWith("~~")) { - chatBoxInner.style.textAlign = "center"; - chatmsg.content = chatmsg.content.substring(2, chatmsg.content.length); - } else { - chatBoxInner.style.textAlign = "inherit"; - } - - // apply effects - fg.style.animation = ""; - const effectName = chatmsg.effects[0].toLowerCase(); - const badEffects = ["", "-", "none"]; - if (effectName.startsWith("rain")) { - (document.getElementById("effect_css")).href = "styles/effects/rain.css"; - let intensity = 200; - if (effectName.endsWith("weak")) { - intensity = 100; - } else if (effectName.endsWith("strong")) { - intensity = 400; - } - if (intensity < fg.childElementCount) - fg.innerHTML = ''; - else - intensity = intensity - fg.childElementCount; - - for (let i = 0; i < intensity; i++) { - let drop = document.createElement("p"); - drop.style.left = (Math.random() * 100) + "%"; - drop.style.animationDelay = String(Math.random()) + "s"; - fg.appendChild(drop) - } - } else if ( - chatmsg.effects[0] && - !badEffects.includes(effectName) - ) { - (document.getElementById("effect_css")).href = ""; - fg.innerHTML = ''; - const baseEffectUrl = `${AO_HOST}themes/default/effects/`; - fg.src = `${baseEffectUrl}${encodeURI(effectName)}.webp`; - } else { - fg.innerHTML = ''; - fg.src = transparentPng; - } - - charLayers.style.opacity = "1"; - - const soundChecks = ["0", "1", "", undefined]; - if (soundChecks.some((check) => chatmsg.sound === check)) { - chatmsg.sound = chatmsg.effects[2]; - } - chatmsg.parsed = await attorneyMarkdown.applyMarkdown( - chatmsg.content, - COLORS[chatmsg.color] - ); - chat_tick(); - }; - const handleTextTick = async (charLayers: HTMLImageElement) => { const chatBox = document.getElementById("client_chat"); const waitingBox = document.getElementById("client_chatwaiting"); @@ -631,7 +232,8 @@ const viewport = (masterClient: Client): Viewport => { const chat_tick = async () => { // note: this is called fairly often // do not perform heavy operations here - + console.log(textnow) + console.log(chatmsg.content) await delay(chatmsg.speed); if (textnow === chatmsg.content) { return; @@ -696,14 +298,15 @@ const viewport = (masterClient: Client): Viewport => { } else { pairLayers.style.opacity = "0"; } + // Done with first check, move to second - startFirstTickCheck = false; - startSecondTickCheck = true; + setStartFirstTickCheck(false) + setStartSecondTickCheck(true) chatmsg.startpreanim = false; chatmsg.startspeaking = true; } - + const hasNonInterruptingPreAnim = chatmsg.noninterrupting_preanim === 1; if (textnow !== chatmsg.content && hasNonInterruptingPreAnim) { const chatContainerBox = document.getElementById("client_chatcontainer"); @@ -717,7 +320,7 @@ const viewport = (masterClient: Client): Viewport => { if (chatmsg.evidence > 0) { // Prepare evidence eviBox.src = safeTags( - masterClient.evidences[chatmsg.evidence - 1].icon + client.evidences[chatmsg.evidence - 1].icon ); eviBox.style.width = "auto"; @@ -842,59 +445,53 @@ const viewport = (masterClient: Client): Viewport => { ); } } + console.log(animating) if (animating) { chat_tick(); } tickTimer += UPDATE_INTERVAL; }; - /** - * Triggered by the theme selector. - */ - function reloadTheme() { - theme = (document.getElementById("client_themeselect")) - .value; - - setCookie("theme", theme); - (( - document.getElementById("client_theme") - )).href = `styles/${theme}.css`; - } - window.reloadTheme = reloadTheme; - - const changeMusicVolume = (volume: number = -1) => { - const clientVolume = Number( - (document.getElementById("client_mvolume")).value - ); - let musicVolume = volume === -1 ? clientVolume : volume; - music.forEach( - (channel: HTMLAudioElement) => (channel.volume = musicVolume) - ); - setCookie("musicVolume", String(musicVolume)); - }; - window.changeMusicVolume = changeMusicVolume; return { + getTextNow, + setTextNow, + getChatmsg, + setChatmsg, + getSfxPlayed, + setSfxPlayed, + setTickTimer, + getTickTimer, + setAnimating, + getAnimating, + getLastEvidence, + setLastEvidence, + setLastCharacter, + getLastCharacter, + getShoutTimer, + setShoutTimer, + setTheme, + getTheme, + setTestimonyTimer, + getTestimonyTimer, + setTestimonyUpdater, + getTestimonyUpdater, + testimonyAudio, chat_tick, - changeMusicVolume, - reloadTheme, playSFX, set_side, setBackgroundName, - initTestimonyUpdater, updateTestimony, disposeTestimony, - handle_ic_speaking, handleTextTick, getBackgroundFolder, getBackgroundName, getSfxAudio, setSfxAudio, - theme, - chatmsg, blipChannels, - lastChar, music, musicVolume, + shoutaudio, + updater, }; }; -- cgit From c3bde03911eb41bb768d1f01c0857d69300e36b8 Mon Sep 17 00:00:00 2001 From: Caleb Date: Tue, 13 Sep 2022 18:16:22 -0400 Subject: Run on a pull request --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b0d5ea4..eaf50c1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,6 +1,6 @@ name: Deploy CI -on: [push] +on: [push, pull_request] jobs: build: -- cgit From 0bff001a1dd5ed8ba83aba4a9de116d566347124 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 23 Sep 2022 17:53:12 +0200 Subject: no more undefined --- webAO/master.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/webAO/master.ts b/webAO/master.ts index 5a31024..2527323 100644 --- a/webAO/master.ts +++ b/webAO/master.ts @@ -20,10 +20,10 @@ let selectedServer: number = -1; let servers: { name: string, description: string, ip: string, port: number, ws_port: number, assets: string, online: string }[] = []; servers[-2] = { - name: 'Singleplayer', description: 'Build cases, try out new things', ip: '127.0.0.1', port: 50001, ws_port: 50001, assets: '', online: '', + name: 'Singleplayer', description: 'Build cases, try out new things', ip: '127.0.0.1', port: 50001, ws_port: 50001, assets: '', online: 'Online: 0/1', }; servers[-1] = { - name: 'Localhost', description: 'This is your computer on port 50001', ip: '127.0.0.1', port: 50001, ws_port: 50001, assets: '', online: 'Online: ?/?', + name: 'Localhost', description: 'This is your computer on port 50001', ip: '127.0.0.1', port: 50001, ws_port: 50001, assets: '', online: 'Offline', }; const fpPromise = FingerprintJS.load(); @@ -58,11 +58,7 @@ export function setServ(ID: number) { if (document.getElementById(`server${ID}`).className === '') { checkOnline(ID, `${servers[ID].ip}:${servers[ID].ws_port}`); } - if (servers[ID].description !== undefined) { - document.getElementById('serverdescription_content').innerHTML = `${servers[ID].online}
${safeTags(servers[ID].description)}`; - } else { - document.getElementById('serverdescription_content').innerHTML = ''; - } + document.getElementById('serverdescription_content').innerHTML = `${servers[ID].online}
${safeTags(servers[ID].description)}`; } window.setServ = setServ; @@ -136,6 +132,7 @@ function processServerlist(thelist: { name: string, description: string, ip: str for (let i = 0; i < thelist.length - 1; i++) { const serverEntry: { name: string, description: string, ip: string, port: number, ws_port: number, assets: string, online: string } = thelist[i]; + servers[i].online = "Offline"; servers[i] = serverEntry; const ipport = `${serverEntry.ip}:${serverEntry.ws_port}`; -- cgit From a732a654c058842e39917210e47ca7476fa7ef68 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 23 Sep 2022 17:56:54 +0200 Subject: swap lines --- webAO/master.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webAO/master.ts b/webAO/master.ts index 2527323..7e9c994 100644 --- a/webAO/master.ts +++ b/webAO/master.ts @@ -132,8 +132,8 @@ function processServerlist(thelist: { name: string, description: string, ip: str for (let i = 0; i < thelist.length - 1; i++) { const serverEntry: { name: string, description: string, ip: string, port: number, ws_port: number, assets: string, online: string } = thelist[i]; - servers[i].online = "Offline"; servers[i] = serverEntry; + servers[i].online = "Offline"; const ipport = `${serverEntry.ip}:${serverEntry.ws_port}`; -- cgit From 4a177accdacb718462f7c5e4bca90b20bdc360cf Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 12 Oct 2022 18:27:12 +0200 Subject: move cred response to dom folder --- webAO/dom/twofactor.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 webAO/dom/twofactor.ts diff --git a/webAO/dom/twofactor.ts b/webAO/dom/twofactor.ts new file mode 100644 index 0000000..145a00e --- /dev/null +++ b/webAO/dom/twofactor.ts @@ -0,0 +1,6 @@ +import { client } from "../client"; + +function handleCredentialResponse(response: any) { + client.sender.sendServer(`2T#${response.credential}#%`); + } +window.handleCredentialResponse = handleCredentialResponse; \ No newline at end of file -- cgit From d6fbcd9aee2fcaf228cf311a439b4537e3d22e61 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 12 Oct 2022 18:29:03 +0200 Subject: don't need this here --- webAO/client.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/webAO/client.ts b/webAO/client.ts index 6d1483b..7e498ec 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -293,6 +293,4 @@ class Client extends EventEmitter { fetchEvidenceList(); } -} - -export default Client; +} \ No newline at end of file -- cgit From 72ed30819368bda1b3ebf9d4908e5ac801da7876 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 17:44:08 +0200 Subject: whoops --- webAO/client.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webAO/client.ts b/webAO/client.ts index 7e498ec..f3711e9 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -293,4 +293,6 @@ class Client extends EventEmitter { fetchEvidenceList(); } -} \ No newline at end of file +} + +export default Client; \ No newline at end of file -- cgit From 5aca325ce9d2d8e2f4472f93a1e74cdfacbe7edf Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 17:54:07 +0200 Subject: center the thing --- public/client.html | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/public/client.html b/public/client.html index de97aba..f65ed9e 100644 --- a/public/client.html +++ b/public/client.html @@ -51,25 +51,25 @@

Choose your character

-- cgit From d1611910b33aa9e188e17400d4778fef9d0cad23 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 17:54:29 +0200 Subject: isn't in client class anymore --- webAO/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webAO/client.ts b/webAO/client.ts index f3711e9..7919402 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -69,8 +69,8 @@ fpPromise client = new Client(serverIP); client.connect() - client.isLowMemory(); - client.loadResources(); + isLowMemory(); + loadResources(); }); export const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); -- cgit From 3445fe86cd359080e6c21b18cb43f08bb5e5881a Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 17:55:00 +0200 Subject: add to window class --- webAO/dom/twofactor.ts | 1 + webAO/dom/window.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/webAO/dom/twofactor.ts b/webAO/dom/twofactor.ts index 145a00e..cb7bccd 100644 --- a/webAO/dom/twofactor.ts +++ b/webAO/dom/twofactor.ts @@ -1,6 +1,7 @@ import { client } from "../client"; function handleCredentialResponse(response: any) { + console.log(response); client.sender.sendServer(`2T#${response.credential}#%`); } window.handleCredentialResponse = handleCredentialResponse; \ No newline at end of file diff --git a/webAO/dom/window.ts b/webAO/dom/window.ts index 2535768..956526c 100644 --- a/webAO/dom/window.ts +++ b/webAO/dom/window.ts @@ -51,6 +51,7 @@ declare global { onEnter: (event: any) => void; onReplayGo: (_event: any) => void; onOOCEnter: (_event: any) => void; + handleCredentialResponse: (_event: any) => void; } } export { } \ No newline at end of file -- cgit From 4b015ddc346835fc97f40ca425666af45d7ec632 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 18:03:35 +0200 Subject: show the dialog --- webAO/dom/twofactor.ts | 6 +++++- webAO/packets/packets.ts | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/webAO/dom/twofactor.ts b/webAO/dom/twofactor.ts index cb7bccd..38a2bac 100644 --- a/webAO/dom/twofactor.ts +++ b/webAO/dom/twofactor.ts @@ -4,4 +4,8 @@ function handleCredentialResponse(response: any) { console.log(response); client.sender.sendServer(`2T#${response.credential}#%`); } -window.handleCredentialResponse = handleCredentialResponse; \ No newline at end of file +window.handleCredentialResponse = handleCredentialResponse; + +export function showFactorDialog() { + document.getElementById("client_secondfactor").style.display = "block"; +} \ No newline at end of file diff --git a/webAO/packets/packets.ts b/webAO/packets/packets.ts index 79c43c1..c9d0bb8 100644 --- a/webAO/packets/packets.ts +++ b/webAO/packets/packets.ts @@ -2,6 +2,7 @@ import { handleMS } from './handlers/handleMS'; import { handleCT } from './handlers/handleCT' import { handleMC } from './handlers/handleMC' import { handleRMC } from './handlers/handleRMC' +import { showFactorDialog } from '../dom/twofactor' import { handleFL } from './handlers/handleFL' import { handleLE } from './handlers/handleLE' import { handleEM } from './handlers/handleEM' @@ -47,6 +48,7 @@ export const packets = { "CI": handleCI, "SC": handleSC, "EI": handleEI, + "2A": showFactorDialog, "FL": handleFL, "LE": handleLE, "EM": handleEM, -- cgit From fb399fd938b9205c761237917af7d7f3bc52ffff Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 18:44:18 +0200 Subject: this is much nicer --- webAO/dom/twofactor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webAO/dom/twofactor.ts b/webAO/dom/twofactor.ts index 38a2bac..28b6e6c 100644 --- a/webAO/dom/twofactor.ts +++ b/webAO/dom/twofactor.ts @@ -6,6 +6,6 @@ function handleCredentialResponse(response: any) { } window.handleCredentialResponse = handleCredentialResponse; -export function showFactorDialog() { - document.getElementById("client_secondfactor").style.display = "block"; +export function showFactorDialog(display: string) { + document.getElementById("client_secondfactor").style.display = display; } \ No newline at end of file -- cgit From ae3e34625af72eb5df9e9ce6a0c25afc28a5485f Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 19:14:56 +0200 Subject: Update sendServer.ts --- webAO/client/sender/sendServer.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/webAO/client/sender/sendServer.ts b/webAO/client/sender/sendServer.ts index a9da3bd..01052aa 100644 --- a/webAO/client/sender/sendServer.ts +++ b/webAO/client/sender/sendServer.ts @@ -6,5 +6,6 @@ let { mode } = queryParser() * @param {string} message the message to send */ export const sendServer = (message: string) => { + console.log("C: "+message) mode === "replay" ? client.sender.sendSelf(message) : client.serv.send(message); } \ No newline at end of file -- cgit From 9d771dafbff209e0ecc43d190b798662ac10033c Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 19:29:36 +0200 Subject: send version number --- webAO/client.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webAO/client.ts b/webAO/client.ts index 7919402..c9bb08e 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -16,6 +16,7 @@ import { packetHandler } from './packets/packetHandler' import { loadResources } from './client/loadResources' import { AO_HOST } from './client/aoHost' import { fetchBackgroundList, fetchEvidenceList } from './client/fetchLists' +const version = process.env.npm_package_version; let { ip: serverIP, mode, theme } = queryParser(); let THEME: string = theme || "default"; @@ -189,7 +190,7 @@ class Client extends EventEmitter { */ joinServer() { this.sender.sendServer(`HI#${hdid}#%`); - this.sender.sendServer("ID#webAO#webAO#%"); + this.sender.sendServer(`ID#webAO#${version}#%`); if (mode !== "replay") { this.checkUpdater = setInterval(() => this.sender.sendCheck(), 5000); } -- cgit From cc568bbc87d890a43e14728d9328b537afe090b7 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 22 Oct 2022 19:37:28 +0200 Subject: whoops forgot args are a list --- webAO/dom/twofactor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webAO/dom/twofactor.ts b/webAO/dom/twofactor.ts index 28b6e6c..de569b9 100644 --- a/webAO/dom/twofactor.ts +++ b/webAO/dom/twofactor.ts @@ -6,6 +6,6 @@ function handleCredentialResponse(response: any) { } window.handleCredentialResponse = handleCredentialResponse; -export function showFactorDialog(display: string) { - document.getElementById("client_secondfactor").style.display = display; +export function showFactorDialog(args: string[]) { + document.getElementById("client_secondfactor").style.display = args[1]; } \ No newline at end of file -- cgit From 9d7f648642a82d90a7ada4ed94d228af936911c0 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 10 Nov 2022 22:50:35 +0100 Subject: put localhost at the bottom --- public/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 8d0b1c4..1469359 100644 --- a/public/index.html +++ b/public/index.html @@ -95,11 +95,14 @@

webAO requires JavaScript to work

-
    +
    • Singleplayer (beta)

      Try
    • +
    +
      +
      • Localhost

        Watch -- cgit From b686e9fd19e5dbffd1a68fd7ae88bcab3cc05ace Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 11 Nov 2022 11:28:39 +0100 Subject: console spam --- webAO/viewport/viewport.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/webAO/viewport/viewport.ts b/webAO/viewport/viewport.ts index 9ac6e96..de95030 100644 --- a/webAO/viewport/viewport.ts +++ b/webAO/viewport/viewport.ts @@ -232,8 +232,6 @@ const viewport = (): Viewport => { const chat_tick = async () => { // note: this is called fairly often // do not perform heavy operations here - console.log(textnow) - console.log(chatmsg.content) await delay(chatmsg.speed); if (textnow === chatmsg.content) { return; @@ -445,7 +443,6 @@ const viewport = (): Viewport => { ); } } - console.log(animating) if (animating) { chat_tick(); } -- cgit From 5cdcb94d763dec8105fd840ccc15e5c79922e81b Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 11 Nov 2022 11:45:32 +0100 Subject: more console spam --- webAO/client/sender/sendServer.ts | 2 +- webAO/dom/opusCheck.ts | 2 +- webAO/dom/resizeChatbox.ts | 1 - webAO/viewport/utils/handleICSpeaking.ts | 1 - webAO/viewport/utils/setSide.ts | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/webAO/client/sender/sendServer.ts b/webAO/client/sender/sendServer.ts index 01052aa..7678381 100644 --- a/webAO/client/sender/sendServer.ts +++ b/webAO/client/sender/sendServer.ts @@ -6,6 +6,6 @@ let { mode } = queryParser() * @param {string} message the message to send */ export const sendServer = (message: string) => { - console.log("C: "+message) + console.debug("C: "+message) mode === "replay" ? client.sender.sendSelf(message) : client.serv.send(message); } \ No newline at end of file diff --git a/webAO/dom/opusCheck.ts b/webAO/dom/opusCheck.ts index 939fdc6..5f0248d 100644 --- a/webAO/dom/opusCheck.ts +++ b/webAO/dom/opusCheck.ts @@ -9,7 +9,7 @@ export function opusCheck( if (audio === "") { return; } - console.info(`failed to load sound ${channel.src}`); + console.warn(`failed to load sound ${channel.src}`); let oldsrc = ""; let newsrc = ""; oldsrc = channel.src; diff --git a/webAO/dom/resizeChatbox.ts b/webAO/dom/resizeChatbox.ts index efb8bdc..887877d 100644 --- a/webAO/dom/resizeChatbox.ts +++ b/webAO/dom/resizeChatbox.ts @@ -17,7 +17,6 @@ export function resizeChatbox() { let weekday = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; const month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; document.getElementById("client_clock_month")!.innerText = month[now.getMonth()]; - console.debug(CHATBOX); if (CHATBOX == "acww") { weekday = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; document.getElementById("client_clock_weekday")!.innerText = weekday[now.getDay()]; diff --git a/webAO/viewport/utils/handleICSpeaking.ts b/webAO/viewport/utils/handleICSpeaking.ts index c396093..83c216d 100644 --- a/webAO/viewport/utils/handleICSpeaking.ts +++ b/webAO/viewport/utils/handleICSpeaking.ts @@ -154,7 +154,6 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => { client.viewport.getChatmsg().name!.toLowerCase() )}/${encodeURI(client.viewport.getChatmsg().preanim)}` ); - console.debug("preanim is " + gifLength + " long"); client.viewport.getChatmsg().startspeaking = false; } else { client.viewport.getChatmsg().startspeaking = true; diff --git a/webAO/viewport/utils/setSide.ts b/webAO/viewport/utils/setSide.ts index 15cb7c6..3726e83 100644 --- a/webAO/viewport/utils/setSide.ts +++ b/webAO/viewport/utils/setSide.ts @@ -20,7 +20,6 @@ export const set_side = async ({ showDesk: boolean; }) => { const view = document.getElementById("client_fullview")!; - console.log(position) let bench: HTMLImageElement; if (['def','pro','wit'].includes(position)) { bench = ( -- cgit From eb3c603a39d75e5b2ba80af1efbdbee2e3e35888 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 11 Nov 2022 18:49:45 +0100 Subject: client id was missing gcontent --- public/client.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/client.html b/public/client.html index f65ed9e..e5bff14 100644 --- a/public/client.html +++ b/public/client.html @@ -54,7 +54,7 @@

        You need to authorize to continue

        Date: Fri, 11 Nov 2022 19:02:03 +0100 Subject: gsi client id --- public/client.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/client.html b/public/client.html index e5bff14..ea06de6 100644 --- a/public/client.html +++ b/public/client.html @@ -7,7 +7,7 @@ - + -- cgit From 18d3d49355661dffacf4eb7fe2b7dcc1fd9ebfbf Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 11 Nov 2022 19:02:07 +0100 Subject: Revert "client id was missing gcontent" This reverts commit eb3c603a39d75e5b2ba80af1efbdbee2e3e35888. --- public/client.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/client.html b/public/client.html index ea06de6..2059ca8 100644 --- a/public/client.html +++ b/public/client.html @@ -54,7 +54,7 @@

        You need to authorize to continue

        Date: Fri, 11 Nov 2022 19:02:54 +0100 Subject: Revert "Revert "client id was missing gcontent"" This reverts commit 18d3d49355661dffacf4eb7fe2b7dcc1fd9ebfbf. --- public/client.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/client.html b/public/client.html index 2059ca8..ea06de6 100644 --- a/public/client.html +++ b/public/client.html @@ -54,7 +54,7 @@

        You need to authorize to continue

        Date: Sun, 13 Nov 2022 20:13:14 +0100 Subject: bring back iniedit dropdown --- public/client.html | 4 ++-- webAO/dom/twofactor.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/public/client.html b/public/client.html index ea06de6..81400fb 100644 --- a/public/client.html +++ b/public/client.html @@ -54,7 +54,7 @@

        You need to authorize to continue

        Ini editing (experimental)

        - +

        diff --git a/webAO/dom/twofactor.ts b/webAO/dom/twofactor.ts index de569b9..b7e947a 100644 --- a/webAO/dom/twofactor.ts +++ b/webAO/dom/twofactor.ts @@ -1,7 +1,6 @@ import { client } from "../client"; function handleCredentialResponse(response: any) { - console.log(response); client.sender.sendServer(`2T#${response.credential}#%`); } window.handleCredentialResponse = handleCredentialResponse; -- cgit From 942c2040afeec721dc025278478b9cfb76466351 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sun, 13 Nov 2022 20:18:23 +0100 Subject: populate the list --- webAO/client.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webAO/client.ts b/webAO/client.ts index c9bb08e..c7420fb 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -15,7 +15,7 @@ import { onReplayGo } from './dom/onReplayGo' import { packetHandler } from './packets/packetHandler' import { loadResources } from './client/loadResources' import { AO_HOST } from './client/aoHost' -import { fetchBackgroundList, fetchEvidenceList } from './client/fetchLists' +import { fetchBackgroundList, fetchEvidenceList, fetchCharacterList } from './client/fetchLists' const version = process.env.npm_package_version; let { ip: serverIP, mode, theme } = queryParser(); @@ -292,6 +292,7 @@ class Client extends EventEmitter { fetchBackgroundList(); fetchEvidenceList(); + fetchCharacterList(); } } -- cgit From 60576eeec28aa3a42f0c855118e39ce140c01458 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 16:32:23 +0000 Subject: Bump loader-utils from 1.4.0 to 1.4.2 Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.2. - [Release notes](https://github.com/webpack/loader-utils/releases) - [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md) - [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.2) --- updated-dependencies: - dependency-name: loader-utils dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b6b3e0..92b4eac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6884,9 +6884,9 @@ "dev": true }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", -- cgit From 2592bf4cb162cac88ecb52d036249ab52c16153c Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 22:51:18 +0100 Subject: rename to iniselect --- public/client.html | 4 ++-- webAO/dom/iniEdit.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/client.html b/public/client.html index 81400fb..f4298c6 100644 --- a/public/client.html +++ b/public/client.html @@ -521,8 +521,8 @@

        Ini editing (experimental)

        - - + +

        diff --git a/webAO/dom/iniEdit.ts b/webAO/dom/iniEdit.ts index 0710de9..fb05ae2 100644 --- a/webAO/dom/iniEdit.ts +++ b/webAO/dom/iniEdit.ts @@ -6,7 +6,7 @@ import { packetHandler } from "../packets/packetHandler"; * Triggered by the ini button. */ export async function iniedit() { - const ininame = (document.getElementById("client_ininame")) + const ininame = (document.getElementById("client_iniselect")) .value; const inicharID = client.charID; await handleCharacterInfo(ininame.split("&"), inicharID); -- cgit From fbb4ce9fafab3183e27204eccad73c542cb684c8 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 22:51:24 +0100 Subject: custom is entry 0 --- webAO/client/fetchLists.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/webAO/client/fetchLists.ts b/webAO/client/fetchLists.ts index e9772cb..7f0104e 100644 --- a/webAO/client/fetchLists.ts +++ b/webAO/client/fetchLists.ts @@ -26,7 +26,7 @@ export const fetchCharacterList = async () => { // the try catch will fail before here when there is no file const char_select = ( - document.getElementById("client_ininame") + document.getElementById("client_iniselect") ); char_select.innerHTML = ""; @@ -50,10 +50,12 @@ export const fetchEvidenceList = async () => { ); evi_select.innerHTML = ""; + evi_select.add(new Option("Custom", "0")); + evi_array.forEach((evi: string) => { evi_select.add(new Option(evi)); }); - evi_select.add(new Option("Custom", "0")); + } catch (err) { console.warn("there was no evidence.json file"); } -- cgit From fa9ca955b10bb272cdc0a1f803efbdd768111c60 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 22:51:58 +0100 Subject: add custom ini --- webAO/client/fetchLists.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webAO/client/fetchLists.ts b/webAO/client/fetchLists.ts index 7f0104e..bf4fd1b 100644 --- a/webAO/client/fetchLists.ts +++ b/webAO/client/fetchLists.ts @@ -30,6 +30,8 @@ export const fetchCharacterList = async () => { ); char_select.innerHTML = ""; + char_select.add(new Option("Custom", "0")); + char_array.forEach((character: string) => { char_select.add(new Option(character)); }); -- cgit From 60dacea009356d2bcd36bd0dd8c95124f7a3c218 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 22:52:59 +0100 Subject: add custom ininame --- public/client.html | 1 + 1 file changed, 1 insertion(+) diff --git a/public/client.html b/public/client.html index f4298c6..c1fa5bd 100644 --- a/public/client.html +++ b/public/client.html @@ -523,6 +523,7 @@

        Ini editing (experimental)

        +

        -- cgit From 7d3a6dc03bb284e3bb711a4a0fa698d197e585ea Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 22:55:36 +0100 Subject: both ini dropdown and custom --- public/client.html | 2 +- webAO/dom/updateIniswap.ts | 18 ++++++++++++++++++ webAO/dom/window.ts | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 webAO/dom/updateIniswap.ts diff --git a/public/client.html b/public/client.html index c1fa5bd..9f9510a 100644 --- a/public/client.html +++ b/public/client.html @@ -522,7 +522,7 @@

        Ini editing (experimental)

        - +
        diff --git a/webAO/dom/updateIniswap.ts b/webAO/dom/updateIniswap.ts new file mode 100644 index 0000000..e040e64 --- /dev/null +++ b/webAO/dom/updateIniswap.ts @@ -0,0 +1,18 @@ +/** + * Update iniswap drowdown + */ +export function updateIniswap() { + const ini_select = ( + document.getElementById("evi_select") + ); + const ini_name = ( + document.getElementById("evi_filename") + ); + + if (ini_select.selectedIndex === 0) { + ini_filename.style.display = "initial"; + } else { + ini_filename.style.display = "none"; + } +} +window.updateIniswap = updateIniswap; diff --git a/webAO/dom/window.ts b/webAO/dom/window.ts index 956526c..0b3bd34 100644 --- a/webAO/dom/window.ts +++ b/webAO/dom/window.ts @@ -17,6 +17,7 @@ declare global { changeBackgroundOOC: () => void; updateActionCommands: (side: string) => void; updateEvidenceIcon: () => void; + updateIniswap: () => void; resizeChatbox: () => void; setChatbox: (style: string) => void; getIndexFromSelect: (select_box: string, value: string) => Number; -- cgit From 1ca093371aa446a79b76cd54e2ce822c2c39cdfd Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 23:10:23 +0100 Subject: copypasta :spaghetti: --- webAO/dom/updateIniswap.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webAO/dom/updateIniswap.ts b/webAO/dom/updateIniswap.ts index e040e64..251e1f1 100644 --- a/webAO/dom/updateIniswap.ts +++ b/webAO/dom/updateIniswap.ts @@ -10,9 +10,9 @@ export function updateIniswap() { ); if (ini_select.selectedIndex === 0) { - ini_filename.style.display = "initial"; + ini_name.style.display = "initial"; } else { - ini_filename.style.display = "none"; + ini_name.style.display = "none"; } } window.updateIniswap = updateIniswap; -- cgit From 2b78887579ba24355936ae75f912c55343bf0d0b Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 23:17:07 +0100 Subject: :spaghetti: :spaghetti: :spaghetti: :spaghetti: :spaghetti: :spaghetti: :spaghetti: --- webAO/dom/updateIniswap.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webAO/dom/updateIniswap.ts b/webAO/dom/updateIniswap.ts index 251e1f1..5bea0f5 100644 --- a/webAO/dom/updateIniswap.ts +++ b/webAO/dom/updateIniswap.ts @@ -3,10 +3,10 @@ */ export function updateIniswap() { const ini_select = ( - document.getElementById("evi_select") + document.getElementById("client_iniselect") ); const ini_name = ( - document.getElementById("evi_filename") + document.getElementById("client_ininame") ); if (ini_select.selectedIndex === 0) { -- cgit From 14dd6bf87f05a411b4eadcb4f6f37f726341a800 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 23:29:17 +0100 Subject: still have custom if request fails --- webAO/client/fetchLists.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/webAO/client/fetchLists.ts b/webAO/client/fetchLists.ts index bf4fd1b..704c889 100644 --- a/webAO/client/fetchLists.ts +++ b/webAO/client/fetchLists.ts @@ -21,10 +21,6 @@ export const fetchBackgroundList = async () => { export const fetchCharacterList = async () => { try { - const chardata = await request(`${AO_HOST}characters.json`); - const char_array = JSON.parse(chardata); - // the try catch will fail before here when there is no file - const char_select = ( document.getElementById("client_iniselect") ); @@ -32,6 +28,10 @@ export const fetchCharacterList = async () => { char_select.add(new Option("Custom", "0")); + const chardata = await request(`${AO_HOST}characters.json`); + const char_array = JSON.parse(chardata); + // the try catch will fail before here when there is no file + char_array.forEach((character: string) => { char_select.add(new Option(character)); }); @@ -43,10 +43,6 @@ export const fetchCharacterList = async () => { export const fetchEvidenceList = async () => { try { - const evidata = await request(`${AO_HOST}evidence.json`); - const evi_array = JSON.parse(evidata); - // the try catch will fail before here when there is no file - const evi_select = ( document.getElementById("evi_select") ); @@ -54,6 +50,10 @@ export const fetchEvidenceList = async () => { evi_select.add(new Option("Custom", "0")); + const evidata = await request(`${AO_HOST}evidence.json`); + const evi_array = JSON.parse(evidata); + // the try catch will fail before here when there is no file + evi_array.forEach((evi: string) => { evi_select.add(new Option(evi)); }); -- cgit From 0dfae205629db81833ab6281c87fc23fc7e2c33e Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Thu, 17 Nov 2022 23:30:02 +0100 Subject: not even gonna try, just do it --- webAO/client/fetchLists.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/webAO/client/fetchLists.ts b/webAO/client/fetchLists.ts index 704c889..38c3236 100644 --- a/webAO/client/fetchLists.ts +++ b/webAO/client/fetchLists.ts @@ -20,14 +20,14 @@ export const fetchBackgroundList = async () => { } export const fetchCharacterList = async () => { - try { - const char_select = ( - document.getElementById("client_iniselect") - ); - char_select.innerHTML = ""; - - char_select.add(new Option("Custom", "0")); + const char_select = ( + document.getElementById("client_iniselect") + ); + char_select.innerHTML = ""; + char_select.add(new Option("Custom", "0")); + + try { const chardata = await request(`${AO_HOST}characters.json`); const char_array = JSON.parse(chardata); // the try catch will fail before here when there is no file @@ -42,14 +42,14 @@ export const fetchCharacterList = async () => { export const fetchEvidenceList = async () => { - try { - const evi_select = ( - document.getElementById("evi_select") - ); - evi_select.innerHTML = ""; + const evi_select = ( + document.getElementById("evi_select") + ); + evi_select.innerHTML = ""; - evi_select.add(new Option("Custom", "0")); + evi_select.add(new Option("Custom", "0")); + try { const evidata = await request(`${AO_HOST}evidence.json`); const evi_array = JSON.parse(evidata); // the try catch will fail before here when there is no file -- cgit From fdf5fc329a48d9f6ed54d055f7b0e60cb65e35f3 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 18 Nov 2022 19:55:31 +0100 Subject: fix iniedit input box --- webAO/dom/iniEdit.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/webAO/dom/iniEdit.ts b/webAO/dom/iniEdit.ts index fb05ae2..9d31259 100644 --- a/webAO/dom/iniEdit.ts +++ b/webAO/dom/iniEdit.ts @@ -6,10 +6,15 @@ import { packetHandler } from "../packets/packetHandler"; * Triggered by the ini button. */ export async function iniedit() { - const ininame = (document.getElementById("client_iniselect")) - .value; + const iniselect = (document.getElementById("client_iniselect")) + const ininame = (document.getElementById("client_ininame")); const inicharID = client.charID; - await handleCharacterInfo(ininame.split("&"), inicharID); + + const newname = iniselect.selectedIndex === 0 ? ininame.value : iniselect.value; + + await handleCharacterInfo(newname.split("&"), inicharID); packetHandler.get("PV")!(`PV#0#CID#${inicharID}`.split("#")); + + ); } window.iniedit = iniedit; -- cgit From f53a8293cf0d6f162008953ac6504a84959ee152 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Tue, 22 Nov 2022 19:59:58 +0100 Subject: where did this bracket come from --- webAO/dom/iniEdit.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/webAO/dom/iniEdit.ts b/webAO/dom/iniEdit.ts index 9d31259..b26c179 100644 --- a/webAO/dom/iniEdit.ts +++ b/webAO/dom/iniEdit.ts @@ -14,7 +14,5 @@ export async function iniedit() { await handleCharacterInfo(newname.split("&"), inicharID); packetHandler.get("PV")!(`PV#0#CID#${inicharID}`.split("#")); - - ); } window.iniedit = iniedit; -- cgit From 20b19c474c9e6e80ddd23caad109feebd8a60410 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 7 Dec 2022 20:46:45 +0100 Subject: remove chat from chatbox names --- public/client.html | 12 ++-- webAO/styles/chatbox/999.css | 128 +++++++++++++++++++++++++++++++++ webAO/styles/chatbox/chat999.css | 128 --------------------------------- webAO/styles/chatbox/chatboxes.js | 12 ++-- webAO/styles/chatbox/chatdd.css | 111 ----------------------------- webAO/styles/chatbox/chatdr2.css | 127 --------------------------------- webAO/styles/chatbox/chatfuture.css | 137 ------------------------------------ webAO/styles/chatbox/chatp3.css | 117 ------------------------------ webAO/styles/chatbox/chatplvsaa.css | 113 ----------------------------- webAO/styles/chatbox/dd.css | 111 +++++++++++++++++++++++++++++ webAO/styles/chatbox/dr2.css | 127 +++++++++++++++++++++++++++++++++ webAO/styles/chatbox/future.css | 137 ++++++++++++++++++++++++++++++++++++ webAO/styles/chatbox/p3.css | 117 ++++++++++++++++++++++++++++++ webAO/styles/chatbox/plvsaa.css | 113 +++++++++++++++++++++++++++++ 14 files changed, 745 insertions(+), 745 deletions(-) create mode 100644 webAO/styles/chatbox/999.css delete mode 100644 webAO/styles/chatbox/chat999.css delete mode 100644 webAO/styles/chatbox/chatdd.css delete mode 100644 webAO/styles/chatbox/chatdr2.css delete mode 100644 webAO/styles/chatbox/chatfuture.css delete mode 100644 webAO/styles/chatbox/chatp3.css delete mode 100644 webAO/styles/chatbox/chatplvsaa.css create mode 100644 webAO/styles/chatbox/dd.css create mode 100644 webAO/styles/chatbox/dr2.css create mode 100644 webAO/styles/chatbox/future.css create mode 100644 webAO/styles/chatbox/p3.css create mode 100644 webAO/styles/chatbox/plvsaa.css diff --git a/public/client.html b/public/client.html index 9f9510a..3f45793 100644 --- a/public/client.html +++ b/public/client.html @@ -488,16 +488,16 @@
        - +

        -- cgit From b81480a194a144fc0894b1457018d89ecc406673 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 23 Jan 2023 14:36:49 +0100 Subject: replaceall was missing --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 1a2dd33..7f8928e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "outDir": "./dist", "allowJs": true, "target": "es5", - "lib": ["DOM","DOM.Iterable"], + "lib": ["DOM","DOM.Iterable","ES2021.String"], "strict": true, "strictNullChecks": false, //document.getElementBy "downlevelIteration": true -- cgit From 3600fe4e479c8da1bd8f7f6d648cb352b506228b Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 23 Jan 2023 14:39:08 +0100 Subject: handle blankposts that are only spaces --- webAO/viewport/utils/handleICSpeaking.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webAO/viewport/utils/handleICSpeaking.ts b/webAO/viewport/utils/handleICSpeaking.ts index 83c216d..e2d147d 100644 --- a/webAO/viewport/utils/handleICSpeaking.ts +++ b/webAO/viewport/utils/handleICSpeaking.ts @@ -157,7 +157,7 @@ export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => { client.viewport.getChatmsg().startspeaking = false; } else { client.viewport.getChatmsg().startspeaking = true; - if (client.viewport.getChatmsg().content !== "") chatContainerBox.style.opacity = "1"; + if (client.viewport.getChatmsg().content.trim() !== "") chatContainerBox.style.opacity = "1"; } client.viewport.getChatmsg().preanimdelay = gifLength; const setAside = { -- cgit From 95c688f3683ba6c1cabf39beeaf972e5bd80b6c4 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 23 Jan 2023 22:27:28 +0100 Subject: bring mute back --- webAO/dom/muteListClick.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 webAO/dom/muteListClick.ts diff --git a/webAO/dom/muteListClick.ts b/webAO/dom/muteListClick.ts new file mode 100644 index 0000000..e7c9357 --- /dev/null +++ b/webAO/dom/muteListClick.ts @@ -0,0 +1,19 @@ +import { client } from "../client"; +/** + * Triggered when a character in the mute list is clicked + * @param {MouseEvent} event + */ +export function mutelist_click(_event: Event) { + const mutelist = (document.getElementById('mute_select')); + const selected_character = mutelist.options[mutelist.selectedIndex]; + + if (client.chars[selected_character.value].muted === false) { + client.chars[selected_character.value].muted = true; + selected_character.text = `${client.chars[selected_character.value].name} (muted)`; + console.info(`muted ${client.chars[selected_character.value].name}`); + } else { + client.chars[selected_character.value].muted = false; + selected_character.text = client.chars[selected_character.value].name; + } +} +window.mutelist_click = mutelist_click; \ No newline at end of file -- cgit From 4f5275821ec75f493cec9a4332c5312b3521f8c6 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 23 Jan 2023 22:27:41 +0100 Subject: detect blankpost --- webAO/packets/handlers/handleMS.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webAO/packets/handlers/handleMS.ts b/webAO/packets/handlers/handleMS.ts index de681a4..c30e777 100644 --- a/webAO/packets/handlers/handleMS.ts +++ b/webAO/packets/handlers/handleMS.ts @@ -154,6 +154,11 @@ export const handleMS = (args: string[]) => { chatmsg = Object.assign(extra_28, chatmsg); } + if (chatmsg.content.trim() === "") { + //blankpost + chatmsg.content = ""; + } + // our own message appeared, reset the buttons if (chatmsg.charid === client.charID) { resetICParams(); -- cgit From a7e7fac4905bf742c631839251181b8fd4c81fa8 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 30 Jan 2023 19:34:44 +0100 Subject: the best color --- webAO/viewport/constants/colors.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/webAO/viewport/constants/colors.ts b/webAO/viewport/constants/colors.ts index aad3530..4858081 100644 --- a/webAO/viewport/constants/colors.ts +++ b/webAO/viewport/constants/colors.ts @@ -8,4 +8,5 @@ export const COLORS = [ "pink", "cyan", "grey", + "rainbow", ]; \ No newline at end of file -- cgit From 74d4eda18f2d5a98abaaf978dad6afa39864d8f7 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 30 Jan 2023 19:37:13 +0100 Subject: client users be like: --- webAO/packets/handlers/handleFL.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webAO/packets/handlers/handleFL.ts b/webAO/packets/handlers/handleFL.ts index 89df4ed..22dfff5 100644 --- a/webAO/packets/handlers/handleFL.ts +++ b/webAO/packets/handlers/handleFL.ts @@ -18,7 +18,8 @@ export const handleFL = (args: string[]) => { colorselect.options[colorselect.options.length] = new Option("Yellow","5"); colorselect.options[colorselect.options.length] = new Option("Pink", "6"); colorselect.options[colorselect.options.length] = new Option("Cyan", "7"); - colorselect.options[colorselect.options.length] = new Option("Grey", "8"); + colorselect.options[colorselect.options.length] = new Option("Grey", "8"); + colorselect.options[colorselect.options.length] = new Option("Rainbow", "9"); } if (args.includes("cccc_ic_support")) { -- cgit From 56fa48be906354c340a928bd6f44c5eed849ca02 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 30 Jan 2023 19:44:20 +0100 Subject: Revert "client users be like:" This reverts commit 74d4eda18f2d5a98abaaf978dad6afa39864d8f7. --- webAO/packets/handlers/handleFL.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webAO/packets/handlers/handleFL.ts b/webAO/packets/handlers/handleFL.ts index 22dfff5..89df4ed 100644 --- a/webAO/packets/handlers/handleFL.ts +++ b/webAO/packets/handlers/handleFL.ts @@ -18,8 +18,7 @@ export const handleFL = (args: string[]) => { colorselect.options[colorselect.options.length] = new Option("Yellow","5"); colorselect.options[colorselect.options.length] = new Option("Pink", "6"); colorselect.options[colorselect.options.length] = new Option("Cyan", "7"); - colorselect.options[colorselect.options.length] = new Option("Grey", "8"); - colorselect.options[colorselect.options.length] = new Option("Rainbow", "9"); + colorselect.options[colorselect.options.length] = new Option("Grey", "8"); } if (args.includes("cccc_ic_support")) { -- cgit From 777162e9205a115e823db18a9d81a5a342cc8882 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Mon, 30 Jan 2023 19:47:54 +0100 Subject: fix color --- webAO/styles/client.css | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/webAO/styles/client.css b/webAO/styles/client.css index 31bc64b..ced8339 100644 --- a/webAO/styles/client.css +++ b/webAO/styles/client.css @@ -21,15 +21,12 @@ .text_rainbow { background-color: #fff; - background-image: repeating-linear-gradient(to right, - red 0% 8%, orange 8% 16%, yellow 16% 24%, green 24% 32%, blue 32% 40%, - red 40% 48%, orange 48% 56%, yellow 56% 64%, green 64% 72%, blue 72% 80%, - red 80% 88%, orange 88% 96%, yellow 96% 100%); - background-size: 40% 40%; + background-image: repeating-linear-gradient(to right, red 0% 20%, orange 20% 40%, yellow 40% 60%, green 60% 80%, blue 80% 100%); + background-size: 75% 75%; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; - animation: rainbow 4s linear infinite; + animation: rainbow 2s linear infinite; } @keyframes rainbow_alt { -- cgit From bc74ddd629d179a8c54e4e278ed1fa0eb34cac99 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 1 Feb 2023 13:51:17 +0100 Subject: stop loading 25mb on every join --- webAO/client.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webAO/client.ts b/webAO/client.ts index 6df8748..a86664c 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -295,9 +295,8 @@ class Client extends EventEmitter { fetchBackgroundList(); fetchEvidenceList(); fetchCharacterList(); - fetchManifest(); } } -export default Client; \ No newline at end of file +export default Client; -- cgit