初始提交: UE5.3项目基础框架

This commit is contained in:
2025-10-14 11:14:54 +08:00
commit 721d9fd98e
5334 changed files with 316782 additions and 0 deletions

View File

@ -0,0 +1,62 @@
#pragma once
#include <string>
namespace CesiumIonClient {
/**
* @brief An enumeration representing the values of the `authenticationMode`
* property in the `appData` response.
*/
enum AuthenticationMode {
/**
* Authentication using OAuth with an ion.cesium.com account.
*/
CesiumIon,
/**
* Authentication using OAuth with Cesium ion Self-Hosted.
* On the server, this uses the Security Assertion Markup Language (SAML) to
* communicate with another authentication server.
* From our perspective, we can treat this the same as {@link AuthenticationMode::CesiumIon}.
*/
Saml,
/**
* A Cesium ion Self-Hosted server without authentication.
* In single-user mode, any application that can reach the server has
* permissions to use its endpoints. In this mode, some endpoints (like /me
* and /tokens) are unavailable.
*/
SingleUser
};
/**
* @brief Data retrieved from the Cesium ion server via an "appData" request
* from Cesium ion. This actually represents information about the server
* itself.
*/
struct ApplicationData {
/**
* The authentication mode that the ion server is running in.
*/
AuthenticationMode authenticationMode;
/**
* The type of store used by this ion server to hold files.
* Known values: FILE_SYSTEM, S3
*/
std::string dataStoreType;
/**
* The attribution HTML for this ion server.
*/
std::string attribution;
/**
* @brief Does the `authenticationMode` require OAuth authentication?
*/
bool needsOauthAuthentication() const {
return this->authenticationMode != AuthenticationMode::SingleUser;
}
};
} // namespace CesiumIonClient

View File

@ -0,0 +1,93 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace CesiumIonClient {
/**
* @brief A Cesium ion Asset, such as a 3D Tiles tileset or an imagery layer.
*/
struct Asset {
/**
* @brief The unique identifier for this asset.
*/
int64_t id = -1;
/**
* @brief The name of this asset.
*/
std::string name;
/**
* @brief A Markdown compatible string describing this asset.
*/
std::string description;
/**
* @brief A Markdown compatible string containing any required attribution for
* this asset.
*
* Clients will be required to display this attribution to end users.
*/
std::string attribution;
/**
* @brief The asset's [type](https://cesium.com/docs/rest-api/#tag/Assets)./
*/
std::string type;
/**
* @brief The number of bytes this asset occupies in the user's account.
*/
int64_t bytes = 0;
/**
* @brief The date and time that this asset was created in [RFC
* 3339](https://tools.ietf.org/html/rfc3339) format.
*/
std::string dateAdded;
/**
* @brief Describes the state of the asset during the upload and tiling
* processes.
*
* | *Value* | *Description* |
* | AWAITING_FILES | The asset has been created but the server is waiting for
* source data to be uploaded. | | NOT_STARTED | The server was notified that
* all source data was uploaded and is waiting for the tiling process to
* start. | | IN_PROGRESS | The source data is being tiled, see
* percentComplete to monitor progress. | | COMPLETE | The asset was tiled
* successfully. | | DATA_ERROR | The uploaded source data was invalid or
* unsupported. | | ERROR | An internal error occurred during the tiling
* process. Please contact support@cesium.com. |
*/
std::string status;
/**
* @brief The percentage progress of the tiling pipeline preparing this asset.
*/
int8_t percentComplete = 0;
};
/**
* @brief A page of assets obtained from the Cesium ion `v1/assets` endpoint,
* including a link to obtain the next page, if one exists.
*/
struct Assets {
/**
* @brief An [RFC 5988](https://tools.ietf.org/html/rfc5988) formatted string
* with a relation type of next which points to the next page of data on the
* server, if it exists.
*
* This url should be treated as an opaque link as the actual format may
* change at any time.
*/
std::string link;
/**
* @brief A page of assets.
*/
std::vector<Asset> items;
};
} // namespace CesiumIonClient

