emoemu 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/.claude/settings.local.json +77 -0
- package/.node-version +1 -0
- package/CLAUDE.md +435 -0
- package/README.md +404 -0
- package/TODO.md +655 -0
- package/dist/index.cjs +25108 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +25085 -0
- package/docs/building-libretro-cores-arm-mac.md +237 -0
- package/docs/config-file-format.md +488 -0
- package/docs/cores-trd.md +425 -0
- package/docs/headless-hardware-rendering-trd.md +676 -0
- package/docs/libretro-cores-trd.md +997 -0
- package/docs/mupen64-software-rendering-trd.md +751 -0
- package/docs/n64-support-trd.md +306 -0
- package/docs/native-rendering-trd.md +540 -0
- package/docs/native-ui-rendering-trd.md +1195 -0
- package/docs/netplay-trd.md +665 -0
- package/docs/retroarch-netplay-docs.md +277 -0
- package/docs/save-state-format.md +666 -0
- package/eslint.config.js +111 -0
- package/icon/icon.png +0 -0
- package/icon/icon.pxd +0 -0
- package/package.json +63 -0
- package/pnpm-workspace.yaml +10 -0
- package/src/Emulator/consts.ts +14 -0
- package/src/Emulator/index.ts +2496 -0
- package/src/Emulator/saveState/index.ts +155 -0
- package/src/Emulator/screenshot/index.ts +160 -0
- package/src/Emulator/terminalDimensions/index.ts +79 -0
- package/src/Emulator/types.ts +83 -0
- package/src/cli/commands/consts.ts +10 -0
- package/src/cli/commands/index.ts +462 -0
- package/src/cli/parseArgs/consts.ts +17 -0
- package/src/cli/parseArgs/index.ts +457 -0
- package/src/cli/parseArgs/types.ts +61 -0
- package/src/cli/runEmulator/index.ts +406 -0
- package/src/cli/runEmulator/types.ts +7 -0
- package/src/consts.ts +19 -0
- package/src/core/button/consts.ts +35 -0
- package/src/core/button/index.ts +123 -0
- package/src/core/core.ts +300 -0
- package/src/core/index.ts +19 -0
- package/src/cores/libretro/api/index.ts +334 -0
- package/src/cores/libretro/api/types.ts +148 -0
- package/src/cores/libretro/callbacks/consts.ts +41 -0
- package/src/cores/libretro/callbacks/index.ts +456 -0
- package/src/cores/libretro/consts.ts +45 -0
- package/src/cores/libretro/coreOptions/consts.ts +36 -0
- package/src/cores/libretro/coreOptions/index.ts +222 -0
- package/src/cores/libretro/environment/consts.ts +118 -0
- package/src/cores/libretro/environment/index.ts +1095 -0
- package/src/cores/libretro/index.ts +937 -0
- package/src/cores/libretro/loader/index.ts +496 -0
- package/src/cores/libretro/pixelFormat/consts.ts +43 -0
- package/src/cores/libretro/pixelFormat/index.ts +397 -0
- package/src/cores/libretro/types.ts +339 -0
- package/src/frontend/AudioManager/index.ts +420 -0
- package/src/frontend/SettingsManager/index.ts +250 -0
- package/src/frontend/config/index.ts +608 -0
- package/src/frontend/config/tests.ts +354 -0
- package/src/frontend/config/types.ts +36 -0
- package/src/frontend/consts.ts +114 -0
- package/src/frontend/coreBuilder/index.ts +644 -0
- package/src/frontend/coreBuilder/types.ts +15 -0
- package/src/frontend/coreDownloader/index.ts +620 -0
- package/src/frontend/coreDownloader/types.ts +17 -0
- package/src/frontend/corePreferences/index.ts +69 -0
- package/src/frontend/coreRegistry/index.ts +276 -0
- package/src/frontend/directoryCache/index.ts +75 -0
- package/src/frontend/index.ts +79 -0
- package/src/frontend/notifications/consts.ts +14 -0
- package/src/frontend/notifications/index.ts +250 -0
- package/src/frontend/playlist/consts.ts +168 -0
- package/src/frontend/playlist/index.ts +899 -0
- package/src/frontend/playlist/labelFormatter/consts.ts +15 -0
- package/src/frontend/playlist/labelFormatter/index.ts +155 -0
- package/src/frontend/playlist/labelFormatter/tests.ts +153 -0
- package/src/frontend/playlist/reader/index.ts +559 -0
- package/src/frontend/playlist/sync/index.ts +511 -0
- package/src/frontend/playlist/systemLookup/index.ts +233 -0
- package/src/frontend/playlist/utils/index.ts +50 -0
- package/src/frontend/romScanner/consts.ts +348 -0
- package/src/frontend/romScanner/index.ts +1957 -0
- package/src/frontend/saveServices/consts.ts +2 -0
- package/src/frontend/saveServices/index.ts +313 -0
- package/src/frontend/serviceProvider/index.ts +108 -0
- package/src/frontend/serviceProvider/types.ts +13 -0
- package/src/index.ts +428 -0
- package/src/input/Controller/consts.ts +50 -0
- package/src/input/Controller/index.ts +81 -0
- package/src/input/GamepadManager/consts.ts +22 -0
- package/src/input/GamepadManager/index.ts +418 -0
- package/src/input/InputManager/consts.ts +86 -0
- package/src/input/InputManager/index.ts +593 -0
- package/src/input/InputMapper/consts.ts +33 -0
- package/src/input/InputMapper/index.ts +436 -0
- package/src/input/consts.ts +410 -0
- package/src/input/gamepadProfiles/index.ts +1100 -0
- package/src/input/index.ts +38 -0
- package/src/input/inputUtils/index.ts +31 -0
- package/src/netplay/FrameBuffer/consts.ts +2 -0
- package/src/netplay/FrameBuffer/index.ts +364 -0
- package/src/netplay/FrameBuffer/tests.ts +286 -0
- package/src/netplay/InputBuffer/consts.ts +7 -0
- package/src/netplay/InputBuffer/index.ts +347 -0
- package/src/netplay/InputBuffer/tests.ts +166 -0
- package/src/netplay/NetplayClient/index.ts +976 -0
- package/src/netplay/NetplayConnection/index.ts +536 -0
- package/src/netplay/NetplayDiscovery/consts.ts +41 -0
- package/src/netplay/NetplayDiscovery/index.ts +525 -0
- package/src/netplay/NetplayServer/index.ts +1407 -0
- package/src/netplay/SyncManager/index.ts +984 -0
- package/src/netplay/SyncManager/tests.ts +419 -0
- package/src/netplay/consts.ts +371 -0
- package/src/netplay/crc32/consts.ts +14 -0
- package/src/netplay/crc32/index.ts +97 -0
- package/src/netplay/crc32/tests.ts +40 -0
- package/src/netplay/index.ts +41 -0
- package/src/netplay/netplayLogger/consts.ts +30 -0
- package/src/netplay/netplayLogger/index.ts +345 -0
- package/src/netplay/protocol/consts.ts +86 -0
- package/src/netplay/protocol/index.ts +1280 -0
- package/src/netplay/protocol/tests.ts +606 -0
- package/src/netplay/protocol/types.ts +20 -0
- package/src/netplay/types.ts +395 -0
- package/src/rendering/KittyRenderer/index.ts +616 -0
- package/src/rendering/NativeRenderer/index.ts +279 -0
- package/src/rendering/NativeRenderer/tests.ts +133 -0
- package/src/rendering/TerminalRenderer/index.ts +770 -0
- package/src/rendering/consts.ts +401 -0
- package/src/rendering/fonts/CozetteVector.ttf +0 -0
- package/src/rendering/index.ts +26 -0
- package/src/rendering/nativeUi/NativeWindowManager/index.ts +158 -0
- package/src/rendering/nativeUi/NativeWindowManager/tests.ts +81 -0
- package/src/rendering/nativeUi/consts.ts +6 -0
- package/src/rendering/nativeUi/index.ts +20 -0
- package/src/rendering/postProcessing/consts.ts +38 -0
- package/src/rendering/postProcessing/index.ts +923 -0
- package/src/rendering/shared/ansi/consts.ts +12 -0
- package/src/rendering/shared/ansi/index.ts +104 -0
- package/src/rendering/shared/consts.ts +2 -0
- package/src/rendering/shared/fitToTerminal/index.ts +67 -0
- package/src/ui/AddRomsPrompt/consts.ts +13 -0
- package/src/ui/AddRomsPrompt/index.tsx +781 -0
- package/src/ui/App/consts.ts +2 -0
- package/src/ui/App/index.tsx +456 -0
- package/src/ui/AppCapabilities/index.tsx +67 -0
- package/src/ui/ConfigContext/index.tsx +56 -0
- package/src/ui/CoreManager/consts.ts +11 -0
- package/src/ui/CoreManager/index.tsx +779 -0
- package/src/ui/CoreSelector/consts.ts +2 -0
- package/src/ui/CoreSelector/index.tsx +251 -0
- package/src/ui/DialogContainer/index.tsx +42 -0
- package/src/ui/DialogOptionsList/index.tsx +61 -0
- package/src/ui/DuplicateCrcPrompt/consts.ts +5 -0
- package/src/ui/DuplicateCrcPrompt/index.tsx +146 -0
- package/src/ui/GamepadContext/consts.ts +15 -0
- package/src/ui/GamepadContext/index.tsx +295 -0
- package/src/ui/NativeDialog/index.tsx +120 -0
- package/src/ui/NetplayDisconnectedDialog/index.tsx +93 -0
- package/src/ui/NetplayPauseMenu/consts.ts +2 -0
- package/src/ui/NetplayPauseMenu/index.tsx +97 -0
- package/src/ui/RomBrowser/NetplayPanel/consts.ts +24 -0
- package/src/ui/RomBrowser/NetplayPanel/index.tsx +520 -0
- package/src/ui/RomBrowser/SettingsPanel/index.tsx +478 -0
- package/src/ui/RomBrowser/consts.ts +61 -0
- package/src/ui/RomBrowser/index.tsx +1164 -0
- package/src/ui/RomBrowser/settingsConfig/index.ts +320 -0
- package/src/ui/RomBrowser/types.ts +67 -0
- package/src/ui/SaveStateDialog/consts.ts +2 -0
- package/src/ui/SaveStateDialog/index.tsx +225 -0
- package/src/ui/WarningDialog/index.tsx +113 -0
- package/src/ui/consts.ts +27 -0
- package/src/ui/hooks/useClearTerminal/consts.ts +2 -0
- package/src/ui/hooks/useClearTerminal/index.ts +37 -0
- package/src/ui/hooks/useDialogNavigation/index.ts +99 -0
- package/src/ui/hooks/useGamepad/consts.ts +21 -0
- package/src/ui/hooks/useGamepad/index.ts +194 -0
- package/src/ui/index.ts +27 -0
- package/src/utils/buffer/consts.ts +17 -0
- package/src/utils/buffer/index.ts +129 -0
- package/src/utils/color/consts.ts +58 -0
- package/src/utils/color/index.ts +183 -0
- package/src/utils/compression/consts.ts +50 -0
- package/src/utils/compression/index.ts +101 -0
- package/src/utils/consts.ts +2 -0
- package/src/utils/crc32/consts.ts +22 -0
- package/src/utils/crc32/index.ts +83 -0
- package/src/utils/ensureDirectory/index.ts +10 -0
- package/src/utils/format/consts.ts +8 -0
- package/src/utils/format/index.ts +53 -0
- package/src/utils/getErrorMessage/index.ts +10 -0
- package/src/utils/index.ts +113 -0
- package/src/utils/ini/index.ts +200 -0
- package/src/utils/kitty/consts.ts +13 -0
- package/src/utils/kitty/index.ts +181 -0
- package/src/utils/logger/consts.ts +35 -0
- package/src/utils/logger/index.ts +217 -0
- package/src/utils/paths/consts.ts +18 -0
- package/src/utils/paths/index.ts +151 -0
- package/src/utils/png/consts.ts +34 -0
- package/src/utils/png/index.ts +131 -0
- package/src/utils/readJsonFile/index.ts +16 -0
- package/src/utils/rotateLogFile/index.ts +44 -0
- package/src/utils/safeClose/index.ts +10 -0
- package/src/utils/terminal/consts.ts +8 -0
- package/src/utils/terminal/index.ts +102 -0
- package/src/utils/thumbnailRenderer/consts.ts +2 -0
- package/src/utils/thumbnailRenderer/index.ts +147 -0
- package/src/utils/typedError/index.ts +26 -0
- package/tsconfig.json +31 -0
- package/vitest.config.ts +13 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript interfaces for netplay
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { NetplayCmd, type ConnectionState } from './consts';
|
|
6
|
+
import { createTypedError } from '../utils/typedError';
|
|
7
|
+
|
|
8
|
+
/** Raw netplay command before parsing */
|
|
9
|
+
export interface RawCommand {
|
|
10
|
+
cmd: NetplayCmd;
|
|
11
|
+
payload: Buffer;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Parsed INPUT command.
|
|
16
|
+
*
|
|
17
|
+
* Per RetroArch reference, the INPUT payload contains only frame number, client number,
|
|
18
|
+
* and device input data. Device assignment (which devices a client controls) is
|
|
19
|
+
* determined from the SYNC state, not embedded in INPUT commands.
|
|
20
|
+
*/
|
|
21
|
+
export interface InputCommand {
|
|
22
|
+
cmd: NetplayCmd.INPUT;
|
|
23
|
+
frameNumber: number;
|
|
24
|
+
clientId: number;
|
|
25
|
+
joypadState: number;
|
|
26
|
+
analogLeft?: number;
|
|
27
|
+
analogRight?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Parsed NOINPUT command */
|
|
31
|
+
export interface NoInputCommand {
|
|
32
|
+
cmd: NetplayCmd.NOINPUT;
|
|
33
|
+
frameNumber: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Parsed NICK command */
|
|
37
|
+
export interface NickCommand {
|
|
38
|
+
cmd: NetplayCmd.NICK;
|
|
39
|
+
nickname: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Parsed PASSWORD command */
|
|
43
|
+
export interface PasswordCommand {
|
|
44
|
+
cmd: NetplayCmd.PASSWORD;
|
|
45
|
+
passwordHash: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Parsed INFO command */
|
|
49
|
+
export interface InfoCommand {
|
|
50
|
+
cmd: NetplayCmd.INFO;
|
|
51
|
+
coreName: string;
|
|
52
|
+
coreVersion: string;
|
|
53
|
+
contentCrc: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Parsed SYNC command */
|
|
57
|
+
export interface SyncCommand {
|
|
58
|
+
cmd: NetplayCmd.SYNC;
|
|
59
|
+
frameNumber: number;
|
|
60
|
+
paused: boolean;
|
|
61
|
+
clientNumber: number;
|
|
62
|
+
devices: number[];
|
|
63
|
+
shareModes: number[];
|
|
64
|
+
deviceClients: number[];
|
|
65
|
+
clientNick: string;
|
|
66
|
+
sram: Buffer;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Parsed MODE command */
|
|
70
|
+
export interface ModeCommand {
|
|
71
|
+
cmd: NetplayCmd.MODE;
|
|
72
|
+
frameNumber: number;
|
|
73
|
+
you: boolean;
|
|
74
|
+
playing: boolean;
|
|
75
|
+
slave: boolean;
|
|
76
|
+
clientNumber: number;
|
|
77
|
+
deviceBitmap: number;
|
|
78
|
+
shareModes: number[];
|
|
79
|
+
nick: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Parsed MODE_REFUSED command */
|
|
83
|
+
export interface ModeRefusedCommand {
|
|
84
|
+
cmd: NetplayCmd.MODE_REFUSED;
|
|
85
|
+
reason: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Parsed CRC command */
|
|
89
|
+
export interface CrcCommand {
|
|
90
|
+
cmd: NetplayCmd.CRC;
|
|
91
|
+
frameNumber: number;
|
|
92
|
+
crc: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Parsed LOAD_SAVESTATE command */
|
|
96
|
+
export interface LoadSavestateCommand {
|
|
97
|
+
cmd: NetplayCmd.LOAD_SAVESTATE;
|
|
98
|
+
frameNumber: number;
|
|
99
|
+
uncompressedSize: number;
|
|
100
|
+
state: Buffer;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Parsed PAUSE command */
|
|
104
|
+
export interface PauseCommand {
|
|
105
|
+
cmd: NetplayCmd.PAUSE;
|
|
106
|
+
nickname: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Parsed RESUME command */
|
|
110
|
+
export interface ResumeCommand {
|
|
111
|
+
cmd: NetplayCmd.RESUME;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Parsed STALL command */
|
|
115
|
+
export interface StallCommand {
|
|
116
|
+
cmd: NetplayCmd.STALL;
|
|
117
|
+
frames: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Parsed RESET command */
|
|
121
|
+
export interface ResetCommand {
|
|
122
|
+
cmd: NetplayCmd.RESET;
|
|
123
|
+
frameNumber: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Parsed PLAYER_CHAT command */
|
|
127
|
+
export interface PlayerChatCommand {
|
|
128
|
+
cmd: NetplayCmd.PLAYER_CHAT;
|
|
129
|
+
nickname: string;
|
|
130
|
+
message: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Parsed PING_REQUEST command */
|
|
134
|
+
export interface PingRequestCommand {
|
|
135
|
+
cmd: NetplayCmd.PING_REQUEST;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Parsed PING_RESPONSE command */
|
|
139
|
+
export interface PingResponseCommand {
|
|
140
|
+
cmd: NetplayCmd.PING_RESPONSE;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Parsed ACK command */
|
|
144
|
+
export interface AckCommand {
|
|
145
|
+
cmd: NetplayCmd.ACK;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Parsed NAK command */
|
|
149
|
+
export interface NakCommand {
|
|
150
|
+
cmd: NetplayCmd.NAK;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Parsed DISCONNECT command */
|
|
154
|
+
export interface DisconnectCommand {
|
|
155
|
+
cmd: NetplayCmd.DISCONNECT;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Parsed REQUEST_SAVESTATE command */
|
|
159
|
+
export interface RequestSavestateCommand {
|
|
160
|
+
cmd: NetplayCmd.REQUEST_SAVESTATE;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Parsed SPECTATE command */
|
|
164
|
+
export interface SpectateCommand {
|
|
165
|
+
cmd: NetplayCmd.SPECTATE;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Parsed PLAY command */
|
|
169
|
+
export interface PlayCommand {
|
|
170
|
+
cmd: NetplayCmd.PLAY;
|
|
171
|
+
asSlave: boolean;
|
|
172
|
+
shareMode: number;
|
|
173
|
+
requestedDevices: number;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Setting command (server configuration notifications) */
|
|
177
|
+
export interface SettingCommand {
|
|
178
|
+
cmd: NetplayCmd.SETTING_ALLOW_PAUSING | NetplayCmd.SETTING_INPUT_LATENCY_FRAMES;
|
|
179
|
+
value: number;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Unknown command (for forward compatibility) */
|
|
183
|
+
export interface UnknownCommand {
|
|
184
|
+
cmd: number;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Union of all known parsed commands.
|
|
189
|
+
* Forms a proper discriminated union on the `cmd` field, enabling
|
|
190
|
+
* TypeScript to narrow the type in switch statements.
|
|
191
|
+
*/
|
|
192
|
+
export type KnownCommand =
|
|
193
|
+
| InputCommand
|
|
194
|
+
| NoInputCommand
|
|
195
|
+
| NickCommand
|
|
196
|
+
| PasswordCommand
|
|
197
|
+
| InfoCommand
|
|
198
|
+
| SyncCommand
|
|
199
|
+
| ModeCommand
|
|
200
|
+
| ModeRefusedCommand
|
|
201
|
+
| CrcCommand
|
|
202
|
+
| LoadSavestateCommand
|
|
203
|
+
| PauseCommand
|
|
204
|
+
| ResumeCommand
|
|
205
|
+
| StallCommand
|
|
206
|
+
| ResetCommand
|
|
207
|
+
| PlayerChatCommand
|
|
208
|
+
| PingRequestCommand
|
|
209
|
+
| PingResponseCommand
|
|
210
|
+
| AckCommand
|
|
211
|
+
| NakCommand
|
|
212
|
+
| DisconnectCommand
|
|
213
|
+
| RequestSavestateCommand
|
|
214
|
+
| SpectateCommand
|
|
215
|
+
| PlayCommand
|
|
216
|
+
| SettingCommand;
|
|
217
|
+
|
|
218
|
+
/** Union of all parsed commands, including unknown for forward compatibility */
|
|
219
|
+
export type ParsedCommand = KnownCommand | UnknownCommand;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Known command codes. Used to distinguish known commands from unknown ones
|
|
223
|
+
* at runtime. Uses const enum values (inlined by TypeScript at compile time).
|
|
224
|
+
*/
|
|
225
|
+
const KNOWN_COMMAND_CODES = new Set<number>([
|
|
226
|
+
NetplayCmd.ACK, NetplayCmd.NAK, NetplayCmd.DISCONNECT,
|
|
227
|
+
NetplayCmd.INPUT, NetplayCmd.NOINPUT,
|
|
228
|
+
NetplayCmd.NICK, NetplayCmd.PASSWORD, NetplayCmd.INFO,
|
|
229
|
+
NetplayCmd.SYNC, NetplayCmd.SPECTATE, NetplayCmd.PLAY,
|
|
230
|
+
NetplayCmd.MODE, NetplayCmd.MODE_REFUSED,
|
|
231
|
+
NetplayCmd.CRC, NetplayCmd.REQUEST_SAVESTATE,
|
|
232
|
+
NetplayCmd.LOAD_SAVESTATE, NetplayCmd.PAUSE,
|
|
233
|
+
NetplayCmd.RESUME, NetplayCmd.STALL, NetplayCmd.RESET,
|
|
234
|
+
NetplayCmd.PLAYER_CHAT,
|
|
235
|
+
NetplayCmd.PING_REQUEST, NetplayCmd.PING_RESPONSE,
|
|
236
|
+
NetplayCmd.SETTING_ALLOW_PAUSING,
|
|
237
|
+
NetplayCmd.SETTING_INPUT_LATENCY_FRAMES,
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
/** Type guard to check if a parsed command is a known command type */
|
|
241
|
+
export const isKnownCommand = (cmd: ParsedCommand): cmd is KnownCommand => {
|
|
242
|
+
return KNOWN_COMMAND_CODES.has(cmd.cmd);
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
/** Frame state stored in ring buffer */
|
|
247
|
+
export interface FrameState {
|
|
248
|
+
/** Frame number */
|
|
249
|
+
frameNumber: number;
|
|
250
|
+
/** Serialized core state (may be null if not captured) */
|
|
251
|
+
serializedState: Buffer | null;
|
|
252
|
+
/** Local player input for this frame */
|
|
253
|
+
localInput: number[];
|
|
254
|
+
/** Remote player input (clientId -> input per device) */
|
|
255
|
+
remoteInput: Map<number, number[]>;
|
|
256
|
+
/** Whether remote input is real (vs simulated) */
|
|
257
|
+
remoteInputReal: Map<number, boolean>;
|
|
258
|
+
/** CRC32 of serialized state (for desync detection) */
|
|
259
|
+
crc: number | null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** Per-client connection info */
|
|
263
|
+
export interface ClientInfo {
|
|
264
|
+
/** Unique client ID (0 = server) */
|
|
265
|
+
id: number;
|
|
266
|
+
/** Client nickname */
|
|
267
|
+
nickname: string;
|
|
268
|
+
/** Remote address */
|
|
269
|
+
address: string;
|
|
270
|
+
/** Remote port */
|
|
271
|
+
port: number;
|
|
272
|
+
/** Current connection state */
|
|
273
|
+
state: ConnectionState;
|
|
274
|
+
/** Player number (-1 if spectating) */
|
|
275
|
+
playerNumber: number;
|
|
276
|
+
/** Is this client spectating? */
|
|
277
|
+
spectating: boolean;
|
|
278
|
+
/** Estimated latency in ms */
|
|
279
|
+
latency: number;
|
|
280
|
+
/** Last frame we received from this client */
|
|
281
|
+
lastReceivedFrame: number;
|
|
282
|
+
/** Input devices this client is using */
|
|
283
|
+
devices: number[];
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** Netplay server options */
|
|
287
|
+
export interface NetplayServerOptions {
|
|
288
|
+
/** TCP port to listen on */
|
|
289
|
+
port: number;
|
|
290
|
+
/** Optional password (will be hashed) */
|
|
291
|
+
password?: string;
|
|
292
|
+
/** Require password authentication */
|
|
293
|
+
requirePassword: boolean;
|
|
294
|
+
/** Maximum number of clients */
|
|
295
|
+
maxClients: number;
|
|
296
|
+
/** Input delay frames (0-16) */
|
|
297
|
+
inputDelayFrames: number;
|
|
298
|
+
/** Server nickname */
|
|
299
|
+
nickname: string;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** Netplay client options */
|
|
303
|
+
export interface NetplayClientOptions {
|
|
304
|
+
/** Server hostname or IP */
|
|
305
|
+
host: string;
|
|
306
|
+
/** Server port */
|
|
307
|
+
port: number;
|
|
308
|
+
/** Optional password */
|
|
309
|
+
password?: string;
|
|
310
|
+
/** Client nickname */
|
|
311
|
+
nickname: string;
|
|
312
|
+
/** Input delay frames (0-16) */
|
|
313
|
+
inputDelayFrames: number;
|
|
314
|
+
/** Start as spectator */
|
|
315
|
+
spectate: boolean;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/** Core info for compatibility checking */
|
|
319
|
+
export interface CoreInfo {
|
|
320
|
+
/** Core name (e.g., "bsnes") */
|
|
321
|
+
name: string;
|
|
322
|
+
/** Core version */
|
|
323
|
+
version: string;
|
|
324
|
+
/** Content CRC32 */
|
|
325
|
+
contentCrc: number;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Netplay session state */
|
|
329
|
+
export interface SessionState {
|
|
330
|
+
/** Current frame number */
|
|
331
|
+
frameNumber: number;
|
|
332
|
+
/** Is the game paused? */
|
|
333
|
+
paused: boolean;
|
|
334
|
+
/** Who paused (nickname) */
|
|
335
|
+
pausedBy: string | null;
|
|
336
|
+
/** Connected players bitmap */
|
|
337
|
+
connectedPlayers: number;
|
|
338
|
+
/** Our client ID */
|
|
339
|
+
localClientId: number;
|
|
340
|
+
/** Our player number (-1 if spectating) */
|
|
341
|
+
localPlayerNumber: number;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** Netplay statistics */
|
|
345
|
+
export interface NetplayStats {
|
|
346
|
+
/** Round-trip time in ms */
|
|
347
|
+
rtt: number;
|
|
348
|
+
/** Frames behind remote */
|
|
349
|
+
framesBehind: number;
|
|
350
|
+
/** Number of rollbacks performed */
|
|
351
|
+
rollbackCount: number;
|
|
352
|
+
/** Average rollback depth (frames) */
|
|
353
|
+
avgRollbackDepth: number;
|
|
354
|
+
/** Bytes sent */
|
|
355
|
+
bytesSent: number;
|
|
356
|
+
/** Bytes received */
|
|
357
|
+
bytesReceived: number;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/** Events emitted by netplay server/client */
|
|
361
|
+
export interface NetplayEvents {
|
|
362
|
+
/** Client connected (server only) */
|
|
363
|
+
'client-connected': (client: ClientInfo) => void;
|
|
364
|
+
/** Client disconnected */
|
|
365
|
+
'client-disconnected': (client: ClientInfo, reason: string) => void;
|
|
366
|
+
/** Connected to server (client only) */
|
|
367
|
+
connected: () => void;
|
|
368
|
+
/** Disconnected from server (client only) */
|
|
369
|
+
disconnected: (reason: string) => void;
|
|
370
|
+
/** Desync detected */
|
|
371
|
+
desync: (frameNumber: number, localCrc: number, remoteCrc: number) => void;
|
|
372
|
+
/** Rollback performed */
|
|
373
|
+
rollback: (frames: number) => void;
|
|
374
|
+
/** Mode changed (play/spectate) */
|
|
375
|
+
'mode-changed': (playing: boolean, playerNumber: number) => void;
|
|
376
|
+
/** Game paused */
|
|
377
|
+
paused: (by: string) => void;
|
|
378
|
+
/** Game resumed */
|
|
379
|
+
resumed: () => void;
|
|
380
|
+
/** Chat message received */
|
|
381
|
+
chat: (from: string, message: string) => void;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Netplay error codes */
|
|
385
|
+
export type NetplayErrorCode =
|
|
386
|
+
| 'ALREADY_CONNECTED'
|
|
387
|
+
| 'ALREADY_RUNNING'
|
|
388
|
+
| 'ALREADY_ACTIVE'
|
|
389
|
+
| 'INVALID_HEADER'
|
|
390
|
+
| 'NO_HOSTS_FOUND';
|
|
391
|
+
|
|
392
|
+
const { TypedError: NetplayErrorClass, isTypedError: isNetplayErrorGuard } = createTypedError<NetplayErrorCode>('NetplayError');
|
|
393
|
+
export const NetplayError = NetplayErrorClass;
|
|
394
|
+
export type NetplayError = InstanceType<typeof NetplayErrorClass>;
|
|
395
|
+
export const isNetplayError = isNetplayErrorGuard;
|