diff --git a/include/externs.inc b/include/externs.inc index 2ab3f9d..1cfeb26 100644 --- a/include/externs.inc +++ b/include/externs.inc @@ -136,6 +136,7 @@ EXTERNDEF Hooks_InitNetworkHooks :PROC ; ufunctionhooks.asm - UFunction dispatch hooks EXTERNDEF UFunctionHooks_Initialize :PROC +EXTERNDEF Server_Initialize :PROC EXTERNDEF UFunctionHooks_ToHook_Data :QWORD ; base of UFunction* array EXTERNDEF UFunctionHooks_ToHook_Num :DWORD ; count of registered hooks EXTERNDEF UFunctionHooks_ToCall_Data :QWORD ; base of handler QWORD* array (BYTE (*)(UObject*,void*)) diff --git a/logger.asm b/logger.asm index ddaaa71..c092b43 100644 --- a/logger.asm +++ b/logger.asm @@ -51,8 +51,8 @@ Logger_hFile QWORD ? Logger_Initialize PROC sub rsp, 148h - ; GetModuleFileNameA(NULL, &path, MAX_PATH) → EAX = length - xor ecx, ecx ; hModule = NULL → host EXE + ; GetModuleFileNameA(NULL, &path, MAX_PATH) -> EAX = length + xor ecx, ecx ; hModule = NULL -> host EXE lea rdx, [rsp+38h] ; path buffer mov r8d, 104h ; MAX_PATH = 260 call GetModuleFileNameA diff --git a/native.asm b/native.asm index ba800a9..46c13c6 100644 --- a/native.asm +++ b/native.asm @@ -31,11 +31,11 @@ ENDIF Native_InitializeAll PROC push rbp push rbx - sub rsp, 40 ; shadow space; RSP ≡ 0 mod 16 at all CALLs + sub rsp, 40 ; shadow space; RSP = 0 mod 16 at all CALLs LOG_DBG szNatDbg_Start - xor ecx, ecx ; lpModuleName = NULL → returns base of .exe + xor ecx, ecx ; lpModuleName = NULL -> returns base of .exe call GetModuleHandleA mov QWORD PTR [Imagebase], rax @@ -150,7 +150,7 @@ Native_InitializeAll PROC xor r8d, r8d call Utils_FindPattern mov QWORD PTR [Native_OnlineBeacon_PauseBeaconRequests], rax - ; Also store in the host-specific slot — same function pointer + ; Also store in the host-specific slot - same function pointer mov QWORD PTR [Native_OnlineBeaconHost_PauseBeaconRequests], rax ; OnlineBeacon::NotifyAcceptingConnection (direct) diff --git a/raider.asm b/raider.asm index eb77928..09d93e9 100644 --- a/raider.asm +++ b/raider.asm @@ -20,6 +20,8 @@ szDbgAtchProcEvent DB "[DEBUG] Attached Hooks_ProcessEventHook", 0 szDbgAtchViewPt DB "[DEBUG] Attached Hooks_GetPlayerViewPoint", 0 szDbgDetourCommit DB "[DEBUG] Detours transaction committed", 0 szDbgConsoleCreated DB "[DEBUG] SDK console created", 0 +szDbgServerInit DB "[DEBUG] Server_Initialize starting", 0 +szDbgServerDone DB "[DEBUG] Server_Initialize complete", 0 ENDIF .data @@ -117,6 +119,10 @@ Main PROC call SDK_CreateConsole LOG_DBG szDbgConsoleCreated + LOG_DBG szDbgServerInit + call Server_Initialize + LOG_DBG szDbgServerDone + xor eax, eax ; return 0 (DWORD thread exit code) @@main_exit: diff --git a/ufunctionhooks.asm b/ufunctionhooks.asm index a6443a0..b0b36e6 100644 --- a/ufunctionhooks.asm +++ b/ufunctionhooks.asm @@ -72,7 +72,6 @@ szFn_ServerExecuteInventoryItem DB "Function FortniteGame.FortPlayerControll szFn_ServerReturnToMainMenu DB "Function FortniteGame.FortPlayerController.ServerReturnToMainMenu", 0 szFn_ServerLoadingScreenDropped DB "Function FortniteGame.FortPlayerController.ServerLoadingScreenDropped", 0 szFn_ServerChoosePart DB "Function FortniteGame.FortPlayerControllerCommon.ServerChoosePart", 0 -szFn_ReadyToStartMatch DB "Function FortniteGame.FortGameModeAthena.ReadyToStartMatch", 0 szFn_OnAircraftExitedDropZone DB "Function FortniteGame.FortAthenaAircraft.OnAircraftExitedDropZone", 0 szFn_ServerCheatAll DB "Function FortniteGame.FortGameModeAthena.ServerCheatAll", 0 szFn_Logout DB "Function FortniteGame.FortGameModeAthena.Logout", 0 @@ -1172,15 +1171,23 @@ PEHOOK_ServerEditBuildingActor PROC ret PEHOOK_ServerEditBuildingActor ENDP -; PEHOOK_ReadyToStartMatch - set up full listen-server infrastructure -; RCX = AFortGameModeAthena* (GameMode) +; Server_Initialize - set up full listen-server infrastructure +; Called directly from raider.asm Main after DetourTransactionCommit. +; No arguments; no return value. ; -; Stack: push rbp,rbx,rsi,rdi,r12,r13,r14 = 7 pushes (RSP=0); sub 80 -> 0 -; [rsp+0..31] = shadow -; [rsp+32..79] = FURL struct (0x70 = 112 bytes)... actually needs sub 128 = 0 -; With 7 pushes: RSP=0; sub 128(=0) -> 0 -; FURL at [rsp+32..143] -PEHOOK_ReadyToStartMatch PROC +; Sequence: +; 1. Guard bListening - skip if already listening +; 2. Game_OnReadyToStartMatch() +; 3. Spawn AFortOnlineBeaconHost -> HostBeacon +; 4. Set ListenPort=7776 + InitHost +; 5. Zero-init FURL on stack (port 7777) +; 6. Resolve ServerReplicateActors from ReplicationDriver vtable slot 0x53 +; 7. PauseBeaconRequests(false), bListening=true +; +; Stack: 7 pushes (56) -> entry RSP=8; after 7 odd pushes RSP=0; sub128(=0) -> 0 +; [rsp+0..31] = shadow +; [rsp+32..143] = FURL local struct (112 bytes) +Server_Initialize PROC push rbp push rbx push rsi @@ -1188,10 +1195,7 @@ PEHOOK_ReadyToStartMatch PROC push r12 push r13 push r14 - sub rsp, 128 ; 7 pushes: RSP=0; sub128(=0) -> 0 - ; [rsp+32..143] = FURL local - - mov rbx, rcx ; GameMode + sub rsp, 128 ; Guard: already listening? movzx eax, BYTE PTR [bListening] @@ -1212,20 +1216,18 @@ PEHOOK_ReadyToStartMatch PROC test rax, rax jz @@net_setup - ; SpawnActor - use world + class + null transform + default flags call SDK_GetWorld test rax, rax jz @@net_setup - mov r12, rax ; World mov rcx, QWORD PTR [pClass_FortOnlineBeaconHost] - xor edx, edx ; Location = null (use zero) + xor edx, edx ; Location = null (zero origin) xor r8d, r8d ; Owner = null - call Spawners_SpawnActor ; Phase 10 will fill this + call Spawners_SpawnActor test rax, rax jz @@net_setup - mov r13, rax ; r13 = HostBeacon + mov r13, rax mov QWORD PTR [HostBeacon], r13 ; Set ListenPort = 7776 @@ -1236,40 +1238,36 @@ PEHOOK_ReadyToStartMatch PROC call QWORD PTR [Native_OnlineBeaconHost_InitHost] @@net_setup: - ; Init World NetDriver on port 7777 - ; Build minimal FURL on stack: zero-init [rsp+32..143], set Port=7777 + ; Zero-init FURL on stack, set Port=7777 lea rcx, [rsp + 32] xor edx, edx mov r8d, 112 ; sizeof(FURL) = 0x70 call RtlZeroMemory - mov DWORD PTR [rsp + 32 + FURL_Port], LISTEN_GAME_PORT ; FURL::Port at +0x20 + mov DWORD PTR [rsp + 32 + FURL_Port], LISTEN_GAME_PORT ; Resolve ServerReplicateActors from ReplicationDriver vtable[0x53] call SDK_GetWorld test rax, rax jz @@final_setup - mov rax, QWORD PTR [rax + UWORLD_NetDriver] ; World->NetDriver + mov rax, QWORD PTR [rax + UWORLD_NetDriver] test rax, rax jz @@final_setup - mov rax, QWORD PTR [rax + UNETDRIVER_ReplDriver] ; NetDriver->ReplicationDriver + mov rax, QWORD PTR [rax + UNETDRIVER_ReplDriver] test rax, rax jz @@final_setup - mov r14, rax ; r14 = ReplicationDriver - mov rax, QWORD PTR [r14] ; vtable ptr - mov rax, QWORD PTR [rax + VTABLE_ServerReplicateActors] ; slot 0x53 + mov r14, rax + mov rax, QWORD PTR [r14] + mov rax, QWORD PTR [rax + VTABLE_ServerReplicateActors] mov QWORD PTR [Native_ReplicationDriver_ServerReplicateActors], rax - ; ClassRepNodePolicies is a TMap at RepDriver+0x3B8. - ; Populating it requires iterating registered actor classes; deferred to game-specific setup. - @@final_setup: - ; PauseBeaconRequests(false) if beacon was spawned + ; PauseBeaconRequests(false), mark listening mov rax, QWORD PTR [HostBeacon] test rax, rax jz @@set_listening mov rcx, rax - xor edx, edx ; false = don't pause + xor edx, edx call QWORD PTR [Native_OnlineBeacon_PauseBeaconRequests] @@set_listening: @@ -1284,9 +1282,8 @@ PEHOOK_ReadyToStartMatch PROC pop rsi pop rbx pop rbp - xor al, al ret -PEHOOK_ReadyToStartMatch ENDP +Server_Initialize ENDP ; UFunctionHooks_Initialize ; Resolves all 27 UFunction* pointers and fills the ToHook + ToCall arrays. @@ -1298,7 +1295,7 @@ PEHOOK_ReadyToStartMatch ENDP ; ; Stack: push rbp,rbx,rsi,rdi,r12 = 5 pushes (RSP=8); sub 40(=8) -> 0 -; Helper macro-equivalent - inline for each registration: +; Helper macro-equivalent — inline for each registration: ; REGISTER rcx=szFnName, handler_label ; lea rcx, szFn_X ; call SDK_FindObject @@ -1315,9 +1312,10 @@ UFunctionHooks_Initialize PROC push rsi push rdi push r12 - sub rsp, 40 ; 5 pushes: RSP=8; sub40 -> 0 + sub rsp, 48 ; 5 pushes: entry RSP=8 -> after pushes RSP=0; sub48(=0) -> 0 LOG_DBG szUFDbg_Start + ; Set public pointers to internal storage lea rax, _ToHook_Storage mov QWORD PTR [UFunctionHooks_ToHook_Data], rax @@ -1349,7 +1347,7 @@ UFunctionHooks_Initialize PROC mov QWORD PTR [rdi + rbp * 8], rax inc ebp @@r2: - ; 3. ServerAbilityRPCBatch + ; ServerAbilityRPCBatch lea rcx, szFn_ServerAbilityRPCBatch call SDK_FindObject test rax, rax @@ -1539,7 +1537,7 @@ UFunctionHooks_Initialize PROC mov QWORD PTR [rdi + rbp * 8], rax inc ebp @@r21: - ; 22. ServerLoadingScreenDropped + ; ServerLoadingScreenDropped lea rcx, szFn_ServerLoadingScreenDropped call SDK_FindObject test rax, rax @@ -1549,7 +1547,7 @@ UFunctionHooks_Initialize PROC mov QWORD PTR [rdi + rbp * 8], rax inc ebp @@r22: - ; 23. ServerChoosePart + ; ServerChoosePart lea rcx, szFn_ServerChoosePart call SDK_FindObject test rax, rax @@ -1559,17 +1557,9 @@ UFunctionHooks_Initialize PROC mov QWORD PTR [rdi + rbp * 8], rax inc ebp @@r23: - ; ReadyToStartMatch - lea rcx, szFn_ReadyToStartMatch - call SDK_FindObject - test rax, rax - jz @@r24 - mov QWORD PTR [rsi + rbp * 8], rax - lea rax, PEHOOK_ReadyToStartMatch - mov QWORD PTR [rdi + rbp * 8], rax - inc ebp -@@r24: - ; OnAircraftExitedDropZone + ; ---- 24 (renumbered). OnAircraftExitedDropZone ---- + ; NOTE: ReadyToStartMatch removed — server init now called directly + ; via Server_Initialize from raider.asm Main after Detours commit. lea rcx, szFn_OnAircraftExitedDropZone call SDK_FindObject test rax, rax @@ -1613,7 +1603,7 @@ UFunctionHooks_Initialize PROC mov edx, ebp call Logger_LogInfoFmt - add rsp, 40 + add rsp, 48 pop r12 pop rdi pop rsi diff --git a/zeroinput.asm b/zeroinput.asm index 9c28679..3c835c4 100644 --- a/zeroinput.asm +++ b/zeroinput.asm @@ -52,14 +52,14 @@ ZeroInput_IsMouseClicked PROC ; Check mouseDown[button] mov eax, ecx ; button index (zero-extends rax) - lea rcx, [ZI_mouseDown] ; RIP-relative base → rcx + lea rcx, [ZI_mouseDown] ; RIP-relative base -> rcx movzx eax, BYTE PTR [rcx + rax] ; mouseDown[button] test al, al jz @@clear_already ; not pressed -> clear + return false ; mouseDown[button] is set - check mouseDownAlready[element_id] mov ecx, edx ; element_id (zero-extends rcx) - lea rax, [ZI_mouseDownAlready] ; RIP-relative base → rax + lea rax, [ZI_mouseDownAlready] ; RIP-relative base -> rax movzx eax, BYTE PTR [rax + rcx] ; mouseDownAlready[element_id] test al, al jnz @@check_repeat ; already marked -> check repeat @@ -96,12 +96,12 @@ ZeroInput_IsKeyPressed PROC sub rsp, 28h mov r9d, ecx ; save key index (zero-extends r9) - lea rcx, [ZI_keysDown] ; RIP-relative base → rcx + lea rcx, [ZI_keysDown] ; RIP-relative base -> rcx movzx eax, BYTE PTR [rcx + r9] ; keysDown[key] test al, al jz @@clear_already - lea rax, [ZI_keysDownAlready] ; RIP-relative base → rax + lea rax, [ZI_keysDownAlready] ; RIP-relative base -> rax movzx eax, BYTE PTR [rax + r9] ; keysDownAlready[key] test al, al jnz @@check_repeat