Backend Stability, Basically functional.

This commit is contained in:
2025-10-27 12:38:22 +08:00
parent d0d3373b3b
commit 4ea30cc12e
59 changed files with 5034 additions and 35 deletions

View File

@@ -31,7 +31,7 @@
"format:check": "prettier --check src/",
"fix": "npm run lint -- --fix",
"generate-component": "node scripts/generate-component.js",
"prepare": "cd .. && husky install site/.husky",
"prepare": "if exist .git (husky install) else (echo Skipping husky install)",
"precommit": "npm run format:check && npm run lint"
},
"author": "Christopher Brown"

File diff suppressed because one or more lines are too long

View File

@@ -275,33 +275,79 @@ export class GroupData {
}
static transformCoordinatesFromStorage(coordinates) {
if (coordinates === undefined || coordinates === null) return;
const xOffset = 128;
const yOffset = 1;
// NOTE: The coordinates from runelite seems to have changed? Need to
// offset them now to line them up with the map.
const xOffset = 128;
const yOffset = 1;
return {
x: coordinates[0] + xOffset,
y: coordinates[1] + yOffset,
plane: coordinates[2],
};
try {
// Nothing at all
if (coordinates === undefined || coordinates === null) {
return { x: 0, y: 0, plane: 0 };
}
// Already transformed {x, y, plane} from backend
if (
typeof coordinates === "object" &&
"x" in coordinates &&
"y" in coordinates &&
typeof coordinates.x === "number" &&
typeof coordinates.y === "number"
) {
// No offset — already applied server-side
return coordinates;
}
// Raw array form [x, y, plane] from older plugin
if (Array.isArray(coordinates) && coordinates.length >= 3) {
return {
x: (coordinates[0] ?? 0) + xOffset,
y: (coordinates[1] ?? 0) + yOffset,
plane: coordinates[2] ?? 0,
};
}
console.warn("Unexpected coordinate format:", coordinates);
return { x: 0, y: 0, plane: 0 };
} catch (e) {
console.error("Coordinate transform error:", e, coordinates);
return { x: 0, y: 0, plane: 0 };
}
}
static transformQuestsFromStorage(quests) {
if (quests === undefined || quests === null) return;
if (quests === undefined || quests === null) return;
const result = {};
const questStates = Object.keys(QuestState);
const questIds = Quest.questIds;
for (let i = 0; i < quests.length; ++i) {
const questState = quests[i];
const questId = questIds[i];
result[questId] = questStates[questState];
// If the backend sends a base64 string, decode it first
if (typeof quests === "string") {
try {
const decoded = atob(quests);
const bytes = new Uint8Array(decoded.length);
for (let i = 0; i < decoded.length; i++) {
bytes[i] = decoded.charCodeAt(i);
}
quests = Array.from(bytes);
} catch (e) {
console.error("Failed to decode quest data:", e);
return {};
}
return result;
}
const result = {};
const questStates = Object.keys(QuestState);
const questIds = Quest.questIds;
for (let i = 0; i < quests.length && i < questIds.length; ++i) {
const questState = quests[i];
const questId = questIds[i];
result[questId] = questStates[questState];
}
return result;
}
transformFromStorage(groupData) {
for (const memberData of groupData) {
memberData.inventory = GroupData.transformItemsFromStorage(memberData.inventory);
@@ -314,13 +360,9 @@ export class GroupData {
memberData.coordinates = GroupData.transformCoordinatesFromStorage(memberData.coordinates);
memberData.quests = GroupData.transformQuestsFromStorage(memberData.quests);
if (memberData.interacting) {
memberData.interacting.location = GroupData.transformCoordinatesFromStorage([
memberData.interacting.location.x,
memberData.interacting.location.y,
memberData.interacting.location.plane,
]);
}
// Interacting is just a plain string (e.g., "Guard" or "Capt' Arnav")
// No coordinate transformation needed.
}
}
}

View File

@@ -62,10 +62,28 @@ export class MemberData {
}
if (memberData.quests) {
this.quests = Quest.parseQuestData(memberData.quests);
this.publishUpdate("quests");
updatedAttributes.add("quests");
let quests = memberData.quests;
// Decode base64 string to byte array if needed
if (typeof quests === "string") {
try {
const decoded = atob(quests);
const bytes = new Uint8Array(decoded.length);
for (let i = 0; i < decoded.length; i++) {
bytes[i] = decoded.charCodeAt(i);
}
quests = Array.from(bytes);
} catch (e) {
console.error("Failed to decode quest data:", e);
quests = [];
}
}
this.quests = Quest.parseQuestData(quests);
this.publishUpdate("quests");
updatedAttributes.add("quests");
}
if (memberData.skills) {
const previousSkills = this.skills;
@@ -106,10 +124,20 @@ export class MemberData {
}
if (memberData.interacting) {
memberData.interacting.name = utility.removeTags(memberData.interacting.name);
this.interacting = memberData.interacting;
this.publishUpdate("interacting");
}
if (typeof memberData.interacting === "string") {
// Backend sends a plain name string
this.interacting = { name: utility.removeTags(memberData.interacting) };
} else if (typeof memberData.interacting === "object") {
// Original plugin format (has .name and maybe .location)
memberData.interacting.name = utility.removeTags(memberData.interacting.name);
this.interacting = memberData.interacting;
} else {
this.interacting = { name: null };
}
this.publishUpdate("interacting");
}
if (memberData.seed_vault) {
this.seedVault = Item.parseItemData(memberData.seed_vault);