View File

@ -0,0 +1,342 @@
#pragma once
#include "ApplicationData.h"
#include "Assets.h"
#include "Defaults.h"
#include "Profile.h"
#include "Response.h"
#include "Token.h"
#include "TokenList.h"
#include <CesiumAsync/AsyncSystem.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumAsync/Library.h>
#include <cstdint>
namespace CesiumIonClient {
/**
* @brief Whether sorted results should be ascending or descending.
*/
enum class SortOrder { Ascending, Descending };
/**
* @brief Options to be passed to {@link Connection::tokens}.
*/
struct ListTokensOptions {
/**
* @brief The maximum number of tokens to return in a single page.
*
* Receiving fewer tokens should not be interpreted as the end of the
* collection. The end of the collection is reached when the response does not
* contain {@link Response::nextPageUrl}.
*/
std::optional<int32_t> limit;
/**
* @brief The page number, where the first page of results is page 1 (not 0).
*/
std::optional<int32_t> page;
/**
* @brief One or more keywords separated by whitespace by which to
* filter the list of tokens. The token name will contain each keyword of the
* search string.
*/
std::optional<std::string> search;
/**
* @brief The property by which to sort results. Valid values are
* `"NAME"` and `"LAST_USED"`.
*/
std::optional<std::string> sortBy;
/**
* @brief The property by which to sort results. Valid values are
* `"NAME"` and `"LAST_USED"`.
*/
std::optional<SortOrder> sortOrder;
};
/**
* @brief A connection to Cesium ion that can be used to interact with it via
* its REST API.
*/
class CESIUMASYNC_API Connection {
public:
/**
* @brief Authorizes access to Cesium ion on behalf of a user, and returns a
* {@link Connection} that can be used to interact with ion.
*
* Uses the "Authorization Code with PKCE" OAuth2 flow.
*
* See [Connecting to Cesium ion with
* OAuth2](https://cesium.com/learn/ion/ion-oauth2/) for a description of the
* authorization process.
*
* @param asyncSystem The async system used to do work in threads.
* @param pAssetAccessor The interface used to interact with the Cesium ion
* REST API.
* @param friendlyApplicationName A friendly name for the application
* requesting access. It will be displayed to the user when authorization is
* complete, informing them that they can return to the original application.
* @param clientID The client ID that was assigned to your application when
* you registered it.
* @param redirectPath The path on http://127.0.0.1 that a user will be
* redirected to once they authorize your application. This must match the URI
* provided when you registered your application, without the protocol,
* hostname, or port.
* @param scopes The list of scopes that the eventually-granted token should
* allow access to.
* @param openUrlCallback A function that is invoked to launch the user's web
* browser with a given URL so that they can authorize access.
* @param appData The app data retrieved from the Cesium ion server.
* @param ionApiUrl The base URL of the Cesium ion API.
* @param ionAuthorizeUrl The URL of the Cesium ion OAuth authorization page.
* @return A future that resolves to a Cesium ion {@link Connection} once the
* user authorizes the application and the token handshake completes.
*/
static CesiumAsync::Future<Connection> authorize(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::string& friendlyApplicationName,
int64_t clientID,
const std::string& redirectPath,
const std::vector<std::string>& scopes,
std::function<void(const std::string&)>&& openUrlCallback,
const CesiumIonClient::ApplicationData& appData,
const std::string& ionApiUrl = "https://api.cesium.com/",
const std::string& ionAuthorizeUrl = "https://ion.cesium.com/oauth");
/**
* @brief Retrieves information about the ion API server.
*
* @param asyncSystem The async system used to do work in threads.
* @param pAssetAccessor The interface used to interact with the Cesium ion
* REST API.
* @param apiUrl The URL of the ion REST API to make requests against.
* @return A future that resolves to the application information.
*/
static CesiumAsync::Future<Response<ApplicationData>> appData(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::string& apiUrl = "https://api.cesium.com");
/**
* @brief Attempts to retrieve the ion endpoint URL by looking for a
* `config.json` file on the server.
*
* This config file isn't present on `ion.cesium.com`, but will be present on
* Cesium ion self-hosted instances to allow the user to configure the URLs of
* their self-hosted instance as needed.
*
* @param asyncSystem The async system used to do work in threads.
* @param pAssetAccessor The interface used to interact with the Cesium ion
* REST API.
* @param ionUrl The URL of the Cesium ion instance to make this request
* against.
* @returns The Cesium ion REST API url for this ion instance, or
* `std::nullopt` if none found.
*/
static CesiumAsync::Future<std::optional<std::string>> getApiUrl(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::string& ionUrl);
/**
* @brief Creates a connection to Cesium ion using the provided access token.
*
* @param asyncSystem The async system used to do work in threads.
* @param pAssetAccessor The interface used to interact with the Cesium ion
* REST API.
* @param accessToken The access token
* @param appData The app data retrieved from the Cesium ion server.
* @param apiUrl The base URL of the Cesium ion API.
*/
Connection(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::string& accessToken,
const CesiumIonClient::ApplicationData& appData,
const std::string& apiUrl = "https://api.cesium.com");
/**
* @brief Gets the async system used by this connection to do work in threads.
*/
const CesiumAsync::AsyncSystem& getAsyncSystem() const noexcept {
return this->_asyncSystem;
}
/**
* @brief Gets the interface used by this connection to interact with the
* Cesium ion REST API.
*/
const std::shared_ptr<CesiumAsync::IAssetAccessor>&
getAssetAccessor() const noexcept {
return this->_pAssetAccessor;
}
/**
* @brief Gets the access token used by this connection.
*/
const std::string& getAccessToken() const noexcept {
return this->_accessToken;
}
/**
* @brief Gets the Cesium ion API base URL.
*/
const std::string& getApiUrl() const noexcept { return this->_apiUrl; }
/**
* @brief Retrieves profile information for the access token currently being
* used to make API calls.
*
* This route works with any valid token, but additional information is
* returned if the token uses the `profile:read` scope.
*
* @return A future that resolves to the profile information.
*/
CesiumAsync::Future<Response<Profile>> me() const;
/**
* @brief Retrieves default imagery, terrain and building assets along with
* quick add assets that can be useful to use within other applications.
*
* This route will always return data, but will return user specific
* information with any valid token.
*
* @return A future that resolves to the default information.
*/
CesiumAsync::Future<Response<Defaults>> defaults() const;
/**
* @brief Gets the list of available assets.
*
* @return A future that resolves to the asset information.
*/
CesiumAsync::Future<Response<Assets>> assets() const;
/**
* @brief Invokes the "List tokens" service to get the list of available
* tokens.
*
* Only a single page is returned. To obtain additional pages, use
* {@link Connection::nextPage} and {@link Connection::previousPage}.
*
* @param options Options to include in the "List tokens" request.
* @return A future that resolves to a page of token information.
*/
CesiumAsync::Future<Response<TokenList>>
tokens(const ListTokensOptions& options = {}) const;
/**
* @brief Gets details of the asset with the given ID.
*
* @param assetID The asset ID.
* @return A future that resolves to the asset details.
*/
CesiumAsync::Future<Response<Asset>> asset(int64_t assetID) const;
/**
* @brief Gets details of the token with the given ID.
*
* @param tokenID The token ID.
* @return A future that resolves to the token details.
*/
CesiumAsync::Future<Response<Token>> token(const std::string& tokenID) const;
/**
* @brief Gets the next page of results from the "List tokens" service.
*
* To get the first page, use {@link Connection::tokens}.
*
* @param currentPage The current page from which to get the next page.
* @return A future that resolves to the next page of tokens, or to a
* response with an {@link Response::errorCode} of "NoMorePages" if the
* currentPage is the last one.
*/
CesiumAsync::Future<Response<TokenList>>
nextPage(const Response<TokenList>& currentPage) const;
/**
* @brief Gets the previous page of results from the "List tokens" service.
*
* To get the first page (or a particular page), use {@link Connection::tokens}.
*
* @param currentPage The current page from which to get the previous page.
* @return A future that resolves to the previous page of tokens, or to a
* response with an {@link Response::errorCode} of "NoMorePages" if the
* currentPage is the first one.
*/
CesiumAsync::Future<Response<TokenList>>
previousPage(const Response<TokenList>& currentPage) const;
/**
* @brief Creates a new token.
*
* @param name The name of the new token.
* @param scopes The scopes allowed by this token.
* @param assetIds The assets that may be accessed by this token. If
* `std::nullopt`, access to all assets is allowed.
* @param allowedUrls The URLs from which this token can be accessed. If
* `std::nullopt`, the token can be accessed from any URL.
* @return The new token.
*/
CesiumAsync::Future<Response<Token>> createToken(
const std::string& name,
const std::vector<std::string>& scopes,
const std::optional<std::vector<int64_t>>& assetIds = std::nullopt,
const std::optional<std::vector<std::string>>& allowedUrls =
std::nullopt) const;
/**
* @brief Modifies a token.
*
* @param tokenID The ID of the token to modify.
* @param newName The new name of the token.
* @param newAssetIDs The assets that may be accessed by this token. If
* `std::nullopt`, access to all assets is allowed.
* @param newScopes The new OAuth scopes allowed by this token.
* @param newAllowedUrls The new URLs from which this token can be accessed.
* If `std::nullopt`, the token can be accessed from any URL.
* @return A value-less response. If the response is successful, the token has
* been modified.
*/
CesiumAsync::Future<Response<NoValue>> modifyToken(
const std::string& tokenID,
const std::string& newName,
const std::optional<std::vector<int64_t>>& newAssetIDs,
const std::vector<std::string>& newScopes,
const std::optional<std::vector<std::string>>& newAllowedUrls) const;
/**
* @brief Decodes a token ID from a token.
*
* @param token The token to decode.
* @return The token ID, or std::nullopt if the token ID cannot be determined
* from the token.
*/
static std::optional<std::string> getIdFromToken(const std::string& token);
private:
static CesiumAsync::Future<Connection> completeTokenExchange(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
int64_t clientID,
const std::string& ionApiUrl,
const CesiumIonClient::ApplicationData& appData,
const std::string& code,
const std::string& redirectUrl,
const std::string& codeVerifier);
CesiumAsync::Future<Response<TokenList>> tokens(const std::string& url) const;
CesiumAsync::AsyncSystem _asyncSystem;
std::shared_ptr<CesiumAsync::IAssetAccessor> _pAssetAccessor;
std::string _accessToken;
std::string _apiUrl;
CesiumIonClient::ApplicationData _appData;
};
} // namespace CesiumIonClient

