int32 GetPortFromNetDriver(FName InstanceName) { int32 Port = 0; #if WITH_ENGINE if (GEngine) { UWorld* World = GetWorldForOnline(InstanceName); UNetDriver* NetDriver = World ? GEngine->FindNamedNetDriver(World, NAME_GameNetDriver) : NULL; if (NetDriver && NetDriver->GetNetMode() < NM_Client) { FString AddressStr = NetDriver->LowLevelGetNetworkNumber(); int32 Colon = AddressStr.Find(":", ESearchCase::IgnoreCase, ESearchDir::FromEnd); if (Colon != INDEX_NONE) { FString PortStr = AddressStr.Mid(Colon + 1); if (!PortStr.IsEmpty()) { Port = FCString::Atoi(*PortStr); } } } } #endif return Port; }
float UGameEngine::GetMaxTickRate(float DeltaTime, bool bAllowFrameRateSmoothing) const { float MaxTickRate = 0.f; if (FPlatformProperties::SupportsWindowedMode() == false && !IsRunningDedicatedServer()) { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VSync")); // Limit framerate on console if VSYNC is enabled to avoid jumps from 30 to 60 and back. if( CVar->GetValueOnGameThread() != 0 ) { if (SmoothedFrameRateRange.HasUpperBound()) { MaxTickRate = SmoothedFrameRateRange.GetUpperBoundValue(); } } } else { UWorld* World = NULL; for (int32 WorldIndex = 0; WorldIndex < WorldList.Num(); ++WorldIndex) { if (WorldList[WorldIndex].WorldType == EWorldType::Game) { World = WorldList[WorldIndex].World(); break; } } if( World ) { UNetDriver* NetDriver = World->GetNetDriver(); // In network games, limit framerate to not saturate bandwidth. if( NetDriver && (NetDriver->GetNetMode() == NM_DedicatedServer || (NetDriver->GetNetMode() == NM_ListenServer && NetDriver->bClampListenServerTickRate))) { // We're a dedicated server, use the LAN or Net tick rate. MaxTickRate = FMath::Clamp( NetDriver->NetServerMaxTickRate, 10, 120 ); } /*else if( NetDriver && NetDriver->ServerConnection ) { if( NetDriver->ServerConnection->CurrentNetSpeed <= 10000 ) { MaxTickRate = FMath::Clamp( MaxTickRate, 10.f, 90.f ); } }*/ } } // See if the code in the base class wants to replace this float SuperTickRate = Super::GetMaxTickRate(DeltaTime, bAllowFrameRateSmoothing); if(SuperTickRate != 0.0) { MaxTickRate = SuperTickRate; } return MaxTickRate; }
void UShooterEngine::HandleNetworkFailure(UWorld *World, UNetDriver *NetDriver, ENetworkFailure::Type FailureType, const FString& ErrorString) { // Determine if we need to change the King state based on network failures. // Only handle failure at this level for game or pending net drivers. FName NetDriverName = NetDriver ? NetDriver->NetDriverName : NAME_None; if (NetDriverName == NAME_GameNetDriver || NetDriverName == NAME_PendingNetDriver) { // If this net driver has already been unregistered with this world, then don't handle it. if (World) { UNetDriver * NetDriver = FindNamedNetDriver(World, NetDriverName); if (NetDriver) { bool bGoBackToMain = false; ENetMode FailureNetMode = NetDriver->GetNetMode(); // NetMode of the driver that failed switch (FailureType) { case ENetworkFailure::FailureReceived: break; case ENetworkFailure::PendingConnectionFailure: break; case ENetworkFailure::ConnectionLost: case ENetworkFailure::ConnectionTimeout: // only clients need to bail back to main if they lost connection bGoBackToMain = (FailureNetMode == NM_Client); break; case ENetworkFailure::NetDriverAlreadyExists: case ENetworkFailure::NetDriverCreateFailure: case ENetworkFailure::OutdatedClient: case ENetworkFailure::OutdatedServer: default: break; } if (bGoBackToMain) { UShooterGameInstance* const GI = Cast<UShooterGameInstance>(GameInstance); if (GI) { const FString ReturnReason = NSLOCTEXT( "NetworkErrors", "HostDisconnect", "Lost connection to host." ).ToString(); const FString OKButton = NSLOCTEXT( "DialogButtons", "OKAY", "OK" ).ToString(); GI->ShowMessageThenGotoState( ReturnReason, OKButton, FString(), ShooterGameInstanceState::MainMenu ); } } } } } // standard failure handling. Super::HandleNetworkFailure(World, NetDriver, FailureType, ErrorString); }
bool UActorComponent::CallRemoteFunction( UFunction* Function, void* Parameters, FOutParmRec* OutParms, FFrame* Stack ) { if (AActor* MyOwner = GetOwner()) { UNetDriver* NetDriver = MyOwner->GetNetDriver(); if (NetDriver) { NetDriver->ProcessRemoteFunction(MyOwner, Function, Parameters, OutParms, Stack, this); return true; } } return false; }
bool UGAAbilityBase::CallRemoteFunction(UFunction* Function, void* Parameters, FOutParmRec* OutParms, FFrame* Stack) { check(!HasAnyFlags(RF_ClassDefaultObject)); check(POwner != NULL); UNetDriver* NetDriver = POwner->GetNetDriver(); if (NetDriver) { NetDriver->ProcessRemoteFunction(POwner, Function, Parameters, OutParms, Stack, this); return true; } return false; }
bool UGameplayAbility::CallRemoteFunction(UFunction* Function, void* Parameters, FOutParmRec* OutParms, FFrame* Stack) { check(!HasAnyFlags(RF_ClassDefaultObject)); check(GetOuter() != NULL); AActor* Owner = CastChecked<AActor>(GetOuter()); UNetDriver* NetDriver = Owner->GetNetDriver(); if (NetDriver) { NetDriver->ProcessRemoteFunction(Owner, Function, Parameters, OutParms, Stack, this); return true; } return false; }
bool UActorComponent::CallRemoteFunction( UFunction* Function, void* Parameters, FFrame* Stack ) { AActor* Owner = GetOwner(); if (Owner == NULL) { return false; } UNetDriver* NetDriver = Owner->GetNetDriver(); if (NetDriver) { NetDriver->ProcessRemoteFunction(Owner, Function, Parameters, Stack, this); return true; } return false; }
bool NUTNet::IsSteamNetDriverAvailable() { bool bReturnVal = false; UGameEngine* GameEngine = Cast<UGameEngine>(GEngine); if (GameEngine != NULL) { bool bFoundSteamDriver = false; const TCHAR* SteamDriverClassName = TEXT("OnlineSubsystemSteam.SteamNetDriver"); for (int i=0; i<GameEngine->NetDriverDefinitions.Num(); i++) { if (GameEngine->NetDriverDefinitions[i].DefName == NAME_GameNetDriver) { if (GameEngine->NetDriverDefinitions[i].DriverClassName == SteamDriverClassName) { bFoundSteamDriver = true; } break; } } if (bFoundSteamDriver) { UClass* SteamNetDriverClass = StaticLoadClass(UNetDriver::StaticClass(), NULL, SteamDriverClassName, NULL, LOAD_Quiet); if (SteamDriverClassName != NULL) { UNetDriver* SteamNetDriverDef = Cast<UNetDriver>(SteamNetDriverClass->GetDefaultObject()); bReturnVal = SteamNetDriverDef != NULL && SteamNetDriverDef->IsAvailable(); } } } return bReturnVal; }
/** * Removes the actor from its level's actor list and generally cleans up the engine's internal state. * What this function does not do, but is handled via garbage collection instead, is remove references * to this actor from all other actors, and kill the actor's resources. This function is set up so that * no problems occur even if the actor is being destroyed inside its recursion stack. * * @param ThisActor Actor to remove. * @param bNetForce [opt] Ignored unless called during play. Default is false. * @param bShouldModifyLevel [opt] If true, Modify() the level before removing the actor. Default is true. * @return true if destroy, false if actor couldn't be destroyed. */ bool UWorld::DestroyActor( AActor* ThisActor, bool bNetForce, bool bShouldModifyLevel ) { check(ThisActor); check(ThisActor->IsValidLowLevel()); //UE_LOG(LogSpawn, Log, "Destroy %s", *ThisActor->GetClass()->GetName() ); if (ThisActor->GetWorld() == NULL) { UE_LOG(LogSpawn, Warning, TEXT("Destroying %s, which doesn't have a valid world pointer"), *ThisActor->GetPathName()); } // If already on list to be deleted, pretend the call was successful. // We don't want recursive calls to trigger destruction notifications multiple times. if (ThisActor->IsPendingKillPending()) { return true; } // In-game deletion rules. if( IsGameWorld() ) { // Never destroy the world settings actor. This used to be enforced by bNoDelete and is actually needed for // seamless travel and network games. if (GetWorldSettings() == ThisActor) { return false; } // Can't kill if wrong role. if( ThisActor->Role!=ROLE_Authority && !bNetForce && !ThisActor->bNetTemporary ) { return false; } // Don't destroy player actors. APlayerController* PC = Cast<APlayerController>(ThisActor); if ( PC ) { UNetConnection* C = Cast<UNetConnection>(PC->Player); if( C ) { if( C->Channels[0] && C->State!=USOCK_Closed ) { C->bPendingDestroy = true; C->Channels[0]->Close(); } return false; } } } else { ThisActor->Modify(); } // Prevent recursion //FMarkActorIsBeingDestroyed MarkActorIsBeingDestroyed(ThisActor); // Notify the texture streaming manager about the destruction of this actor. IStreamingManager::Get().NotifyActorDestroyed( ThisActor ); // Tell this actor it's about to be destroyed. ThisActor->Destroyed(); // Detach this actor's children TArray<AActor*> AttachedActors; ThisActor->GetAttachedActors(AttachedActors); if (AttachedActors.Num() > 0) { TInlineComponentArray<USceneComponent*> SceneComponents; ThisActor->GetComponents(SceneComponents); for (TArray< AActor* >::TConstIterator AttachedActorIt(AttachedActors); AttachedActorIt; ++AttachedActorIt) { AActor* ChildActor = *AttachedActorIt; if (ChildActor != NULL) { for (auto SceneCompIter = SceneComponents.CreateIterator(); SceneCompIter; ++SceneCompIter) { ChildActor->DetachSceneComponentsFromParent(*SceneCompIter, true); } #if WITH_EDITOR if( GIsEditor ) { GEngine->BroadcastLevelActorDetached(ChildActor, ThisActor); } #endif } } } // Detach from anything we were attached to USceneComponent* RootComp = ThisActor->GetRootComponent(); if( RootComp != NULL && RootComp->AttachParent != NULL) { AActor* OldParentActor = RootComp->AttachParent->GetOwner(); if (OldParentActor) { OldParentActor->Modify(); } ThisActor->DetachRootComponentFromParent(); #if WITH_EDITOR if( GIsEditor ) { GEngine->BroadcastLevelActorDetached(ThisActor, OldParentActor); } #endif } ThisActor->ClearComponentOverlaps(); // If this actor has an owner, notify it that it has lost a child. if( ThisActor->GetOwner() ) { ThisActor->SetOwner(NULL); } // Notify net players that this guy has been destroyed. UNetDriver* ActorNetDriver = GEngine->FindNamedNetDriver(this, ThisActor->NetDriverName); if (ActorNetDriver) { ActorNetDriver->NotifyActorDestroyed(ThisActor); } if ( DemoNetDriver ) { DemoNetDriver->NotifyActorDestroyed( ThisActor ); } // Remove the actor from the actor list. RemoveActor( ThisActor, bShouldModifyLevel ); // Invalidate the lighting cache in the Editor. We need to check for GIsEditor as play has not begun in network game and objects get destroyed on switching levels if ( GIsEditor ) { ThisActor->InvalidateLightingCache(); #if WITH_EDITOR GEngine->BroadcastLevelActorDeleted(ThisActor); #endif } // Clean up the actor's components. ThisActor->UnregisterAllComponents(); // Mark the actor and its direct components as pending kill. ThisActor->MarkPendingKill(); ThisActor->MarkPackageDirty(); ThisActor->MarkComponentsAsPendingKill(); // Unregister the actor's tick function const bool bRegisterTickFunctions = false; const bool bIncludeComponents = true; ThisActor->RegisterAllActorTickFunctions(bRegisterTickFunctions, bIncludeComponents); // Return success. return true; }