Move dynmap dimension guessing to util function

This commit is contained in:
James Lyne 2022-02-26 13:52:02 +00:00
parent 6373c52729
commit f472422281
2 changed files with 57 additions and 17 deletions

View File

@ -20,7 +20,7 @@ import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
import { import {
Coordinate, Coordinate,
HeadQueueEntry, HeadQueueEntry,
LiveAtlasBounds, LiveAtlasBounds, LiveAtlasDimension,
LiveAtlasGlobalMessageConfig, LiveAtlasGlobalMessageConfig,
LiveAtlasLocation, LiveAtlasLocation,
LiveAtlasMessageConfig, LiveAtlasMessageConfig,
@ -39,8 +39,8 @@ const documentRange = document.createRange(),
headQueue: HeadQueueEntry[] = []; headQueue: HeadQueueEntry[] = [];
export const titleColoursRegex = /§[0-9a-f]/ig; export const titleColoursRegex = /§[0-9a-f]/ig;
export const netherWorldNameRegex = /_?nether(_|$)/i; export const netherWorldNameRegex = /[_\s]?nether([\s_]|$)/i;
export const endWorldNameRegex = /(^|_)end(_|$)/i; export const endWorldNameRegex = /(^|[_\s])end([\s_]|$)/i;
export const getMinecraftTime = (serverTime: number) => { export const getMinecraftTime = (serverTime: number) => {
const day = serverTime >= 0 && serverTime < 13700; const day = serverTime >= 0 && serverTime < 13700;
@ -260,6 +260,14 @@ const _getMessages = (messageKeys: any, config: any = {}) => {
return messages as LiveAtlasGlobalMessageConfig; return messages as LiveAtlasGlobalMessageConfig;
} }
/**
* Determines the bounds required to enclose the given separate arrays of x, y and z coordinates
* All arrays are expected to be the same length
* @param {number[]} x X coordinates
* @param {number[]} y Y coordinates
* @param {number[]} z Z coordinates
* @returns {LiveAtlasBounds} The calculated bounds
*/
export const getBounds = (x: number[], y: number[], z: number[]): LiveAtlasBounds => { export const getBounds = (x: number[], y: number[], z: number[]): LiveAtlasBounds => {
return { return {
min: {x: Math.min.apply(null, x), y: Math.min.apply(null, y), z: Math.min.apply(null, z)}, min: {x: Math.min.apply(null, x), y: Math.min.apply(null, y), z: Math.min.apply(null, z)},
@ -267,6 +275,12 @@ export const getBounds = (x: number[], y: number[], z: number[]): LiveAtlasBound
}; };
} }
/**
* Determines the bounds required to enclose the given array of {@see Coordinate}s
* Multiple dimension arrays are accepted and will be handled recursively
* @param {Coordinate[]} points Points to determine the bounds for
* @returns {LiveAtlasBounds} The calculated bounds
*/
export const getBoundsFromPoints = (points: Coordinate[]): LiveAtlasBounds => { export const getBoundsFromPoints = (points: Coordinate[]): LiveAtlasBounds => {
const bounds = { const bounds = {
max: {x: -Infinity, y: -Infinity, z: -Infinity}, max: {x: -Infinity, y: -Infinity, z: -Infinity},
@ -291,6 +305,11 @@ export const getBoundsFromPoints = (points: Coordinate[]): LiveAtlasBounds => {
return bounds; return bounds;
} }
/**
* Determines the center point of the given {@see LiveAtlasBounds}
* @param {LiveAtlasBounds} bounds The bounds to find the center point for
* @return {LiveAtlasLocation} The center point
*/
export const getMiddle = (bounds: LiveAtlasBounds): LiveAtlasLocation => { export const getMiddle = (bounds: LiveAtlasBounds): LiveAtlasLocation => {
return { return {
x: bounds.min.x + ((bounds.max.x - bounds.min.x) / 2), x: bounds.min.x + ((bounds.max.x - bounds.min.x) / 2),
@ -299,6 +318,10 @@ export const getMiddle = (bounds: LiveAtlasBounds): LiveAtlasLocation => {
}; };
} }
/**
* Creates an "allow-scripts" sandboxed <iframe> to be used by {@see runSandboxed}
* @returns {Window} The iframe's contentWindow
*/
const createIframeSandbox = () => { const createIframeSandbox = () => {
const frame = document.createElement('iframe'); const frame = document.createElement('iframe');
frame.hidden = true; frame.hidden = true;
@ -355,6 +378,14 @@ const sandboxWindow: Window | null = createIframeSandbox();
const sandboxSuccessCallbacks: Map<number, (result?: any) => void> = new Map(); const sandboxSuccessCallbacks: Map<number, (result?: any) => void> = new Map();
const sandboxErrorCallbacks: Map<number, (reason?: any) => void> = new Map(); const sandboxErrorCallbacks: Map<number, (reason?: any) => void> = new Map();
/**
* Runs the given untrusted JavaScript code inside an "allow-scripts" sandboxed <iframe>
* The executing code cannot access or interfere with LiveAtlas state,
* but can still make requests and access many JS APIs
* @param {string} code The code to run
* @returns {Promise<any>} A promise that will resolve with the return value of the executed JS,
* or will reject with any Errors that occurred during execution.
*/
export const runSandboxed = async (code: string) => { export const runSandboxed = async (code: string) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const key = Math.random(); const key = Math.random();
@ -368,3 +399,23 @@ export const runSandboxed = async (code: string) => {
}, '*'); }, '*');
}); });
} }
/**
* Attempts to guess the dimension of the given world name
* The world name is checked against vanilla nether/end world names and regexes covering
* common nether/end world naming conventions
* If none of the above match, the world is assumed to be overworld
* @param {string} worldName Name of the world to guess
* @returns {LiveAtlasDimension} The guessed dimension
*/
export const guessWorldDimension = (worldName: string) => {
let dimension: LiveAtlasDimension = 'overworld';
if (netherWorldNameRegex.test(worldName) || (worldName == 'DIM-1')) {
dimension = 'nether';
} else if (endWorldNameRegex.test(worldName) || (worldName == 'DIM1')) {
dimension = 'end';
}
return dimension;
}

View File

@ -23,7 +23,6 @@ import {
LiveAtlasChat, LiveAtlasChat,
LiveAtlasCircleMarker, LiveAtlasCircleMarker,
LiveAtlasComponentConfig, LiveAtlasComponentConfig,
LiveAtlasDimension,
LiveAtlasLineMarker, LiveAtlasMarker, LiveAtlasLineMarker, LiveAtlasMarker,
LiveAtlasPlayerImageSize, LiveAtlasPlayerImageSize,
LiveAtlasPointMarker, LiveAtlasPointMarker,
@ -33,10 +32,8 @@ import {
} from "@/index"; } from "@/index";
import {getPoints} from "@/util/areas"; import {getPoints} from "@/util/areas";
import { import {
decodeHTMLEntities, decodeHTMLEntities, getBounds, getImagePixelSize,
endWorldNameRegex, getBounds, getImagePixelSize, getMiddle, guessWorldDimension,
getMiddle,
netherWorldNameRegex,
stripHTML, stripHTML,
titleColoursRegex titleColoursRegex
} from "@/util"; } from "@/util";
@ -96,18 +93,10 @@ export function buildWorlds(response: Configuration, config: DynmapUrlConfig): A
//Get all the worlds first so we can handle append_to_world properly //Get all the worlds first so we can handle append_to_world properly
(response.worlds || []).forEach((world: WorldConfiguration) => { (response.worlds || []).forEach((world: WorldConfiguration) => {
let worldType: LiveAtlasDimension = 'overworld';
if (netherWorldNameRegex.test(world.name) || (world.name == 'DIM-1')) {
worldType = 'nether';
} else if (endWorldNameRegex.test(world.name) || (world.name == 'DIM1')) {
worldType = 'end';
}
worlds.set(world.name, { worlds.set(world.name, {
name: world.name, name: world.name,
displayName: world.title || '', displayName: world.title || '',
dimension: worldType, dimension: guessWorldDimension(world.name),
seaLevel: world.sealevel || 64, seaLevel: world.sealevel || 64,
center: { center: {
x: world.center.x || 0, x: world.center.x || 0,