View File

@ -0,0 +1,107 @@
#pragma once
namespace CesiumIonClient {
/**
* @brief The default assets.
*/
struct DefaultAssets {
/**
* @brief The asset id of the default imagery asset.
*/
int64_t imagery = -1;
/**
* @brief The asset id of the default terrain asset.
*/
int64_t terrain = -1;
/**
* @brief The asset id of the default buildings asset.
*/
int64_t buildings = -1;
};
/**
* @brief A raster overlay available for use with a quick add asset.
*/
struct QuickAddRasterOverlay {
/**
* @brief The name of this asset.
*/
std::string name{};
/**
* @brief The unique identifier for this asset.
*/
int64_t assetId = -1;
/**
* @brief `true` if the user is subscribed to the asset, `false` otherwise.
*/
bool subscribed = false;
};
/**
* @brief A quick add asset.
*/
struct QuickAddAsset {
/**
* @brief The name of this asset.
*/
std::string name{};
/**
* @brief The name of the main asset. In most cases this will be the same as
* `name`, but in the cases of assets with raster overlays, this will be the
* non-imagery asset.
*/
std::string objectName{};
/**
* @brief A Markdown compatible string describing this asset.
*/
std::string description{};
/**
* @brief The unique identifier for this asset.
*/
int64_t assetId = -1;
/**
* @brief This asset's type.
*
* Valid values are: `3DTILES`, `GLTF`, `IMAGERY`, `TERRAIN`, `KML`, `CZML`,
* `GEOJSON`.
*/
std::string type{};
/**
* @brief `true` if the user is subscribed to the asset, `false` otherwise.
*/
bool subscribed = false;
/**
* @brief The raster overlays available for this asset
*/
std::vector<QuickAddRasterOverlay> rasterOverlays{};
};
/**
* @brief The data returned by Cesium ion's `v1/defaults` service. It includes
* information about default imagery, terrain and building assets along with
* quick add assets that can be useful to use within other applications.
*/
struct Defaults {
/**
* @brief The default assets
*/
DefaultAssets defaultAssets{};
/**
* @brief The quick add assets
*/
std::vector<QuickAddAsset> quickAddAssets{};
};
} // namespace CesiumIonClient

