2025-10-11 14:45:08 +08:00
|
|
|
|
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:所有人准备,进入fight;2:fight结束
|
|
|
|
|
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())
|
|
|
|
|
{
|
2025-10-11 16:55:43 +08:00
|
|
|
|
const player = this.mPlayers.get(key);
|
|
|
|
|
if(player && player.mHp > 0)
|
2025-10-11 14:45:08 +08:00
|
|
|
|
{
|
2025-10-11 16:55:43 +08:00
|
|
|
|
tempPlayers.set(key, player);
|
2025-10-11 14:45:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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]
|
|
|
|
|
{
|
2025-10-11 16:55:43 +08:00
|
|
|
|
const room = this.mRooms.get(aRoomID);
|
|
|
|
|
if (!room)
|
2025-10-11 14:45:08 +08:00
|
|
|
|
{
|
|
|
|
|
return [false, "No room Id", null, null];
|
|
|
|
|
}
|
|
|
|
|
if(room.mPlayers.has(aName))
|
|
|
|
|
{
|
|
|
|
|
let player = room.mPlayers.get(aName);
|
2025-10-11 16:55:43 +08:00
|
|
|
|
if(player)
|
|
|
|
|
{
|
|
|
|
|
player.setPlayerSocketId(aSocket.id);
|
|
|
|
|
aSocket.join(aRoomID);
|
|
|
|
|
return [true, "", room.mStatus, player];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return [false, "unKnow error", null, null];
|
|
|
|
|
}
|
2025-10-11 14:45:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|