Works now pls test

This commit is contained in:
Scott Gould 2024-09-19 09:03:29 -04:00
parent 69c151162e
commit cc8b3ed638
No known key found for this signature in database
2 changed files with 450 additions and 446 deletions

View file

@ -8,59 +8,59 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
interface UptimeEntry {
time: number;
online: boolean;
time: number;
online: boolean;
}
interface UptimeObject {
[key: string]: UptimeEntry[];
[key: string]: UptimeEntry[];
}
interface Instance {
name: string;
urls?: { api: string };
url?: string;
online?: boolean;
uptime?: {
daytime: number;
weektime: number;
alltime: number;
};
name: string;
urls?: { api: string };
url?: string;
online?: boolean;
uptime?: {
daytime: number;
weektime: number;
alltime: number;
};
}
let uptimeObject: UptimeObject = loadUptimeObject();
export { uptimeObject as uptime };
function loadUptimeObject(): UptimeObject {
const filePath = path.join(__dirname, "..", "uptime.json");
if (fs.existsSync(filePath)) {
try {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
} catch (error) {
console.error("Error reading uptime.json:", error);
return {};
}
}
return {};
const filePath = path.join(__dirname, "..", "uptime.json");
if (fs.existsSync(filePath)) {
try {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
} catch (error) {
console.error("Error reading uptime.json:", error);
return {};
}
}
return {};
}
function saveUptimeObject(): void {
fs.writeFile(
`${__dirname}/uptime.json`,
JSON.stringify(uptimeObject),
(error) => {
if (error) {
console.error("Error saving uptime.json:", error);
}
}
);
fs.writeFile(
path.join(__dirname, "..", "uptime.json"),
JSON.stringify(uptimeObject),
(error) => {
if (error) {
console.error("Error saving uptime.json:", error);
}
}
);
}
function removeUndefinedKey(): void {
if (uptimeObject.undefined) {
delete uptimeObject.undefined;
saveUptimeObject();
}
if (uptimeObject.undefined) {
delete uptimeObject.undefined;
saveUptimeObject();
}
}
removeUndefinedKey();
@ -72,12 +72,12 @@ export async function observe(instances: Instance[]): Promise<void> {
);
await Promise.allSettled(instancePromises);
updateInactiveInstances(activeInstances);
}
}
async function resolveInstance(
async function resolveInstance(
instance: Instance,
activeInstances: Set<string>
): Promise<void> {
): Promise<void> {
try {
calcStats(instance);
const api = await getApiUrl(instance);
@ -86,13 +86,14 @@ export async function observe(instances: Instance[]): Promise<void> {
return;
}
activeInstances.add(instance.name);
await checkHealth(instance, api); // Ensure health is checked immediately
scheduleHealthCheck(instance, api);
} catch (error) {
console.error("Error resolving instance:", error);
}
}
}
async function getApiUrl(instance: Instance): Promise<string | null> {
async function getApiUrl(instance: Instance): Promise<string | null> {
if (instance.urls) {
return instance.urls.api;
}
@ -101,62 +102,64 @@ export async function observe(instances: Instance[]): Promise<void> {
return urls ? urls.api : null;
}
return null;
}
}
function handleUnresolvedApi(instance: Instance): void {
function handleUnresolvedApi(instance: Instance): void {
setStatus(instance, false);
console.warn(`${instance.name} does not resolve api URL`, instance);
setTimeout(() => resolveInstance(instance, new Set()), 1000 * 60 * 30);
}
}
function scheduleHealthCheck(instance: Instance, api: string): void {
function scheduleHealthCheck(instance: Instance, api: string): void {
const checkInterval = 1000 * 60 * 30;
const initialDelay = Math.random() * 1000 * 60 * 10;
setTimeout(() => {
checkHealth(instance, api);
setInterval(() => checkHealth(instance, api), checkInterval);
}, initialDelay);
}
}
async function checkHealth(
async function checkHealth(
instance: Instance,
api: string,
tries = 0
): Promise<void> {
): Promise<void> {
try {
const response = await fetch(`${api}ping`, { method: "HEAD" });
const response = await fetch(`${api}/ping`, { method: "HEAD" });
console.log(`Checking health for ${instance.name}: ${response.status}`);
if (response.ok || tries > 3) {
console.log(`Setting status for ${instance.name} to ${response.ok}`);
setStatus(instance, response.ok);
} else {
retryHealthCheck(instance, api, tries);
}
} catch (error) {
console.error("Error checking health:", error);
console.error(`Error checking health for ${instance.name}:`, error);
if (tries > 3) {
setStatus(instance, false);
} else {
retryHealthCheck(instance, api, tries);
}
}
}
}
function retryHealthCheck(
function retryHealthCheck(
instance: Instance,
api: string,
tries: number
): void {
): void {
setTimeout(() => checkHealth(instance, api, tries + 1), 30000);
}
}
function updateInactiveInstances(activeInstances: Set<string>): void {
function updateInactiveInstances(activeInstances: Set<string>): void {
for (const key of Object.keys(uptimeObject)) {
if (!activeInstances.has(key)) {
setStatus(key, false);
}
}
}
}
function calcStats(instance: Instance): void {
function calcStats(instance: Instance): void {
const obj = uptimeObject[instance.name];
if (!obj) return;
@ -199,15 +202,15 @@ export async function observe(instances: Instance[]): Promise<void> {
weektime,
online
);
}
}
function calculateUptimeStats(
function calculateUptimeStats(
totalTimePassed: number,
alltime: number,
daytime: number,
weektime: number,
online: boolean
): { daytime: number; weektime: number; alltime: number } {
): { daytime: number; weektime: number; alltime: number } {
const dayInMs = 1000 * 60 * 60 * 24;
const weekInMs = dayInMs * 7;
@ -229,9 +232,9 @@ export async function observe(instances: Instance[]): Promise<void> {
}
return { daytime, weektime, alltime };
}
}
function setStatus(instance: string | Instance, status: boolean): void {
function setStatus(instance: string | Instance, status: boolean): void {
const name = typeof instance === "string" ? instance : instance.name;
let obj = uptimeObject[name];
@ -240,12 +243,13 @@ export async function observe(instances: Instance[]): Promise<void> {
uptimeObject[name] = obj;
}
if (obj.at(-1)?.online !== status) {
const lastEntry = obj.at(-1);
if (!lastEntry || lastEntry.online !== status) {
obj.push({ time: Date.now(), online: status });
saveUptimeObject();
}
if (typeof instance !== "string") {
calcStats(instance);
}
}
}

View file

@ -3,133 +3,133 @@ import { Guild } from "./guild.js";
import { Localuser } from "./localuser.js";
class Emoji {
static emojis: {
name: string;
emojis: {
name: string;
emoji: string;
}[];
}[];
name: string;
id: string;
animated: boolean;
owner: Guild | Localuser;
get guild() {
if (this.owner instanceof Guild) {
return this.owner;
}
return;
}
get localuser() {
if (this.owner instanceof Guild) {
return this.owner.localuser;
} else {
return this.owner;
}
}
get info() {
return this.owner.info;
}
constructor(
json: { name: string; id: string; animated: boolean },
owner: Guild | Localuser
) {
this.name = json.name;
this.id = json.id;
this.animated = json.animated;
this.owner = owner;
}
getHTML(bigemoji: boolean = false) {
const emojiElem = document.createElement("img");
emojiElem.classList.add("md-emoji");
emojiElem.classList.add(bigemoji ? "bigemoji" : "smallemoji");
emojiElem.crossOrigin = "anonymous";
emojiElem.src =
this.info.cdn +
"/emojis/" +
this.id +
"." +
(this.animated ? "gif" : "png") +
"?size=32";
static emojis: {
name: string;
emojis: {
name: string;
emoji: string;
}[];
}[];
name: string;
id: string;
animated: boolean;
owner: Guild | Localuser;
get guild() {
if (this.owner instanceof Guild) {
return this.owner;
}
return;
}
get localuser() {
if (this.owner instanceof Guild) {
return this.owner.localuser;
} else {
return this.owner;
}
}
get info() {
return this.owner.info;
}
constructor(
json: { name: string; id: string; animated: boolean },
owner: Guild | Localuser
) {
this.name = json.name;
this.id = json.id;
this.animated = json.animated;
this.owner = owner;
}
getHTML(bigemoji: boolean = false) {
const emojiElem = document.createElement("img");
emojiElem.classList.add("md-emoji");
emojiElem.classList.add(bigemoji ? "bigemoji" : "smallemoji");
emojiElem.crossOrigin = "anonymous";
emojiElem.src =
this.info.cdn +
"/emojis/" +
this.id +
"." +
(this.animated ? "gif" : "png") +
"?size=32";
emojiElem.alt = this.name;
emojiElem.loading = "lazy";
return emojiElem;
}
static decodeEmojiList(buffer: ArrayBuffer) {
const view = new DataView(buffer, 0);
let i = 0;
function read16() {
const int = view.getUint16(i);
i += 2;
return int;
}
function read8() {
const int = view.getUint8(i);
i += 1;
return int;
}
function readString8() {
return readStringNo(read8());
}
function readString16() {
return readStringNo(read16());
}
function readStringNo(length: number) {
const array = new Uint8Array(length);
emojiElem.alt = this.name;
emojiElem.loading = "lazy";
return emojiElem;
}
static decodeEmojiList(buffer: ArrayBuffer) {
const view = new DataView(buffer, 0);
let i = 0;
function read16() {
const int = view.getUint16(i);
i += 2;
return int;
}
function read8() {
const int = view.getUint8(i);
i += 1;
return int;
}
function readString8() {
return readStringNo(read8());
}
function readString16() {
return readStringNo(read16());
}
function readStringNo(length: number) {
const array = new Uint8Array(length);
for (let i = 0; i < length; i++) {
array[i] = read8();
}
//console.log(array);
return new TextDecoder("utf-8").decode(array.buffer);
}
const build: { name: string; emojis: { name: string; emoji: string }[] }[] =
[];
let cats = read16();
for (let i = 0; i < length; i++) {
array[i] = read8();
}
//console.log(array);
return new TextDecoder("utf-8").decode(array.buffer);
}
const build: { name: string; emojis: { name: string; emoji: string }[] }[] =
[];
let cats = read16();
for (; cats !== 0; cats--) {
const name = readString16();
const emojis: {
name: string;
skin_tone_support: boolean;
emoji: string;
}[] = [];
let emojinumber = read16();
for (; emojinumber !== 0; emojinumber--) {
//console.log(emojis);
const name = readString8();
const len = read8();
const skin_tone_support = len > 127;
const emoji = readStringNo(len - Number(skin_tone_support) * 128);
emojis.push({
name,
skin_tone_support,
emoji,
});
}
build.push({
name,
emojis,
});
}
this.emojis = build;
console.log(build);
}
static grabEmoji() {
fetch("/emoji.bin")
.then((e) => {
return e.arrayBuffer();
})
.then((e) => {
Emoji.decodeEmojiList(e);
});
}
static async emojiPicker(
x: number,
y: number,
localuser: Localuser
): Promise<Emoji | string> {
for (; cats !== 0; cats--) {
const name = readString16();
const emojis: {
name: string;
skin_tone_support: boolean;
emoji: string;
}[] = [];
let emojinumber = read16();
for (; emojinumber !== 0; emojinumber--) {
//console.log(emojis);
const name = readString8();
const len = read8();
const skin_tone_support = len > 127;
const emoji = readStringNo(len - Number(skin_tone_support) * 128);
emojis.push({
name,
skin_tone_support,
emoji,
});
}
build.push({
name,
emojis,
});
}
this.emojis = build;
console.log(build);
}
static grabEmoji() {
fetch("/emoji.bin")
.then((e) => {
return e.arrayBuffer();
})
.then((e) => {
Emoji.decodeEmojiList(e);
});
}
static async emojiPicker(
x: number,
y: number,
localuser: Localuser
): Promise<Emoji | string> {
let res: (r: Emoji | string) => void;
const promise: Promise<Emoji | string> = new Promise((r) => {
res = r;
@ -254,6 +254,6 @@ localuser: Localuser
menu.append(body);
return promise;
}
}
Emoji.grabEmoji();
export { Emoji };
}
Emoji.grabEmoji();
export { Emoji };