1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Utility helper functions for dealing with UGC files
//
//==========================================================================//
#ifndef UGC_UTILS_H
#define UGC_UTILS_H
#include "utlbuffer.h"
#include "filesystem.h"
#include "steam/steam_api.h"
#include "dbg.h"
// All UGC files are assumed to be on this path by default
#define UGC_PATHID "DEFAULT_WRITE_PATH"
// This will log the UGC file requests as they're serviced
// #define LOG_FILEREQUEST_PROGRESS
// Enable verbose debug spew to DevMsg
// #define UGC_DEBUG
#define UGCMsg(...) Msg("[UGC] " __VA_ARGS__)
#define UGCWarning(...) Warning("[UGC] " __VA_ARGS__)
#ifdef UGC_DEBUG
#define UGCDebug(...) DevMsg("[UGC Debug] " __VA_ARGS__)
#else // UGC_DEBUG
#define UGCDebug(...)
#endif // UGC_DEBUG
ISteamUGC *GetSteamUGC();
ISteamRemoteStorage *GetSteamRemoteStorage();
// Consistently set/get modified/access timestamps for UGC files.
bool UGC_SetFileTime( const char *pFileRelativePath, RTime32 uTimestamp );
// Simulates stalling of the file IO for testing
// #define FILEREQUEST_IO_STALL
#define FILEREQUEST_IO_STALL_DELAY 1.0f // Seconds
enum UGCFileRequestStatus_t
{
UGCFILEREQUEST_ERROR = -1, // An error occurred while processing the file operation
UGCFILEREQUEST_READY, // File request is ready to do work
UGCFILEREQUEST_DOWNLOADING, // Currently downloading a file
UGCFILEREQUEST_DOWNLOAD_WRITING, // Async write of the downloaded file to the disc
UGCFILEREQUEST_UPLOADING, // Currently uploading a file
UGCFILEREQUEST_FINISHED // Operation complete, no work waiting
};
#ifdef FILEREQUEST_IO_STALL
enum
{
FILEREQUEST_STALL_NONE,
FILEREQUEST_STALL_DOWNLOAD, // Download from UGC server
FILEREQUEST_STALL_WRITE, // Write to disc
};
#endif // FILEREQUEST_IO_STALL
// FIXME(johns): This is superseded by the newer CUGCSyncedFile. Once the
// remaining users of this are migrated it should be nuked.
class CUGCFileRequest
{
public:
CUGCFileRequest( void );
~CUGCFileRequest( void );
UGCFileRequestStatus_t StartDownload( UGCHandle_t hFileHandle, const char *lpszTargetDirectory = NULL, const char *lpszTargetFilename = NULL );
UGCFileRequestStatus_t StartUpload( CUtlBuffer &buffer, const char *lpszFilename );
UGCFileRequestStatus_t Update( void );
UGCFileRequestStatus_t GetStatus( void ) const { return m_UGCStatus; }
// Accessors
const char *GetFileName( void ) { return ( m_szTargetFilename[0] == '\0' ) ? m_szFileName : m_szTargetFilename; }
const char *GetLastError( void ) const { return m_szErrorText; }
UGCHandle_t GetCloudHandle( void ) const { return m_hCloudID; }
void GetLocalFileName( char *pDest, size_t strSize );
void GetLocalDirectory( char *pDest, size_t strSize );
private:
CCallResult<CUGCFileRequest, RemoteStorageDownloadUGCResult_t> m_callbackUGCDownload;
void Steam_OnUGCDownload( RemoteStorageDownloadUGCResult_t *pResult, bool bError );
CCallResult<CUGCFileRequest, RemoteStorageFileShareResult_t> m_callbackFileShare;
void Steam_OnFileShare( RemoteStorageFileShareResult_t *pResult, bool bError );
//
// Marks the file request as complete and frees its internal buffers
//
void MarkCompleteAndFree( void )
{
m_bufContents.Clear();
m_UGCStatus = UGCFILEREQUEST_FINISHED;
}
//
// Sets the file request into an error state
//
UGCFileRequestStatus_t ThrowError( const char *lpszDesc )
{
V_strncpy( m_szErrorText, lpszDesc, ARRAYSIZE(m_szErrorText) );
Warning( "%s", m_szErrorText );
Assert(0);
m_UGCStatus = UGCFILEREQUEST_ERROR;
return m_UGCStatus;
}
private:
char m_szTargetDirectory[MAX_PATH]; // If specified, the directory the file will be placed in
char m_szTargetFilename[MAX_PATH]; // If specified, this name overrides the UGC filename
char m_szFileName[MAX_PATH]; // Filename of in the cloud structure
SteamAPICall_t m_hSteamAPICall; // Used to track Steam API calls which are non-blocking
CUtlBuffer m_bufContents; // Contents of the file once read from the cloud
UGCHandle_t m_hCloudID; // Cloud handle of this request
FSAsyncControl_t m_AsyncControl; // Handle for the async requests this class can initiate
UGCFileRequestStatus_t m_UGCStatus; // The current status of this request
char m_szErrorText[512]; // Holds information if an error occurred
#ifdef FILEREQUEST_IO_STALL
// Debug data
float m_flIOStallDuration; // Amount of time (in seconds) to stall all IO operations
int m_nIOStallType; // Type of stall (0 - none, 1 - download, 2 - write )
float m_flIOStallStart;
#endif // FILEREQUEST_IO_STALL
};
#endif //UGC_UTILS_H
|