aboutsummaryrefslogtreecommitdiff
path: root/webAO/client
diff options
context:
space:
mode:
authorCaleb <caleb.mabry.15@cnu.edu>2022-09-09 18:30:07 -0400
committerCaleb <caleb.mabry.15@cnu.edu>2022-09-09 18:30:07 -0400
commite50167a8077b0ada769cdf785971972c3ad865f7 (patch)
tree711000af34cf52b508ec05ec79b2f7d6d731cd78 /webAO/client
parent1e3f34e03c9dd8fda7e2b24e4533e23fcb7e1de7 (diff)
Pulled out everything I wanted
Diffstat (limited to 'webAO/client')
-rw-r--r--webAO/client/addTrack.ts15
-rw-r--r--webAO/client/createArea.ts30
-rw-r--r--webAO/client/fetchLists.ts60
-rw-r--r--webAO/client/fixLastArea.ts14
-rw-r--r--webAO/client/handleBans.ts17
-rw-r--r--webAO/client/handleCharacterInfo.ts105
-rw-r--r--webAO/client/isAudio.ts6
-rw-r--r--webAO/client/loadResources.ts79
-rw-r--r--webAO/client/saveChatLogHandle.ts26
9 files changed, 352 insertions, 0 deletions
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/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..e4d8725
--- /dev/null
+++ b/webAO/client/fixLastArea.ts
@@ -0,0 +1,14 @@
+import { client } from "../client";
+
+
+/**
+ * Area list fuckery
+ */
+export const fix_last_area = () => {
+ if (client.areas.length > 0) {
+ const malplaced = client.areas.pop().name;
+ const areas = document.getElementById("areas")!;
+ areas.removeChild(areas.lastChild);
+ client.addTrack(malplaced);
+ }
+} \ No newline at end of file
diff --git a/webAO/client/handleBans.ts b/webAO/client/handleBans.ts
new file mode 100644
index 0000000..b977fc8
--- /dev/null
+++ b/webAO/client/handleBans.ts
@@ -0,0 +1,17 @@
+/**
+ * Handles the kicked packet
+ * @param {string} type is it a kick or a ban
+ * @param {string} reason why
+ */
+export const handleBans = (type: string, reason: string) => {
+ document.getElementById("client_error")!.style.display = "flex";
+ document.getElementById(
+ "client_errortext"
+ )!.innerHTML = `${type}:<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/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/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