let gearData = null; let gearThreadActive = false; let keepStatsUpdated = false; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } document.addEventListener('DOMContentLoaded', () => { loadGearData(); sendToCSharp("OSType"); }); const delay = (ms) => new Promise(res => setTimeout(res, ms)); async function updateStatsPage() { while (keepStatsUpdated) { await fetchCemuBase(); await delay(2000); } } async function loadGearData() { try { const response = await fetch('ids.json'); gearData = await response.json(); populateAbilities(); syncGearDropdown(); } catch (e) { console.error("Gear IDs failed to load. Check if ids.json exists.", e); } } function onCategoryChange() { syncGearDropdown(); const grid = document.getElementById('gear-selection-grid'); grid.innerHTML = '
Fetching Gear...
'; execute('FetchGear'); } function syncGearDropdown() { if (!gearData) return; const cat = document.getElementById('gear-category').value; const key = (cat === "clothing") ? "clothes" : cat; const select = document.getElementById('gear-item'); if (!select) return; select.innerHTML = ''; if (gearData[key]) { for (const [id, name] of Object.entries(gearData[key])) { const opt = document.createElement('option'); opt.value = id; opt.textContent = name; select.appendChild(opt); } } } function populateAbilities() { const selectors = ['ability-sub1', 'ability-sub2', 'ability-sub3']; selectors.forEach(id => { const select = document.getElementById(id); if (!select || !gearData.abilities) return; select.innerHTML = ''; for (const [val, name] of Object.entries(gearData.abilities)) { const opt = document.createElement('option'); opt.value = val; opt.textContent = name; select.appendChild(opt); } }); } function populateEquipment() { const weapons = document.getElementById("weapon-sets"); const headgear = document.getElementById("headgear-sets"); const clothes = document.getElementById("clothes-sets"); const shoes = document.getElementById("shoes-sets"); weapons.innerHTML = ''; for (const [val, name] of Object.entries(gearData.WeaponSetIds)) { const opt = document.createElement('option'); opt.value = val; opt.textContent = name; weapons.appendChild(opt); } headgear.innerHTML = ''; for (const [val, name] of Object.entries(gearData.headgear)) { const opt = document.createElement('option'); opt.value = val; opt.textContent = name; headgear.appendChild(opt); } clothes.innerHTML = ''; for (const [val, name] of Object.entries(gearData.clothes)) { const opt = document.createElement('option'); opt.value = val; opt.textContent = name; clothes.appendChild(opt); } shoes.innerHTML = ''; for (const [val, name] of Object.entries(gearData.shoes)) { const opt = document.createElement('option'); opt.value = val; opt.textContent = name; shoes.appendChild(opt); } sendToCSharp("AllEquipment"); } window.external.receiveMessage(message => { // console.log(message) if (message.startsWith("Cemu Base:")) { document.getElementById("cbase").innerHTML = message; } if (message === "2") { alert("MacOS Build is Untested. Expect Issues!"); } try { const data = JSON.parse(message); console.log("Parsed Data:", data); if (data.EquippedWepId !== undefined) { const weapons = document.getElementById("weapon-sets"); const headgear = document.getElementById("headgear-sets"); const clothes = document.getElementById("clothes-sets"); const shoes = document.getElementById("shoes-sets"); weapons.value = data.EquippedWepId; headgear.value = data.EquippedHeadgearId; clothes.value = data.EquippedClothesId; shoes.value = data.EquippedShoesId; return; } const container = document.getElementById("pid-display"); if (data.Players) { container.innerHTML = `Fetching data....
`; let html = `No players found.
'; } else if (data.headgear || data.clothing || data.shoes || data.clothes) { renderGearGrid(data); } } catch (e) { console.log(e.message); } }); function renderGearGrid(fullData) { const category = document.getElementById('gear-category').value; const grid = document.getElementById('gear-selection-grid'); grid.innerHTML = ""; let items = fullData[category]; if (!items && category === "clothing") items = fullData["clothes"]; if (!items || items.length === 0) { grid.innerHTML = 'No gear found in this category.
'; return; } const idLookupKey = (category === "clothing") ? "clothes" : category; items.forEach((item, index) => { const isEmpty = (item.GearID === 4294967295 || item.GearID === -1); let gearName = "Unknown Item"; if (isEmpty) { gearName = "Empty Slot (+)"; } else if (gearData && gearData[idLookupKey] && gearData[idLookupKey][item.GearID]) { gearName = gearData[idLookupKey][item.GearID]; } else { gearName = `ID: ${item.GearID}`; } const card = document.createElement('div'); card.className = 'pid-card'; card.style.cursor = 'pointer'; if (isEmpty) { card.style.borderLeft = '4px dashed #444'; card.style.opacity = '0.7'; } card.innerHTML = `${gearName}