View File

@ -0,0 +1,18 @@
#pragma once
/**
* @brief Classes for working with Cesium ion clients
*
* @mermaid-interactive{dependencies/CesiumIonClient}
*/
namespace CesiumIonClient {}
#if defined(_WIN32) && defined(CESIUM_SHARED)
#ifdef CESIUMIONCLIENT_BUILDING
#define CESIUMIONCLIENT_API __declspec(dllexport)
#else
#define CESIUMIONCLIENT_API __declspec(dllimport)
#endif
#else
#define CESIUMIONCLIENT_API
#endif

View File

@ -0,0 +1,74 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace CesiumIonClient {
/**
* @brief Information about the amount of storage available in a user's account.
*/
struct ProfileStorage final {
/**
* @brief The number of bytes currently being used by this account.
*/
int64_t used = 0;
/**
* @brief The number of bytes available for additional asset uploads to this
* account.
*/
int64_t available = 0;
/**
* @brief The total number of bytes currently allowed to be used by this
* account.
*/
int64_t total = 0;
};
/**
* @brief Contains of a Cesium ion user.
*
* @see CesiumIonConnection#me
*/
struct Profile final {
/**
* @brief The unique identifier for this account.
*/
int64_t id = -1;
/**
* @brief The array of scopes available with this token.
*/
std::vector<std::string> scopes{};
/**
* @brief The account username.
*/
std::string username{};
/**
* @brief The primary email address associated with this account.
*/
std::string email{};
/**
* @brief If true, the email address has been verified for this account.
*/
bool emailVerified = false;
/**
* @brief A url to the profile image associated with this account.
*/
std::string avatar{};
/**
* @brief Information about the amount of storage available in the user's
* account.
*/
ProfileStorage storage{0, 0, 0};
};
} // namespace CesiumIonClient

