AutopatcherPostgreRepository.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file
  11. /// \brief An implementation of the AutopatcherRepositoryInterface to use PostgreSQL to store the relevant data
  12. #define _USE_POSTGRE_REPOSITORY
  13. #ifdef _USE_POSTGRE_REPOSITORY
  14. #include "AutopatcherRepositoryInterface.h"
  15. #include "PostgreSQLInterface.h"
  16. #include "Export.h"
  17. struct pg_conn;
  18. typedef struct pg_conn PGconn;
  19. struct pg_result;
  20. typedef struct pg_result PGresult;
  21. #ifndef __POSTGRE_REPOSITORY_H
  22. #define __POSTGRE_REPOSITORY_H
  23. namespace RakNet
  24. {
  25. class FileListProgress;
  26. /// \ingroup Autopatcher
  27. /// An implementation of the AutopatcherRepositoryInterface to use PostgreSQL to store the relevant data
  28. class RAK_DLL_EXPORT AutopatcherPostgreRepository : public AutopatcherRepositoryInterface, public PostgreSQLInterface
  29. {
  30. public:
  31. AutopatcherPostgreRepository();
  32. virtual ~AutopatcherPostgreRepository();
  33. /// Create the tables used by the autopatcher, for all applications. Call this first.
  34. /// \return True on success, false on failure.
  35. virtual bool CreateAutopatcherTables(void);
  36. /// Destroy the tables used by the autopatcher. Don't call this unless you don't want to use the autopatcher anymore, or are testing.
  37. /// \return True on success, false on failure.
  38. bool DestroyAutopatcherTables(void);
  39. /// Add an application for use by files. Call this second.
  40. /// \param[in] applicationName A null terminated string.
  41. /// \param[in] userName Stored in the database, but otherwise unused. Useful to track who added this application.
  42. /// \return True on success, false on failure.
  43. bool AddApplication(const char *applicationName, const char *userName);
  44. /// Remove an application and files used by that application.
  45. /// \param[in] applicationName A null terminated string previously passed to AddApplication
  46. /// \return True on success, false on failure.
  47. bool RemoveApplication(const char *applicationName);
  48. /// Update all the files for an application to match what is at the specified directory. Call this third.
  49. /// Be careful not to call this with the wrong directory.
  50. /// This is implemented in a Begin and Rollback block so you won't a messed up database from get partial updates.
  51. /// \note It takes 10 bytes of memory to create a patch per byte on disk for a file. So you should not have any files larger than 1/10th your server memory.
  52. /// \param[in] applicationName A null terminated string previously passed to AddApplication
  53. /// \param[in] applicationDirectory The base directory of your application. All files in this directory and subdirectories are added.
  54. /// \param[in] userName Stored in the database, but otherwise unused. Useful to track who added this revision
  55. /// \param[in] cb Callback to get progress updates. Pass 0 to not use.
  56. /// \return True on success, false on failure.
  57. virtual bool UpdateApplicationFiles(const char *applicationName, const char *applicationDirectory, const char *userName, FileListProgress *cb);
  58. /// Get list of files added and deleted since a certain date. This is used by AutopatcherServer and not usually explicitly called.
  59. /// \param[in] applicationName A null terminated string previously passed to AddApplication
  60. /// \param[out] addedFiles A list of the current versions of filenames with SHA1_LENGTH byte hashes as their data that were created after \a sinceData
  61. /// \param[out] deletedFiles A list of the current versions of filenames that were deleted after \a sinceData
  62. /// \param[in] sinceDate
  63. /// \return True on success, false on failure.
  64. virtual bool GetChangelistSinceDate(const char *applicationName, FileList *addedOrModifiedFilesWithHashData, FileList *deletedFiles, double sinceDate);
  65. /// Get patches (or files) for every file in input, assuming that input has a hash for each of those files. This is used by AutopatcherServer and not usually explicitly called.
  66. /// \param[in] applicationName A null terminated string previously passed to AddApplication
  67. /// \param[in] input A list of files with hashes to get from the database. If this hash exists, a patch to the current version is returned if this file is not the current version. Otherwise the current version is returned.
  68. /// \param[in] allowDownloadOfOriginalUnmodifiedFiles If false, then if a file has never been modified and there is no hash for it in the input list, return false. This is to prevent clients from just downloading the game from the autopatcher.
  69. /// \param[out] patchList A list of files with either the filedata or the patch. This is a subset of \a input. The context data for each file will be either PC_WRITE_FILE (to just write the file) or PC_HASH_WITH_PATCH (to patch). If PC_HASH_WITH_PATCH, then the file contains a SHA1_LENGTH byte patch followed by the hash. The datalength is patchlength + SHA1_LENGTH
  70. /// \return 1 on success, 0 on database failure, -1 on tried to download original unmodified file
  71. virtual int GetPatches(const char *applicationName, FileList *input, bool allowDownloadOfOriginalUnmodifiedFiles, FileList *patchList);
  72. /// For the most recent update, return files that were patched, added, or deleted. For files that were patched, return both the patch in \a patchedFiles and the current version in \a updatedFiles
  73. /// \param[in,out] applicationName Name of the application to get patches for. If empty, uses the most recently updated application, and the string will be updated to reflect this name.
  74. /// \param[out] patchedFiles A list of patched files with op PC_HASH_2_WITH_PATCH. It has 2 hashes, the priorHash and the currentHash. The currentHash is checked on the client after patching for patch success. The priorHash is checked in AutopatcherServer::OnGetPatch() to see if the client is able to hash with the version they currently have
  75. /// \param[out] patchedFiles A list of new files. It contains the actual data in addition to the filename
  76. /// \param[out] addedOrModifiedFileHashes A list of file hashes that were either modified or new. This is returned to the client when replying to ID_AUTOPATCHER_CREATION_LIST, which tells the client what files have changed on the server since a certain date
  77. /// \param[out] deletedFiles A list of the current versions of filenames that were deleted in the most recent patch
  78. /// \param[out] whenPatched time in seconds since epoch when patched. Use time() function to get this in C
  79. /// \return true on success, false on failure
  80. virtual bool GetMostRecentChangelistWithPatches(RakNet::RakString &applicationName, FileList *patchedFiles, FileList *addedFiles, FileList *addedOrModifiedFileHashes, FileList *deletedFiles, double *priorRowPatchTime, double *mostRecentRowPatchTime);
  81. /// If any of the above functions fail, the error string is stored internally. Call this to get it.
  82. virtual const char *GetLastError(void) const;
  83. /// Read part of a file into \a destination
  84. /// Return the number of bytes written. Return 0 when file is done.
  85. /// \param[in] filename Filename to read
  86. /// \param[in] startReadBytes What offset from the start of the file to read from
  87. /// \param[in] numBytesToRead How many bytes to read. This is also how many bytes have been allocated to preallocatedDestination
  88. /// \param[out] preallocatedDestination Write your data here
  89. /// \return The number of bytes read, or 0 if none
  90. virtual unsigned int GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
  91. /// \return Passed to FileListTransfer::Send() as the _chunkSize parameter.
  92. virtual const int GetIncrementalReadChunkSize(void) const;
  93. // Use a separate connection for file parts, because PGConn is not threadsafe
  94. PGconn *filePartConnection;
  95. SimpleMutex filePartConnectionMutex;
  96. protected:
  97. virtual unsigned int GetPatchPart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
  98. };
  99. // This version references the version on the harddrive, rather than store the patch in the database
  100. // It is necessary if your game has files over about 400 megabytes.
  101. class RAK_DLL_EXPORT AutopatcherPostgreRepository2 : public AutopatcherPostgreRepository
  102. {
  103. public:
  104. virtual bool CreateAutopatcherTables(void);
  105. virtual bool GetMostRecentChangelistWithPatches(RakNet::RakString &applicationName, FileList *patchedFiles, FileList *addedFiles, FileList *addedOrModifiedFileHashes, FileList *deletedFiles, double *priorRowPatchTime, double *mostRecentRowPatchTime);
  106. virtual bool UpdateApplicationFiles(const char *applicationName, const char *applicationDirectory, const char *userName, FileListProgress *cb);
  107. virtual unsigned int GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
  108. /// Can override this to create patches using a different tool
  109. /// \param[in] oldFile Path to the old version of the file, on disk
  110. /// \param[in] newFile Path to the updated file, on disk
  111. /// \param[out] patch Pointer you should allocate, to hold the patch
  112. /// \param[out] patchLength Write the length of the resultant patch here
  113. /// \param[out] patchAlgorithm Stored in the database. Use if you want to represent what algorithm was used. Transmitted to the client for decompression
  114. virtual int MakePatch(const char *oldFile, const char *newFile, char **patch, unsigned int *patchLength, int *patchAlgorithm);
  115. protected:
  116. // Implements MakePatch using bsDiff. Uses a lot of memory, should not use for files above about 100 megabytes.
  117. virtual bool MakePatchBSDiff(FILE *fpOld, int contentLengthOld, FILE *fpNew, int contentLengthNew, char **patch, unsigned int *patchLength);
  118. };
  119. } // namespace RakNet
  120. #endif
  121. #endif
粤ICP备19079148号