init: add workspace files
This commit is contained in:
341
os/world.js
Normal file
341
os/world.js
Normal file
@@ -0,0 +1,341 @@
|
||||
|
||||
require("./util/util");
|
||||
const db = require("./util/data");
|
||||
WORLD = {
|
||||
USERS: [],
|
||||
COMMANDS: {},
|
||||
SKILLS: {},
|
||||
ROOMS: {},
|
||||
RUN_ROOMS: [],
|
||||
DEFAULT_SKILLS: {},
|
||||
AREAS: [],
|
||||
TASKS: [],
|
||||
SYSTEMTASKS: [],
|
||||
USER_EVENTS: [],
|
||||
OBJ_STROE: new Map(),
|
||||
NPC_STROE: new Map(),
|
||||
HEARTBEATCOUNT: 0,
|
||||
RECEIVED: [],
|
||||
LOGS: [],
|
||||
SERVERID: 0,
|
||||
SERVERS: [],
|
||||
CONNECT_COUNT: 0,
|
||||
DATA: require('./data'),
|
||||
USERLOGIN: require('./login'),
|
||||
DB: db,
|
||||
SocketCount: 0,
|
||||
LISTENER: require("./ws"),
|
||||
max_connect_count: 1100,
|
||||
max_user_count: 5100,
|
||||
MESSAGE: {
|
||||
stores: new Map(),
|
||||
NOTICES: [],
|
||||
},
|
||||
STATS: {
|
||||
TOPS: [],
|
||||
EXP: [],
|
||||
SCORE: [],
|
||||
WEAPON: [],
|
||||
},
|
||||
status: -1,//-1关闭 0正常 >1 用户等级>连接
|
||||
SocketIn: function () {
|
||||
this.SocketCount++;
|
||||
},
|
||||
connect: function (socket) {
|
||||
if (WORLD.status < 0)
|
||||
return socket.end();
|
||||
if (!WORLD.check_connect(socket))
|
||||
return socket.end();
|
||||
|
||||
socket.user = new USER();
|
||||
|
||||
socket.user.socket = socket;
|
||||
socket.user.wait_input = this.USERLOGIN.check_session.bind(this.USERLOGIN);
|
||||
|
||||
socket.setTimeout(60000);
|
||||
},
|
||||
check_connect: function (socket) {
|
||||
return true;
|
||||
},
|
||||
before_login: function (user) {
|
||||
if (this.status < 0) return false;
|
||||
if (this.status === 0) return true;
|
||||
return this.status <= user.user_level;
|
||||
},
|
||||
disconnect: function (socket) {
|
||||
if (socket.user) {
|
||||
socket.user.socket = null;
|
||||
socket.user.disconnect();
|
||||
}
|
||||
this.SocketCount--;
|
||||
if (socket.oserver) {
|
||||
socket.oserver.disconnect();
|
||||
socket.oserver = null;
|
||||
}
|
||||
}, request: function (request, socket) {
|
||||
if (!request) return;
|
||||
var user = socket.user;
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
if (user.request_count > 20) {
|
||||
return user.send("不要急,慢慢来。");
|
||||
}
|
||||
user.request_count = user.request_count + 1;
|
||||
var time = Date.now();
|
||||
try {
|
||||
user.command(request);
|
||||
} catch (e) {
|
||||
console.log(user.name, "命令错误:", request, e.message, e.stack);
|
||||
WORLD.log(user, request, e.message + e.stack);
|
||||
}
|
||||
WORLD.RECEIVED.push({
|
||||
time: time,
|
||||
cmd: request + " " + (Date.now() - time).toString(),
|
||||
user: user.id
|
||||
});
|
||||
if (WORLD.RECEIVED.length > 1000) {
|
||||
WORLD.saveRequest();
|
||||
}
|
||||
}, saveRequest: function () {
|
||||
db.saveRequest(WORLD.RECEIVED);
|
||||
WORLD.RECEIVED.length = 0;
|
||||
},
|
||||
startup: async function (sid) {
|
||||
if (sid) {
|
||||
sid = parseInt(sid);
|
||||
this.SERVERS = await db.getServers();
|
||||
this.SERVER = this.getServer(sid);
|
||||
} else {
|
||||
this.SERVER = __CONFIG.def_server;
|
||||
}
|
||||
|
||||
if (!this.SERVER) throw "服务器设置错误,无法启动";
|
||||
this.SERVERID = this.SERVER.id;
|
||||
|
||||
await db.initDataDir();
|
||||
loadResource();
|
||||
await this.DATA.load();
|
||||
await this.LISTENER.start(this.SERVER.port);
|
||||
console.log("服务", this.SERVER.name, "(" + this.SERVERID + ")启动");
|
||||
console.log("ws://" + this.SERVER.ip + ":" + this.SERVER.port);
|
||||
this.heart_beat_service = setInterval(WORLD.heart_beat, __CONFIG.HEARTBEAT);
|
||||
|
||||
this.status = __CONFIG.CONNECT_LEVEL ?? 0;
|
||||
this.on_startup();
|
||||
if (this.status > 0)
|
||||
console.log('当前允许级别' + this.status + "账号登陆");
|
||||
},
|
||||
|
||||
|
||||
sendAll: function (msg) {
|
||||
for (var i = 0; i < WORLD.USERS.length; i++) {
|
||||
WORLD.USERS[i].send(msg);
|
||||
}
|
||||
},
|
||||
getUser: function (id) {
|
||||
if (!id) return;
|
||||
for (var i = 0; i < WORLD.USERS.length; i++) {
|
||||
if (WORLD.USERS[i].id == id) return WORLD.USERS[i];
|
||||
}
|
||||
|
||||
}, find_user: function (name) {
|
||||
if (!name) return;
|
||||
for (var i = 0; i < WORLD.USERS.length; i++) {
|
||||
if (WORLD.USERS[i].name == name) return WORLD.USERS[i];
|
||||
}
|
||||
},
|
||||
on_user_login: function (user) {
|
||||
|
||||
},
|
||||
on_user_cross_login: function (user) {
|
||||
|
||||
},
|
||||
on_startup: function () {
|
||||
|
||||
},
|
||||
on_user_quit: function (user) {
|
||||
|
||||
},
|
||||
on_user_relogin: function (user) {
|
||||
|
||||
}
|
||||
,
|
||||
on_heart_beat: function (user) {
|
||||
|
||||
},
|
||||
heart_beat: function () {
|
||||
var avtived_obj = null;
|
||||
try {
|
||||
const dt = Date.now();
|
||||
WORLD.CONNECT_COUNT = 0;
|
||||
for (let i = 0; i < WORLD.USERS.length; i++) {
|
||||
avtived_obj = WORLD.USERS[i];
|
||||
if (avtived_obj.socket) WORLD.CONNECT_COUNT++;
|
||||
avtived_obj.heart_beat(dt);
|
||||
}
|
||||
WORLD.on_heart_beat(dt);
|
||||
for (let i = 0; i < WORLD.RUN_ROOMS.length; i++) {
|
||||
avtived_obj = WORLD.RUN_ROOMS[i];
|
||||
avtived_obj.heart_beat(dt);
|
||||
}
|
||||
WORLD.HEARTBEATCOUNT++;
|
||||
if (WORLD.HEARTBEATCOUNT > 720) {
|
||||
WORLD.HEARTBEATCOUNT = 0;
|
||||
WORLD.save();
|
||||
console.log("数据已备份%d", Date.now() - dt);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(avtived_obj ? (avtived_obj.path ?? avtived_obj.name) : "", "心跳错误:", e, e.stack);
|
||||
WORLD.log(null, e.message, e.stack);
|
||||
}
|
||||
|
||||
},
|
||||
login_out: function (user) {
|
||||
this.on_user_quit(user);
|
||||
if (user.serverid === WORLD.SERVERID) {
|
||||
user.save();
|
||||
}
|
||||
WORLD.USERS.remove(user);
|
||||
|
||||
if (user.socket) {
|
||||
try {
|
||||
user.socket.end();
|
||||
user.socket.destroy();
|
||||
} catch (e) {
|
||||
console.log(e.message, e.stack);
|
||||
}
|
||||
}
|
||||
}, send: function (text) {
|
||||
for (var i = 0; i < this.USERS.length; i++) {
|
||||
this.USERS[i].send(text);
|
||||
}
|
||||
}, log: function (user, cmd, msg) {
|
||||
WORLD.LOGS.push({
|
||||
time: Date.now(),
|
||||
cmd: cmd,
|
||||
user: user ? user.name : "",
|
||||
msg: msg
|
||||
});
|
||||
if (WORLD.LOGS.length > 500) {
|
||||
db.saveLogs(WORLD.LOGS);
|
||||
WORLD.LOGS.length = 0;
|
||||
}
|
||||
}, saveLog: function () {
|
||||
db.saveLogs(WORLD.LOGS);
|
||||
WORLD.LOGS.length = 0;
|
||||
}
|
||||
,
|
||||
is_server: function (user) {
|
||||
return user.serverid == WORLD.SERVERID;
|
||||
},
|
||||
save: async function () {
|
||||
|
||||
var roles = [];
|
||||
for (var i = 0; i < WORLD.USERS.length; i++) {
|
||||
if (WORLD.USERS[i].serverid != WORLD.SERVERID) continue;
|
||||
roles.push(WORLD.USERS[i].getData());
|
||||
}
|
||||
try {
|
||||
console.time('saved');
|
||||
await db.saveRoles(roles);
|
||||
console.log('玩家数据已保存');
|
||||
await this.DATA.save();
|
||||
console.log('全局数据已经保存');
|
||||
await this.saveLog();
|
||||
await this.saveRequest();
|
||||
console.log('日志数据已经保存');
|
||||
console.timeEnd('saved');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('玩家数据保存失败', error.message);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
writeHeapSnapshot: function () {
|
||||
let v8 = UTIL.require('v8');
|
||||
let dt = new Date();
|
||||
let fname = __PATH.DATA + "/" + dt.getFullYear() + "_" + dt.getMonth() + "_"
|
||||
+ dt.getDate() + "_" + dt.getHours() + "_" + dt.getMinutes() + ".heapsnapshot";
|
||||
v8.writeHeapSnapshot(fname);
|
||||
console.log('快照保存到', fname);
|
||||
}
|
||||
,
|
||||
loadLocalData: function () {
|
||||
let data = db.getLocalRoles();
|
||||
if (!data || !data.length) return;
|
||||
console.log("加载上次未保存的本地用户%d", data.length);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let user = new USER();
|
||||
user.loadData(data[i]);
|
||||
this.USERS.push(user);
|
||||
}
|
||||
db.deleteLocalRoles();
|
||||
},
|
||||
on_cross_response: function (id, sid) {
|
||||
//允许跨服
|
||||
},
|
||||
can_cross: function (id) {
|
||||
//允许跨服
|
||||
}, on_user_die: function (me, killer, corpse) {
|
||||
|
||||
}, on_resource_loaded: function () {
|
||||
|
||||
}
|
||||
};
|
||||
function loadResource() {
|
||||
let fs = require("fs");
|
||||
function readdir(basePath, path) {
|
||||
path = path || basePath;
|
||||
let files = fs.readdirSync(path);
|
||||
let count = 0;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let sub_path = path + files[i];
|
||||
let stat = fs.statSync(sub_path);
|
||||
if (stat.isDirectory()) {
|
||||
count += readdir(basePath, sub_path + "/");
|
||||
} else {
|
||||
let fname = sub_path.replace(basePath, "").replace(".js", "");
|
||||
BASE.CREATE(basePath, fname);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
try {
|
||||
let sum = 0;
|
||||
let count = readdir(__PATH.EXTENDS);
|
||||
console.log("%s %d ", __PATH.EXTENDS, count);
|
||||
sum += count;
|
||||
count = readdir(__PATH.COMMAND);
|
||||
console.log("%s%d ", __PATH.COMMAND, count);
|
||||
sum += count;
|
||||
count = readdir(__PATH.FAMILY);
|
||||
console.log("%s %d ", __PATH.FAMILY, count);
|
||||
sum += count;
|
||||
|
||||
|
||||
count = readdir(__PATH.OBJ);
|
||||
console.log("%s %d ", __PATH.OBJ, count);
|
||||
sum += count;
|
||||
|
||||
count = readdir(__PATH.AREA);
|
||||
console.log("%s %d ", __PATH.AREA, count);
|
||||
sum += count;
|
||||
|
||||
count = readdir(__PATH.SKILL);
|
||||
console.log("%s %d ", __PATH.SKILL, count);
|
||||
sum += count;
|
||||
|
||||
count = readdir(__PATH.MAP);
|
||||
console.log("%s %d ", __PATH.MAP, count);
|
||||
sum += count;
|
||||
count = readdir(__PATH.TASK);
|
||||
console.log("%s %d ", __PATH.TASK, count);
|
||||
sum += count;
|
||||
console.log('资源脚本加载%d', sum);
|
||||
WORLD.on_resource_loaded();
|
||||
} catch (e) {
|
||||
console.log("error: ", e, e.stack);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user