SQLiteServerLoggerPlugin.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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 Extends SQLite3ServerPlugin to support logging functions, including compressing images.
  12. ///
  13. #ifndef ___SQLITE_SERVER_LOGGER_PLUGIN_H
  14. #define ___SQLITE_SERVER_LOGGER_PLUGIN_H
  15. #include "SQLite3ServerPlugin.h"
  16. #include "SQLiteLoggerCommon.h"
  17. class RakPeerInterface;
  18. #define MAX_PACKETS_PER_CPU_INPUT_THREAD 16
  19. namespace RakNet
  20. {
  21. /// \brief Extends SQLite3ServerPlugin to support logging functions, including compressing images.
  22. /// \details SQLiteClientLoggerPlugin has the ability to send logs. Logs contain a description of the name of the table, the name of the columns, the types, and the data.<BR>
  23. /// This class will create tables as necessary to support the client inputs.<BR>
  24. /// Also, if images are sent, the server will format them from uncompressed to compressed JPG using jpeg-7 in a thread.<BR>
  25. /// Compatible as a plugin with both RakPeerInterface and PacketizedTCP
  26. /// \ingroup SQL_LITE_3_PLUGIN
  27. class RAK_DLL_EXPORT SQLiteServerLoggerPlugin : public SQLite3ServerPlugin
  28. {
  29. public:
  30. SQLiteServerLoggerPlugin();
  31. virtual ~SQLiteServerLoggerPlugin();
  32. /// Used with SetSessionManagementMode()
  33. enum SessionManagementMode
  34. {
  35. /// \brief USE_ANY_DB_HANDLE is for games where the clients are not allowed to create new databases, and the clients don't care which database is written to. Typically only used if there is only one database ever.
  36. /// \details Ignore SQLiteClientLoggerPlugin::StartSession(), and rely on a prior call to SQLite3ServerPlugin::AddDBHandle().
  37. /// If no handles exist, logging calls silently fail.
  38. USE_ANY_DB_HANDLE,
  39. /// \brief USE_NAMED_DB_HANDLE is for games where the clients are not allowed to create new databases. Instead, they use named databases precreated.
  40. /// \details Interpret the sessionId parameter passed to SQLiteClientLoggerPlugin::StartSession() as the dbIdentifier parameter passed to SQLite3ServerPlugin::AddDBHandle().
  41. /// Use this database if it exists. If not, logging calls silently fail.
  42. USE_NAMED_DB_HANDLE,
  43. /// \brief CREATE_EACH_NAMED_DB_HANDLE is for single player games or multiplayer games where every game has a unique sesionId.
  44. /// \details Use the sessionId parameter passed to SQLiteClientLoggerPlugin::StartSession() as a dbIdentifier.
  45. /// A new database is created for each user
  46. CREATE_EACH_NAMED_DB_HANDLE,
  47. /// \brief CREATE_SHARED_NAMED_DB_HANDLE is for multiplayer games where you don't want to have to transmit and synchronize a unique sessionId. Everyone is in the same sessionId.
  48. /// \details Use the sessionId parameter passed to SQLiteClientLoggerPlugin::StartSession() as a dbIdentifier.
  49. /// A new database is created only if the sessionId is different. Two users using the same sessionId will write to the same database
  50. CREATE_SHARED_NAMED_DB_HANDLE,
  51. };
  52. /// \brief Determine if and how to automatically create databases, rather than call SQLite3ServerPlugin::AddDBHandle()
  53. /// \details Typically you want one database to hold the events of a single application session, rather than one database for all sessions over all time.
  54. /// A user of SQLiteClientLoggerPlugin can optionally call SQLiteClientLoggerPlugin::StartSession() in order to join a session to enable this.
  55. /// Call this before calling AddDBHandle(), and before any clients connect
  56. /// \param[in] _sessionManagementMode See SessionManagementMode. Default is CREATE_EACH_NAMED_DB_HANDLE.
  57. /// \param[in] _createDirectoryForFile If true, uses the current server date as a directory to the filename. This ensures filenames do not overwrite each other, even if the sessionId is reused. Defaults to true.
  58. /// \param[in] _newDatabaseFilePath For CREATE_EACH_NAMED_DB_HANDLE and CREATE_SHARED_NAMED_DB_HANDLE, will create the databases here. Not used for the other modes. Defaults to whatever the operating system picks (usually the application directory).
  59. void SetSessionManagementMode(SessionManagementMode _sessionManagementMode, bool _createDirectoryForFile, const char *_newDatabaseFilePath);
  60. /// Close all connected sessions, writing all databases immediately
  61. void CloseAllSessions(void);
  62. /// \brief Enable using realtime shader based DXT compression on an Nvidia based video card. This will activate OpenGL
  63. /// \details Call this before anyone connects.
  64. /// If not enabled, or initialization fails, then jpg compression is used instead on the CPU.
  65. /// Defaults to false, in case the target system does not support OpenGL
  66. /// \param[in] enable True to enable, false to disable.
  67. void SetEnableDXTCompression(bool enable);
  68. struct ProcessingStatus
  69. {
  70. int packetsBuffered;
  71. int cpuPendingProcessing;
  72. int cpuProcessedAwaitingDeallocation;
  73. int cpuNumThreadsWorking;
  74. int sqlPendingProcessing;
  75. int sqlProcessedAwaitingDeallocation;
  76. int sqlNumThreadsWorking;
  77. };
  78. /// Return the thread and command processing statuses
  79. void GetProcessingStatus(ProcessingStatus *processingStatus);
  80. /// \internal
  81. void Update(void);
  82. /// \internal For plugin handling
  83. virtual PluginReceiveResult OnReceive(Packet *packet);
  84. /// \internal For plugin handling
  85. virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
  86. /// \internal For plugin handling
  87. virtual void OnShutdown(void);
  88. virtual void OnAttach(void);
  89. virtual void OnDetach(void);
  90. struct SessionNameAndSystemAddress
  91. {
  92. RakNet::RakString sessionName;
  93. SystemAddress systemAddress;
  94. sqlite3 *referencedPointer;
  95. RakNet::TimeMS timestampDelta;
  96. // RakNet::TimeMS dbAgeWhenCreated;
  97. };
  98. DataStructures::List<SessionNameAndSystemAddress> loggedInSessions;
  99. // An incoming data packet, and when it arrived
  100. struct CPUThreadInputNode
  101. {
  102. RakNet::Packet *packet;
  103. // RakNet::TimeMS whenMessageArrived;
  104. // Time difference from their time to server time, plus the age of the database at the time the session was created
  105. // Applied to CPUThreadOutputNode::clientSendingTime before being passed to SQL
  106. RakNet::TimeMS timestampDelta;
  107. RakNet::RakString dbIdentifier;
  108. };
  109. // As packets arrive, they are added to a CPUThreadInput structure.
  110. // When the structure is full, or when a maximum amount of time has elapsed, whichever is first, then it is pushed to a thread for processing
  111. // Deallocated in the thread
  112. struct CPUThreadInput
  113. {
  114. // One or more incoming data packets, and when those packets arrived
  115. // Processed on the CPU, possibly with batch processing for image compression
  116. CPUThreadInputNode cpuInputArray[MAX_PACKETS_PER_CPU_INPUT_THREAD];
  117. int arraySize;
  118. };
  119. // Each CPUThreadInputNode is unpacked to a CPUThreadOutputNode
  120. // Images are now in compressed format, should the parameter list indeed have a query
  121. struct CPUThreadOutputNode
  122. {
  123. RakNet::Packet *packet; // Passthrough
  124. // RakNet::TimeMS whenMessageArrived; // Passthrough
  125. RakNet::RakString dbIdentifier; // Passthrough
  126. // SystemAddress systemAddress;
  127. char ipAddressString[32];
  128. RakNet::RakString tableName;
  129. RakNet::RakString file;
  130. RakNet::TimeMS clientSendingTime;
  131. unsigned char parameterCount;
  132. bool isFunctionCall;
  133. DataStructures::List<RakNet::RakString> insertingColumnNames;
  134. LogParameter parameterList[MAX_SQLLITE_LOGGER_PARAMETERS];
  135. uint32_t tickCount;
  136. int line;
  137. };
  138. // List of CPUThreadOutputNode
  139. struct CPUThreadOutput
  140. {
  141. // cpuOutputNodeArray pointers are not deallocated, just handed over to SQLThreadInput
  142. // Each element in the array is pushed to one SQLThreadInput
  143. CPUThreadOutputNode *cpuOutputNodeArray[MAX_PACKETS_PER_CPU_INPUT_THREAD];
  144. int arraySize;
  145. };
  146. struct SQLThreadInput
  147. {
  148. sqlite3 *dbHandle;
  149. CPUThreadOutputNode *cpuOutputNode;
  150. };
  151. struct SQLThreadOutput
  152. {
  153. // cpuOutputNode gets deallocated here
  154. CPUThreadOutputNode *cpuOutputNode;
  155. };
  156. protected:
  157. unsigned int CreateDBHandle(RakNet::RakString dbIdentifier);
  158. void CloseUnreferencedSessions(void);
  159. SessionManagementMode sessionManagementMode;
  160. bool createDirectoryForFile;
  161. RakNet::RakString newDatabaseFilePath;
  162. ThreadPool<CPUThreadInput*, CPUThreadOutput*> cpuLoggerThreadPool;
  163. ThreadPool<SQLThreadInput, SQLThreadOutput> sqlLoggerThreadPool;
  164. CPUThreadInput *LockCpuThreadInput(void);
  165. void ClearCpuThreadInput(void);
  166. void UnlockCpuThreadInput(void);
  167. void CancelLockCpuThreadInput(void);
  168. void PushCpuThreadInputIfNecessary(void);
  169. void PushCpuThreadInput(void);
  170. void StopCPUSQLThreads(void);
  171. CPUThreadInput *cpuThreadInput;
  172. RakNet::TimeMS whenCpuThreadInputAllocated;
  173. bool dxtCompressionEnabled;
  174. };
  175. };
  176. #endif
粤ICP备19079148号