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;
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
/**
 * 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;
}