diff --git a/packages/junon-common/protocol/enum.proto b/packages/junon-common/protocol/enum.proto index 90df3900..de67defa 100644 --- a/packages/junon-common/protocol/enum.proto +++ b/packages/junon-common/protocol/enum.proto @@ -266,6 +266,7 @@ enum BuildingType { MiasmaGate = 272; CabbageSeed = 273; Cabbage = 274; + SmallAirlock = 275; } enum TerrainType { diff --git a/packages/junon-io/client/assets/images/small_airlock.png b/packages/junon-io/client/assets/images/small_airlock.png new file mode 100644 index 00000000..064131fb Binary files /dev/null and b/packages/junon-io/client/assets/images/small_airlock.png differ diff --git a/packages/junon-io/client/assets/images/small_airlock_lower.png b/packages/junon-io/client/assets/images/small_airlock_lower.png new file mode 100644 index 00000000..c187edce Binary files /dev/null and b/packages/junon-io/client/assets/images/small_airlock_lower.png differ diff --git a/packages/junon-io/client/assets/images/small_airlock_upper.png b/packages/junon-io/client/assets/images/small_airlock_upper.png new file mode 100644 index 00000000..17c1fc1d Binary files /dev/null and b/packages/junon-io/client/assets/images/small_airlock_upper.png differ diff --git a/packages/junon-io/client/src/entities/buildings/index.js b/packages/junon-io/client/src/entities/buildings/index.js index 01fcb020..9625c2bc 100644 --- a/packages/junon-io/client/src/entities/buildings/index.js +++ b/packages/junon-io/client/src/entities/buildings/index.js @@ -32,6 +32,7 @@ Buildings.Production.AmmoPrinter = require("./ammo_printer") Buildings.Structures.SpikeTrap = require("./spike_trap") Buildings.Structures.WebTrap = require("./web_trap") Buildings.Structures.ManualAirlock = require("./manual_airlock") +Buildings.Structures.SmallAirlock = require("./small_airlock") Buildings.Structures.Airlock = require("./airlock") Buildings.Structures.SealedDoor = require("./sealed_door") Buildings.Structures.Fence = require("./fence") diff --git a/packages/junon-io/client/src/entities/buildings/lamp.js b/packages/junon-io/client/src/entities/buildings/lamp.js index b1454c17..3bdaaff2 100644 --- a/packages/junon-io/client/src/entities/buildings/lamp.js +++ b/packages/junon-io/client/src/entities/buildings/lamp.js @@ -226,6 +226,10 @@ class Lamp extends BaseBuilding { } } + getDefaultSpriteColor() { + return ClientHelper.hexToInt(this.getLightColor()) + } + getType() { return Protocol.definition().BuildingType.Lamp } diff --git a/packages/junon-io/client/src/entities/buildings/small_airlock.js b/packages/junon-io/client/src/entities/buildings/small_airlock.js new file mode 100644 index 00000000..0acca4e0 --- /dev/null +++ b/packages/junon-io/client/src/entities/buildings/small_airlock.js @@ -0,0 +1,47 @@ +const Airlock = require("./airlock") +const Constants = require("./../../../../common/constants.json") +const Protocol = require("./../../../../common/util/protocol") + +class SmallAirlock extends Airlock { + + getConstantsTable() { + return "Buildings.SmallAirlock" + } + + open() { + this.tween = super.getOpenTween(Constants.tileSize * 1.5) + this.tween.start() + } + + getType() { + return Protocol.definition().BuildingType.SmallAirlock + } + + getBuildingSprite() { + let sprite = new PIXI.Container() + + let texture = PIXI.utils.TextureCache["small_airlock_upper.png"] + this.upperDoorSprite = new PIXI.Sprite(texture) + this.upperDoorSprite.anchor.set(0.5) + this.upperDoorSprite.name = "UpperDoor" + + texture = PIXI.utils.TextureCache["small_airlock_lower.png"] + this.lowerDoorSprite = new PIXI.Sprite(texture) + this.lowerDoorSprite.anchor.set(0.5) + this.lowerDoorSprite.name = "LowerDoor" + + sprite.addChild(this.lowerDoorSprite) + sprite.addChild(this.upperDoorSprite) + + return sprite + } + + getSpritePath() { + return "small_airlock.png" + } + + + +} + +module.exports = SmallAirlock diff --git a/packages/junon-io/client/src/entities/buildings/suit_station.js b/packages/junon-io/client/src/entities/buildings/suit_station.js index 0b342ada..1160c311 100644 --- a/packages/junon-io/client/src/entities/buildings/suit_station.js +++ b/packages/junon-io/client/src/entities/buildings/suit_station.js @@ -12,6 +12,8 @@ class SuitStation extends BaseBuilding { onContentChanged() { const armorType = this.content + // just remove armor when content change + if (this.armor) this.armor.remove() if (armorType) { let suitType = armorType.split(":")[0] let color = armorType.split(":")[1] @@ -22,9 +24,6 @@ class SuitStation extends BaseBuilding { } this.armor = Equipments.forType(suitType).build(this.game, data) - } else if (this.armor) { - // no more armor in storage, remove it - this.armor.remove() } } diff --git a/packages/junon-io/client/src/entities/effects/invisible.js b/packages/junon-io/client/src/entities/effects/invisible.js index 2670b46a..1f2a4a94 100644 --- a/packages/junon-io/client/src/entities/effects/invisible.js +++ b/packages/junon-io/client/src/entities/effects/invisible.js @@ -16,11 +16,12 @@ class Invisible extends BaseEffect { let opacity = { opacity: 1 } let targetOpacity = 0 if (this.affectedEntity.isPlayer() && - this.affectedEntity.isMe()) { + (this.affectedEntity.isMe && this.affectedEntity.isMe())) { targetOpacity = 0.2 } - if(this.affectedEntity.sector.settings.isFovMode && !this.affectedEntity.isMe()) { + if(this.affectedEntity.sector.settings.isFovMode && + (this.affectedEntity.isMe && !this.affectedEntity.isMe())) { return new TWEEN.Tween(opacity) .to({ opacity: targetOpacity }, 0) .onUpdate(() => { diff --git a/packages/junon-io/client/src/entities/game.js b/packages/junon-io/client/src/entities/game.js index 9dcf4380..cf475845 100644 --- a/packages/junon-io/client/src/entities/game.js +++ b/packages/junon-io/client/src/entities/game.js @@ -1412,7 +1412,7 @@ class Game { // PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST - let tempAssets = ['displacement_map.png', 'squid_lord_heart.png', 'squid_staff.png', 'fries.png', 'energy_drink.png', 'alien_juice.png', 'rocket_launcher.png', 'scar_17_by_px.png', 'bowl_by_px.png', 'potato_soup_by_px.png', 'miso_soup_by_px.png', 'slime_broth_by_px.png', 'bomber_turret_by_px.png', 'firebat.png', 'plasma_blade.png', 'raven.png', 'starberries.png', 'car.png', 'bricks_texture.png', 'checker_texture.png', 'noise_texture.png', 'x_texture.png', 'xchecker_texture.png', 'nihonshu.png', 'pumpkin.png', 'pumpkin_plant.png', 'pumpkin_seed.png', 'rice.png', 'rice_plant.png', 'rice_seed.png', 'fish.png', 'nigiri.png', 'katana_reskin.png', 'pumpkin_pie.png', 'imperial_special_forces_armor.png', 'deconstructor.png', 'blue_laser.png', 'keypad_door.png', 'keypad_door_lower.png', 'keypad_door_upper.png', 'unbreakable_wall.png', 'sapper.png', 'sapper_corpse.png', 'dynamite.png', 'miasma_gate.png', "solid_texture2.png", "simplex_texture.png", "cabbage_seed.png", "cabbage_plant.png", "cabbage.png", "3dwall-0.png", "3dwall-1.png", "3dwall-2.png", "3dwall-3.png", "3dwall-4.png", "3dwall-5.png", "3dwall-6.png", "3dwall-7.png", "3dwall-8.png", "3dwall-9.png", "3dwall-10.png", "3dwall-11.png", "3dwall-12.png", "3dwall-13.png"] + let tempAssets = ['displacement_map.png', 'squid_lord_heart.png', 'squid_staff.png', 'fries.png', 'energy_drink.png', 'alien_juice.png', 'rocket_launcher.png', 'scar_17_by_px.png', 'bowl_by_px.png', 'potato_soup_by_px.png', 'miso_soup_by_px.png', 'slime_broth_by_px.png', 'bomber_turret_by_px.png', 'firebat.png', 'plasma_blade.png', 'raven.png', 'starberries.png', 'car.png', 'bricks_texture.png', 'checker_texture.png', 'noise_texture.png', 'x_texture.png', 'xchecker_texture.png', 'nihonshu.png', 'pumpkin.png', 'pumpkin_plant.png', 'pumpkin_seed.png', 'rice.png', 'rice_plant.png', 'rice_seed.png', 'fish.png', 'nigiri.png', 'katana_reskin.png', 'pumpkin_pie.png', 'imperial_special_forces_armor.png', 'deconstructor.png', 'blue_laser.png', 'keypad_door.png', 'keypad_door_lower.png', 'keypad_door_upper.png', 'unbreakable_wall.png', 'sapper.png', 'sapper_corpse.png', 'dynamite.png', 'miasma_gate.png', "solid_texture2.png", "simplex_texture.png", "cabbage_seed.png", "cabbage_plant.png", "cabbage.png", "3dwall-0.png", "3dwall-1.png", "3dwall-2.png", "3dwall-3.png", "3dwall-4.png", "3dwall-5.png", "3dwall-6.png", "3dwall-7.png", "3dwall-8.png", "3dwall-9.png", "3dwall-10.png", "3dwall-11.png", "3dwall-12.png", "3dwall-13.png", "small_airlock_upper.png","small_airlock_lower.png","small_airlock.png"] tempAssets.forEach((asset) => { PIXI.Texture.addToCache(PIXI.Texture.fromImage('/assets/images/' + asset), asset) }) diff --git a/packages/junon-io/client/src/entities/player.js b/packages/junon-io/client/src/entities/player.js index a52b15cf..3c5f144d 100644 --- a/packages/junon-io/client/src/entities/player.js +++ b/packages/junon-io/client/src/entities/player.js @@ -1117,6 +1117,7 @@ class Player extends BaseEntity { this.registerToChunk() this.repositionOnUnitMap() + this.redrawVisionLightSprite() if (this.isMe()) { if (this.sector.isFovMode()) { @@ -1125,7 +1126,6 @@ class Player extends BaseEntity { } this.highlightNearbyEntities() - this.redrawVisionLightSprite() this.updateSelectedEntity() if (options.isGridPositionChanged) { @@ -1415,6 +1415,11 @@ class Player extends BaseEntity { this.usernameText.remove() } + if (this.visionLightSprite){ + this.visionLightSprite.destroy() + this.visionLightCanvas.remove() + } + this.getContainer().unregisterEntity("players", this) if (this.chunk) { diff --git a/packages/junon-io/client/src/menus/entity_menu.js b/packages/junon-io/client/src/menus/entity_menu.js index b3d55c2e..043a524d 100644 --- a/packages/junon-io/client/src/menus/entity_menu.js +++ b/packages/junon-io/client/src/menus/entity_menu.js @@ -400,6 +400,7 @@ class EntityMenu extends BaseMenu { } this.el.querySelector(".entity_action").innerHTML = "" // reset + this.el.querySelector('.entity_color').innerText = "" if (this.game.shouldShowDebugDetails()) { @@ -425,7 +426,8 @@ class EntityMenu extends BaseMenu { const isFloorOrWall = entity.hasCategory && (entity.hasCategory('platform') || entity.hasCategory('wall') || entity.hasCategory('custom_colors')) if (isFloorOrWall && entity.data && entity.data.colorIndex > 37) { - this.el.querySelector('.entity_color').innerText = ClientHelper.toHex(entity.data.colorIndex - 38) + this.el.querySelector(".debug_container").style.display = 'block' + this.el.querySelector('.entity_color').innerText = "color: " + ClientHelper.toHex(entity.data.colorIndex - 38) } } diff --git a/packages/junon-io/client/src/menus/map_menu.js b/packages/junon-io/client/src/menus/map_menu.js index d9f64ca0..8a7eea2b 100644 --- a/packages/junon-io/client/src/menus/map_menu.js +++ b/packages/junon-io/client/src/menus/map_menu.js @@ -57,6 +57,7 @@ class MapMenu extends BaseMenu { reinit() { // the grid size is 200x200. map is 600px by 600px wide let sectorColCount = this.game.sector.getColCount() + this.alerts = {} this.zoomMultiplier = Math.floor(this.mapSize / sectorColCount) } @@ -450,4 +451,4 @@ class MapMenu extends BaseMenu { -module.exports = MapMenu \ No newline at end of file +module.exports = MapMenu diff --git a/packages/junon-io/common/constants.json b/packages/junon-io/common/constants.json index 79767710..f13c96ff 100644 --- a/packages/junon-io/common/constants.json +++ b/packages/junon-io/common/constants.json @@ -2786,6 +2786,7 @@ "Gelatin": { "width": 24, "height": 24, + "isCooked": true, "cost": { "gold": 15 }, @@ -2874,6 +2875,7 @@ "HotDog": { "width": 24, "height": 24, + "isCooked": true, "sprite": { "position": { "x": 60, @@ -2896,6 +2898,7 @@ "Bread": { "width": 24, "height": 24, + "isCooked": true, "isIngredient": true, "sprite": { "position": { @@ -2919,6 +2922,7 @@ "VeganPizza": { "width": 40, "height": 40, + "isCooked": true, "sprite": { "position": { "x": 95, @@ -2941,6 +2945,7 @@ "SlimyMeatPizza": { "width": 40, "height": 40, + "isCooked": true, "cost": { "gold": 500 }, @@ -2963,6 +2968,7 @@ "LectersDinner": { "width": 40, "height": 40, + "isCooked": true, "cost": { "gold": 300 }, @@ -3088,6 +3094,7 @@ "Fries": { "width": 24, "height": 24, + "isCooked": true, "cost": { "gold": 100 }, @@ -3111,6 +3118,7 @@ "Steak": { "width": 24, "height": 24, + "isCooked": true, "cost": { "gold": 200 }, @@ -3153,6 +3161,7 @@ "PotatoSoup": { "width": 32, "height": 32, + "isCooked": true, "cost": { "gold": 200 }, @@ -3173,6 +3182,7 @@ "SlimeBroth": { "width": 32, "height": 32, + "isCooked": true, "cost": { "gold": 200 }, @@ -3192,6 +3202,7 @@ "MisoSoup": { "width": 32, "height": 32, + "isCooked": true, "cost": { "gold": 200 }, @@ -3211,6 +3222,7 @@ "Omelette": { "width": 24, "height": 24, + "isCooked": true, "cost": { "gold": 200 }, @@ -3233,6 +3245,7 @@ "Nigiri": { "width": 24, "height": 24, + "isCooked": true, "cost": { "gold": 400 }, @@ -3257,6 +3270,7 @@ "PumpkinPie": { "width": 32, "height": 32, + "isCooked": true, "cost": { "gold": 250 }, @@ -6090,19 +6104,33 @@ "description": "Airtight door. No power required to operate" }, "SmallAirlock": { - "width": 64, + "width": 32, "height": 32, + "isInteractable": true, + "showInteractTooltip": true, + "isUpgradable": true, + "isAirtight": true, + "categories": {"door":true,"melee_resistant":true}, + "minimapColor": "#3bceaa", + "requirements": { + "IronBar": 5 + }, "cost": { "gold": 50 }, + "sprite":{ + "width": 32, + "height": 32 + }, "stats": { "health": 100, "count": 125 }, "upgrade": { - "health": "+25", - "count": "+25" - } + "health": "+15", + "count": "+15" + }, + "description":"A smaller airtight door." }, "ResearchTable": { "width": 32, diff --git a/packages/junon-io/common/interfaces/taintable.js b/packages/junon-io/common/interfaces/taintable.js index 75ebcec2..20c2aeb6 100644 --- a/packages/junon-io/common/interfaces/taintable.js +++ b/packages/junon-io/common/interfaces/taintable.js @@ -247,9 +247,10 @@ Taintable.prototype = { removeEffect(effectName) { if (!this.effects) return + this.setEffectLevel(effectName, 0) - delete this.effects[effectName] - this.onEffectRemoved(effectName) + // delete this.effects[effectName] + // this.onEffectRemoved(effectName) }, removeAllEffects() { @@ -278,4 +279,3 @@ Taintable.prototype = { } module.exports = Taintable - diff --git a/packages/junon-io/server/commands/fill.js b/packages/junon-io/server/commands/fill.js index f2ddfd02..21f00da3 100644 --- a/packages/junon-io/server/commands/fill.js +++ b/packages/junon-io/server/commands/fill.js @@ -9,7 +9,7 @@ class Fill extends BaseCommand { getUsage() { return [ "/fill [start_row] [start_col] [end_row] [end_col] [terrain_type] [color]", - // "/fill building [start_row] [start_col] [end_row] [end_col] [1x1 building] [color]" + "/fill building [start_row] [start_col] [end_row] [end_col] [1x1 building] [color]" ] } @@ -19,7 +19,7 @@ class Fill extends BaseCommand { perform(player, args) { - if(false) { + if(args[0] == 'building') { let startRow = parseInt(args[1]) let startCol = parseInt(args[2]) let endRow = parseInt(args[3]) diff --git a/packages/junon-io/server/commands/interact.js b/packages/junon-io/server/commands/interact.js index 74cb7b45..c56005ce 100644 --- a/packages/junon-io/server/commands/interact.js +++ b/packages/junon-io/server/commands/interact.js @@ -72,7 +72,7 @@ class Interact extends BaseCommand { } } - if (entity.hasCategory("door")) { + if (entity.hasCategory("door") || entity.hasCategory("lamp")) { if (operation === "open") { entity.open() } else if (operation === "close") { diff --git a/packages/junon-io/server/commands/menu.js b/packages/junon-io/server/commands/menu.js index d5acde8f..312c4f0c 100644 --- a/packages/junon-io/server/commands/menu.js +++ b/packages/junon-io/server/commands/menu.js @@ -1,4 +1,6 @@ const BaseCommand = require("./base_command") +const Constants = require("../../common/constants") +const Protocol = require('../../common/util/protocol') class Menu extends BaseCommand { getUsage() { @@ -6,10 +8,29 @@ class Menu extends BaseCommand { "/menu close [menu name] [player name]", "/menu open [menu name] [player name]", "Available menu names:", - "keypadMenu, craftMenu, atmMenu, friendsMenu, commandBlockMenu, teamMenu, welcomeMenu, stoveMenu, tradeMenu, slaveTradeMenu, badgeMenu" + this.getAllowedMenus().join(", ") ] } + getAllowedMenus() + { + return ["blueprintMenu", + "inventoryMenu", + "chatMenu", + "tradeMenu", + "slaveTradeMenu", + "welcomeMenu", + "mapMenu", + "miniMapMenu", + "atmMenu", + "sidebarMenu", + "commandBlockMenu", + "voteMenu", + "friendsMenu", + "badgeMenu", + "teamMenu"] + } + allowOwnerOnly() { return true } @@ -20,7 +41,6 @@ class Menu extends BaseCommand { let player = args[2] let multiplePlayers // if(!caller || !caller.isPlayer()) return - // Commented cuz of didn't work in command block and useless if(player) { player = this.getPlayersBySelector(player) @@ -30,6 +50,16 @@ class Menu extends BaseCommand { } if(subcommand == "open") { + // only check allowed menus here + // since player shouldn't have entity-dependent menus open with this cmd + // but should be able to have them closed + let allowedMenus = this.getAllowedMenus() + if(allowedMenus.indexOf(menuName) === -1) + { + caller.showChatError("Menu invalid / unallowed: " + menuName) + return + } + if(multiplePlayers) { player.forEach((entity) => { this.getSocketUtil().emit(entity.socket, "OpenMenu", {menuName: menuName}) @@ -42,7 +72,7 @@ class Menu extends BaseCommand { if(subcommand == "close") { if(multiplePlayers) { player.forEach((entity) => { - this.getSocketUtil().emit(entity.socket, "OpenMenu", {menuName: menuName}) + this.getSocketUtil().emit(entity.socket, "CloseMenu", {menuName: menuName}) }) return } @@ -54,4 +84,4 @@ class Menu extends BaseCommand { } } -module.exports = Menu \ No newline at end of file +module.exports = Menu diff --git a/packages/junon-io/server/entities/base_entity.js b/packages/junon-io/server/entities/base_entity.js index ea1c174f..adf84122 100644 --- a/packages/junon-io/server/entities/base_entity.js +++ b/packages/junon-io/server/entities/base_entity.js @@ -652,6 +652,9 @@ class BaseEntity extends BaseTransientEntity { if (x > this.sector.getGridWidth()) x = this.sector.getGridWidth() - 1 if (y > this.sector.getGridHeight()) y = this.sector.getGridHeight() - 1 const prevChunk = { row: this.getChunkRow(), col: this.getChunkCol() } + + x = Math.round(x * Constants.tileSize) / Constants.tileSize + y = Math.round(y * Constants.tileSize) / Constants.tileSize this.setPositionInternal(x, y) @@ -986,10 +989,12 @@ class BaseEntity extends BaseTransientEntity { if (tileHit.entity === null) return const otherBox = this.getTileBoxForEdgify(tileHit) const position = this.getPositionToEdgify(body) + // limit correction force so golems don't get stuck + let correction = body.entity.getWidth() >= 64 ? 32 : body.entity.getWidth() / 2 if (body.velocity[0] < 0) { // going left - position[0] = otherBox.pos.x + otherBox.w + + body.entity.getWidth() / 2 + position[0] = otherBox.pos.x + otherBox.w + correction // body.entity.getWidth() / 2 } else if (body.velocity[0] > 0) { // going right - position[0] = otherBox.pos.x - body.entity.getWidth() / 2 + position[0] = otherBox.pos.x - correction // body.entity.getWidth() / 2 } this.postEdgify(body) @@ -1000,10 +1005,11 @@ class BaseEntity extends BaseTransientEntity { if (tileHit.entity === null) return const otherBox = this.getTileBoxForEdgify(tileHit) const position = this.getPositionToEdgify(body) + let correction = body.entity.getWidth() >= 64 ? 32 : body.entity.getWidth() / 2 if (body.velocity[1] < 0) { // going up - position[1] = otherBox.pos.y + otherBox.h + body.entity.getHeight() / 2 + position[1] = otherBox.pos.y + otherBox.h + correction // body.entity.getHeight() / 2 } else if (body.velocity[1] > 0) { // going down - position[1] = otherBox.pos.y - body.entity.getHeight() / 2 // we're setting center of body, so accomodate its on width/height + position[1] = otherBox.pos.y - correction // body.entity.getHeight() / 2 // we're setting center of body, so accomodate its on width/height } this.postEdgify(body) diff --git a/packages/junon-io/server/entities/buildings/index.js b/packages/junon-io/server/entities/buildings/index.js index bd765076..16bfff45 100644 --- a/packages/junon-io/server/entities/buildings/index.js +++ b/packages/junon-io/server/entities/buildings/index.js @@ -29,6 +29,7 @@ Buildings.SealedDoor = require("./sealed_door") Buildings.KeypadDoor = require("./keypad_door") Buildings.Airlock = require("./airlock") Buildings.ManualAirlock = require("./manual_airlock") +Buildings.SmallAirlock = require("./small_airlock") Buildings.SolarPanel = require("./solar_panel") Buildings.OxygenTank = require("./oxygen_tank") Buildings.SmallOxygenTank = require("./small_oxygen_tank") diff --git a/packages/junon-io/server/entities/buildings/small_airlock.js b/packages/junon-io/server/entities/buildings/small_airlock.js new file mode 100644 index 00000000..d219a6ea --- /dev/null +++ b/packages/junon-io/server/entities/buildings/small_airlock.js @@ -0,0 +1,30 @@ +const Airlock = require("./airlock") +const Constants = require('../../../common/constants.json') +const Protocol = require('../../../common/util/protocol') + +class SmallAirlock extends Airlock { + + getConstantsTable() { + return "Buildings.SmallAirlock" + } + + isAutomatic() { + return false + } + + getType() { + return Protocol.definition().BuildingType.SmallAirlock + } + + getDoorLengthDivisor() { + return 1 + } + + shouldObstruct(body, hit) { + return !this.isOpen + } + + +} + +module.exports = SmallAirlock diff --git a/packages/junon-io/server/entities/buildings/stove.js b/packages/junon-io/server/entities/buildings/stove.js index 3348182a..437eab4d 100644 --- a/packages/junon-io/server/entities/buildings/stove.js +++ b/packages/junon-io/server/entities/buildings/stove.js @@ -1,5 +1,6 @@ const Constants = require('../../../common/constants.json') const Protocol = require('../../../common/util/protocol') +const Helper = require("./../../../common/helper") const BaseBuilding = require("./base_building") const Foods = require("./../foods/index") const ExceptionReporter = require('junon-common/exception_reporter') @@ -98,6 +99,14 @@ class Stove extends BaseBuilding { } } + setBuildingContent(content) { + let foodType = parseInt(content) + let foodKlass = Foods.forType(foodType) + // prevent invalid items from being cooked + if (!foodKlass) return + if (foodKlass.prototype.getConstants().isCooked) super.setBuildingContent(content) + } + getInteractDistance() { return Constants.tileSize * 2 } @@ -105,8 +114,9 @@ class Stove extends BaseBuilding { onFoodReady() { try { let item = this.getDesiredFoodItem() - + this.activeUser.setIsWorking(false) + if(!item.isFoodCooked()) return let isSuccessful if (this.activeUser.isPlayer()) { @@ -169,4 +179,3 @@ class Stove extends BaseBuilding { } module.exports = Stove - diff --git a/packages/junon-io/server/entities/buildings/suit_station.js b/packages/junon-io/server/entities/buildings/suit_station.js index ee8e8c1f..7c7ab9ad 100644 --- a/packages/junon-io/server/entities/buildings/suit_station.js +++ b/packages/junon-io/server/entities/buildings/suit_station.js @@ -127,6 +127,15 @@ class SuitStation extends BaseBuilding { return item.isArmor() } + store(item) { + // to prevent non-armors from being stored + if(item.isArmor()) { + super.store(item) + } else { + return + } + } + onStorageChanged(item, index) { super.onStorageChanged(item, index) diff --git a/packages/junon-io/server/entities/event_handler.js b/packages/junon-io/server/entities/event_handler.js index 20e5aa0d..f1302db6 100644 --- a/packages/junon-io/server/entities/event_handler.js +++ b/packages/junon-io/server/entities/event_handler.js @@ -22,6 +22,8 @@ class EventHandler { this.isRoundStarted = false this.isRoundStarting = false this.processingEvents = new Set() // Track events currently being processed to prevent infinite loops + this.processingOverflow = 0 + this.PROCESSING_LIMIT = 25 } getSocketUtil() { @@ -1015,9 +1017,9 @@ class EventHandler { // Prevent infinite loops by checking if this event is already being processed // disable for now. need to fix to handle nested events - // if (this.processingEvents.has(eventKey)) { - // return - // } + if (this.processingEvents.has(eventKey)) { + this.processingOverflow++ + } // Mark this event as being processed this.processingEvents.add(eventKey) @@ -1072,6 +1074,7 @@ class EventHandler { resetProcessingEvents() { this.processingEvents.clear() + this.processingOverflow = 0 } updateTaskCompleted() { @@ -1118,7 +1121,11 @@ class EventHandler { } runAction(action, params) { - this.commandDelay = 0 // always reset command delay at beginning + if(this.processingOverflow > this.PROCESSING_LIMIT) { + this.commandDelay = 0.1 * (this.processingOverflow - this.PROCESSING_LIMIT) // offload if overwhelmed + } else { + this.commandDelay = 0 // always reset command delay at beginning + } if (action.timer) { if (action.timer.shouldRemove) { diff --git a/packages/junon-io/server/entities/game.js b/packages/junon-io/server/entities/game.js index 0d41f1b0..caf8dc15 100644 --- a/packages/junon-io/server/entities/game.js +++ b/packages/junon-io/server/entities/game.js @@ -255,6 +255,7 @@ class Game { const args = tokens.filter((token) => { return token.length > 0 }) const command = this.commands[commandName] if (!command) return + if (!this.isGameReady) return if (delay > 0 && command.isDelayable()) { let timestampDelay = delay * Constants.physicsTimeStep @@ -1037,7 +1038,19 @@ class Game { triggerEvent(eventName, params = {}) { if (!this.isGameReady) return - this.sector && this.sector.eventHandler.trigger(eventName, params) + try + { + this.sector && this.sector.eventHandler.trigger(eventName, params) + } + catch(e) + { + if(e.name === "RangeError"){ + // disable processing more triggers + this.isGameReady = false + throw new Error("possible lag machine detected") + } + + } } addTimer(timer) { diff --git a/packages/junon-io/server/entities/item.js b/packages/junon-io/server/entities/item.js index 39e8b4f9..63d9c4d0 100644 --- a/packages/junon-io/server/entities/item.js +++ b/packages/junon-io/server/entities/item.js @@ -176,6 +176,12 @@ class Item extends BaseTransientEntity { return klass.prototype.getConstants().isIngredient } + isFoodCooked() { + let klass = this.getKlass(this.type) + if (!klass) return false + return klass.prototype.getConstants().isCooked + } + isNameTag() { const klass = this.getKlass(this.type) if (!klass) return false diff --git a/packages/junon-io/server/server.js b/packages/junon-io/server/server.js index 58036603..a81fb39d 100644 --- a/packages/junon-io/server/server.js +++ b/packages/junon-io/server/server.js @@ -1261,7 +1261,7 @@ class Server { game.sendUpdates() let endProcessTime = (new Date()).getTime() // remove worlds that are likely too resource-intensive - if(endProcessTime - startProcessTime >= 300){ + if(endProcessTime - startProcessTime >= 1200){ game.forEachPlayer((player) => { if (player.socket) player.socket.close() player.remove()