优化 设置宽度限制

This commit is contained in:
Suwings 2020-10-08 12:13:27 +08:00
parent d5e043db35
commit 841ae19644
78 changed files with 511 additions and 2189 deletions

View File

@ -1 +1,4 @@
{}
{
"printWidth": 200,
"trailingComma":"none"
}

84
app.js
View File

@ -40,8 +40,7 @@ const tools = require("./core/tools");
//生成第一次配置文件
const INIT_CONFIG_PATH = "./model/init_config/";
const PRO_CONFIG = "./property.js";
if (!fs.existsSync(PRO_CONFIG))
tools.mCopyFileSync(INIT_CONFIG_PATH + "property.js", PRO_CONFIG);
if (!fs.existsSync(PRO_CONFIG)) tools.mCopyFileSync(INIT_CONFIG_PATH + "property.js", PRO_CONFIG);
//加载配置
require("./property");
@ -158,12 +157,7 @@ app.use("/public", express.static("./public"));
// console 中间件挂载
app.use((req, res, next) => {
// 部分请求不必显示
if (
req.originalUrl.indexOf("/api/") == -1 &&
req.originalUrl.indexOf("/fs/") == -1 &&
req.originalUrl.indexOf("/fs_auth/") == -1 &&
req.originalUrl.indexOf("/fs_auth/") == -1
) {
if (req.originalUrl.indexOf("/api/") == -1 && req.originalUrl.indexOf("/fs/") == -1 && req.originalUrl.indexOf("/fs_auth/") == -1 && req.originalUrl.indexOf("/fs_auth/") == -1) {
// MCSERVER.log('[', req.method.cyan, ']', '[', req.ip, ']', req.originalUrl);
}
if (MCSERVER.localProperty.is_allow_csrf) {
@ -226,13 +220,8 @@ process.on("unhandledRejection", (reason, p) => {
if (!fs.existsSync(RECORD_PARH)) fs.mkdirSync(RECORD_PARH);
// 生成不 git 同步的文件
if (!fs.existsSync(CENTEN_LOG_JSON_PATH))
tools.mCopyFileSync(
INIT_CONFIG_PATH + "info_reset.json",
CENTEN_LOG_JSON_PATH
);
if (!fs.existsSync(PUBLIC_URL_PATH))
tools.mCopyFileSync(INIT_CONFIG_PATH + "INIT_URL.js", PUBLIC_URL_PATH);
if (!fs.existsSync(CENTEN_LOG_JSON_PATH)) tools.mCopyFileSync(INIT_CONFIG_PATH + "info_reset.json", CENTEN_LOG_JSON_PATH);
if (!fs.existsSync(PUBLIC_URL_PATH)) tools.mCopyFileSync(INIT_CONFIG_PATH + "INIT_URL.js", PUBLIC_URL_PATH);
} catch (err) {
MCSERVER.error("初始化文件环境失败,建议重启,请检查以下报错:", err);
}
@ -242,20 +231,13 @@ process.on("unhandledRejection", (reason, p) => {
MCSERVER.infoLog("OnlineFs", "正在初始化文件管理路由与中间件 ");
//必须先进行登陆 且 fs API 请求必须为 Ajax 请求,得以保证跨域阻止
app.use(
["/fs/mkdir", "/fs/rm", "/fs/patse", "/fs/cp", "/fs/rename", "/fs/ls"],
function (req, res, next) {
if (req.session.fsos && req.xhr) {
next();
return;
}
res
.status(403)
.send(
"禁止访问:权限不足!您不能直接访问文件在线管理程序 API请通过正常流程"
);
app.use(["/fs/mkdir", "/fs/rm", "/fs/patse", "/fs/cp", "/fs/rename", "/fs/ls"], function (req, res, next) {
if (req.session.fsos && req.xhr) {
next();
return;
}
);
res.status(403).send("禁止访问:权限不足!您不能直接访问文件在线管理程序 API请通过正常流程");
});
//载入在线文件管理路由
app.use("/fs_auth", require("./onlinefs/controller/auth"));
@ -279,41 +261,27 @@ app.use("/fs", require("./onlinefs/controller/function"));
if (host == "::") host = "127.0.0.1";
//App Http listen
app.listen(
MCSERVER.localProperty.http_port,
MCSERVER.localProperty.http_ip,
() => {
MCSERVER.infoLog(
"HTTP",
"HTTP 模块监听: [ http://" +
(host || "127.0.0.1".yellow) +
":" +
port +
" ]"
);
app.listen(MCSERVER.localProperty.http_port, MCSERVER.localProperty.http_ip, () => {
MCSERVER.infoLog("HTTP", "HTTP 模块监听: [ http://" + (host || "127.0.0.1".yellow) + ":" + port + " ]");
//现在执行 FTP 服务器启动过程
ftpServerInterface.initFTPdServerOptions({
host: MCSERVER.localProperty.ftp_ip || "127.0.0.1",
port: MCSERVER.localProperty.ftp_port,
tls: null,
});
//现在执行 FTP 服务器启动过程
ftpServerInterface.initFTPdServerOptions({
host: MCSERVER.localProperty.ftp_ip || "127.0.0.1",
port: MCSERVER.localProperty.ftp_port,
tls: null,
});
if (MCSERVER.localProperty.ftp_is_allow) require("./ftpd/index"); //执行ftp逻辑
if (MCSERVER.localProperty.ftp_is_allow) require("./ftpd/index"); //执行ftp逻辑
MCSERVER.infoLog("INFO", "配置文件: property.js 文件");
MCSERVER.infoLog(
"INFO",
"文档参阅: https://github.com/suwings/mcsmanager"
);
MCSERVER.infoLog("INFO", "配置文件: property.js 文件");
MCSERVER.infoLog("INFO", "文档参阅: https://github.com/suwings/mcsmanager");
if (MCSERVER.allError <= 0) {
MCSERVER.infoLog("INFO", "控制面板已经启动");
} else {
MCSERVER.infoLog("INFO", "控制面板启动异常");
}
if (MCSERVER.allError <= 0) {
MCSERVER.infoLog("INFO", "控制面板已经启动");
} else {
MCSERVER.infoLog("INFO", "控制面板启动异常");
}
);
});
})();
//用于捕捉前方所有路由都未经过的请求,则可为 404 页面

View File

@ -34,11 +34,7 @@ class ServerProcess extends EventEmitter {
MCSERVER.log(["根:", this.dataModel.cwd].join(" "));
MCSERVER.log("-------------------------------");
if (
!this.dataModel.highCommande ||
this.dataModel.highCommande.trim().length <= 0
)
throw new Error("自定义参数非法,无法启动服务端");
if (!this.dataModel.highCommande || this.dataModel.highCommande.trim().length <= 0) throw new Error("自定义参数非法,无法启动服务端");
let commandArray = this.dataModel.highCommande.split(" ");
let javaPath = commandArray.shift();
//过滤
@ -71,8 +67,7 @@ class ServerProcess extends EventEmitter {
parList.push(tmpAddList[k]);
}
let commandString =
this.dataModel.java + " " + parList.toString().replace(/,/gim, " ");
let commandString = this.dataModel.java + " " + parList.toString().replace(/,/gim, " ");
//是否只获取命令字符串
if (onlyCommandString) return commandString;
@ -85,11 +80,7 @@ class ServerProcess extends EventEmitter {
MCSERVER.log(["根:", this.dataModel.cwd].join(" "));
MCSERVER.log("-------------------------------");
this.process = childProcess.spawn(
this.dataModel.java,
parList,
this.ProcessConfig
);
this.process = childProcess.spawn(this.dataModel.java, parList, this.ProcessConfig);
}
//使用 Docker API 启动进程
@ -100,18 +91,14 @@ class ServerProcess extends EventEmitter {
// 采用 Docker API 进行启动与监控
// 启动命令解析
let startCommande = "";
if (this.dataModel.highCommande.trim() != "")
startCommande = this.dataModel.highCommande;
if (this.dataModel.highCommande.trim() != "") startCommande = this.dataModel.highCommande;
else startCommande = this.templateStart(true);
const startCommandeArray = startCommande.split(" ");
let portmap = this.dataModel.dockerConfig.dockerPorts;
// 端口解析
var agreement = portmap.split("/");
var protocol = "tcp";
if (
agreement.length >= 2 &&
(agreement[1] === "udp" || agreement[1] === "tcp")
) {
if (agreement.length >= 2 && (agreement[1] === "udp" || agreement[1] === "tcp")) {
protocol = agreement[1];
}
portmap = portmap.split(":");
@ -193,13 +180,7 @@ class ServerProcess extends EventEmitter {
process.kill = () => {
auxContainer.kill().then(() => {
auxContainer.remove().then(() => {
MCSERVER.log(
"实例",
"[",
self.dataModel.name,
"]",
"容器已强制移除"
);
MCSERVER.log("实例", "[", self.dataModel.name, "]", "容器已强制移除");
});
});
};
@ -212,14 +193,7 @@ class ServerProcess extends EventEmitter {
// 容器流错误事件传递
stream.on("error", (err) => {
MCSERVER.error("服务器运行时异常,建议检查配置与环境", err);
self.printlnStdin([
"Error:",
err.name,
"\n Error Message:",
err.message,
"\n 进程 PID:",
self.process.pid || "启动失败,无法获取进程。",
]);
self.printlnStdin(["Error:", err.name, "\n Error Message:", err.message, "\n 进程 PID:", self.process.pid || "启动失败,无法获取进程。"]);
self.stop();
self.emit("error", err);
});
@ -237,17 +211,13 @@ class ServerProcess extends EventEmitter {
self.dataModel.lastDate = new Date().toLocaleString();
// 输出事件的传递
process.stdout.on("data", (data) =>
self.emit("console", iconv.decode(data, self.dataModel.oe))
);
process.stdout.on("data", (data) => self.emit("console", iconv.decode(data, self.dataModel.oe)));
// 产生事件开启
self.emit("open", self);
// 输出开服资料
self.printlnCommandLine(
"服务端 " + self.dataModel.name + " 执行开启命令."
);
self.printlnCommandLine("服务端 " + self.dataModel.name + " 执行开启命令.");
}
);
}
@ -258,16 +228,11 @@ class ServerProcess extends EventEmitter {
// 服务端时间权限判断
let timeResult = this.isDealLineDate();
if (timeResult) {
throw new Error(
"服务端于 " +
this.dataModel.timeLimitDate +
" 时间已到期,拒绝启动,请咨询管理员。"
);
throw new Error("服务端于 " + this.dataModel.timeLimitDate + " 时间已到期,拒绝启动,请咨询管理员。");
}
// 防止重复启动
if (this._run || this._loading)
throw new Error("服务端进程在运行或正在加载..");
if (this._run || this._loading) throw new Error("服务端进程在运行或正在加载..");
this._loading = true;
@ -313,18 +278,14 @@ class ServerProcess extends EventEmitter {
this.dockerStart().then(undefined, (error) => {
// Docker 启动时异常处理
MCSERVER.error("此服务器启动时异常,具体错误信息:", error);
this.printlnCommandLine(
"进程实例启动时失败,建议检查配置文件与启动参数"
);
this.printlnCommandLine("进程实例启动时失败,建议检查配置文件与启动参数");
this.stop();
});
// 阻止继续运行下去
return true;
} else {
// 确定是自定义命令启动还是模板正常方式启动。
this.dataModel.highCommande
? this.customCommandStart()
: this.templateStart();
this.dataModel.highCommande ? this.customCommandStart() : this.templateStart();
}
} catch (err) {
this.stop();
@ -339,36 +300,22 @@ class ServerProcess extends EventEmitter {
// 进程事件监听
this.process.on("error", (err) => {
MCSERVER.error("服务器运行时异常,建议检查配置与环境", err);
this.printlnStdin([
"Error:",
err.name,
"\n Error Message:",
err.message,
"\n 进程 PID:",
this.process.pid || "启动失败,无法获取进程。",
]);
this.printlnStdin(["Error:", err.name, "\n Error Message:", err.message, "\n 进程 PID:", this.process.pid || "启动失败,无法获取进程。"]);
this.stop();
this.emit("error", err);
});
// 进程启动成功确认
if (!this.process.pid) {
MCSERVER.error(
"服务端进程启动失败建议检查启动命令与参数是否正确pid:",
this.process.pid
);
MCSERVER.error("服务端进程启动失败建议检查启动命令与参数是否正确pid:", this.process.pid);
this.stop();
delete this.process;
throw new Error("服务端进程启动失败,建议检查启动命令与参数是否正确");
}
// 输出事件的传递
this.process.stdout.on("data", (data) =>
this.emit("console", iconv.decode(data, this.dataModel.oe))
);
this.process.stderr.on("data", (data) =>
this.emit("console", iconv.decode(data, this.dataModel.oe))
);
this.process.stdout.on("data", (data) => this.emit("console", iconv.decode(data, this.dataModel.oe)));
this.process.stderr.on("data", (data) => this.emit("console", iconv.decode(data, this.dataModel.oe)));
this.process.on("exit", (code) => {
this.emit("exit", code);
this.stop();
@ -386,9 +333,7 @@ class ServerProcess extends EventEmitter {
send(command) {
if (this._run) {
if (this.process.dockerContainer != null) {
this.process.stdin.write(
iconv.encode(command, this.dataModel.ie) + "\n"
);
this.process.stdin.write(iconv.encode(command, this.dataModel.ie) + "\n");
} else {
this.process.stdin.write(iconv.encode(command, this.dataModel.ie));
this.process.stdin.write("\n");
@ -460,22 +405,14 @@ class ServerProcess extends EventEmitter {
//输出一行到标准输出
printlnStdin(line) {
let str = ["[MCSMANAGER] [", tools.getFullTime(), "]:", line, "\r\n"].join(
" "
);
let str = ["[MCSMANAGER] [", tools.getFullTime(), "]:", line, "\r\n"].join(" ");
this.emit("console", str);
}
printlnCommandLine(line) {
this.emit(
"console",
"[MCSMANAGER] -------------------------------------------------------------- \r\n"
);
this.emit("console", "[MCSMANAGER] -------------------------------------------------------------- \r\n");
this.printlnStdin(line);
this.emit(
"console",
"[MCSMANAGER] -------------------------------------------------------------- \r\n"
);
this.emit("console", "[MCSMANAGER] -------------------------------------------------------------- \r\n");
}
isDealLineDate() {

View File

@ -34,8 +34,7 @@ class MinecraftServer extends ServerProcess {
// this.isDocker = false;
//Docker 配置项目
this.dataModel.dockerConfig = {
dockerCommand:
"docker run -i ${xmx} -v ${serverpath}:/mcsd/ ${ports} ${imagename} ${commande}",
dockerCommand: "docker run -i ${xmx} -v ${serverpath}:/mcsd/ ${ports} ${imagename} ${commande}",
dockerImageName: "mcsd",
dockerXmx: "",
dockerPorts: "",

View File

@ -44,9 +44,7 @@ class ServerManager extends EventEmitter {
fs.unlinkSync(BASE_SERVER_DIR + name + ".json");
delete this.serverList[name];
} catch (err) {
throw new Error(
"删除服务器出现错误,删除失败并且服务器可能已经损坏:" + err
);
throw new Error("删除服务器出现错误,删除失败并且服务器可能已经损坏:" + err);
}
}
@ -85,14 +83,8 @@ class ServerManager extends EventEmitter {
}
startMinecraftServer(name) {
if (!this.isExist(name))
throw new Error(
"您选择的服务器 [" +
name +
"] 似乎不存在,请重新创建或检查数据是否完整。"
);
if (this.serverList[name].isRun())
throw new Error("服务器已经运行,无法再继续运行");
if (!this.isExist(name)) throw new Error("您选择的服务器 [" + name + "] 似乎不存在,请重新创建或检查数据是否完整。");
if (this.serverList[name].isRun()) throw new Error("服务器已经运行,无法再继续运行");
return this.serverList[name].start();
}

View File

@ -52,11 +52,7 @@ class UserCenter {
//理应只有管理员可以操作
reUsername(username, newUsername) {
let oldDataModel = this.userList[username].dataModel;
let newUser = new User(
newUsername,
oldDataModel.password,
oldDataModel.salt
);
let newUser = new User(newUsername, oldDataModel.password, oldDataModel.salt);
//移植數據
// for (let k in oldDataModel) {
// if (k == '__filename__') continue;
@ -70,18 +66,8 @@ class UserCenter {
this.deleteUser(username);
}
loginCheck(
username,
password,
truecb,
falsecb,
md5key,
notSafeLogin = false
) {
if (
this.userList.hasOwnProperty(username) &&
this.userList[username] != undefined
) {
loginCheck(username, password, truecb, falsecb, md5key, notSafeLogin = false) {
if (this.userList.hasOwnProperty(username) && this.userList[username] != undefined) {
let loginUser = this.userList[username];
try {
loginUser.load();

View File

@ -12,10 +12,7 @@ module.exports.init = () => {
module.exports.load();
//定时清楚
setInterval(function () {
if (
new Date().getDate() == 1 &&
new Date().getMonth() + 1 >= dataModel.reloadMonth
) {
if (new Date().getDate() == 1 && new Date().getMonth() + 1 >= dataModel.reloadMonth) {
dataModel.reloadMonth = new Date().getMonth() + 2; //调至下个月
MCSERVER.log(" ---- 数据期限已到 清空数据统计 ---- ");
for (let i in initDataCallbackList) {
@ -29,8 +26,7 @@ module.exports.init = () => {
module.exports.load = () => {
dataModel.load();
counterMask = dataModel.counterData;
if (dataModel.reloadMonth == undefined)
dataModel.reloadMonth = new Date().getMonth() + 2; //下个月
if (dataModel.reloadMonth == undefined) dataModel.reloadMonth = new Date().getMonth() + 2; //下个月
dataModel.save();
return this;
};

View File

@ -7,18 +7,7 @@ if (!fs.existsSync("logs/")) fs.mkdirSync("logs");
// 启动时自动储存上次日志文件
if (fs.existsSync(LOG_FILE_PATH)) {
const date = new Date();
const logFilename =
date.getFullYear() +
"-" +
(date.getMonth() + 1) +
"-" +
date.getDay() +
"_" +
date.getHours() +
"-" +
date.getMinutes() +
"-" +
date.getSeconds();
const logFilename = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDay() + "_" + date.getHours() + "-" + date.getMinutes() + "-" + date.getSeconds();
fs.renameSync(LOG_FILE_PATH, "logs/" + logFilename + ".log");
}

View File

@ -31,8 +31,7 @@ module.exports.md5 = () => {
module.exports.randomString = (len) => {
len = len || 64;
var $chars =
"ABCDEFGHIJKLNMOPQRSTUVWXYZabcdefghijklnmopqrstuvwxyz1234567890_";
var $chars = "ABCDEFGHIJKLNMOPQRSTUVWXYZabcdefghijklnmopqrstuvwxyz1234567890_";
var maxPos = $chars.length;
var pwd = "";
for (let i = 0; i < len; i++) {
@ -74,19 +73,7 @@ module.exports.getSystemCodeing = () => {
module.exports.getFullTime = () => {
var date = new Date();
return (
date.getFullYear() +
"/" +
date.getMonth() +
"/" +
date.getDay() +
" " +
date.getHours() +
":" +
date.getMinutes() +
":" +
date.getSeconds()
);
return date.getFullYear() + "/" + date.getMonth() + "/" + date.getDay() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
};
const REPALCE_STR = "__MCSMANAGER_REPLACE_STR__";

View File

@ -63,23 +63,7 @@ module.exports.runFTPServer = () => {
FTPserver.debugging = 0;
FTPserver.listen(options.port);
MCSERVER.infoLog(
"FTP".green,
[
" FTP 被动传输端口范围: [",
MCSERVER.localProperty.ftp_start_port,
"-",
MCSERVER.localProperty.ftp_end_port,
"]",
].join(" ")
);
MCSERVER.infoLog("FTP".green, [" FTP 被动传输端口范围: [", MCSERVER.localProperty.ftp_start_port, "-", MCSERVER.localProperty.ftp_end_port, "]"].join(" "));
MCSERVER.infoLog(
"FTP".green,
" FTP 模块监听: [ ftp://" +
(options.host || "127.0.0.1".yellow) +
":" +
options.port +
" ]"
);
MCSERVER.infoLog("FTP".green, " FTP 模块监听: [ ftp://" + (options.host || "127.0.0.1".yellow) + ":" + options.port + " ]");
};

View File

@ -19,19 +19,12 @@ ftpServerInterface.createFTPServer({
let user = userModel.userCenter().get(realName);
let dataModel =
serverModel.ServerManager().getServer(serverName).dataModel || null;
let dataModel = serverModel.ServerManager().getServer(serverName).dataModel || null;
if (dataModel) {
MCSERVER.infoLog(
"Ftpd",
["用户", realName, "请求 FTP 访问 |", serverName, "| OK"].join(" ")
);
MCSERVER.infoLog("Ftpd", ["用户", realName, "请求 FTP 访问 |", serverName, "| OK"].join(" "));
return dataModel.cwd;
}
MCSERVER.warning(
"Ftpd 发现不明身份不明根目录者正在尝试访问",
["已经阻止 | 可能的值", username, serverName].join(" ")
);
MCSERVER.warning("Ftpd 发现不明身份不明根目录者正在尝试访问", ["已经阻止 | 可能的值", username, serverName].join(" "));
return null;
},
pasvPortRangeStart: MCSERVER.localProperty.ftp_start_port,
@ -50,10 +43,7 @@ ftpServerInterface.initFTPServerListener({
let arrName = usname.split(".");
let serverName = arrName[1];
let userName = arrName[0];
if (
serverModel.ServerManager().isExist(serverName) &&
permission.isCanServer(userName, serverName)
) {
if (serverModel.ServerManager().isExist(serverName) && permission.isCanServer(userName, serverName)) {
try {
return userModel.beliveLogin(userName, password);
} catch (e) {

View File

@ -47,11 +47,7 @@ module.exports.error = (res, error = new NullError(), statusCode = 500) => {
res.end();
};
module.exports.forbidden = (
res,
error = new ForbiddenError(),
statusCode = 403
) => {
module.exports.forbidden = (res, error = new ForbiddenError(), statusCode = 403) => {
res.send(
JSON.stringify({
status: statusCode,
@ -61,11 +57,7 @@ module.exports.forbidden = (
res.end();
};
module.exports.unavailable = (
res,
error = new UnavailableError(),
statusCode = 503
) => {
module.exports.unavailable = (res, error = new UnavailableError(), statusCode = 503) => {
res.send(
JSON.stringify({
status: statusCode,

View File

@ -37,13 +37,7 @@ class LogHistory {
}
} else {
fs.writeFile(this.path, text, (err) => {
if (err)
MCSERVER.log(
"实例",
this.id,
"日志历史记录文件创建错误:",
err.message
);
if (err) MCSERVER.log("实例", this.id, "日志历史记录文件创建错误:", err.message);
});
}
}
@ -74,12 +68,7 @@ class LogHistory {
// 倒置指针,从末尾开始读字符
fs.read(fd, buffer, 0, size, endReadPoint, (err, bytesRead, buffer) => {
if (err) {
MCSERVER.log(
"实例",
this.id,
"日志历史记录文件读取错误:",
err.message
);
MCSERVER.log("实例", this.id, "日志历史记录文件读取错误:", err.message);
fs.closeSync(fd);
return;
}
@ -118,12 +107,7 @@ class LogHistory {
// 倒置指针,从末尾开始读字符
fs.read(fd, buffer, 0, size, endReadPoint, (err, bytesRead, buffer) => {
if (err) {
MCSERVER.log(
"实例",
this.id,
"日志历史记录文件读取错误:",
err.message
);
MCSERVER.log("实例", this.id, "日志历史记录文件读取错误:", err.message);
return;
}
const logText = buffer.slice(0, bytesRead).toString();

View File

@ -1,8 +1,7 @@
var Logined = {};
module.exports.addLogined = (sessionID, username, userdata) => {
if (username && userdata && sessionID)
Logined[sessionID] = [username, userdata, Date.now()];
if (username && userdata && sessionID) Logined[sessionID] = [username, userdata, Date.now()];
else throw new Error("Username or Userdata is Null");
};

View File

@ -113,10 +113,7 @@ function CreateMCPingTask(id, ip, port) {
} else {
// 连续查询错误次数 300 次以上,即 30 分钟,主动销毁自身
TASK_OBJECT_DATABASE[id] && TASK_OBJECT_DATABASE[id].errorCount++;
if (
TASK_OBJECT_DATABASE[id] &&
TASK_OBJECT_DATABASE[id].errorCount > 300
) {
if (TASK_OBJECT_DATABASE[id] && TASK_OBJECT_DATABASE[id].errorCount > 300) {
DestroyMCPingTask(id);
}
}

View File

@ -2,8 +2,7 @@ const loginedContainer = require("./LoginedContainer");
function randomString(len) {
len = len || 32;
var $chars =
"ABCDEFGHIJKLNMOPQRSTUVWXYZabcdefghijklnmopqrstuvwxyz1234567890_";
var $chars = "ABCDEFGHIJKLNMOPQRSTUVWXYZabcdefghijklnmopqrstuvwxyz1234567890_";
var maxPos = $chars.length;
var pwd = "";
for (let i = 0; i < len; i++) {
@ -12,13 +11,7 @@ function randomString(len) {
return pwd;
}
function defaultFalseCallBack(
req,
res,
ResponseKey,
ResponseValue,
notAjaxRedirect
) {
function defaultFalseCallBack(req, res, ResponseKey, ResponseValue, notAjaxRedirect) {
if (req.xhr) {
res.send({
ResponseKey: ResponseKey,
@ -34,18 +27,13 @@ module.exports.randomString = randomString;
module.exports.needLogin = (req, res, trueCallBack, falseCallBack) => {
let username = req.session["username"];
if (
req.session["login"] &&
loginedContainer.isLogined(req.sessionID, username)
) {
if (req.session["login"] && loginedContainer.isLogined(req.sessionID, username)) {
if (req.session["login"] === true && username) {
trueCallBack && trueCallBack();
return true;
}
}
falseCallBack
? falseCallBack()
: defaultFalseCallBack(req, res, "user/status", "NotLogin");
falseCallBack ? falseCallBack() : defaultFalseCallBack(req, res, "user/status", "NotLogin");
return false;
};
@ -92,9 +80,7 @@ module.exports.tokenCheck = (req, res, trueCallBack, falseCallBack) => {
return;
}
}
falseCallBack
? falseCallBack()
: defaultFalseCallBack(req, res, "user/status", "NotToken", "/error/token");
falseCallBack ? falseCallBack() : defaultFalseCallBack(req, res, "user/status", "NotToken", "/error/token");
};
const serverModel = require("../model/ServerModel");

View File

@ -28,11 +28,7 @@ class RecordCommand {
fs.appendFile(this.path, data, FILE_CODE, function (err) {
if (err) throw err;
});
else
fs.writeFileSync(
this.path,
new Buffer(HISTORY_SIZE_LINE * 2).toString() + data
);
else fs.writeFileSync(this.path, new Buffer(HISTORY_SIZE_LINE * 2).toString() + data);
}
readRecord(pstart = 0, length = 32, callback = (logStr) => {}) {

View File

@ -45,41 +45,22 @@ module.exports.init = () => {
for (const key in MCSERVER.Schedule.dataModel.list) {
const element = MCSERVER.Schedule.dataModel.list[key];
if (element == null) continue;
createScheduleJobCount(
element.id,
element.time,
element.count,
element.commande,
element.servername,
null,
false
);
createScheduleJobCount(element.id, element.time, element.count, element.commande, element.servername, null, false);
}
};
//计次型任务
function createScheduleJobCount(
id,
time,
count,
commande,
servername,
callback,
_save = true
) {
function createScheduleJobCount(id, time, count, commande, servername, callback, _save = true) {
let lco = 0;
let mask = (MCSERVER.Schedule.container[id] = schedule.scheduleJob(
time,
(fireDate) => {
if (lco >= count && count > 0) {
deleteScheduleJob(id);
return;
}
lco++;
serverExe(servername, commande);
callback && callback(commande);
let mask = (MCSERVER.Schedule.container[id] = schedule.scheduleJob(time, (fireDate) => {
if (lco >= count && count > 0) {
deleteScheduleJob(id);
return;
}
));
lco++;
serverExe(servername, commande);
callback && callback(commande);
}));
if (mask && _save) {
MCSERVER.Schedule.dataModel.list.push({
id: id,

View File

@ -27,8 +27,7 @@ module.exports.createServerDir = (serverName, cwd) => {
};
module.exports.createServer = (serverName, config) => {
if (config.cwd == "" || config.cwd == "<默认标准位置>")
config.cwd = getServerDir(serverName);
if (config.cwd == "" || config.cwd == "<默认标准位置>") config.cwd = getServerDir(serverName);
if (!fs.existsSync(config.cwd)) {
fsextra.mkdirsSync(config.cwd);
}
@ -86,12 +85,7 @@ schedule.scheduleJob("1 0 */2 * * *", function () {
if (server && server.isRun()) {
let res = server.isDealLineDate();
if (res) {
MCSERVER.log(
"[时间期限] 服务端 [",
server.dataModel.name,
"]",
"于现在过期,正在执行关闭程序."
);
MCSERVER.log("[时间期限] 服务端 [", server.dataModel.name, "]", "于现在过期,正在执行关闭程序.");
//先进行标准流程关闭服务端,如果 45 秒后未关闭,则强制性结束进程
server.send("stop");
server.send("end");
@ -103,9 +97,6 @@ schedule.scheduleJob("1 0 */2 * * *", function () {
}
}
} catch (err) {
MCSERVER.error(
"[时间期限] 关闭服务端时出现异常,某个服务端可能未能正确关闭:",
err
);
MCSERVER.error("[时间期限] 关闭服务端时出现异常,某个服务端可能未能正确关闭:", err);
}
});

View File

@ -13,25 +13,11 @@ module.exports.registerUser = (username, password) => {
};
module.exports.loginUser = (username, password, truecb, falsecb, enkey) => {
return userCenters.loginCheck(
username,
password,
truecb,
falsecb,
enkey,
false
);
return userCenters.loginCheck(username, password, truecb, falsecb, enkey, false);
};
module.exports.beliveLogin = (username, password, truecb, falsecb) => {
return userCenters.loginCheck(
username,
password,
truecb,
falsecb,
null,
true
);
return userCenters.loginCheck(username, password, truecb, falsecb, null, true);
};
module.exports.deleteUser = (username, truecb, falsecb) => {

View File

@ -27,9 +27,7 @@ router.all("/auth_master/pwd", (req, res) => {
// 判断是否为管理员
if (permission.IsSessionMaster(req, res)) {
MCSERVER.log("[Online Fs]", "管理员", userName, "访问服务端存放目录");
const absServersDir = pathm.normalize(
pathm.join(pathm.join(__dirname, "../../"), SERVERS_DIR)
);
const absServersDir = pathm.normalize(pathm.join(pathm.join(__dirname, "../../"), SERVERS_DIR));
req.session.fsos = new FileOperateStructure(absServersDir, "./");
req.session.fsoperate = {};
req.session.fsoperate.tmp = [];
@ -56,32 +54,17 @@ router.all("/auth/:servername", (req, res) => {
}
let dataModel = null;
if (
serverModel.ServerManager().isExist(serverName) &&
permission.isCanServer(userName, serverName)
) {
dataModel =
serverModel.ServerManager().getServer(serverName).dataModel || null;
if (serverModel.ServerManager().isExist(serverName) && permission.isCanServer(userName, serverName)) {
dataModel = serverModel.ServerManager().getServer(serverName).dataModel || null;
}
if (!dataModel || !dataModel.cwd) {
res.send("[ 权限阻止 ] dataModel 空,无权限操作的服务器!");
return;
}
let cwd = null;
if (!pathm.isAbsolute(dataModel.cwd))
cwd = pathm.normalize(
pathm.join(pathm.join(__dirname, "../../"), dataModel.cwd)
);
if (!pathm.isAbsolute(dataModel.cwd)) cwd = pathm.normalize(pathm.join(pathm.join(__dirname, "../../"), dataModel.cwd));
else cwd = dataModel.cwd;
MCSERVER.log(
"[Online Fs]",
"用户",
userName,
"访问服务器",
serverName,
"根:",
cwd
);
MCSERVER.log("[Online Fs]", "用户", userName, "访问服务器", serverName, "根:", cwd);
req.session.fsos = new FileOperateStructure(cwd, "./");
req.session.fsoperate = {};

View File

@ -1,15 +1,8 @@
const express = require("express");
const router = express.Router();
const pathm = require("path");
const {
parseHandle,
sendHandle,
filesToPaths,
} = require("../module/dataHandle");
const {
FileOperateStructure,
UseFileOperate,
} = require("../model/fsoperate_session");
const { parseHandle, sendHandle, filesToPaths } = require("../module/dataHandle");
const { FileOperateStructure, UseFileOperate } = require("../model/fsoperate_session");
const fsoperate = require("../module/fsoperate");
const fs = require("fs");
const os = require("os");
@ -29,12 +22,9 @@ router.post("/mkdir", (req, res) => {
router.post("/ls", (req, res) => {
let name = parseHandle(req.body, "string") || "./";
// 唯一的当前目录赋值场景
req.session.fsos.cwd = pathm.normalize(
pathm.join(req.session.fsos.cwd, name)
);
req.session.fsos.cwd = pathm.normalize(pathm.join(req.session.fsos.cwd, name));
let fileOperate = new UseFileOperate(req.session.fsos).fileOperate;
if (req.session.fsos.cwd == "..\\" || req.session.fsos.cwd == "../")
req.session.fsos.cwd = "./"; //越级,重置
if (req.session.fsos.cwd == "..\\" || req.session.fsos.cwd == "../") req.session.fsos.cwd = "./"; //越级,重置
let obj = fileOperate.lsType(req.session.fsos.cwd);
req.session.save();
sendHandle(req, res, obj);
@ -73,14 +63,8 @@ router.post("/patse", (req, res) => {
let fileOperate = new UseFileOperate(req.session.fsos).fileOperate;
if (req.session.fsoperate.tmp_action == "cp") callFunc = fileOperate.cp;
else callFunc = fileOperate.mv;
let oldpaths = filesToPaths(
req.session.fsoperate.tmp_files,
req.session.fsoperate.tmp_cwd
);
let newpaths = filesToPaths(
req.session.fsoperate.tmp_files,
req.session.fsos.cwd
);
let oldpaths = filesToPaths(req.session.fsoperate.tmp_files, req.session.fsoperate.tmp_cwd);
let newpaths = filesToPaths(req.session.fsoperate.tmp_files, req.session.fsos.cwd);
let obj = fileOperate.batchExectue(callFunc, oldpaths, newpaths);
sendHandle(req, res, obj);
@ -118,14 +102,10 @@ router.post("/edit_write", (req, res) => {
const obj = parseHandle(req.body);
if (!obj || !obj.filename || !obj.context) return;
//先进行基本的越权过滤
if (obj.filename.indexOf("../") != -1 || obj.filename.indexOf("./") != -1)
return;
if (obj.filename.indexOf("../") != -1 || obj.filename.indexOf("./") != -1) return;
const cwd = req.session.fsos.cwd;
const fileOperate = new UseFileOperate(req.session.fsos).fileOperate;
const result = fileOperate.writeFile(
pathm.join(cwd, obj.filename),
obj.context
);
const result = fileOperate.writeFile(pathm.join(cwd, obj.filename), obj.context);
sendHandle(req, res, result);
});

View File

@ -10,9 +10,7 @@ class FileOperateStructure {
class UseFileOperate {
constructor(fileOperateStructure) {
if (!fileOperateStructure || !fileOperateStructure["rootPath"]) {
throw new Error(
"[UseFileOperate Mineself Error] UseFileOperate(...) Not is FileOperateStructure"
);
throw new Error("[UseFileOperate Mineself Error] UseFileOperate(...) Not is FileOperateStructure");
}
this.fileOperate = new FileOperate(fileOperateStructure.rootPath);
this.fileOperateStructure = fileOperateStructure;

View File

@ -7,8 +7,7 @@ const DEBUG = true;
//基本的操作权限
class BaseFileOperate {
constructor(rootPath) {
if (path_moduel.isAbsolute(rootPath))
this.rootPath = path_moduel.normalize(rootPath);
if (path_moduel.isAbsolute(rootPath)) this.rootPath = path_moduel.normalize(rootPath);
else throw Error("RootPath 必须是一个绝对路径,否则将无法定位");
// this.rootPath = path_moduel.normalize(path_moduel.resolve(rootPath));
this.fs = fs;

View File

@ -28,11 +28,7 @@ if (realArgv.length >= 1) {
//执行解压
const absPath = realArgv[1];
//目录名与原文件同名
const zipExtractDir = path.normalize(
path.dirname(absPath) +
"/解压文件_" +
path.basename(absPath, path.extname(absPath))
);
const zipExtractDir = path.normalize(path.dirname(absPath) + "/解压文件_" + path.basename(absPath, path.extname(absPath)));
// 创建目标目录
try {
fs.mkdirSync(zipExtractDir);
@ -63,9 +59,7 @@ if (realArgv.length >= 1) {
// 此压缩库支持异步写法,但以防不测,依然列入子进程
if (ACTION === "compress") {
const absPath = realArgv[1];
const compressZipPath = path.normalize(
path.dirname(absPath) + "/压缩文件_" + path.basename(absPath) + ".zip"
);
const compressZipPath = path.normalize(path.dirname(absPath) + "/压缩文件_" + path.basename(absPath) + ".zip");
// 进行压缩操作
compressing.zip
.compressDir(absPath, compressZipPath, {

View File

@ -7,8 +7,7 @@ const fsex = require("fs-extra");
const child_process = require("child_process");
// 最大同时解压任务
let MAX_EXTRACT_AND_COMPRESS_TASK_LIMIT =
MCSERVER.localProperty.max_eac_task_limit || 1;
let MAX_EXTRACT_AND_COMPRESS_TASK_LIMIT = MCSERVER.localProperty.max_eac_task_limit || 1;
// 当前解压任务
let nowEacTaskCounter = 0;
// 解压缩任务队列
@ -22,10 +21,7 @@ setInterval(() => {
const task = EAC_QUQUE.pop();
if (task == null) return;
nowEacTaskCounter += 1;
const extend_worker = child_process.fork(
"./onlinefs/module/extend_worker.js",
[task["category"], task["path"]]
);
const extend_worker = child_process.fork("./onlinefs/module/extend_worker.js", [task["category"], task["path"]]);
extend_worker.on("close", () => {
nowEacTaskCounter -= 1;
});
@ -116,10 +112,7 @@ class FileOperate extends BaseFileOperate {
});
} else {
//若删除文件夹则分配子进程来进行解压操作
child_process.fork("./onlinefs/module/extend_worker.js", [
"remove",
absPath,
]);
child_process.fork("./onlinefs/module/extend_worker.js", ["remove", absPath]);
}
});
}

View File

@ -1,8 +1,6 @@
html,
body {
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC,
Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei,
sans-serif;
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;
font-size: 14px;
color: #1a1a1a;
-webkit-tap-highlight-color: rgba(26, 26, 26, 0);
@ -71,8 +69,7 @@ input {
top: 0px;
bottom: 0px;
font-size: 18px;
box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.42),
0 4px 25px 0px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2);
box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.42), 0 4px 25px 0px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2);
}
#Container {

View File

@ -1,12 +1,5 @@
//通用登陆 API js
MCSERVER.login = function (
username,
password,
rand,
loginSuccess,
loginError,
error
) {
MCSERVER.login = function (username, password, rand, loginSuccess, loginError, error) {
var POST_OBJECT = null;
$.get({
url: MCSERVER.URL("./user/login_key"),

View File

@ -1,8 +1,7 @@
(function () {
MCSERVER.findPropertiesShow = function (key) {
var SuwingsLoveYou = {
"generator-settings":
"用于自定义超平坦世界的生成,不生成超平坦世界请留空",
"generator-settings": "用于自定义超平坦世界的生成,不生成超平坦世界请留空",
"allow-nether": "是否允许下界(包括地狱)",
"level-name": "世界(地图)名称 不要使用中文",
"enable-query": "是否允许使用GameSpy4协议的服务器监听器",
@ -23,23 +22,19 @@
"online-mode": "在线(正版)验证",
pvp: "是否允许玩家互相攻击",
difficulty: "难度0=和平 1=简单 2=普通 3=困难",
"player-idle-timeout":
"允许的挂机时间,单位为分钟 超过限制后自动T出服务器",
"player-idle-timeout": "允许的挂机时间,单位为分钟 超过限制后自动T出服务器",
gamemode: "游戏模式 0=生存 1=创造 2=冒险 3=旁观",
"max-players": "服务器最大玩家数限制",
"spawn-monsters": "生成攻击型生物(怪物)",
"view-distance": "服务器发送给客户端的数据量,决定玩家能设置的视野",
"generate-structures":
"生成世界时生成结构(如村庄)禁止后地牢和地下要塞仍然生成",
"generate-structures": "生成世界时生成结构(如村庄)禁止后地牢和地下要塞仍然生成",
motd: "服务器信息展示 若使用ColorMotd等插件可留空该选项",
"op-permission-level": "OP权限等级 ",
"announce-player-achievements":
"玩家获得成就时是否在服务器聊天栏显示是否允许其装X",
"announce-player-achievements": "玩家获得成就时是否在服务器聊天栏显示是否允许其装X",
"network-compression-threshold": "网络压缩阈值",
"resource-pack-sha1": "资源包的SHA-1值必须为小写十六进制不是必填选项",
"enable-command-block": "启用命令方块",
"resource-pack":
"统一资源标识符 (URI) 指向一个资源包。玩家可选择是否使用",
"resource-pack": "统一资源标识符 (URI) 指向一个资源包。玩家可选择是否使用",
"max-world-size": "最大世界大小",
"function-permission-level": "设定函数的默认权限等级",
"max-tick-time": "设置每个tick花费的最大毫秒数",
@ -47,14 +42,12 @@
"rcon.port": "设置RCON远程访问的端口号",
"rcon.password": "设置RCON远程访问的密码参见enable-rcon",
"query.port": "设置监听服务器的端口号(参见 enable-rcon",
"use-native-transport":
"是否使用针对Linux平台的数据包收发优化 [ 仅Linux ]",
"use-native-transport": "是否使用针对Linux平台的数据包收发优化 [ 仅Linux ]",
debug: "调试模式",
"broadcast-rcon-to-ops": "向OP广播RCON信息",
"broadcast-console-to-ops": "向OP广播服务器控制台信息",
"enforce-whitelist": "在服务器上强制使用白名单",
"spawn-protection":
"通过将该值进行 2x+1 的运算来决定出生点的保护半径设置为0将只保护出生点下方那一个方块。",
"spawn-protection": "通过将该值进行 2x+1 的运算来决定出生点的保护半径设置为0将只保护出生点下方那一个方块。",
};
if (SuwingsLoveYou.hasOwnProperty(key)) {

View File

@ -9,9 +9,7 @@
RES.TOKEN = null;
RES.getToken = function (callback) {
//同源策略可以防止其他域对这里发送一个Ajax请求.
var _url = MCSERVER.URL(
"./token?_LoveYouMaster_Time=" + Date.parse(new Date())
);
var _url = MCSERVER.URL("./token?_LoveYouMaster_Time=" + Date.parse(new Date()));
$.get(_url, function (data, status) {
data = JSON.parse(data);
if (data.hasOwnProperty("ResponseValue")) {
@ -75,10 +73,7 @@
//响应事件函数
function responseCallback(response, status, xhr) {
if (status != "success")
TOOLS.pushMsgWindow(
"[ " + status + " ] 由于网络或权限问题,请求的网页无法成功!"
);
if (status != "success") TOOLS.pushMsgWindow("[ " + status + " ] 由于网络或权限问题,请求的网页无法成功!");
callback && callback();
}

View File

@ -50,13 +50,7 @@
// XSS 攻击防御函数
TOOLS.encode = function (html) {
var rstr = html
.replace(/&/gim, "&amp;")
.replace(/</gim, "&lt;")
.replace(/>/gim, "&gt;")
.replace(/\"/gim, "&quot;")
.replace(/\'/gim, "&apos;")
.replace(/ /gim, "&nbsp;");
var rstr = html.replace(/&/gim, "&amp;").replace(/</gim, "&lt;").replace(/>/gim, "&gt;").replace(/\"/gim, "&quot;").replace(/\'/gim, "&apos;").replace(/ /gim, "&nbsp;");
return rstr;
};
@ -83,17 +77,11 @@
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval = TOOLS.getCookie(name);
if (cval != null)
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
if (cval != null) document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
};
TOOLS.setCookie = function (name, value) {
document.cookie =
name +
"=" +
escape(value) +
";expires=" +
new Date(Date.now() + 10000 * 60 * 60 * 4).toGMTString();
document.cookie = name + "=" + escape(value) + ";expires=" + new Date(Date.now() + 10000 * 60 * 60 * 4).toGMTString();
};
//判断是否是一个 标准字符串(标准的定义:仅有字母数字下划线)
@ -139,14 +127,8 @@
// 基本颜色
text = text.replace(/([A-Za-z _§&;\-\\.]{1,}:)/gim, "§6$1§r");
text = text.replace(
/INFO/gm,
term.TERM_TEXT_GREEN + "INFO" + term.TERM_NULL
);
text = text.replace(
/(\d{2,}:\d{2,}:\d{2,})/gm,
term.TERM_TEXT_CYAN + "$1" + term.TERM_NULL
);
text = text.replace(/INFO/gm, term.TERM_TEXT_GREEN + "INFO" + term.TERM_NULL);
text = text.replace(/(\d{2,}:\d{2,}:\d{2,})/gm, term.TERM_TEXT_CYAN + "$1" + term.TERM_NULL);
// Minecraft 原生颜色替代解析
text = text.replace(/§0/gm, term.TERM_TEXT_WHITE);
@ -199,16 +181,7 @@
// 特殊文本替换
var RegExpStringArr = [
//蓝色
[
"Unknown command",
"Loading libraries, please wait...",
"Loading",
"Loaded",
"\\d{1,3}%",
"true",
"false",
"plugin.yml",
],
["Unknown command", "Loading libraries, please wait...", "Loading", "Loaded", "\\d{1,3}%", "true", "false", "plugin.yml"],
//绿色
[
"/help",
@ -229,48 +202,25 @@
"Preparing start region for level",
],
//红色
[
"WARN",
"EULA",
"Error",
"Invalid",
"Stopping the server",
"Caused by",
"Stopping",
],
["WARN", "EULA", "Error", "Invalid", "Stopping the server", "Caused by", "Stopping"],
//黄色
[
"Starting Minecraft server on",
"world_the_end",
"world_nether",
"Done",
"MCSMANAGER",
],
["Starting Minecraft server on", "world_the_end", "world_nether", "Done", "MCSMANAGER"],
];
for (var k in RegExpStringArr) {
for (var y in RegExpStringArr[k]) {
var reg = new RegExp(
"(" + RegExpStringArr[k][y].replace(/ /gim, "&nbsp;") + ")",
"igm"
);
var reg = new RegExp("(" + RegExpStringArr[k][y].replace(/ /gim, "&nbsp;") + ")", "igm");
if (k == 0)
//蓝色
text = text.replace(reg, term.TERM_TEXT_BLUE + "$1" + term.TERM_NULL);
if (k == 1)
//绿色
text = text.replace(
reg,
term.TERM_TEXT_GREEN + "$1" + term.TERM_NULL
);
text = text.replace(reg, term.TERM_TEXT_GREEN + "$1" + term.TERM_NULL);
if (k == 2)
//红色
text = text.replace(reg, term.TERM_TEXT_RED + "$1" + term.TERM_NULL);
if (k == 3)
//黄色
text = text.replace(
reg,
term.TERM_TEXT_YELLOW + "$1" + term.TERM_NULL
);
text = text.replace(reg, term.TERM_TEXT_YELLOW + "$1" + term.TERM_NULL);
}
}
// 行结尾符号替换
@ -281,31 +231,16 @@
//Minecraft 服务器输出基本颜色
TOOLS.encodeConsoleColorForHtml = function (text) {
text = text.replace(/\n/gim, "<br />");
text = text.replace(
/([A-Za-z _&;-\\.]{1,}:)/gim,
"<span style='color:#ffa700;'>$1</span>"
);
text = text.replace(/([A-Za-z _&;-\\.]{1,}:)/gim, "<span style='color:#ffa700;'>$1</span>");
text = text.replace(/\[/gim, "<span style='color:#10e616;'>[</span>");
text = text.replace(/\]/gim, "<span style='color:#10e616;'>]</span>");
text = text.replace(/INFO/gm, "<span style='color:#03ea0a;'>INFO</span>");
text = text.replace(
/(\d{2,}:\d{2,}:\d{2,})/gm,
"<span style='color:#017EBC;'>$1</span>"
);
text = text.replace(/(\d{2,}:\d{2,}:\d{2,})/gm, "<span style='color:#017EBC;'>$1</span>");
text = text.replace(/§[0-9A-Za-z]{1}/gim, "");
RegExpStringArr = [
//蓝色
[
"Unknown command",
"Loading libraries, please wait...",
"Loading",
"Loaded",
"\\d{1,3}%",
"true",
"false",
"plugin.yml",
],
["Unknown command", "Loading libraries, please wait...", "Loading", "Loaded", "\\d{1,3}%", "true", "false", "plugin.yml"],
//绿色
[
"/help",
@ -325,32 +260,13 @@
"Preparing start region for level",
],
//红色
[
"WARN",
"EULA",
"Error",
"Invalid",
"Stopping the server",
"Caused by",
"Stopping",
],
["WARN", "EULA", "Error", "Invalid", "Stopping the server", "Caused by", "Stopping"],
//黄色
[
"Starting Minecraft server on",
"world_the_end",
"world_nether",
"Usage",
"Server thread",
"Done",
"MCSMANAGER",
],
["Starting Minecraft server on", "world_the_end", "world_nether", "Usage", "Server thread", "Done", "MCSMANAGER"],
];
for (var k in RegExpStringArr) {
for (var y in RegExpStringArr[k]) {
var reg = new RegExp(
"(" + RegExpStringArr[k][y].replace(/ /gim, "&nbsp;") + ")",
"igm"
);
var reg = new RegExp("(" + RegExpStringArr[k][y].replace(/ /gim, "&nbsp;") + ")", "igm");
if (k == 0)
//蓝色
text = text.replace(reg, "<span style='color:#009fef;'>$1</span>");
@ -387,9 +303,7 @@
});
popWinContext.load(config.template, function (response, status, xhr) {
if (status != "success") {
popWinContext.html(
"信息框加载失败!请保持网络通畅!单击灰色区域关闭!"
);
popWinContext.html("信息框加载失败!请保持网络通畅!单击灰色区域关闭!");
return;
}
});
@ -415,18 +329,9 @@
// 异步大文件上传方案
// $("#m-upload-file")[0].files[0] 参数 进程回调
TOOLS.fileupload = function (
file,
url,
args,
progressCallback,
successCallback,
failureCallback
) {
TOOLS.fileupload = function (file, url, args, progressCallback, successCallback, failureCallback) {
if (typeof FormData != "function") {
alert(
"很遗憾,您的浏览器不兼容异步文件上传。请使用现代浏览器!推荐 Chrome"
);
alert("很遗憾,您的浏览器不兼容异步文件上传。请使用现代浏览器!推荐 Chrome");
return null;
}
console.log(file);
@ -470,11 +375,7 @@
}
console.log(parameters);
if (parameters["page"]) {
RES.redirectPage(
"./" + parameters["page"] + ".html",
parameters["api"],
parameters["listen"]
);
RES.redirectPage("./" + parameters["page"] + ".html", parameters["api"], parameters["listen"]);
return true;
} else {
return false;

View File

@ -143,8 +143,7 @@
"<br /><br />[ 控制面板 ]: 日志显示过长,为避免网页卡顿,现已自动清空。<br />[ 控制面板 ]: 若想回看历史日志,请点击右上角刷新按钮,再重新进入点击 [历史] 按钮即可。<br /><br />";
}
eleTerminal.innerHTML = eleTerminal.innerHTML + text;
var BUFF_FONTIER_SIZE_DOWN =
eleTerminal.scrollHeight - eleTerminal.clientHeight;
var BUFF_FONTIER_SIZE_DOWN = eleTerminal.scrollHeight - eleTerminal.clientHeight;
flag = eleTerminal.scrollTop + 400 >= BUFF_FONTIER_SIZE_DOWN;
if (flag) eleTerminal.scrollTop = eleTerminal.scrollHeight;
}
@ -207,18 +206,7 @@
// 终端提示行
term.prompt = function (command) {
term.write(
"\x1B[1;1;33m" +
"[" +
term.TERM_TEXT_WHITE +
term.TERM_TEXT_GREEN +
PAGE.serverName +
"@" +
"app" +
term.TERM_TEXT_YELLOW +
"]" +
term.TERM_TEXT_WHITE +
(command || "") +
"\x1B[0m \r\n"
"\x1B[1;1;33m" + "[" + term.TERM_TEXT_WHITE + term.TERM_TEXT_GREEN + PAGE.serverName + "@" + "app" + term.TERM_TEXT_YELLOW + "]" + term.TERM_TEXT_WHITE + (command || "") + "\x1B[0m \r\n"
);
};
// 初始化终端方法
@ -250,8 +238,7 @@
WS.sendMsg("server/console/open", PAGE.serverName);
},
toCommand: function (parCommand) {
if (parCommand && typeof parCommand == "string")
this.command = parCommand;
if (parCommand && typeof parCommand == "string") this.command = parCommand;
MCSERVER.term.prompt(this.command);
console.log("发送命令:", this.command);
var data = {

View File

@ -201,8 +201,7 @@ function bit_rol(num, cnt) {
function str2binl(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << i % 32;
for (var i = 0; i < str.length * chrsz; i += chrsz) bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << i % 32;
return bin;
}
@ -212,8 +211,7 @@ function str2binl(str) {
function binl2str(bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode((bin[i >> 5] >>> i % 32) & mask);
for (var i = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i >> 5] >>> i % 32) & mask);
return str;
}
@ -224,9 +222,7 @@ function binl2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str +=
hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xf) +
hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xf);
str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xf) + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xf);
}
return str;
}
@ -238,10 +234,7 @@ function binl2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet =
(((binarray[i >> 2] >> (8 * (i % 4))) & 0xff) << 16) |
(((binarray[(i + 1) >> 2] >> (8 * ((i + 1) % 4))) & 0xff) << 8) |
((binarray[(i + 2) >> 2] >> (8 * ((i + 2) % 4))) & 0xff);
var triplet = (((binarray[i >> 2] >> (8 * (i % 4))) & 0xff) << 16) | (((binarray[(i + 1) >> 2] >> (8 * ((i + 1) % 4))) & 0xff) << 8) | ((binarray[(i + 2) >> 2] >> (8 * ((i + 2) % 4))) & 0xff);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
else str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f);

View File

@ -6,10 +6,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<meta name="renderer" content="webkit" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"
/>
<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no" />
<title>MCSM 管理面板</title>
<link href="./common/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
@ -24,22 +21,8 @@
<link href="./favicon.ico" rel="shortcut icon" />
<!--[if lt IE 9]>
<div
id="Not_"
class="show-ui"
style="
height: 40px;
background-color: rgb(221, 79, 67);
text-align: center;
line-height: 40px;
color: white;
"
>
<b
>无法访问! 您的浏览器版本过低或是兼容模式,请使用最新/更高版本的浏览器:
IE10+ chrome FireFox
如果是国内浏览器请打开极速浏览模式webkit内核</b
>
<div id="Not_" class="show-ui" style="height: 40px; background-color: rgb(221, 79, 67); text-align: center; line-height: 40px; color: white">
<b>无法访问! 您的浏览器版本过低或是兼容模式,请使用最新/更高版本的浏览器: IE10+ chrome FireFox 等如果是国内浏览器请打开极速浏览模式webkit内核</b>
</div>
<![endif]-->
</head>
@ -63,25 +46,14 @@
Mcserver Manager
<br />
<div id="websocket2">
<div v-if="is">
<span class="color-green">在线: </span>{{ MCSERVER.username }}
</div>
<div v-if="is"><span class="color-green">在线: </span>{{ MCSERVER.username }}</div>
<div v-else>offline (离线)</div>
</div>
</div>
<div id="SideColFor">
<!--如果您想更改菜单名或功能,请查看 common/js/meum.js 文件-->
<a
href="javascript:void(0);"
v-for="item of items"
:class="{ MeumSelect: item.select }"
v-on:click="onRedirect(item.link,item.api,item)"
>
<span
class="glyphicon"
:class="item.class"
aria-hidden="true"
></span>
<a href="javascript:void(0);" v-for="item of items" :class="{ MeumSelect: item.select }" v-on:click="onRedirect(item.link,item.api,item)">
<span class="glyphicon" :class="item.class" aria-hidden="true"></span>
<span v-text="item.name"></span>
</a>
</div>
@ -113,30 +85,14 @@
<!--信息框HTML-->
<div id="ToolsInfo">
<transition name="fade">
<div
class="ToolsInfo tools-info text-center show-ui"
v-if="show"
v-text="msg"
></div>
<div class="ToolsInfo tools-info text-center show-ui" v-if="show" v-text="msg"></div>
</transition>
</div>
<!--页面加载进度条-->
<div class="Toolscon" id="ToolsPageLoading">
<div
class="progress"
style="
height: 4px;
line-height: 4px;
background-color: inherit;
border: 0px;
"
>
<div
id="ToolsLoading"
class="progress-bar progress-bar-success progress-bar-striped active"
style="width: 0%; height: 4px"
></div>
<div class="progress" style="height: 4px; line-height: 4px; background-color: inherit; border: 0px">
<div id="ToolsLoading" class="progress-bar progress-bar-success progress-bar-striped active" style="width: 0%; height: 4px"></div>
</div>
</div>
@ -160,16 +116,7 @@
<div id="SidebarButton" v-on:click="operate()">
<div class="SidebarButtonWapper">
<!-- <span class="glyphicon " :class="!isExpand?'glyphicon-th-list':'glyphicon-list'" aria-hidden="true"></span> -->
<svg
t="1583817080960"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="941"
width="24"
height="46"
>
<svg t="1583817080960" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="941" width="24" height="46">
<path
d="M393 475.7H176.5c-44.9 0-81.5-36.6-81.5-81.5V182.5c0-44.9 36.6-81.5 81.5-81.5H393c44.9 0 81.5 36.6 81.5 81.5v211.7c0 45-36.5 81.5-81.5 81.5zM176.5 155.4c-15 0-27.2 12.2-27.2 27.2v211.7c0 15 12.2 27.2 27.2 27.2H393c15 0 27.2-12.2 27.2-27.2V182.5c0-15-12.2-27.2-27.2-27.2l-216.5 0.1zM846.5 469.9H629.9c-44.9 0-81.5-36.6-81.5-81.5V176.7c0-44.9 36.6-81.5 81.5-81.5h216.6c44.9 0 81.5 36.6 81.5 81.5v211.7c0 44.9-36.6 81.5-81.5 81.5zM629.9 149.5c-15 0-27.2 12.2-27.2 27.2v211.7c0 15 12.2 27.2 27.2 27.2h216.6c15 0 27.2-12.2 27.2-27.2V176.7c0-15-12.2-27.2-27.2-27.2H629.9zM393 928.2H176.5c-44.9 0-81.5-36.6-81.5-81.5V635c0-44.9 36.6-81.5 81.5-81.5H393c44.9 0 81.5 36.6 81.5 81.5v211.7c0 45-36.5 81.5-81.5 81.5zM176.5 607.9c-15 0-27.2 12.2-27.2 27.2v211.7c0 15 12.2 27.2 27.2 27.2H393c15 0 27.2-12.2 27.2-27.2V635c0-15-12.2-27.2-27.2-27.2H176.5v0.1zM846.5 922.4H629.9c-44.9 0-81.5-36.6-81.5-81.5V629.2c0-44.9 36.6-81.5 81.5-81.5h216.6c44.9 0 81.5 36.6 81.5 81.5v211.7c0 44.9-36.6 81.5-81.5 81.5zM629.9 602c-15 0-27.2 12.2-27.2 27.2v211.7c0 15 12.2 27.2 27.2 27.2h216.6c15 0 27.2-12.2 27.2-27.2V629.2c0-15-12.2-27.2-27.2-27.2H629.9z"
fill="#ffffff"
@ -185,11 +132,7 @@
<div class="PanelTitle">控制终端</div>
<div class="PanelBody">
<!-- 终端 -->
<div
id="WebTerminal"
class="WebTerminalScreen"
style="display: block"
></div>
<div id="WebTerminal" class="WebTerminalScreen" style="display: block"></div>
<div id="WebTerminalControl">
<div class="input-group input-group-sm">
<span class="input-group-addon">/</span>
@ -207,31 +150,19 @@
</div>
<div class="PanelItemF" style="text-align: right">
<div class="PanelItem mb0" v-on:click="toCommand">
<span
class="glyphicon glyphicon-console"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-console" aria-hidden="true"></span>
执行命令
</div>
<div class="PanelItem mb0" v-on:click="stopServer()">
<span
class="glyphicon glyphicon-pause"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-pause" aria-hidden="true"></span>
关闭
</div>
<div class="PanelItem mb0" v-on:click="toOpenServer()">
<span
class="glyphicon glyphicon-play"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-play" aria-hidden="true"></span>
开启
</div>
<div class="PanelItem mb0" v-on:click="TOOLS.CloseTerminal()">
<span
class="glyphicon glyphicon-modal-window"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-modal-window" aria-hidden="true"></span>
关闭窗口
</div>
</div>
@ -317,17 +248,9 @@
// 初始化终端
//判断是否是#权限用户,请放心,后端也会给予判断并不只是前端
if (MCSERVER.username.substr(0, 1) == "#") {
RES.redirectPage(
"./template/center.html",
"center/show",
"--- 更新页面 ---"
);
RES.redirectPage("./template/center.html", "center/show", "--- 更新页面 ---");
} else {
RES.redirectPage(
"./template/gen_home.html",
"genuser/home",
"--- 更新页面 ---"
);
RES.redirectPage("./template/gen_home.html", "genuser/home", "--- 更新页面 ---");
}
}
});

View File

@ -34,38 +34,12 @@
<p>使用您的 MCSM 账户</p>
<div id="mlogin_form">
<p>用户名</p>
<input
id="login-userid"
type="text"
class="minput"
placeholder="普通账号 | 管理用户"
onkeypress="enKeyPress()"
/>
<input id="login-userid" type="text" class="minput" placeholder="普通账号 | 管理用户" onkeypress="enKeyPress()" />
<p>密码</p>
<input
id="login-passwd"
type="password"
class="minput"
placeholder="账号密码"
onkeypress="enKeyPress()"
/>
<button
id="login-button"
class="mbutton"
onclick="MCSERVER.btnLogin()"
>
验证
</button>
<a
href="#"
class="mlogin_forge"
onclick="alert('请联系管理员更改密码如果您是管理员请删除user/文件夹下的所有#开头的管理用户')"
>
忘记密码?
</a>
<a href="#" class="mlogin_forge" onclick="alert('暂无帮助提供')">
需要帮助?
</a>
<input id="login-passwd" type="password" class="minput" placeholder="账号密码" onkeypress="enKeyPress()" />
<button id="login-button" class="mbutton" onclick="MCSERVER.btnLogin()">验证</button>
<a href="#" class="mlogin_forge" onclick="alert('请联系管理员更改密码如果您是管理员请删除user/文件夹下的所有#开头的管理用户')"> 忘记密码? </a>
<a href="#" class="mlogin_forge" onclick="alert('暂无帮助提供')"> 需要帮助? </a>
</div>
<p class="mlogin_context_footer phone">
<span>©2020 MCSManager. All rights reserved.</span>

View File

@ -6,36 +6,16 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<meta name="renderer" content="webkit" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"
/>
<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no" />
<title>Mcserver 验证</title>
<link
href="./static/template/bootstrap/css/bootstrap.min.css"
rel="stylesheet"
/>
<link href="./static/template/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="./static/login/css/style.css" rel="stylesheet" />
<link href="./static/common/image/icon.ico" rel="shortcut icon" />
<!--[if lt IE 9]>
<div
id="Not_"
class="show-ui"
style="
height: 40px;
background-color: rgb(221, 79, 67);
text-align: center;
line-height: 40px;
color: white;
"
>
<b
>无法访问! 您的浏览器版本过低或是兼容模式,请使用最新/更高版本的浏览器:
IE10+ chrome FireFox
如果是国内浏览器请打开极速浏览模式webkit内核</b
>
<div id="Not_" class="show-ui" style="height: 40px; background-color: rgb(221, 79, 67); text-align: center; line-height: 40px; color: white">
<b>无法访问! 您的浏览器版本过低或是兼容模式,请使用最新/更高版本的浏览器: IE10+ chrome FireFox 等如果是国内浏览器请打开极速浏览模式webkit内核</b>
</div>
<![endif]-->
</head>
@ -57,52 +37,25 @@
<form class="form-horizontal" role="form">
<div class="form-group has-feedback">
<div class="col-sm-12">
<input
type="text"
class="form-control border-1 minput"
id="login-userid"
placeholder="普通用户 | 管理用户"
/>
<span
class="glyphicon glyphicon-user form-control-feedback"
aria-hidden="true"
></span>
<input type="text" class="form-control border-1 minput" id="login-userid" placeholder="普通用户 | 管理用户" />
<span class="glyphicon glyphicon-user form-control-feedback" aria-hidden="true"></span>
</div>
</div>
<div class="form-group has-feedback">
<div class="col-sm-12">
<input
type="password"
class="form-control border-1 minput"
id="login-passwd"
placeholder="密码"
onkeypress="enKeyPress()"
/>
<span
class="glyphicon glyphicon-th form-control-feedback"
aria-hidden="true"
></span>
<input type="password" class="form-control border-1 minput" id="login-passwd" placeholder="密码" onkeypress="enKeyPress()" />
<span class="glyphicon glyphicon-th form-control-feedback" aria-hidden="true"></span>
</div>
</div>
<div class="form-group">
<div class="col-xs-4 col-sm-6"></div>
<div class="col-xs-8 col-sm-6">
<a
href="/"
id="form-help"
class="text-right help-text"
onclick="alert('请联系管理员更改密码如果您是管理员请删除user/文件夹下的所有#开头的管理用户')"
>忘记密码?</a
>
<a href="/" id="form-help" class="text-right help-text" onclick="alert('请联系管理员更改密码如果您是管理员请删除user/文件夹下的所有#开头的管理用户')">忘记密码?</a>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<div
id="login-button"
class="btn btn-default btn-info border-1"
onclick="MCSERVER.btnLogin()"
>
<div id="login-button" class="btn btn-default btn-info border-1" onclick="MCSERVER.btnLogin()">
<b>验证</b>
</div>
</div>
@ -117,9 +70,7 @@
</div>
</div>
</div>
<div id="view-info" class="alert alert-info show-ui tools-info">
默认信息框
</div>
<div id="view-info" class="alert alert-info show-ui tools-info">默认信息框</div>
</body>
<script type="text/javascript" src="./static/template/jq/jq.min.js"></script>
<script type="text/javascript" src="../common/URL.js"></script>

View File

@ -6,10 +6,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<meta name="renderer" content="webkit" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"
/>
<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no" />
<title>Mcserver Manager | 身份验证</title>
@ -18,22 +15,8 @@
<link href="./static/login/css/style.css" rel="stylesheet" />
<link href="./static/common/image/icon.ico" rel="shortcut icon" />
<!--[if lt IE 9]>
<div
id="Not_"
class="show-ui"
style="
height: 40px;
background-color: rgb(221, 79, 67);
text-align: center;
line-height: 40px;
color: white;
"
>
<b
>无法访问! 您的浏览器版本过低或是兼容模式,请使用最新/更高版本的浏览器:
IE10+ chrome FireFox
如果是国内浏览器请打开极速浏览模式webkit内核</b
>
<div id="Not_" class="show-ui" style="height: 40px; background-color: rgb(221, 79, 67); text-align: center; line-height: 40px; color: white">
<b>无法访问! 您的浏览器版本过低或是兼容模式,请使用最新/更高版本的浏览器: IE10+ chrome FireFox 等如果是国内浏览器请打开极速浏览模式webkit内核</b>
</div>
<![endif]-->
</head>
@ -53,33 +36,12 @@
<p>您必须要进行身份识别,才可以进入面板</p>
<div id="panel-context">
<!-- 元素的 id 不可更改 -->
<input
id="login-userid"
type="text"
class="minput"
placeholder="标准账号 或 管理账号"
/>
<input
id="login-passwd"
type="password"
class="minput"
onkeypress="enKeyPress()"
placeholder="此账号密码"
/>
<button
id="login-button"
class="mbutton"
onclick="MCSERVER.btnLogin()"
>
验证
</button>
<input id="login-userid" type="text" class="minput" placeholder="标准账号 或 管理账号" />
<input id="login-passwd" type="password" class="minput" onkeypress="enKeyPress()" placeholder="此账号密码" />
<button id="login-button" class="mbutton" onclick="MCSERVER.btnLogin()">验证</button>
<p>
忘记密码?
<a
href="#"
onclick="alert('请联系管理员更改密码,如果您是管理员,请删除 user/ 文件夹下的所有#开头的管理用户')"
>点击这里</a
>
<a href="#" onclick="alert('请联系管理员更改密码,如果您是管理员,请删除 user/ 文件夹下的所有#开头的管理用户')">点击这里</a>
</p>
<div id="copyright" class="">

View File

@ -4,8 +4,7 @@
<div class="Panel">
<div class="PanelTitle PanelBlack">
<!--请不要怀疑这是在欺骗您数据统计日期来自前端事实上后端是在每月1日统计至今所以是一致的-->
控制面板 {{ new Date().getMonth()+1 }}月1日 ~ {{ new
Date().getMonth()+1 }}月{{ new Date().getDate() }}日 基础监控
控制面板 {{ new Date().getMonth()+1 }}月1日 ~ {{ new Date().getMonth()+1 }}月{{ new Date().getDate() }}日 基础监控
</div>
<div class="PanelBody">
<div class="row">
@ -47,9 +46,7 @@
<div class="">
<div class="row">
<div class="col-md-4 col-sm-4">
<div class="LogV">
{{ (sysTotalmem - sysFreemem).toFixed(1) }} MB
</div>
<div class="LogV">{{ (sysTotalmem - sysFreemem).toFixed(1) }} MB</div>
<div class="LogK">系统已使用内存</div>
</div>
<div class="col-md-4 col-sm-4">

View File

@ -5,8 +5,7 @@
<div class="PanelTitle">服务端信息</div>
<div class="PanelBody">
<div class="PanelItem">
<span class="glyphicon glyphicon-th-large" aria-hidden="true">
</span>
<span class="glyphicon glyphicon-th-large" aria-hidden="true"> </span>
名称: {{ serverData.name }}
</div>
<div class="PanelItem">
@ -14,8 +13,7 @@
CPU 使用率: {{ sysCpu }} %
</div>
<div class="PanelItem">
<span class="glyphicon glyphicon-equalizer" aria-hidden="true">
</span>
<span class="glyphicon glyphicon-equalizer" aria-hidden="true"> </span>
内存 使用率: {{ (100 - sysMonery).toFixed(1) }} %
</div>
<div class="PanelItem" v-if="run">
@ -32,8 +30,7 @@
<div class="PanelTitle">服务端操作</div>
<div class="PanelBody">
<div class="PanelItem" v-on:click="toTerminal()">
<span class="glyphicon glyphicon-unchecked" aria-hidden="true">
</span>
<span class="glyphicon glyphicon-unchecked" aria-hidden="true"> </span>
模拟型终端
</div>
<transition name="slide-fade">
@ -43,39 +40,22 @@
</div>
</transition>
<transition name="slide-fade">
<div
class="PanelItem"
v-on:click="toCommand('__stop__')"
v-show="run"
>
<span class="glyphicon glyphicon-pause" aria-hidden="true">
</span>
<div class="PanelItem" v-on:click="toCommand('__stop__')" v-show="run">
<span class="glyphicon glyphicon-pause" aria-hidden="true"> </span>
关闭服务器
</div>
</transition>
<div
class="PanelItem"
v-on:click="toCommand('__restart__')"
v-show="run"
>
<span class="glyphicon glyphicon-refresh" aria-hidden="true">
</span>
<div class="PanelItem" v-on:click="toCommand('__restart__')" v-show="run">
<span class="glyphicon glyphicon-refresh" aria-hidden="true"> </span>
重启服务器
</div>
<div
class="PanelItem"
v-on:click="toCommand('__killserver__')"
v-show="run"
>
<div class="PanelItem" v-on:click="toCommand('__killserver__')" v-show="run">
<span class="glyphicon glyphicon-remove" aria-hidden="true"> </span>
强制性结束进程
</div>
</div>
</div>
<div
class="Panel"
:class="serverData.autoRestart?'PanelGreen':'PanelGray'"
>
<div class="Panel" :class="serverData.autoRestart?'PanelGreen':'PanelGray'">
<div class="PanelTitle">崩溃监视与配置</div>
<div class="PanelBody">
<div class="PanelItem" v-on:click="toProperties()">
@ -83,25 +63,15 @@
Server.properties 配置文件
</div>
<transition name="slide-fade">
<div
class="PanelItem"
v-on:click="toAutoRestart(false)"
v-show="serverData.autoRestart"
>
<span class="glyphicon glyphicon-retweet" aria-hidden="true">
</span>
<div class="PanelItem" v-on:click="toAutoRestart(false)" v-show="serverData.autoRestart">
<span class="glyphicon glyphicon-retweet" aria-hidden="true"> </span>
崩溃重启:
<span style="color: #29b90c">打开</span>
</div>
</transition>
<transition name="slide-fade">
<div
class="PanelItem"
v-on:click="toAutoRestart(true)"
v-show="!serverData.autoRestart"
>
<span class="glyphicon glyphicon-retweet" aria-hidden="true">
</span>
<div class="PanelItem" v-on:click="toAutoRestart(true)" v-show="!serverData.autoRestart">
<span class="glyphicon glyphicon-retweet" aria-hidden="true"> </span>
崩溃重启:
<span style="color: #818181">关闭</span>
</div>
@ -117,8 +87,7 @@
</div>
<div class="PanelItem">
<span class="glyphicon glyphicon-th-list" aria-hidden="true">
</span>
<span class="glyphicon glyphicon-th-list" aria-hidden="true"> </span>
端口: {{ FTP_port }}
</div>
<div class="PanelItem">
@ -137,8 +106,7 @@
<div class="PanelTitle">普通外置接口</div>
<div class="PanelBody">
<div class="PanelItem">
<span class="glyphicon glyphicon-barcode" aria-hidden="true">
</span>
<span class="glyphicon glyphicon-barcode" aria-hidden="true"> </span>
<span v-on:click="toAPI_JSON()">格式 JSON | API 接口</span>
</div>
</div>
@ -149,14 +117,10 @@
<div class="PanelTitle">服务端控制组</div>
<div class="PanelBody">
<div class="row">
<div
class="col-md-3 col-sm-6"
v-on:click="RES.redirectPage('./template/component/terminal.html', null, '')"
>
<div class="col-md-3 col-sm-6" v-on:click="RES.redirectPage('./template/component/terminal.html', null, '')">
<div class="PanelItemBlock">
<div class="LogV">
<span class="glyphicon glyphicon-console" aria-hidden="true">
</span>
<span class="glyphicon glyphicon-console" aria-hidden="true"> </span>
</div>
<div class="LogK">命令控制台</div>
</div>
@ -164,8 +128,7 @@
<div class="col-md-3 col-sm-6" v-on:click="toOnlineFs()">
<div class="PanelItemBlock">
<div class="LogV">
<span class="glyphicon glyphicon-th-list" aria-hidden="true">
</span>
<span class="glyphicon glyphicon-th-list" aria-hidden="true"> </span>
</div>
<div class="LogK">文件在线管理</div>
</div>
@ -173,11 +136,7 @@
<div class="col-md-3 col-sm-6" v-on:click="toSchedule()">
<div class="PanelItemBlock">
<div class="LogV">
<span
class="glyphicon glyphicon-indent-right"
aria-hidden="true"
>
</span>
<span class="glyphicon glyphicon-indent-right" aria-hidden="true"> </span>
</div>
<div class="LogK">计划任务项目</div>
</div>
@ -188,15 +147,9 @@
<!-- <span class="glyphicon glyphicon-cog" aria-hidden="true"> </span> -->
<strong>
<span>
<span
style="color: rgb(38, 165, 26)"
v-text="mcping.current_players"
></span>
<span style="color: rgb(38, 165, 26)" v-text="mcping.current_players"></span>
<span style="color: rgb(0, 0, 0)">/</span>
<span
style="color: rgb(38, 165, 26)"
v-text="mcping.max_players"
></span>
<span style="color: rgb(38, 165, 26)" v-text="mcping.max_players"></span>
</span>
</strong>
</div>
@ -236,11 +189,7 @@
<script>
MI.rListener("onload", function () {
// 定义页面地址
TOOLS.definePage(
"template/component/console",
"server/console",
MCSERVER.listenServername
);
TOOLS.definePage("template/component/console", "server/console", MCSERVER.listenServername);
var serverName = MCSERVER.listenServername;
@ -251,9 +200,7 @@
WS.sendMsg("server/console/autorestart", serverName);
},
toOnlineFs: function () {
var path = MCSERVER.URL(
"fs_auth/auth/" + encodeURIComponent(serverName)
);
var path = MCSERVER.URL("fs_auth/auth/" + encodeURIComponent(serverName));
window.open(path);
},
toOpenServer: function () {
@ -261,8 +208,7 @@
WS.sendMsg("server/console/open", serverName);
},
toCommand: function (parCommand) {
if (parCommand && typeof parCommand == "string")
this.command = parCommand;
if (parCommand && typeof parCommand == "string") this.command = parCommand;
var data = {
command: this.command,
serverName: serverName,
@ -273,25 +219,13 @@
this.command = "";
},
toProperties: function () {
RES.redirectPage(
"./template/component/properties.html",
"server/properties",
serverName
);
RES.redirectPage("./template/component/properties.html", "server/properties", serverName);
},
toTerminal: function () {
RES.redirectPage(
"./template/component/terminal.html",
"server/console",
serverName
);
RES.redirectPage("./template/component/terminal.html", "server/console", serverName);
},
toSchedule: function () {
RES.redirectPage(
"./template/component/schedule.html",
"schedule/list",
serverName
);
RES.redirectPage("./template/component/schedule.html", "schedule/list", serverName);
},
toAPI_JSON: function () {
window.open("/api/status/" + serverName);

View File

@ -4,14 +4,8 @@
<div class="Panel PanelRed">
<div class="PanelItem">修改密码须知</div>
<div class="PanelBody">
<p>
1.
密码安全至关重要,安全程度绝大部分取决密码,推荐采用数字,字母(大小写),符号组合为密码最佳。
</p>
<p>
2.
其他任何人都不会知道您的密码,包括管理员,密码采用不可逆向的加密方式,在密码足够复杂的情况下,几乎无法得知密码。
</p>
<p>1. 密码安全至关重要,安全程度绝大部分取决密码,推荐采用数字,字母(大小写),符号组合为密码最佳。</p>
<p>2. 其他任何人都不会知道您的密码,包括管理员,密码采用不可逆向的加密方式,在密码足够复杂的情况下,几乎无法得知密码。</p>
<p>3. 密码必须 6~18 位,否则会拒绝修改。</p>
</div>
</div>
@ -31,12 +25,7 @@
<th>原密码</th>
<th>
<div class="input-group input-group-sm">
<input
type="password"
class="form-control"
aria-describedby="basic-addon1"
v-model="oldPassword"
/>
<input type="password" class="form-control" aria-describedby="basic-addon1" v-model="oldPassword" />
</div>
</th>
</tr>
@ -44,12 +33,7 @@
<th>新密码</th>
<th>
<div class="input-group input-group-sm">
<input
type="password"
class="form-control"
aria-describedby="basic-addon1"
v-model="newPassword1"
/>
<input type="password" class="form-control" aria-describedby="basic-addon1" v-model="newPassword1" />
</div>
</th>
</tr>
@ -57,12 +41,7 @@
<th>确认新密码</th>
<th>
<div class="input-group input-group-sm">
<input
type="password"
class="form-control"
aria-describedby="basic-addon1"
v-model="newPassword2"
/>
<input type="password" class="form-control" aria-describedby="basic-addon1" v-model="newPassword2" />
</div>
</th>
</tr>
@ -71,12 +50,8 @@
<p>确认无误后,您可以进行以下操作:</p>
<div class="Line"></div>
<div class="PanelItemMuem">
<button class="btn btn-info" v-on:click="toRePassword()">
修改密码
</button>
<button class="btn btn-success" v-on:click="toBack()">
返回到用户中心
</button>
<button class="btn btn-info" v-on:click="toRePassword()">修改密码</button>
<button class="btn btn-success" v-on:click="toBack()">返回到用户中心</button>
</div>
</div>
</div>

View File

@ -6,39 +6,16 @@
<div class="row">
<div class="col-md-12">
<p>
<a
href="https://github.com/Suwings/MCSManager/blob/gh-pages/Question_1.md"
style="color: #2f3ad6"
>如何让 Minecraft 服务端运行在 Docker 镜像中?</a
>
<a
href="https://github.com/Suwings/MCSManager/blob/gh-pages/Question_2.md"
style="color: #2f3ad6"
>如何在我的电脑上安装 Docker</a
>
<a href="https://github.com/Suwings/MCSManager/blob/gh-pages/Question_1.md" style="color: #2f3ad6">如何让 Minecraft 服务端运行在 Docker 镜像中?</a>
<a href="https://github.com/Suwings/MCSManager/blob/gh-pages/Question_2.md" style="color: #2f3ad6">如何在我的电脑上安装 Docker</a>
</p>
<h4>DockerFile 文件</h4>
<p>
DockerFile 可以供你定制与参考,使用 DockerFile 来生成 Docker
镜像,随后使用镜像名与指定的服务端文件,就可以在 Docker 中开启
Minecraft 服务器。
</p>
<p style="color: red">
必须使用 /mcsd 作为工作目录。Docker
镜像名就是您生成后的名字,请一定要记住!
</p>
<p>DockerFile 可以供你定制与参考,使用 DockerFile 来生成 Docker 镜像,随后使用镜像名与指定的服务端文件,就可以在 Docker 中开启 Minecraft 服务器。</p>
<p style="color: red">必须使用 /mcsd 作为工作目录。Docker 镜像名就是您生成后的名字,请一定要记住!</p>
<!-- <pre id="dockerfile" contenteditable="true" autocomplete="off"></pre> -->
<textarea
id="dockerfile"
row="30"
style="height: 220px; width: 100%"
v-model="dockerFileText"
>
</textarea>
<textarea id="dockerfile" row="30" style="height: 220px; width: 100%" v-model="dockerFileText"> </textarea>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3"
>Docker 镜像名</span
>
<span class="input-group-addon" id="sizing-addon3">Docker 镜像名</span>
<input
type="text"
autocomplete="off"
@ -50,31 +27,15 @@
</div>
<p>
<b>
<span style="color: red"
>这需要联网下载文件构建,构建时间根据网络与处理器决定,大小约
700
MB可能需要一段时间可以关闭网页控制台任务完成后可以在结果列表按钮处查看结果。</span
>
<span style="color: red">这需要联网下载文件构建,构建时间根据网络与处理器决定,大小约 700 MB可能需要一段时间可以关闭网页控制台任务完成后可以在结果列表按钮处查看结果。</span>
<br />
<br />
<span
>如果出现构建失败失败,请尝试检查 Docker 服务是否成功启动
(service docker start),以及 docker
命令是否能执行,网络是否畅通。</span
>
<span>如果出现构建失败失败,请尝试检查 Docker 服务是否成功启动 (service docker start),以及 docker 命令是否能执行,网络是否畅通。</span>
</b>
</p>
<button
v-bind:disabled="createDockerDis"
class="btn btn-danger"
v-on:click="createDocker()"
>
创建 Docker 镜像
</button>
<button v-bind:disabled="createDockerDis" class="btn btn-danger" v-on:click="createDocker()">创建 Docker 镜像</button>
&nbsp;|&nbsp;
<button class="btn btn-success" v-on:click="toCreateRes()">
任务结果列表
</button>
<button class="btn btn-success" v-on:click="toCreateRes()">任务结果列表</button>
</div>
</div>
</div>
@ -85,16 +46,11 @@
<script>
MI.rListener("onload", function () {
// 定义页面地址
TOOLS.definePage(
"template/component/new_docker_image",
"genuser/home",
null
);
TOOLS.definePage("template/component/new_docker_image", "genuser/home", null);
new Vue({
el: "#NewDockerImage",
data: {
dockerFileText:
'FROM java:latest\nRUN mkdir -p /mcsd\nRUN echo "Asia/Shanghai" > /etc/timezone;dpkg-reconfigure -f noninteractive tzdata\nWORKDIR /mcsd',
dockerFileText: 'FROM java:latest\nRUN mkdir -p /mcsd\nRUN echo "Asia/Shanghai" > /etc/timezone;dpkg-reconfigure -f noninteractive tzdata\nWORKDIR /mcsd',
dockerImageName: "",
createDockerDis: false,
},
@ -104,16 +60,7 @@
dockerImageName: this.dockerImageName || "mcsd",
dockerfile: TOOLS.decode(this.dockerFileText),
};
if (
!confirm(
"DockerFile 文件:\n" +
obj.dockerfile +
"\n镜像名:" +
obj.dockerImageName +
"\n确认无误单击【确定】得以继续"
)
)
return;
if (!confirm("DockerFile 文件:\n" + obj.dockerfile + "\n镜像名:" + obj.dockerImageName + "\n确认无误单击【确定】得以继续")) return;
if (!TOOLS.isStdText(obj.dockerImageName)) {
TOOLS.pushMsgWindow("镜像名字不合法!仅限字母数字下划线!");
return;

View File

@ -14,28 +14,13 @@
</tr>
<tr>
<th>
<input
style="width: 90%"
type="text"
v-model="time"
placeholder="[必填]"
/>
<input style="width: 90%" type="text" v-model="time" placeholder="[必填]" />
</th>
<th>
<input
style="width: 90%"
type="text"
v-model="count"
placeholder="[必填]"
/>
<input style="width: 90%" type="text" v-model="count" placeholder="[必填]" />
</th>
<th>
<input
style="width: 100%"
type="text"
v-model="commande"
placeholder="如: stop,say Hello,__start__ 等等"
/>
<input style="width: 100%" type="text" v-model="commande" placeholder="如: stop,say Hello,__start__ 等等" />
</th>
</tr>
</table>
@ -44,26 +29,18 @@
<div class="row">
<hr />
<div class="col-sm-12 PanelItemF">
<p>
如果您不会填写,请仔细阅读参数手册,或者使用简单模式来生成参数。
</p>
<p>如果您不会填写,请仔细阅读参数手册,或者使用简单模式来生成参数。</p>
<div class="PanelItem" v-on:click="toSave()">
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
新建/保存
</div>
<div class="PanelItem" v-on:click="toBack()">
<span
class="glyphicon glyphicon-remove"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
放弃并返回
</div>
<div class="PanelItem" v-on:click="toPopWindForTime()">
<span
class="glyphicon glyphicon-certificate"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-certificate" aria-hidden="true"></span>
<span style="color: #ec1616">使用简单模式生成(推荐)</span>
</div>
</div>
@ -76,33 +53,22 @@
<div class="row">
<div class="col-md-12">
<p>这是服务器 {{servername}} 的其中一个计划任务项目控制。</p>
<p>
这里是计划任务项目的所有数据,请根据您的需要更改,如果不知如何更改,请仔细阅读下面说明:
</p>
<p>这里是计划任务项目的所有数据,请根据您的需要更改,如果不知如何更改,请仔细阅读下面说明:</p>
<p>
<b>任务时间间隔</b>
</p>
<p>
如果您使用过 Linux 的 crontab
命令,您会发现它的用法非常相似。总共有 6 个 *
号,其中按照顺序代表不同的时间,分别是
秒,分,时,每月第几天,第几个月,每周第几天
</p>
<p>如果您使用过 Linux 的 crontab 命令,您会发现它的用法非常相似。总共有 6 个 * 号,其中按照顺序代表不同的时间,分别是 秒,分,时,每月第几天,第几个月,每周第几天</p>
<p>如果您不会使用这个,请按照以下修改:</p>
<p>
<code> */20 */2 * * * * </code> &nbsp;代表每隔 2
分钟的一分钟内每隔 20 秒执行一次
<code> */20 */2 * * * * </code> &nbsp;代表每隔 2 分钟的一分钟内每隔 20 秒执行一次
<br />
<code> */1 * * * * * </code> &nbsp;代表每 1 秒钟执行一次 (1~59)
<br />
<code> 1 */5 * * * * </code> &nbsp;代表每 5 分钟的第一秒时执行一次
(1~59)
<code> 1 */5 * * * * </code> &nbsp;代表每 5 分钟的第一秒时执行一次 (1~59)
<br />
<code> 1 1 */4 * * * </code> &nbsp;代表每 4
小时第一分钟第一秒时执行一次 (1~24)
<code> 1 1 */4 * * * </code> &nbsp;代表每 4 小时第一分钟第一秒时执行一次 (1~24)
<br />
<code> 1 1 1 */2 * * </code> &nbsp;代表每 2 天的(同理)执行一次
(1~31)
<code> 1 1 1 */2 * * </code> &nbsp;代表每 2 天的(同理)执行一次 (1~31)
</p>
<p>其他的您基本使用不到,无需学习过多。</p>
<p>
@ -110,9 +76,7 @@
</p>
<p>数字 0 代表重复任务,不断执行,直到您手动删除掉它。</p>
<p>数字大于 0 代表计次任务,代表着执行多少次之后自动删除。</p>
<p>
注意:如果在计次次数未归零前,控制面板被关闭,我们只能重新计次。
</p>
<p>注意:如果在计次次数未归零前,控制面板被关闭,我们只能重新计次。</p>
<p>
<b>任务指令</b>
</p>
@ -120,9 +84,7 @@
向 Minecraft 服务器一样,正常的输入命令即可,切记不要加
<code>/</code>
</p>
<p>
特殊指令__start__ 代表开启服务器__restart__ 代表重启服务器。
</p>
<p>特殊指令__start__ 代表开启服务器__restart__ 代表重启服务器。</p>
</div>
</div>
</div>
@ -145,11 +107,7 @@
},
methods: {
toBack: function () {
RES.redirectPage(
"./template/component/schedule.html",
"schedule/list",
servername
);
RES.redirectPage("./template/component/schedule.html", "schedule/list", servername);
},
toSave: function () {
if (this.id.length >= 1) {

View File

@ -4,127 +4,61 @@
<div class="Panel PanelGreen">
<div class="PanelTitle">创建服务器</div>
<div class="PanelBody">
<p>
您可以创建一个新的服务器,默认所有用户不可操作,只限于管理员一人可以控制。
</p>
<p>您可以创建一个新的服务器,默认所有用户不可操作,只限于管理员一人可以控制。</p>
<p>不过创建一个服务器您可以需要完善以下信息:</p>
<div class="row" style="padding-top: 10px; padding-bottom: 30px">
<div class="col-md-6">
<p>
[必填] 服务器名字必须唯一,这个名字标识唯一的一个服务器终端
(仅限字母数字下划线组合)
</p>
<p>[必填] 服务器名字必须唯一,这个名字标识唯一的一个服务器终端 (仅限字母数字下划线组合)</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">服务器名字</span>
<input
type="text"
class="form-control"
v-model="name"
placeholder="[不可空,必填]"
/>
<input type="text" class="form-control" v-model="name" placeholder="[不可空,必填]" />
</div>
<p>
[可填]
服务端核心文件,可以后再填或上传后再填,因为服务端目录还未创建,但是您指定目录的话就可填写.
</p>
<p>[可填] 服务端核心文件,可以后再填或上传后再填,因为服务端目录还未创建,但是您指定目录的话就可填写.</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 服务端文件名 </span>
<input type="text" class="form-control" v-model="jarName" />
</div>
<p>
[选填]
您可以指定您计算机上的Java环境程序路径默认自动选择环境变量
</p>
<p>[选填] 您可以指定您计算机上的Java环境程序路径默认自动选择环境变量</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">Java 路径</span>
<input
type="text"
class="form-control"
v-model="java"
placeholder="[自动]"
/>
<input type="text" class="form-control" v-model="java" placeholder="[自动]" />
</div>
<p>
[选填]
您可以从已有的服务器配置中,复制一份配置到这里,来避免重复的输入相同的数据。
</p>
<p>[选填] 您可以从已有的服务器配置中,复制一份配置到这里,来避免重复的输入相同的数据。</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">目标实例名字</span>
<input
type="text"
class="form-control"
v-model="readServerName"
placeholder="[在此输入目标服务端的名字即可复制它的配置项目]"
/>
<input type="text" class="form-control" v-model="readServerName" placeholder="[在此输入目标服务端的名字即可复制它的配置项目]" />
<span class="input-group-btn">
<button
class="btn btn-default"
v-on:click="readServerConfig(readServerName)"
>
导入配置
</button>
<button class="btn btn-default" v-on:click="readServerConfig(readServerName)">导入配置</button>
</span>
</div>
</div>
<div class="col-md-6">
<p>
[选填] 一般而言当您需要附加参数如 (-server 等等) 时,可以填写
</p>
<p>[选填] 一般而言当您需要附加参数如 (-server 等等) 时,可以填写</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">启动附加参数</span>
<input
type="text"
class="form-control"
v-model="addCmd"
placeholder="[无附加参数]"
/>
<input type="text" class="form-control" v-model="addCmd" placeholder="[无附加参数]" />
</div>
<p>
[选填]
可不填写,只有当您需要指定目录时填写,默认将自动建立目录,选择好请单击按钮确认
</p>
<p style="color: #b92c28">
当前服务端根目录设为: {{ serverCwd }}
</p>
<p>[选填] 可不填写,只有当您需要指定目录时填写,默认将自动建立目录,选择好请单击按钮确认</p>
<p style="color: #b92c28">当前服务端根目录设为: {{ serverCwd }}</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">服务端文件根目录</span>
<input
type="text"
class="form-control"
v-model="cwd"
:placeholder="serverCwd"
/>
<input type="text" class="form-control" v-model="cwd" :placeholder="serverCwd" />
<span class="input-group-btn">
<button class="btn btn-success" v-on:click="toCreaterDir()">
确认创建目录
</button>
<button class="btn btn-success" v-on:click="toCreaterDir()">确认创建目录</button>
</span>
</div>
<p>
[选填]
根据您的需求或计算机内存大小填写,默认自动,需要在数字后加单位
</p>
<p>[选填] 根据您的需求或计算机内存大小填写,默认自动,需要在数字后加单位</p>
<div class="row">
<div class="col-sm-6">
<div class="input-group input-group-sm">
<span class="input-group-addon"> 最大内存堆 </span>
<input
type="text"
class="form-control"
v-model="Xmx"
placeholder="[缺省值]"
/>
<input type="text" class="form-control" v-model="Xmx" placeholder="[缺省值]" />
</div>
</div>
<div class="col-sm-6">
<div class="input-group input-group-sm">
<span class="input-group-addon"> 初始内存堆 </span>
<input
type="text"
class="form-control"
v-model="Xms"
placeholder="[缺省值]"
/>
<input type="text" class="form-control" v-model="Xms" placeholder="[缺省值]" />
</div>
</div>
</div>
@ -132,15 +66,11 @@
</div>
<div class="row">
<div class="col-lg-12">
<p>
到目前为止,我们创建一个服务器只需要这些信息足以,您可以在创建之后修改相关配置;
</p>
<p>到目前为止,我们创建一个服务器只需要这些信息足以,您可以在创建之后修改相关配置;</p>
<p>或者,如果您想的话,可以分配给其他用户使用。</p>
<div class="Line"></div>
<div class="" style="float: right; margin-top: 20px">
<button class="btn btn-primary" v-on:click="toCreateServer()">
创建服务器
</button>
<button class="btn btn-primary" v-on:click="toCreateServer()">创建服务器</button>
</div>
</div>
</div>
@ -153,14 +83,8 @@
<div class="Panel PanelRed">
<div class="PanelTitle">创建服务器相关协议</div>
<div class="PanelBody">
<p>
您使用本控制面板创建 Minecraft
之后,请遵循您所使用的那个服务端的相关协议;
</p>
<p>
面板不会自动同意Minecraft
EULA最终用户协议请首次启动后手动修改eula.txt文件更改。
</p>
<p>您使用本控制面板创建 Minecraft 之后,请遵循您所使用的那个服务端的相关协议;</p>
<p>面板不会自动同意Minecraft EULA最终用户协议请首次启动后手动修改eula.txt文件更改。</p>
<p>尊重版权,请支持 Minecraft 正版。</p>
</div>
</div>

View File

@ -46,10 +46,7 @@
<div class="PAGE_NewserverxLogV">
<p>引导创建(推荐)</p>
</div>
<div class="PAGE_NewserverxLogK">
适应于基于 Java 开发的主流服务端SpigotBukkitBungeecord
等)
</div>
<div class="PAGE_NewserverxLogK">适应于基于 Java 开发的主流服务端SpigotBukkitBungeecord 等)</div>
</div>
</div>
<div class="col-md-4">
@ -57,9 +54,7 @@
<div class="PAGE_NewserverxLogV">
<p>快速创建</p>
</div>
<div class="PAGE_NewserverxLogK">
适应于基于 Java 开发的主流服务端,并且非常熟悉面板操作的用户
</div>
<div class="PAGE_NewserverxLogK">适应于基于 Java 开发的主流服务端,并且非常熟悉面板操作的用户</div>
</div>
</div>
<div class="col-md-4">
@ -67,9 +62,7 @@
<div class="PAGE_NewserverxLogV">
<p>自定义启动命令</p>
</div>
<div class="PAGE_NewserverxLogK">
支持所有类型的服务端,支持所有程序,甚至可以启动脚本来实现各种需求
</div>
<div class="PAGE_NewserverxLogK">支持所有类型的服务端,支持所有程序,甚至可以启动脚本来实现各种需求</div>
</div>
</div>
</div>
@ -77,11 +70,7 @@
</div>
</div>
<div
class="PAGE_NewserverxCreatePanelWapper"
v-show="pagecode==1"
style="max-width: 500px"
>
<div class="PAGE_NewserverxCreatePanelWapper" v-show="pagecode==1" style="max-width: 500px">
<div class="Panel PanelBlack">
<div class="PanelTitle">项目确定</div>
<div class="PanelBody">
@ -96,20 +85,11 @@
<p>项目存放目录,一般情况自动即可</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">项目位置</span>
<input
type="text"
class="form-control"
placeholder="[自动]"
v-model="cwd"
/>
<input type="text" class="form-control" placeholder="[自动]" v-model="cwd" />
</div>
<div class="PAGE_NewserverNextWapper">
<button class="btn btn-warning" v-on:click="previousStep">
上一步
</button>
<button class="btn btn-success" v-on:click="nextStep">
下一步
</button>
<button class="btn btn-warning" v-on:click="previousStep">上一步</button>
<button class="btn btn-success" v-on:click="nextStep">下一步</button>
</div>
</div>
</div>
@ -123,39 +103,19 @@
<div class="PanelBody">
<div class="row">
<div class="col-md-12">
<p v-show="selectCreateType==0">
请上传你的核心程序或者 Minecraft 服务端程序。
</p>
<p v-show="selectCreateType==0">
通常都是以 jar
结尾的文件支持大部分主流服务端SpigotBukkitBungeecord 等)
</p>
<p v-show="selectCreateType==2">
上传你的程序,记住你的文件名,稍后可能会用到
</p>
<p v-show="selectCreateType==2">
支持任何可执行程序,支持所有服务端程序,(如 jar,exe,bat,sh
</p>
<p v-show="selectCreateType==0">请上传你的核心程序或者 Minecraft 服务端程序。</p>
<p v-show="selectCreateType==0">通常都是以 jar 结尾的文件支持大部分主流服务端SpigotBukkitBungeecord 等)</p>
<p v-show="selectCreateType==2">上传你的程序,记住你的文件名,稍后可能会用到</p>
<p v-show="selectCreateType==2">支持任何可执行程序,支持所有服务端程序,(如 jar,exe,bat,sh</p>
<p>
<button class="btn btn-primary" v-on:click="uploadFile()">
选择上传文件
</button>
<span
>&nbsp;&nbsp;上传进度:
<span id="uploadPercentComplete">0%</span></span
>
<button class="btn btn-primary" v-on:click="uploadFile()">选择上传文件</button>
<span>&nbsp;&nbsp;上传进度: <span id="uploadPercentComplete">0%</span></span>
</p>
<p class="red">实例项目存放目录: {{serverCwd}}</p>
<p class="red">
启动程序端: <span class="color-high-red">{{jarName}}</span>
</p>
<p class="red">启动程序端: <span class="color-high-red">{{jarName}}</span></p>
<div class="PAGE_NewserverNextWapper">
<button class="btn btn-warning" v-on:click="previousStep">
上一步
</button>
<button class="btn btn-success" v-on:click="nextStep">
下一步
</button>
<button class="btn btn-warning" v-on:click="previousStep">上一步</button>
<button class="btn btn-success" v-on:click="nextStep">下一步</button>
</div>
</div>
</div>
@ -163,11 +123,7 @@
</div>
</div>
<div
class="PAGE_NewserverxCreatePanelWapper"
style="margin-top: 5%"
v-show="pagecode==3&&selectCreateType==0"
>
<div class="PAGE_NewserverxCreatePanelWapper" style="margin-top: 5%" v-show="pagecode==3&&selectCreateType==0">
<div class="Panel PanelGreen">
<div class="PanelTitle">即将创建</div>
<div class="PanelBody">
@ -175,44 +131,25 @@
<div class="col-md-12">
<h4>确保 Java 安装正常,再填写相关启动参数,即可创建完成</h4>
<br />
<p>
[选填]
根据您的需求或计算机内存大小填写,默认自动,需要在数字后加单位(如
1024M2G
</p>
<p>[选填] 根据您的需求或计算机内存大小填写,默认自动,需要在数字后加单位(如 1024M2G</p>
<div class="row">
<div class="col-sm-6">
<div class="input-group input-group-sm">
<span class="input-group-addon"> 最大内存堆 </span>
<input
type="text"
class="form-control"
v-model="Xmx"
placeholder="[自动] 若填写请加单位(如1024M,2G)"
/>
<input type="text" class="form-control" v-model="Xmx" placeholder="[自动] 若填写请加单位(如1024M,2G)" />
</div>
</div>
<div class="col-sm-6">
<div class="input-group input-group-sm">
<span class="input-group-addon"> 初始内存堆 </span>
<input
type="text"
class="form-control"
v-model="Xms"
placeholder="[自动] 若填写请加单位(如1024M,2G)"
/>
<input type="text" class="form-control" v-model="Xms" placeholder="[自动] 若填写请加单位(如1024M,2G)" />
</div>
</div>
</div>
<p>[选填] 一般而言当您需要附加参数如 (-server 等等) 时,可以填写</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">启动附加参数</span>
<input
type="text"
class="form-control"
v-model="addCmd"
placeholder="[无附加参数,可不填] (列如: -server)"
/>
<input type="text" class="form-control" v-model="addCmd" placeholder="[无附加参数,可不填] (列如: -server)" />
</div>
</div>
<div class="col-md-12">
@ -220,17 +157,10 @@
<p><b>实例项目名:</b> {{name}}</p>
<p><b>服务端文件:</b> {{jarName}}</p>
<p><b>存放目录:</b> {{serverCwd}}</p>
<p>
<b>最大内存:</b>{{Xmx || '自动'}}<b> | 最小内存:</b>{{Xms ||
'自动'}} <b> | 附加参数:</b>{{addCmd || '无'}}
</p>
<p><b>最大内存:</b>{{Xmx || '自动'}}<b> | 最小内存:</b>{{Xms || '自动'}} <b> | 附加参数:</b>{{addCmd || '无'}}</p>
<div class="PAGE_NewserverNextWapper">
<button class="btn btn-warning" v-on:click="previousStep">
上一步
</button>
<button class="btn btn-success" v-on:click="toCreateServer">
确认无误,立刻创建
</button>
<button class="btn btn-warning" v-on:click="previousStep">上一步</button>
<button class="btn btn-success" v-on:click="toCreateServer">确认无误,立刻创建</button>
</div>
</div>
</div>
@ -238,29 +168,18 @@
</div>
</div>
<div
class="PAGE_NewserverxCreatePanelWapper"
style="margin-top: 10%"
v-show="pagecode==3&&selectCreateType==2"
>
<div class="PAGE_NewserverxCreatePanelWapper" style="margin-top: 10%" v-show="pagecode==3&&selectCreateType==2">
<div class="Panel PanelBlack">
<div class="PanelTitle">填写自定义启动命令</div>
<div class="PanelBody">
<div class="row">
<div class="col-md-12">
<p>
通常是一行启动命令,若你想启动多行命令,可将命令写在脚本文件中,然后在这里启动脚本
</p>
<p>通常是一行启动命令,若你想启动多行命令,可将命令写在脚本文件中,然后在这里启动脚本</p>
<br />
<div class="input-group input-group-sm">
<span class="input-group-addon">启动命令</span>
<input
type="text"
class="form-control"
placeholder="程序启动命令.... (列如: java -jar xxx.jar)"
v-model="highCommande"
/>
<input type="text" class="form-control" placeholder="程序启动命令.... (列如: java -jar xxx.jar)" v-model="highCommande" />
</div>
<small>运行目录: {{serverCwd}} </small>
<br />
@ -268,25 +187,13 @@
<br /><br />
<p>自定义命令可以帮助您执行任何命令,请务必仔细阅读以下文字!</p>
<ul class="ulInfo">
<li>
若是 java 程序可能需要添加
-Djline.terminal=jline.UnsupportedTerminal 参数在 -jar 之前。
</li>
<li>
示范: java -Djline.terminal=jline.UnsupportedTerminal -jar
run.jar --nogui
</li>
<li>
示范: "bash""cmd.exe""./start_server.sh" 或 "python xxx.py"
</li>
<li>若是 java 程序可能需要添加 -Djline.terminal=jline.UnsupportedTerminal 参数在 -jar 之前。</li>
<li>示范: java -Djline.terminal=jline.UnsupportedTerminal -jar run.jar --nogui</li>
<li>示范: "bash""cmd.exe""./start_server.sh" 或 "python xxx.py"</li>
</ul>
<div class="PAGE_NewserverNextWapper">
<button class="btn btn-warning" v-on:click="previousStep">
上一步
</button>
<button class="btn btn-success" v-on:click="toCreateServer">
确认无误,立刻创建
</button>
<button class="btn btn-warning" v-on:click="previousStep">上一步</button>
<button class="btn btn-success" v-on:click="toCreateServer">确认无误,立刻创建</button>
</div>
</div>
</div>
@ -294,19 +201,8 @@
</div>
</div>
<!-- 文件上传时的表单 -->
<form
id="PAGE_UploadForm"
style="display: none"
method="post"
enctype="multipart/form-data"
action="/fileupload"
>
<input
type="file"
name="upload_file"
id="PAGE_UploadFormButton"
v-on:change="uploadFormChange"
/>
<form id="PAGE_UploadForm" style="display: none" method="post" enctype="multipart/form-data" action="/fileupload">
<input type="file" name="upload_file" id="PAGE_UploadFormButton" v-on:change="uploadFormChange" />
<input type="text" name="cwd" v-model="cwd" />
</form>
</div>
@ -411,8 +307,7 @@
},
computed: {
serverCwd: function () {
if (this.cwd == "")
return "<面板所在目录>/server/server_core/" + this.name + "/";
if (this.cwd == "") return "<面板所在目录>/server/server_core/" + this.name + "/";
return this.cwd;
},
},

View File

@ -8,10 +8,7 @@
<div class="col-sm-12 PanelItemF">
<p>您可以进行如下操作:</p>
<div class="PanelItem" v-on:click="toBackConsole()">
<span
class="glyphicon glyphicon-backward"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-backward" aria-hidden="true"></span>
返回到控制台
</div>
<div class="PanelItem" v-on:click="toUpdateProperties()">
@ -19,17 +16,11 @@
更新配置
</div>
<div class="PanelItem" v-on:click="re()">
<span
class="glyphicon glyphicon-repeat"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>
从内存刷新
</div>
<div class="PanelItem" v-on:click="toUpdatePropertiesFormFile()">
<span
class="glyphicon glyphicon-retweet"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-retweet" aria-hidden="true"></span>
从文件刷新
</div>
</div>
@ -37,10 +28,7 @@
<div class="row">
<div class="col-lg-12">
<p>{{ serverName }} 服务器 Properties 配置文件更改</p>
<p>
解释: true 代表开, false
代表关,空白代表无值,请注意格式修改,确认无误保存即可,重启服务端生效
</p>
<p>解释: true 代表开, false 代表关,空白代表无值,请注意格式修改,确认无误保存即可,重启服务端生效</p>
<table class="PropertiesList" width="100%">
<tr>
<th>原字段键值</th>
@ -53,12 +41,7 @@
<th>
<center>
<div class="input-group input-group-sm">
<input
type="text"
class="form-control"
aria-describedby="basic-addon1"
v-model="properties[key]"
/>
<input type="text" class="form-control" aria-describedby="basic-addon1" v-model="properties[key]" />
</div>
</center>
</th>
@ -68,34 +51,20 @@
<div class="row">
<div class="col-sm-12 PanelItemF">
<div class="PanelItem" v-on:click="toBackConsole()">
<span
class="glyphicon glyphicon-backward"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-backward" aria-hidden="true"></span>
返回到控制台
</div>
<div class="PanelItem" v-on:click="toUpdateProperties()">
<span
class="glyphicon glyphicon-ok"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
更新配置
</div>
<div class="PanelItem" v-on:click="re()">
<span
class="glyphicon glyphicon-repeat"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>
重新刷新读取
</div>
<hr />
<p>
最后,请检查是否符合格式,条件,仔细检查后即可确认修改,或者直接返回到其他页面直接舍弃修改。
</p>
<p>
如果显示不全或不是最新,您可以单击 [重新刷新读取]
来进行获取更新,设置完毕请重启服务器。
</p>
<p>最后,请检查是否符合格式,条件,仔细检查后即可确认修改,或者直接返回到其他页面直接舍弃修改。</p>
<p>如果显示不全或不是最新,您可以单击 [重新刷新读取] 来进行获取更新,设置完毕请重启服务器。</p>
</div>
</div>
</div>
@ -109,11 +78,7 @@
<script src="./common/js/properties.js"></script>
<script>
// 定义页面地址
TOOLS.definePage(
"template/component/properties",
"server/properties",
MCSERVER.listenServername
);
TOOLS.definePage("template/component/properties", "server/properties", MCSERVER.listenServername);
MI.rListener("onload", function () {
// MCSERVER.autoColmDo();
@ -130,18 +95,10 @@
WS.sendMsg("server/properties_update", JSON.stringify(obj));
},
toBackConsole: function () {
RES.redirectPage(
"./template/component/console.html",
"server/console",
this.serverName
);
RES.redirectPage("./template/component/console.html", "server/console", this.serverName);
},
re: function () {
RES.redirectPage(
"./template/component/properties.html",
"server/properties",
this.serverName
);
RES.redirectPage("./template/component/properties.html", "server/properties", this.serverName);
},
toUpdatePropertiesFormFile: function () {
WS.sendMsg("server/properties_update_reload", this.serverName);

View File

@ -7,17 +7,11 @@
<div class="row">
<div class="col-sm-12 PanelItemF">
<div class="PanelItem" v-on:click="toBackConsole()">
<span
class="glyphicon glyphicon-backward"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-backward" aria-hidden="true"></span>
返回到控制台
</div>
<div class="PanelItem" v-on:click="toBackNew()">
<span
class="glyphicon glyphicon-plus"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
新建计划任务项目
</div>
</div>
@ -25,12 +19,7 @@
<div class="row">
<div class="col-lg-12">
<p>欢迎您,{{username}},这是本服务器的计划任务列表</p>
<p>
<b>凡是</b> __xxx__
格式的命令均是内部命令,不影响使用,请勿乱使用,以防错误。
<b>另外</b>,任务性质为 0 代表重复任务,不为 0
代表计次任务并且代表剩余计次数量。
</p>
<p><b>凡是</b> __xxx__ 格式的命令均是内部命令,不影响使用,请勿乱使用,以防错误。 <b>另外</b>,任务性质为 0 代表重复任务,不为 0 代表计次任务并且代表剩余计次数量。</p>
<table class="PropertiesList" width="100%">
<tr>
<th class="PhoneDisplayNone">任务序号</th>
@ -65,21 +54,13 @@
MCSERVER.website.schedule = {};
// 定义页面地址
TOOLS.definePage(
"template/component/schedule",
"schedule/list",
MCSERVER.listenServername
);
TOOLS.definePage("template/component/schedule", "schedule/list", MCSERVER.listenServername);
VIEW_MODEL.newVue("ServerSchedule", {
el: "#ServerSchedule",
methods: {
toBackConsole: function () {
RES.redirectPage(
"./template/component/console.html",
"server/console",
this.servername
);
RES.redirectPage("./template/component/console.html", "server/console", this.servername);
},
toBackNew: function () {
RES.redirectPage("./template/component/new_schedule.html", null);

View File

@ -29,60 +29,28 @@
<div class="col-md-6">
<div class="input-group input-group-sm">
<span class="input-group-addon">服务器唯一标识名</span>
<input
type="text"
class="form-control"
v-model="name"
placeholder="[未设定]"
/>
<input type="text" class="form-control" v-model="name" placeholder="[未设定]" />
</div>
<p>如果您 Java 环境无误,使用 "java" 环境变量即可</p>
<div class="input-group input-group-sm">
<span class="input-group-addon">Java 路径</span>
<input
v-bind:disabled="isHighCommande"
type="text"
class="form-control"
v-model="java"
placeholder="[未设定]"
/>
<input v-bind:disabled="isHighCommande" type="text" class="form-control" v-model="java" placeholder="[未设定]" />
</div>
<p>端根目录: [ {{ cwd }} ]</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 服务端文件名 </span>
<input
v-bind:disabled="isHighCommande"
type="text"
class="form-control"
v-model="jarName"
placeholder="[未设定]"
/>
<input v-bind:disabled="isHighCommande" type="text" class="form-control" v-model="jarName" placeholder="[未设定]" />
</div>
<p>
如需设置请按照 2018/10/1
这种格式,到期后服务端将无法开启,但文件依然可以上传下载。你可以从用户的可用服务端列表让他彻底对此失去控制。
</p>
<p>如需设置请按照 2018/10/1 这种格式,到期后服务端将无法开启,但文件依然可以上传下载。你可以从用户的可用服务端列表让他彻底对此失去控制。</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 到期限制 </span>
<input
v-bind:disabled="isHighCommande"
type="text"
class="form-control"
v-model="timeLimitDate"
placeholder="[未设定 如 2018/10/1 2020/1/12]"
/>
<input v-bind:disabled="isHighCommande" type="text" class="form-control" v-model="timeLimitDate" placeholder="[未设定 如 2018/10/1 2020/1/12]" />
</div>
</div>
<div class="col-md-6">
<div class="input-group input-group-sm">
<span class="input-group-addon">启动附加参数</span>
<input
v-bind:disabled="isHighCommande"
type="text"
class="form-control"
v-model="addCmd"
placeholder="[可空 列如: -server -xxx 等]"
/>
<input v-bind:disabled="isHighCommande" type="text" class="form-control" v-model="addCmd" placeholder="[可空 列如: -server -xxx 等]" />
</div>
<p>服务端文件与数据的目录所在地。</p>
<div class="input-group input-group-sm">
@ -93,53 +61,30 @@
<p>实质是 -Xmx -Xms 参数,填写请加单位(M,G)</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 最大内存堆 </span>
<input
v-bind:disabled="isHighCommande"
type="text"
class="form-control"
v-model="Xmx"
placeholder="[自动 如需修改请加单位]"
/>
<input v-bind:disabled="isHighCommande" type="text" class="form-control" v-model="Xmx" placeholder="[自动 如需修改请加单位]" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 初始内存堆 </span>
<input
v-bind:disabled="isHighCommande"
type="text"
class="form-control"
v-model="Xms"
placeholder="[自动 如需修改请加单位]"
/>
<input v-bind:disabled="isHighCommande" type="text" class="form-control" v-model="Xms" placeholder="[自动 如需修改请加单位]" />
</div>
<div class="row">
<div class="col-lg-12">
<p>
端 1.9.X 以上可能需要输入编码为
UTF-8如控制台有乱码可修改这里。 <br />
端 1.9.X 以上可能需要输入编码为 UTF-8如控制台有乱码可修改这里。 <br />
默认值: Windows 默认 GBK 编码Linux 默认 UTF8 编码。
</p>
</div>
<div class="col-lg-6">
<div class="input-group input-group-sm">
<span class="input-group-addon"> 日志输出编码 </span>
<input
type="text"
class="form-control"
v-model="oe"
placeholder="[默认 自动选择]"
/>
<input type="text" class="form-control" v-model="oe" placeholder="[默认 自动选择]" />
</div>
</div>
<div class="col-lg-6">
<div class="input-group input-group-sm">
<span class="input-group-addon"> 命令输入编码 </span>
<input
type="text"
class="form-control"
v-model="ie"
placeholder="[默认 自动选择]"
/>
<input type="text" class="form-control" v-model="ie" placeholder="[默认 自动选择]" />
</div>
</div>
</div>
@ -180,17 +125,11 @@
<div class="row">
<div class="col-lg-12">
<div class="" style="float: right; margin-top: 20px">
<button class="btn btn-danger" v-on:click="toDocker(name)">
Docker 配置
</button>
<button class="btn btn-danger" v-on:click="toDocker(name)">Docker 配置</button>
&nbsp;|&nbsp;
<button class="btn btn-primary" v-on:click="toConsole(name)">
控制面板
</button>
<button class="btn btn-primary" v-on:click="toConsole(name)">控制面板</button>
&nbsp;|&nbsp;
<button class="btn btn-success" v-on:click="toRebulider()">
保存设置
</button>
<button class="btn btn-success" v-on:click="toRebulider()">保存设置</button>
</div>
</div>
</div>
@ -231,11 +170,7 @@
},
toConsole: function (serverName) {
MCSERVER.listenServername = this.oldServerName;
RES.redirectPage(
"./template/component/console.html",
"server/console",
this.oldServerName
);
RES.redirectPage("./template/component/console.html", "server/console", this.oldServerName);
},
toRebulider: function () {
var addCmdList = this.addCmd.split(" ");
@ -243,10 +178,7 @@
TOOLS.pushMsgWindow("服务器名字不合法!仅限字母数字下划线!");
return;
}
if (
this.timeLimitDate != "" &&
!TOOLS.isSmallDate(this.timeLimitDate)
) {
if (this.timeLimitDate != "" && !TOOLS.isSmallDate(this.timeLimitDate)) {
TOOLS.pushMsgWindow("您输入的时间期限格式不正确,请检查再尝试。");
return;
}
@ -281,11 +213,8 @@
},
},
});
VIEW_MODEL["ServerPanel"].addCmd = VIEW_MODEL["ServerPanel"].addCmd
.toString()
.replace(/,/gim, " ");
VIEW_MODEL["ServerPanel"].oldServerName =
VIEW_MODEL["ServerPanel"].name + "";
VIEW_MODEL["ServerPanel"].addCmd = VIEW_MODEL["ServerPanel"].addCmd.toString().replace(/,/gim, " ");
VIEW_MODEL["ServerPanel"].oldServerName = VIEW_MODEL["ServerPanel"].name + "";
});
MI.rListener("onend", function () {});

View File

@ -1,56 +1,29 @@
<div id="Terminal">
<div class="row" style="position: absolute; right: 16px">
<div class="col-sm-12 PanelItemF">
<div
class="PanelItem PanelItemBlack"
v-on:click="RES.redirectPage('./template/component/console.html', 'server/console', MCSERVER.listenServername);"
>
<span
class="glyphicon glyphicon-modal-window"
aria-hidden="true"
></span>
<div class="PanelItem PanelItemBlack" v-on:click="RES.redirectPage('./template/component/console.html', 'server/console', MCSERVER.listenServername);">
<span class="glyphicon glyphicon-modal-window" aria-hidden="true"></span>
控制台
</div>
<div
v-if="MCSERVER.username.substr(0, 1)=='#'"
class="PanelItem PanelItemBlack"
v-on:click="RES.redirectPage('./template/server.html', 'server/view', '');"
>
<div v-if="MCSERVER.username.substr(0, 1)=='#'" class="PanelItem PanelItemBlack" v-on:click="RES.redirectPage('./template/server.html', 'server/view', '');">
<span class="glyphicon glyphicon-list" aria-hidden="true"></span>
实例列表
</div>
<div class="PanelItem PanelItemBlack" v-on:click="loadHistory()">
<span
class="glyphicon glyphicon-facetime-video"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-facetime-video" aria-hidden="true"></span>
历史
</div>
<div
class="PanelItem PanelItemBlack PhoneDisplayNone"
v-on:click="goBttom()"
>
<span
class="glyphicon glyphicon-download PhoneDisplayNone"
aria-hidden="true"
></span>
<div class="PanelItem PanelItemBlack PhoneDisplayNone" v-on:click="goBttom()">
<span class="glyphicon glyphicon-download PhoneDisplayNone" aria-hidden="true"></span>
底部
</div>
<div class="PanelItem PanelItemBlack" v-on:click="clearConsole()">
<span class="glyphicon glyphicon-th-large" aria-hidden="true"></span>
清屏
</div>
<div class="PanelItem PanelItemBlack" v-on:click="stopServer()">
<span class="glyphicon glyphicon-pause" aria-hidden="true"></span> 关闭
</div>
<div
class="PanelItem PanelItemBlack PhoneDisplayNone"
v-on:click="toOpenServer()"
>
<span
class="glyphicon glyphicon-play PhoneDisplayNone"
aria-hidden="true"
></span>
<div class="PanelItem PanelItemBlack" v-on:click="stopServer()"><span class="glyphicon glyphicon-pause" aria-hidden="true"></span> 关闭</div>
<div class="PanelItem PanelItemBlack PhoneDisplayNone" v-on:click="toOpenServer()">
<span class="glyphicon glyphicon-play PhoneDisplayNone" aria-hidden="true"></span>
开启
</div>
</div>
@ -79,11 +52,7 @@
<script>
MI.rListener("onload", function () {
// 定义页面地址
TOOLS.definePage(
"template/component/terminal",
"server/console",
MCSERVER.listenServername
);
TOOLS.definePage("template/component/terminal", "server/console", MCSERVER.listenServername);
PAGE.nowPage = 0; //当前最低页
PAGE.serverName = MCSERVER.listenServername;
@ -97,16 +66,10 @@
WS.sendMsg("server/console/ws", PAGE.serverName);
PAGE.TerminalMinecraft = $("#TerminalMinecraft");
PAGE.TerminalMinecraft.css(
"height",
document.body.clientHeight - 45 + "px"
);
PAGE.TerminalMinecraft.css("height", document.body.clientHeight - 45 + "px");
PAGE.tmp_onresize = function () {
$("#TerminalMinecraft").css(
"height",
document.body.clientHeight - 45 + "px"
);
$("#TerminalMinecraft").css("height", document.body.clientHeight - 45 + "px");
};
MI.listener("resize", PAGE.tmp_onresize);
@ -137,8 +100,7 @@
WS.sendMsg("server/console/open", PAGE.serverName);
},
toCommand: function (parCommand) {
if (parCommand && typeof parCommand == "string")
this.command = parCommand;
if (parCommand && typeof parCommand == "string") this.command = parCommand;
var data = {
command: this.command,
serverName: PAGE.serverName,
@ -152,15 +114,9 @@
this.commandListPrint = 0;
},
toCommandhi: function (fl) {
if (this.commandListPrint > this.commandList.length - 1)
this.commandListPrint = this.commandList.length - 1;
if (this.commandListPrint > this.commandList.length - 1) this.commandListPrint = this.commandList.length - 1;
if (this.commandListPrint < 0) this.commandListPrint = 0;
console.log(
"commandListPrint",
this.commandListPrint,
"vlaue",
this.commandList[this.commandListPrint]
);
console.log("commandListPrint", this.commandListPrint, "vlaue", this.commandList[this.commandListPrint]);
if (fl == 1) {
//up
this.command = this.commandList[this.commandListPrint];

View File

@ -19,18 +19,10 @@
</div>
</div>
<div class="col-sm-7">
<p>
密码 [字母 数字 下划线] (6~18位) 注意* 显示 “未更改”
代表不改动本身密码
</p>
<p>密码 [字母 数字 下划线] (6~18位) 注意* 显示 “未更改” 代表不改动本身密码</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 账号密码 </span>
<input
type="text"
class="form-control"
v-model="password"
placeholder="[未更改 您可以直接从这里重设此用户的密码]"
/>
<input type="text" class="form-control" v-model="password" placeholder="[未更改 您可以直接从这里重设此用户的密码]" />
</div>
</div>
</div>
@ -39,12 +31,7 @@
<p>注意,如果是以#开头的最高权限账号,则可以无条件访问任何服务器</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 准许的服务器 </span>
<input
type="text"
class="form-control"
v-model="allowedServer"
placeholder="默认空,列如 ServerNameA ServerNameB ServerNameC"
/>
<input type="text" class="form-control" v-model="allowedServer" placeholder="默认空,列如 ServerNameA ServerNameB ServerNameC" />
</div>
</div>
</div>
@ -54,17 +41,11 @@
<br />
<br />
<p>您可以重新配置这个用户</p>
<p>
警告:修改用户名时请务必减少此类操作,如果当前用户在线的话,很有可能会导致意外的错误,因为用户已经使用原用户名登陆,请确保用户不在线的情况下修改用户名.
</p>
<p>警告:修改用户名时请务必减少此类操作,如果当前用户在线的话,很有可能会导致意外的错误,因为用户已经使用原用户名登陆,请确保用户不在线的情况下修改用户名.</p>
<div class="Line"></div>
<div class="PanelItemMuem">
<button class="btn btn-success" v-on:click="toUpdate()">
更新配置
</button>
<button class="btn btn-danger" v-on:click="toDeleteUser()">
删除此用户
</button>
<button class="btn btn-success" v-on:click="toUpdate()">更新配置</button>
<button class="btn btn-danger" v-on:click="toDeleteUser()">删除此用户</button>
</div>
</div>
</div>
@ -115,9 +96,7 @@
var viewModel = VIEW_MODEL["OneUserView"];
viewModel.oldUsername = viewModel.username + " ";
viewModel.ServerLen = viewModel.allowedServer.length;
viewModel.allowedServer = viewModel.allowedServer
.toString()
.replace(/,/gim, " ");
viewModel.allowedServer = viewModel.allowedServer.toString().replace(/,/gim, " ");
});
MI.rListener("onend", function () {});

View File

@ -3,47 +3,28 @@
<b>设置第三方应用程序接口密匙API KEY</b>
</p>
<p>
<small
>若此用户是管理员用户,那么密匙将可以"管理用户","管理所有服务器","获取高级信息"</small
>
<small>若此用户是管理员用户,那么密匙将可以"管理用户","管理所有服务器","获取高级信息"</small>
</p>
<p>
<small
>若此用户是普通用户,则仅仅能管理其名下的所有服务器与获取部分信息。</small
>
<small>若此用户是普通用户,则仅仅能管理其名下的所有服务器与获取部分信息。</small>
</p>
<div class="input-group">
<span class="input-group-addon">API KEY</span>
<input
type="text"
class="form-control"
v-model="API_KEY"
placeholder="关闭"
/>
<input type="text" class="form-control" v-model="API_KEY" placeholder="关闭" />
</div>
<p style="color: rgb(230, 55, 55)">
此字段至关重要,切勿泄露,复制给其他人。
</p>
<p style="color: rgb(230, 55, 55)">此字段至关重要,切勿泄露,复制给其他人。</p>
<p>
留空则代表关闭此用户 API 功能 |
<a
href="https://github.com/Suwings/MCSManager/wiki/API-Documentation"
target="_blank"
><b>接口开发文档(推荐)</b></a
>
<a href="https://github.com/Suwings/MCSManager/wiki/API-Documentation" target="_blank"><b>接口开发文档(推荐)</b></a>
</p>
<button class="btn btn-success" v-on:click="updateKey()">更新 KEY</button>
<button class="btn btn-success" v-on:click="deleteKey()">
删除/关闭 KEY
</button>
<button class="btn btn-success" v-on:click="deleteKey()">删除/关闭 KEY</button>
&nbsp;|&nbsp;
<button class="btn btn-danger" v-on:click="TOOLS.popWindClose();">
关闭
</button>
<button class="btn btn-danger" v-on:click="TOOLS.popWindClose();">关闭</button>
</div>
<script>
new Vue({

View File

@ -15,61 +15,31 @@
<p><small>启动命令修改是无效的,只是展示等价命令效果。</small></p>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">等价启动命令</span>
<input
type="text"
class="form-control"
disabled="disabled"
aria-describedby="sizing-addon3"
v-model="dockerCommand"
/>
<input type="text" class="form-control" disabled="disabled" aria-describedby="sizing-addon3" v-model="dockerCommand" />
</div>
<p><small>镜像名,在创建虚拟镜像时填写的名称,一般默认即可。</small></p>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">Docker 镜像名</span>
<input
type="text"
class="form-control"
placeholder="可填,默认是名叫 mcsd 镜像。"
aria-describedby="sizing-addon3"
v-model="dockerImageName"
/>
<input type="text" class="form-control" placeholder="可填,默认是名叫 mcsd 镜像。" aria-describedby="sizing-addon3" v-model="dockerImageName" />
</div>
<p>
<small>以 GB 为单位1G 为 1024 MB最小 1GB 内存。不填写无限制。</small>
</p>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">内存限制</span>
<input
type="text"
class="form-control"
placeholder="可填,列如填写 2G 则代表容器最大可使用 2G 内存。"
aria-describedby="sizing-addon3"
v-model="dockerXmx"
/>
<input type="text" class="form-control" placeholder="可填,列如填写 2G 则代表容器最大可使用 2G 内存。" aria-describedby="sizing-addon3" v-model="dockerXmx" />
</div>
<p>
<small
>开放的端口,冒号左边代表容器内部端口,右边代表宿主机端口,通常保持相同即可。</small
>
<small>开放的端口,冒号左边代表容器内部端口,右边代表宿主机端口,通常保持相同即可。</small>
</p>
<p><small>目前最多只准许开放一个</small></p>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">开放端口</span>
<input
type="text"
class="form-control"
placeholder="可填,列如 25565:25565"
aria-describedby="sizing-addon3"
v-model="dockerPorts"
/>
<input type="text" class="form-control" placeholder="可填,列如 25565:25565" aria-describedby="sizing-addon3" v-model="dockerPorts" />
</div>
<p>
确认无误之后,单击保存即可 | &nbsp;
<a
href="https://github.com/Suwings/MCSManager/blob/gh-pages/Question_3.md"
style="color: rgb(32, 32, 192)"
>什么是 Docker ?</a
>
<a href="https://github.com/Suwings/MCSManager/blob/gh-pages/Question_3.md" style="color: rgb(32, 32, 192)">什么是 Docker ?</a>
</p>
<button class="btn btn-success" v-on:click="ok()">保存 Docker 配置</button>
</div>

View File

@ -5,44 +5,20 @@
<p>数据每隔 10 秒刷新缓存。</p>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">服务器名称</span>
<input
type="text"
class="form-control"
placeholder="选填,默认是 Minecraft Server推荐自己取名"
aria-describedby="sizing-addon3"
v-model="mcpingName"
/>
<input type="text" class="form-control" placeholder="选填,默认是 Minecraft Server推荐自己取名" aria-describedby="sizing-addon3" v-model="mcpingName" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">域名或IP地址</span>
<input
type="text"
class="form-control"
placeholder="选填,默认是 localhost不推荐修改"
aria-describedby="sizing-addon3"
v-model="mcpingHost"
/>
<input type="text" class="form-control" placeholder="选填,默认是 localhost不推荐修改" aria-describedby="sizing-addon3" v-model="mcpingHost" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">服务端端口</span>
<input
type="text"
class="form-control"
placeholder="选填,为空则自动,取自 server.properties 文件"
aria-describedby="sizing-addon3"
v-model="mcpingPort"
/>
<input type="text" class="form-control" placeholder="选填,为空则自动,取自 server.properties 文件" aria-describedby="sizing-addon3" v-model="mcpingPort" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">自定义 Motd</span>
<input
type="text"
class="form-control"
placeholder="选填,不填写则获取 motd"
aria-describedby="sizing-addon3"
v-model="mcpingMotd"
/>
<input type="text" class="form-control" placeholder="选填,不填写则获取 motd" aria-describedby="sizing-addon3" v-model="mcpingMotd" />
</div>
<div class="PanelBody">
@ -56,14 +32,10 @@
<span v-on:click="toAPI_PAGE()">贴图系统 Beta</span>
</div> -->
</div>
<p style="color: rgb(230, 55, 55)">
保存或更新配置内容后,需要重启 Minecraft 服务器,才可使用。
</p>
<p style="color: rgb(230, 55, 55)">保存或更新配置内容后,需要重启 Minecraft 服务器,才可使用。</p>
<button class="btn btn-success" v-on:click="ok()">保存配置</button>
&nbsp;|&nbsp;
<button class="btn btn-danger" v-on:click="TOOLS.popWindClose();">
返回
</button>
<button class="btn btn-danger" v-on:click="TOOLS.popWindClose();">返回</button>
</div>
<script>
WS.sendMsg("mcping/config", PAGE.listenServername, function (obj) {

View File

@ -4,36 +4,15 @@
<hr />
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">每隔时间</span>
<input
id="DialogSec"
type="text"
class="form-control"
placeholder="单位分钟,每隔多久执行 | 列如 60 代表一个小时"
aria-describedby="sizing-addon3"
v-model="sec"
/>
<input id="DialogSec" type="text" class="form-control" placeholder="单位分钟,每隔多久执行 | 列如 60 代表一个小时" aria-describedby="sizing-addon3" v-model="sec" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">执行次数</span>
<input
id="DialogCount"
type="text"
class="form-control"
placeholder="0 代表无限,其他正整数代表次数"
v-model="count"
aria-describedby="sizing-addon3"
/>
<input id="DialogCount" type="text" class="form-control" placeholder="0 代表无限,其他正整数代表次数" v-model="count" aria-describedby="sizing-addon3" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3">执行指令</span>
<input
id="DialogCommand"
type="text"
class="form-control"
placeholder="与控制台命令一样,不要加 \ 符号"
v-model="command"
aria-describedby="sizing-addon3"
/>
<input id="DialogCommand" type="text" class="form-control" placeholder="与控制台命令一样,不要加 \ 符号" v-model="command" aria-describedby="sizing-addon3" />
</div>
<p>填写好您需要的计划数据,单击 "生成" 再进行保存即可。</p>
<button class="btn btn-success" v-on:click="ok()">生成</button>
@ -68,15 +47,7 @@
return;
}
}
var reg =
"0 " +
(mf == 0 ? "*/" : "") +
time +
" " +
(mf == 1 ? "*/" + h : mf == 0 ? "*" : h) +
" */" +
d +
" * *";
var reg = "0 " + (mf == 0 ? "*/" : "") + time + " " + (mf == 1 ? "*/" + h : mf == 0 ? "*" : h) + " */" + d + " * *";
reg = reg.replace(/\*\/0/gim, "*");
reg = reg.replace(/\_0/gim, "*");
console.log("生成的时间表达式是:", reg);

View File

@ -1,20 +1,11 @@
<div class="container">
<p>自定义命令可以帮助您执行任何命令!</p>
<ul class="ulInfo">
<li>
必须添加 -Djline.terminal=jline.UnsupportedTerminal 参数在 -jar
之前,否则可能导致命令传递失效。
</li>
<li>必须添加 -Djline.terminal=jline.UnsupportedTerminal 参数在 -jar 之前,否则可能导致命令传递失效。</li>
<li>一旦使用这个自定义参数,将会忽略您上面所设置的所有选项。</li>
<li>您设定的自定义启动参数依然会将服务端根目录作为工作目录来执行命令。</li>
<li>甚至可以运行 bash shell 或 cmd.exe 程序,谨慎设置。</li>
<li>
如开启 Docker 也可配合 Docker 容器使用,列如 /bin/bash 将启动 Docker
容器的 bash 程序。
</li>
<li>
列如填写: java -Djline.terminal=jline.UnsupportedTerminal -jar run.jar
--nogui 就是自定义命令。
</li>
<li>如开启 Docker 也可配合 Docker 容器使用,列如 /bin/bash 将启动 Docker 容器的 bash 程序。</li>
<li>列如填写: java -Djline.terminal=jline.UnsupportedTerminal -jar run.jar --nogui 就是自定义命令。</li>
</ul>
</div>

View File

@ -4,9 +4,7 @@
<div class="Panel PanelBlack">
<div class="PanelTitle">最新动态与信息通知</div>
<div class="PanelBody" style="max-height: 94vh; overflow-y: scroll">
<p>
关注这里如果出现BUG/新版本我们会立即通告 (面板自动每天定时更新)
</p>
<p>关注这里如果出现BUG/新版本我们会立即通告 (面板自动每天定时更新)</p>
<div class="news" v-for="item of items">
<p class="color-gray" v-text="item.time"></p>
<p v-text="item.msg"></p>
@ -34,9 +32,7 @@
<p>支持开发团队,支持开源项目</p>
<p>
爱发电赞助平台:
<a target="_blank" href="https://afdian.net/@mcsmanager"
>https://afdian.net/@mcsmanager</a
>
<a target="_blank" href="https://afdian.net/@mcsmanager">https://afdian.net/@mcsmanager</a>
</p>
<p>
资助支付宝二维码:
@ -44,11 +40,7 @@
</p>
<p>
宣传贴:
<a
target="_blank"
href="http://www.mcbbs.net/thread-140678-1-1.html"
>点击此处</a
>
<a target="_blank" href="http://www.mcbbs.net/thread-140678-1-1.html">点击此处</a>
</p>
<p>软件所有代码与文件均可转载,修改。</p>
</div>
@ -59,17 +51,13 @@
<div class="PanelBody">
<p>项目完全开源:</p>
<p>
<a href="https://github.com/Suwings/MCSManager" target="_blank"
>https://github.com/Suwings/MCSManager
</a>
<a href="https://github.com/Suwings/MCSManager" target="_blank">https://github.com/Suwings/MCSManager </a>
</p>
<p>使用 MIT License</p>
<p>
<small
>A short and simple permissive license with conditions only
requiring preservation of copyright and license notices. Licensed
works, modifications, and larger works may be distributed under
different terms and without source code.</small
>A short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed
under different terms and without source code.</small
>
</p>
<br />

View File

@ -16,10 +16,7 @@
</div>
</div>
<div class="col-sm-3" v-for="item of userServerList">
<div
class="Panel AppInlineBlockList"
v-on:click="toOnlineFs(item.serverName)"
>
<div class="Panel AppInlineBlockList" v-on:click="toOnlineFs(item.serverName)">
<div class="PanelBody">
<div class="PanelItemInfo">
<p class="PagePanelItemInfoTextCenter">{{item.serverName}}</p>
@ -66,9 +63,7 @@
methods: {
toOnlineFs: function (serverName) {
// MCSERVER.listenServername = serverName;
var path = MCSERVER.URL(
"fs_auth/auth/" + encodeURIComponent(serverName)
);
var path = MCSERVER.URL("fs_auth/auth/" + encodeURIComponent(serverName));
window.open(path);
},
toServersDir: function () {

View File

@ -9,10 +9,7 @@
用户名: {{ username }}
</div>
<div class="PanelItem">
<span
class="glyphicon glyphicon-calendar"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>
创建时间: {{ createDate }}
</div>
<div class="PanelItem">
@ -42,23 +39,15 @@
<div class="row">
<div class="col-sm-6">
<div class="PanelItem text-center" v-on:click="toRePassword()">
<span
class="glyphicon glyphicon-lock"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
修改密码
</div>
</div>
<div class="col-sm-6">
<div class="PanelItem text-center">
<span
class="glyphicon glyphicon-book"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-book" aria-hidden="true"></span>
<!-- 您可以在这里附上您的链接,修改 href 属性即可 -->
<a href="javascript:alert('您的提供商未提供使用说明')"
>使用说明</a
>
<a href="javascript:alert('您的提供商未提供使用说明')">使用说明</a>
</div>
</div>
</div>
@ -68,10 +57,7 @@
<div class="PanelTitle">用户 API 密匙</div>
<div class="PanelBody">
<div class="PanelItem text-center" v-on:click="toApiKey()">
<span
class="glyphicon glyphicon-th-large"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-th-large" aria-hidden="true"></span>
我的 API 密匙
</div>
</div>
@ -93,9 +79,7 @@
<p v-text="'文件名:' + item.jarName || '未设置'"></p>
</h4>
状态:
<span v-if="item.run" class="color-green">
正在运行
</span>
<span v-if="item.run" class="color-green"> 正在运行 </span>
<span v-else="item.run" class="color-red"> 关闭 </span>
<!--<br>创建时间 <span v-text="item.createDate"></span>-->
<br />最后启动:
@ -106,12 +90,7 @@
</div>
<div class="col-md-5 NextCol">
<div class="GenhomeButton">
<button
class="btn btn-info"
v-on:click="toConsole(item.serverName)"
>
控制 | 管理
</button>
<button class="btn btn-info" v-on:click="toConsole(item.serverName)">控制 | 管理</button>
</div>
</div>
</div>
@ -136,11 +115,7 @@
methods: {
toConsole: function (serverName) {
MCSERVER.listenServername = serverName;
RES.redirectPage(
"./template/component/console.html",
"server/console",
serverName
);
RES.redirectPage("./template/component/console.html", "server/console", serverName);
},
toRePassword: function () {
RES.redirectPage("./template/component/gen_repassword.html");

View File

@ -14,19 +14,7 @@
</head>
<body>
<div
style="
margin-bottom: 8px;
background-color: #0d6aad;
height: 60px;
line-height: 60px;
font-size: 18px;
color: white;
padding-left: 8px;
"
>
支持开发团队
</div>
<div style="margin-bottom: 8px; background-color: #0d6aad; height: 60px; line-height: 60px; font-size: 18px; color: white; padding-left: 8px">支持开发团队</div>
<div style="overflow: scroll; word-break: break-word; text-align: center">
<img src="../../common/get_alipay.png" />
</div>

View File

@ -7,39 +7,25 @@
<div class="row">
<div class="col-sm-12 PanelItemF">
<div class="PanelItem" v-on:click="newServerx()">
<span
class="glyphicon glyphicon-plus"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
创建新实例应用
</div>
<!-- <div class="PanelItem" v-on:click="newServer()">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> 直接创建新应用(高级)
</div> -->
<div class="PanelItem" v-on:click="opt_all('start')">
<span
class="glyphicon glyphicon-ok-sign"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
启动所有实例应用
</div>
<div class="PanelItem" v-on:click="opt_all('stop')">
<span
class="glyphicon glyphicon-remove-sign"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span>
关闭所有实例应用
</div>
<div class="PanelItem" v-on:click="newDocker()">
<span
class="glyphicon glyphicon-send"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-send" aria-hidden="true"></span>
创建虚拟镜像
</div>
<p style="color: #969292; line-height: 35px; float: right">
若实例数量众多,可以使用 Ctrl+F 来查询
</p>
<p style="color: #969292; line-height: 35px; float: right">若实例数量众多,可以使用 Ctrl+F 来查询</p>
</div>
</div>
</div>
@ -50,26 +36,18 @@
<div class="container-fluid" style="padding: 0px">
<div class="row">
<div class="col-md-6 col-lg-4" v-for="item of items">
<a
href="javascript:void(0);"
class="FontBlack"
v-on:click="toConsole(item.serverName);"
>
<a href="javascript:void(0);" class="FontBlack" v-on:click="toConsole(item.serverName);">
<div class="Panel AppInlineBlockList">
<!-- <div class="PanelTitle"></div> -->
<div class="PanelBody">
<div class="AppInlineBlockListTitle">
<h4 v-if="item.data.jarName == '' && !item.data.highCommande">
<s v-text="item.serverName"></s>
<span class="AppInlineBlockListTitleTip color-high-red"
>未配置</span
>
<span class="AppInlineBlockListTitleTip color-high-red">未配置</span>
</h4>
<h4 v-if="item.data.highCommande">
<span v-text="item.serverName"></span>
<span class="AppInlineBlockListTitleTip"
><span class="FontGray">自定义</span></span
>
<span class="AppInlineBlockListTitleTip"><span class="FontGray">自定义</span></span>
<span class="AppInlineBlockListTitlePlayer">
<span v-text="item.data.currentPlayers"></span>
/
@ -78,9 +56,7 @@
</h4>
<h4 v-if="item.data.jarName != '' && !item.data.highCommande">
<span v-text="item.serverName"></span>
<span class="AppInlineBlockListTitleTip"
><span class="FontGray">普通</span></span
>
<span class="AppInlineBlockListTitleTip"><span class="FontGray">普通</span></span>
<span class="AppInlineBlockListTitlePlayer">
<span v-text="item.data.currentPlayers"></span>
/
@ -92,12 +68,8 @@
<div class="row">
<div class="col-xs-9">
<p>
<span v-if="item.data.run" class="color-green">
状态: 正在运行
</span>
<span v-else="item.data.run" class="color-red">
状态: 关闭
</span>
<span v-if="item.data.run" class="color-green"> 状态: 正在运行 </span>
<span v-else="item.data.run" class="color-red"> 状态: 关闭 </span>
</p>
<hr style="margin-top: 8px; margin-bottom: 10px" />
<p>
@ -119,51 +91,12 @@
</p>
</div>
<div class="col-xs-3" style="text-align: center">
<a
href="javascript:void(0);"
class="mbuttonWhite"
v-on:click="toTerminal(item.serverName);"
>
<span
class="glyphicon glyphicon-console"
aria-hidden="true"
>
</span
>&nbsp; 终端
</a>
<a
href="javascript:void(0);"
class="mbuttonWhite"
v-on:click="toConsole(item.serverName);"
>
<span
class="glyphicon glyphicon-th-large"
aria-hidden="true"
>
</span
>&nbsp; 管理
</a>
<a
href="javascript:void(0);"
class="mbuttonWhite"
v-on:click="onRedirect('./template/component/server.html','server/get',item.serverName);"
>
<span class="glyphicon glyphicon-cog" aria-hidden="true">
</span
>&nbsp; 参数
</a>
<a
href="javascript:void(0);"
class="mbuttonWhite"
v-on:click="toDeleteServer(item.serverName)"
>
<span
class="glyphicon glyphicon-trash"
aria-hidden="true"
>
</span
>&nbsp; 删除
<a href="javascript:void(0);" class="mbuttonWhite" v-on:click="toTerminal(item.serverName);"> <span class="glyphicon glyphicon-console" aria-hidden="true"> </span>&nbsp; 终端 </a>
<a href="javascript:void(0);" class="mbuttonWhite" v-on:click="toConsole(item.serverName);"> <span class="glyphicon glyphicon-th-large" aria-hidden="true"> </span>&nbsp; 管理 </a>
<a href="javascript:void(0);" class="mbuttonWhite" v-on:click="onRedirect('./template/component/server.html','server/get',item.serverName);">
<span class="glyphicon glyphicon-cog" aria-hidden="true"> </span>&nbsp; 参数
</a>
<a href="javascript:void(0);" class="mbuttonWhite" v-on:click="toDeleteServer(item.serverName)"> <span class="glyphicon glyphicon-trash" aria-hidden="true"> </span>&nbsp; 删除 </a>
</div>
</div>
</div>
@ -279,11 +212,7 @@
methods: {
toConsole: function (serverName) {
MCSERVER.listenServername = serverName;
RES.redirectPage(
"./template/component/console.html",
"server/console",
serverName
);
RES.redirectPage("./template/component/console.html", "server/console", serverName);
},
onRedirect: function (link, api, serverName) {
RES.redirectPage(link, api, serverName);
@ -303,11 +232,7 @@
}
},
toDeleteServer: function (serverName) {
var result = confirm(
"是否删除 [" +
serverName +
"] 这个服务端?\n注意: 删除服务器并不会删除服务端文件,只会从控制面板删除!"
);
var result = confirm("是否删除 [" + serverName + "] 这个服务端?\n注意: 删除服务器并不会删除服务端文件,只会从控制面板删除!");
if (!result) return;
WS.sendMsg("server/delete", serverName);
RES.redirectPage("./template/server.html", "server/view");
@ -319,11 +244,7 @@
// RES.redirectPage('./template/component/terminal.html', null, '');
},
newDocker: function () {
RES.redirectPage(
"./template/component/new_docker_image.html",
null,
""
);
RES.redirectPage("./template/component/new_docker_image.html", null, "");
},
},
});

View File

@ -7,24 +7,15 @@
<div class="row">
<div class="col-sm-12 PanelItemF">
<div class="PanelItem" v-on:click="createUser = !createUser">
<span
class="glyphicon glyphicon-plus"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
创建新用户
</div>
<div class="PanelItem" v-on:click="refresh()">
<span
class="glyphicon glyphicon-repeat"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>
从内存刷新
</div>
<div class="PanelItem" v-on:click="reloadUser()">
<span
class="glyphicon glyphicon-repeat"
aria-hidden="true"
></span>
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>
重新从文件刷新用户
</div>
</div>
@ -35,18 +26,12 @@
<div class="col-md-7">
<div class="PanelItemInfo">
<h4>
<span
v-if="TOOLS.isMaster(item.username)"
class="color-high-red"
>[管理账号]
</span>
<span v-if="TOOLS.isMaster(item.username)" class="color-high-red">[管理账号] </span>
<span v-else class="color-green">[普通账号] </span>
<span v-text="item.username"></span>
</h4>
<div>
<span v-if="item.data.online" class="color-green"
>正在线上</span
>
<span v-if="item.data.online" class="color-green">正在线上</span>
<span v-if="!item.data.online" class="color-red">离线</span>
| 创建时间:
<span v-text="item.data.createDate"> </span>
@ -59,25 +44,10 @@
<div class="PanelItemMuem">
<!-- <button class="btn btn-primary" v-on:click="">权限配置</button> -->
<button
class="btn btn-success"
v-on:click="toUserView(item.username)"
>
详细信息
</button>
<button class="btn btn-success" v-on:click="toUserView(item.username)">详细信息</button>
<span style="margin-left: 8px"> | </span>
<button
class="btn btn-primary"
v-on:click="toAPIKey(item.username)"
>
API Key
</button>
<button
class="btn btn-danger"
v-on:click="toDeleteUser(item.username)"
>
删除用户
</button>
<button class="btn btn-primary" v-on:click="toAPIKey(item.username)">API Key</button>
<button class="btn btn-danger" v-on:click="toDeleteUser(item.username)">删除用户</button>
</div>
</div>
</div>
@ -92,9 +62,7 @@
<div class="PanelTitle">用户机制须知</div>
<div class="PanelBody">
<p class="color-high-red">以#符合开头的均是最高权限账号,请慎重创建</p>
<p>
我们尽可能的保证管理员与普通用户的数据安全性,但管理员是可以一定程度管理普通用户。
</p>
<p>我们尽可能的保证管理员与普通用户的数据安全性,但管理员是可以一定程度管理普通用户。</p>
<p>普通用户只可以在规定的服务器内操作。</p>
<p>普通用户无法创建,删除服务器和编辑服务器启动时参数配置。</p>
<p>普通用户无法查看具体内存值与CPU具体信息保证主机的信息。</p>
@ -111,51 +79,29 @@
<p>用户名 [字母 数字 下划线] (6~18位)</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 用户名 </span>
<input
type="text"
class="form-control"
v-model="username"
placeholder="用户名 [字母 数字 下划线] (6~18位)"
/>
<input type="text" class="form-control" v-model="username" placeholder="用户名 [字母 数字 下划线] (6~18位)" />
</div>
</div>
<div class="col-sm-6">
<p>密码 [字母 数字 符号] (6~18位)</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 密码 </span>
<input
type="text"
class="form-control"
v-model="password"
placeholder="密码 [字母 数字 符号] (6~18位)"
/>
<input type="text" class="form-control" v-model="password" placeholder="密码 [字母 数字 符号] (6~18位)" />
</div>
</div>
</div>
<p>准许的服务器,输入服务器名字,分别以空格分割</p>
<div class="input-group input-group-sm">
<span class="input-group-addon"> 准许的服务器 </span>
<input
type="text"
class="form-control"
v-model="allowedServer"
placeholder="列如: 服务器名字A 服务器名字B 服务器名字C"
/>
<input type="text" class="form-control" v-model="allowedServer" placeholder="列如: 服务器名字A 服务器名字B 服务器名字C" />
</div>
<div class="row">
<div class="col-lg-12">
<p>当您的数据完善时,即可确认创建新的用户</p>
<div class="Line"></div>
<div class="" style="float: right; margin-top: 20px">
<button class="btn btn-primary" v-on:click="toRegisterUser()">
创建新用户
</button>
<button
class="btn btn-warning"
v-on:click="createUser =!createUser"
>
取消
</button>
<button class="btn btn-primary" v-on:click="toRegisterUser()">创建新用户</button>
<button class="btn btn-warning" v-on:click="createUser =!createUser">取消</button>
</div>
</div>
</div>
@ -222,11 +168,7 @@
},
toUserView: function (_username) {
RES.redirectPage(
"./template/component/user.html",
"userset/view",
_username
);
RES.redirectPage("./template/component/user.html", "userset/view", _username);
},
toAPIKey: function (username) {
// 弹出用户密匙设置窗口

View File

@ -135,10 +135,7 @@ router.post("/create_user", function (req, res) {
try {
// 账号密码判定
const uPattern = /^[a-zA-Z0-9_#\$]{4,18}$/;
if (
!uPattern.test(req.body.username) ||
!tools.between(req.body.password, 6, 18)
) {
if (!uPattern.test(req.body.username) || !tools.between(req.body.password, 6, 18)) {
apiResponse.error(res, new Error("用户名或密码格式不正确"));
return;
}
@ -152,10 +149,7 @@ router.post("/create_user", function (req, res) {
allowedServerList.push(serverList[k]);
}
}
userModel
.userCenter()
.get(req.body.username)
.allowedServer(allowedServerList);
userModel.userCenter().get(req.body.username).allowedServer(allowedServerList);
// 数据模型保存
userModel.userCenter().get(req.body.username).dataModel.save();
// 返回状态码
@ -216,9 +210,7 @@ router.all("/restart_server/:name", function (req, res) {
return;
}
// 流量限制 | 60 秒执行一次
if (
!requestLimit.execute(apiResponse.key(req) + "restart_server", 1000 * 60)
) {
if (!requestLimit.execute(apiResponse.key(req) + "restart_server", 1000 * 60)) {
apiResponse.unavailable(res);
return;
}
@ -282,9 +274,7 @@ router.post("/execute/", function (req, res) {
return;
}
// 启动服务器
const result = serverModel
.ServerManager()
.sendMinecraftServer(params.name, params.command);
const result = serverModel.ServerManager().sendMinecraftServer(params.name, params.command);
// 返回状态码
result ? apiResponse.ok(res) : apiResponse.error(res);
} catch (err) {

View File

@ -45,12 +45,7 @@ router.post("/", (req, res) => {
});
res.send("Done");
MCSERVER.log(
"[ 文件上传 ] 用户",
req.session["username"],
"上传文件到",
target_path
);
MCSERVER.log("[ 文件上传 ] 用户", req.session["username"], "上传文件到", target_path);
} catch (err) {
res.status(500).send("上传出错" + err);
}

View File

@ -17,12 +17,7 @@ router.get("/", function (req, res) {
//ajax 会受到浏览器跨域限制姑不能对其进行csrf攻击获取token尽管它可伪造。
if (req.xhr) {
if (!username || !loginedContainer.isLogined(req.sessionID)) {
MCSERVER.log(
"[ Token ]",
"未登录用户 ",
username,
" 请求更新令牌 | 已经阻止"
);
MCSERVER.log("[ Token ]", "未登录用户 ", username, " 请求更新令牌 | 已经阻止");
//用户未登录,返回一个随机的 token 给它,并且这个 token 与正常的 token 几乎一模一样
response.returnMsg(res, "token", {
token: getRandToken(),
@ -48,10 +43,7 @@ router.get("/", function (req, res) {
});
} else {
counter.plus("csrfCounter");
res.send(
"<h1>CSRF 防御策略</h1><hr><p>您不能直接访问本页面,这是为了防御 CSRF 攻击,务必直接访问首页!</p>" +
"<p>具体信息我们将统计到非法 API 请求,这可能需要值得您注意.</p>"
);
res.send("<h1>CSRF 防御策略</h1><hr><p>您不能直接访问本页面,这是为了防御 CSRF 攻击,务必直接访问首页!</p>" + "<p>具体信息我们将统计到非法 API 请求,这可能需要值得您注意.</p>");
}
res.end();
});

View File

@ -14,8 +14,7 @@ const userManager = userCenter();
router.post("/loginout", function (req, res) {
if (!req.xhr) return;
//删除一些辅助管理器的值
if (req.session["username"] && req.session["login"])
loginedContainer.delLogined(req.sessionID);
if (req.session["username"] && req.session["login"]) loginedContainer.delLogined(req.sessionID);
TokenManager.delToken(req.session["token"]);
MCSERVER.log("[ loginout ] 用户:", req.session["username"], "退出,会话注销");
@ -65,21 +64,13 @@ router.post("/login", function (req, res) {
let enkey = req.session["login_md5key"] || "";
//登陆规则
if (!LoginRule(ip)) {
response.returnMsg(
res,
"login/check",
"密码错误次数过多!您已被锁定!请10分钟之后再进行登录!"
);
response.returnMsg(res, "login/check", "密码错误次数过多!您已被锁定!请10分钟之后再进行登录!");
return;
}
//判断是否有 ws 正在连接
if (OnlyLoginCheck(req.sessionID)) {
response.returnMsg(
res,
"login/check",
"您已在此浏览器登录过账号,请关闭所有与服务器的链接网页并退出账号!"
);
response.returnMsg(res, "login/check", "您已在此浏览器登录过账号,请关闭所有与服务器的链接网页并退出账号!");
return;
}
@ -113,9 +104,7 @@ router.post("/login", function (req, res) {
//密码错误记录
MCSERVER.login[ip] ? MCSERVER.login[ip]++ : (MCSERVER.login[ip] = 1);
//防止数目过于太大 溢出
MCSERVER.login[ip] > 1000
? (MCSERVER.login[ip] = 1000)
: (MCSERVER.login[ip] = MCSERVER.login[ip]);
MCSERVER.login[ip] > 1000 ? (MCSERVER.login[ip] = 1000) : (MCSERVER.login[ip] = MCSERVER.login[ip]);
//passwordError
counter.plus("passwordError");
req.session["login"] = false;

View File

@ -78,10 +78,7 @@ router.ws("/ws", function (ws, req) {
//用户名检查
if (!username || typeof username != "string" || username.trim() == "") {
MCSERVER.warning(
"错误令牌的 WS 尝试建立链接 | 已经阻止",
["用户值:", username, " 令牌值:", token].join(" ")
);
MCSERVER.warning("错误令牌的 WS 尝试建立链接 | 已经阻止", ["用户值:", username, " 令牌值:", token].join(" "));
counter.plus("notPermssionCounter");
ws.close();
return;
@ -89,10 +86,7 @@ router.ws("/ws", function (ws, req) {
//唯一性检查
if (isWsOnline(token)) {
MCSERVER.warning(
"此令牌正在使用 | 阻止重复使用 | isWsOnline",
["用户值:", username, " 令牌值:", token].join(" ")
);
MCSERVER.warning("此令牌正在使用 | 阻止重复使用 | isWsOnline", ["用户值:", username, " 令牌值:", token].join(" "));
ws.close();
return;
}
@ -101,10 +95,7 @@ router.ws("/ws", function (ws, req) {
//登录逻辑性缺陷检查
if (!loginedContainer.isLogined(session_id, username)) {
MCSERVER.warning(
"未经过登陆逻辑的用户尝试连接 | 已经阻止",
["用户值:", username, " 令牌值:", token].join(" ")
);
MCSERVER.warning("未经过登陆逻辑的用户尝试连接 | 已经阻止", ["用户值:", username, " 令牌值:", token].join(" "));
counter.plus("notPermssionCounter");
ws.close();
return;
@ -124,10 +115,7 @@ router.ws("/ws", function (ws, req) {
//Session 级别验证登录检查
if (!WsSession.login) {
MCSERVER.warning(
"不明身份者建立 ws 链接",
"已经阻止 | 可能的用户值: " + WsSession.username
);
MCSERVER.warning("不明身份者建立 ws 链接", "已经阻止 | 可能的用户值: " + WsSession.username);
counter.plus("notPermssionCounter");
ws.close();
return;
@ -138,8 +126,7 @@ router.ws("/ws", function (ws, req) {
//放置全局在线列表
MCSERVER.allSockets[uid] = WsSession;
if (!MCSERVER.onlineUser[WsSession.username])
MCSERVER.onlineUser[WsSession.username] = WsSession;
if (!MCSERVER.onlineUser[WsSession.username]) MCSERVER.onlineUser[WsSession.username] = WsSession;
//检查通过..
MCSERVER.log("[ WebSocket INIT ]", " 用户:", username, "与服务器建立链接");
@ -150,10 +137,7 @@ router.ws("/ws", function (ws, req) {
//是否合法用户检查
if (!WsSession.login) {
//触发这里代表极为有可能有人正在攻击你
MCSERVER.warning(
"没有登录的用户正在尝试发送 Ws 命令",
"已经阻止 | 可能的用户值: " + username
);
MCSERVER.warning("没有登录的用户正在尝试发送 Ws 命令", "已经阻止 | 可能的用户值: " + username);
counter.plus("notPermssionCounter");
ws.close();
return;
@ -210,12 +194,7 @@ router.ws("/ws", function (ws, req) {
var HBMask = setInterval(() => {
// 超过指定次数不响应,代表链接丢失
if (wsAliveHBCount <= 0) {
MCSERVER.log(
"[ WebSocket HBPackage ]",
"用户",
username,
"长时间未响应心跳包 | 已自动断开"
);
MCSERVER.log("[ WebSocket HBPackage ]", "用户", username, "长时间未响应心跳包 | 已自动断开");
WebSocketClose();
}
wsAliveHBCount--;
@ -245,13 +224,9 @@ router.ws("/ws", function (ws, req) {
});
//加载 ws 子路由
require("../core/tools").autoLoadModule(
"route/websocket/",
"websocket/",
(path) => {
require(path);
}
);
require("../core/tools").autoLoadModule("route/websocket/", "websocket/", (path) => {
require(path);
});
//模块导出
module.exports = router;

View File

@ -6,9 +6,7 @@ const response = require("../../helper/Response");
// 获取指定用户的 API KEY
WebSocketObserver().listener("apikey/get", (data) => {
const username = permssion.isMaster(data.WsSession)
? data.body
: data.WsSession.username;
const username = permssion.isMaster(data.WsSession) ? data.body : data.WsSession.username;
const user = userCenter().get(username);
if (!user) return;
@ -18,9 +16,7 @@ WebSocketObserver().listener("apikey/get", (data) => {
// 更新用户的 API KEY
// 其中API KEY 不可自定义,有且只能根据后端算法生成
WebSocketObserver().listener("apikey/update", (data) => {
const username = permssion.isMaster(data.WsSession)
? data.body
: data.WsSession.username;
const username = permssion.isMaster(data.WsSession) ? data.body : data.WsSession.username;
const user = userCenter().get(username);
if (!user) return;
@ -34,9 +30,7 @@ WebSocketObserver().listener("apikey/update", (data) => {
// 删除 API KEY
WebSocketObserver().listener("apikey/delete", (data) => {
const username = permssion.isMaster(data.WsSession)
? data.body
: data.WsSession.username;
const username = permssion.isMaster(data.WsSession) ? data.body : data.WsSession.username;
const user = userCenter().get(username);
if (!user) return;

View File

@ -94,11 +94,7 @@ setInterval(function () {
let useMemBai = ((os.freemem() / os.totalmem()) * 100).toFixed(0);
//压入记录器
MCSERVER.logCenter.pushLogData(
"CPU",
tools.getMineTime(),
parseInt(cacheCPU)
);
MCSERVER.logCenter.pushLogData("CPU", tools.getMineTime(), parseInt(cacheCPU));
MCSERVER.logCenter.pushLogData("RAM", tools.getMineTime(), 100 - useMemBai);
setTimeout(() => counter.save(), 0); //让其异步地去保存

View File

@ -36,20 +36,13 @@ serverModel.ServerManager().on("exit", (data) => {
setTimeout(() => {
serverModel.startServer(data.serverName);
}, 5000);
selectWebsocket(data.serverName, (socket) =>
response.wsMsgWindow(
socket.ws,
"检测到服务器关闭,稍后将根据任务自动重启!"
)
);
selectWebsocket(data.serverName, (socket) => response.wsMsgWindow(socket.ws, "检测到服务器关闭,稍后将根据任务自动重启!"));
return;
}
//输出到标准输出
server.printlnCommandLine("服务端 " + data.serverName + " 关闭.");
// 告知前端已关闭
selectWebsocket(data.serverName, (socket) =>
response.wsMsgWindow(socket.ws, "服务器关闭")
);
selectWebsocket(data.serverName, (socket) => response.wsMsgWindow(socket.ws, "服务器关闭"));
// 传递服务器关闭事件
serverModel.ServerManager().emit("exit_next", data);
// 历史记录类释放
@ -82,16 +75,13 @@ WebSocketObserver().listener("server/console/ws", (data) => {
let serverName = data.body.trim();
if (permssion.isCanServer(userName, serverName)) {
MCSERVER.log(
"[" + serverName + "] >>> 准许用户 " + userName + " 控制台监听"
);
MCSERVER.log("[" + serverName + "] >>> 准许用户 " + userName + " 控制台监听");
// 设置监听终端
data.WsSession["console"] = serverName;
// 重置用户历史指针
const instanceLogHistory = serverModel.ServerManager().getServer(serverName)
.logHistory;
const instanceLogHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (instanceLogHistory) instanceLogHistory.setPoint(userName, 0);
return;
}

View File

@ -15,10 +15,7 @@ WebSocketObserver().listener("server/console", (data) => {
if (permssion.isCanServer(userName, serverName)) {
let serverData = serverModel.ServerManager().getServer(serverName);
let sysMonery = (
(os.freemem() / 1024 / (os.totalmem() / 1024)) *
100
).toFixed(2);
let sysMonery = ((os.freemem() / 1024 / (os.totalmem() / 1024)) * 100).toFixed(2);
let cpu = MCSERVER.dataCenter.cacheCPU;
response.wsSend(data.ws, "server/console", {
serverData: serverData.dataModel,

View File

@ -12,34 +12,18 @@ WebSocketObserver().listener("server/console/history", (data) => {
let serverName = bodyJson["serverName"] || "";
if (permssion.isCanServer(userName, serverName)) {
const logHistory = serverModel.ServerManager().getServer(serverName)
.logHistory;
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (!logHistory) {
response.wsSend(
data.ws,
"server/console/history",
"terminalBack",
"[控制面板]: 暂无任何历史记录.\r\n"
);
response.wsSend(data.ws, "server/console/history", "terminalBack", "[控制面板]: 暂无任何历史记录.\r\n");
return;
}
logHistory.readLine(userName, HISTORY_SIZE_LINE, (sendText) => {
if (sendText) {
sendText = sendText.replace(/\n/gim, "\r\n");
sendText = sendText.replace(/\r\r\n/gim, "\r\n");
response.wsSend(
data.ws,
"server/console/history",
"terminalBack",
sendText
);
response.wsSend(data.ws, "server/console/history", "terminalBack", sendText);
} else {
response.wsSend(
data.ws,
"server/console/history",
"terminalBack",
"[控制面板]: 无法再读取更多的服务端日志.\r\n"
);
response.wsSend(data.ws, "server/console/history", "terminalBack", "[控制面板]: 无法再读取更多的服务端日志.\r\n");
}
});
}
@ -52,19 +36,13 @@ WebSocketObserver().listener("server/console/history_reverse", (data) => {
let serverName = bodyJson["serverName"] || "";
if (permssion.isCanServer(userName, serverName)) {
const logHistory = serverModel.ServerManager().getServer(serverName)
.logHistory;
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (!logHistory) return;
logHistory.readLineOnce(userName, HISTORY_SIZE_LINE * 3, (sendText) => {
if (sendText) {
sendText = sendText.replace(/\n/gim, "\r\n");
sendText = sendText.replace(/\r\r\n/gim, "\r\n");
response.wsSend(
data.ws,
"server/console/history",
"terminalBack",
sendText
);
response.wsSend(data.ws, "server/console/history", "terminalBack", sendText);
}
});
}
@ -77,8 +55,7 @@ WebSocketObserver().listener("server/console/history_reset", (data) => {
let serverName = bodyJson["serverName"] || "";
if (permssion.isCanServer(userName, serverName)) {
const logHistory = serverModel.ServerManager().getServer(serverName)
.logHistory;
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (!logHistory) return;
logHistory.setPoint(userName, 0);
}

View File

@ -37,11 +37,7 @@ serverModel.ServerManager().on("open_next", (data) => {
if (server) {
// 若已设定值,则使用已设定值
if (server.dataModel.mcpingConfig.mcpingPort) {
mcPingProtocol.CreateMCPingTask(
data.serverName,
host,
parseInt(server.dataModel.mcpingConfig.mcpingPort)
);
mcPingProtocol.CreateMCPingTask(data.serverName, host, parseInt(server.dataModel.mcpingConfig.mcpingPort));
return;
}
// 首先从配置文件读取,若成功读取则使用配置文件,否则使用原值
@ -51,11 +47,7 @@ serverModel.ServerManager().on("open_next", (data) => {
mcPingProtocol.CreateMCPingTask(data.serverName, host, 25565);
} else {
// 配置文件存在,读取配置
mcPingProtocol.CreateMCPingTask(
data.serverName,
host,
parseInt(obj["server-port"])
);
mcPingProtocol.CreateMCPingTask(data.serverName, host, parseInt(obj["server-port"]));
}
});
}

View File

@ -13,10 +13,7 @@ WebSocketObserver().listener("server/properties", (data) => {
.getServer(serverName)
.propertiesLoad((properties, err) => {
if (err) {
response.wsMsgWindow(
data.ws,
"properties 文件不存在或读取出错!请自行检查或确认是否存在以及格式正确."
);
response.wsMsgWindow(data.ws, "properties 文件不存在或读取出错!请自行检查或确认是否存在以及格式正确.");
return;
}
response.wsSend(data.ws, "server/properties", {
@ -57,13 +54,9 @@ WebSocketObserver().listener("server/properties_update_reload", (data) => {
.getServer(serverName)
.propertiesLoad(() => {
//再读一次
let properties = serverModel.ServerManager().getServer(serverName)
.properties;
let properties = serverModel.ServerManager().getServer(serverName).properties;
if (properties == undefined) {
response.wsMsgWindow(
data.ws,
"properties 文件不存在或读取出错,请先开启服务器以生成文件."
);
response.wsMsgWindow(data.ws, "properties 文件不存在或读取出错,请先开启服务器以生成文件.");
return;
}
//将数据在来一次,前端路由会动态处理

View File

@ -15,10 +15,7 @@ WebSocketObserver().listener("server/console/autorestart", (data) => {
server.save();
response.wsMsgWindow(data.ws, "更改设置成功!");
} catch (err) {
response.wsMsgWindow(
data.ws,
"更改设置失败!不正常,请刷新网页重新设置!"
);
response.wsMsgWindow(data.ws, "更改设置失败!不正常,请刷新网页重新设置!");
}
return;
}

View File

@ -43,27 +43,17 @@ WebSocketObserver().listener("docker/new", (data) => {
if (!fs.existsSync("./docker_temp")) fs.mkdirSync("./docker_temp");
fs.writeFileSync("./docker_temp/dockerfile", dockerfileData);
let process = childProcess.spawn(
"docker",
["build", "-t", dockerImageName.trim(), "./docker_temp/"],
{
cwd: ".",
stdio: "pipe",
}
);
let process = childProcess.spawn("docker", ["build", "-t", dockerImageName.trim(), "./docker_temp/"], {
cwd: ".",
stdio: "pipe",
});
process.on("exit", (code) => {
console.log("EXIT", code);
if (code == 0) {
response.wsMsgWindow(
data.ws,
["镜像", dockerImageName, "创建完毕."].join(" ")
);
response.wsMsgWindow(data.ws, ["镜像", dockerImageName, "创建完毕."].join(" "));
pushRes("成功");
} else {
response.wsMsgWindow(
data.ws,
["镜像", dockerImageName, "构建失败,原因未知."].join(" ")
);
response.wsMsgWindow(data.ws, ["镜像", dockerImageName, "构建失败,原因未知."].join(" "));
pushRes("失败");
}
});

View File

@ -11,11 +11,7 @@ WebSocketObserver().listener("genuser/home", (data) => {
let user = userCenter().get(username);
//有一定可能是 管理员修改了用户名
if (!user) {
for (let i = 0; i < 5; i++)
response.wsMsgWindow(
data.ws,
"您的用户资料似乎已经被修改且失效,请咨询管理员"
);
for (let i = 0; i < 5; i++) response.wsMsgWindow(data.ws, "您的用户资料似乎已经被修改且失效,请咨询管理员");
data.ws.close();
return;
}
@ -32,9 +28,7 @@ WebSocketObserver().listener("genuser/home", (data) => {
let userServerList = [];
let OnlineServerList = [];
for (let k in allowedServerList) {
let userHaveServer = serverModel
.ServerManager()
.getServer(allowedServerList[k]);
let userHaveServer = serverModel.ServerManager().getServer(allowedServerList[k]);
//有些用户就是喜欢取不存在的
if (userHaveServer == undefined) continue;
//有些数据不应该是用户可以收到的
@ -78,10 +72,7 @@ WebSocketObserver().listener("genuser/re_password", (data) => {
() => {
try {
if (config.newPassword.length > 18 || config.newPassword.length < 6) {
response.wsMsgWindow(
data.ws,
"新的密码长度不正确,需要 6~18 位长度"
);
response.wsMsgWindow(data.ws, "新的密码长度不正确,需要 6~18 位长度");
return;
}
userCenter().rePassword(username, config.newPassword);

View File

@ -15,13 +15,7 @@ function CreateScheduleJob(obj) {
let id = tools.randomString(6) + "_" + new Date().getTime();
let thisServer = serverModel.ServerManager().getServer(obj.servername);
schedulejob.createScheduleJobCount(
id,
obj.time,
obj.count,
obj.commande,
obj.servername
);
schedulejob.createScheduleJobCount(id, obj.time, obj.count, obj.commande, obj.servername);
}
//过滤计划任务列表

View File

@ -19,10 +19,7 @@ WebSocketObserver().listener("server/get", (data) => {
let serverName = data.body.trim();
let mcserver = serverModel.ServerManager().getServer(serverName);
if (mcserver == null) {
response.wsMsgWindow(
data.ws,
"服务端 " + serverName + " 不存在!请刷新或自行检查。"
);
response.wsMsgWindow(data.ws, "服务端 " + serverName + " 不存在!请刷新或自行检查。");
return;
}
@ -126,10 +123,7 @@ WebSocketObserver().listener("server/opt_all", (data) => {
continue;
}
}
response.wsMsgWindow(
data.ws,
"操作执行发出!需要一定时间,具体结果请看服务端运行状态."
);
response.wsMsgWindow(data.ws, "操作执行发出!需要一定时间,具体结果请看服务端运行状态.");
} catch (err) {
response.wsMsgWindow(data.ws, "执行失败:" + err);
}

View File

@ -44,10 +44,7 @@ WebSocketObserver().listener("userset/create", (data) => {
//去除掉空白的
let allowedServerList = [];
for (let k in newUserConfig.allowedServer) {
if (
newUserConfig.allowedServer[k] != " " &&
newUserConfig.allowedServer[k].length > 0
) {
if (newUserConfig.allowedServer[k] != " " && newUserConfig.allowedServer[k].length > 0) {
allowedServerList.push(newUserConfig.allowedServer[k]);
}
}
@ -132,10 +129,7 @@ WebSocketObserver().listener("userset/upinfo", (data) => {
//去除掉空白的
let allowedServerList = [];
for (let k in newUserConfig.allowedServer) {
if (
newUserConfig.allowedServer[k] != " " &&
newUserConfig.allowedServer[k].length > 0
) {
if (newUserConfig.allowedServer[k] != " " && newUserConfig.allowedServer[k].length > 0) {
allowedServerList.push(newUserConfig.allowedServer[k]);
}
}
@ -159,10 +153,7 @@ WebSocketObserver().listener("userset/upinfo", (data) => {
if (username != newUS) {
let uPattern = /^[a-zA-Z0-9_#\$]{4,18}$/;
if (!uPattern.test(newUS)) {
response.wsMsgWindow(
data.ws,
"新的用户名格式不正确,已舍弃用户名的更改"
);
response.wsMsgWindow(data.ws, "新的用户名格式不正确,已舍弃用户名的更改");
return;
}
userCenter().reUsername(username, newUS);