|
| 1 | +import { logger } from '@runejs/core'; |
| 2 | +import _ from 'lodash'; |
| 3 | +import { |
| 4 | + ItemDetails, |
| 5 | + ItemPresetConfiguration, |
| 6 | + loadItemConfigurations, |
| 7 | + translateItemConfig |
| 8 | +} from '@engine/config/item-config'; |
| 9 | +import { filestore, questMap } from '@engine/game-server'; |
| 10 | +import { |
| 11 | + loadNpcConfigurations, |
| 12 | + NpcDetails, |
| 13 | + NpcPresetConfiguration, |
| 14 | + translateNpcServerConfig |
| 15 | +} from '@engine/config/npc-config'; |
| 16 | +import { loadNpcSpawnConfigurations, NpcSpawn } from '@engine/config/npc-spawn-config'; |
| 17 | +import { loadShopConfigurations, Shop } from '@engine/config/shop-config'; |
| 18 | +import { Quest } from '@engine/world/actor/player/quest'; |
| 19 | +import { ItemSpawn, loadItemSpawnConfigurations } from '@engine/config/item-spawn-config'; |
| 20 | +import { loadSkillGuideConfigurations, SkillGuide } from '@engine/config/skill-guide-config'; |
| 21 | +import { loadMusicRegionConfigurations, MusicTrack } from '@engine/config/music-regions-config'; |
| 22 | +import { LandscapeObject, loadXteaRegionFiles, ObjectConfig, XteaRegion } from '@runejs/filestore'; |
| 23 | + |
| 24 | +require('json5/lib/register'); |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +export let itemMap: { [key: string]: ItemDetails }; |
| 29 | +export let itemIdMap: { [key: number]: string }; |
| 30 | +export let objectMap: { [key: number]: ObjectConfig }; |
| 31 | +export let itemPresetMap: ItemPresetConfiguration; |
| 32 | +export let npcMap: { [key: string]: NpcDetails }; |
| 33 | +export let npcIdMap: { [key: number]: string }; |
| 34 | +export let npcPresetMap: NpcPresetConfiguration; |
| 35 | +export let npcSpawns: NpcSpawn[] = []; |
| 36 | +export let musicRegions: MusicTrack[] = []; |
| 37 | +export let itemSpawns: ItemSpawn[] = []; |
| 38 | +export let shopMap: { [key: string]: Shop }; |
| 39 | +export let skillGuides: SkillGuide[] = []; |
| 40 | +export let xteaRegions: { [key: number]: XteaRegion }; |
| 41 | + |
| 42 | +export const musicRegionMap = new Map<number, number>(); |
| 43 | +export const widgets: { [key: string]: any } = require('../../../data/config/widgets.json5'); |
| 44 | + |
| 45 | +export async function loadCoreConfigurations(): Promise<void> { |
| 46 | + xteaRegions = await loadXteaRegionFiles('data/config/xteas'); |
| 47 | +} |
| 48 | + |
| 49 | +export async function loadGameConfigurations(): Promise<void> { |
| 50 | + logger.info(`Loading server configurations...`); |
| 51 | + |
| 52 | + const { items, itemIds, itemPresets } = await loadItemConfigurations('data/config/items/'); |
| 53 | + itemMap = items; |
| 54 | + itemIdMap = itemIds; |
| 55 | + itemPresetMap = itemPresets; |
| 56 | + |
| 57 | + const { npcs, npcIds, npcPresets } = await loadNpcConfigurations('data/config/npcs/'); |
| 58 | + npcMap = npcs; |
| 59 | + npcIdMap = npcIds; |
| 60 | + npcPresetMap = npcPresets; |
| 61 | + |
| 62 | + npcSpawns = await loadNpcSpawnConfigurations('data/config/npc-spawns/'); |
| 63 | + musicRegions = await loadMusicRegionConfigurations(); |
| 64 | + musicRegions.forEach(song => song.regionIds.forEach(region => musicRegionMap.set(region, song.songId))); |
| 65 | + itemSpawns = await loadItemSpawnConfigurations('data/config/item-spawns/'); |
| 66 | + |
| 67 | + shopMap = await loadShopConfigurations('data/config/shops/'); |
| 68 | + skillGuides = await loadSkillGuideConfigurations('data/config/skill-guides/'); |
| 69 | + |
| 70 | + objectMap = {}; |
| 71 | + |
| 72 | + logger.info(`Loaded ${musicRegions.length} music regions, ${Object.keys(itemMap).length} items, ${itemSpawns.length} item spawns, ` + |
| 73 | + `${Object.keys(npcMap).length} npcs, ${npcSpawns.length} npc spawns, ${Object.keys(shopMap).length} shops and ${skillGuides.length} skill guides.`); |
| 74 | +} |
| 75 | + |
| 76 | + |
| 77 | +export const findItem = (itemKey: number | string): ItemDetails | null => { |
| 78 | + if(!itemKey) { |
| 79 | + return null; |
| 80 | + } |
| 81 | + |
| 82 | + let gameId: number; |
| 83 | + if(typeof itemKey === 'number') { |
| 84 | + gameId = itemKey; |
| 85 | + itemKey = itemIdMap[gameId]; |
| 86 | + |
| 87 | + if(!itemKey) { |
| 88 | + logger.warn(`Item ${gameId} is not yet registered on the server.`); |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + let item; |
| 93 | + |
| 94 | + if(itemKey) { |
| 95 | + item = itemMap[itemKey]; |
| 96 | + if(!item) { |
| 97 | + // Try fetching variation with suffix 0 |
| 98 | + item = itemMap[`${itemKey}:0`] |
| 99 | + } |
| 100 | + if(item?.gameId) { |
| 101 | + gameId = item.gameId; |
| 102 | + } |
| 103 | + |
| 104 | + if(item?.extends) { |
| 105 | + let extensions = item.extends; |
| 106 | + if(typeof extensions === 'string') { |
| 107 | + extensions = [ extensions ]; |
| 108 | + } |
| 109 | + |
| 110 | + extensions.forEach(extKey => { |
| 111 | + const extensionItem = itemPresetMap[extKey]; |
| 112 | + if(extensionItem) { |
| 113 | + item = _.merge(item, translateItemConfig(undefined, extensionItem)); |
| 114 | + } |
| 115 | + }); |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + if(gameId) { |
| 120 | + const cacheItem = filestore.configStore.itemStore.getItem(gameId); |
| 121 | + item = _.merge(item, cacheItem); |
| 122 | + } |
| 123 | + |
| 124 | + return item ? new ItemDetails(item) : null; |
| 125 | +}; |
| 126 | + |
| 127 | + |
| 128 | +export const findNpc = (npcKey: number | string): NpcDetails | null => { |
| 129 | + if(!npcKey) { |
| 130 | + return null; |
| 131 | + } |
| 132 | + |
| 133 | + if(typeof npcKey === 'number') { |
| 134 | + const gameId = npcKey; |
| 135 | + npcKey = npcIdMap[gameId]; |
| 136 | + |
| 137 | + if(!npcKey) { |
| 138 | + const cacheNpc = filestore.configStore.npcStore.getNpc(gameId); |
| 139 | + if(cacheNpc) { |
| 140 | + return cacheNpc as any; |
| 141 | + } else { |
| 142 | + logger.warn(`NPC ${gameId} is not yet configured on the server and a matching cache NPC was not found.`); |
| 143 | + return null; |
| 144 | + } |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + let npc = npcMap[npcKey]; |
| 149 | + if(!npc) { |
| 150 | + // Try fetching variation with suffix 0 |
| 151 | + npc = npcMap[`${npc}:0`] |
| 152 | + } |
| 153 | + |
| 154 | + if(!npc) { |
| 155 | + logger.warn(`NPC ${npcKey} is not yet configured on the server and a matching cache NPC was not provided.`); |
| 156 | + return null; |
| 157 | + } |
| 158 | + |
| 159 | + if(npc.extends) { |
| 160 | + let extensions = npc.extends; |
| 161 | + if(typeof extensions === 'string') { |
| 162 | + extensions = [ extensions ]; |
| 163 | + } |
| 164 | + |
| 165 | + extensions.forEach(extKey => { |
| 166 | + const extensionNpc = npcPresetMap[extKey]; |
| 167 | + if(extensionNpc) { |
| 168 | + npc = _.merge(npc, translateNpcServerConfig(undefined, extensionNpc)); |
| 169 | + } |
| 170 | + }); |
| 171 | + } |
| 172 | + |
| 173 | + return npc; |
| 174 | +}; |
| 175 | + |
| 176 | + |
| 177 | +export const findObject = (objectId: number): ObjectConfig | null => { |
| 178 | + if(!objectMap[objectId]) { |
| 179 | + const object = filestore.objectStore.getObject(objectId); |
| 180 | + if(!object) { |
| 181 | + return null; |
| 182 | + } |
| 183 | + |
| 184 | + objectMap[objectId] = object; |
| 185 | + return object; |
| 186 | + } else { |
| 187 | + return objectMap[objectId]; |
| 188 | + } |
| 189 | +}; |
| 190 | + |
| 191 | + |
| 192 | +export const findShop = (shopKey: string): Shop | null => { |
| 193 | + if(!shopKey) { |
| 194 | + return null; |
| 195 | + } |
| 196 | + |
| 197 | + return shopMap[shopKey] || null; |
| 198 | +}; |
| 199 | + |
| 200 | + |
| 201 | +export const findQuest = (questId: string): Quest | null => { |
| 202 | + return questMap[Object.keys(questMap).find(quest => quest.toLocaleLowerCase() === questId.toLocaleLowerCase())] || null; |
| 203 | +}; |
| 204 | + |
| 205 | +export const findMusicTrack = (trackId: number): MusicTrack | null => { |
| 206 | + return musicRegions.find(track => track.songId === trackId) || null; |
| 207 | +}; |
| 208 | + |
| 209 | +export const findMusicTrackByButtonId = (buttonId: number): MusicTrack | null => { |
| 210 | + return musicRegions.find(track => track.musicTabButtonId === buttonId) || null; |
| 211 | +}; |
| 212 | + |
| 213 | +export const findSongIdByRegionId = (regionId: number): number | null => { |
| 214 | + return musicRegionMap.has(regionId) ? musicRegionMap.get(regionId) : null; |
| 215 | +}; |
0 commit comments