Ctrl K
ComunidadGuías…

ParadoxRuntime/Networking.h

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/*
 * Original work Copyright (C) 2026 gwog :3 (SyST3MDeV/Undaunted)
 * Modified work Copyright (C) 2026 MysticFox / Pranav Karande (pranav158/Mystic-Paradox)
 *
 * Licensed under the GNU Affero General Public License v3.0.
 * You may obtain a copy of the License at the root of this repository.
 *
 * SPDX-License-Identifier: AGPL-3.0-only
 * Additional terms under AGPLv3 Section 7 apply. See ADDITIONAL_TERMS.md.
 */

#pragma once

#include <Windows.h>
#include "SDK.hpp"

using namespace SDK;

namespace Networking {
	extern UNetDriver* NetDriver;

	// Returns true only after InitListen succeeds and, in player-hosted mode, the
	// launcher has accepted the structured readiness message over its private pipe.
	bool Listen(UEngine* Engine, int Port);

	// [1.14.7 2026-10-03] Emit the exact MYSTICPARADOX_GAMESERVER_READY marker the DeployServer waits for,
	// for the case where the ENGINE created the listener itself (map URL carries ?listen) instead of
	// this module creating the NetDriver by hand. The manual path leaves the world context invalid on
	// 1.14.7 ("WorldContext requested with invalid context object" x28 per run), so the engine path is
	// preferred; readiness is still announced only once a listener actually exists.
	void AnnounceEngineReady(int Port);

	void TickNetworking();

	// [2026-07-25 PLAYER-ROLE PUSH DIAGNOSIS]
	// UActorChannel::ReplicateActor (1.12 RVA 0x03B7B470) can report "wrote nothing" for two very
	// different reasons, and the old bare wroteData=0 log could not tell them apart:
	//   (a) it never got to try - it returns immediately, before touching any property, when
	//       bPendingDormancy is set and the connection is not replaying, or when it is already
	//       replicating this same actor further up the stack;
	//   (b) it ran fully and neither ReplicateProperties nor ReplicateSubobjects had dirty state.
	// (a) means "retry later", (b) means "nothing to send". Treating them alike is why the
	// post-activation refresh burned its 3-attempt budget in 4.5s and declared EXHAUSTED.
	//
	// Offsets read off the 1.12 binary in Ghidra (ReplicateActor prologue):
	//   UActorChannel + 0x30 bit 0x100 = bPendingDormancy        (`*(uint*)(param_1+6)  >> 8 & 1`)
	//   UActorChannel + 0x90 bit 0x004 = bIsReplicatingActor     (`*(uint*)(param_1+0x12) & 4`)
	//   UChannel      + 0x28           = Connection              (`param_1[5]`)
	//   UNetConnection+ 0x1510         = ResendAllDataState       (`*(char*)(param_1[5]+0x1510)`)
	struct ActorChannelPushDiag {
		void* Channel = nullptr;
		bool  ExistingChannel = false;
		bool  WroteData = false;
		bool  PendingDormancy = false;
		bool  ReplicatingReentrant = false;
		int   ResendAllDataState = -1;
		bool  Valid = false;

		// The channel state made a write impossible this frame, independent of dirty properties.
		bool Blocked() const { return Valid && (PendingDormancy || ReplicatingReentrant); }
	};

	// Creates and emits the initial actor channel for a single actor/connection pair. This is a
	// narrowly-scoped bootstrap for dynamically-created owner equipment that has already been routed
	// into the native RepGraph but did not receive an initial channel. Ongoing replication remains
	// owned by the graph. OutDiag is optional and purely observational.
	int BootstrapActorChannel(AActor* Actor, UNetConnection* Connection,
	                          ActorChannelPushDiag* OutDiag = nullptr);

	// [2026-07-25 OMNICELL CHANNEL CHURN] Read-only probe: does an open UActorChannel currently
	// exist for this actor on this connection, and if so what is its ChIndex?
	//
	// Repro 10 established that the server's AArchonPlayerRole actors are STABLE - two pointers
	// (PR_ICEBORNE 1823233038128, PR_TEMPEST 1825136038496) for the entire match - while both
	// clients minted a brand new role UObject every few seconds:
	//   21:03:33.570 role=2152964842720   21:03:36.180 role=2152969074400
	//   21:03:57.635 role=2153085740288   21:04:00.402 role=2152938156720
	// every one of them arriving with gameplayEquipped=0 roleActive=0 bpEquipCalled=0. A client
	// minting a new object for a stable server actor means the actor channel closed and reopened -
	// each reopen is a fresh NetGUID->object resolve, and the HUD binds/unbinds with it. That is
	// the omnicell flicker.
	//
	// Polling channel presence per (role, connection) and logging only the transitions tells us
	// exactly when the channel drops, which is the half we have never been able to see. Returns the
	// ChIndex when a channel exists, -1 when it does not, -2 when the inputs are unusable.
	int GetActorChannelIndexForConnection(AActor* Actor, UNetConnection* Connection);
}