UNPKG

@runejs/filestore

Version:

Tools for managing the RuneJS filestore.

162 lines (161 loc) 6.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RegionStore = exports.maxRegions = void 0; const tslib_1 = require("tslib"); const common_1 = require("@runejs/common"); const node_fs_1 = require("node:fs"); const node_path_1 = tslib_1.__importDefault(require("node:path")); exports.maxRegions = 32768; class RegionStore { fileStore; xteas = {}; regionIndex; constructor(fileStore, xteas) { this.fileStore = fileStore; this.regionIndex = this.fileStore.getIndex('regions'); if (xteas) { this.xteas = xteas; } else { const array = JSON.parse((0, node_fs_1.readFileSync)(node_path_1.default.join(this.fileStore.configDir, 'map-keys.json'), 'utf8')); for (let i = 0; i < array.length; i++) { const object = array[i]; this.xteas[object.name] = object; } } } getMapKeys(regionX, regionY) { return this.xteas[`l${regionX}_${regionY}`]?.key || [0, 0, 0, 0]; } getRegion(regionX, regionY) { const mapFile = this.getMapFile(regionX, regionY); if (!mapFile) { return null; } const landscapeFile = this.getLandscapeFile(regionX, regionY) || null; return { regionX, regionY, mapFile, landscapeFile }; } getLandscapeFile(regionX, regionY) { const keys = this.getMapKeys(regionX, regionY); const landscapeFile = this.regionIndex.getFile(`l${regionX}_${regionY}`, keys); if (!landscapeFile) { common_1.logger.warn(`Landscape file not found for region ${regionX},${regionY}`); return null; } const landscapeObjects = []; let objectId = -1; landscapeFile.content.readerIndex = 0; let objectLoop = true; while (objectLoop) { const objectIdOffset = landscapeFile.content.get('SMART_SHORT'); if (objectIdOffset === 0) { objectLoop = false; break; } objectId += objectIdOffset; let objectPositionInfo = 0; let positionLoop = true; while (positionLoop) { const objectPositionInfoOffset = landscapeFile.content.get('SMART_SHORT'); if (objectPositionInfoOffset === 0) { positionLoop = false; break; } objectPositionInfo += objectPositionInfoOffset - 1; const worldX = (regionX & 0xff) * 64; const worldY = regionY * 64; const x = ((objectPositionInfo >> 6) & 0x3f) + worldX; const y = (objectPositionInfo & 0x3f) + worldY; const level = (objectPositionInfo >> 12) & 0x3; const objectMetadata = landscapeFile.content.get('BYTE', 'UNSIGNED'); const type = objectMetadata >> 2; const orientation = objectMetadata & 0x3; landscapeObjects.push({ objectId, x, y, level, type, orientation, }); } } return { fileId: landscapeFile.fileId, regionX, regionY, landscapeObjects, }; } getMapFile(regionX, regionY) { const mapFile = this.regionIndex.getFile(`m${regionX}_${regionY}`); if (!mapFile) { common_1.logger.warn(`Map file not found for region ${regionX},${regionY}`); return null; } const tileHeights = new Array(4); const tileSettings = new Array(4); const tileOverlayIds = new Array(4); const tileOverlayPaths = new Array(4); const tileOverlayOrientations = new Array(4); const tileUnderlayIds = new Array(4); const buffer = mapFile.content; buffer.readerIndex = 0; for (let level = 0; level < 4; level++) { tileHeights[level] = new Array(64); tileSettings[level] = new Array(64); tileOverlayIds[level] = new Array(64); tileOverlayPaths[level] = new Array(64); tileOverlayOrientations[level] = new Array(64); tileUnderlayIds[level] = new Array(64); for (let x = 0; x < 64; x++) { tileHeights[level][x] = new Array(64); tileSettings[level][x] = new Uint8Array(64); tileOverlayIds[level][x] = new Uint8Array(64); tileOverlayPaths[level][x] = new Uint8Array(64); tileOverlayOrientations[level][x] = new Uint8Array(64); tileUnderlayIds[level][x] = new Uint8Array(64); for (let y = 0; y < 64; y++) { tileSettings[level][x][y] = 0; let run = true; while (run) { const opcode = buffer.get('BYTE', 'UNSIGNED'); if (opcode === 0) { run = false; break; } if (opcode === 1) { tileHeights[level][x][y] = buffer.get('BYTE', 'UNSIGNED'); run = false; break; } if (opcode <= 49) { tileOverlayIds[level][x][y] = buffer.get('BYTE'); tileOverlayPaths[level][x][y] = (opcode - 2) / 4; tileOverlayOrientations[level][x][y] = (opcode - 2) & 3; } else if (opcode <= 81) { tileSettings[level][x][y] = opcode - 49; } else { tileUnderlayIds[level][x][y] = opcode - 81; } } } } } return { fileId: mapFile.fileId, regionX, regionY, tileHeights, tileOverlayIds, tileOverlayOrientations, tileOverlayPaths, tileSettings, tileUnderlayIds, }; } } exports.RegionStore = RegionStore;