View File

@ -0,0 +1,124 @@
#pragma once
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
namespace CesiumAsync {
class IAssetRequest;
}
namespace CesiumIonClient {
/**
* @brief A response from Cesium ion.
*
* @tparam T The type of the response object.
*/
template <typename T> struct Response final {
/**
* @brief Creates a new empty `Response`.
*/
Response();
/**
* @brief Creates a `Response` from a completed request and a response value.
*
* @param pRequest A completed request. The constructor will attempt to obtain
* the `httpStatusCode`, `previousPageUrl`, and `nextPageUrl` from this
* request.
* @param value The response value.
*/
Response(
const std::shared_ptr<CesiumAsync::IAssetRequest>& pRequest,
T&& value);
/**
* @brief Creates a `Response` from a response value, status code, and error
* information
*
* @param value The response value.
* @param httpStatusCode The HTTP status code of the response.
* @param errorCode The error code. See \ref Response::errorCode. If no error
* occurred, pass an empty string.
* @param errorMessage The error message. See \ref Response::errorMessage. If
* no error occurred, pass an empty string.
*/
Response(
T&& value,
uint16_t httpStatusCode,
const std::string& errorCode,
const std::string& errorMessage);
/**
* @brief Creates a `Response` with no value, a status code, and error
* information.
*
* @param httpStatusCode The HTTP status code of the response.
* @param errorCode The error code. See \ref Response::errorCode.
* @param errorMessage The error message. See \ref Response::errorMessage.
*/
Response(
uint16_t httpStatusCode,
const std::string& errorCode,
const std::string& errorMessage);
/**
* @brief The response value, or `std::nullopt` if the response was
* unsuccessful.
*/
std::optional<T> value;
/**
* @brief The HTTP status code returned by Cesium ion.
*/
uint16_t httpStatusCode;
/**
* @brief The error code, or empty string if there was no error.
*
* If no response is received at all, the code will be `"NoResponse"`.
*
* If Cesium ion returns an error, this will be the `code` reported by Cesium
* ion.
*
* If Cesium ion reports success but an error occurs while attempting to parse
* the response, the code will be
* `"ParseError"`.
*/
std::string errorCode;
/**
* @brief The error message returned, or an empty string if there was no
* error.
*
* If Cesium ion returns an error, this will be the `message` reported by
* Cesium ion. If Cesium ion reports success but another error occurs, the
* message will contain further details of the error.
*/
std::string errorMessage;
/**
* @brief The URL to use to obtain the next page of results, if there is a
* next page.
*
* Call {@link Connection::nextPage} rather than using this field directly.
*/
std::optional<std::string> nextPageUrl;
/**
* @brief The URL to use to obtain the previous page of results, if there is
* one.
*
* Call {@link Connection::previousPage} rather than using this field directly.
*/
std::optional<std::string> previousPageUrl;
};
/**
* @brief A non-value, for use with a valueless {@link Response}.
*/
struct NoValue {};
} // namespace CesiumIonClient

