diff options
Diffstat (limited to 'webAO/client.js')
| -rw-r--r-- | webAO/client.js | 271 |
1 files changed, 190 insertions, 81 deletions
diff --git a/webAO/client.js b/webAO/client.js index 6ad2193..a45e2b6 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -35,7 +35,7 @@ const serverIP = queryDict.ip; let mode = queryDict.mode; // Unless there is an asset URL specified, use the wasabi one -const DEFAULT_HOST = location.hostname ? "https://cloudflare-ipfs.com/ipfs/QmeWK7nB1xjS3zQRwqwGYrKcbiNUKYiWHYCryXzrJF336c/" : "base/"; +const DEFAULT_HOST = location.hostname ? "https://bafybeicndnzjokdlnf4ooigvkav7clnvkll3pbigifw5td6inhbrindue4.ipfs.dweb.link/" : "base/"; const AO_HOST = queryDict.asset || DEFAULT_HOST; const THEME = queryDict.theme || "default"; const MUSIC_HOST = AO_HOST + "sounds/music/"; @@ -143,25 +143,29 @@ class Client extends EventEmitter { "src": AO_HOST + "misc/default/takethat_bubble.png", "duration": 840 }, + "custom": { + "src": "", + "duration": 840 + }, "witnesstestimony": { "src": AO_HOST + "themes/" + THEME + "/witnesstestimony.gif", "duration": 1560, - "sfx": AO_HOST + "sounds/general/sfx-testimony.wav" + "sfx": AO_HOST + "sounds/general/sfx-testimony.opus" }, "crossexamination": { "src": AO_HOST + "themes/" + THEME + "/crossexamination.gif", "duration": 1600, - "sfx": AO_HOST + "sounds/general/sfx-testimony2.wav" + "sfx": AO_HOST + "sounds/general/sfx-testimony2.opus" }, "guilty": { "src": AO_HOST + "themes/" + THEME + "/guilty.gif", "duration": 2870, - "sfx": AO_HOST + "sounds/general/sfx-guilty.wav" + "sfx": AO_HOST + "sounds/general/sfx-guilty.opus" }, "notguilty": { "src": AO_HOST + "themes/" + THEME + "/notguilty.gif", "duration": 2440, - "sfx": AO_HOST + "sounds/general/sfx-notguilty.wav" + "sfx": AO_HOST + "sounds/general/sfx-notguilty.opus" }, }; @@ -184,6 +188,8 @@ class Client extends EventEmitter { this.on("FL", this.handleFL.bind(this)); this.on("LE", this.handleLE.bind(this)); this.on("EM", this.handleEM.bind(this)); + 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("BD", this.handleBD.bind(this)); @@ -444,7 +450,7 @@ class Client extends EventEmitter { document.querySelector('#client_chatboxselect [value="' + cookiechatbox + '"]').selected = true; setChatbox(cookiechatbox); - document.getElementById("client_musicaudio").volume = getCookie("musicVolume") || 1; + document.getElementById("client_mvolume").value = getCookie("musicVolume") || 1; changeMusicVolume(); document.getElementById("client_sfxaudio").volume = getCookie("sfxVolume") || 1; changeSFXVolume(); @@ -457,6 +463,7 @@ class Client extends EventEmitter { document.getElementById("ic_chat_name").value = getCookie("ic_chat_name"); document.getElementById("showname").checked = getCookie("showname"); + showname_click(); document.getElementById("client_callwords").value = getCookie("callwords"); } @@ -734,8 +741,11 @@ class Client extends EventEmitter { handleMC(args) { const track = prepChat(args[1]); let charID = Number(args[2]); + const showname = args[3] || ""; + const looping = Boolean(args[4]); + const channel = Number(args[5]) || 0; - const music = viewport.music; + const music = viewport.music[channel]; let musicname; music.pause(); if(track.startsWith("http")) { @@ -743,6 +753,7 @@ class Client extends EventEmitter { } else { music.src = MUSIC_HOST + encodeURI(track.toLowerCase()); } + music.loop = looping; music.play(); try { @@ -785,6 +796,7 @@ class Client extends EventEmitter { async handleCharacterInfo(chargs, charid) { if (chargs[0]) { let cini = {}; + let cswap = {}; let icon = AO_HOST + "characters/" + encodeURI(chargs[0].toLowerCase()) + "/char_icon.png"; let img = document.getElementById(`demo_${charid}`); img.alt = chargs[0]; @@ -801,12 +813,18 @@ class Client extends EventEmitter { // If it does, give the user a visual indication that the character is unusable } + // Load iniswaps if there are any + try { + const cswapdata = await request(AO_HOST + "characters/" + encodeURI(chargs[0].toLowerCase()) + "/iniswaps.ini"); + cswap = cswapdata.split("\n"); + } catch (err) { + cswap = {}; + } + const mute_select = document.getElementById("mute_select"); mute_select.add(new Option(safe_tags(chargs[0]), charid)); const pair_select = document.getElementById("pair_select"); pair_select.add(new Option(safe_tags(chargs[0]), charid)); - const iniedit_select = document.getElementById("client_ininame"); - iniedit_select.add(new Option(safe_tags(chargs[0]))); // sometimes ini files lack important settings const default_options = { @@ -834,8 +852,10 @@ class Client extends EventEmitter { evidence: chargs[3], icon: icon, inifile: cini, + swaps: cswap, muted: false }; + } else { console.warn("missing charid " + charid); let img = document.getElementById(`demo_${charid}`); @@ -924,14 +944,17 @@ class Client extends EventEmitter { } resetMusiclist() { - this.musics = []; + this.musics = []; + document.getElementById("client_musiclist").innerHTML = ""; + } + + resetArealist() { this.areas = []; - document.getElementById("client_musiclist").innerHTML = ""; - document.getElementById("areas").innerHTML = ""; + document.getElementById("areas").innerHTML = ""; } isAudio(trackname) { - if (/\.(?:wav|mp3|mp4|ogg|opus)$/i.test(trackname) || // regex for file extenstions + if (trackname.includes(".") || // regex for file extenstions trackname.startsWith("=") || trackname.startsWith("-")) // category markers { @@ -941,38 +964,46 @@ class Client extends EventEmitter { } } + addTrack(trackname) { + const newentry = document.createElement("OPTION"); + newentry.text = trackname; + document.getElementById("client_musiclist").options.add(newentry); + this.musics.push(trackname); + } + handleMusicInfo(trackindex,trackname) { if (this.isAudio(trackname)) { - // After reached the audio put everything in the music list - const newentry = document.createElement("OPTION"); - newentry.text = trackname; - document.getElementById("client_musiclist").options.add(newentry); - this.musics.push(trackname); + this.addTrack(trackname); } else { - const thisarea = { - name: trackname, - players: 0, - status: "IDLE", - cm: "", - locked: "FREE" - }; + this.createArea(trackindex,trackname); + } + } - this.areas.push(thisarea); - - // Create area button - let newarea = document.createElement("SPAN"); - newarea.classList = "area-button area-default"; - newarea.id = "area" + trackindex; - newarea.innerText = thisarea.name; - newarea.title = "Players: <br>" + - "Status: <br>" + - "CM: "; - newarea.onclick = function () { - area_click(this); - }; + createArea(id,name) { + const thisarea = { + name: name, + players: 0, + status: "IDLE", + cm: "", + locked: "FREE" + }; - document.getElementById("areas").appendChild(newarea); - } + this.areas.push(thisarea); + + // Create area button + let newarea = document.createElement("SPAN"); + newarea.classList = "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(this); + }; + + document.getElementById("areas").appendChild(newarea); } /** @@ -984,6 +1015,7 @@ class Client extends EventEmitter { document.getElementById("client_loadingtext").innerHTML = "Loading Music"; if(args[1] === "0") { this.resetMusiclist(); + this.resetArealist(); } for (let i = 2; i < args.length - 1; i++) { @@ -1004,6 +1036,7 @@ class Client extends EventEmitter { handleSM(args) { document.getElementById("client_loadingtext").innerHTML = "Loading Music "; this.resetMusiclist(); + this.resetArealist(); for (let i = 1; i < args.length - 1; i++) { // Check when found the song for the first time @@ -1016,6 +1049,31 @@ class Client extends EventEmitter { } /** + * Handles updated music list + * @param {Array} args packet arguments + */ + handleFM(args) { + this.resetMusiclist(); + + for (let i = 1; i < args.length - 1; i++) { + // Check when found the song for the first time + this.addTrack(safe_tags(args[i])); + } + } + + /** + * Handles updated area list + * @param {Array} args packet arguments + */ + handleFA(args) { + this.resetArealist(); + + for (let i = 1; i < args.length - 1; i++) { + this.createArea(i-1,safe_tags(args[i])); + } + } + + /** * Handles the "MusicMode" packet * @param {Array} args packet arguments */ @@ -1152,7 +1210,7 @@ class Client extends EventEmitter { viewport.sfxaudio.pause(); const oldvolume = viewport.sfxaudio.volume; viewport.sfxaudio.volume = 1; - viewport.sfxaudio.src = AO_HOST + "sounds/general/sfx-gallery.wav"; + viewport.sfxaudio.src = AO_HOST + "sounds/general/sfx-gallery.opus"; viewport.sfxaudio.play(); viewport.sfxaudio.volume = oldvolume; } @@ -1221,11 +1279,9 @@ class Client extends EventEmitter { switch (Number(args[0])) { case 0: // playercount this.areas[i].players = Number(args[i+1]); - thisarea.innerText = `${this.areas[i].name} (${this.areas[i].players})`; break; case 1: // status this.areas[i].status = safe_tags(args[i+1]); - thisarea.classList = "area-button area-" + this.areas[i].status.toLowerCase(); break; case 2: this.areas[i].cm = safe_tags(args[i+1]); @@ -1235,6 +1291,10 @@ class Client extends EventEmitter { break; } + thisarea.classList = "area-button area-" + this.areas[i].status.toLowerCase(); + + thisarea.innerText = `${this.areas[i].name} (${this.areas[i].players}) [${this.areas[i].status}]`; + thisarea.title = `Players: ${this.areas[i].players}\n` + `Status: ${this.areas[i].status}\n` + `CM: ${this.areas[i].cm}\n` + @@ -1394,12 +1454,31 @@ class Client extends EventEmitter { alt="${emotes[i].desc}" class="emote_button" onclick="pickEmotion(${i})">`; + } catch (e) { console.error("missing emote " + i); } } pickEmotion(1); } + + if(await fileExists(AO_HOST + "characters/" + encodeURI(me.name.toLowerCase()) + "/custom.gif")) + document.getElementById("button_4").style.display = ""; + else + document.getElementById("button_4").style.display = "none"; + + const iniedit_select = document.getElementById("client_ininame"); + + function addIniswap(value) { + iniedit_select.add(new Option(safe_tags(value))); + } + + // most iniswaps don't list their original char + if (me.swaps.length > 0) { + iniedit_select.innerHTML = ""; + addIniswap(me.name); + me.swaps.forEach(addIniswap); + } } /** @@ -1453,7 +1532,8 @@ class Viewport { undefined, "holdit", "objection", - "takethat" + "takethat", + "custom" ]; this.colors = [ @@ -1471,23 +1551,24 @@ class Viewport { // Allocate multiple blip audio channels to make blips less jittery this.blipChannels = new Array(6); - this.blipChannels.fill(new Audio(AO_HOST + "sounds/general/sfx-blipmale.wav")) + this.blipChannels.fill(new Audio(AO_HOST + "sounds/general/sfx-blipmale.opus")) .forEach(channel => channel.volume = 0.5); this.currentBlipChannel = 0; this.sfxaudio = document.getElementById("client_sfxaudio"); - this.sfxaudio.src = `${AO_HOST}sounds/general/sfx-realization.wav`; + this.sfxaudio.src = `${AO_HOST}sounds/general/sfx-realization.opus`; this.sfxplayed = 0; this.shoutaudio = document.getElementById("client_shoutaudio"); - this.shoutaudio.src = `${AO_HOST}misc/default/objection.wav`; + this.shoutaudio.src = `${AO_HOST}misc/default/objection.opus`; this.testimonyAudio = document.getElementById("client_testimonyaudio"); - this.testimonyAudio.src = `${AO_HOST}sounds/general/sfx-guilty.wav`; + this.testimonyAudio.src = `${AO_HOST}sounds/general/sfx-guilty.opus`; - this.music = document.getElementById("client_musicaudio"); - this.music.src = `${AO_HOST}sounds/music/trial (aa).mp3`; + this.music = new Array(3); + this.music.fill(new Audio(`${AO_HOST}sounds/music/trial (aa).opus`)) + .forEach(channel => channel.volume = 0.5); this.updater = null; this.testimonyUpdater = null; @@ -1513,7 +1594,7 @@ class Viewport { } /** - * Sets the volume of the blip sound. + * Sets the volume of the blip sounds. * @param {number} volume */ set blipVolume(volume) { @@ -1521,6 +1602,14 @@ class Viewport { } /** + * Sets the volume of the music. + * @param {number} volume + */ + set musicVolume(volume) { + this.music.forEach(channel => channel.volume = volume); + } + + /** * Returns the path which the background is located in. */ get bgFolder() { @@ -1824,7 +1913,7 @@ async changeBackground(position) { } this.lastChar = this.chatmsg.name; - appendICLog(this.chatmsg.content, displayname); + appendICLog(this.chatmsg.content, this.chatmsg.showname, this.chatmsg.nameplate); checkCallword(this.chatmsg.content); @@ -1840,23 +1929,16 @@ async changeBackground(position) { if (shout) { // Hide message box chatContainerBox.style.opacity = 0; - shoutSprite.src = client.resources[shout]["src"]; - shoutSprite.style.opacity = 1; - shoutSprite.style.animation = "bubble 700ms steps(10, jump-both)"; - - let shoutUrl; - - try { - const { url: soundUrl } = await this.oneSuccess([ - this.rejectOnError(fetch(`${AO_HOST}characters/${encodeURI(this.chatmsg.name.toLowerCase())}/${shout}.wav`)), - this.rejectOnError(fetch(`${AO_HOST}misc/default/objection.wav`)) - ]); - shoutUrl = soundUrl; - } catch (error) { - shoutUrl = AO_HOST + `${AO_HOST}characters/${encodeURI(this.chatmsg.name.toLowerCase())}/${shout}.wav`; + if (this.chatmsg.objection === 4) { + shoutSprite.src = `${AO_HOST}characters/${encodeURI(this.chatmsg.name.toLowerCase())}/custom.gif`; + } else { + shoutSprite.src = client.resources[shout]["src"]; + shoutSprite.style.animation = "bubble 700ms steps(10, jump-both)"; } + shoutSprite.style.opacity = 1; + - this.shoutaudio.src = shoutUrl; + this.shoutaudio.src = `${AO_HOST}characters/${encodeURI(this.chatmsg.name.toLowerCase())}/${shout}.opus`; this.shoutaudio.play(); this.shoutTimer = client.resources[shout]["duration"]; } else { @@ -1903,7 +1985,7 @@ async changeBackground(position) { pairLayers.style.transform = "scaleX(1)"; } - this.blipChannels.forEach(channel => channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI(this.chatmsg.blips.toLowerCase())}.wav`); + this.blipChannels.forEach(channel => channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI(this.chatmsg.blips.toLowerCase())}.opus`); // process markup if(this.chatmsg.content.startsWith("~~")) { @@ -1983,12 +2065,12 @@ async changeBackground(position) { // Effect stuff if (this.chatmsg.screenshake === 1) { // Shake screen - this.playSFX(AO_HOST + "sounds/general/sfx-stab.wav", false); + this.playSFX(AO_HOST + "sounds/general/sfx-stab.opus", false); gamewindow.style.animation = "shake 0.2s 1"; } if (this.chatmsg.flash === 1) { // Flash screen - this.playSFX(AO_HOST + "sounds/general/sfx-realization.wav", false); + this.playSFX(AO_HOST + "sounds/general/sfx-realization.opus", false); effectlayer.style.animation = "flash 0.4s 1"; } @@ -2022,7 +2104,7 @@ async changeBackground(position) { eviBox.style.height = "36.5%"; eviBox.style.opacity = 1; - this.testimonyAudio.src = AO_HOST + "sounds/general/sfx-evidenceshoop.wav"; + this.testimonyAudio.src = AO_HOST + "sounds/general/sfx-evidenceshoop.opus"; this.testimonyAudio.play(); if (this.chatmsg.side === "def") { @@ -2099,7 +2181,7 @@ async changeBackground(position) { if (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) { this.sfxplayed = 1; if (this.chatmsg.sound !== "0" && this.chatmsg.sound !== "1" && this.chatmsg.sound !== "" && this.chatmsg.sound !== undefined) { - this.playSFX(AO_HOST + "sounds/general/" + encodeURI(this.chatmsg.sound.toLowerCase()) + ".wav", this.chatmsg.looping_sfx); + this.playSFX(AO_HOST + "sounds/general/" + encodeURI(this.chatmsg.sound.toLowerCase()) + ".opus", this.chatmsg.looping_sfx); } } this.textTimer = this.textTimer + UPDATE_INTERVAL; @@ -2323,6 +2405,13 @@ window.mutelist_click = mutelist_click; export function showname_click(_event) { setCookie("showname", document.getElementById("showname").checked); setCookie("ic_chat_name", document.getElementById("ic_chat_name").value); + + const css_s = document.getElementById("nameplate_setting"); + + if (document.getElementById("showname").checked) + css_s.href = "styles/shownames.css"; + else + css_s.href = "styles/nameplates.css"; } window.showname_click = showname_click; @@ -2345,7 +2434,8 @@ window.area_click = area_click; * Triggered by the music volume slider. */ export function changeMusicVolume() { - setCookie("musicVolume", document.getElementById("client_musicaudio").volume); + viewport.musicVolume = document.getElementById("client_mvolume").value; + setCookie("musicVolume", document.getElementById("client_mvolume").value); } window.changeMusicVolume = changeMusicVolume; @@ -2366,6 +2456,17 @@ export function changeShoutVolume() { window.changeShoutVolume = changeShoutVolume; /** + * Triggered when the shout could not be found + */ +export function shoutMissing(self) { + if (self.src !== `${AO_HOST}misc/default/objection.opus`) { + self.src = `${AO_HOST}misc/default/objection.opus`; + self.play(); + } +} +window.shoutMissing = shoutMissing; + +/** * Triggered by the testimony volume slider. */ export function changeTestimonyVolume() { @@ -2586,17 +2687,25 @@ window.ReconnectButton = ReconnectButton; * @param {string} msg the string to be added * @param {string} name the name of the sender */ -function appendICLog(msg, name = "", time = new Date()) { +function appendICLog(msg, showname = "", nameplate = "", time = new Date()) { const entry = document.createElement("p"); - const nameField = document.createElement("span"); - const textField = document.createElement("span"); - nameField.className = "iclog_name"; - nameField.appendChild(document.createTextNode(name)); + const shownameField = document.createElement("span"); + const nameplateField = document.createElement("span"); + const textField = document.createElement("span"); + nameplateField.classList = "iclog_name iclog_nameplate"; + nameplateField.appendChild(document.createTextNode(nameplate)); + + shownameField.classList = "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(nameField); + entry.appendChild(shownameField); + entry.appendChild(nameplateField); entry.appendChild(textField); // Only put a timestamp if the minute has changed. @@ -2633,7 +2742,7 @@ export function checkCallword(message) { if(item !== "" && message.toLowerCase().includes(item.toLowerCase())) { viewport.sfxaudio.pause(); - viewport.sfxaudio.src = AO_HOST + "sounds/general/sfx-gallery.wav"; + viewport.sfxaudio.src = AO_HOST + "sounds/general/sfx-gallery.opus"; viewport.sfxaudio.play(); } } @@ -3069,4 +3178,4 @@ export function toggleShout(shout) { selectedShout = shout; } } -window.toggleShout = toggleShout;
\ No newline at end of file +window.toggleShout = toggleShout; |
