Files
Sprout-Farm/server/server.js
2025-04-13 14:40:41 +08:00

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();
});