Files
2026-08-24 22:20:36 +02:00

240 lines
7.4 KiB
JavaScript

const Limiter = require("../Game/PacketLimiter");
const EquipmentLimiter = require("../Game/EquipmentLimiter");
const Inventory = require("../Game/Inventory");
const Player = require("../Game/Player");
const Game = require("../Game/Game");
const playerHandlers = require("../Handlers/Player");
const EnvironmentSetupPacket = require("../Packets/EnvironmentSetup");
const rewardCallback = require("../Callbacks/reward");
const attackCallback = require("../Callbacks/attack");
const baseStarterRewards = require("../Data/startRewards");
const { maps, players, guilds } = Game;
const queries = require("../Data/queries");
const { QUERY_FETCH_PLAYER_DATA, QUERY_FETCH_PLAYER_INFORMATION, QUERY_FETCH_GUILD_INFORMATION, QUERY_INSERT_DEFAULT_PLAYER, QUERY_FETCH_ACTIVE_QUESTS, QUERY_FETCH_STATUS, QUERY_FETCH_RESOURCES, QUERY_FETCH_EQUIPMENTS } = queries;
const playerEvents = Object.keys(playerHandlers);
const PlayerBehaviour = require("../Game/PlayerBehaviour");
const DoubleLinkedList = require("../Utility/DoubleLinkedList");
global.actionContext = new DoubleLinkedList();
module.exports = async function (ws) {
console.info("Before open for", ws.username, Game.state, ws.isAdmin);
if (Game.state === 0 && !ws.isAdmin) return ws.end(1337);
ws.connectedAt = Date.now();
let abruptDisconnectTest = performance.now();
const ID = ws.accountID;
const sessionID = Date.now().toString(36) + Math.random().toString(36).substring(2) + "!" + ID;
socket.sockets[sessionID] = ws;
ws.id = sessionID;
ws.limiter = new Limiter({
countThreshold: 10,
timeThreshold: 1000
});
const alreadyConnectedPlayer = players[ID];
if (alreadyConnectedPlayer) {
const player = alreadyConnectedPlayer;
const alreadyConnectedSoket = socket.sockets[player.sessionID];
if (alreadyConnectedSoket) alreadyConnectedSoket.end(1);
player.sessionID = sessionID;
ws.subscribe(player.map.id.toString());
player.map.removePlayer(player.id);
player.map.addPlayer(player);
player.isUnderDisconnect = false;
player.cancelDisconnect();
const packet = EnvironmentSetupPacket(player.map.id);
return ws.send(packet, true, true);
};
const playerBehaviour = new PlayerBehaviour({
size: 16,
buffer: global.playerBehaviourContext,
id: ID
});
global.actionContext.addItem(ID, playerBehaviour);
const generalQuery = execute(QUERY_FETCH_PLAYER_DATA, [ID]);
const informationQuery = execute(QUERY_FETCH_PLAYER_INFORMATION, [ID]);
const guildQuery = execute(QUERY_FETCH_GUILD_INFORMATION, [ID]);
const questQuery = execute(QUERY_FETCH_ACTIVE_QUESTS, [ID]);
const statusQuery = execute(QUERY_FETCH_STATUS, [ID, true]);
const resourcesQuery = execute(QUERY_FETCH_RESOURCES, [ID]);
const equipmentsQuery = execute(QUERY_FETCH_EQUIPMENTS, [ID]);
const res = await Promise.all([generalQuery, informationQuery, guildQuery, questQuery, statusQuery, resourcesQuery, equipmentsQuery]);
const hasError = res.some(q => q.error !== undefined);
if (hasError) return;
if (ws.isInterrupted) return;
let isAlive = false;
let map = null;
let hitpoints = {
current: 0,
maximum: 0
};
let position = {};
let attemptToDoubleLog = false;
let maximumCannonRange = 0;
let maximumHarpoonerRange = 0;
let textureID = 0;
let sight = 0;
let speed = 0;
let globalRank = 0;
let levelRank = 0;
const playerFromDB = res[0].data[0];
const guildFromDB = res[2].data[0];
const questFromDB = res[3].data;
const statusFromDB = res[4].data;
const resourcesFromDB = res[5].data;
const equipmentsFromDB = res[6].data;
const statusPoints = [];
const guildID = guildFromDB ? guildFromDB.id : 0;
const guild = guilds[guildID];
const selectedAmmunition = playerFromDB ? playerFromDB.selectedAmmunitionID : 0;
const selectedHarpoon = playerFromDB ? playerFromDB.selectedHarpoonID : 0;
const resourceSharedLimiter = {
cannon: new EquipmentLimiter({
maximum: 50
}),
harpooner: new EquipmentLimiter({
maximum: 25
}),
sail: new EquipmentLimiter({
maximum: 5
}),
pirate: new EquipmentLimiter({
maximum: 250
})
};
const inventory = new Inventory({
resourceSharedLimiter
});
resourcesFromDB.forEach(r => {
switch (r.categoryID) {
case 6:
statusPoints.push(r);
break;
case 7:
case 8:
const equipment = equipmentsFromDB.find(e => e.id === r.id && e.categoryID === r.categoryID);
r.amountEquipped = equipment ? equipment.amountEquipped : 0;
break;
};
inventory.refreshSingle(r);
});
inventory.setSelectedAmmunition(selectedAmmunition);
inventory.setSelectedHarpoon(selectedHarpoon);
if (!attemptToDoubleLog) {
const playerHasData = playerFromDB ? true : false;
if (!playerHasData) {
const startingMap = maps.find(m => m.id === 1);
const { x, y } = startingMap.grid.randomNode(10);
textureID = 1;
sight = 450;
speed = 250;
globalRank = 1;
levelRank = 1;
isAlive = true;
map = startingMap;
position = {
x,
y
};
hitpoints = {
current: 10000,
maximum: 50000
};
baseStarterRewards.forEach(r => inventory.refreshSingle(r));
await execute(QUERY_INSERT_DEFAULT_PLAYER, [ID, x, y, 1]);
} else {
textureID = playerFromDB.designID;
sight = playerFromDB.sight;
speed = playerFromDB.speed;
globalRank = playerFromDB.globalRank;
levelRank = playerFromDB.levelRank;
isAlive = !!hitpoints;
map = maps.find(m => m.id === playerFromDB.mapID);
position = {
x: playerFromDB.x,
y: playerFromDB.y
};
hitpoints = {
current: playerFromDB.currentHitpoints,
maximum: playerFromDB.maximumHitpoints
};
};
};
const player = new Player({
id: ID,
sessionID: ws.id,
name: ws.username,
textureID,
map,
guild,
positionX: position.x,
positionY: position.y,
isAlive,
hitpoints,
maximumCannonRange,
maximumHarpoonerRange,
sight,
speed,
globalRank,
levelRank,
inventory,
statusPoints,
activeStatusEffects: statusFromDB,
quests: questFromDB,
rewardCallback,
attackCallback
});
player.setDesign(textureID);
ws.subscribe(player.map.id.toString());
playerEvents.forEach(e => player.on(e, playerHandlers[e]));
players[ID] = player;
const packet = EnvironmentSetupPacket(player.map.id);
ws.send(packet, true, true);
};