const MainPlayerPacket = require("../Packets/MainPlayer"); const QuestRemovalPacket = require("../Packets/QuestRemoval"); const EntityOldPacket = require("../Packets/EntityOld"); const EntityNewPacket = require("../Packets/EntityNew"); const AmmunitionUsedPacket = require("../Packets/AmmunitionUsed"); const LogoutCancelledPacket = require("../Packets/LogoutCancelled"); const PropertyChangedPacket = require("../Packets/PropertyChanged") const AttackInformationPacket = require("../Packets/AttackInformation"); const AttackingPacket = require("../Packets/Attacking"); const AttackAbortedPacket = require("../Packets/AttackAborted"); const AttackerInformationPacket = require("../Packets/AttackerInformation"); const EntityDiePacket = require("../Packets/EntityDie"); const RespawnConfirmationPacket = require("../Packets/RespawnConfirmation"); const EffectAddPacket = require("../Packets/EffectAdd"); const EntitySpeedChangedPacket = require("../Packets/EntitySpeedChanged"); const MapChangeStatePacket = require("../Packets/MapChangeState"); const MapChangedPacket = require("../Packets/MapChanged"); const LevelUpPacket = require("../Packets/LevelUp"); const LevelIsLowPacket = require("../Packets/LevelIsLow"); const HealthChangedAuthorlessPacket = require("../Packets/HealthChangedAuthorless"); const HealthChangedPacket = require("../Packets/HealthChanged"); const ItemUsedPacket = require("../Packets/ItemUsed"); const NewDestinationNodePacket = require("../Packets/NewDestinationNode"); const GuildMemberNewPacket = require("../Packets/GuildMemberNew"); const GuildDataMemberChangedPacket = require("../Packets/GuildDataMemberChanged"); const quests = require("../Data/quests"); const constants = require("../Data/constants"); const Game = require("../Game/Game"); const { players } = Game; const { TYPES } = constants; const { ENTITY_TYPE_PLAYER, ENTITY_TYPE_NPC, ENTITY_TYPE_MONSTER, ENTITY_TYPE_TOWER, ENTITY_TYPE_COLLECTABLE } = TYPES; const [playerEconomy] = require("../Data/batchSave"); // just to add "lag" function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }; global.PlayerWorker.on("message", data => { const player = players[data.id]; if (!player) return; if (player.map.id !== data.mapId) return; if (player.movementRequestTracker !== data.movementRequestTracker) return; player.startingPosition = data.startingPosition; const { path } = data; if (!player.isMoving) player.initializeMovement(path, data); else player.emit("scheduledPathReady", path, data); }); module.exports.scheduledPathReady = function (path, data) { if (path.length) { this.data = data; this.scheduledPath = path; this.isNewPathReady = true; } else this.isLastNodeFinished = true; if (this.isNewPathReady && this.isLastNodeFinished) { this.isNewPathReady = false; this.isLastNodeFinished = false; this.initializeMovement(this.scheduledPath, this.data); this.scheduledPath = []; }; }; module.exports.updateVisibility = function (entityProps) { const { type, data } = entityProps; let packet = null; if (type) { switch (data.typeID) { case ENTITY_TYPE_PLAYER: packet = EntityNewPacket.player(data); break; case ENTITY_TYPE_NPC: packet = EntityNewPacket.npc(data); break; case ENTITY_TYPE_MONSTER: packet = EntityNewPacket.monster(data); break; case ENTITY_TYPE_TOWER: packet = EntityNewPacket.tower(data); break; case ENTITY_TYPE_COLLECTABLE: packet = EntityNewPacket.collectable(data); break; }; } else packet = EntityOldPacket(data); this.map.registerIndividualNetworkPacket(this.id, packet.buffer ? packet.buffer : packet, [packet.metadata]); }; module.exports.disconnect = async function (data) { const { map, position, hp, inventory, textureID } = this; const playerID = this.id; const oldEntityID = { typeID: this.typeID, id: playerID }; const packet = EntityOldPacket(oldEntityID); this.map.registerNetworkPacket(this.id, packet, [1]); if (this.guild.id) { const guildDataMemberChanged = { id: playerID, isOnline: false }; const packet = GuildDataMemberChangedPacket(guildDataMemberChanged); const topic = Game.getTopic(this.guild.topic); topic.push(packet); }; this.isUnderDisconnect = true; if (!this.hasUnexpectedlyLeft) { socket.sockets[this.sessionID].end(); delete socket.sockets[this.sessionID]; console.info("player handler end socket", performance.now()); }; const ammunition = inventory.getAmmunitions(); const harpoon = inventory.getHarpoons(); const economy = inventory.getEconomy(); const items = inventory.getItems(); const designs = inventory.getDesignIDs(); const cannons = inventory.getCannons(); const harpooners = inventory.getHarpooners(); const resources = []; const equipments = []; economy.forEach(e => { playerEconomy.removeItem(`${playerID}-1-${e.id}`); resources.push([playerID, 1, e.id, e.amount]) }); items.forEach(i => { playerEconomy.removeItem(`${playerID}-2-${i.id}`); resources.push([playerID, 2, i.id, i.amount]) }); ammunition.forEach(a => { playerEconomy.removeItem(`${playerID}-3-${a.id}`); resources.push([playerID, 3, a.id, a.amount]) }); harpoon.forEach(h => { playerEconomy.removeItem(`${playerID}-4-${h.id}`); resources.push([playerID, 4, h.id, h.amount]) }); designs.forEach(id => { playerEconomy.removeItem(`${playerID}-5-${id}`); resources.push([playerID, 5, id, 1]) }); this.statusPoints.forEach(s => { playerEconomy.removeItem(`${playerID}-6-${s.id}`); resources.push([playerID, 6, s.id, s.amount]) }); cannons.forEach(c => { playerEconomy.removeItem(`${playerID}-7-${c.id}`); resources.push([playerID, 7, c.id, c.amount]); equipments.push([playerID, 7, c.id, c.amountEquipped]); }); harpooners.forEach(h => { playerEconomy.removeItem(`${playerID}-8-${h.id}`); resources.push([playerID, 8, h.id, h.amount]); equipments.push([playerID, 8, h.id, h.amountEquipped]) }); // await delay(20000) Object.entries(this.quests.completedQuestsAmount).forEach(async q => { const [questID, amount] = q; const questScheme = quests[questID - 1]; const isQuestAccepted = this.quests.has(questID); let questState = 0; if (questScheme.maximumComplete && amount >= questScheme.maximumComplete) questState = 2; else if (!isQuestAccepted) questState = 1; else questState = 0; await execute("INSERT INTO quests (playerID, questID, state, completedAmount) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE state = ?, completedAmount = ?", [playerID, questID, questState, amount, questState, amount]); if (isQuestAccepted) { const quest = this.quests.list[questID]; const questProgression = quest.getProgression(); questProgression.forEach(async progression => { const { amount, index, type } = progression; await execute("INSERT INTO questprogression (playerID, questID, amount, taskIndex, taskType) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE amount = ?", [playerID, quest.id, amount, index, type, amount]); }); }; }); const finishedQuestsID = Object.keys(this.quests.finishedQuests); if (finishedQuestsID.length) await execute("UPDATE questprogression SET amount = 0 WHERE questID IN (?)", finishedQuestsID); await execute("UPDATE playerdata SET mapID = ?, x = ?, y = ?, currentHitpoints = ?, maximumHitpoints = ?, selectedAmmunitionID = ?, selectedHarpoonID = ?, designID = ? WHERE playerID = ?", [map.id, position.x, position.y, hp.current, hp.maximum, inventory.selectedAmmunition, inventory.selectedHarpoon, textureID, playerID]); if (resources.length) await query(`INSERT INTO resources (playerID, categoryID, itemID, amount) VALUES ? ON DUPLICATE KEY UPDATE amount = VALUES(amount)`, [resources]); const activeStatusEffects = this.activeStatusEffects.length ? this.activeStatusEffects : [0]; const activeStatusEffectsFormatted = this.activeStatusEffects.map(e => [playerID, e, 1]); if (this.activeStatusEffects.length) await query(`INSERT INTO status (playerID, statusID, isActive) VALUES ? ON DUPLICATE KEY UPDATE isActive = ?`, [activeStatusEffectsFormatted, 1]); await query(`UPDATE status SET isActive = ? WHERE statusID NOT IN (?) AND playerID = ?`, [0, activeStatusEffects, playerID]); if (equipments.length) await query("INSERT INTO equipments (playerID, categoryID, itemID, amountEquipped) VALUES ? ON DUPLICATE KEY UPDATE amountEquipped = VALUES(amountEquipped)", [equipments]); if (this.isUnderDisconnect) { console.info("player handler disconnect finished", performance.now()); delete players[playerID]; } }; module.exports.disconnectCancel = function() { const packet = LogoutCancelledPacket(); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.healthChangedAuthorless = function (data, author) { const packet = HealthChangedAuthorlessPacket(data); this.map.registerNetworkPacket(author, packet); }; module.exports.attackBar = function (data, author) { const packet = AttackerInformationPacket(data); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.attackStarted = function (data, author) { const packet = AttackInformationPacket(data); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.attacking = function (data, author) { const packet = AttackingPacket(data[1]); const packett = HealthChangedPacket(data[0]); this.map.registerNetworkPacket(author, [packet, packett], [1, 1]); }; module.exports.attackAbortedByUser = function (data, author) { const packet = AttackAbortedPacket(data); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.die = function (data, author) { const packet = EntityDiePacket(data); this.map.registerNetworkPacket(author, packet, [19]); }; module.exports.propertyChanged = function (data, author) { const packet = PropertyChangedPacket(data); this.map.registerIndividualNetworkPacket(author, packet); }; module.exports.ableToJump = function (data) { const packet = MapChangeStatePacket(data); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.unableToJump = function (data) { const packet = MapChangeStatePacket(data); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.mapChanged = function (data, author) { const selfSwitchPacket = MapChangedPacket(data.newMap); this.map.registerIndividualNetworkPacket(this.id, selfSwitchPacket); const socketInstance = socket.sockets[this.sessionID]; socketInstance.unsubscribe(data.oldMap.id.toString()); socketInstance.subscribe(data.newMap.mapID.toString()); }; module.exports.levelUp = function (data) { if (this.guild.id) { const guildDataMemberChanged = { id: this.id, level: data.level }; const guildDataMemberChangedPacket = GuildDataMemberChangedPacket(guildDataMemberChanged); const topic = Game.getTopic(this.guild.topic); topic.push(guildDataMemberChangedPacket); } const packet = LevelUpPacket(data); this.map.registerNetworkPacket(this.id, packet); }; module.exports.levelIsLow = function() { const packet = LevelIsLowPacket(); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.questDone = async function (data) { await execute("INSERT INTO quests (playerID, questID, state, completedAmount) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE state = ?, completedAmount = completedAmount + 1", [this.id, data.questID, 1, 1, 1]); const packet = QuestRemovalPacket(data); this.map.registerIndividualNetworkPacket(this.id, packet); }; module.exports.testOvertimeDamage = function (data, author) { const packet = HealthChangedPacket(data); this.map.registerNetworkPacket(author, packet); }; module.exports.itemUsed = function (data, author) { const packet = ItemUsedPacket(data); this.map.registerIndividualNetworkPacket(author, packet); }; module.exports.cannonsUsed = function (data, author) { const packet = AmmunitionUsedPacket(data); this.map.registerIndividualNetworkPacket(author, packet); }; module.exports.harpoonersUsed = function (data, author) { const packet = AmmunitionUsedPacket(data); this.map.registerIndividualNetworkPacket(author, packet); }; module.exports.newDestination = function (data) { const packet = NewDestinationNodePacket(data); this.map.registerNetworkPacket(this.id, packet); }; module.exports.effectAdd = function (data) { const packet = EffectAddPacket(data); this.map.registerNetworkPacket(this.id, packet); }; module.exports.speedUpdate = function (data) { const packet = EntitySpeedChangedPacket(data); this.map.registerNetworkPacket(this.id, packet); }; module.exports.respawn = async function() { const respawnPacket = RespawnConfirmationPacket(); this.map.registerIndividualNetworkPacket(this.id, respawnPacket); const respawningPlayerProperties = this.getProperties(); const respawningPlayerPacket = MainPlayerPacket(respawningPlayerProperties); const packetsToSend = [respawningPlayerPacket]; if (this.guild && this.guild.id) { const guildProperties = { playerID: this.id, tag: this.guild.tag }; const guildPacket = GuildMemberNewPacket(guildProperties); packetsToSend.push(guildPacket); }; this.map.registerIndividualNetworkPacket(this.id, packetsToSend); };