serverplace / src /types /index.ts
3v324v23's picture
Update Server: Fix Vote Bug, Memory Leak, and Role Reveal
05d8628
export type GameType = 'MAFIA';
export type GameStatus = 'WAITING' | 'PLAYING' | 'GAME_OVER';
export type GamePhase = 'LOBBY' | 'NIGHT' | 'DAY' | 'VOTING' | 'VOTING_RESULT' | 'GAME_OVER';
export type Role = 'MAFIA' | 'DOCTOR' | 'DETECTIVE' | 'JOKER' | 'VILLAGER' | 'THIEF' | 'PLAYWRIGHT';
export interface Player {
id: string; // Socket ID (volatile)
userId: string; // Persistent User ID (from client/auth)
username: string;
avatar: string;
isHost: boolean;
isAlive: boolean;
isOnline: boolean; // Handle disconnects
isBot?: boolean; // AI Flag
role?: Role; // Only assigned when game starts
actionTarget?: string | null;
votesReceived: number;
isRobbed?: boolean;
thiefCooldown?: number;
elimTeamHistory?: string[];
}
export interface ActionLog {
phase: GamePhase;
round: number;
actorId: string;
targetId?: string; // Optional because some actions might not have a target or target is hidden
action: 'VOTE' | 'KILL' | 'SAVE' | 'INVESTIGATE' | 'STEAL' | 'SWAP_VOTES' | 'VOTES_SWAPPED' | 'PENALTY_DEATH' | 'VOTE_OUT' | 'KILLED_BY_MAFIA' | 'SAVED_BY_DOCTOR';
result?: string; // e.g., "MAFIA_REVEALED", "SAVED", "DIED", "ROLE_STOLEN"
}
export interface ChatLog {
senderId: string;
senderName: string; // Store name for NLP matching
text: string;
phase: GamePhase;
timestamp: number;
}
export interface GameSettings {
timers: {
NIGHT: number;
DAY: number;
VOTING: number;
};
mafiaCount: number;
roles: {
DOCTOR: boolean;
DETECTIVE: boolean;
JOKER: boolean;
THIEF: boolean;
PLAYWRIGHT: boolean;
};
}
export interface Room {
id: string;
name: string;
isPublic: boolean;
gameType: GameType;
status: GameStatus;
phase: GamePhase;
players: Player[];
hostId: string;
maxPlayers: number;
settings: GameSettings; // Added settings
// Game State
createdAt: number;
lastActivity: number;
round: number;
timer: number;
// History for Analytics
history: ActionLog[];
chatHistory: ChatLog[]; // New: Chat Memory for Bots
// Logic State
nightActions: {
mafiaVote: Record<string, string>;
doctorTarget: string | null;
detectiveTarget: string | null;
playwrightSwap: { targetA: string, targetB: string } | null;
};
votes: Record<string, number>; // TargetID -> Count
lastNightResult: string;
winner: string | null;
}
// Socket Events
export interface ServerToClientEvents {
room_list_update: (rooms: Room[]) => void;
// We send a sanitized version of the room
room_state_update: (room: Partial<Room>) => void;
game_phase_update: (phase: GamePhase, timer: number) => void;
player_action_update: (data: { type: string, payload: any }) => void;
private_message: (data: { text: string, avatar?: string }) => void;
new_message: (data: { sender: string, text: string, type?: 'chat' | 'system', avatar?: string }) => void;
game_over: (winner: string) => void;
error_message: (msg: string) => void;
YOU_DIED: (data: { killerName: string }) => void;
PLAYER_ROBBED: (data: { victimId: string }) => void;
kicked: () => void; // Notify player they were kicked
}
export interface ClientToServerEvents {
create_room: (data: { name: string; isPublic: boolean; gameType: GameType; hostUser: any; settings?: any }, callback: (roomId: string) => void) => void;
join_room: (data: { roomId: string; user: any }) => void;
get_rooms: () => void;
start_game: (roomId: string) => void;
reset_room: (roomId: string) => void;
update_settings: (data: { roomId: string; settings: any }) => void;
add_bot: (roomId: string) => void;
kick_player: (data: { roomId: string; targetId: string }) => void;
night_action: (data: { roomId: string; action: string; targetId: string }) => void;
day_action: (data: { roomId: string; action: string; targetId?: string; targetA?: string; targetB?: string }) => void;
vote: (data: { roomId: string; targetId: string }) => void;
send_message: (data: { roomId: string; text: string }) => void;
}
export interface InterServerEvents {}
export interface SocketData {
userId: string;
roomId: string;
}