Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 96 additions & 9 deletions src/storage/steam/SDL_steamstorage.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,20 @@ typedef struct STEAM_RemoteStorage
#include "SDL_steamstorage_proc.h"
} STEAM_RemoteStorage;

static SDL_AtomicInt SDL_steam_storage_refcount;

static bool STEAM_CloseStorage(void *userdata)
{
bool result = true;
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
bool end_batch = SDL_AtomicDecRef(&SDL_steam_storage_refcount);
if (steamremotestorage == NULL) {
result = SDL_SetError("SteamRemoteStorage unavailable");
} else if (!steam->SteamAPI_ISteamRemoteStorage_EndFileWriteBatch(steamremotestorage)) {
result = SDL_SetError("SteamRemoteStorage()->EndFileWriteBatch() failed");
} else if (end_batch) {
if (!steam->SteamAPI_ISteamRemoteStorage_EndFileWriteBatch(steamremotestorage)) {
result = SDL_SetError("SteamRemoteStorage()->EndFileWriteBatch() failed");
}
}
SDL_UnloadObject(steam->libsteam_api);
SDL_free(steam);
Expand All @@ -75,6 +80,67 @@ static bool STEAM_StorageReady(void *userdata)
return true;
}

static bool STEAM_EnumerateStorageDirectory(void *userdata, const char *path, SDL_EnumerateDirectoryCallback callback, void *callback_userdata)
{
bool result = true;
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
if (steamremotestorage == NULL) {
return SDL_SetError("SteamRemoteStorage unavailable");
}

const char *prefix;
if (SDL_strcmp(path, ".") == 0) {
prefix = "";
} else {
prefix = path;
while (*prefix == '/') {
++prefix;
}
}
size_t prefixlen = SDL_strlen(prefix);
while (prefixlen > 0 && prefix[prefixlen - 1] == '/') {
--prefixlen;
}

bool done = false;
Sint32 count = steam->SteamAPI_ISteamRemoteStorage_GetFileCount(steamremotestorage);
for (Sint32 i = 0; i < count && !done; ++i) {
const char *file = steam->SteamAPI_ISteamRemoteStorage_GetFileNameAndSize(steamremotestorage, i, NULL);
if (!file) {
continue;
}

const char *fname;
if (prefixlen > 0) {
// Make sure the prefix matches
if (SDL_strncmp(prefix, file, prefixlen) != 0 || *(file + prefixlen) != '/') {
continue;
}
fname = file + prefixlen + 1;
} else {
// Make sure this is a top-level file
if (SDL_strchr(file, '/') != NULL) {
continue;
}
fname = file;
}

switch (callback(callback_userdata, path, fname)) {
case SDL_ENUM_SUCCESS:
done = true;
break;
case SDL_ENUM_FAILURE:
result = false;
done = true;
break;
default:
break;
}
}
return result;
}

static bool STEAM_GetStoragePathInfo(void *userdata, const char *path, SDL_PathInfo *info)
{
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
Expand All @@ -83,10 +149,16 @@ static bool STEAM_GetStoragePathInfo(void *userdata, const char *path, SDL_PathI
return SDL_SetError("SteamRemoteStorage unavailable");
}

if (!steam->SteamAPI_ISteamRemoteStorage_FileExists(steamremotestorage, path)) {
return SDL_SetError("Can't stat");
}

if (info) {
SDL_zerop(info);
info->type = SDL_PATHTYPE_FILE;
info->size = steam->SteamAPI_ISteamRemoteStorage_GetFileSize(steamremotestorage, path);
Sint64 mtime = steam->SteamAPI_ISteamRemoteStorage_GetFileTimestamp(steamremotestorage, path);
info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(mtime);
}
return true;
}
Expand Down Expand Up @@ -129,6 +201,19 @@ static bool STEAM_WriteStorageFile(void *userdata, const char *path, const void
return result;
}

static bool STEAM_RemoveStoragePath(void *userdata, const char *path)
{
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
if (steamremotestorage == NULL) {
return SDL_SetError("SteamRemoteStorage unavailable");
}
if (!steam->SteamAPI_ISteamRemoteStorage_FileDelete(steamremotestorage, path)) {
return SDL_SetError("SteamRemoteStorage()->FileDelete() failed");
}
return true;
}

static Uint64 STEAM_GetStorageSpaceRemaining(void *userdata)
{
Uint64 total, remaining;
Expand All @@ -149,12 +234,12 @@ static const SDL_StorageInterface STEAM_user_iface = {
sizeof(SDL_StorageInterface),
STEAM_CloseStorage,
STEAM_StorageReady,
NULL, // enumerate
STEAM_EnumerateStorageDirectory,
STEAM_GetStoragePathInfo,
STEAM_ReadStorageFile,
STEAM_WriteStorageFile,
NULL, // mkdir
NULL, // remove
STEAM_RemoveStoragePath,
NULL, // rename
NULL, // copy
STEAM_GetStorageSpaceRemaining
Expand Down Expand Up @@ -198,15 +283,17 @@ static SDL_Storage *STEAM_User_Create(const char *org, const char *app, SDL_Prop
SDL_SetError("Steam cloud is disabled for this application");
goto steamfail;
}
if (!steam->SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch(steamremotestorage)) {
SDL_SetError("SteamRemoteStorage()->BeginFileWriteBatch() failed");
goto steamfail;
}

result = SDL_OpenStorage(&STEAM_user_iface, steam);
if (result == NULL) {
if (!result) {
goto steamfail;
}

if (SDL_AtomicIncRef(&SDL_steam_storage_refcount) == 0) {
if (!steam->SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch(steamremotestorage)) {
// We probably already have a batch in progress (maybe we crashed earlier?)
}
}
return result;

steamfail:
Expand Down
6 changes: 6 additions & 0 deletions src/storage/steam/SDL_steamstorage_proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp, (void*))
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch, (void*))
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_EndFileWriteBatch, (void*))

STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_FileExists, (void*, const char*))
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_GetFileSize, (void*, const char*))
STEAM_PROC(Sint64, SteamAPI_ISteamRemoteStorage_GetFileTimestamp, (void*, const char *))
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileRead, (void*, const char*, void*, Sint32))
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileWrite, (void*, const char*, const void*, Sint32))
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_FileDelete, (void*, const char*))
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_GetQuota, (void*, Uint64*, Uint64*))

STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_GetFileCount, (void*))
STEAM_PROC(const char *, SteamAPI_ISteamRemoteStorage_GetFileNameAndSize, (void*, int, Sint32*))

#undef STEAM_PROC
Loading