SA-MP/raknet/LightweightDatabaseServer.h
RD42 bcdbedc0be Revert RakNet source files back to the original v2.518 state
* Add RakNet source files to the VS project
2024-08-16 23:33:48 +08:00

148 lines
7.0 KiB
C++

/// \file
/// \brief A simple flat database included with RakNet, useful for a server browser or a lobby server.
///
/// This file is part of RakNet Copyright 2003 Kevin Jenkins.
///
/// Usage of RakNet is subject to the appropriate license agreement.
/// Creative Commons Licensees are subject to the
/// license found at
/// http://creativecommons.org/licenses/by-nc/2.5/
/// Single application licensees are subject to the license found at
/// http://www.rakkarsoft.com/SingleApplicationLicense.html
/// Custom license users are subject to the terms therein.
/// GPL license users are subject to the GNU General Public
/// License as published by the Free
/// Software Foundation; either version 2 of the License, or (at your
/// option) any later version.
#ifndef __LIGHTWEIGHT_DATABASE_SERVER_H
#define __LIGHTWEIGHT_DATABASE_SERVER_H
#include "Export.h"
#include "PluginInterface.h"
#include "LightweightDatabaseCommon.h"
#include "DS_Map.h"
class RakPeerInterface;
struct Packet;
/// \brief A simple flat database included with RakNet, useful for a server browser or a lobby server.
/// A flat database interface. Adds the ability to track IPs of row updaters and passwords for table read and write operations,
/// Best used for data in which queries which do not need to be updated in real-time
/// \ingroup SIMPLE_DATABSE_GROUP
class RAK_DLL_EXPORT LightweightDatabaseServer : public PluginInterface
{
public:
/// Constructor
LightweightDatabaseServer();
/// Destructor
~LightweightDatabaseServer();
/// Returns a table by name.
/// It is valid to read and write to the returned pointer.
/// \param[in] tableName The name of the table that was passed to AddTable
/// \return The requested table, or 0 if \a tableName cannot be found.
DataStructures::Table *GetTable(char *tableName);
/// Adds a new table
/// It is valid to read and write to the returned pointer.
/// \param[in] tableName Name of the new table to create. Remote systems will refer to this table by this name.
/// \param[in] allowRemoteQuery true to allow remote systems to query the table. false to not allow this.
/// \param[in] allowRemoteUpdate true to allow remote systems to update rows in the table. false to not allow this.
/// \param[in] allowRemoteRemove true to allow remote systems to remove rows from the table. false to not allow this.
/// \param[in] queryPassword The password required to query the table. Pass an empty string for no password.
/// \param[in] updatePassword The password required to update rows in the table. Pass an empty string for no password.
/// \param[in] removePassword The password required to remove rows from the table. Pass an empty string for no password.
/// \param[in] oneRowPerSystemId Only used if allowRemoteUpdate==true. This limits remote systems to one row.
/// \param[in] onlyUpdateOwnRows Only used if allowRemoteUpdate==true. This limits remote systems to only updating rows they created.
/// \param[in] removeRowOnPingFailure Only used if allowRemoteUpdate==true and removeRowOnDisconnect==false. If true, this will periodically ping disconnected systems and remove rows created by that system if that system does not respond to pings.
/// \param[in] removeRowOnDisconnect Only used if allowRemoteUpdate==true. This removes rows created by a system when that system disconnects.
/// \param[in] autogenerateRowIDs true to automatically generate row IDs. Rows are stored in order by row ID. If false, the clients must specify a unique row ID when adding rows. If they specify a row that already exists the addition is ignored.
/// \return The newly created table, or 0 on failure.
DataStructures::Table* AddTable(char *tableName,
bool allowRemoteQuery,
bool allowRemoteUpdate,
bool allowRemoteRemove,
char queryPassword[_SIMPLE_DATABASE_PASSWORD_LENGTH],
char updatePassword[_SIMPLE_DATABASE_PASSWORD_LENGTH],
char removePassword[_SIMPLE_DATABASE_PASSWORD_LENGTH],
bool oneRowPerSystemId,
bool onlyUpdateOwnRows,
bool removeRowOnPingFailure,
bool removeRowOnDisconnect,
bool autogenerateRowIDs);
/// Removes a table by name.
/// \param[in] tableName The name of the table that was passed to AddTable
/// \return true on success, false on failure.
bool RemoveTable(char *tableName);
/// Clears all memory.
void Clear(void);
// Gets the next valid auto-generated rowId for a table and increments it.
unsigned GetAndIncrementRowID(char *tableName);
/// Returns a linked list of ordered lists containing the rows of a table, by name.
/// The returned structure is internal to the BPlus tree. See DS_BPlusTree
/// This is a convenience accessor, as you can also get this from the table returned from GetTable()
/// \param[in] tableName The name of the table that was passed to AddTable
/// \return The requested rows, or 0 if \a tableName cannot be found.
DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *GetTableRows(char *tableName);
/// \internal For plugin handling
virtual void OnAttach(RakPeerInterface *peer);
/// \internal For plugin handling
virtual void Update(RakPeerInterface *peer);
/// \internal For plugin handling
virtual PluginReceiveResult OnReceive(RakPeerInterface *peer, Packet *packet);
/// \internal For plugin handling
virtual void OnDisconnect(RakPeerInterface *peer);
/// \internal For plugin handling
virtual void OnCloseConnection(RakPeerInterface *peer, PlayerID playerId);
struct DatabaseTable
{
bool allowRemoteUpdate;
bool allowRemoteQuery;
bool allowRemoteRemove;
char updatePassword[_SIMPLE_DATABASE_PASSWORD_LENGTH];
char queryPassword[_SIMPLE_DATABASE_PASSWORD_LENGTH];
char removePassword[_SIMPLE_DATABASE_PASSWORD_LENGTH];
bool oneRowPerSystemId;
bool onlyUpdateOwnRows;
bool removeRowOnPingFailure;
bool removeRowOnDisconnect;
bool autogenerateRowIDs;
char tableName[_SIMPLE_DATABASE_TABLE_NAME_LENGTH];
// Used if autogenerateRowIDs==true
unsigned nextRowId;
unsigned systemIdColumnIndex;
unsigned lastPingResponseColumnIndex;
unsigned nextPingSendColumnIndex;
RakNetTime nextRowPingCheck;
DataStructures::Table table;
};
static int DatabaseTableComp( char* const &key1, char* const &key2 );
protected:
DataStructures::Map<char *, LightweightDatabaseServer::DatabaseTable*, LightweightDatabaseServer::DatabaseTableComp> database;
void OnQueryRequest(RakPeerInterface *peer, Packet *packet);
void OnUpdateRow(RakPeerInterface *peer, Packet *packet);
void OnRemoveRow(RakPeerInterface *peer, Packet *packet);
void OnPong(RakPeerInterface *peer, Packet *packet);
// mode 0 = query, mode 1 = update, mode 2 = remove
DatabaseTable * DeserializeClientHeader(RakNet::BitStream *inBitstream, RakPeerInterface *peer, Packet *packet, int mode);
DataStructures::Table::Row * GetRowFromIP(DatabaseTable *databaseTable, PlayerID playerId, unsigned *rowId);
bool RowHasIP(DataStructures::Table::Row *row, PlayerID playerId, unsigned systemIdColumnIndex);
DataStructures::Table::Row * AddRow(LightweightDatabaseServer::DatabaseTable *databaseTable, PlayerID playerId, bool hasRowId, unsigned rowId);
void RemoveRowsFromIP(PlayerID playerId);
};
#endif