199 lines
5.8 KiB
JavaScript
199 lines
5.8 KiB
JavaScript
const express = require('express');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const bodyParser = require('body-parser');
|
|
const cors = require('cors');
|
|
const chalk = require('chalk'); // 用于控制台颜色
|
|
|
|
// 创建 Express 应用
|
|
const app = express();
|
|
const PORT = 3000;
|
|
|
|
// 配置中间件
|
|
app.use(cors()); // 允许跨域资源共享
|
|
app.use(bodyParser.json()); // 解析 JSON 请求体
|
|
|
|
// 服务器存储目录,模拟远程存储位置
|
|
const SERVER_STORAGE_PATH = path.join(__dirname, 'game_saves');
|
|
|
|
// 确保存储目录存在
|
|
if (!fs.existsSync(SERVER_STORAGE_PATH)) {
|
|
fs.mkdirSync(SERVER_STORAGE_PATH);
|
|
}
|
|
|
|
// 日志记录函数
|
|
function logServer(message) {
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
console.log(chalk.gray(`[${timestamp}] `) + chalk.cyan('[服务器] ') + message);
|
|
}
|
|
|
|
function logPlayer(player, message) {
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
console.log(chalk.gray(`[${timestamp}] `) + chalk.yellow(`[${player}] `) + message);
|
|
}
|
|
|
|
function logWarning(message) {
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
console.log(chalk.gray(`[${timestamp}] `) + chalk.yellow('[警告] ') + message);
|
|
}
|
|
|
|
function logError(message) {
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
console.log(chalk.gray(`[${timestamp}] `) + chalk.red('[错误] ') + message);
|
|
}
|
|
|
|
/**
|
|
* 登录路由
|
|
* @route POST /login
|
|
* @param {string} req.body.user_name - 用户名
|
|
* @param {string} req.body.user_password - 用户密码
|
|
* @returns {Object} 登录结果
|
|
*/
|
|
app.post('/login', (req, res) => {
|
|
try {
|
|
const { user_name, user_password } = req.body;
|
|
|
|
if (!user_name || !user_password) {
|
|
logWarning(`登录尝试失败: 用户名或密码为空`);
|
|
return res.json({
|
|
message: '用户名和密码不能为空'
|
|
});
|
|
}
|
|
|
|
const filePath = path.join(SERVER_STORAGE_PATH, `${user_name}.json`);
|
|
|
|
if (!fs.existsSync(filePath)) {
|
|
logWarning(`登录失败: 用户 ${user_name} 不存在`);
|
|
return res.json({
|
|
message: '用户不存在'
|
|
});
|
|
}
|
|
|
|
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
const userData = JSON.parse(fileContent);
|
|
|
|
if (userData.user_password !== user_password) {
|
|
logWarning(`用户 ${user_name} 登录失败: 密码错误`);
|
|
return res.json({
|
|
message: '密码错误'
|
|
});
|
|
}
|
|
|
|
logPlayer(user_name, '成功登录游戏');
|
|
res.json({
|
|
message: '登录成功',
|
|
data: userData
|
|
});
|
|
} catch (error) {
|
|
logError(`登录过程发生错误: ${error.message}`);
|
|
res.json({
|
|
message: '服务器错误',
|
|
error: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
/**
|
|
* 注册路由
|
|
* @route POST /register
|
|
* @param {string} req.body.user_name - 用户名
|
|
* @param {string} req.body.user_password - 用户密码
|
|
* @param {string} req.body.farm_name - 农场名称
|
|
* @returns {Object} 注册结果
|
|
*/
|
|
app.post('/register', (req, res) => {
|
|
try {
|
|
const { user_name, user_password, farm_name } = req.body;
|
|
|
|
if (!user_name || !user_password || !farm_name) {
|
|
logWarning(`注册失败: 注册信息不完整`);
|
|
return res.json({
|
|
message: '注册信息不完整'
|
|
});
|
|
}
|
|
|
|
const filePath = path.join(SERVER_STORAGE_PATH, `${user_name}.json`);
|
|
|
|
if (fs.existsSync(filePath)) {
|
|
logWarning(`注册失败: 用户名 ${user_name} 已存在`);
|
|
return res.json({
|
|
message: '用户名已存在'
|
|
});
|
|
}
|
|
|
|
fs.writeFileSync(filePath, JSON.stringify(req.body, null, 2), 'utf8');
|
|
logPlayer(user_name, `注册成功,农场名称: ${farm_name}`);
|
|
|
|
res.json({
|
|
message: '注册成功'
|
|
});
|
|
} catch (error) {
|
|
logError(`注册过程发生错误: ${error.message}`);
|
|
res.json({
|
|
message: '服务器错误',
|
|
error: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
/**
|
|
* 保存游戏数据
|
|
* @route POST /save
|
|
* @param {string} req.body.user_name - 用户名
|
|
* @param {Object} req.body - 游戏保存数据
|
|
* @returns {Object} 保存结果
|
|
*/
|
|
app.post('/save', (req, res) => {
|
|
try {
|
|
const { user_name, money, level, experience } = req.body;
|
|
|
|
if (!user_name) {
|
|
logWarning(`保存失败: 用户名为空`);
|
|
return res.json({
|
|
message: '用户名不能为空'
|
|
});
|
|
}
|
|
|
|
const filePath = path.join(SERVER_STORAGE_PATH, `${user_name}.json`);
|
|
fs.writeFileSync(filePath, JSON.stringify(req.body, null, 2), 'utf8');
|
|
|
|
logPlayer(user_name, `保存游戏数据 [金钱: ${money}, 等级: ${level}, 经验: ${experience}]`);
|
|
res.json({
|
|
message: '保存成功'
|
|
});
|
|
} catch (error) {
|
|
logError(`保存游戏数据时发生错误: ${error.message}`);
|
|
res.json({
|
|
message: '服务器错误',
|
|
error: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
/**
|
|
* 服务器健康检查路由
|
|
* @route GET /health
|
|
* @returns {Object} 服务器状态
|
|
*/
|
|
app.get('/health', (req, res) => {
|
|
logServer('收到健康检查请求');
|
|
res.json({
|
|
status: 'healthy',
|
|
message: 'Godot农场游戏服务器正在运行'
|
|
});
|
|
});
|
|
|
|
// 启动服务器
|
|
app.listen(PORT, () => {
|
|
logServer(chalk.green('农场游戏服务器启动成功'));
|
|
logServer(`监听端口: ${PORT}`);
|
|
logServer(`存储路径: ${SERVER_STORAGE_PATH}`);
|
|
logServer('等待玩家连接...');
|
|
});
|
|
|
|
// 优雅关闭服务器
|
|
process.on('SIGINT', () => {
|
|
logServer(chalk.yellow('正在关闭服务器...'));
|
|
// 这里可以添加一些清理工作
|
|
process.exit();
|
|
}); |