FPreviewScene::FPreviewScene(FPreviewScene::ConstructionValues CVS) : PreviewWorld(NULL) , bForceAllUsedMipsResident(CVS.bForceMipsResident) { PreviewWorld = NewObject<UWorld>(); PreviewWorld->WorldType = EWorldType::Preview; if (CVS.bTransactional) { PreviewWorld->SetFlags(RF_Transactional); } FWorldContext& WorldContext = GEngine->CreateNewWorldContext(EWorldType::Preview); WorldContext.SetCurrentWorld(PreviewWorld); PreviewWorld->InitializeNewWorld(UWorld::InitializationValues() .AllowAudioPlayback(CVS.bAllowAudioPlayback) .CreatePhysicsScene(CVS.bCreatePhysicsScene) .RequiresHitProxies(false) .CreateNavigation(false) .CreateAISystem(false) .ShouldSimulatePhysics(CVS.bShouldSimulatePhysics) .SetTransactional(CVS.bTransactional)); PreviewWorld->InitializeActorsForPlay(FURL()); GetScene()->UpdateDynamicSkyLight(FLinearColor::White * CVS.SkyBrightness, FLinearColor::Black); DirectionalLight = NewObject<UDirectionalLightComponent>(GetTransientPackage()); DirectionalLight->Intensity = CVS.LightBrightness; DirectionalLight->LightColor = FColor::White; AddComponent(DirectionalLight, FTransform(CVS.LightRotation)); LineBatcher = NewObject<ULineBatchComponent>(GetTransientPackage()); AddComponent(LineBatcher, FTransform::Identity); }
void FLiveEditorManager::CreateLiveEditorWorld() { LiveEditorWorld = NewObject<UWorld>(); LiveEditorWorld->SetFlags(RF_Transactional); LiveEditorWorld->WorldType = EWorldType::Preview; bool bTransactional = false; if (!bTransactional) { LiveEditorWorld->ClearFlags(RF_Transactional); } FWorldContext& WorldContext = GEngine->CreateNewWorldContext(EWorldType::Preview); WorldContext.SetCurrentWorld(LiveEditorWorld); LiveEditorWorld->InitializeNewWorld(UWorld::InitializationValues() .AllowAudioPlayback(true) .CreatePhysicsScene(false) .RequiresHitProxies(false) .CreateNavigation(false) .CreateAISystem(false) .ShouldSimulatePhysics(false) .SetTransactional(bTransactional)); LiveEditorWorld->InitializeActorsForPlay(FURL()); }
void UGameInstance::StartGameInstance() { UEngine* const Engine = GetEngine(); // Create default URL. // @note: if we change how we determine the valid start up map update LaunchEngineLoop's GetStartupMap() FURL DefaultURL; DefaultURL.LoadURLConfig(TEXT("DefaultPlayer"), GGameIni); // Enter initial world. EBrowseReturnVal::Type BrowseRet = EBrowseReturnVal::Failure; FString Error; TCHAR Parm[4096] = TEXT(""); const TCHAR* Tmp = FCommandLine::Get(); #if UE_BUILD_SHIPPING // In shipping don't allow an override Tmp = TEXT(""); #endif // UE_BUILD_SHIPPING const UGameMapsSettings* GameMapsSettings = GetDefault<UGameMapsSettings>(); const FString& DefaultMap = GameMapsSettings->GetGameDefaultMap(); if (!FParse::Token(Tmp, Parm, ARRAY_COUNT(Parm), 0) || Parm[0] == '-') { FCString::Strcpy(Parm, *(DefaultMap + GameMapsSettings->LocalMapOptions)); } FURL URL(&DefaultURL, Parm, TRAVEL_Partial); if (URL.Valid) { BrowseRet = Engine->Browse(*WorldContext, URL, Error); } // If waiting for a network connection, go into the starting level. if (BrowseRet != EBrowseReturnVal::Success && FCString::Stricmp(Parm, *DefaultMap) != 0) { const FText Message = FText::Format(NSLOCTEXT("Engine", "MapNotFound", "The map specified on the commandline '{0}' could not be found. Would you like to load the default map instead?"), FText::FromString(URL.Map)); // the map specified on the command-line couldn't be loaded. ask the user if we should load the default map instead if (FCString::Stricmp(*URL.Map, *DefaultMap) != 0 && FMessageDialog::Open(EAppMsgType::OkCancel, Message) != EAppReturnType::Ok) { // user canceled (maybe a typo while attempting to run a commandlet) FPlatformMisc::RequestExit(false); return; } else { BrowseRet = Engine->Browse(*WorldContext, FURL(&DefaultURL, *(DefaultMap + GameMapsSettings->LocalMapOptions), TRAVEL_Partial), Error); } } // Handle failure. if (BrowseRet != EBrowseReturnVal::Success) { UE_LOG(LogLoad, Fatal, TEXT("%s"), *FString::Printf(TEXT("Failed to enter %s: %s. Please check the log for errors."), Parm, *Error)); } }
// // Construct a URL from text and an optional relative base. // FURL::FURL( FURL* Base, const TCHAR* TextURL, ETravelType Type ) : Protocol ( UrlConfig.DefaultProtocol ) , Host ( UrlConfig.DefaultHost ) , Port ( UrlConfig.DefaultPort ) , Map ( UGameMapsSettings::GetGameDefaultMap() ) , Op () , Portal ( UrlConfig.DefaultPortal ) , Valid ( 1 ) { check(TextURL); if( !bDefaultsInitialized ) { FURL::StaticInit(); Protocol = UrlConfig.DefaultProtocol; Host = UrlConfig.DefaultHost; Port = UrlConfig.DefaultPort; Portal = UrlConfig.DefaultPortal; } // Make a copy. const int32 URLLength = FCString::Strlen(TextURL); TCHAR* TempURL = new TCHAR[URLLength+1]; TCHAR* URL = TempURL; FCString::Strcpy( TempURL, URLLength + 1, TextURL ); // Copy Base. if( Type==TRAVEL_Relative ) { check(Base); Protocol = Base->Protocol; Host = Base->Host; Map = Base->Map; Portal = Base->Portal; Port = Base->Port; } if( Type==TRAVEL_Relative || Type==TRAVEL_Partial ) { check(Base); for( int32 i=0; i<Base->Op.Num(); i++ ) { new(Op)FString(Base->Op[i]); } } // Skip leading blanks. while( *URL == ' ' ) { URL++; } // Options. TCHAR* s = HelperStrchr(URL,'?','#'); if( s ) { TCHAR OptionChar=*s, NextOptionChar=0; *(s++) = 0; do { TCHAR* t = HelperStrchr(s,'?','#'); if( t ) { NextOptionChar = *t; *(t++) = 0; } if( !ValidNetChar( s ) ) { *this = FURL(); Valid = 0; break; } if( OptionChar=='?' ) { if (s && s[0] == '-') { // Remove an option if it starts with - s++; RemoveOption( s ); } else { AddOption( s ); } } else { Portal = s; } s = t; OptionChar = NextOptionChar; } while( s ); } if (Valid == 1) { // Handle pure filenames & Posix paths. bool FarHost=0; bool FarMap=0; if( FCString::Strlen(URL)>2 && (URL[1]==':' || (URL[0]=='/' && !FPackageName::IsValidLongPackageName(URL, true))) ) { // Pure filename. Protocol = UrlConfig.DefaultProtocol; Host = UrlConfig.DefaultHost; Map = URL; Portal = UrlConfig.DefaultPortal; URL = NULL; FarHost = 1; FarMap = 1; Host = TEXT(""); } else { // Parse protocol. if ( (FCString::Strchr(URL,':')!=NULL) && (FCString::Strchr(URL,':')>URL+1) && (FCString::Strchr(URL,'.')==NULL || FCString::Strchr(URL,':')<FCString::Strchr(URL,'.')) ) { TCHAR* ss = URL; URL = FCString::Strchr(URL,':'); *(URL++) = 0; Protocol = ss; } // Parse optional leading double-slashes. if( *URL=='/' && *(URL+1) =='/' ) { URL += 2; FarHost = 1; Host = TEXT(""); } // Parse optional host name and port. const TCHAR* Dot = FCString::Strchr(URL,'.'); const int32 ExtLen = FPackageName::GetMapPackageExtension().Len(); if ( (Dot) && (Dot-URL>0) && (FCString::Strnicmp( Dot, *FPackageName::GetMapPackageExtension(), FPackageName::GetMapPackageExtension().Len() )!=0 || FChar::IsAlnum(Dot[ExtLen]) ) && (FCString::Strnicmp( Dot+1,*UrlConfig.DefaultSaveExt, UrlConfig.DefaultSaveExt.Len() )!=0 || FChar::IsAlnum(Dot[UrlConfig.DefaultSaveExt.Len()+1]) ) && (FCString::Strnicmp( Dot+1,TEXT("demo"), 4 ) != 0 || FChar::IsAlnum(Dot[5])) ) { TCHAR* ss = URL; URL = FCString::Strchr(URL,'/'); if( URL ) { *(URL++) = 0; } TCHAR* t = FCString::Strchr(ss,':'); if( t ) { // Port. *(t++) = 0; Port = FCString::Atoi( t ); } Host = ss; if( FCString::Stricmp(*Protocol,*UrlConfig.DefaultProtocol)==0 ) { Map = UGameMapsSettings::GetGameDefaultMap(); } else { Map = TEXT(""); } FarHost = 1; } } } // Parse optional map if (Valid == 1 && URL && *URL) { // Map. if (*URL != '/') { // find full pathname from short map name FString MapFullName; FText MapNameError; if (FPaths::FileExists(URL)) { Map = FPackageName::FilenameToLongPackageName(URL); } else if (!FPackageName::DoesPackageNameContainInvalidCharacters(URL, &MapNameError) && FPackageName::SearchForPackageOnDisk(URL, &MapFullName)) { Map = MapFullName; } else { // can't find file, invalidate and bail UE_CLOG(MapNameError.ToString().Len() > 0, LogLongPackageNames, Warning, TEXT("URL: %s: %s"), URL, *MapNameError.ToString()); *this = FURL(); Valid = 0; } } else { // already a full pathname Map = URL; } } // Validate everything. // The FarHost check does not serve any purpose I can see, and will just cause valid URLs to fail (URLs with no options, why does a URL // need an option to be valid?) if (Valid == 1 && (!ValidNetChar(*Protocol) || !ValidNetChar(*Host) /*|| !ValidNetChar(*Map)*/ || !ValidNetChar(*Portal) /*|| (!FarHost && !FarMap && !Op.Num())*/)) { *this = FURL(); Valid = 0; } // If Valid == 1, success. delete[] TempURL; }
bool UGameInstance::StartPIEGameInstance(ULocalPlayer* LocalPlayer, bool bInSimulateInEditor, bool bAnyBlueprintErrors, bool bStartInSpectatorMode) { UEditorEngine* const EditorEngine = CastChecked<UEditorEngine>(GetEngine()); ULevelEditorPlaySettings const* PlayInSettings = GetDefault<ULevelEditorPlaySettings>(); const EPlayNetMode PlayNetMode = [&PlayInSettings]{ EPlayNetMode NetMode(PIE_Standalone); return (PlayInSettings->GetPlayNetMode(NetMode) ? NetMode : PIE_Standalone); }(); // for clients, just connect to the server if (PlayNetMode == PIE_Client) { FString Error; FURL BaseURL = WorldContext->LastURL; if (EditorEngine->Browse(*WorldContext, FURL(&BaseURL, TEXT("127.0.0.1"), (ETravelType)TRAVEL_Absolute), Error) == EBrowseReturnVal::Pending) { EditorEngine->TransitionType = TT_WaitingToConnect; } else { FMessageDialog::Open(EAppMsgType::Ok, FText::Format(NSLOCTEXT("UnrealEd", "Error_CouldntLaunchPIEClient", "Couldn't Launch PIE Client: {0}"), FText::FromString(Error))); return false; } } else { // we're going to be playing in the current world, get it ready for play UWorld* const PlayWorld = GetWorld(); // make a URL FURL URL; // If the user wants to start in spectator mode, do not use the custom play world for now if (EditorEngine->UserEditedPlayWorldURL.Len() > 0 && !bStartInSpectatorMode) { // If the user edited the play world url. Verify that the map name is the same as the currently loaded map. URL = FURL(NULL, *EditorEngine->UserEditedPlayWorldURL, TRAVEL_Absolute); if (URL.Map != PIEMapName) { // Ensure the URL map name is the same as the generated play world map name. URL.Map = PIEMapName; } } else { // The user did not edit the url, just build one from scratch. URL = FURL(NULL, *EditorEngine->BuildPlayWorldURL(*PIEMapName, bStartInSpectatorMode), TRAVEL_Absolute); } // If a start location is specified, spawn a temporary PlayerStartPIE actor at the start location and use it as the portal. AActor* PlayerStart = NULL; if (EditorEngine->SpawnPlayFromHereStart(PlayWorld, PlayerStart, EditorEngine->PlayWorldLocation, EditorEngine->PlayWorldRotation) == false) { // failed to create "play from here" playerstart FMessageDialog::Open(EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "Error_FailedCreatePlayFromHerePlayerStart", "Failed to create PlayerStart at desired starting location.")); return false; } if (!PlayWorld->SetGameMode(URL)) { // Setting the game mode failed so bail FMessageDialog::Open(EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "Error_FailedCreateEditorPreviewWorld", "Failed to create editor preview world.")); return false; } // Make sure "always loaded" sub-levels are fully loaded PlayWorld->FlushLevelStreaming(EFlushLevelStreamingType::Visibility); UNavigationSystem::InitializeForWorld(PlayWorld, LocalPlayers.Num() > 0 ? FNavigationSystem::PIEMode : FNavigationSystem::SimulationMode); PlayWorld->CreateAISystem(); PlayWorld->InitializeActorsForPlay(URL); // @todo, just use WorldContext.GamePlayer[0]? if (LocalPlayer) { FString Error; if (!LocalPlayer->SpawnPlayActor(URL.ToString(1), Error, PlayWorld)) { FMessageDialog::Open(EAppMsgType::Ok, FText::Format(NSLOCTEXT("UnrealEd", "Error_CouldntSpawnPlayer", "Couldn't spawn player: {0}"), FText::FromString(Error))); return false; } } UGameViewportClient* const GameViewport = GetGameViewportClient(); if (GameViewport != NULL && GameViewport->Viewport != NULL) { // Stream any levels now that need to be loaded before the game starts GEngine->BlockTillLevelStreamingCompleted(PlayWorld); } if (PlayNetMode == PIE_ListenServer) { // start listen server with the built URL PlayWorld->Listen(URL); } PlayWorld->BeginPlay(); } return true; }
void UIpNetDriver::TickDispatch( float DeltaTime ) { Super::TickDispatch( DeltaTime ); ISocketSubsystem* SocketSubsystem = GetSocketSubsystem(); // Process all incoming packets. uint8 Data[NETWORK_MAX_PACKET]; TSharedRef<FInternetAddr> FromAddr = SocketSubsystem->CreateInternetAddr(); for( ; Socket != NULL; ) { int32 BytesRead = 0; // Get data, if any. CLOCK_CYCLES(RecvCycles); bool bOk = Socket->RecvFrom(Data, sizeof(Data), BytesRead, *FromAddr); UNCLOCK_CYCLES(RecvCycles); // Handle result. if( bOk == false ) { ESocketErrors Error = SocketSubsystem->GetLastErrorCode(); if(Error == SE_EWOULDBLOCK || Error == SE_NO_ERROR) { // No data or no error? break; } else { if( Error != SE_ECONNRESET && Error != SE_UDP_ERR_PORT_UNREACH ) { UE_LOG(LogNet, Warning, TEXT("UDP recvfrom error: %i (%s) from %s"), (int32)Error, SocketSubsystem->GetSocketError(Error), *FromAddr->ToString(true)); break; } } } // Figure out which socket the received data came from. UIpConnection* Connection = NULL; if (GetServerConnection() && (*GetServerConnection()->RemoteAddr == *FromAddr)) { Connection = GetServerConnection(); } for( int32 i=0; i<ClientConnections.Num() && !Connection; i++ ) { UIpConnection* TestConnection = (UIpConnection*)ClientConnections[i]; check(TestConnection); if(*TestConnection->RemoteAddr == *FromAddr) { Connection = TestConnection; } } if( bOk == false ) { if( Connection ) { if( Connection != GetServerConnection() ) { // We received an ICMP port unreachable from the client, meaning the client is no longer running the game // (or someone is trying to perform a DoS attack on the client) // rcg08182002 Some buggy firewalls get occasional ICMP port // unreachable messages from legitimate players. Still, this code // will drop them unceremoniously, so there's an option in the .INI // file for servers with such flakey connections to let these // players slide...which means if the client's game crashes, they // might get flooded to some degree with packets until they timeout. // Either way, this should close up the usual DoS attacks. if ((Connection->State != USOCK_Open) || (!AllowPlayerPortUnreach)) { if (LogPortUnreach) { UE_LOG(LogNet, Log, TEXT("Received ICMP port unreachable from client %s. Disconnecting."), *FromAddr->ToString(true)); } Connection->CleanUp(); } } } else { if (LogPortUnreach) { UE_LOG(LogNet, Log, TEXT("Received ICMP port unreachable from %s. No matching connection found."), *FromAddr->ToString(true)); } } } else { // If we didn't find a client connection, maybe create a new one. if( !Connection ) { // Determine if allowing for client/server connections const bool bAcceptingConnection = Notify->NotifyAcceptingConnection() == EAcceptConnection::Accept; if (bAcceptingConnection) { Connection = ConstructObject<UIpConnection>(NetConnectionClass); check(Connection); Connection->InitRemoteConnection( this, Socket, FURL(), *FromAddr, USOCK_Open); Notify->NotifyAcceptedConnection( Connection ); AddClientConnection(Connection); } } // Send the packet to the connection for processing. if( Connection ) { Connection->ReceivedRawPacket( Data, BytesRead ); } } } }
void UGameEngine::Init(IEngineLoop* InEngineLoop) { DECLARE_SCOPE_CYCLE_COUNTER(TEXT("UGameEngine Init"), STAT_GameEngineStartup, STATGROUP_LoadTime); // Call base. UEngine::Init(InEngineLoop); #if USE_NETWORK_PROFILER FString NetworkProfilerTag; if( FParse::Value(FCommandLine::Get(), TEXT("NETWORKPROFILER="), NetworkProfilerTag ) ) { GNetworkProfiler.EnableTracking(true); } #endif // Load and apply user game settings GetGameUserSettings()->LoadSettings(); GetGameUserSettings()->ApplySettings(); // Creates the initial world context. For GameEngine, this should be the only WorldContext that ever gets created. FWorldContext &InitialWorldContext = CreateNewWorldContext(EWorldType::Game); // Initialize the viewport client. UGameViewportClient* ViewportClient = NULL; if(GIsClient) { ViewportClient = ConstructObject<UGameViewportClient>(GameViewportClientClass,this); ViewportClient->SetReferenceToWorldContext(InitialWorldContext); GameViewport = ViewportClient; InitialWorldContext.GameViewport = ViewportClient; } bCheckForMovieCapture = true; // Attach the viewport client to a new viewport. if(ViewportClient) { // This must be created before any gameplay code adds widgets bool bWindowAlreadyExists = GameViewportWindow.IsValid(); if (!bWindowAlreadyExists) { GameViewportWindow = CreateGameWindow(); } CreateGameViewport( ViewportClient ); if( !bWindowAlreadyExists ) { SwitchGameWindowToUseGameViewport(); } FString Error; if(!ViewportClient->Init(Error)) { UE_LOG(LogEngine, Fatal,TEXT("%s"),*Error); } } // Create default URL. // @note: if we change how we determine the valid start up map update LaunchEngineLoop's GetStartupMap() FURL DefaultURL; DefaultURL.LoadURLConfig( TEXT("DefaultPlayer"), GGameIni ); // Enter initial world. EBrowseReturnVal::Type BrowseRet = EBrowseReturnVal::Failure; FString Error; TCHAR Parm[4096]=TEXT(""); const TCHAR* Tmp = FCommandLine::Get(); #if UE_BUILD_SHIPPING // In shipping don't allow an override Tmp = TEXT(""); #endif // UE_BUILD_SHIPPING const UGameMapsSettings* GameMapsSettings = GetDefault<UGameMapsSettings>(); const FString& DefaultMap = GameMapsSettings->GetGameDefaultMap(); if (!FParse::Token(Tmp, Parm, ARRAY_COUNT(Parm), 0) || Parm[0] == '-') { FCString::Strcpy(Parm, *(DefaultMap + GameMapsSettings->LocalMapOptions)); } FURL URL( &DefaultURL, Parm, TRAVEL_Partial ); if( URL.Valid ) { BrowseRet = Browse(InitialWorldContext, URL, Error ); } // If waiting for a network connection, go into the starting level. if (BrowseRet != EBrowseReturnVal::Success && FCString::Stricmp(Parm, *DefaultMap) != 0) { const FText Message = FText::Format( NSLOCTEXT("Engine", "MapNotFound", "The map specified on the commandline '{0}' could not be found. Would you like to load the default map instead?"), FText::FromString( URL.Map ) ); // the map specified on the command-line couldn't be loaded. ask the user if we should load the default map instead if ( FCString::Stricmp(*URL.Map, *DefaultMap) != 0 && FMessageDialog::Open( EAppMsgType::OkCancel, Message ) != EAppReturnType::Ok) { // user canceled (maybe a typo while attempting to run a commandlet) FPlatformMisc::RequestExit( false ); return; } else { BrowseRet = Browse(InitialWorldContext, FURL(&DefaultURL, *(DefaultMap + GameMapsSettings->LocalMapOptions), TRAVEL_Partial), Error); } } // Handle failure. if( BrowseRet != EBrowseReturnVal::Success ) { UE_LOG(LogLoad, Fatal, TEXT("%s"), *FString::Printf( TEXT("Failed to enter %s: %s. Please check the log for errors."), Parm, *Error) ); } UE_LOG(LogInit, Display, TEXT("Game Engine Initialized.") ); // for IsInitialized() bIsInitialized = true; }