Files
CardServer/RoomManager.ts
2025-10-11 14:45:08 +08:00

276 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Socket } from "socket.io";
import { Player } from "./Player";
import { Json } from "sequelize/types/utils";
import { Matchmaker, createMatchmaker, PairingResult } from "./MatchMaker";
import { ALL_PLAYER_NUM } from "./GameDefine";
import { GameManager } from "./GameManager";
import { getLocalTime } from "./GetLocalTime";
type RoomPlayerInfo = {
playerName: string;
playerPrepared: boolean;
};
interface GameInfo {
playerId: string;
opponentId: string;
socketID: string;
rank: number;
character: string;
hp: number;
};
class Room
{
mPlayers:Map<string, Player> = new Map<string, Player>
mStatus:number = 0;//0房间开启1所有人准备进入fight2fight结束
mMatchMaker:Matchmaker = createMatchmaker(this.mPlayers);
mGameManager:GameManager = new GameManager();
mCreatedTime:Date = getLocalTime();
isRoomPrepared():boolean
{
if(this.mPlayers.size != ALL_PLAYER_NUM)
{
return false;
}
for(const value of this.mPlayers.values())
{
if(value.mPrepared == false)
{
return false;
}
}
return true;
}
setRoomPrepared()
{
this.generatePairings();
this.mStatus = 1;
}
generatePairings():PairingResult[]
{
let tempPlayers:Map<string, Player> = new Map<string, Player>;
for(const key of this.mPlayers.keys())
{
if(this.mPlayers.get(key)!.mHp > 0)
{
tempPlayers.set(key, this.mPlayers.get(key)!);
}
}
this.mMatchMaker.updatePlayers(tempPlayers);
let result = this.mMatchMaker.generatePairings();
for(let i=0; i<result.length; ++i)
{
let player = this.mPlayers.get(result[i].playerId);
if(player)
{
player.mCurrentEnemy = result[i].opponentId;
player.mIsResting = result[i].isResting;
}
}
return result;
}
getGameInfos():GameInfo[]
{
let gameInfo: GameInfo[] = [];
for(const player of this.mPlayers.values())
{
gameInfo.push({playerId:player.mPlayerName,
opponentId:player.mCurrentEnemy,
socketID: player.mSocketId,
rank: player.mRank,
character: player.mCharacterName,
hp: player.mHp});
}
return gameInfo;
}
getGameRoundInfos():GameInfo[]
{
let gameInfo: GameInfo[] = [];
for(const player of this.mGameManager.mGameFightPlayer.values())
{
gameInfo.push({playerId:player.mPlayerName,
opponentId:player.mCurrentEnemy,
socketID: player.mSocketId,
rank: player.mRank,
character: player.mCharacterName,
hp: player.mHp});
}
return gameInfo;
}
getGameInfo(aPlayerID:string):GameInfo|null
{
let player = this.mPlayers.get(aPlayerID);
if(player)
{
return {playerId:player.mPlayerName,opponentId:player.mCurrentEnemy,socketID:player.mSocketId,rank:player.mRank,character: player.mCharacterName, hp:player.mHp}
}
return null;
}
setGameFight(aPlayerID:string, aAttack:number, aDefender:number):boolean
{
let player = this.mPlayers.get(aPlayerID);
if(!player)
{
return false;
}
player.mAttack = aAttack;
player.mDefener = aDefender;
return this.mGameManager.setGameRoundInfo(aPlayerID, player);
}
}
export class RoomManager
{
static mInstance : RoomManager;
static getInstance(): RoomManager
{
if(this.mInstance == null)
{
this.mInstance = new RoomManager();
}
return this.mInstance;
}
mRooms = new Map<string, Room>;
join(aRoomID:string, aName:string, aSocket:Socket):[boolean, string, number | null, Player | null]
{
if(!this.mRooms.has(aRoomID))
{
return [false, "No room Id", null, null];
}
let room = this.mRooms.get(aRoomID)!;
if(room.mPlayers.has(aName))
{
let player = room.mPlayers.get(aName);
player!.setPlayerSocketId(aSocket.id);
aSocket.join(aRoomID);
return [true, "", room.mStatus, player!];
}
if(room.mPlayers.size < ALL_PLAYER_NUM)
{
let player = new Player(aName, aSocket.id);
aSocket.join(aRoomID);
room.mPlayers.set(aName, player);
return [true,"", 0, null];
}
return [false, "room full", null, null];
}
setPlayerInfo(roomId:string, playerId:string, strength:number, stamina:number, agile:number, cards:number[])
: boolean //返回值是是否所有玩家都准备完毕
{
let room = this.mRooms.get(roomId);
if(!room)
{
return false;
}
let player = room.mPlayers.get(playerId);
if(!player)
{
return false;
}
player.setPlayerInfo(strength, stamina, agile, cards);
if(room.isRoomPrepared() == true )
{
room.setRoomPrepared();
return true;
}
return false;
}
createRoom(aRoomID:string)
{
this.mRooms.set(aRoomID, new Room());
}
getPlayersByRoomID(aRoomID:string):RoomPlayerInfo[]
{
let room = this.mRooms.get(aRoomID);
let result:RoomPlayerInfo[] = [];
if(room?.mPlayers)
{
for(const value of room.mPlayers.values())
{
result.push({playerName:value.mPlayerName,playerPrepared:value.mPrepared});
}
}
return result;
}
getGameInfos(aRoomID:string):GameInfo[]
{
let room = this.mRooms.get(aRoomID);
if(room)
{
return room.getGameInfos();
}
return [];
}
getGameInfo(aRoomID:string, aPlayerID:string):GameInfo|null
{
let room = this.mRooms.get(aRoomID);
if(room)
{
return room.getGameInfo(aPlayerID);
}
return null;
}
getGameRoundInfos(aRoomID:string, aPlayerID:string):GameInfo[]
{
let room = this.mRooms.get(aRoomID);
if(room)
{
return room.getGameRoundInfos();
}
return [];
}
//返回值是否所有人都准备完毕
setGameFight(aRoomID:string, aPlayerID:string, aAttack:number, aDefender:number):boolean
{
let room = this.mRooms.get(aRoomID);
if(!room)
{
return false;
}
let result = room.setGameFight(aPlayerID, aAttack, aDefender);
if(result)
{
room.generatePairings();
}
return result;
}
clearGameRoundPlayer(aRoomID:string)
{
let room = this.mRooms.get(aRoomID);
if(!room)
{
return;
}
room.mGameManager.clearGameRoundPlayer();
}
isRoomExist(aRoomID:string):boolean
{
return this.mRooms.has(aRoomID);
}
}