2015-07-22 16:28:15 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Gather Controller
|
|
|
|
*
|
|
|
|
* Server API
|
2015-07-22 23:30:14 +00:00
|
|
|
* gather:refresh - Refreshes active gather
|
2015-09-26 11:16:12 +00:00
|
|
|
* gather:archive:refresh - Refreshes gather archive
|
2015-07-22 23:30:14 +00:00
|
|
|
*
|
2015-07-22 16:28:15 +00:00
|
|
|
* Client API
|
2015-07-22 23:30:14 +00:00
|
|
|
* gather:join - Assigns user to gather
|
2015-07-24 13:34:02 +00:00
|
|
|
* gather:vote - Assigns vote to map, leader or server
|
2015-07-29 13:50:39 +00:00
|
|
|
* gather:leave - Leave gather
|
|
|
|
* gather:select - Select player for team
|
|
|
|
* gather:refresh - Refresh gather for client
|
2015-07-29 14:35:58 +00:00
|
|
|
* gather:reset - Resets gather (ADMIN)
|
|
|
|
*
|
2015-07-22 16:28:15 +00:00
|
|
|
*/
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
const Map = require("./map");
|
|
|
|
const Server = require("./server");
|
|
|
|
const mongoose = require("mongoose");
|
|
|
|
const GatherPool = require("./gather_pool");
|
|
|
|
const ArchivedGather = mongoose.model("ArchivedGather");
|
|
|
|
const Event = mongoose.model("Event");
|
|
|
|
const _ = require("lodash");
|
|
|
|
const winston = require("winston");
|
2015-07-27 11:55:36 +00:00
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
module.exports = function (namespace) {
|
2019-01-10 17:15:14 +00:00
|
|
|
const emitGather = (socket, gather) => {
|
|
|
|
socket.emit("gather:refresh", {
|
2019-02-14 20:21:29 +00:00
|
|
|
gather: gather ? gather.toJson() : null,
|
2019-01-10 17:15:14 +00:00
|
|
|
type: gather ? gather.type : null,
|
|
|
|
maps: Map.list,
|
|
|
|
});
|
2019-02-14 20:21:29 +00:00
|
|
|
};
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
const refreshArchive = () => {
|
2015-09-26 11:16:12 +00:00
|
|
|
ArchivedGather.recent((error, recentGathers) => {
|
|
|
|
if (error) return winston.error(error);
|
2015-09-27 11:55:00 +00:00
|
|
|
namespace.emit("gather:archive:refresh", {
|
|
|
|
archive: recentGathers,
|
2018-12-29 15:28:15 +00:00
|
|
|
maps: Map.list
|
2015-09-26 11:16:12 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
const refreshGather = type => {
|
|
|
|
if (type === undefined) {
|
|
|
|
for (let attr in gatherRefreshers) {
|
|
|
|
gatherRefreshers[attr].call();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const refresh = gatherRefreshers[type];
|
|
|
|
if (refresh) refresh();
|
2015-10-02 14:53:11 +00:00
|
|
|
}
|
2016-03-19 13:31:30 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 00:02:22 +00:00
|
|
|
const updateUserAsOnlineInGather = (userId) => {
|
|
|
|
return GatherPool.forEach((gatherManager, type) => {
|
|
|
|
for (var gatherer of gatherManager.current.gatherers) {
|
|
|
|
if (gatherer.user.id == userId && !gatherer.user.online) {
|
|
|
|
gatherer.user.online = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const refreshGathersWhereUserWentOffline = (userId) => {
|
|
|
|
return GatherPool.forEach((gatherManager, type) => {
|
|
|
|
for (var gatherer of gatherManager.current.gatherers) {
|
|
|
|
if (gatherer.user.id == userId && gatherer.user.online) {
|
|
|
|
gatherer.user.online = false;
|
|
|
|
gatherer.user.lastSeen = Date.now();
|
|
|
|
|
|
|
|
refreshGather(type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
const gatherRefreshers = {}; // Stores debounced procedures to refresh gathers
|
|
|
|
|
|
|
|
GatherPool.forEach((gatherManager, type) => {
|
|
|
|
let config = gatherManager.config;
|
|
|
|
gatherManager.registerCallback('onDone', refreshGather.bind(null, type));
|
|
|
|
gatherManager.registerCallback('onEvent', refreshGather.bind(null, type));
|
|
|
|
gatherManager.registerCallback('onEvent', (event, from, to) => {
|
|
|
|
if (from !== to) {
|
|
|
|
namespace.emit("stateChange", {
|
|
|
|
type: type,
|
|
|
|
event: event,
|
|
|
|
state: {
|
|
|
|
from: from,
|
|
|
|
to: to
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
gatherManager.onArchiveUpdate(refreshArchive);
|
|
|
|
|
|
|
|
gatherRefreshers[type] = _.debounce(function () {
|
|
|
|
namespace.emit("gather:refresh", {
|
2019-02-14 20:21:29 +00:00
|
|
|
gather: gatherManager.current ? gatherManager.current.toJson() : null,
|
2016-03-19 13:31:30 +00:00
|
|
|
type: gatherManager.current ? gatherManager.current.type : null,
|
|
|
|
maps: Map.list,
|
|
|
|
});
|
|
|
|
}, 200, {
|
|
|
|
leading: true,
|
|
|
|
trailing: true
|
|
|
|
});
|
|
|
|
|
|
|
|
gatherManager.restart();
|
2015-10-02 14:53:11 +00:00
|
|
|
});
|
2015-08-08 17:13:17 +00:00
|
|
|
|
|
|
|
// ***** Generate Test Users *****
|
2015-08-27 11:06:21 +00:00
|
|
|
if (process.env.POPULATE_GATHER) {
|
2015-09-14 16:50:00 +00:00
|
|
|
let helper = require("./helper");
|
2016-03-19 13:31:30 +00:00
|
|
|
|
|
|
|
GatherPool.forEach(gatherManager => {
|
2018-12-01 11:21:56 +00:00
|
|
|
helper.createTestUsers({
|
|
|
|
gather: gatherManager.current
|
|
|
|
}, refreshGather());
|
2016-03-19 13:31:30 +00:00
|
|
|
});
|
2015-08-27 11:06:21 +00:00
|
|
|
}
|
2019-02-14 20:21:29 +00:00
|
|
|
|
2015-08-08 17:13:17 +00:00
|
|
|
namespace.on("connection", function (socket) {
|
2020-02-12 00:02:22 +00:00
|
|
|
const connectedUserId = socket._user && socket._user.id;
|
|
|
|
|
|
|
|
updateUserAsOnlineInGather(connectedUserId);
|
|
|
|
|
2015-09-26 11:16:12 +00:00
|
|
|
ArchivedGather.recent((error, recentGathers) => {
|
|
|
|
if (error) return winston.error(error);
|
|
|
|
socket.emit("gather:archive:refresh", {
|
2015-09-27 11:55:00 +00:00
|
|
|
archive: recentGathers,
|
2018-12-29 15:28:15 +00:00
|
|
|
maps: Map.list
|
2015-09-26 11:16:12 +00:00
|
|
|
});
|
|
|
|
});
|
2019-02-14 20:21:29 +00:00
|
|
|
|
|
|
|
socket.on("disconnect", () => {
|
2020-02-12 00:02:22 +00:00
|
|
|
const onlineIds = Object.values(namespace.sockets).map(s => s._user.id);
|
|
|
|
|
|
|
|
// need to check if this disconnect actually meant user went offline
|
|
|
|
// they could have another tab open...
|
|
|
|
if (onlineIds.indexOf(connectedUserId) === -1) {
|
|
|
|
refreshGathersWhereUserWentOffline(connectedUserId);
|
|
|
|
}
|
2019-02-14 20:21:29 +00:00
|
|
|
});
|
2015-09-26 11:16:12 +00:00
|
|
|
|
2015-08-08 17:13:17 +00:00
|
|
|
socket.on("gather:join", function (data) {
|
2016-03-19 13:31:30 +00:00
|
|
|
if (!data) data = {};
|
|
|
|
const gatherManager = GatherPool.get(data.type);
|
|
|
|
if (!gatherManager) return;
|
|
|
|
const gather = gatherManager.current;
|
2016-04-17 14:37:50 +00:00
|
|
|
if (gather.can("addGatherer")) {
|
|
|
|
gather.addGatherer(socket._user);
|
|
|
|
if (gather.containsUser(socket._user)) {
|
|
|
|
Event.joiner(socket._user);
|
|
|
|
} else {
|
|
|
|
socket.emit("notify", {
|
|
|
|
type: "error",
|
|
|
|
message: "Unable to add you to the gather"
|
|
|
|
});
|
|
|
|
}
|
|
|
|
refreshGather(data.type);
|
|
|
|
}
|
2015-07-24 15:01:56 +00:00
|
|
|
});
|
2015-07-22 23:30:14 +00:00
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
socket.on("gather:refresh", function (data) {
|
|
|
|
// Refresh all gathers
|
|
|
|
if (!data) data = {};
|
|
|
|
if (data.type === undefined) {
|
|
|
|
GatherPool.forEach(manager => emitGather(socket, manager.current));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Otherwise refresh specified gather
|
|
|
|
const gatherManager = GatherPool.get(data.type);
|
|
|
|
if (gatherManager == undefined) return;
|
|
|
|
emitGather(socket, gatherManager.current)
|
2015-07-28 23:32:50 +00:00
|
|
|
});
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
const removeGatherer = (gather, user) => {
|
2016-02-18 14:59:42 +00:00
|
|
|
let gatherLeaver = gather.getGatherer(user);
|
2020-02-12 00:01:20 +00:00
|
|
|
|
|
|
|
if (!gatherLeaver) {
|
|
|
|
winston.info(`${user.username} ${user.id} attempted to leave ${gather.type} gather, but was not in gather.`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-18 14:59:42 +00:00
|
|
|
if (gather.can("removeGatherer")) {
|
|
|
|
gather.removeGatherer(user);
|
|
|
|
}
|
2015-10-03 15:55:42 +00:00
|
|
|
if (user.cooldown) gather.applyCooldown(user);
|
2020-02-12 00:02:22 +00:00
|
|
|
|
2016-02-18 14:59:42 +00:00
|
|
|
Event.leaver(gatherLeaver.user);
|
2016-03-19 13:31:30 +00:00
|
|
|
refreshGather(gather.type);
|
2015-09-17 12:36:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
socket.on("gather:leave", function (data) {
|
2016-03-19 13:31:30 +00:00
|
|
|
if (!data) data = {};
|
|
|
|
const gatherManager = GatherPool.get(data.type);
|
|
|
|
if (!gatherManager) return;
|
|
|
|
const gather = gatherManager.current;
|
|
|
|
if (data.gatherer) {
|
2015-09-17 12:36:18 +00:00
|
|
|
// Remove gatherer defined by ID (admins only)
|
2015-10-20 22:40:40 +00:00
|
|
|
if (!socket._user.isGatherAdmin()) return;
|
2018-12-15 14:44:44 +00:00
|
|
|
|
|
|
|
removeGatherer(gather, { id: data.gatherer, cooldown: true });
|
|
|
|
let adminName = socket._user.username;
|
|
|
|
let playerId = data.gatherer;
|
|
|
|
winston.info(`Admin removal: ${adminName} removed ${playerId} from the gather.`);
|
2015-09-17 12:36:18 +00:00
|
|
|
} else {
|
|
|
|
// Remove gatherer attached to socket
|
2016-03-19 13:31:30 +00:00
|
|
|
removeGatherer(gather, socket._user);
|
2015-09-17 12:36:18 +00:00
|
|
|
}
|
2015-07-24 15:01:56 +00:00
|
|
|
});
|
|
|
|
|
2015-07-28 23:32:50 +00:00
|
|
|
socket.on("gather:select", function (data) {
|
2016-03-19 13:31:30 +00:00
|
|
|
if (!data) data = {};
|
|
|
|
const gatherManager = GatherPool.get(data.type);
|
|
|
|
if (!gatherManager) return;
|
|
|
|
const gather = gatherManager.current;
|
|
|
|
|
2015-09-14 16:50:00 +00:00
|
|
|
let playerId = data.player;
|
2015-07-28 23:32:50 +00:00
|
|
|
// Check team & leader
|
2016-03-19 13:59:48 +00:00
|
|
|
let gatherer = gather.getGatherer(socket._user);
|
2015-07-28 23:32:50 +00:00
|
|
|
|
|
|
|
// Cancel if not gatherer or leader
|
2016-03-19 13:31:30 +00:00
|
|
|
if (gatherer === null || gatherer.leader === false) {
|
2015-07-28 23:32:50 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cancel if id belongs to a leader
|
2016-03-19 13:59:48 +00:00
|
|
|
let selectedPlayer = gather.getGatherer({id: playerId});
|
2015-07-28 23:32:50 +00:00
|
|
|
|
|
|
|
if (selectedPlayer === null || selectedPlayer.leader) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
let team = gatherer.team;
|
2015-07-28 23:32:50 +00:00
|
|
|
|
2015-09-14 16:50:00 +00:00
|
|
|
let method = (team === 'alien') ? gather.moveToAlien : gather.moveToMarine;
|
2015-09-16 15:16:00 +00:00
|
|
|
method.call(gather, selectedPlayer.user, socket._user);
|
|
|
|
|
|
|
|
// Check if last player and add to last team
|
|
|
|
if (gather.lobby().length === 1) {
|
2018-12-01 11:21:56 +00:00
|
|
|
let assignLast = (gather.marines().length === 6) ?
|
2015-09-16 15:16:00 +00:00
|
|
|
gather.moveToAlien : gather.moveToMarine;
|
|
|
|
assignLast.call(gather, gather.lobby().pop());
|
|
|
|
}
|
2015-07-28 23:32:50 +00:00
|
|
|
|
|
|
|
if (gather.can("confirmSelection")) {
|
2015-07-29 14:54:45 +00:00
|
|
|
gather.confirmSelection(socket._user);
|
2015-07-28 23:32:50 +00:00
|
|
|
}
|
2015-07-29 14:35:58 +00:00
|
|
|
|
2016-01-02 21:32:26 +00:00
|
|
|
Event.playerSelected(socket._user, data, gather);
|
2015-09-14 21:40:49 +00:00
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
refreshGather(data.type);
|
2015-07-28 23:32:50 +00:00
|
|
|
});
|
|
|
|
|
2015-07-22 23:30:14 +00:00
|
|
|
socket.on("gather:vote", function (data) {
|
2016-03-19 13:31:30 +00:00
|
|
|
if (!data) data = {};
|
|
|
|
const gatherManager = GatherPool.get(data.type);
|
|
|
|
if (!gatherManager) return;
|
|
|
|
const gather = gatherManager.current;
|
|
|
|
|
2015-07-27 11:55:36 +00:00
|
|
|
if (data.leader) {
|
|
|
|
gather.selectLeader(socket._user, data.leader.candidate);
|
2016-01-02 21:32:26 +00:00
|
|
|
Event.leaderVote(socket._user, data, gather);
|
2015-07-27 11:55:36 +00:00
|
|
|
}
|
2015-07-29 13:50:39 +00:00
|
|
|
|
|
|
|
if (data.map) {
|
2015-12-25 08:01:08 +00:00
|
|
|
gather.toggleMapVote(socket._user, data.map.id);
|
2016-01-02 21:32:26 +00:00
|
|
|
Event.mapVote(socket._user, data, gather, Map.list);
|
2015-07-29 13:50:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (data.server) {
|
2016-01-02 21:32:26 +00:00
|
|
|
gather.toggleServerVote(socket._user, data.server.id);
|
|
|
|
Event.serverVote(socket._user, data, gather, Server.list);
|
2015-07-29 13:50:39 +00:00
|
|
|
}
|
|
|
|
|
2015-09-17 13:56:50 +00:00
|
|
|
if (typeof data.regather === 'boolean' && gather.can("regather")) {
|
|
|
|
gather.regather(socket._user, data.regather);
|
|
|
|
}
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
refreshGather(data.type);
|
2015-07-22 23:30:14 +00:00
|
|
|
});
|
2015-07-24 15:01:56 +00:00
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
socket.on("gather:reset", function (data) {
|
|
|
|
if (!data) data = {};
|
|
|
|
const gatherManager = GatherPool.get(data.type);
|
|
|
|
if (!gatherManager) return;
|
2015-10-20 22:40:40 +00:00
|
|
|
if (socket._user.isGatherAdmin()) {
|
2016-03-19 23:37:28 +00:00
|
|
|
gatherManager.reset();
|
2016-03-19 13:31:30 +00:00
|
|
|
refreshGather(data.type);
|
2016-01-02 21:32:26 +00:00
|
|
|
Event.adminRegather(socket._user);
|
2015-07-29 14:35:58 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-03-19 13:31:30 +00:00
|
|
|
// Refresh gather
|
|
|
|
for (let attr in gatherRefreshers) {
|
|
|
|
gatherRefreshers[attr].call();
|
|
|
|
}
|
2015-07-22 23:30:14 +00:00
|
|
|
});
|
2015-07-22 16:28:15 +00:00
|
|
|
};
|