bmh/FlightSimulation/Plugins/CesiumForUnreal_5.4/Source/CesiumRuntime/Private/CesiumIonServer.cpp
2025-02-07 22:52:32 +08:00

197 lines
6.0 KiB
C++

// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#include "CesiumIonServer.h"
#include "CesiumAsync/AsyncSystem.h"
#include "CesiumIonClient/Connection.h"
#include "CesiumRuntime.h"
#include "CesiumRuntimeSettings.h"
#include "UObject/Package.h"
#include "UObject/UObjectGlobals.h"
#if WITH_EDITOR
#include "AssetRegistry/AssetRegistryModule.h"
#include "CesiumIonClient/Connection.h"
#include "Factories/DataAssetFactory.h"
#include "FileHelpers.h"
#endif
const FString DISPLAY_NAME = TEXT("ion.cesium.com");
const FString SERVER_URL = TEXT("https://ion.cesium.com");
const FString API_URL = TEXT("https://api.cesium.com");
const int64 OAUTH_APP_ID = 190;
/*static*/ UCesiumIonServer* UCesiumIonServer::_pDefaultForNewObjects = nullptr;
/*static*/ UCesiumIonServer* UCesiumIonServer::GetDefaultServer() {
UPackage* Package = CreatePackage(
TEXT("/Game/CesiumSettings/CesiumIonServers/CesiumIonSaaS"));
Package->FullyLoad();
UCesiumIonServer* Server =
Cast<UCesiumIonServer>(Package->FindAssetInPackage());
#if WITH_EDITOR
if (!IsValid(Server)) {
UDataAssetFactory* Factory = NewObject<UDataAssetFactory>();
Server = Cast<UCesiumIonServer>(Factory->FactoryCreateNew(
UCesiumIonServer::StaticClass(),
Package,
"CesiumIonSaaS",
RF_Public | RF_Standalone | RF_Transactional,
nullptr,
GWarn));
Server->DisplayName = DISPLAY_NAME;
Server->ServerUrl = SERVER_URL;
Server->ApiUrl = API_URL;
Server->OAuth2ApplicationID = OAUTH_APP_ID;
FAssetRegistryModule::AssetCreated(Server);
Package->FullyLoad();
Package->SetDirtyFlag(true);
UEditorLoadingAndSavingUtils::SavePackages({Package}, true);
}
#else
if (!IsValid(Server)) {
Server = NewObject<UCesiumIonServer>(
UCesiumIonServer::StaticClass(),
"CesiumIonSaaS",
RF_Public | RF_Standalone | RF_Transactional);
Server->DisplayName = DISPLAY_NAME;
Server->ServerUrl = SERVER_URL;
Server->ApiUrl = API_URL;
Server->OAuth2ApplicationID = OAUTH_APP_ID;
}
#endif
return Server;
}
/*static*/ UCesiumIonServer* UCesiumIonServer::GetServerForNewObjects() {
if (IsValid(_pDefaultForNewObjects)) {
return _pDefaultForNewObjects;
} else {
return GetDefaultServer();
}
}
/*static*/ void
UCesiumIonServer::SetServerForNewObjects(UCesiumIonServer* Server) {
_pDefaultForNewObjects = Server;
}
#if WITH_EDITOR
UCesiumIonServer*
UCesiumIonServer::GetBackwardCompatibleServer(const FString& apiUrl) {
// Return the default server if the API URL is unspecified or if it's the
// standard SaaS API URL.
if (apiUrl.IsEmpty() ||
apiUrl.StartsWith(TEXT("https://api.ion.cesium.com")) ||
apiUrl.StartsWith(TEXT("https://api.cesium.com"))) {
return UCesiumIonServer::GetDefaultServer();
}
// Find a server with this API URL.
TArray<FAssetData> CesiumIonServers;
FAssetRegistryModule& AssetRegistryModule =
FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
AssetRegistryModule.Get().GetAssetsByClass(
UCesiumIonServer::StaticClass()->GetClassPathName(),
CesiumIonServers);
FAssetData* pFound =
CesiumIonServers.FindByPredicate([&apiUrl](const FAssetData& asset) {
UCesiumIonServer* pServer = Cast<UCesiumIonServer>(asset.GetAsset());
return pServer && pServer->ApiUrl == apiUrl;
});
if (pFound) {
return Cast<UCesiumIonServer>(pFound->GetAsset());
}
// Not found - create a new server asset.
UDataAssetFactory* Factory = NewObject<UDataAssetFactory>();
UPackage* Package = nullptr;
FString PackageBasePath = TEXT("/Game/CesiumSettings/CesiumIonServers/");
FString PackageName;
FString PackagePath;
const int ArbitraryPackageIndexLimit = 10000;
for (int i = 0; i < ArbitraryPackageIndexLimit; ++i) {
PackageName = TEXT("FromApiUrl") + FString::FromInt(i);
PackagePath = PackageBasePath + PackageName;
Package = FindPackage(nullptr, *PackagePath);
if (Package == nullptr) {
Package = CreatePackage(*PackagePath);
break;
}
}
if (Package == nullptr)
return nullptr;
Package->FullyLoad();
UCesiumIonServer* Server = Cast<UCesiumIonServer>(Factory->FactoryCreateNew(
UCesiumIonServer::StaticClass(),
Package,
FName(PackageName),
RF_Public | RF_Standalone | RF_Transactional,
nullptr,
GWarn));
Server->DisplayName = apiUrl;
Server->ServerUrl = apiUrl;
Server->ApiUrl = apiUrl;
Server->OAuth2ApplicationID = 190;
// Adopt the token from the default server, consistent with the behavior in
// old versions of Cesium for Unreal.
UCesiumIonServer* pDefault = UCesiumIonServer::GetDefaultServer();
Server->DefaultIonAccessTokenId = pDefault->DefaultIonAccessTokenId;
Server->DefaultIonAccessToken = pDefault->DefaultIonAccessToken;
FAssetRegistryModule::AssetCreated(Server);
Package->FullyLoad();
Package->SetDirtyFlag(true);
UEditorLoadingAndSavingUtils::SavePackages({Package}, true);
return Server;
}
CesiumAsync::Future<void> UCesiumIonServer::ResolveApiUrl() {
if (!this->ApiUrl.IsEmpty())
return getAsyncSystem().createResolvedFuture();
if (this->ServerUrl.IsEmpty()) {
// We don't even have a server URL, so use the SaaS defaults.
this->ServerUrl = TEXT("https://ion.cesium.com/");
this->ApiUrl = TEXT("https://api.cesium.com/");
this->Modify();
UEditorLoadingAndSavingUtils::SavePackages({this->GetPackage()}, true);
return getAsyncSystem().createResolvedFuture();
}
TObjectPtr<UCesiumIonServer> pServer = this;
return CesiumIonClient::Connection::getApiUrl(
getAsyncSystem(),
getAssetAccessor(),
TCHAR_TO_UTF8(*this->ServerUrl))
.thenInMainThread([pServer](std::optional<std::string>&& apiUrl) {
if (pServer && pServer->ApiUrl.IsEmpty()) {
pServer->ApiUrl = UTF8_TO_TCHAR(apiUrl->c_str());
pServer->Modify();
UEditorLoadingAndSavingUtils::SavePackages(
{pServer->GetPackage()},
true);
}
});
}
#endif