diff options
30 files changed, 643 insertions, 615 deletions
diff --git a/webAO/client.ts b/webAO/client.ts index e92489c..8b2f691 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -3,36 +3,18 @@ * 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 { 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 { escapeChat, 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"; @@ -77,38 +59,25 @@ 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) => { 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(); }); 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[]; @@ -134,6 +103,8 @@ class Client extends EventEmitter { _lastTimeICReceived: any; viewport: Viewport; connect: () => void; + loadResources: () => void + isLowMemory: () => void constructor(address: string) { super(); @@ -175,6 +146,8 @@ class Client extends EventEmitter { this.sender = sender this.viewport = masterViewport(this); this._lastTimeICReceived = new Date(0); + loadResources + isLowMemory } /** @@ -200,8 +173,6 @@ class Client extends EventEmitter { : 0; } - - /** * Hook for sending messages to the client * @param {string} message the message to send @@ -216,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") { @@ -225,78 +195,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 = <HTMLSelectElement>( - 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 = <HTMLSelectElement>( - 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 - (<HTMLInputElement>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"; - - (<HTMLOptionElement>( - document.querySelector(`#client_themeselect [value="${cookietheme}"]`) - )).selected = true; - this.viewport.reloadTheme(); - - const cookiechatbox = getCookie("chatbox") || "dynamic"; - - (<HTMLOptionElement>( - document.querySelector(`#client_chatboxselect [value="${cookiechatbox}"]`) - )).selected = true; - setChatbox(cookiechatbox); - - (<HTMLInputElement>document.getElementById("client_mvolume")).value = - getCookie("musicVolume") || "1"; - this.viewport.changeMusicVolume(); - (<HTMLAudioElement>document.getElementById("client_sfxaudio")).volume = - Number(getCookie("sfxVolume")) || 1; - changeSFXVolume(); - (<HTMLAudioElement>document.getElementById("client_shoutaudio")).volume = - Number(getCookie("shoutVolume")) || 1; - changeShoutVolume(); - (<HTMLAudioElement>( - document.getElementById("client_testimonyaudio") - )).volume = Number(getCookie("testimonyVolume")) || 1; - changeTestimonyVolume(); - (<HTMLInputElement>document.getElementById("client_bvolume")).value = - getCookie("blipVolume") || "1"; - this.viewport.changeBlipVolume(); - - (<HTMLInputElement>document.getElementById("ic_chat_name")).value = - getCookie("ic_chat_name"); - (<HTMLInputElement>document.getElementById("showname")).checked = Boolean( - getCookie("showname") - ); - showname_click(null); - - (<HTMLInputElement>document.getElementById("client_callwords")).value = - getCookie("callwords"); - } - - /** * Triggered when a connection is established to the server. */ onOpen(_e: Event) { @@ -335,7 +233,6 @@ class Client extends EventEmitter { packetHandler.has(packetHeader) ? packetHandler.get(packetHeader)(splitPacket) : console.warn(`Invalid packet header ${packetHeader}`); - } /** @@ -353,7 +250,6 @@ class Client extends EventEmitter { */ cleanup() { clearInterval(this.checkUpdater); - this.serv.close(); } @@ -383,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 - (<HTMLInputElement>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 = <HTMLImageElement>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 = <HTMLSelectElement>( - document.getElementById("mute_select") - ); - mute_select.add(new Option(safeTags(chargs[0]), String(charid))); - const pair_select = <HTMLSelectElement>( - 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 = ""; @@ -515,231 +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 = <HTMLSelectElement>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 = <HTMLSelectElement>( - 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 = <HTMLSelectElement>( - 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 - ); + fetchBackgroundList(); + fetchEvidenceList(); } - addTrack(trackname: string) { - const newentry = <HTMLOptionElement>document.createElement("OPTION"); - const songName = getFilenameFromPath(trackname); - newentry.text = unescapeChat(songName); - newentry.value = trackname; - (<HTMLSelectElement>( - document.getElementById("client_musiclist") - )).options.add(newentry); - this.musics.push(trackname); - } - - 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}:<br>${reason.replace(/\n/g, "<br />")}`; - (<HTMLElement>( - document.getElementsByClassName("client_reconnect")[0] - )).style.display = "none"; - (<HTMLElement>( - document.getElementsByClassName("client_reconnect")[1] - )).style.display = "none"; - } -} - -/** - * 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() { - (<HTMLInputElement>document.getElementById("client_inputbox")).value = ""; - document.getElementById("button_flash").className = "client_button"; - document.getElementById("button_shake").className = "client_button"; - - (<HTMLInputElement>document.getElementById("sendpreanim")).checked = false; - (<HTMLInputElement>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/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 = <HTMLOptionElement>document.createElement("OPTION"); + const songName = getFilenameFromPath(trackname); + newentry.text = unescapeChat(songName); + newentry.value = trackname; + (<HTMLSelectElement>( + document.getElementById("client_musiclist") + )).options.add(newentry); + client.musics.push(trackname); +}
\ 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/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 = <HTMLSelectElement>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 = <HTMLSelectElement>( + 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 = <HTMLSelectElement>( + 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..f1aa99f --- /dev/null +++ b/webAO/client/fixLastArea.ts @@ -0,0 +1,15 @@ +import { client } from "../client"; +import { addTrack } from "./addTrack"; + + +/** + * 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); + 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}:<br>${reason.replace(/\n/g, "<br />")}`; + (<HTMLElement>( + document.getElementsByClassName("client_reconnect")[0] + )).style.display = "none"; + (<HTMLElement>( + 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 = <HTMLImageElement>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 = <HTMLSelectElement>( + document.getElementById("mute_select") + ); + mute_select.add(new Option(safeTags(chargs[0]), String(charid))); + const pair_select = <HTMLSelectElement>( + 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/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/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 = <HTMLSelectElement>( + 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 = <HTMLSelectElement>( + 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 + (<HTMLInputElement>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"; + + (<HTMLOptionElement>( + document.querySelector(`#client_themeselect [value="${cookietheme}"]`) + )).selected = true; + client.viewport.reloadTheme(); + + const cookiechatbox = getCookie("chatbox") || "dynamic"; + + (<HTMLOptionElement>( + document.querySelector(`#client_chatboxselect [value="${cookiechatbox}"]`) + )).selected = true; + setChatbox(cookiechatbox); + + (<HTMLInputElement>document.getElementById("client_mvolume")).value = + getCookie("musicVolume") || "1"; + client.viewport.changeMusicVolume(); + (<HTMLAudioElement>document.getElementById("client_sfxaudio")).volume = + Number(getCookie("sfxVolume")) || 1; + changeSFXVolume(); + (<HTMLAudioElement>document.getElementById("client_shoutaudio")).volume = + Number(getCookie("shoutVolume")) || 1; + changeShoutVolume(); + (<HTMLAudioElement>( + document.getElementById("client_testimonyaudio") + )).volume = Number(getCookie("testimonyVolume")) || 1; + changeTestimonyVolume(); + (<HTMLInputElement>document.getElementById("client_bvolume")).value = + getCookie("blipVolume") || "1"; + client.viewport.changeBlipVolume(); + + (<HTMLInputElement>document.getElementById("ic_chat_name")).value = + getCookie("ic_chat_name"); + (<HTMLInputElement>document.getElementById("showname")).checked = Boolean( + getCookie("showname") + ); + showname_click(null); + + (<HTMLInputElement>document.getElementById("client_callwords")).value = + getCookie("callwords"); +}
\ No newline at end of file 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() { + (<HTMLInputElement>document.getElementById("client_inputbox")).value = ""; + document.getElementById("button_flash")!.className = "client_button"; + document.getElementById("button_shake")!.className = "client_button"; + + (<HTMLInputElement>document.getElementById("sendpreanim")).checked = false; + (<HTMLInputElement>document.getElementById("sendsfx")).checked = false; + + if (selectedShout) { + document.getElementById(`button_${selectedShout}`)!.className = + "client_button"; + setSelectedShout(0); + } +}
\ 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 + (<HTMLInputElement>document.getElementById("client_inputbox")).value = ""; +};
\ 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 = (<HTMLInputElement>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/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((<HTMLInputElement>document.getElementById("showname")).checked) 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[]) => { (<HTMLProgressElement>( 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("<and>"), // HACK: here as well, client is fucked and uses this instead of & + other_offset: args[21].split("<and>"), + 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("<and>"), // HACK: here as well, client is fucked and uses this instead of & - other_offset: args[21].split("<and>"), - 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 = (<HTMLInputElement>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")) { (<HTMLLinkElement>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) |
