aboutsummaryrefslogtreecommitdiff
path: root/webAO/client.js
diff options
context:
space:
mode:
Diffstat (limited to 'webAO/client.js')
-rw-r--r--webAO/client.js271
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;