DirectoryDeltaTransfer.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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 DirectoryDeltaTransfer.h
  11. /// \brief Simple class to send changes between directories.
  12. /// \details In essence, a simple autopatcher that can be used for transmitting levels, skins, etc.
  13. ///
  14. #include "NativeFeatureIncludes.h"
  15. #if _RAKNET_SUPPORT_DirectoryDeltaTransfer==1 && _RAKNET_SUPPORT_FileOperations==1
  16. #ifndef __DIRECTORY_DELTA_TRANSFER_H
  17. #define __DIRECTORY_DELTA_TRANSFER_H
  18. #include "RakMemoryOverride.h"
  19. #include "RakNetTypes.h"
  20. #include "Export.h"
  21. #include "PluginInterface2.h"
  22. #include "DS_Map.h"
  23. #include "PacketPriority.h"
  24. /// \defgroup DIRECTORY_DELTA_TRANSFER_GROUP DirectoryDeltaTransfer
  25. /// \brief Simple class to send changes between directories
  26. /// \details
  27. /// \ingroup PLUGINS_GROUP
  28. /// \brief Simple class to send changes between directories. In essence, a simple autopatcher that can be used for transmitting levels, skins, etc.
  29. /// \details
  30. /// \sa AutopatcherClient class for database driven patching, including binary deltas and search by date.
  31. ///
  32. /// To use, first set the path to your application. For example "C:/Games/MyRPG/"<BR>
  33. /// To allow other systems to download files, call AddUploadsFromSubdirectory, where the parameter is a path relative<BR>
  34. /// to the path to your application. This includes subdirectories.<BR>
  35. /// For example:<BR>
  36. /// SetApplicationDirectory("C:/Games/MyRPG/");<BR>
  37. /// AddUploadsFromSubdirectory("Mods/Skins/");<BR>
  38. /// would allow downloads from<BR>
  39. /// "C:/Games/MyRPG/Mods/Skins/*.*" as well as "C:/Games/MyRPG/Mods/Skins/Level1/*.*"<BR>
  40. /// It would NOT allow downloads from C:/Games/MyRPG/Levels, nor would it allow downloads from C:/Windows<BR>
  41. /// While pathToApplication can be anything you want, applicationSubdirectory must match either partially or fully between systems.
  42. /// \ingroup DIRECTORY_DELTA_TRANSFER_GROUP
  43. namespace RakNet
  44. {
  45. /// Forward declarations
  46. class RakPeerInterface;
  47. class FileList;
  48. struct Packet;
  49. struct InternalPacket;
  50. struct DownloadRequest;
  51. class FileListTransfer;
  52. class FileListTransferCBInterface;
  53. class FileListProgress;
  54. class IncrementalReadInterface;
  55. class RAK_DLL_EXPORT DirectoryDeltaTransfer : public PluginInterface2
  56. {
  57. public:
  58. // GetInstance() and DestroyInstance(instance*)
  59. STATIC_FACTORY_DECLARATIONS(DirectoryDeltaTransfer)
  60. // Constructor
  61. DirectoryDeltaTransfer();
  62. // Destructor
  63. virtual ~DirectoryDeltaTransfer();
  64. /// \brief This plugin has a dependency on the FileListTransfer plugin, which it uses to actually send the files.
  65. /// \details So you need an instance of that plugin registered with RakPeerInterface, and a pointer to that interface should be passed here.
  66. /// \param[in] flt A pointer to a registered instance of FileListTransfer
  67. void SetFileListTransferPlugin(FileListTransfer *flt);
  68. /// \brief Set the local root directory to base all file uploads and downloads off of.
  69. /// \param[in] pathToApplication This path will be prepended to \a applicationSubdirectory in AddUploadsFromSubdirectory to find the actual path on disk.
  70. void SetApplicationDirectory(const char *pathToApplication);
  71. /// \brief What parameters to use for the RakPeerInterface::Send() call when uploading files.
  72. /// \param[in] _priority See RakPeerInterface::Send()
  73. /// \param[in] _orderingChannel See RakPeerInterface::Send()
  74. void SetUploadSendParameters(PacketPriority _priority, char _orderingChannel);
  75. /// \brief Add all files in the specified subdirectory recursively.
  76. /// \details \a subdir is appended to \a pathToApplication in SetApplicationDirectory().
  77. /// All files in the resultant directory and subdirectories are then hashed so that users can download them.
  78. /// \pre You must call SetFileListTransferPlugin with a valid FileListTransfer plugin
  79. /// \param[in] subdir Concatenated with pathToApplication to form the final path from which to allow uploads.
  80. void AddUploadsFromSubdirectory(const char *subdir);
  81. /// \brief Downloads files from the matching parameter \a subdir in AddUploadsFromSubdirectory.
  82. /// \details \a subdir must contain all starting characters in \a subdir in AddUploadsFromSubdirectory
  83. /// Therefore,
  84. /// AddUploadsFromSubdirectory("Levels/Level1/"); would allow you to download using DownloadFromSubdirectory("Levels/Level1/Textures/"...
  85. /// but it would NOT allow you to download from DownloadFromSubdirectory("Levels/"... or DownloadFromSubdirectory("Levels/Level2/"...
  86. /// \pre You must call SetFileListTransferPlugin with a valid FileListTransfer plugin
  87. /// \note Blocking. Will block while hashes of the local files are generated
  88. /// \param[in] subdir A directory passed to AddUploadsFromSubdirectory on the remote system. The passed dir can be more specific than the remote dir.
  89. /// \param[in] outputSubdir The directory to write the output to. Usually this will match \a subdir but it can be different if you want.
  90. /// \param[in] prependAppDirToOutputSubdir True to prepend outputSubdir with pathToApplication when determining the final output path. Usually you want this to be true.
  91. /// \param[in] host The address of the remote system to send the message to.
  92. /// \param[in] onFileCallback Callback to call per-file (optional). When fileIndex+1==setCount in the callback then the download is done
  93. /// \param[in] _priority See RakPeerInterface::Send()
  94. /// \param[in] _orderingChannel See RakPeerInterface::Send()
  95. /// \param[in] cb Callback to get progress updates. Pass 0 to not use.
  96. /// \return A set ID, identifying this download set. Returns 65535 on host unreachable.
  97. unsigned short DownloadFromSubdirectory(const char *subdir, const char *outputSubdir, bool prependAppDirToOutputSubdir, SystemAddress host, FileListTransferCBInterface *onFileCallback, PacketPriority _priority, char _orderingChannel, FileListProgress *cb);
  98. /// \brief Downloads files from the matching parameter \a subdir in AddUploadsFromSubdirectory.
  99. /// \details \a subdir must contain all starting characters in \a subdir in AddUploadsFromSubdirectory
  100. /// Therefore,
  101. /// AddUploadsFromSubdirectory("Levels/Level1/"); would allow you to download using DownloadFromSubdirectory("Levels/Level1/Textures/"...
  102. /// but it would NOT allow you to download from DownloadFromSubdirectory("Levels/"... or DownloadFromSubdirectory("Levels/Level2/"...
  103. /// \pre You must call SetFileListTransferPlugin with a valid FileListTransfer plugin
  104. /// \note Nonblocking, but requires call to GenerateHashes()
  105. /// \param[in] localFiles Hashes of local files already on the harddrive. Populate with GenerateHashes(), which you may wish to call from a thread
  106. /// \param[in] subdir A directory passed to AddUploadsFromSubdirectory on the remote system. The passed dir can be more specific than the remote dir.
  107. /// \param[in] outputSubdir The directory to write the output to. Usually this will match \a subdir but it can be different if you want.
  108. /// \param[in] prependAppDirToOutputSubdir True to prepend outputSubdir with pathToApplication when determining the final output path. Usually you want this to be true.
  109. /// \param[in] host The address of the remote system to send the message to.
  110. /// \param[in] onFileCallback Callback to call per-file (optional). When fileIndex+1==setCount in the callback then the download is done
  111. /// \param[in] _priority See RakPeerInterface::Send()
  112. /// \param[in] _orderingChannel See RakPeerInterface::Send()
  113. /// \param[in] cb Callback to get progress updates. Pass 0 to not use.
  114. /// \return A set ID, identifying this download set. Returns 65535 on host unreachable.
  115. unsigned short DownloadFromSubdirectory(FileList &localFiles, const char *subdir, const char *outputSubdir, bool prependAppDirToOutputSubdir, SystemAddress host, FileListTransferCBInterface *onFileCallback, PacketPriority _priority, char _orderingChannel, FileListProgress *cb);
  116. /// Hash files already on the harddrive, in preparation for a call to DownloadFromSubdirectory(). Passed to second version of DownloadFromSubdirectory()
  117. /// This is slow, and it is exposed so you can call it from a thread before calling DownloadFromSubdirectory()
  118. /// \param[out] localFiles List of hashed files populated from \a outputSubdir and \a prependAppDirToOutputSubdir
  119. /// \param[in] outputSubdir The directory to write the output to. Usually this will match \a subdir but it can be different if you want.
  120. /// \param[in] prependAppDirToOutputSubdir True to prepend outputSubdir with pathToApplication when determining the final output path. Usually you want this to be true.
  121. void GenerateHashes(FileList &localFiles, const char *outputSubdir, bool prependAppDirToOutputSubdir);
  122. /// \brief Clear all allowed uploads previously set with AddUploadsFromSubdirectory
  123. void ClearUploads(void);
  124. /// \brief Returns how many files are available for upload
  125. /// \return How many files are available for upload
  126. unsigned GetNumberOfFilesForUpload(void) const;
  127. /// \brief Normally, if a remote system requests files, those files are all loaded into memory and sent immediately.
  128. /// \details This function allows the files to be read in incremental chunks, saving memory
  129. /// \param[in] _incrementalReadInterface If a file in \a fileList has no data, filePullInterface will be used to read the file in chunks of size \a chunkSize
  130. /// \param[in] _chunkSize How large of a block of a file to send at once
  131. void SetDownloadRequestIncrementalReadInterface(IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize);
  132. /// \internal For plugin handling
  133. virtual PluginReceiveResult OnReceive(Packet *packet);
  134. protected:
  135. void OnDownloadRequest(Packet *packet);
  136. char applicationDirectory[512];
  137. FileListTransfer *fileListTransfer;
  138. FileList *availableUploads;
  139. PacketPriority priority;
  140. char orderingChannel;
  141. IncrementalReadInterface *incrementalReadInterface;
  142. unsigned int chunkSize;
  143. };
  144. } // namespace RakNet
  145. #endif
  146. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号