noname/game/server.js

403 lines
9.3 KiB
JavaScript
Raw Permalink Normal View History

2024-04-15 16:49:47 +00:00
(function () {
var WebSocketServer = require("ws").Server;
var wss = new WebSocketServer({ port: 8080 });
var bannedKeys = [];
var bannedIps = [];
2021-03-06 10:57:22 +00:00
2024-04-15 16:49:47 +00:00
var rooms = [];
var events = [];
var clients = {};
var bannedKeyWords = [];
var messages = {
create: function (key, nickname, avatar, config, mode) {
if (this.onlineKey != key) return;
this.nickname = util.getNickname(nickname);
this.avatar = avatar;
var room = {};
2021-09-20 10:56:11 +00:00
rooms.push(room);
2024-04-15 16:49:47 +00:00
this.room = room;
2021-09-20 10:56:11 +00:00
delete this.status;
2024-04-15 16:49:47 +00:00
room.owner = this;
room.key = key;
this.sendl("createroom", key);
2021-09-20 10:56:11 +00:00
},
2024-04-15 16:49:47 +00:00
enter: function (key, nickname, avatar) {
this.nickname = util.getNickname(nickname);
this.avatar = avatar;
var room = false;
for (var i of rooms) {
if (i.key == key) {
room = i;
2021-09-20 10:56:11 +00:00
break;
}
}
2024-04-15 16:49:47 +00:00
if (!room) {
this.sendl("enterroomfailed");
2021-09-20 10:56:11 +00:00
return;
2021-03-06 10:57:22 +00:00
}
2024-04-15 16:49:47 +00:00
this.room = room;
2021-03-06 10:57:22 +00:00
delete this.status;
2024-04-15 16:49:47 +00:00
if (room.owner) {
if (
room.servermode &&
!room.owner._onconfig &&
config &&
mode
) {
room.owner.sendl("createroom", index, config, mode);
room.owner._onconfig = this;
room.owner.nickname = util.getNickname(nickname);
room.owner.avatar = avatar;
} else if (
!room.config ||
(room.config.gameStarted &&
(!room.config.observe || !room.config.observeReady))
) {
this.sendl("enterroomfailed");
} else {
this.owner = room.owner;
this.owner.sendl("onconnection", this.wsid);
2021-03-06 10:57:22 +00:00
}
util.updaterooms();
}
},
2024-04-15 16:49:47 +00:00
changeAvatar: function (nickname, avatar) {
this.nickname = util.getNickname(nickname);
this.avatar = avatar;
2021-03-06 10:57:22 +00:00
util.updateclients();
},
2024-04-15 16:49:47 +00:00
server: function (cfg) {
if (cfg) {
this.servermode = true;
var room = rooms[cfg[0]];
if (!room || room.owner) {
this.sendl("reloadroom", true);
} else {
room.owner = this;
this.room = room;
this.nickname = util.getNickname(cfg[1]);
this.avatar = cfg[2];
this.sendl("createroom", cfg[0], {}, "auto");
2021-03-06 10:57:22 +00:00
}
2024-04-15 16:49:47 +00:00
} else {
for (var i = 0; i < rooms.length; i++) {
if (!rooms[i].owner) {
rooms[i].owner = this;
rooms[i].servermode = true;
this.room = rooms[i];
this.servermode = true;
2021-03-06 10:57:22 +00:00
break;
}
}
util.updaterooms();
}
},
2024-04-15 16:49:47 +00:00
key: function (id) {
if (!id || typeof id != "object") {
this.sendl("denied", "key");
2021-03-06 10:57:22 +00:00
this.close();
clearTimeout(this.keyCheck);
delete this.keyCheck;
return;
2024-04-15 16:49:47 +00:00
} else if (bannedKeys.indexOf(id[0]) != -1) {
2021-03-06 10:57:22 +00:00
bannedIps.push(this._socket.remoteAddress);
this.close();
}
2024-04-15 16:49:47 +00:00
this.onlineKey = id[0];
2021-03-06 10:57:22 +00:00
clearTimeout(this.keyCheck);
delete this.keyCheck;
},
2024-04-15 16:49:47 +00:00
events: function (cfg, id, type) {
if (
bannedKeys.indexOf(id) != -1 ||
typeof id != "string" ||
this.onlineKey != id
) {
2021-03-06 10:57:22 +00:00
bannedIps.push(this._socket.remoteAddress);
console.log(id, this._socket.remoteAddress);
this.close();
return;
}
2024-04-15 16:49:47 +00:00
var changed = false;
var time = new Date().getTime();
if (cfg && id) {
if (typeof cfg == "string") {
for (var i = 0; i < events.length; i++) {
if (events[i].id == cfg) {
if (type == "join") {
if (events[i].members.indexOf(id) == -1) {
2021-03-06 10:57:22 +00:00
events[i].members.push(id);
}
2024-04-15 16:49:47 +00:00
changed = true;
} else if (type == "leave") {
var index = events[i].members.indexOf(id);
if (index != -1) {
events[i].members.splice(index, 1);
if (events[i].members.length == 0) {
events.splice(i--, 1);
2021-03-06 10:57:22 +00:00
}
}
2024-04-15 16:49:47 +00:00
changed = true;
2021-03-06 10:57:22 +00:00
}
}
}
2024-04-15 16:49:47 +00:00
} else if (
cfg.hasOwnProperty("utc") &&
cfg.hasOwnProperty("day") &&
cfg.hasOwnProperty("hour") &&
cfg.hasOwnProperty("content")
) {
if (events.length >= 20) {
this.sendl("eventsdenied", "total");
} else if (cfg.utc <= time) {
this.sendl("eventsdenied", "time");
} else if (util.isBanned(cfg.content)) {
this.sendl("eventsdenied", "ban");
} else {
cfg.nickname = util.getNickname(cfg.nickname);
cfg.avatar = cfg.nickname || "caocao";
cfg.creator = id;
cfg.id = util.getid();
cfg.members = [id];
2021-03-06 10:57:22 +00:00
events.unshift(cfg);
2024-04-15 16:49:47 +00:00
changed = true;
2021-03-06 10:57:22 +00:00
}
}
}
2024-04-15 16:49:47 +00:00
if (changed) {
2021-03-06 10:57:22 +00:00
util.updateevents();
}
},
2024-04-15 16:49:47 +00:00
config: function (config) {
var room = this.room;
if (room && room.owner == this) {
if (room.servermode) {
room.servermode = false;
if (this._onconfig) {
if (clients[this._onconfig.wsid]) {
this._onconfig.owner = this;
this.sendl("onconnection", this._onconfig.wsid);
2021-03-06 10:57:22 +00:00
}
delete this._onconfig;
}
}
2024-04-15 16:49:47 +00:00
room.config = config;
2021-03-06 10:57:22 +00:00
}
util.updaterooms();
},
2024-04-15 16:49:47 +00:00
status: function (str) {
if (typeof str == "string") {
this.status = str;
} else {
2021-03-06 10:57:22 +00:00
delete this.status;
}
util.updateclients();
},
2024-04-15 16:49:47 +00:00
send: function (id, message) {
if (clients[id] && clients[id].owner == this) {
try {
2021-03-06 10:57:22 +00:00
clients[id].send(message);
2024-04-15 16:49:47 +00:00
} catch (e) {
2021-03-06 10:57:22 +00:00
clients[id].close();
}
}
},
2024-04-15 16:49:47 +00:00
close: function (id) {
if (clients[id] && clients[id].owner == this) {
2021-03-06 10:57:22 +00:00
clients[id].close();
}
},
};
2024-04-15 16:49:47 +00:00
var util = {
getNickname: function (str) {
return typeof str == "string" ? str.slice(0, 12) : "无名玩家";
2021-10-05 15:46:56 +00:00
},
2024-04-15 16:49:47 +00:00
isBanned: function (str) {
for (var i of bannedKeyWords) {
if (str.indexOf(i) != -1) return true;
2021-03-06 10:57:22 +00:00
}
return false;
},
2024-04-15 16:49:47 +00:00
sendl: function () {
var args = [];
for (var i = 0; i < arguments.length; i++) {
2021-03-06 10:57:22 +00:00
args.push(arguments[i]);
}
2024-04-15 16:49:47 +00:00
try {
2021-03-06 10:57:22 +00:00
this.send(JSON.stringify(args));
2024-04-15 16:49:47 +00:00
} catch (e) {
2021-03-06 10:57:22 +00:00
this.close();
}
},
2024-04-15 16:49:47 +00:00
getid: function () {
return Math.floor(
1000000000 + 9000000000 * Math.random()
).toString();
2021-03-06 10:57:22 +00:00
},
2024-04-15 16:49:47 +00:00
getroomlist: function () {
var roomlist = [];
for (var i = 0; i < rooms.length; i++) {
rooms[i]._num = 0;
2021-03-06 10:57:22 +00:00
}
2024-04-15 16:49:47 +00:00
for (var i in clients) {
if (clients[i].room && !clients[i].servermode) {
2021-03-06 10:57:22 +00:00
clients[i].room._num++;
}
}
2024-04-15 16:49:47 +00:00
for (var i = 0; i < rooms.length; i++) {
if (rooms[i].servermode) {
roomlist[i] = "server";
} else if (rooms[i].owner && rooms[i].config) {
if (rooms[i]._num == 0) {
rooms[i].owner.sendl("reloadroom");
2021-03-06 10:57:22 +00:00
}
2024-04-15 16:49:47 +00:00
roomlist.push([
rooms[i].owner.nickname,
rooms[i].owner.avatar,
rooms[i].config,
rooms[i]._num,
rooms[i].key,
]);
2021-03-06 10:57:22 +00:00
}
delete rooms[i]._num;
}
return roomlist;
},
2024-04-15 16:49:47 +00:00
getclientlist: function () {
var clientlist = [];
for (var i in clients) {
clientlist.push([
clients[i].nickname,
clients[i].avatar,
!clients[i].room,
clients[i].status,
clients[i].wsid,
clients[i].onlineKey,
]);
2021-03-06 10:57:22 +00:00
}
return clientlist;
},
2024-04-15 16:49:47 +00:00
updaterooms: function () {
var roomlist = util.getroomlist();
var clientlist = util.getclientlist();
for (var i in clients) {
if (!clients[i].room) {
clients[i].sendl("updaterooms", roomlist, clientlist);
2021-03-06 10:57:22 +00:00
}
}
},
2024-04-15 16:49:47 +00:00
updateclients: function () {
var clientlist = util.getclientlist();
for (var i in clients) {
if (!clients[i].room) {
clients[i].sendl("updateclients", clientlist);
2021-03-06 10:57:22 +00:00
}
}
},
2024-04-15 16:49:47 +00:00
checkevents: function () {
if (events.length) {
var time = new Date().getTime();
for (var i = 0; i < events.length; i++) {
if (events[i].utc <= time) {
events.splice(i--, 1);
2021-03-06 10:57:22 +00:00
}
}
}
return events;
},
2024-04-15 16:49:47 +00:00
updateevents: function () {
2021-03-06 10:57:22 +00:00
util.checkevents();
2024-04-15 16:49:47 +00:00
for (var i in clients) {
if (!clients[i].room) {
clients[i].sendl("updateevents", events);
2021-03-06 10:57:22 +00:00
}
}
2024-04-15 16:49:47 +00:00
},
2021-03-06 10:57:22 +00:00
};
2024-04-15 16:49:47 +00:00
wss.on("connection", function (ws) {
ws.sendl = util.sendl;
if (bannedIps.indexOf(ws._socket.remoteAddress) != -1) {
ws.sendl("denied", "banned");
setTimeout(function () {
2021-03-06 10:57:22 +00:00
ws.close();
2024-04-15 16:49:47 +00:00
}, 500);
2021-03-06 10:57:22 +00:00
return;
}
2024-04-15 16:49:47 +00:00
ws.keyCheck = setTimeout(function () {
ws.sendl("denied", "key");
setTimeout(function () {
2021-03-06 10:57:22 +00:00
ws.close();
2024-04-15 16:49:47 +00:00
}, 500);
}, 2000);
ws.wsid = util.getid();
clients[ws.wsid] = ws;
ws.sendl(
"roomlist",
util.getroomlist(),
util.checkevents(),
util.getclientlist(ws),
ws.wsid
);
ws.heartbeat = setInterval(function () {
if (ws.beat) {
2021-03-06 10:57:22 +00:00
ws.close();
clearInterval(ws.heartbeat);
2024-04-15 16:49:47 +00:00
} else {
ws.beat = true;
try {
ws.send("heartbeat");
} catch (e) {
2021-03-06 10:57:22 +00:00
ws.close();
}
}
2024-04-15 16:49:47 +00:00
}, 60000);
ws.on("message", function (message) {
if (!clients[this.wsid]) return;
if (message == "heartbeat") {
this.beat = false;
} else if (this.owner) {
this.owner.sendl("onmessage", this.wsid, message);
} else {
2021-03-06 10:57:22 +00:00
var arr;
2024-04-15 16:49:47 +00:00
try {
arr = JSON.parse(message);
if (!Array.isArray(arr)) {
throw "err";
2021-03-06 10:57:22 +00:00
}
2024-04-15 16:49:47 +00:00
} catch (e) {
this.sendl("denied", "banned");
2021-03-06 10:57:22 +00:00
return;
}
2024-04-15 16:49:47 +00:00
if (arr.shift() == "server") {
var type = arr.shift();
if (messages[type]) {
messages[type].apply(this, arr);
2021-03-06 10:57:22 +00:00
}
}
}
});
2024-04-15 16:49:47 +00:00
ws.on("close", function () {
for (var i = 0; i < rooms.length; i++) {
if (rooms[i].owner == this) {
for (var j in clients) {
if (clients[j].room == rooms[i] && clients[j] != this) {
clients[j].sendl("selfclose");
2021-03-06 10:57:22 +00:00
// clients[j].close();
// delete clients[j];
}
}
2024-04-15 16:49:47 +00:00
rooms.splice(i--, 1);
2021-03-06 10:57:22 +00:00
}
}
2024-04-15 16:49:47 +00:00
if (clients[this.wsid]) {
if (this.owner) {
this.owner.sendl("onclose", this.wsid);
2021-03-06 10:57:22 +00:00
}
delete clients[this.wsid];
}
2024-04-15 16:49:47 +00:00
if (this.room) util.updaterooms();
2021-03-06 10:57:22 +00:00
else util.updateclients();
});
});
2024-04-15 16:49:47 +00:00
})();