Files
CardServer/Server.js

154 lines
5.5 KiB
JavaScript
Raw Normal View History

2025-10-11 14:45:08 +08:00
const http = require('http');
const logger = require('./logger')
const { Server } = require('socket.io');
const { getConnection, isRoomAvailable } = require('./db');
const { isStealthId } = require('./CreateRoom')
const {RoomManager} = require('./RoomManager');
const server = http.createServer();
const io = new Server(server, {
cors: {
origin: "*"
}
});
const RoomConnectionCount = new Map();
io.use((socket, next) => {
const ip = socket.handshake.address;
const roomId = socket.handshake.query.roomId;
if(roomId == undefined)
{
logger.info("room id is empty", ip);
return next(new Error("room id is empty:"));
}
if(!isStealthId(roomId) /*|| !RoomManager.getInstance().isRoomExist(roomId)*/)
{
logger.info("illegal roomId", ip, roomId);
return next(new Error("illegal room id"));
}
// 限制:最大并发数
const count = RoomConnectionCount.get(roomId) || 0;
if (count >= 9) {
logger.info("Room max connection", ip);
return next(new Error("Too many connections from this room"));
}
// 记录连接
RoomConnectionCount.set(roomId, count + 1);
logger.info('Client connected', ip, roomId, count + 1);
next();
});
io.on('connection', (socket) => {
socket.on('createRoom', async ({ roomId }) => {
(async () => {
const conn = await getConnection();
if (!conn) return;
try {
const isAvailable = await isRoomAvailable(conn, roomId);
if(isAvailable)
{
RoomManager.getInstance().createRoom(roomId);
}
socket.emit('createRoomResult', {result:isAvailable});
logger.info('createRoom', isAvailable, roomId);
} catch (err) {
socket.emit('createRoomResult', {result:false});
logger.info('createRoom failed', roomId);
} finally {
conn.release();
}
})();
});
socket.on('joinRoom', async ({ roomId, playerId }) => {
let result = RoomManager.getInstance().join(roomId, playerId, socket);
socket.emit('joinRoomResult', {result:result[0],message:result[1],roomStatus:result[2], playerInfo: result[3]});
logger.info('joinRoom', result[0], result[1], "roomId:", roomId, "PlayerId:", playerId);
if(result[0] == true && result[3] == null)//第一次加入房间
{
io.to(roomId).emit('updateRoomPlayerName', RoomManager.getInstance().getPlayersByRoomID(roomId));
}
else if(result[3] != null)//角色创建完后,断线后再次加入房间
{
socket.emit('updateRoomPlayerName', RoomManager.getInstance().getPlayersByRoomID(roomId));
let gameInfo = RoomManager.getInstance().getGameInfo(roomId, playerId);
if(gameInfo != null)
{
socket.emit('updateGameInfo', {enemyName:gameInfo.opponentId, hp:gameInfo.hp, rank:gameInfo.rank, character:gameInfo.character});
}
}
});
socket.on('leaveRoom', async ({ roomId, playerId }) => {
// roomManager.leaveRoom(roomId, playerId);
// socket.leave(roomId);
// await db.execute('DELETE FROM room_players WHERE room_id = ? AND player_id = ?', [roomId, playerId]);
// io.to(roomId).emit('playerLeft', { playerId });
});
socket.on('getRoomInfo', async ({ roomId }) => {
let room = RoomManager.getInstance().mRooms.get(roomId);
socket.emit('getRoomInfoResult', {result:room});
});
socket.on("setPlayerInfo", async ({roomId, playerId, strength, stamina, agile, cards})=>
{
let isRoomReady = RoomManager.getInstance().setPlayerInfo(roomId, playerId, strength, stamina, agile, cards);
socket.emit('setPlayerInfoResult', {result:true,message:""});
io.to(roomId).emit('updateRoomPlayerPrepare', {playerName:playerId});
if (isRoomReady)
{
io.to(roomId).emit('roomReady', {roomStatus:1});
let gameInfos = RoomManager.getInstance().getGameInfos(roomId);
for(let i=0; i<gameInfos.length; ++i)
{
let gameInfo = gameInfos[i];
//更新第一次进入fight场景时对手和hp
io.to(gameInfo.socketID).emit('updateGameInfo', {enemyName:gameInfo.opponentId, hp:gameInfo.hp, rank:gameInfo.rank, character:gameInfo.character});
}
}
});
socket.on('setFightInfo', async ({roomId, playerId, attack, defender})=>
{
let isFightReady = RoomManager.getInstance().setGameFight(roomId, playerId, attack, defender);
socket.emit('setFightInfoResult');
io.to(roomId).emit('updateRoomPlayerFightStatus', {playerName:playerId});
if(isFightReady)
{
let gameInfos = RoomManager.getInstance().getGameRoundInfos(roomId);
for(let i=0; i<gameInfos.length; ++i)
{
let gameInfo = gameInfos[i];
io.to(gameInfo.socketID).emit('endGameRound', {enemyName:gameInfo.opponentId, rank:gameInfo.rank, character:gameInfo.character, hp:gameInfo.hp});
if(gameInfo.hp <= 0)
{
io.to(roomId).emit('setPlayerDead', gameInfo.playerId);
}
}
RoomManager.getInstance().clearGameRoundPlayer(roomId);
}
});
socket.on('disconnect', async () => {
const ip = socket.handshake.address;
const roomId = socket.handshake.query.roomId;
const count = (RoomConnectionCount.get(roomId) || 1) - 1;
if (count <= 0) {
RoomConnectionCount.delete(roomId);
} else {
RoomConnectionCount.set(roomId, count);
}
logger.info('Client disconnected', ip, roomId, count);
});
});
server.listen(2888, () => {
logger.info('Socket.IO server running');
});