View File

@ -0,0 +1,68 @@
#pragma once
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
namespace CesiumIonClient {
/**
* @brief A Cesium ion access token.
*/
struct Token {
/**
* @brief The identifier of the token.
*/
std::string id{};
/**
* @brief The name of the token.
*/
std::string name{};
/**
* @brief The token value.
*/
std::string token{};
/**
* @brief The date and time that this token was created, in RFC 3339 format.
*/
std::string dateAdded{};
/**
* @brief The date and time that this token was last modified, in RFC 3339
* format.
*/
std::string dateModified{};
/**
* @brief The date and time that this token was last used, in RFC 3339 format.
*/
std::string dateLastUsed{};
/**
* @brief The IDs of the assets that can be accessed using this token.
*
* If `std::nullopt`, the token allows access to all assets.
*/
std::optional<std::vector<int64_t>> assetIds{};
/**
* @brief True if this is the default token.
*/
bool isDefault{};
/**
* @brief The URLs from which this token can be accessed.
*
* If `std::nullopt`, the token can be accessed from any URL.
*/
std::optional<std::vector<std::string>> allowedUrls{};
/**
* @brief The scopes granted by this token.
*/
std::vector<std::string> scopes{};
};
} // namespace CesiumIonClient

View File

@ -0,0 +1,19 @@
#pragma once
#include "Token.h"
namespace CesiumIonClient {
/**
* @brief A list of Cesium ion access tokens, as returned by the "List Tokens"
* service.
*/
struct TokenList {
/**
* @brief The tokens.
*
*/
std::vector<Token> items;
};
} // namespace CesiumIonClient