From 0fccff867d3e91e413710183cf65065b89302c2a Mon Sep 17 00:00:00 2001 From: Shaun Date: Sat, 8 Jan 2022 07:07:50 +0200 Subject: [PATCH] initial commit --- .gitignore | 1 + src/client/js/rendering/renderer.js | 120 ++-- src/client/js/rendering/textures.js | 27 + src/client/js/rendering/tileOpacity.js | 31 +- src/server/components/aggro.js | 2 +- src/server/components/chest.js | 2 +- src/server/components/effects.js | 4 +- src/server/components/equipment.js | 20 +- src/server/components/gatherer.js | 4 +- src/server/components/inventory.js | 18 +- src/server/components/inventory/getItem.js | 6 +- src/server/components/inventory/useItem.js | 2 +- src/server/components/sound.js | 2 +- src/server/components/spellbook.js | 10 +- src/server/components/stats.js | 4 +- src/server/components/syncer.js | 2 +- src/server/components/trade.js | 4 +- src/server/components/wardrobe.js | 2 +- src/server/components/workbench.js | 4 +- .../components/workbench/buildNeedItems.js | 4 +- src/server/config/clientConfig.js | 33 +- .../config/quests/templates/questKillX.js | 2 +- src/server/config/serverConfig.js | 2 +- src/server/config/spells/spellTemplate.js | 2 +- src/server/events/events.js | 2 +- src/server/items/generators/quality.js | 2 +- src/server/items/salvager.js | 2 +- src/server/misc/helpers.js | 2 +- src/server/mods/class-necromancer/index.js | 4 +- src/server/mods/feature-cards/index.js | 5 - src/server/objects/objBase.js | 4 +- src/server/package-lock.json | 579 ++++++++++++++++++ src/server/package.json | 1 + src/server/security/connections.js | 4 +- src/server/world/instancer.js | 32 +- src/server/world/map.js | 194 +----- src/server/world/map/builders/object.js | 157 +++++ src/server/world/map/builders/tile.js | 42 ++ .../world/map/getObjectifiedProperties.js | 17 + src/server/world/mobBuilder.js | 4 +- src/server/world/spriteBuilder/index.js | 117 ++++ src/server/world/worker.js | 4 +- 42 files changed, 1126 insertions(+), 354 deletions(-) create mode 100644 src/client/js/rendering/textures.js create mode 100644 src/server/world/map/builders/object.js create mode 100644 src/server/world/map/builders/tile.js create mode 100644 src/server/world/map/getObjectifiedProperties.js create mode 100644 src/server/world/spriteBuilder/index.js diff --git a/.gitignore b/.gitignore index 6d4b9fc1..f50c995f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules package-lock.json +src/client/images/temp storage.db *.sublime-project diff --git a/src/client/js/rendering/renderer.js b/src/client/js/rendering/renderer.js index 71a567fa..ac145ca2 100644 --- a/src/client/js/rendering/renderer.js +++ b/src/client/js/rendering/renderer.js @@ -9,7 +9,8 @@ define([ 'js/rendering/spritePool', 'js/system/globals', 'js/rendering/renderLoginBackground', - 'js/rendering/helpers/resetRenderer' + 'js/rendering/helpers/resetRenderer', + 'js/rendering/textures' ], function ( resources, events, @@ -21,7 +22,8 @@ define([ spritePool, globals, renderLoginBackground, - resetRenderer + resetRenderer, + textures ) { const mRandom = Math.random.bind(Math); @@ -120,6 +122,7 @@ define([ textureList.forEach(t => { this.textures[t] = new PIXI.BaseTexture(sprites[t]); this.textures[t].scaleMode = PIXI.SCALE_MODES.NEAREST; + this.textures[t].size = this.textures[t].width / 8; }); particleLayers.forEach(p => { @@ -132,39 +135,6 @@ define([ particleEngines[p] = engine; }); - - this.buildSpritesTexture(); - }, - - buildSpritesTexture: function () { - const { clientConfig: { atlasTextureDimensions, atlasTextures } } = globals; - - let container = new PIXI.Container(); - - let totalHeight = 0; - atlasTextures.forEach(t => { - let texture = this.textures[t]; - let tile = new PIXI.Sprite(new PIXI.Texture(texture)); - tile.width = texture.width; - tile.height = texture.height; - tile.x = 0; - tile.y = totalHeight; - - atlasTextureDimensions[t] = { - w: texture.width / 8, - h: texture.height / 8 - }; - - container.addChild(tile); - - totalHeight += tile.height; - }); - - let renderTexture = PIXI.RenderTexture.create(this.textures.tiles.width, totalHeight); - this.renderer.render(container, renderTexture); - - this.textures.sprites = renderTexture; - this.textures.scaleMult = PIXI.SCALE_MODES.NEAREST; }, toggleScreen: function () { @@ -184,7 +154,7 @@ define([ buildTitleScreen: function () { this.titleScreen = true; - renderLoginBackground(this); + //renderLoginBackground(this); }, onResize: function () { @@ -213,22 +183,28 @@ define([ events.emit('onResize'); }, - getTexture: function (baseTex, cell, size) { - size = size || 8; - let textureName = baseTex + '_' + cell; + getTexture: function (baseTex, cell) { + try { + let textureName = baseTex + '_' + cell; - let textureCache = this.textureCache; + let textureCache = this.textureCache; - let cached = textureCache[textureName]; + let cached = textureCache[textureName]; - if (!cached) { - let y = ~~(cell / 8); - let x = cell - (y * 8); - cached = new PIXI.Texture(this.textures[baseTex], new PIXI.Rectangle(x * size, y * size, size, size)); - textureCache[textureName] = cached; - } + if (!cached) { + let y = ~~(cell / 8); + let x = cell - (y * 8); + const texture = this.textures[baseTex]; + const size = texture.size; - return cached; + cached = new PIXI.Texture(texture, new PIXI.Rectangle(x * size, y * size, size, size)); + textureCache[textureName] = cached; + } + + return cached; + } catch (e) { + console.log(e, baseTex, cell); + } }, clean: function () { @@ -240,7 +216,7 @@ define([ let container = this.layers.tileSprites; this.stage.removeChild(container); - this.layers.tileSprites = container = new PIXI.Container(); + this.layers.tileSprites = container = new PIXI.ParticleContainer(30000); container.layer = 'tiles'; this.stage.addChild(container); @@ -255,6 +231,8 @@ define([ return 1; return 0; }); + + this.textureCache = {}; }, buildTile: function (c, i, j) { @@ -277,7 +255,23 @@ define([ return tile; }, - onGetMap: function (msg) { + onGetMap: async function (msg) { + tileOpacity.initMap(msg); + + //Load sprite atlas + let spriteAtlas = null; + await new Promise(res => { + spriteAtlas = new Image(); + spriteAtlas.onload = res; + spriteAtlas.src = msg.spriteAtlasPath; + }); + + //Build sprite texture + this.textures.sprites = new PIXI.BaseTexture(spriteAtlas); + this.textures.sprites.scaleMode = PIXI.SCALE_MODES.NEAREST; + this.textures.sprites.size = 8; + + //Misc this.titleScreen = false; physics.init(msg.collisionMap); @@ -793,20 +787,36 @@ define([ particleEngine.destroyEmitter(emitter); }, - setSprite: function (obj) { + loadTexture: async function (textureName, texturePath) { + texturePath = texturePath ?? textureName; + + if (!texturePath.includes('.png')) + texturePath = `images/${texturePath}.png`; + + const image = await textures.getLoader(texturePath); + + //Build sprite texture + this.textures[textureName] = new PIXI.BaseTexture(image); + this.textures[textureName].scaleMode = PIXI.SCALE_MODES.NEAREST; + this.textures[textureName].size = this.textures[textureName].width / 8; + }, + + setSprite: async function (obj) { const { sprite, sheetName, cell } = obj; - const bigSheets = globals.clientConfig.bigTextures; - const isBigSheet = bigSheets.includes(sheetName); + const textureExists = this.textures.hasOwnProperty(sheetName); + if (!textureExists) + await this.loadTexture(sheetName); + + sprite.texture = this.getTexture(sheetName, cell); - const newSize = isBigSheet ? 24 : 8; + const newSize = sprite.texture.width; obj.w = newSize * scaleMult; obj.h = obj.w; sprite.width = obj.w; sprite.height = obj.h; - sprite.texture = this.getTexture(sheetName, cell, newSize); if (newSize !== sprite.size) { sprite.size = newSize; diff --git a/src/client/js/rendering/textures.js b/src/client/js/rendering/textures.js new file mode 100644 index 00000000..95f49cef --- /dev/null +++ b/src/client/js/rendering/textures.js @@ -0,0 +1,27 @@ +define([ + +], function ( + +) { + const loaders = {}; + + return { + getLoader: async path => { + if (loaders[path]) + return loaders[path]; + + loaders[path] = new Promise(async resOuter => { + let image = null; + await new Promise(resInner => { + image = new Image(); + image.onload = resInner; + image.src = path; + }); + + resOuter(image); + }); + + return loaders[path]; + } + }; +}); diff --git a/src/client/js/rendering/tileOpacity.js b/src/client/js/rendering/tileOpacity.js index d7491518..7680858f 100644 --- a/src/client/js/rendering/tileOpacity.js +++ b/src/client/js/rendering/tileOpacity.js @@ -3,7 +3,15 @@ define([ ], function ( globals ) { + let noFlipTiles = null; + let tileOpacities = null; + return { + initMap: function (msg) { + noFlipTiles = msg.noFlipTiles; + tileOpacities = msg.tileOpacities; + }, + getSheetNum: function (tile) { if (tile < 224) return 0; @@ -47,15 +55,13 @@ define([ }, map: function (tile) { - const { clientConfig: { tileOpacities } } = globals; - - const { offset, sheetName } = this.getOffsetAndSheet(tile); - const mappedTile = tile - offset; + if (tileOpacities[tile] === undefined) + return 1; - const opacityConfig = tileOpacities[sheetName] || tileOpacities.default; + const { max, opacity } = tileOpacities[tile]; - let alpha = (opacityConfig[mappedTile] || opacityConfig.default); - if (opacityConfig.max !== null) { + let alpha = opacity; + if (max !== undefined) { alpha = alpha + (Math.random() * (alpha * 0.2)); alpha = Math.min(1, alpha); } @@ -64,16 +70,7 @@ define([ }, canFlip: function (tile) { - const { clientConfig: { tilesNoFlip } } = globals; - - const { offset, sheetName } = this.getOffsetAndSheet(tile); - const mappedTile = tile - offset; - - const noFlipTiles = tilesNoFlip[sheetName]; - if (!noFlipTiles) - return true; - - return !noFlipTiles.includes(mappedTile); + return !noFlipTiles.includes(tile + 1); } }; }); diff --git a/src/server/components/aggro.js b/src/server/components/aggro.js index df67e17b..430ee896 100644 --- a/src/server/components/aggro.js +++ b/src/server/components/aggro.js @@ -31,7 +31,7 @@ module.exports = { this.faction = blueprint.faction; //TODO: Why don't we move if faction is null? - if (!this.has('faction')) + if (!this.isDefined('faction')) return; if (this.physics.width > 0) diff --git a/src/server/components/chest.js b/src/server/components/chest.js index 6f66402f..9df69cb6 100644 --- a/src/server/components/chest.js +++ b/src/server/components/chest.js @@ -6,7 +6,7 @@ module.exports = { ttl: -1, init: function (blueprint) { - if (blueprint.has('ownerName')) + if (blueprint.isDefined('ownerName')) this.ownerName = blueprint.ownerName; if (blueprint.ttl) diff --git a/src/server/components/effects.js b/src/server/components/effects.js index 59656719..ecd328c5 100644 --- a/src/server/components/effects.js +++ b/src/server/components/effects.js @@ -126,7 +126,7 @@ module.exports = { }, canApplyEffect: function (type) { - if (!this.ccResistances.has(type)) + if (!this.ccResistances.isDefined(type)) return true; let ccResistances = this.ccResistances; @@ -138,7 +138,7 @@ module.exports = { addEffect: function (options, source) { //Skip 0-duration effects - if ((options.has('ttl')) && (options.ttl === 0)) + if ((options.isDefined('ttl')) && (options.ttl === 0)) return; options.caster = options.caster || source; diff --git a/src/server/components/equipment.js b/src/server/components/equipment.js index e7bc2a05..75a49a94 100644 --- a/src/server/components/equipment.js +++ b/src/server/components/equipment.js @@ -29,7 +29,7 @@ module.exports = { }, isSlotEmpty: function (slot) { - return !this.eq.has(slot); + return !this.eq.isDefined(slot); }, autoEquip: function (itemId) { @@ -44,7 +44,7 @@ module.exports = { return; } - if (!this.eq.has(item.slot)) { + if (!this.eq.isDefined(item.slot)) { this.equip(itemId); return true; } @@ -71,12 +71,12 @@ module.exports = { if (!slot) slot = item.equipSlot || item.slot; if (slot === 'twoHanded') { - if (this.eq.has('offHand')) + if (this.eq.isDefined('offHand')) this.unequip(this.eq.offHand, true); slot = 'oneHanded'; } else if (slot === 'offHand') { - if (this.eq.has('oneHanded')) { + if (this.eq.isDefined('oneHanded')) { let oneHandedEq = inventory.findItem(this.eq.oneHanded); if (oneHandedEq.slot === 'twoHanded') this.unequip(this.eq.oneHanded, true); @@ -98,8 +98,8 @@ module.exports = { delete item.pos; if (slot === 'finger') { - let f1 = (this.eq.has('finger-1')); - let f2 = (this.eq.has('finger-2')); + let f1 = (this.eq.isDefined('finger-1')); + let f2 = (this.eq.isDefined('finger-2')); if ((f1) && (f2)) slot = 'finger-1'; @@ -109,7 +109,7 @@ module.exports = { slot = 'finger-2'; } - if (this.eq.has(slot)) { + if (this.eq.isDefined(slot)) { if (this.eq[slot] === item.id) return; @@ -142,7 +142,7 @@ module.exports = { let obj = this.obj; let inventory = obj.inventory; - if (typeof(item) !== 'object' || !item.has('id')) + if (typeof(item) !== 'object' || !item.isDefined('id')) item = inventory.findItem(itemId); if (!item) @@ -186,7 +186,7 @@ module.exports = { let obj = this.obj; const inventory = obj.inventory; - if (!msg.has('itemId') && this.quickSlots.has(msg.slot)) { + if (!msg.isDefined('itemId') && this.quickSlots.isDefined(msg.slot)) { let currentQuickItem = inventory.findItem(this.quickSlots[msg.slot]); if (!currentQuickItem) return; @@ -218,7 +218,7 @@ module.exports = { }, useQuickSlot: function (msg) { - if (!this.quickSlots.has(msg.slot)) + if (!this.quickSlots.isDefined(msg.slot)) return; const inventory = this.obj.inventory; diff --git a/src/server/components/gatherer.js b/src/server/components/gatherer.js index 866c709d..2cc28566 100644 --- a/src/server/components/gatherer.js +++ b/src/server/components/gatherer.js @@ -219,7 +219,7 @@ module.exports = { let nodeType = node.resourceNode.nodeType; if (nodeType === 'fish') { - if (!obj.equipment.eq.has('tool')) { + if (!obj.equipment.eq.isDefined('tool')) { this.sendAnnouncement('You need a fishing rod to fish'); return; @@ -318,7 +318,7 @@ module.exports = { continue; if (node.resourceNode.nodeType === 'fish') { - if (!this.obj.equipment.eq.has('tool')) { + if (!this.obj.equipment.eq.isDefined('tool')) { this.sendAnnouncement('You need a fishing rod to fish'); if (this.gathering === node) { diff --git a/src/server/components/inventory.js b/src/server/components/inventory.js index 7c4a9abc..8a11011d 100644 --- a/src/server/components/inventory.js +++ b/src/server/components/inventory.js @@ -25,8 +25,8 @@ module.exports = { //Spells should be sorted so they're EQ'd in the right order items.sort(function (a, b) { - let aId = a.has('spellId') ? ~~a.spellId : 9999; - let bId = b.has('spellId') ? ~~b.spellId : 9999; + let aId = a.isDefined('spellId') ? ~~a.spellId : 9999; + let bId = b.isDefined('spellId') ? ~~b.spellId : 9999; return (aId - bId); }); @@ -49,7 +49,7 @@ module.exports = { for (let i = 0; i < iLen; i++) { let item = items[i]; - let pos = item.has('pos') ? item.pos : null; + let pos = item.isDefined('pos') ? item.pos : null; let newItem = this.getItem(item, true, true); newItem.pos = pos; @@ -146,7 +146,7 @@ module.exports = { }, learnAbility: function (itemId, runeSlot) { - if (itemId.has('itemId')) { + if (itemId.isDefined('itemId')) { let msg = itemId; itemId = msg.itemId; runeSlot = msg.slot; @@ -252,7 +252,7 @@ module.exports = { }, unlearnAbility: function (itemId) { - if (itemId.has('itemId')) + if (itemId.isDefined('itemId')) itemId = itemId.itemId; let item = this.findItem(itemId); @@ -348,7 +348,7 @@ module.exports = { if ((!item) || (item.noDrop) || (item.quest)) return; - if (item.has('quickSlot')) { + if (item.isDefined('quickSlot')) { this.obj.equipment.setQuickSlot({ itemId: null, slot: item.quickSlot @@ -416,7 +416,7 @@ module.exports = { }); } - if (!item.has('pos') && !item.eq) { + if (!item.isDefined('pos') && !item.eq) { let pos = i; for (let j = 0; j < iLen; j++) { if (!items.some(fj => (fj.pos === j))) { @@ -478,7 +478,7 @@ module.exports = { }, resolveCallback: function (msg, result) { - let callbackId = msg.has('callbackId') ? msg.callbackId : msg; + let callbackId = msg.isDefined('callbackId') ? msg.callbackId : msg; result = result || []; if (!callbackId) @@ -506,7 +506,7 @@ module.exports = { return ( i.spell && i.spell.rolls && - i.spell.rolls.has('damage') && + i.spell.rolls.isDefined('damage') && ( i.slot === 'twoHanded' || i.slot === 'oneHanded' diff --git a/src/server/components/inventory/getItem.js b/src/server/components/inventory/getItem.js index 4abedb09..426d721d 100644 --- a/src/server/components/inventory/getItem.js +++ b/src/server/components/inventory/getItem.js @@ -33,7 +33,7 @@ module.exports = (cpnInv, item, hideMessage, noStack, hideAlert, createBagIfFull //We need to know if a mob dropped it for quest purposes let fromMob = item.fromMob; - if (!item.has('quality')) + if (!item.isDefined('quality')) item.quality = 0; //Store the quantity to send to the player @@ -69,7 +69,7 @@ module.exports = (cpnInv, item, hideMessage, noStack, hideAlert, createBagIfFull if (item.eq) delete item.pos; - if (!item.has('pos') && !item.eq) { + if (!item.isDefined('pos') && !item.eq) { const iLen = items.length; let pos = iLen; for (let i = 0; i < iLen; i++) { @@ -129,7 +129,7 @@ module.exports = (cpnInv, item, hideMessage, noStack, hideAlert, createBagIfFull delete item.eq; obj.equipment.equip(item.id); } - } else if (item.has('quickSlot')) { + } else if (item.isDefined('quickSlot')) { obj.equipment.setQuickSlot({ itemId: item.id, slot: item.quickSlot diff --git a/src/server/components/inventory/useItem.js b/src/server/components/inventory/useItem.js index a9351994..638d80ec 100644 --- a/src/server/components/inventory/useItem.js +++ b/src/server/components/inventory/useItem.js @@ -108,7 +108,7 @@ module.exports = async (cpnInv, itemId) => { } cpnInv.destroyItem(itemId, 1); - if (item.has('quickSlot')) + if (item.isDefined('quickSlot')) cpnInv.obj.equipment.replaceQuickSlot(item); } }; diff --git a/src/server/components/sound.js b/src/server/components/sound.js index 050dd714..b049e161 100644 --- a/src/server/components/sound.js +++ b/src/server/components/sound.js @@ -14,7 +14,7 @@ module.exports = { const s = Object.fromEntries( serializeProps .map(p => { - if (!this.has(p)) + if (!this.isDefined(p)) return null; return [p, this[p]]; diff --git a/src/server/components/spellbook.js b/src/server/components/spellbook.js index 4f15ea71..0b456ca1 100644 --- a/src/server/components/spellbook.js +++ b/src/server/components/spellbook.js @@ -146,7 +146,7 @@ module.exports = { this.furthestRange = builtSpell.range; } - if ((!options.has('id')) && (spellId === -1)) { + if ((!options.isDefined('id')) && (spellId === -1)) { spellId = 0; this.spells.forEach(function (s) { if (s.id >= spellId) @@ -154,7 +154,7 @@ module.exports = { }); } - builtSpell.id = !options.has('id') ? spellId : options.id; + builtSpell.id = !options.isDefined('id') ? spellId : options.id; //Mobs don't get abilities put on CD when they learn them if (!this.obj.mob && builtSpell.cdMax) @@ -322,7 +322,7 @@ module.exports = { }, canCast: function (action) { - if (!action.has('spell')) + if (!action.isDefined('spell')) return false; let spell = this.spells.find(s => (s.id === action.spell)); @@ -336,7 +336,7 @@ module.exports = { }, cast: function (action, isAuto) { - if (!action.has('spell')) { + if (!action.isDefined('spell')) { const isCasting = this.isCasting(); this.stopCasting(); @@ -368,7 +368,7 @@ module.exports = { if (!isAuto) this.sendAnnouncement('Insufficient mana to cast spell'); success = false; - } else if (spell.has('range')) { + } else if (spell.isDefined('range')) { let distance = Math.max(Math.abs(action.target.x - this.obj.x), Math.abs(action.target.y - this.obj.y)); let range = spell.range; if ((spell.useWeaponRange) && (this.obj.player)) { diff --git a/src/server/components/stats.js b/src/server/components/stats.js index 1b094f5f..d81d91c8 100644 --- a/src/server/components/stats.js +++ b/src/server/components/stats.js @@ -453,7 +453,7 @@ module.exports = { for (let i = 0; i < aLen; i++) { let a = aggroList[i]; - if (a.damage <= 0 || !a.obj.has('serverId')) + if (a.damage <= 0 || !a.obj.isDefined('serverId')) continue; obj.inventory.dropBag(a.obj.name, killSource); @@ -602,7 +602,7 @@ module.exports = { return; let threatMult = heal.threatMult; - if (!heal.has('threatMult')) + if (!heal.isDefined('threatMult')) threatMult = 1; let values = this.values; diff --git a/src/server/components/syncer.js b/src/server/components/syncer.js index 6a41de6d..9a08f390 100644 --- a/src/server/components/syncer.js +++ b/src/server/components/syncer.js @@ -163,7 +163,7 @@ module.exports = { if (self) o = this.oSelf; - if (!o.has(property)) + if (!o.isDefined(property)) o[property] = []; o[property].push(value); diff --git a/src/server/components/trade.js b/src/server/components/trade.js index 4af96e40..2813800c 100644 --- a/src/server/components/trade.js +++ b/src/server/components/trade.js @@ -111,7 +111,7 @@ module.exports = { }, startBuy: function (msg) { - if (!msg.has('target') && !msg.targetName) + if (!msg.isDefined('target') && !msg.targetName) return false; let target = msg.target; @@ -353,7 +353,7 @@ module.exports = { }, resolveCallback: function (msg, result) { - let callbackId = msg.has('callbackId') ? msg.callbackId : msg; + let callbackId = msg.isDefined('callbackId') ? msg.callbackId : msg; result = result || []; if (!callbackId) diff --git a/src/server/components/wardrobe.js b/src/server/components/wardrobe.js index 71211ec3..ea65a2e3 100644 --- a/src/server/components/wardrobe.js +++ b/src/server/components/wardrobe.js @@ -77,7 +77,7 @@ module.exports = { }, open: function (msg) { - if (!msg.has('sourceId')) + if (!msg.isDefined('sourceId')) return; let obj = this.obj.instance.objects.objects.find(o => o.serverId === msg.sourceId); diff --git a/src/server/components/workbench.js b/src/server/components/workbench.js index ffb16682..daf26afa 100644 --- a/src/server/components/workbench.js +++ b/src/server/components/workbench.js @@ -79,7 +79,7 @@ module.exports = { }, open: async function (msg) { - if (!msg.has('sourceId')) + if (!msg.isDefined('sourceId')) return; let obj = this.obj.instance.objects.objects.find(o => o.serverId === msg.sourceId); @@ -121,7 +121,7 @@ module.exports = { }, resolveCallback: function (msg, result) { - let callbackId = (msg.has('callbackId')) ? msg.callbackId : msg; + let callbackId = (msg.isDefined('callbackId')) ? msg.callbackId : msg; result = result || []; if (!callbackId) diff --git a/src/server/components/workbench/buildNeedItems.js b/src/server/components/workbench/buildNeedItems.js index b81cd8d6..a72ca1e3 100644 --- a/src/server/components/workbench/buildNeedItems.js +++ b/src/server/components/workbench/buildNeedItems.js @@ -8,8 +8,8 @@ module.exports = ({ inventory: { items } }, { needItems }) => { const allowedItemIds = items .filter(item => { const isValidItem = ( - withProps.every(p => item.has(p)) && - withoutProps.every(p => !item.has(p)) && + withProps.every(p => item.isDefined(p)) && + withoutProps.every(p => !item.isDefined(p)) && checks.every(c => c(item)) ); diff --git a/src/server/config/clientConfig.js b/src/server/config/clientConfig.js index 1652297c..6fd461ea 100644 --- a/src/server/config/clientConfig.js +++ b/src/server/config/clientConfig.js @@ -9,36 +9,15 @@ const config = { loginBgGeneratorPath: null, resourceList: [], textureList: [ - 'tiles', - 'walls', - 'mobs', - 'bosses', - 'animBigObjects', - 'bigObjects', - 'objects', - 'characters', - 'attacks', - 'ui', - 'auras', - 'animChar', - 'animMob', - 'animBoss', - 'white', - 'ray' + ], //Textures that are 24x24. The renderer needs to know this bigTextures: [ - 'animBigObjects', - 'animBoss', - 'bigObjects', - 'bosses', - 'auras' + ], atlasTextureDimensions: {}, atlasTextures: [ - 'tiles', - 'walls', - 'objects' + ], spriteSizes: { 'images/tiles.png': 8, @@ -46,9 +25,9 @@ const config = { 'images/objects.png': 8, 'images/mobs.png': 8 }, - blockingTileIndices: [ - 6, 7, 54, 55, 62, 63, 154, 189, 190, 192, 193, 194, 195, 196, 197 - ], + blockingTileIndices: { + tiles: [6, 7, 54, 55, 62, 63, 154, 189, 190, 192, 193, 194, 195, 196, 197] + }, tileOpacities: { default: { default: 0.4, diff --git a/src/server/config/quests/templates/questKillX.js b/src/server/config/quests/templates/questKillX.js index 7a2a78ea..babd2d03 100644 --- a/src/server/config/quests/templates/questKillX.js +++ b/src/server/config/quests/templates/questKillX.js @@ -28,7 +28,7 @@ module.exports = { !mobBlueprint.noQuest && ( mobBlueprint.attackable || - !mobBlueprint.has('attackable') + !mobBlueprint.isDefined('attackable') ) && mobBlueprint.level <= ~~(this.obj.stats.values.level * 1.35) && mobCounts[m] > 1 diff --git a/src/server/config/serverConfig.js b/src/server/config/serverConfig.js index b04099c6..0b728cc0 100644 --- a/src/server/config/serverConfig.js +++ b/src/server/config/serverConfig.js @@ -8,7 +8,7 @@ module.exports = { // sqlite // rethink //eslint-disable-next-line no-process-env - db: process.env.IWD_DB || 'sqlite', + db: process.env.IWD_DB || 'rethink', //eslint-disable-next-line no-process-env dbHost: process.env.IWD_DB_HOST || 'localhost', //eslint-disable-next-line no-process-env diff --git a/src/server/config/spells/spellTemplate.js b/src/server/config/spells/spellTemplate.js index 30ca220f..e9020d12 100644 --- a/src/server/config/spells/spellTemplate.js +++ b/src/server/config/spells/spellTemplate.js @@ -27,7 +27,7 @@ module.exports = { return true; let inRange = true; - if (this.has('range')) { + if (this.isDefined('range')) { let obj = this.obj; let distance = Math.max(Math.abs(target.x - obj.x), Math.abs(target.y - obj.y)); inRange = (distance <= this.range); diff --git a/src/server/events/events.js b/src/server/events/events.js index 89cc1972..082b4a3c 100644 --- a/src/server/events/events.js +++ b/src/server/events/events.js @@ -383,7 +383,7 @@ module.exports = { phase.destroyed = true; continue; } else { - if (phase.has('ttl')) { + if (phase.isDefined('ttl')) { if (phase.ttl === 0) { phase.end = true; continue; diff --git a/src/server/items/generators/quality.js b/src/server/items/generators/quality.js index 0f9cceba..d1cfe039 100644 --- a/src/server/items/generators/quality.js +++ b/src/server/items/generators/quality.js @@ -10,7 +10,7 @@ module.exports = { magicFindMult: 7, generate: function (item, blueprint) { - if (blueprint.has('quality')) { + if (blueprint.isDefined('quality')) { item.quality = ~~blueprint.quality; return; } diff --git a/src/server/items/salvager.js b/src/server/items/salvager.js index bc0b2233..a1aceb53 100644 --- a/src/server/items/salvager.js +++ b/src/server/items/salvager.js @@ -146,7 +146,7 @@ module.exports = { if (m.qualityName) { newItem.quality = item.quality; newItem.name = m.qualityName[item.quality]; - } else if (m.has('quality')) + } else if (m.isDefined('quality')) newItem.quality = m.quality; newItem.sprite = materialItems[newItem.name].sprite; diff --git a/src/server/misc/helpers.js b/src/server/misc/helpers.js index ed9d473f..c115b1a4 100644 --- a/src/server/misc/helpers.js +++ b/src/server/misc/helpers.js @@ -51,7 +51,7 @@ Object.defineProperty(Array.prototype, 'spliceFirstWhere', { }); //eslint-disable-next-line no-extend-native -Object.defineProperty(Object.prototype, 'has', { +Object.defineProperty(Object.prototype, 'isDefined', { enumerable: false, value: function (prop) { //eslint-disable-next-line no-undefined diff --git a/src/server/mods/class-necromancer/index.js b/src/server/mods/class-necromancer/index.js index db4823e2..765b1641 100644 --- a/src/server/mods/class-necromancer/index.js +++ b/src/server/mods/class-necromancer/index.js @@ -75,10 +75,8 @@ module.exports = { }; }, - onBeforeGetClientConfig: function ({ resourceList, textureList }) { + onBeforeGetClientConfig: function ({ resourceList }) { resourceList.push(`${this.folderName}/images/abilityIcons.png`); - - textureList.push(`${this.folderName}/images/mobs.png`); }, beforeGetSpellTemplate: function (spell) { diff --git a/src/server/mods/feature-cards/index.js b/src/server/mods/feature-cards/index.js index 60b1dc11..57dadd7d 100644 --- a/src/server/mods/feature-cards/index.js +++ b/src/server/mods/feature-cards/index.js @@ -6,17 +6,12 @@ module.exports = { name: 'Feature: Cards', init: function () { - this.events.on('onBeforeGetClientConfig', this.onBeforeGetClientConfig.bind(this)); this.events.on('onBeforeDropBag', this.onBeforeDropBag.bind(this)); this.events.on('onBeforeGetRecipes', this.onBeforeGetRecipes.bind(this)); this.events.on('onAfterGetZone', this.onAfterGetZone.bind(this)); this.events.on('onAfterGetLayerObjects', this.onAfterGetLayerObjects.bind(this)); }, - onBeforeGetClientConfig: function (config) { - config.textureList.push(`${this.folderName}/images/mobs.png`); - }, - onAfterGetZone: function (zoneName, config) { const { zoneName: dealerZoneName, zoneConfig } = dealer; const dealerName = zoneConfig.name.toLowerCase(); diff --git a/src/server/objects/objBase.js b/src/server/objects/objBase.js index 699c1caf..ac35b61c 100644 --- a/src/server/objects/objBase.js +++ b/src/server/objects/objBase.js @@ -24,7 +24,7 @@ module.exports = { this[cpn.type] = cpn; } - if (cpn.init && this.has('instance')) + if (cpn.init && this.isDefined('instance')) cpn.init(blueprint || {}, isTransfer); else { for (let p in blueprint) @@ -220,7 +220,7 @@ module.exports = { }, clearQueue: function () { - if (this.has('serverId')) { + if (this.isDefined('serverId')) { this.instance.syncer.queue('onClearQueue', { id: this.id }, [this.serverId]); diff --git a/src/server/package-lock.json b/src/server/package-lock.json index 0e099441..4e11562c 100644 --- a/src/server/package-lock.json +++ b/src/server/package-lock.json @@ -85,6 +85,14 @@ "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", "dev": true }, + "@babel/runtime": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", + "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, "@babel/template": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", @@ -230,6 +238,327 @@ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", "dev": true }, + "@jimp/bmp": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.16.1.tgz", + "integrity": "sha512-iwyNYQeBawrdg/f24x3pQ5rEx+/GwjZcCXd3Kgc+ZUd+Ivia7sIqBsOnDaMZdKCBPlfW364ekexnlOqyVa0NWg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "bmp-js": "^0.1.0" + } + }, + "@jimp/core": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.16.1.tgz", + "integrity": "sha512-la7kQia31V6kQ4q1kI/uLimu8FXx7imWVajDGtwUG8fzePLWDFJyZl0fdIXVCL1JW2nBcRHidUot6jvlRDi2+g==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "exif-parser": "^0.1.12", + "file-type": "^9.0.0", + "load-bmfont": "^1.3.1", + "mkdirp": "^0.5.1", + "phin": "^2.9.1", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/custom": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.16.1.tgz", + "integrity": "sha512-DNUAHNSiUI/j9hmbatD6WN/EBIyeq4AO0frl5ETtt51VN1SvE4t4v83ZA/V6ikxEf3hxLju4tQ5Pc3zmZkN/3A==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/core": "^0.16.1" + } + }, + "@jimp/gif": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.16.1.tgz", + "integrity": "sha512-r/1+GzIW1D5zrP4tNrfW+3y4vqD935WBXSc8X/wm23QTY9aJO9Lw6PEdzpYCEY+SOklIFKaJYUAq/Nvgm/9ryw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "gifwrap": "^0.9.2", + "omggif": "^1.0.9" + } + }, + "@jimp/jpeg": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.1.tgz", + "integrity": "sha512-8352zrdlCCLFdZ/J+JjBslDvml+fS3Z8gttdml0We759PnnZGqrnPRhkOEOJbNUlE+dD4ckLeIe6NPxlS/7U+w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "jpeg-js": "0.4.2" + } + }, + "@jimp/plugin-blit": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.16.1.tgz", + "integrity": "sha512-fKFNARm32RoLSokJ8WZXHHH2CGzz6ire2n1Jh6u+XQLhk9TweT1DcLHIXwQMh8oR12KgjbgsMGvrMVlVknmOAg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-blur": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.16.1.tgz", + "integrity": "sha512-1WhuLGGj9MypFKRcPvmW45ht7nXkOKu+lg3n2VBzIB7r4kKNVchuI59bXaCYQumOLEqVK7JdB4glaDAbCQCLyw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-circle": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.16.1.tgz", + "integrity": "sha512-JK7yi1CIU7/XL8hdahjcbGA3V7c+F+Iw+mhMQhLEi7Q0tCnZ69YJBTamMiNg3fWPVfMuvWJJKOBRVpwNTuaZRg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-color": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.16.1.tgz", + "integrity": "sha512-9yQttBAO5SEFj7S6nJK54f+1BnuBG4c28q+iyzm1JjtnehjqMg6Ljw4gCSDCvoCQ3jBSYHN66pmwTV74SU1B7A==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/plugin-contain": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.16.1.tgz", + "integrity": "sha512-44F3dUIjBDHN+Ym/vEfg+jtjMjAqd2uw9nssN67/n4FdpuZUVs7E7wadKY1RRNuJO+WgcD5aDQcsvurXMETQTg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-cover": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.16.1.tgz", + "integrity": "sha512-YztWCIldBAVo0zxcQXR+a/uk3/TtYnpKU2CanOPJ7baIuDlWPsG+YE4xTsswZZc12H9Kl7CiziEbDtvF9kwA/Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-crop": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.16.1.tgz", + "integrity": "sha512-UQdva9oQzCVadkyo3T5Tv2CUZbf0klm2cD4cWMlASuTOYgaGaFHhT9st+kmfvXjKL8q3STkBu/zUPV6PbuV3ew==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-displace": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.16.1.tgz", + "integrity": "sha512-iVAWuz2+G6Heu8gVZksUz+4hQYpR4R0R/RtBzpWEl8ItBe7O6QjORAkhxzg+WdYLL2A/Yd4ekTpvK0/qW8hTVw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-dither": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.16.1.tgz", + "integrity": "sha512-tADKVd+HDC9EhJRUDwMvzBXPz4GLoU6s5P7xkVq46tskExYSptgj5713J5Thj3NMgH9Rsqu22jNg1H/7tr3V9Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-fisheye": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.16.1.tgz", + "integrity": "sha512-BWHnc5hVobviTyIRHhIy9VxI1ACf4CeSuCfURB6JZm87YuyvgQh5aX5UDKtOz/3haMHXBLP61ZBxlNpMD8CG4A==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-flip": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.16.1.tgz", + "integrity": "sha512-KdxTf0zErfZ8DyHkImDTnQBuHby+a5YFdoKI/G3GpBl3qxLBvC+PWkS2F/iN3H7wszP7/TKxTEvWL927pypT0w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-gaussian": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.16.1.tgz", + "integrity": "sha512-u9n4wjskh3N1mSqketbL6tVcLU2S5TEaFPR40K6TDv4phPLZALi1Of7reUmYpVm8mBDHt1I6kGhuCJiWvzfGyg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-invert": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.16.1.tgz", + "integrity": "sha512-2DKuyVXANH8WDpW9NG+PYFbehzJfweZszFYyxcaewaPLN0GxvxVLOGOPP1NuUTcHkOdMFbE0nHDuB7f+sYF/2w==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-mask": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.16.1.tgz", + "integrity": "sha512-snfiqHlVuj4bSFS0v96vo2PpqCDMe4JB+O++sMo5jF5mvGcGL6AIeLo8cYqPNpdO6BZpBJ8MY5El0Veckhr39Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-normalize": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.16.1.tgz", + "integrity": "sha512-dOQfIOvGLKDKXPU8xXWzaUeB0nvkosHw6Xg1WhS1Z5Q0PazByhaxOQkSKgUryNN/H+X7UdbDvlyh/yHf3ITRaw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-print": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.16.1.tgz", + "integrity": "sha512-ceWgYN40jbN4cWRxixym+csyVymvrryuKBQ+zoIvN5iE6OyS+2d7Mn4zlNgumSczb9GGyZZESIgVcBDA1ezq0Q==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "load-bmfont": "^1.4.0" + } + }, + "@jimp/plugin-resize": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.16.1.tgz", + "integrity": "sha512-u4JBLdRI7dargC04p2Ha24kofQBk3vhaf0q8FwSYgnCRwxfvh2RxvhJZk9H7Q91JZp6wgjz/SjvEAYjGCEgAwQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-rotate": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.16.1.tgz", + "integrity": "sha512-ZUU415gDQ0VjYutmVgAYYxC9Og9ixu2jAGMCU54mSMfuIlmohYfwARQmI7h4QB84M76c9hVLdONWjuo+rip/zg==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-scale": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.16.1.tgz", + "integrity": "sha512-jM2QlgThIDIc4rcyughD5O7sOYezxdafg/2Xtd1csfK3z6fba3asxDwthqPZAgitrLgiKBDp6XfzC07Y/CefUw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-shadow": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.16.1.tgz", + "integrity": "sha512-MeD2Is17oKzXLnsphAa1sDstTu6nxscugxAEk3ji0GV1FohCvpHBcec0nAq6/czg4WzqfDts+fcPfC79qWmqrA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugin-threshold": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.16.1.tgz", + "integrity": "sha512-iGW8U/wiCSR0+6syrPioVGoSzQFt4Z91SsCRbgNKTAk7D+XQv6OI78jvvYg4o0c2FOlwGhqz147HZV5utoSLxA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1" + } + }, + "@jimp/plugins": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.16.1.tgz", + "integrity": "sha512-c+lCqa25b+4q6mJZSetlxhMoYuiltyS+ValLzdwK/47+aYsq+kcJNl+TuxIEKf59yr9+5rkbpsPkZHLF/V7FFA==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/plugin-blit": "^0.16.1", + "@jimp/plugin-blur": "^0.16.1", + "@jimp/plugin-circle": "^0.16.1", + "@jimp/plugin-color": "^0.16.1", + "@jimp/plugin-contain": "^0.16.1", + "@jimp/plugin-cover": "^0.16.1", + "@jimp/plugin-crop": "^0.16.1", + "@jimp/plugin-displace": "^0.16.1", + "@jimp/plugin-dither": "^0.16.1", + "@jimp/plugin-fisheye": "^0.16.1", + "@jimp/plugin-flip": "^0.16.1", + "@jimp/plugin-gaussian": "^0.16.1", + "@jimp/plugin-invert": "^0.16.1", + "@jimp/plugin-mask": "^0.16.1", + "@jimp/plugin-normalize": "^0.16.1", + "@jimp/plugin-print": "^0.16.1", + "@jimp/plugin-resize": "^0.16.1", + "@jimp/plugin-rotate": "^0.16.1", + "@jimp/plugin-scale": "^0.16.1", + "@jimp/plugin-shadow": "^0.16.1", + "@jimp/plugin-threshold": "^0.16.1", + "timm": "^1.6.1" + } + }, + "@jimp/png": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.16.1.tgz", + "integrity": "sha512-iyWoCxEBTW0OUWWn6SveD4LePW89kO7ZOy5sCfYeDM/oTPLpR8iMIGvZpZUz1b8kvzFr27vPst4E5rJhGjwsdw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.16.1", + "pngjs": "^3.3.3" + } + }, + "@jimp/tiff": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.16.1.tgz", + "integrity": "sha512-3K3+xpJS79RmSkAvFMgqY5dhSB+/sxhwTFA9f4AVHUK0oKW+u6r52Z1L0tMXHnpbAdR9EJ+xaAl2D4x19XShkQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "utif": "^2.0.1" + } + }, + "@jimp/types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.16.1.tgz", + "integrity": "sha512-g1w/+NfWqiVW4CaXSJyD28JQqZtm2eyKMWPhBBDCJN9nLCN12/Az0WFF3JUAktzdsEC2KRN2AqB1a2oMZBNgSQ==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/bmp": "^0.16.1", + "@jimp/gif": "^0.16.1", + "@jimp/jpeg": "^0.16.1", + "@jimp/png": "^0.16.1", + "@jimp/tiff": "^0.16.1", + "timm": "^1.6.1" + } + }, + "@jimp/utils": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.1.tgz", + "integrity": "sha512-8fULQjB0x4LzUSiSYG6ZtQl355sZjxbv8r9PPAuYHzS9sGiSHJQavNqK/nKnpDsVkU88/vRGcE7t3nMU0dEnVw==", + "requires": { + "@babel/runtime": "^7.7.2", + "regenerator-runtime": "^0.13.3" + } + }, "@types/component-emitter": { "version": "1.2.10", "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", @@ -304,6 +633,11 @@ "color-convert": "^1.9.0" } }, + "any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -357,6 +691,11 @@ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -372,6 +711,11 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, + "bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=" + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -406,6 +750,20 @@ "concat-map": "0.0.1" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -565,6 +923,11 @@ "esutils": "^2.0.2" } }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -958,6 +1321,11 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -1038,6 +1406,11 @@ "flat-cache": "^3.0.4" } }, + "file-type": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -1095,6 +1468,15 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "gifwrap": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", + "integrity": "sha512-fcIswrPaiCDAyO8xnWvHSZdWChjKXUanKKpAiWWJ/UTkEi/aYKn5+90e7DE820zbEaVR9CE2y4z9bzhQijZ0BA==", + "requires": { + "image-q": "^1.1.1", + "omggif": "^1.0.10" + } + }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -1118,6 +1500,15 @@ "is-glob": "^4.0.1" } }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -1150,12 +1541,22 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "image-q": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-q/-/image-q-1.1.1.tgz", + "integrity": "sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY=" + }, "image-size": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", @@ -1212,6 +1613,11 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1227,6 +1633,23 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "jimp": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.1.tgz", + "integrity": "sha512-+EKVxbR36Td7Hfd23wKGIeEyHbxShZDX6L8uJkgVW3ESA9GiTEPK08tG1XI2r/0w5Ch0HyJF5kPqF9K7EmGjaw==", + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/custom": "^0.16.1", + "@jimp/plugins": "^0.16.1", + "@jimp/types": "^0.16.1", + "regenerator-runtime": "^0.13.3" + } + }, + "jpeg-js": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", + "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1271,6 +1694,21 @@ "type-check": "~0.4.0" } }, + "load-bmfont": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", + "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", + "requires": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^2.9.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -1337,6 +1775,14 @@ "mime-db": "1.43.0" } }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1346,6 +1792,19 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1367,6 +1826,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -1403,6 +1867,11 @@ "word-wrap": "^1.2.3" } }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1412,6 +1881,30 @@ "callsites": "^3.0.0" } }, + "parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=" + }, + "parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=" + }, + "parse-bmfont-xml": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", + "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", + "requires": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.4.5" + } + }, + "parse-headers": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz", + "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1440,6 +1933,24 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "phin": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", + "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" + }, + "pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", + "requires": { + "pngjs": "^3.0.0" + } + }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -1455,6 +1966,11 @@ "fast-diff": "^1.1.2" } }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -1512,6 +2028,11 @@ } } }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -1566,6 +2087,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -1822,6 +2348,16 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "timm": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", + "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -1904,6 +2440,14 @@ "punycode": "^2.1.0" } }, + "utif": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", + "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", + "requires": { + "pako": "^1.0.5" + } + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1951,6 +2495,41 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" }, + "xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=" + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/src/server/package.json b/src/server/package.json index e14d5258..80e7ec26 100644 --- a/src/server/package.json +++ b/src/server/package.json @@ -9,6 +9,7 @@ "express": "^4.17.1", "express-minify": "^1.0.0", "image-size": "^1.0.0", + "jimp": "^0.16.1", "rethinkdbdash": "^2.3.31", "socket.io": "^4.2.0", "universal-analytics": "^0.5.1" diff --git a/src/server/security/connections.js b/src/server/security/connections.js index 6f1b0913..2cd320d2 100644 --- a/src/server/security/connections.js +++ b/src/server/security/connections.js @@ -25,7 +25,7 @@ module.exports = { let sessionDuration = 0; - if (player.has('id')) { + if (player.isDefined('id')) { if (player.social) player.social.dc(); sessionDuration = ~~(((+new Date()) - player.player.sessionStart) / 1000); @@ -49,7 +49,7 @@ module.exports = { onGetDisconnectedPlayer: [player.name] }); - if (player.has('id')) + if (player.isDefined('id')) this.modifyPlayerCount(-1); } diff --git a/src/server/world/instancer.js b/src/server/world/instancer.js index 742f160b..34322b37 100644 --- a/src/server/world/instancer.js +++ b/src/server/world/instancer.js @@ -1,17 +1,18 @@ -let map = require('./map'); -let syncer = require('./syncer'); -let objects = require('../objects/objects'); -let spawners = require('./spawners'); -let physics = require('./physics'); -let resourceSpawner = require('./resourceSpawner'); -let spellCallbacks = require('../config/spells/spellCallbacks'); -let questBuilder = require('../config/quests/questBuilder'); -let events = require('../events/events'); -let scheduler = require('../misc/scheduler'); -let herbs = require('../config/herbs'); -let eventEmitter = require('../misc/events'); +const map = require('./map'); +const syncer = require('./syncer'); +const objects = require('../objects/objects'); +const spawners = require('./spawners'); +const physics = require('./physics'); +const resourceSpawner = require('./resourceSpawner'); +const spellCallbacks = require('../config/spells/spellCallbacks'); +const questBuilder = require('../config/quests/questBuilder'); +const events = require('../events/events'); +const scheduler = require('../misc/scheduler'); +const herbs = require('../config/herbs'); +const eventEmitter = require('../misc/events'); const mods = require('../misc/mods'); const transactions = require('../security/transactions'); +const spriteBuilder = require('./spriteBuilder/index'); //Own helpers const { stageZoneIn, unstageZoneIn, clientAck } = require('./instancer/handshakes'); @@ -26,11 +27,12 @@ module.exports = { lastTime: 0, - init: function (args) { + init: async function (args) { this.zoneId = args.zoneId; spellCallbacks.init(); herbs.init(); + spriteBuilder.init(args.name); map.init(args); const fakeInstance = { @@ -67,6 +69,8 @@ module.exports = { [resourceSpawner, syncer, objects, questBuilder, events].forEach(i => i.init(fakeInstance)); + await spriteBuilder.finalize(); + this.tick(); this.clientAck = clientAck; @@ -208,7 +212,7 @@ module.exports = { if (msg.keepPos && (!physics.isValid(obj.x, obj.y) || !map.canPathFromPos(obj))) msg.keepPos = false; - if (!msg.keepPos || !obj.has('x') || (map.mapFile.properties.isRandom && obj.instanceId !== map.seed)) { + if (!msg.keepPos || !obj.isDefined('x') || (map.mapFile.properties.isRandom && obj.instanceId !== map.seed)) { obj.x = spawnPos.x; obj.y = spawnPos.y; } diff --git a/src/server/world/map.js b/src/server/world/map.js index 07d250e8..a8774ac9 100644 --- a/src/server/world/map.js +++ b/src/server/world/map.js @@ -1,31 +1,23 @@ -let objects = require('../objects/objects'); -let physics = require('./physics'); -let spawners = require('./spawners'); -let resourceSpawner = require('./resourceSpawner'); -let globalZone = require('../config/zoneBase'); -let randomMap = require('./randomMap/randomMap'); +const physics = require('./physics'); +const resourceSpawner = require('./resourceSpawner'); +const globalZone = require('../config/zoneBase'); +const randomMap = require('./randomMap/randomMap'); const generateMappings = require('./randomMap/generateMappings'); -let events = require('../misc/events'); +const events = require('../misc/events'); +const spriteBuilder = require('./spriteBuilder/index'); -const mapObjects = require('./map/mapObjects'); +//Builders +const buildTile = require('./map/builders/tile'); +const buildObject = require('./map/builders/object'); + +//Helpers const canPathFromPos = require('./map/canPathFromPos'); +const getObjectifiedProperties = require('./map/getObjectifiedProperties'); let mapFile = null; let mapScale = null; let padding = null; -const objectifyProperties = oldProperties => { - if (!oldProperties || !oldProperties.push) - return oldProperties || {}; - - let newProperties = {}; - oldProperties.forEach(p => { - newProperties[p.name] = p.value; - }); - - return newProperties; -}; - module.exports = { name: null, path: null, @@ -105,9 +97,10 @@ module.exports = { mapFile = require('../' + this.path + '/' + this.name + '/map'); this.mapFile = mapFile; //Fix for newer versions of Tiled - this.mapFile.properties = objectifyProperties(this.mapFile.properties); + this.mapFile.properties = getObjectifiedProperties(this.mapFile.properties); mapScale = mapFile.tilesets[0].tileheight; + this.mapScale = mapScale; this.custom = mapFile.properties.custom; @@ -126,7 +119,10 @@ module.exports = { collisionMap: this.collisionMap, clientObjects: this.objBlueprints, padding: padding, - hiddenRooms: this.hiddenRooms + hiddenRooms: this.hiddenRooms, + spriteAtlasPath: spriteBuilder.getPath(), + noFlipTiles: spriteBuilder.getNoFlipTiles(), + tileOpacities: spriteBuilder.getTileOpacities() }; }, @@ -196,7 +192,7 @@ module.exports = { //Fix for newer versions of Tiled this.randomMap.templates .forEach(r => { - r.properties = objectifyProperties(r.properties); + r.properties = getObjectifiedProperties(r.properties); }); this.randomMap.templates @@ -381,159 +377,11 @@ module.exports = { builders: { tile: function (info) { - let { x, y, cell, layer: layerName, sheetName } = info; - - if (cell === 0) { - if (layerName === 'tiles') - this.collisionMap[x][y] = 1; - - return; - } - - let cellInfo = this.getCellInfo(cell, x, y, layerName); - if (!sheetName) { - info.sheetName = cellInfo.sheetName; - sheetName = cellInfo.sheetName; - } - - const offsetCell = this.getOffsetCellPos(sheetName, cellInfo.cell); - - const isHiddenLayer = layerName.indexOf('hidden') === 0; - - if (isHiddenLayer) - this[layerName][x][y] = offsetCell; - else { - const layer = this.layers; - - if (this.oldLayers[layerName]) - this.oldLayers[layerName][x][y] = offsetCell; - - layer[x][y] = (layer[x][y] === null) ? offsetCell : layer[x][y] + ',' + offsetCell; - - if (layerName.indexOf('walls') > -1) - this.collisionMap[x][y] = 1; - else if (clientConfig.config.blockingTileIndices.includes(offsetCell)) - this.collisionMap[x][y] = 1; - } + buildTile(this, info); }, object: function (layerName, cell) { - //Fixes for newer versions of tiled - cell.properties = objectifyProperties(cell.properties); - cell.polyline = cell.polyline || cell.polygon; - - const x = cell.x / mapScale; - const y = (cell.y / mapScale) - 1; - - let clientObj = (layerName === 'clientObjects'); - let cellInfo = this.getCellInfo(cell.gid, x, y, layerName); - - let name = (cell.name || ''); - let objZoneName = name; - if (name.indexOf('|') > -1) { - let split = name.split('|'); - name = split[0]; - objZoneName = split[1]; - } - - let blueprint = { - id: cell.properties.id, - clientObj: clientObj, - sheetName: cell.has('sheetName') ? cell.sheetName : cellInfo.sheetName, - cell: cell.has('cell') ? cell.cell : cellInfo.cell - 1, - x, - y, - name: name, - properties: cell.properties || {}, - layerName: layerName - }; - - if (objZoneName !== name) - blueprint.objZoneName = objZoneName; - - if (this.zone) { - if ((this.zone.objects) && (this.zone.objects[objZoneName.toLowerCase()])) - extend(blueprint, this.zone.objects[objZoneName.toLowerCase()]); - else if ((this.zone.objects) && (this.zone.mobs[objZoneName.toLowerCase()])) - extend(blueprint, this.zone.mobs[objZoneName.toLowerCase()]); - } - - if (blueprint.blocking) - this.collisionMap[blueprint.x][blueprint.y] = 1; - - if ((blueprint.properties.cpnNotice) || (blueprint.properties.cpnLightPatch) || (layerName === 'rooms') || (layerName === 'hiddenRooms')) { - blueprint.y++; - blueprint.width = cell.width / mapScale; - blueprint.height = cell.height / mapScale; - } else if (cell.width === 24) - blueprint.x++; - - if (cell.polyline) - mapObjects.polyline(this.size, blueprint, cell, mapScale); - - if (layerName === 'rooms') { - if (blueprint.properties.exit) { - let room = this.rooms.find(function (r) { - return (!( - (blueprint.x + blueprint.width < r.x) || - (blueprint.y + blueprint.height < r.y) || - (blueprint.x >= r.x + r.width) || - (blueprint.y >= r.y + r.height) - )); - }); - - room.exits.push(blueprint); - } else if (blueprint.properties.resource) - resourceSpawner.register(blueprint.properties.resource, blueprint); - else { - blueprint.exits = []; - blueprint.objects = []; - this.rooms.push(blueprint); - } - } else if (layerName === 'hiddenRooms') { - blueprint.fog = (cell.properties || {}).fog; - blueprint.interior = (cell.properties || {}).interior; - blueprint.discoverable = (cell.properties || {}).discoverable; - blueprint.layer = ~~((cell.properties || {}).layer || 0); - - if (!mapFile.properties.isRandom) - this.hiddenRooms.push(blueprint); - else { - let room = this.rooms.find(r => { - return !( - blueprint.x < r.x || - blueprint.y < r.y || - blueprint.x >= r.x + r.width || - blueprint.y >= r.y + r.height - ); - }); - - room.objects.push(blueprint); - } - } else if (!clientObj) { - if (!mapFile.properties.isRandom) - spawners.register(blueprint, blueprint.spawnCd || mapFile.properties.spawnCd); - else { - let room = this.rooms.find(r => { - return !( - blueprint.x < r.x || - blueprint.y < r.y || - blueprint.x >= r.x + r.width || - blueprint.y >= r.y + r.height - ); - }); - - room.objects.push(blueprint); - } - } else { - if ((cell.width) && (!cell.polyline)) { - blueprint.width = cell.width / mapScale; - blueprint.height = cell.height / mapScale; - } - - let obj = objects.buildObjects([blueprint], true).getSimple(true); - this.objBlueprints.push(obj); - } + buildObject(this, layerName, cell); } }, diff --git a/src/server/world/map/builders/object.js b/src/server/world/map/builders/object.js new file mode 100644 index 00000000..b096871e --- /dev/null +++ b/src/server/world/map/builders/object.js @@ -0,0 +1,157 @@ +//Imports +const objects = require('../../../objects/objects'); +const spawners = require('./../../spawners'); +const resourceSpawner = require('../../resourceSpawner'); + +const mapObjects = require('../mapObjects'); +const getObjectifiedProperties = require('../getObjectifiedProperties'); + +const spriteBuilder = require('../../spriteBuilder/index'); + +//Helpers +const buildRoom = (mapModule, blueprint) => { + if (blueprint.properties.exit) { + const room = mapModule.rooms.find(r => { + return (!( + (blueprint.x + blueprint.width < r.x) || + (blueprint.y + blueprint.height < r.y) || + (blueprint.x >= r.x + r.width) || + (blueprint.y >= r.y + r.height) + )); + }); + + room.exits.push(blueprint); + } else if (blueprint.properties.resource) + resourceSpawner.register(blueprint.properties.resource, blueprint); + else { + blueprint.exits = []; + blueprint.objects = []; + mapModule.rooms.push(blueprint); + } +}; + +const buildHiddenRoom = (mapModule, blueprint) => { + const { mapFile } = mapModule; + const { cell } = blueprint; + + blueprint.fog = (cell.properties || {}).fog; + blueprint.interior = (cell.properties || {}).interior; + blueprint.discoverable = (cell.properties || {}).discoverable; + blueprint.layer = ~~((cell.properties || {}).layer || 0); + + if (!mapFile.properties.isRandom) + mapModule.hiddenRooms.push(blueprint); + else { + const room = mapModule.rooms.find(r => { + return !( + blueprint.x < r.x || + blueprint.y < r.y || + blueprint.x >= r.x + r.width || + blueprint.y >= r.y + r.height + ); + }); + + room.objects.push(blueprint); + } +}; + +const buildRegularObject = (mapModule, blueprint) => { + const { mapFile } = mapModule; + + if (!mapFile.properties.isRandom) + spawners.register(blueprint, blueprint.spawnCd || mapFile.properties.spawnCd); + else { + const room = mapModule.rooms.find(r => { + return !( + blueprint.x < r.x || + blueprint.y < r.y || + blueprint.x >= r.x + r.width || + blueprint.y >= r.y + r.height + ); + }); + + room.objects.push(blueprint); + } +}; + +const buildClientObject = (mapModule, blueprint) => { + const { mapScale } = mapModule; + + const { cell } = blueprint; + + if ((cell.width) && (!cell.polyline)) { + blueprint.width = cell.width / mapScale; + blueprint.height = cell.height / mapScale; + } + + const obj = objects.buildObjects([blueprint], true).getSimple(true); + mapModule.objBlueprints.push(obj); +}; + +//Builder +const buildObject = (mapModule, layerName, cell) => { + const { mapScale } = mapModule; + + cell.properties = getObjectifiedProperties(cell.properties); + cell.polyline = cell.polyline || cell.polygon; + + const x = cell.x / mapScale; + const y = (cell.y / mapScale) - 1; + + const clientObj = (layerName === 'clientObjects'); + const cellInfo = mapModule.getCellInfo(cell.gid, x, y, layerName); + + let name = (cell.name || ''); + let objZoneName = name; + if (name.indexOf('|') > -1) { + const split = name.split('|'); + name = split[0]; + objZoneName = split[1]; + } + + const blueprint = { + id: cell.properties.id, + clientObj: clientObj, + sheetName: cell.isDefined('sheetName') ? cell.sheetName : cellInfo.sheetName, + cell: cell.isDefined('cell') ? cell.cell : cellInfo.cell - 1, + x, + y, + name: name, + properties: cell.properties || {}, + layerName: layerName + }; + + if (objZoneName !== name) + blueprint.objZoneName = objZoneName; + + if (mapModule.zone) { + if ((mapModule.zone.objects) && (mapModule.zone.objects[objZoneName.toLowerCase()])) + extend(blueprint, mapModule.zone.objects[objZoneName.toLowerCase()]); + else if ((mapModule.zone.objects) && (mapModule.zone.mobs[objZoneName.toLowerCase()])) + extend(blueprint, mapModule.zone.mobs[objZoneName.toLowerCase()]); + } + + if (blueprint.blocking) + mapModule.collisionMap[blueprint.x][blueprint.y] = 1; + + if ((blueprint.properties.cpnNotice) || (blueprint.properties.cpnLightPatch) || (layerName === 'rooms') || (layerName === 'hiddenRooms')) { + blueprint.y++; + blueprint.width = cell.width / mapScale; + blueprint.height = cell.height / mapScale; + } else if (cell.width === 24) + blueprint.x++; + + if (cell.polyline) + mapObjects.polyline(mapModule.size, blueprint, cell, mapScale); + + if (layerName === 'rooms') + buildRoom(mapModule, blueprint); + else if (layerName === 'hiddenRooms') + buildHiddenRoom(mapModule, blueprint); + else if (!clientObj) + buildRegularObject(mapModule, blueprint); + else + buildClientObject(mapModule, blueprint); +}; + +module.exports = buildObject; diff --git a/src/server/world/map/builders/tile.js b/src/server/world/map/builders/tile.js new file mode 100644 index 00000000..cc6dda1b --- /dev/null +++ b/src/server/world/map/builders/tile.js @@ -0,0 +1,42 @@ +//Imports +const spriteBuilder = require('../../spriteBuilder/index'); + +//Builder +const buildTile = (mapModule, tileInfo) => { + const { x, y, cell, layer: layerName } = tileInfo; + + if (cell === 0) { + if (layerName === 'tiles') + mapModule.collisionMap[x][y] = 1; + + return; + } + + const cellInfo = mapModule.getCellInfo(cell, x, y, layerName); + if (!tileInfo.sheetName) + tileInfo.sheetName = cellInfo.sheetName; + + const offsetCell = spriteBuilder.track(cellInfo); + + //const offsetCell = mapModule.getOffsetCellPos(tileInfo.sheetName, cellInfo.cell); + + const isHiddenLayer = layerName.indexOf('hidden') === 0; + + if (isHiddenLayer) + mapModule[layerName][x][y] = offsetCell; + else { + const layer = mapModule.layers; + + if (mapModule.oldLayers[layerName]) + mapModule.oldLayers[layerName][x][y] = offsetCell; + + layer[x][y] = (layer[x][y] === null) ? offsetCell : layer[x][y] + ',' + offsetCell; + + if (layerName.indexOf('walls') > -1) + mapModule.collisionMap[x][y] = 1; + else if (clientConfig.config.blockingTileIndices?.[cellInfo.sheetName]?.includes(cellInfo.cell)) + mapModule.collisionMap[x][y] = 1; + } +}; + +module.exports = buildTile; diff --git a/src/server/world/map/getObjectifiedProperties.js b/src/server/world/map/getObjectifiedProperties.js new file mode 100644 index 00000000..35c82014 --- /dev/null +++ b/src/server/world/map/getObjectifiedProperties.js @@ -0,0 +1,17 @@ +//In older versions of the Tiled map editor, properties are stored as an object +// whereas newer versions store them as as an array. This helper converts the array +// version in to an object version. + +const getObjectifiedProperties = oldProperties => { + if (!oldProperties || !oldProperties.push) + return oldProperties || {}; + + let newProperties = {}; + oldProperties.forEach(p => { + newProperties[p.name] = p.value; + }); + + return newProperties; +}; + +module.exports = getObjectifiedProperties; diff --git a/src/server/world/mobBuilder.js b/src/server/world/mobBuilder.js index a5cb9bfa..97b8c034 100644 --- a/src/server/world/mobBuilder.js +++ b/src/server/world/mobBuilder.js @@ -27,7 +27,7 @@ module.exports = { if (typeDefinition.sheetName) mob.sheetName = typeDefinition.sheetName; - if (typeDefinition.has('cell')) + if (typeDefinition.isDefined('cell')) mob.cell = typeDefinition.cell; mob.addComponent('stats', { @@ -63,7 +63,7 @@ module.exports = { dmgMult: typeDefinition.dmgMult }); - if (!blueprint.has('attackable') || blueprint.attackable === true) { + if (!blueprint.isDefined('attackable') || blueprint.attackable === true) { mob.addComponent('aggro', { faction: blueprint.faction }); diff --git a/src/server/world/spriteBuilder/index.js b/src/server/world/spriteBuilder/index.js new file mode 100644 index 00000000..8a7782c4 --- /dev/null +++ b/src/server/world/spriteBuilder/index.js @@ -0,0 +1,117 @@ +//Imports +const jimp = require('jimp'); + +//System +let mapName = null; +let stage = null; +let noFlipTiles = null; +let tileOpacities = null; + +//Methods +const init = _mapName => { + mapName = _mapName; + stage = []; + noFlipTiles = []; + tileOpacities = []; +}; + +const track = tileInfo => { + const { cell, sheetName } = tileInfo; + + if (!sheetName || cell === undefined) + return cell; + + const existIndex = stage.findIndex(s => s.cell === cell && s.sheetName === sheetName); + if (existIndex !== -1) + return existIndex + 1; + + stage.push({ + cell, + sheetName + }); + + const { config: { tilesNoFlip: noFlip, tileOpacities: opacities } } = clientConfig; + + if (noFlip?.[sheetName]?.includes(cell - 1)) + noFlipTiles.push(stage.length); + + tileOpacities.push({ + max: opacities?.[sheetName]?.max ?? opacities.default.max, + opacity: opacities?.[sheetName]?.[cell - 1] ?? opacities?.[sheetName]?.default ?? opacities.default.default + }); + + return stage.length; +}; + +const getPath = () => { + const path = `images/temp/${mapName}.png`; + + return path; +}; + +const finalize = async () => { + const pathMaps = {}; + + const paths = []; + stage.forEach(s => { + const sheetName = s.sheetName; + + const path = sheetName.includes('.png') ? `../${sheetName}` : `../client/images/${sheetName}.png`; + + if (paths.includes(path)) + return; + + pathMaps[sheetName] = path; + + paths.push(path); + }); + + const loaders = await Promise.all(paths.map(p => jimp.read(p))); + + //Load images + const images = await Promise.all(loaders); + + const w = 8 * 8; + const h = Math.ceil(stage.length / 8) * 8; + + //Create new + const res = new jimp(w, h, async (err, image) => { + stage.forEach(({ sheetName, cell }, i) => { + const mappedPath = pathMaps[sheetName]; + const imageIndex = paths.findIndex(p => p === mappedPath); + const sourceImage = images[imageIndex]; + + const y = ~~(i / 8); + const x = i - (y * 8); + + const sy = ~~((cell - 1) / 8); + const sx = cell - 1 - (sy * 8); + + image.blit(sourceImage, x * 8, y * 8, sx * 8, sy * 8, 8, 8); + }); + + const path = `../client/${getPath()}`; + + image.writeAsync(path); + }); + + return res; +}; + +const getNoFlipTiles = () => { + return noFlipTiles; +}; + +const getTileOpacities = () => { + return tileOpacities; +}; + +//Exports +module.exports = { + init, + track, + getPath, + getNoFlipTiles, + getTileOpacities, + finalize +}; diff --git a/src/server/world/worker.js b/src/server/world/worker.js index f3ab787d..632b25c2 100644 --- a/src/server/world/worker.js +++ b/src/server/world/worker.js @@ -78,7 +78,7 @@ let onDbReady = async function () { io.init(onDbReady); -process.on('message', m => { +process.on('message', async m => { if (m.module) { let instances = instancer.instances; let iLen = instances.length; @@ -103,7 +103,7 @@ process.on('message', m => { } else if (m.threadModule) global[m.threadModule][m.method](m.data); else if (m.method) - instancer[m.method](m.args); + await instancer[m.method](m.args); else if (m.event) eventEmitter.emit(m.event, m.data); });