@phalanx-engine/server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +507 -0
- package/dist/Phalanx.d.ts +85 -0
- package/dist/Phalanx.d.ts.map +1 -0
- package/dist/Phalanx.js +600 -0
- package/dist/Phalanx.js.map +1 -0
- package/dist/config/defaults.d.ts +10 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +51 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/validation.d.ts +15 -0
- package/dist/config/validation.d.ts.map +1 -0
- package/dist/config/validation.js +74 -0
- package/dist/config/validation.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/services/GameRoom.d.ts +359 -0
- package/dist/services/GameRoom.d.ts.map +1 -0
- package/dist/services/GameRoom.js +1272 -0
- package/dist/services/GameRoom.js.map +1 -0
- package/dist/services/MatchmakingService.d.ts +102 -0
- package/dist/services/MatchmakingService.d.ts.map +1 -0
- package/dist/services/MatchmakingService.js +286 -0
- package/dist/services/MatchmakingService.js.map +1 -0
- package/dist/services/OAuthExchangeService.d.ts +49 -0
- package/dist/services/OAuthExchangeService.d.ts.map +1 -0
- package/dist/services/OAuthExchangeService.js +96 -0
- package/dist/services/OAuthExchangeService.js.map +1 -0
- package/dist/services/PrivateRoomService.d.ts +136 -0
- package/dist/services/PrivateRoomService.d.ts.map +1 -0
- package/dist/services/PrivateRoomService.js +395 -0
- package/dist/services/PrivateRoomService.js.map +1 -0
- package/dist/services/TokenValidator.d.ts +60 -0
- package/dist/services/TokenValidator.d.ts.map +1 -0
- package/dist/services/TokenValidator.js +213 -0
- package/dist/services/TokenValidator.js.map +1 -0
- package/dist/types/index.d.ts +390 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/DeterministicRandom.d.ts +88 -0
- package/dist/utils/DeterministicRandom.d.ts.map +1 -0
- package/dist/utils/DeterministicRandom.js +140 -0
- package/dist/utils/DeterministicRandom.js.map +1 -0
- package/dist/utils/FixedMath.d.ts +22 -0
- package/dist/utils/FixedMath.d.ts.map +1 -0
- package/dist/utils/FixedMath.js +26 -0
- package/dist/utils/FixedMath.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phalanx Server Authentication
|
|
3
|
+
*
|
|
4
|
+
* Token validation for securing WebSocket connections.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Token Validator Service
|
|
8
|
+
*
|
|
9
|
+
* Validates OAuth tokens for server-side authentication.
|
|
10
|
+
*/
|
|
11
|
+
export class TokenValidatorService {
|
|
12
|
+
config;
|
|
13
|
+
tokenCache = new Map();
|
|
14
|
+
googleKeysCache = null;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = {
|
|
17
|
+
cacheTokens: true,
|
|
18
|
+
cacheTtlMs: 5 * 60 * 1000, // 5 minutes
|
|
19
|
+
...config,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validate a token
|
|
24
|
+
*/
|
|
25
|
+
async validate(token) {
|
|
26
|
+
if (!token) {
|
|
27
|
+
return { valid: false, error: 'No token provided' };
|
|
28
|
+
}
|
|
29
|
+
// Check cache first
|
|
30
|
+
if (this.config.cacheTokens) {
|
|
31
|
+
const cached = this.tokenCache.get(token);
|
|
32
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
33
|
+
return cached.result;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
let result;
|
|
37
|
+
// Use custom validator if provided
|
|
38
|
+
if (this.config.validator) {
|
|
39
|
+
result = await this.config.validator(token);
|
|
40
|
+
}
|
|
41
|
+
// Use Google validator if configured
|
|
42
|
+
else if (this.config.google) {
|
|
43
|
+
result = await this.validateGoogleToken(token);
|
|
44
|
+
}
|
|
45
|
+
// No validator configured
|
|
46
|
+
else {
|
|
47
|
+
return {
|
|
48
|
+
valid: false,
|
|
49
|
+
error: 'No token validator configured',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// Cache the result
|
|
53
|
+
if (this.config.cacheTokens && result.valid) {
|
|
54
|
+
const cacheTtl = this.config.cacheTtlMs || 5 * 60 * 1000;
|
|
55
|
+
this.tokenCache.set(token, {
|
|
56
|
+
result,
|
|
57
|
+
expiresAt: Date.now() + cacheTtl,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate a Google ID token
|
|
64
|
+
*/
|
|
65
|
+
async validateGoogleToken(token) {
|
|
66
|
+
try {
|
|
67
|
+
// Decode the token (without verification first to get the header)
|
|
68
|
+
const parts = token.split('.');
|
|
69
|
+
if (parts.length !== 3 || !parts[0] || !parts[1]) {
|
|
70
|
+
return { valid: false, error: 'Invalid token format' };
|
|
71
|
+
}
|
|
72
|
+
// Decode payload
|
|
73
|
+
const payloadJson = this.base64UrlDecode(parts[1]);
|
|
74
|
+
const payload = JSON.parse(payloadJson);
|
|
75
|
+
// Validate issuer
|
|
76
|
+
if (payload.iss !== 'https://accounts.google.com' &&
|
|
77
|
+
payload.iss !== 'accounts.google.com') {
|
|
78
|
+
return { valid: false, error: 'Invalid issuer' };
|
|
79
|
+
}
|
|
80
|
+
// Validate audience (client ID)
|
|
81
|
+
if (payload.aud !== this.config.google.clientId) {
|
|
82
|
+
return { valid: false, error: 'Invalid audience' };
|
|
83
|
+
}
|
|
84
|
+
// Validate expiration
|
|
85
|
+
if (payload.exp * 1000 < Date.now()) {
|
|
86
|
+
return { valid: false, error: 'Token expired' };
|
|
87
|
+
}
|
|
88
|
+
// Validate hosted domain if configured
|
|
89
|
+
if (this.config.google.allowedDomains?.length) {
|
|
90
|
+
if (!payload.hd ||
|
|
91
|
+
!this.config.google.allowedDomains.includes(payload.hd)) {
|
|
92
|
+
return {
|
|
93
|
+
valid: false,
|
|
94
|
+
error: `User must be from allowed domains: ${this.config.google.allowedDomains.join(', ')}`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// TODO: For production, verify the token signature using Google's JWKS
|
|
99
|
+
// This requires fetching keys from https://www.googleapis.com/oauth2/v3/certs
|
|
100
|
+
// and verifying the RS256 signature. See user story 04-id-token-signature-verification.md
|
|
101
|
+
return {
|
|
102
|
+
valid: true,
|
|
103
|
+
userId: payload.sub,
|
|
104
|
+
username: payload.name,
|
|
105
|
+
email: payload.email,
|
|
106
|
+
expiresAt: payload.exp * 1000,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return {
|
|
111
|
+
valid: false,
|
|
112
|
+
error: error instanceof Error ? error.message : 'Token validation failed',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Verify token signature using Google's JWKS (for production use)
|
|
118
|
+
* TODO: Implement full signature verification
|
|
119
|
+
*/
|
|
120
|
+
async verifyGoogleSignature(_token, _kid) {
|
|
121
|
+
// This is a placeholder for full signature verification
|
|
122
|
+
// See user story 04-id-token-signature-verification.md
|
|
123
|
+
console.warn('[TokenValidator] Signature verification not implemented - using claims-only validation');
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Base64URL decode
|
|
128
|
+
*/
|
|
129
|
+
base64UrlDecode(input) {
|
|
130
|
+
let base64 = input.replace(/-/g, '+').replace(/_/g, '/');
|
|
131
|
+
const padding = base64.length % 4;
|
|
132
|
+
if (padding) {
|
|
133
|
+
base64 += '='.repeat(4 - padding);
|
|
134
|
+
}
|
|
135
|
+
return Buffer.from(base64, 'base64').toString('utf-8');
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Clear the token cache
|
|
139
|
+
*/
|
|
140
|
+
clearCache() {
|
|
141
|
+
this.tokenCache.clear();
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get cache statistics
|
|
145
|
+
*/
|
|
146
|
+
getCacheStats() {
|
|
147
|
+
return {
|
|
148
|
+
size: this.tokenCache.size,
|
|
149
|
+
hits: 0, // Would need to track this
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Create a simple custom validator that accepts any non-empty token.
|
|
155
|
+
* FOR DEVELOPMENT/TESTING ONLY - DO NOT USE IN PRODUCTION!
|
|
156
|
+
*/
|
|
157
|
+
export function createDevValidator() {
|
|
158
|
+
console.warn('[TokenValidator] Using development validator - DO NOT USE IN PRODUCTION!');
|
|
159
|
+
return async (token) => {
|
|
160
|
+
if (!token) {
|
|
161
|
+
return { valid: false, error: 'No token' };
|
|
162
|
+
}
|
|
163
|
+
// In dev mode, extract userId from token if it looks like "dev:userId"
|
|
164
|
+
if (token.startsWith('dev:')) {
|
|
165
|
+
const userId = token.slice(4);
|
|
166
|
+
return {
|
|
167
|
+
valid: true,
|
|
168
|
+
userId,
|
|
169
|
+
username: userId,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// Accept any token in dev mode
|
|
173
|
+
return {
|
|
174
|
+
valid: true,
|
|
175
|
+
userId: 'dev-user',
|
|
176
|
+
username: 'Developer',
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create a validator that validates tokens via an external endpoint.
|
|
182
|
+
* Useful when you have a backend auth service.
|
|
183
|
+
*/
|
|
184
|
+
export function createEndpointValidator(endpointUrl, options) {
|
|
185
|
+
return async (token) => {
|
|
186
|
+
try {
|
|
187
|
+
const controller = new AbortController();
|
|
188
|
+
const timeoutId = setTimeout(() => controller.abort(), options?.timeout || 5000);
|
|
189
|
+
const response = await fetch(endpointUrl, {
|
|
190
|
+
method: 'POST',
|
|
191
|
+
headers: {
|
|
192
|
+
'Content-Type': 'application/json',
|
|
193
|
+
...options?.headers,
|
|
194
|
+
},
|
|
195
|
+
body: JSON.stringify({ token }),
|
|
196
|
+
signal: controller.signal,
|
|
197
|
+
});
|
|
198
|
+
clearTimeout(timeoutId);
|
|
199
|
+
if (!response.ok) {
|
|
200
|
+
return { valid: false, error: `Validation failed: ${response.status}` };
|
|
201
|
+
}
|
|
202
|
+
const result = await response.json();
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
return {
|
|
207
|
+
valid: false,
|
|
208
|
+
error: error instanceof Error ? error.message : 'Validation request failed',
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=TokenValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenValidator.js","sourceRoot":"","sources":["../../src/services/TokenValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phalanx Engine Types
|
|
3
|
+
* All exported types for TypeScript users
|
|
4
|
+
*/
|
|
5
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
6
|
+
/**
|
|
7
|
+
* Game mode preset string
|
|
8
|
+
*/
|
|
9
|
+
export type GameModePreset = '1v1' | '2v2' | '3v3' | '4v4' | 'FFA4';
|
|
10
|
+
/**
|
|
11
|
+
* Custom game mode configuration
|
|
12
|
+
*/
|
|
13
|
+
export interface CustomGameMode {
|
|
14
|
+
playersPerMatch: number;
|
|
15
|
+
teamsCount: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Game mode - either a preset string or custom configuration
|
|
19
|
+
*/
|
|
20
|
+
export type GameMode = GameModePreset | CustomGameMode;
|
|
21
|
+
/**
|
|
22
|
+
* Tick mode: 'continuous' runs a server tick loop; 'event' is tickless (relay-only).
|
|
23
|
+
*/
|
|
24
|
+
export type TickMode = 'continuous' | 'event';
|
|
25
|
+
/**
|
|
26
|
+
* Per-game-type configuration overrides.
|
|
27
|
+
* Fields here override the base PhalanxConfig for matches of this game type.
|
|
28
|
+
*/
|
|
29
|
+
export interface GameTypeConfig {
|
|
30
|
+
gameType: string;
|
|
31
|
+
tickMode?: TickMode;
|
|
32
|
+
tickRate?: number;
|
|
33
|
+
gameMode?: GameMode;
|
|
34
|
+
countdownSeconds?: number;
|
|
35
|
+
turnTimeoutMs?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* CORS configuration
|
|
39
|
+
*/
|
|
40
|
+
export interface CorsConfig {
|
|
41
|
+
origin: string | string[];
|
|
42
|
+
methods?: string[];
|
|
43
|
+
credentials?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* TLS/SSL configuration for secure WebSocket connections (WSS)
|
|
47
|
+
*/
|
|
48
|
+
export interface TlsConfig {
|
|
49
|
+
/** Enable TLS/SSL encryption */
|
|
50
|
+
enabled: boolean;
|
|
51
|
+
/** Path to the private key file (PEM format) */
|
|
52
|
+
keyPath: string;
|
|
53
|
+
/** Path to the certificate file (PEM format) */
|
|
54
|
+
certPath: string;
|
|
55
|
+
/** Optional path to CA certificate chain (for Let's Encrypt) */
|
|
56
|
+
caPath?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Action to take when desync is detected
|
|
60
|
+
*/
|
|
61
|
+
export type DesyncAction = 'log-only' | 'end-match';
|
|
62
|
+
/**
|
|
63
|
+
* Configuration for desync detection behavior
|
|
64
|
+
*/
|
|
65
|
+
export interface DesyncConfig {
|
|
66
|
+
/** Whether desync detection is enabled */
|
|
67
|
+
enabled: boolean;
|
|
68
|
+
/** Action to take on confirmed desync */
|
|
69
|
+
action: DesyncAction;
|
|
70
|
+
/** Number of consecutive desyncs before taking action (default: 1) */
|
|
71
|
+
gracePeriodTicks: number;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Configuration for pause/resume behavior
|
|
75
|
+
*/
|
|
76
|
+
export interface PauseConfig {
|
|
77
|
+
/**
|
|
78
|
+
* Maximum number of pauses allowed per player.
|
|
79
|
+
* Set to Infinity for unlimited pauses.
|
|
80
|
+
* @default Infinity
|
|
81
|
+
*/
|
|
82
|
+
maxPausesPerPlayer: number;
|
|
83
|
+
/**
|
|
84
|
+
* Whether the game can only be resumed by the same player who paused it.
|
|
85
|
+
* If false, any player can resume the game.
|
|
86
|
+
* @default false
|
|
87
|
+
*/
|
|
88
|
+
requireSamePlayerToResume: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Token validator function type.
|
|
92
|
+
* Implement this to validate tokens from your OAuth provider.
|
|
93
|
+
*/
|
|
94
|
+
export type TokenValidator = (token: string) => Promise<TokenValidationResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Result of token validation
|
|
97
|
+
*/
|
|
98
|
+
export interface TokenValidationResult {
|
|
99
|
+
/** Whether the token is valid */
|
|
100
|
+
valid: boolean;
|
|
101
|
+
/** User ID from the token (if valid) */
|
|
102
|
+
userId?: string;
|
|
103
|
+
/** Username from the token (if valid) */
|
|
104
|
+
username?: string;
|
|
105
|
+
/** Email from the token (if valid) */
|
|
106
|
+
email?: string;
|
|
107
|
+
/** Token expiration timestamp in milliseconds (if valid) */
|
|
108
|
+
expiresAt?: number;
|
|
109
|
+
/** Error message (if invalid) */
|
|
110
|
+
error?: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Authentication configuration for securing WebSocket connections
|
|
114
|
+
*/
|
|
115
|
+
export interface AuthConfig {
|
|
116
|
+
/** Enable authentication (default: false for development) */
|
|
117
|
+
enabled: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Custom token validator function.
|
|
120
|
+
* If not provided and enabled=true, you must configure a built-in validator.
|
|
121
|
+
*/
|
|
122
|
+
validator?: TokenValidator;
|
|
123
|
+
/**
|
|
124
|
+
* Built-in Google token validation.
|
|
125
|
+
* Validates Google ID tokens.
|
|
126
|
+
*/
|
|
127
|
+
google?: {
|
|
128
|
+
/** Your Google OAuth Client ID */
|
|
129
|
+
clientId: string;
|
|
130
|
+
/** Your Google OAuth Client Secret (required for token exchange) */
|
|
131
|
+
clientSecret?: string;
|
|
132
|
+
/** Allowed hosted domains (optional, for Google Workspace) */
|
|
133
|
+
allowedDomains?: string[];
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Allow unauthenticated connections (for development/testing).
|
|
137
|
+
* If true, connections without tokens are allowed when auth is enabled.
|
|
138
|
+
* @default false
|
|
139
|
+
*/
|
|
140
|
+
allowAnonymous?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Cache validated tokens to reduce validation overhead.
|
|
143
|
+
* @default true
|
|
144
|
+
*/
|
|
145
|
+
cacheTokens?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Token cache TTL in milliseconds.
|
|
148
|
+
* @default 300000 (5 minutes)
|
|
149
|
+
*/
|
|
150
|
+
cacheTtlMs?: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Full Phalanx configuration
|
|
154
|
+
*/
|
|
155
|
+
export interface PhalanxConfig {
|
|
156
|
+
port: number;
|
|
157
|
+
cors: CorsConfig;
|
|
158
|
+
tls?: TlsConfig;
|
|
159
|
+
auth?: AuthConfig;
|
|
160
|
+
tickRate: number;
|
|
161
|
+
tickDeadlineMs: number;
|
|
162
|
+
tickMode?: TickMode;
|
|
163
|
+
gameTypes?: GameTypeConfig[];
|
|
164
|
+
turnTimeoutMs?: number;
|
|
165
|
+
gameMode: GameMode;
|
|
166
|
+
matchmakingIntervalMs: number;
|
|
167
|
+
countdownSeconds: number;
|
|
168
|
+
timeoutTicks: number;
|
|
169
|
+
disconnectTicks: number;
|
|
170
|
+
reconnectGracePeriodMs: number;
|
|
171
|
+
maxTickBehind: number;
|
|
172
|
+
maxTickAhead: number;
|
|
173
|
+
commandHistoryTicks: number;
|
|
174
|
+
/** Enable input sequence validation (default: false for backward compatibility) */
|
|
175
|
+
validateInputSequence?: boolean;
|
|
176
|
+
/** Enable state hashing for desync detection (default: false) */
|
|
177
|
+
enableStateHashing?: boolean;
|
|
178
|
+
/** Interval in ticks between state hash checks (default: 60) */
|
|
179
|
+
stateHashInterval?: number;
|
|
180
|
+
/** Desync detection behavior configuration */
|
|
181
|
+
desync?: Partial<DesyncConfig>;
|
|
182
|
+
/** Timeout in milliseconds for all clients to report ready after game-start (default: 30000) */
|
|
183
|
+
readyTimeoutMs?: number;
|
|
184
|
+
/**
|
|
185
|
+
* How long `GameRoom.start()` will wait for all participants' sockets
|
|
186
|
+
* to be present before kicking off the countdown. If at least one
|
|
187
|
+
* player is offline at start time, the match enters
|
|
188
|
+
* `'waiting-for-players'` and emits `match-waiting-for-players` to
|
|
189
|
+
* whoever is online; the countdown only begins once everyone
|
|
190
|
+
* reconnects, or after this timeout the match is ended with
|
|
191
|
+
* `match-end: 'players-not-connected'`. Default: 60000.
|
|
192
|
+
*/
|
|
193
|
+
playersConnectTimeoutMs?: number;
|
|
194
|
+
/** Pause/resume behavior configuration */
|
|
195
|
+
pause?: Partial<PauseConfig>;
|
|
196
|
+
/**
|
|
197
|
+
* Optional hook for mounting additional request handlers on the same HTTP
|
|
198
|
+
* server. Called after CORS preflight, before built-in routes.
|
|
199
|
+
*
|
|
200
|
+
* Return `true` to signal the request was fully handled (no further
|
|
201
|
+
* routing). Return `false` (or `undefined`) to let Phalanx continue with
|
|
202
|
+
* its own routing.
|
|
203
|
+
*/
|
|
204
|
+
extraRequestHandler?: (req: IncomingMessage, res: ServerResponse) => boolean | Promise<boolean>;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Player command sent from client
|
|
208
|
+
*/
|
|
209
|
+
export interface PlayerCommand {
|
|
210
|
+
type: string;
|
|
211
|
+
tick: number;
|
|
212
|
+
playerId: string;
|
|
213
|
+
data: unknown;
|
|
214
|
+
/** Optional sequence number for input validation (monotonically increasing per player) */
|
|
215
|
+
sequence?: number;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Information about a player
|
|
219
|
+
*/
|
|
220
|
+
export interface PlayerInfo {
|
|
221
|
+
id: string;
|
|
222
|
+
teamId: number;
|
|
223
|
+
connected: boolean;
|
|
224
|
+
lastTick: number;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Information about an active match
|
|
228
|
+
*/
|
|
229
|
+
export interface MatchInfo {
|
|
230
|
+
id: string;
|
|
231
|
+
players: PlayerInfo[];
|
|
232
|
+
currentTick: number;
|
|
233
|
+
state: 'waiting-for-players' | 'countdown' | 'waiting-for-ready' | 'playing' | 'paused' | 'finished';
|
|
234
|
+
createdAt: Date;
|
|
235
|
+
gameType?: string;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Player info for match-found event (minimal data)
|
|
239
|
+
*/
|
|
240
|
+
export interface MatchPlayerInfo {
|
|
241
|
+
playerId: string;
|
|
242
|
+
username: string;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Match found event payload - personalized for each player
|
|
246
|
+
*/
|
|
247
|
+
export interface MatchFoundEvent {
|
|
248
|
+
matchId: string;
|
|
249
|
+
playerId: string;
|
|
250
|
+
teamId: number;
|
|
251
|
+
teammates: MatchPlayerInfo[];
|
|
252
|
+
opponents: MatchPlayerInfo[];
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Countdown event payload - sent every second before game starts
|
|
256
|
+
*/
|
|
257
|
+
export interface CountdownEvent {
|
|
258
|
+
seconds: number;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Game start event payload - sent when countdown reaches 0
|
|
262
|
+
*/
|
|
263
|
+
export interface GameStartEvent {
|
|
264
|
+
matchId: string;
|
|
265
|
+
/** Random seed for deterministic RNG (optional for backward compatibility) */
|
|
266
|
+
randomSeed?: number;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Tick sync event payload - sent every tick for synchronization
|
|
270
|
+
*/
|
|
271
|
+
export interface TickSyncEvent {
|
|
272
|
+
tick: number;
|
|
273
|
+
timestamp: number;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Commands batch event payload - sent to all clients each tick
|
|
277
|
+
*/
|
|
278
|
+
export interface CommandsBatchEvent {
|
|
279
|
+
tick: number;
|
|
280
|
+
commands: PlayerCommand[];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Commands grouped by player for a specific tick
|
|
284
|
+
*/
|
|
285
|
+
export interface TickCommands {
|
|
286
|
+
[playerId: string]: PlayerCommand[];
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Submit commands event payload from client
|
|
290
|
+
*/
|
|
291
|
+
export interface SubmitCommandsEvent {
|
|
292
|
+
tick: number;
|
|
293
|
+
commands: PlayerCommand[];
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Player queued for matchmaking
|
|
297
|
+
*/
|
|
298
|
+
export interface QueuedPlayer {
|
|
299
|
+
playerId: string;
|
|
300
|
+
username: string;
|
|
301
|
+
socketId: string;
|
|
302
|
+
joinedAt: number;
|
|
303
|
+
gameType?: string;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Queue status response
|
|
307
|
+
*/
|
|
308
|
+
export interface QueueStatusEvent {
|
|
309
|
+
position: number;
|
|
310
|
+
waitTime: number;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Private room events — client/server wire contracts.
|
|
314
|
+
*
|
|
315
|
+
* These mirror the interfaces exported from
|
|
316
|
+
* `services/PrivateRoomService.ts` and are documented here for
|
|
317
|
+
* consistency with the rest of the public event surface.
|
|
318
|
+
*
|
|
319
|
+
* Socket events:
|
|
320
|
+
* • server → host: `room-created` → `RoomCreatedEvent`
|
|
321
|
+
* • server → host: `room-recovered` → `RoomRecoveredEvent`
|
|
322
|
+
* • server → host: `room-cancelled` → `{ code: string }`
|
|
323
|
+
* • server → host: `room-expired` → `{ code: string }`
|
|
324
|
+
* • server → peer: `room-error` → `RoomErrorEvent`
|
|
325
|
+
* • client → server: `room-create` → `{ playerId, username?, gameType? }`
|
|
326
|
+
* • client → server: `room-join` → `{ playerId, username?, code }`
|
|
327
|
+
* • client → server: `room-cancel` → `{}`
|
|
328
|
+
* • client → server: `room-recover` → `{ playerId, username?, code }`
|
|
329
|
+
*
|
|
330
|
+
* The `code` on `room-recover` is required: it proves the caller is
|
|
331
|
+
* actually the host who created the room. In an unauthenticated
|
|
332
|
+
* socket environment `playerId` alone is not a credential, so the
|
|
333
|
+
* server refuses to recover without a matching code and emits
|
|
334
|
+
* `room-error: "Room expired"` instead (same message as "no such
|
|
335
|
+
* room" so we never leak whether a given playerId currently owns
|
|
336
|
+
* a room).
|
|
337
|
+
*/
|
|
338
|
+
/** Event sent to the host when a room is created. */
|
|
339
|
+
export interface RoomCreatedEvent {
|
|
340
|
+
code: string;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Event sent to the host when they successfully reclaim a room
|
|
344
|
+
* via `room-recover` after a transient socket disconnect.
|
|
345
|
+
*/
|
|
346
|
+
export interface RoomRecoveredEvent {
|
|
347
|
+
code: string;
|
|
348
|
+
}
|
|
349
|
+
/** Event sent when a private-room operation fails. */
|
|
350
|
+
export interface RoomErrorEvent {
|
|
351
|
+
message: string;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* State hash event from client (2.1.3)
|
|
355
|
+
*/
|
|
356
|
+
export interface StateHashEvent {
|
|
357
|
+
tick: number;
|
|
358
|
+
hash: string;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Desync detected event (2.1.3)
|
|
362
|
+
*/
|
|
363
|
+
export interface DesyncDetectedEvent {
|
|
364
|
+
tick: number;
|
|
365
|
+
hashes: {
|
|
366
|
+
[playerId: string]: string;
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Available Phalanx events
|
|
371
|
+
*/
|
|
372
|
+
export type PhalanxEventType = 'match-created' | 'match-started' | 'match-ended' | 'match-paused' | 'match-resumed' | 'player-command' | 'player-timeout' | 'player-reconnected' | 'player-disconnected' | 'desync-detected';
|
|
373
|
+
/**
|
|
374
|
+
* Event handler types
|
|
375
|
+
*/
|
|
376
|
+
export interface PhalanxEventHandlers {
|
|
377
|
+
'match-created': (match: MatchInfo) => void;
|
|
378
|
+
'match-started': (match: MatchInfo) => void;
|
|
379
|
+
'match-ended': (matchId: string, reason: string) => void;
|
|
380
|
+
'match-paused': (matchId: string, requestedBy: string) => void;
|
|
381
|
+
'match-resumed': (matchId: string, requestedBy: string) => void;
|
|
382
|
+
'player-command': (playerId: string, command: PlayerCommand) => boolean | void;
|
|
383
|
+
'player-timeout': (playerId: string, matchId: string) => void;
|
|
384
|
+
'player-reconnected': (playerId: string, matchId: string) => void;
|
|
385
|
+
'player-disconnected': (playerId: string, matchId: string) => void;
|
|
386
|
+
'desync-detected': (matchId: string, tick: number, hashes: {
|
|
387
|
+
[playerId: string]: string;
|
|
388
|
+
}) => void;
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|