async function getPortalToken() {
if (window.shell?.getTokenDeferred) {
return await shell.getTokenDeferred();
}
const hidden = document.querySelector(“input[name=’__RequestVerificationToken’]”);
if (hidden?.value) return hidden.value;
const res = await fetch(“/_layout/tokenhtml”, { credentials: “same-origin” });
const html = await res.text();
const doc = new DOMParser().parseFromString(html, “text/html”);
return doc.querySelector(“input[name=’__RequestVerificationToken’]”)?.value || “”;
}
async function loadZonesFromWebApi({ putOnMap = false } = {}) {
const select = Object.values(ZONE_FIELDS).join(“,”);
const url = `/_api/${ZONES_ENTITY_SET}?$select=${encodeURIComponent(select)}`;
const token = await getPortalToken();
debugger;
const res = await fetch(url, {
method: “GET”,
headers: {
“Accept”: “application/json”,
“OData-Version”: “4.0”,
“OData-MaxVersion”: “4.0”,
“Prefer”: “odata.include-annotations=\”OData.Community.Display.V1.FormattedValue\””,
“__RequestVerificationToken”: token
},
credentials: “same-origin”
});
if (!res.ok) {
const text = await res.text();
throw new Error(`Web API failed ${res.status}: ${text}`);
}
const data = await res.json();
const rows = data.value || [];
// Map Dataverse row -> your zone object shape
const zones = rows.map(r => ({
id: r[ZONE_FIELDS.id],
name: r[ZONE_FIELDS.name],
// Use formatted values when available, else fallback to numeric value
biome: r[`${ZONE_FIELDS.biome}@OData.Community.Display.V1.FormattedValue`] ?? r[ZONE_FIELDS.biome],
category: r[`${ZONE_FIELDS.category}@OData.Community.Display.V1.FormattedValue`] ?? r[ZONE_FIELDS.category],
startX: String(r[ZONE_FIELDS.startX] ?? “”),
startY: String(r[ZONE_FIELDS.startY] ?? “”),
startZ: String(r[ZONE_FIELDS.startZ] ?? “”),
endX: String(r[ZONE_FIELDS.endX] ?? “”),
endY: String(r[ZONE_FIELDS.endY] ?? “”),
endZ: String(r[ZONE_FIELDS.endZ] ?? “”),
protection: !!r[ZONE_FIELDS.protection],
pvpEnabled: !!r[ZONE_FIELDS.pvpEnabled],
maxPlayers: String(r[ZONE_FIELDS.maxPlayers] ?? “”)
}));
STATE.zones = zones;
if (putOnMap) {
STATE.map = […zones];
updateMapCount();
if (STATE.activeTab === “map”) renderMap();
}
return zones; // if you want to use it elsewhere
}
In our Minecraft solution, we leverage client-side JavaScript to manage the creation and review of user-defined zones and building applications—all with a focus on automation, feedback, and interactive mapping.
Instead of performing repetitive, manual tasks, users interact with a dynamic interface that lets them:
- Apply for building rights
- Define protected or Not Allowed zones
- See approvals, pending, and rejections in real time
- Visualize all changes on an interactive map



