This commit is contained in:
2025-11-24 14:19:51 +05:30
commit f5c1412b28
6734 changed files with 1527575 additions and 0 deletions

View File

@ -0,0 +1,609 @@
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*/
#include "LibVoice.h"

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*/
/// \file LibVoice.h
/// \brief Implements libvoice for PS3 and Vita
///
#include "NativeFeatureIncludes.h"

View File

@ -0,0 +1,132 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Client.h"
#include "slikenet/assert.h"
#include "slikenet/MessageIdentifiers.h"
using namespace SLNet;
Lobby2Client::Lobby2Client()
{
serverAddress= SLNet::UNASSIGNED_SYSTEM_ADDRESS;
}
Lobby2Client::~Lobby2Client()
{
}
void Lobby2Client::SetServerAddress(SystemAddress addr)
{
serverAddress=addr;
}
SystemAddress Lobby2Client::GetServerAddress(void) const
{
return serverAddress;
}
void Lobby2Client::SendMsg(Lobby2Message *msg)
{
// Callback must be ready to receive reply
RakAssert(callbacks.Size());
msg->resultCode=L2RC_PROCESSING;
SLNet::BitStream bs;
bs.Write((MessageID)ID_LOBBY2_SEND_MESSAGE);
bs.Write((MessageID)msg->GetID());
msg->Serialize(true,false,&bs);
SendUnified(&bs,packetPriority, RELIABLE_ORDERED, orderingChannel, serverAddress, false);
}
void Lobby2Client::SendMsgAndDealloc(Lobby2Message *msg)
{
SendMsg(msg);
msgFactory->Dealloc(msg);
}
PluginReceiveResult Lobby2Client::OnReceive(Packet *packet)
{
RakAssert(packet);
switch (packet->data[0])
{
case ID_LOBBY2_SEND_MESSAGE:
OnMessage(packet);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
return RR_CONTINUE_PROCESSING;
}
void Lobby2Client::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
(void)systemAddress;
(void)rakNetGUID;
(void)lostConnectionReason;
// if (systemAddress==serverAddress)
// ClearIgnoreList();
}
void Lobby2Client::OnShutdown(void)
{
// ClearIgnoreList();
}
void Lobby2Client::OnMessage(Packet *packet)
{
SLNet::BitStream bs(packet->data,packet->length,false);
bs.IgnoreBytes(1); // ID_LOBBY2_SEND_MESSAGE
MessageID msgId;
bs.Read(msgId);
Lobby2MessageID lobby2MessageID = (Lobby2MessageID) msgId;
Lobby2Message *lobby2Message = msgFactory->Alloc(lobby2MessageID);
if (lobby2Message)
{
lobby2Message->Serialize(false,true,&bs);
if (lobby2Message->ClientImpl(this))
{
for (unsigned long i=0; i < callbacks.Size(); i++)
{
if (lobby2Message->callbackId==(uint32_t)-1 || lobby2Message->callbackId==callbacks[i]->callbackId)
lobby2Message->CallCallback(callbacks[i]);
}
}
msgFactory->Dealloc(lobby2Message);
}
else
{
RakAssert("Lobby2Client::OnMessage lobby2Message==0" && 0);
}
}
/*
void Lobby2Client::AddToIgnoreList(SLNet::RakString user)
{
ignoreList.Insert(user,user,false);
}
void Lobby2Client::RemoveFromIgnoreList(SLNet::RakString user)
{
ignoreList.RemoveIfExists(user);
}
void Lobby2Client::SetIgnoreList(DataStructures::List<SLNet::RakString> users)
{
for (unsigned int i=0; i < users.Size(); i++)
ignoreList.Insert(users[i],users[i],false);
}
bool Lobby2Client::IsInIgnoreList(SLNet::RakString user) const
{
return ignoreList.HasData(user);
}
void Lobby2Client::ClearIgnoreList(void)
{
ignoreList.Clear(_FILE_AND_LINE_);
}
const DataStructures::OrderedList<SLNet::RakString, SLNet::RakString>* Lobby2Client::GetIgnoreList(void) const
{
return &ignoreList;
}
*/

View File

@ -0,0 +1,89 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_CLIENT_H
#define __LOBBY_2_CLIENT_H
#include "Lobby2Plugin.h"
#include "slikenet/DS_OrderedList.h"
namespace SLNet
{
struct Lobby2Message;
/// \brief Class used to send commands to Lobby2Server
/// \details The lobby system works by sending implementations of Lobby2Message from Lobby2Client to Lobby2Server, and getting the results via Lobby2Client::SetCallbackInterface()<BR>
/// The client itself is a thin shell that does little more than call Serialize on the messages.<BR>
/// To use:<BR>
/// <OL>
/// <LI>Call Lobby2Client::SetServerAddress() after connecting to the system running Lobby2Server.
/// <LI>Instantiate an instance of SLNet::Lobby2MessageFactory and register it with SLNet::Lobby2Plugin::SetMessageFactory() (the base class of Lobby2Client)
/// <LI>Call messageFactory.Alloc(command); where command is one of the Lobby2MessageID enumerations.
/// <LI>Instantiate a (probably derived) instance of Lobby2Callbacks and register it with Lobby2Client::SetCallbackInterface()
/// <LI>Cast the returned structure, fill in the input parameters, and call Lobby2Client::SendMsg() to send this command to the server.
/// <LI>Wait for the result of the operation to be sent to your callback. The message will contain the original input parameters, possibly output parameters, and Lobby2Message::resultCode will be filled in.
/// </OL>
/// \ingroup LOBBY_2_CLIENT
class RAK_DLL_EXPORT Lobby2Client : public SLNet::Lobby2Plugin
{
public:
Lobby2Client();
virtual ~Lobby2Client();
/// \brief Set the address of the server. When you call SendMsg() the packet will be sent to this address.
void SetServerAddress(SystemAddress addr);
// \brief Return whatever was passed to SetServerAddress()
SystemAddress GetServerAddress(void) const;
/// \brief Send a command to the server
/// \param[in] msg The message that represents the command
/// \param[in] callbackId Which callback, registered with SetCallbackInterface() or AddCallbackInterface(), should process the result. -1 for all
virtual void SendMsg(Lobby2Message *msg);
/// \brief Same as SendMsg()
/// Also calls Dealloc on the message factory
virtual void SendMsgAndDealloc(Lobby2Message *msg);
// Let the user do this if they want. Not all users may want ignore lists
/*
/// For convenience, the list of ignored users is populated when Client_GetIgnoreList, Client_StopIgnore, and Client_StartIgnore complete.
/// Client_GetIgnoreList is sent to us from the server automatically on login.
/// The main reason this is here is so if you use RoomsPlugin as a client, you can check this list to filter out chat messages from ignored users.
/// This is just a list of strings for you to read - it does NOT actually perform the ignore operation.
virtual void AddToIgnoreList(SLNet::RakString user);
virtual void RemoveFromIgnoreList(SLNet::RakString user);
virtual void SetIgnoreList(DataStructures::List<SLNet::RakString> users);
virtual bool IsInIgnoreList(SLNet::RakString user) const;
void ClearIgnoreList(void);
const DataStructures::OrderedList<SLNet::RakString, SLNet::RakString>* GetIgnoreList(void) const;
DataStructures::OrderedList<SLNet::RakString, SLNet::RakString> ignoreList;
*/
protected:
PluginReceiveResult OnReceive(Packet *packet);
void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
void OnShutdown(void);
void OnMessage(Packet *packet);
SystemAddress serverAddress;
Lobby2Callbacks *callback;
};
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Plugin.h"
using namespace SLNet;
Lobby2Plugin::Lobby2Plugin()
{
orderingChannel=0;
packetPriority=HIGH_PRIORITY;
}
Lobby2Plugin::~Lobby2Plugin()
{
}
void Lobby2Plugin::SetOrderingChannel(char oc)
{
orderingChannel=oc;
}
void Lobby2Plugin::SetSendPriority(PacketPriority pp)
{
packetPriority=pp;
}
void Lobby2Plugin::SetMessageFactory(Lobby2MessageFactory *f)
{
msgFactory=f;
}
Lobby2MessageFactory* Lobby2Plugin::GetMessageFactory(void) const
{
return msgFactory;
}
void Lobby2Plugin::SetCallbackInterface(Lobby2Callbacks *cb)
{
ClearCallbackInterfaces();
callbacks.Insert(cb, _FILE_AND_LINE_ );
}
void Lobby2Plugin::AddCallbackInterface(Lobby2Callbacks *cb)
{
RemoveCallbackInterface(cb);
callbacks.Insert(cb, _FILE_AND_LINE_ );
}
void Lobby2Plugin::RemoveCallbackInterface(Lobby2Callbacks *cb)
{
unsigned long index = callbacks.GetIndexOf(cb);
if (index!=MAX_UNSIGNED_LONG)
callbacks.RemoveAtIndex(index);
}
void Lobby2Plugin::ClearCallbackInterfaces()
{
callbacks.Clear(false, _FILE_AND_LINE_);
}

View File

@ -0,0 +1,114 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_PLUGIN_H
#define __LOBBY_2_PLUGIN_H
#include "Lobby2Message.h"
#include "slikenet/PluginInterface2.h"
#include "slikenet/PacketPriority.h"
#include "slikenet/peerinterface.h"
/// \defgroup LOBBY_2_GROUP Lobby2Plugin
/// \brief SQL based lobby system, with support for users, friends, clans, emails, ranking, and a message board
/// \details
/// \ingroup PLUGINS_GROUP
/// \defgroup LOBBY_2_COMMANDS Lobby2Commands
/// \brief Commands that can be sent to Lobby2Server from Lobby2Client
/// \details
/// \ingroup LOBBY_2_GROUP
/// \defgroup LOBBY_2_NOTIFICATIONS Lobby2Notifications
/// \brief Callbacks that the Lobby2System will send to you
/// \details
/// \ingroup LOBBY_2_GROUP
/// \defgroup LOBBY_2_SERVER Lobby2Server
/// \brief Runs the server modules that asynchronously processes Lobby2Message
/// \details
/// \ingroup LOBBY_2_GROUP
/// \defgroup LOBBY_2_CLIENT Lobby2Client
/// \brief Sends commands to Lobby2Server
/// \details
/// \ingroup LOBBY_2_GROUP
namespace SLNet
{
/// \ingroup LOBBY_2_GROUP
enum ServerErrors
{
// Class factory could not create a message of the given type
// Followed by 4 bytes, with the message number
L2SE_UNKNOWN_MESSAGE_ID,
// Client is trying to run a function that requires admin access. Use Lobby2Server::AddAdminAddress() to add this client.
L2SE_REQUIRES_ADMIN,
};
struct Lobby2MessageFactory;
/// \brief Both Lobby2Server and Lobby2Client derive from this class
/// \details
/// \ingroup LOBBY_2_GROUP
class RAK_DLL_EXPORT Lobby2Plugin : public PluginInterface2
{
public:
Lobby2Plugin();
virtual ~Lobby2Plugin();
/// \brief Ordering channel to send messages on
/// \param[in] oc The ordering channel
void SetOrderingChannel(char oc);
/// \brief Send priority to send messages on
/// \param[in] pp The packet priority
void SetSendPriority(PacketPriority pp);
/// \brief Creates messages from message IDs
/// \details Server should get a factory that creates messages with database functionality.<BR>
/// Client can use the base class
/// \param[in] f Class factory instance, which should remain valid for the scope of the plugin
void SetMessageFactory(Lobby2MessageFactory *f);
/// \brief Returns whatever was passed to SetMessageFactory()
Lobby2MessageFactory* GetMessageFactory(void) const;
/// \brief Set the callback to receive the results of operations via SendMsg()
virtual void SetCallbackInterface(Lobby2Callbacks *cb);
/// \brief You can have more than one callback to get called from the results of operations via SendMsg()
virtual void AddCallbackInterface(Lobby2Callbacks *cb);
/// \brief Removes a callback added with AddCallbackInterface();
virtual void RemoveCallbackInterface(Lobby2Callbacks *cb);
/// \brief Removes all callbacks added with AddCallbackInterface();
virtual void ClearCallbackInterfaces();
protected:
char orderingChannel;
PacketPriority packetPriority;
Lobby2MessageFactory *msgFactory;
DataStructures::List<Lobby2Callbacks*> callbacks;
};
}; // namespace SLNet
#endif

View File

@ -0,0 +1,62 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Presence.h"
#include "slikenet/BitStream.h"
using namespace SLNet;
Lobby2Presence::Lobby2Presence() {
status=UNDEFINED;
isVisible=true;
}
Lobby2Presence::Lobby2Presence(const Lobby2Presence& input) {
status=input.status;
isVisible=input.isVisible;
titleNameOrID=input.titleNameOrID;
statusString=input.statusString;
}
Lobby2Presence& Lobby2Presence::operator = ( const Lobby2Presence& input )
{
status=input.status;
isVisible=input.isVisible;
titleNameOrID=input.titleNameOrID;
statusString=input.statusString;
return *this;
}
Lobby2Presence::~Lobby2Presence()
{
}
void Lobby2Presence::Serialize(SLNet::BitStream *bitStream, bool writeToBitstream)
{
unsigned char gs = (unsigned char) status;
bitStream->Serialize(writeToBitstream,gs);
status=(Status) gs;
bitStream->Serialize(writeToBitstream,isVisible);
bitStream->Serialize(writeToBitstream,titleNameOrID);
bitStream->Serialize(writeToBitstream,statusString);
}

View File

@ -0,0 +1,85 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_PRESENCE_H
#define __LOBBY_2_PRESENCE_H
#include "slikenet/string.h"
namespace SLNet
{
class BitStream;
/// Lobby2Presence is information about your online status. It is only held in memory, so is lost when you go offline.
/// Set by calling Client_SetPresence and retrieve with Client_GetPresence
struct Lobby2Presence
{
Lobby2Presence();
Lobby2Presence(const Lobby2Presence& input);
Lobby2Presence& operator = ( const Lobby2Presence& input );
~Lobby2Presence();
void Serialize(SLNet::BitStream *bitStream, bool writeToBitstream);
enum Status
{
/// Set by the constructor, meaning it was never set. This is the default if a user is online, but SetPresence() was never called.
UNDEFINED,
/// Returned by Client_GetPresence() if you query for a user that is not online, whether or not SetPresence was ever called().
NOT_ONLINE,
/// Set by the user (you)
AWAY,
/// Set by the user (you)
DO_NOT_DISTURB,
/// Set by the user (you)
MINIMIZED,
/// Set by the user (you)
TYPING,
/// Set by the user (you)
VIEWING_PROFILE,
/// Set by the user (you)
EDITING_PROFILE,
/// Set by the user (you)
IN_LOBBY,
/// Set by the user (you)
IN_ROOM,
/// Set by the user (you)
IN_GAME
} status;
/// Visibility flag. This is not enforced by the server, so if you want a user's presence to be not visible, just don't display it on the client
bool isVisible;
/// Although game name is also present in the titleNameOrID member of Client_Login, this is the visible name returned by presence queries
/// That is because Client_Login::titleNameOrID member is optional, for example for lobbies that support multiple titles.
/// Set by the user (you) or leave blank if desired.
RakString titleNameOrID;
/// Anything you want
RakString statusString;
};
}
#endif

View File

@ -0,0 +1,305 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2ResultCode.h"
#include "slikenet/assert.h"
using namespace SLNet;
static Lobby2ResultCodeDescription resultCodeDescriptions[L2RC_COUNT] =
{
{L2RC_SUCCESS, "SUCCESS", "SUCCESS"},
{L2RC_PROCESSING, "PROCESSING", "PROCESSING"},
{L2RC_BUSY_EXCEEDED_PROCESSING_LIMIT, "BUSY_EXCEEDED_PROCESSING_LIMIT", "BUSY_EXCEEDED_PROCESSING_LIMIT"},
{L2RC_INVALID_PARAMETERS, "INVALID_PARAMETERS", "INVALID_PARAMETERS"},
{L2RC_GENERAL_ERROR, "GENERAL_ERROR", "GENERAL_ERROR"},
{L2RC_UNSUPPORTED_PLATFORM, "UNSUPPORTED_PLATFORM", "UNSUPPORTED_PLATFORM"},
{L2RC_OUT_OF_MEMORY, "OUT_OF_MEMORY", "OUT_OF_MEMORY"},
{L2RC_NOT_IMPLEMENTED, "NOT_IMPLEMENTED", "NOT_IMPLEMENTED"},
{L2RC_NOT_LOGGED_IN, "NOT_LOGGED_IN", "NOT_LOGGED_IN"},
{L2RC_DATABASE_CONSTRAINT_FAILURE, "DATABASE_CONSTRAINT_FAILURE", "DATABASE_CONSTRAINT_FAILURE"},
{L2RC_PROFANITY_FILTER_CHECK_FAILED, "PROFANITY_FILTER_CHECK_FAILED", "PROFANITY_FILTER_CHECK_FAILED"},
{L2RC_REQUIRES_ADMIN, "REQUIRES_ADMIN", "REQUIRES_ADMIN"},
{L2RC_REQUIRES_RANKING_PERMISSION, "REQUIRES_RANKING_PERMISSION", "REQUIRES_RANKING_PERMISSION"},
{L2RC_UNKNOWN_USER, "UNKNOWN_USER", "UNKNOWN_USER"},
{L2RC_HANDLE_IS_EMPTY, "HANDLE_IS_EMPTY", "HANDLE_IS_EMPTY"},
{L2RC_HANDLE_CONTAINS_NON_PRINTABLE, "HANDLE_CONTAINS_NON_PRINTABLE", "HANDLE_CONTAINS_NON_PRINTABLE"},
{L2RC_HANDLE_STARTS_WITH_SPACES, "HANDLE_STARTS_WITH_SPACES", "HANDLE_STARTS_WITH_SPACES"},
{L2RC_HANDLE_ENDS_WITH_SPACES, "HANDLE_ENDS_WITH_SPACES", "HANDLE_ENDS_WITH_SPACES"},
{L2RC_HANDLE_HAS_CONSECUTIVE_SPACES, "HANDLE_HAS_CONSECUTIVE_SPACES", "HANDLE_HAS_CONSECUTIVE_SPACES"},
{L2RC_HANDLE_IS_TOO_SHORT, "HANDLE_IS_TOO_SHORT", "HANDLE_IS_TOO_SHORT"},
{L2RC_HANDLE_IS_TOO_LONG, "HANDLE_IS_TOO_LONG", "HANDLE_IS_TOO_LONG"},
{L2RC_BINARY_DATA_LENGTH_EXCEEDED, "BINARY_DATA_LENGTH_EXCEEDED", "BINARY_DATA_LENGTH_EXCEEDED"},
{L2RC_BINARY_DATA_NULL_POINTER, "BINARY_DATA_NULL_POINTER", "BINARY_DATA_NULL_POINTER"},
{L2RC_REQUIRED_TEXT_IS_EMPTY, "REQUIRED_TEXT_IS_EMPTY", "REQUIRED_TEXT_IS_EMPTY"},
{L2RC_PASSWORD_IS_WRONG, "PASSWORD_IS_WRONG", "PASSWORD_IS_WRONG"},
{L2RC_PASSWORD_IS_EMPTY, "PASSWORD_IS_EMPTY", "PASSWORD_IS_EMPTY"},
{L2RC_PASSWORD_IS_TOO_SHORT, "PASSWORD_IS_TOO_SHORT", "PASSWORD_IS_TOO_SHORT"},
{L2RC_PASSWORD_IS_TOO_LONG, "PASSWORD_IS_TOO_LONG", "PASSWORD_IS_TOO_LONG"},
{L2RC_EMAIL_ADDRESS_IS_EMPTY, "EMAIL_ADDRESS_IS_EMPTY", "EMAIL_ADDRESS_IS_EMPTY"},
{L2RC_EMAIL_ADDRESS_IS_INVALID, "EMAIL_ADDRESS_IS_INVALID", "EMAIL_ADDRESS_IS_INVALID"},
{L2RC_System_CreateTitle_TITLE_ALREADY_IN_USE, "System_CreateTitle_TITLE_ALREADY_IN_USE", "System_CreateTitle_TITLE_ALREADY_IN_USE"},
{L2RC_System_DestroyTitle_TITLE_NOT_IN_USE, "System_DestroyTitle_TITLE_NOT_IN_USE", "System_DestroyTitle_TITLE_NOT_IN_USE"},
{L2RC_System_GetTitleBinaryData_TITLE_NOT_IN_USE, "System_GetTitleBinaryData_TITLE_NOT_IN_USE", "System_GetTitleBinaryData_TITLE_NOT_IN_USE"},
{L2RC_System_GetTitleRequiredAge_TITLE_NOT_IN_USE, "System_GetTitleRequiredAge_TITLE_NOT_IN_USE", "System_GetTitleRequiredAge_TITLE_NOT_IN_USE"},
{L2RC_System_RegisterProfanity_CANNOT_REGISTER_EMPTY_STRINGS, "System_RegisterProfanity_CANNOT_REGISTER_EMPTY_STRINGS", "System_RegisterProfanity_CANNOT_REGISTER_EMPTY_STRINGS"},
{L2RC_System_BanUser_INVALID_DURATION, "System_BanUser_INVALID_DURATION", "System_BanUser_INVALID_DURATION"},
{L2RC_System_BanUser_ALREADY_BANNED, "System_BanUser_ALREADY_BANNED", "System_BanUser_ALREADY_BANNED"},
{L2RC_System_UnbanUser_NOT_BANNED, "System_UnbanUser_NOT_BANNED", "System_UnbanUser_NOT_BANNED"},
{L2RC_System_DeleteAccount_INVALID_PASSWORD, "System_DeleteAccount_INVALID_PASSWORD", "System_DeleteAccount_INVALID_PASSWORD"},
{L2RC_CDKey_Add_TITLE_NOT_IN_USE, "CDKey_Add_TITLE_NOT_IN_USE", "CDKey_Add_TITLE_NOT_IN_USE"},
{L2RC_CDKey_GetStatus_TITLE_NOT_IN_USE, "CDKey_GetStatus_TITLE_NOT_IN_USE", "CDKey_GetStatus_TITLE_NOT_IN_USE"},
{L2RC_CDKey_GetStatus_UNKNOWN_CD_KEY, "CDKey_GetStatus_UNKNOWN_CD_KEY", "CDKey_GetStatus_UNKNOWN_CD_KEY"},
{L2RC_CDKey_Use_TITLE_NOT_IN_USE, "CDKey_Use_TITLE_NOT_IN_USE", "CDKey_Use_TITLE_NOT_IN_USE"},
{L2RC_CDKey_Use_UNKNOWN_CD_KEY, "CDKey_Use_UNKNOWN_CD_KEY", "CDKey_Use_UNKNOWN_CD_KEY"},
{L2RC_CDKey_Use_NOT_USABLE, "CDKey_Use_NOT_USABLE", "CDKey_Use_NOT_USABLE"},
{L2RC_CDKey_Use_CD_KEY_ALREADY_USED, "CDKey_Use_CD_KEY_ALREADY_USED", "CDKey_Use_CD_KEY_ALREADY_USED"},
{L2RC_CDKey_Use_CD_KEY_STOLEN, "CDKey_Use_CD_KEY_STOLEN", "CDKey_Use_CD_KEY_STOLEN"},
{L2RC_CDKey_FlagStolen_TITLE_NOT_IN_USE, "CDKey_FlagStolen_TITLE_NOT_IN_USE", "CDKey_FlagStolen_TITLE_NOT_IN_USE"},
{L2RC_CDKey_FlagStolen_UNKNOWN_CD_KEY, "CDKey_FlagStolen_UNKNOWN_CD_KEY", "CDKey_FlagStolen_UNKNOWN_CD_KEY"},
{L2RC_Client_Login_HANDLE_NOT_IN_USE_OR_BAD_SECRET_KEY, "Client_Login_HANDLE_NOT_IN_USE_OR_BAD_SECRET_KEY", "Client_Login_HANDLE_NOT_IN_USE_OR_BAD_SECRET_KEY"},
{L2RC_Client_Login_CANCELLED, "Client_Login_CANCELLED", "Client_Login_CANCELLED"},
{L2RC_Client_Login_CABLE_NOT_CONNECTED, "Client_Login_CABLE_NOT_CONNECTED", "Client_Login_CABLE_NOT_CONNECTED"},
{L2RC_Client_Login_NET_NOT_CONNECTED, "Client_Login_NET_NOT_CONNECTED", "Client_Login_NET_NOT_CONNECTED"},
{L2RC_Client_Login_BANNED, "Client_Login_BANNED", "Client_Login_BANNED"},
{L2RC_Client_Login_CDKEY_STOLEN, "Client_Login_CDKEY_STOLEN", "Client_Login_CDKEY_STOLEN"},
{L2RC_Client_Login_EMAIL_ADDRESS_NOT_VALIDATED, "Client_Login_EMAIL_ADDRESS_NOT_VALIDATED", "Client_Login_EMAIL_ADDRESS_NOT_VALIDATED"},
{L2RC_Client_Login_BAD_TITLE_OR_TITLE_SECRET_KEY, "Client_Login_BAD_TITLE_OR_TITLE_SECRET_KEY", "Client_Login_BAD_TITLE_OR_TITLE_SECRET_KEY"},
{L2RC_Client_Login_CONTEXT_CREATION_FAILURE, "Client_Login_CONTEXT_CREATION_FAILURE", "Client_Login_CONTEXT_CREATION_FAILURE"},
{L2RC_Client_RegisterAccount_HANDLE_ALREADY_IN_USE, "Client_RegisterAccount_HANDLE_ALREADY_IN_USE", "Client_RegisterAccount_HANDLE_ALREADY_IN_USE"},
{L2RC_Client_RegisterAccount_REQUIRED_AGE_NOT_MET, "Client_RegisterAccount_REQUIRED_AGE_NOT_MET", "Client_RegisterAccount_REQUIRED_AGE_NOT_MET"},
{L2RC_Client_RegisterAccount_INVALID_STATE, "Client_RegisterAccount_INVALID_STATE", "Client_RegisterAccount_INVALID_STATE"},
{L2RC_Client_RegisterAccount_INVALID_COUNTRY, "Client_RegisterAccount_INVALID_COUNTRY", "Client_RegisterAccount_INVALID_COUNTRY"},
{L2RC_Client_RegisterAccount_INVALID_RACE, "Client_RegisterAccount_INVALID_RACE", "Client_RegisterAccount_INVALID_RACE"},
{L2RC_Client_RegisterAccount_REQUIRES_CD_KEY, "Client_RegisterAccount_REQUIRES_CD_KEY", "Client_RegisterAccount_REQUIRES_CD_KEY"},
{L2RC_Client_RegisterAccount_REQUIRES_TITLE, "Client_RegisterAccount_REQUIRES_TITLE", "Client_RegisterAccount_REQUIRES_TITLE"},
{L2RC_Client_RegisterAccount_CD_KEY_ALREADY_USED, "Client_RegisterAccount_CD_KEY_ALREADY_USED", "Client_RegisterAccount_CD_KEY_ALREADY_USED"},
{L2RC_Client_RegisterAccount_CD_KEY_STOLEN, "Client_RegisterAccount_CD_KEY_STOLEN", "Client_RegisterAccount_CD_KEY_STOLEN"},
{L2RC_Client_RegisterAccount_CD_KEY_NOT_USABLE, "Client_RegisterAccount_CD_KEY_NOT_USABLE", "Client_RegisterAccount_CD_KEY_NOT_USABLE"},
{L2RC_Client_ValidateHandle_HANDLE_ALREADY_IN_USE, "Client_ValidateHandle_HANDLE_ALREADY_IN_USE", "Client_ValidateHandle_HANDLE_ALREADY_IN_USE"},
{L2RC_Client_GetPasswordByPasswordRecoveryAnswer_BAD_ANSWER, "Client_GetPasswordByPasswordRecoveryAnswer_BAD_ANSWER", "Client_GetPasswordByPasswordRecoveryAnswer_BAD_ANSWER"},
{L2RC_Client_ChangeHandle_NEW_HANDLE_ALREADY_IN_USE, "Client_ChangeHandle_NEW_HANDLE_ALREADY_IN_USE", "Client_ChangeHandle_NEW_HANDLE_ALREADY_IN_USE"},
{L2RC_Client_ChangeHandle_HANDLE_NOT_CHANGED, "Client_ChangeHandle_HANDLE_NOT_CHANGED", "Client_ChangeHandle_HANDLE_NOT_CHANGED"},
{L2RC_Client_ChangeHandle_INVALID_PASSWORD, "Client_ChangeHandle_INVALID_PASSWORD", "Client_ChangeHandle_INVALID_PASSWORD"},
{L2RC_Client_UpdateAccount_REQUIRED_AGE_NOT_MET, "Client_UpdateAccount_REQUIRED_AGE_NOT_MET", "Client_UpdateAccount_REQUIRED_AGE_NOT_MET"},
{L2RC_Client_StartIgnore_UNKNOWN_TARGET_HANDLE, "Client_StartIgnore_UNKNOWN_TARGET_HANDLE", "Client_StartIgnore_UNKNOWN_TARGET_HANDLE"},
{L2RC_Client_StartIgnore_CANNOT_PERFORM_ON_SELF, "Client_StartIgnore_CANNOT_PERFORM_ON_SELF", "Client_StartIgnore_CANNOT_PERFORM_ON_SELF"},
{L2RC_Client_StartIgnore_ALREADY_IGNORED, "Client_StartIgnore_ALREADY_IGNORED", "Client_StartIgnore_ALREADY_IGNORED"},
{L2RC_Client_StopIgnore_UNKNOWN_TARGET_HANDLE, "Client_StopIgnore_UNKNOWN_TARGET_HANDLE", "Client_StopIgnore_UNKNOWN_TARGET_HANDLE"},
{L2RC_Client_StopIgnore_CANNOT_PERFORM_ON_SELF, "Client_StopIgnore_CANNOT_PERFORM_ON_SELF", "Client_StopIgnore_CANNOT_PERFORM_ON_SELF"},
{L2RC_Client_PerTitleIntegerStorage_TITLE_NOT_IN_USE, "Client_PerTitleIntegerStorage_TITLE_NOT_IN_USE", "Client_PerTitleIntegerStorage_TITLE_NOT_IN_USE"},
{L2RC_Client_PerTitleIntegerStorage_ROW_EMPTY, "Client_PerTitleIntegerStorage_ROW_EMPTY", "Client_PerTitleIntegerStorage_ROW_EMPTY"},
{L2RC_Client_PerTitleBinaryStorage_TITLE_NOT_IN_USE, "Client_PerTitleBinaryStorage_TITLE_NOT_IN_USE", "Client_PerTitleBinaryStorage_TITLE_NOT_IN_USE"},
{L2RC_Client_PerTitleBinaryStorage_ROW_EMPTY, "Client_PerTitleBinaryStorage_ROW_EMPTY", "Client_PerTitleBinaryStorage_ROW_EMPTY"},
{L2RC_Friends_SendInvite_UNKNOWN_TARGET_HANDLE, "Friends_SendInvite_UNKNOWN_TARGET_HANDLE", "Friends_SendInvite_UNKNOWN_TARGET_HANDLE"},
{L2RC_Friends_SendInvite_CANNOT_PERFORM_ON_SELF, "Friends_SendInvite_CANNOT_PERFORM_ON_SELF", "Friends_SendInvite_CANNOT_PERFORM_ON_SELF"},
{L2RC_Friends_SendInvite_ALREADY_SENT_INVITE, "Friends_SendInvite_ALREADY_SENT_INVITE", "Friends_SendInvite_ALREADY_SENT_INVITE"},
{L2RC_Friends_SendInvite_ALREADY_FRIENDS, "Friends_SendInvite_ALREADY_FRIENDS", "Friends_SendInvite_ALREADY_FRIENDS"},
{L2RC_Friends_AcceptInvite_UNKNOWN_TARGET_HANDLE, "Friends_AcceptInvite_UNKNOWN_TARGET_HANDLE", "Friends_AcceptInvite_UNKNOWN_TARGET_HANDLE"},
{L2RC_Friends_AcceptInvite_CANNOT_PERFORM_ON_SELF, "Friends_AcceptInvite_CANNOT_PERFORM_ON_SELF", "Friends_AcceptInvite_CANNOT_PERFORM_ON_SELF"},
{L2RC_Friends_AcceptInvite_NO_INVITE, "Friends_AcceptInvite_NO_INVITE", "Friends_AcceptInvite_NO_INVITE"},
{L2RC_Friends_RejectInvite_UNKNOWN_TARGET_HANDLE, "Friends_RejectInvite_UNKNOWN_TARGET_HANDLE", "Friends_RejectInvite_UNKNOWN_TARGET_HANDLE"},
{L2RC_Friends_RejectInvite_CANNOT_PERFORM_ON_SELF, "Friends_RejectInvite_CANNOT_PERFORM_ON_SELF", "Friends_RejectInvite_CANNOT_PERFORM_ON_SELF"},
{L2RC_Friends_RejectInvite_NO_INVITE, "Friends_RejectInvite_NO_INVITE", "Friends_RejectInvite_NO_INVITE"},
{L2RC_Friends_GetFriends_UNKNOWN_TARGET_HANDLE, "Friends_GetFriends_UNKNOWN_TARGET_HANDLE", "Friends_GetFriends_UNKNOWN_TARGET_HANDLE"},
{L2RC_Friends_Remove_UNKNOWN_TARGET_HANDLE, "Friends_Remove_UNKNOWN_TARGET_HANDLE", "Friends_Remove_UNKNOWN_TARGET_HANDLE"},
{L2RC_Friends_Remove_CANNOT_PERFORM_ON_SELF, "Friends_Remove_CANNOT_PERFORM_ON_SELF", "Friends_Remove_CANNOT_PERFORM_ON_SELF"},
{L2RC_Friends_Remove_NOT_FRIENDS, "Friends_Remove_NOT_FRIENDS", "Friends_Remove_NOT_FRIENDS"},
{L2RC_BookmarkedUsers_Add_UNKNOWN_TARGET_HANDLE, "BookmarkedUsers_Add_UNKNOWN_TARGET_HANDLE", "BookmarkedUsers_Add_UNKNOWN_TARGET_HANDLE"},
{L2RC_BookmarkedUsers_Add_CANNOT_PERFORM_ON_SELF, "BookmarkedUsers_Add_CANNOT_PERFORM_ON_SELF", "BookmarkedUsers_Add_CANNOT_PERFORM_ON_SELF"},
{L2RC_BookmarkedUsers_Add_ALREADY_BOOKMARKED, "BookmarkedUsers_Add_ALREADY_BOOKMARKED", "BookmarkedUsers_Add_ALREADY_BOOKMARKED"},
{L2RC_BookmarkedUsers_Remove_UNKNOWN_TARGET_HANDLE, "BookmarkedUsers_Remove_UNKNOWN_TARGET_HANDLE", "BookmarkedUsers_Remove_UNKNOWN_TARGET_HANDLE"},
{L2RC_BookmarkedUsers_Remove_CANNOT_PERFORM_ON_SELF, "BookmarkedUsers_Remove_CANNOT_PERFORM_ON_SELF", "BookmarkedUsers_Remove_CANNOT_PERFORM_ON_SELF"},
{L2RC_Emails_Send_NO_RECIPIENTS, "Emails_Send_NO_RECIPIENTS", "Emails_Send_NO_RECIPIENTS"},
{L2RC_Emails_Send_CANNOT_PERFORM_ON_SELF, "Emails_Send_CANNOT_PERFORM_ON_SELF", "Emails_Send_CANNOT_PERFORM_ON_SELF"},
{L2RC_Emails_Delete_UNKNOWN_EMAIL_ID, "Emails_Delete_UNKNOWN_EMAIL_ID", "Emails_Delete_UNKNOWN_EMAIL_ID"},
{L2RC_Emails_Delete_ALREADY_DELETED, "Emails_Delete_ALREADY_DELETED,", "Emails_Delete_ALREADY_DELETED"},
{L2RC_Emails_SetStatus_NOTHING_TO_DO, "Emails_SetStatus_NOTHING_TO_DO", "Emails_SetStatus_NOTHING_TO_DO"},
{L2RC_Emails_SetStatus_UNKNOWN_EMAIL_ID, "Emails_SetStatus_UNKNOWN_EMAIL_ID", "Emails_SetStatus_UNKNOWN_EMAIL_ID"},
{L2RC_Emails_SetStatus_WAS_DELETED, "Emails_SetStatus_WAS_DELETED", "Emails_SetStatus_WAS_DELETED"},
{L2RC_Ranking_SubmitMatch_TITLE_NOT_IN_USE, "Ranking_SubmitMatch_TITLE_NOT_IN_USE", "Ranking_SubmitMatch_TITLE_NOT_IN_USE"},
{L2RC_Ranking_SubmitMatch_NO_PARTICIPANTS, "Ranking_SubmitMatch_NO_PARTICIPANTS", "Ranking_SubmitMatch_NO_PARTICIPANTS"},
{L2RC_Ranking_GetMatches_TITLE_NOT_IN_USE, "Ranking_GetMatches_TITLE_NOT_IN_USE", "Ranking_GetMatches_TITLE_NOT_IN_USE"},
{L2RC_Ranking_GetMatchBinaryData_INVALID_MATCH_ID, "Ranking_GetMatchBinaryData_INVALID_MATCH_ID", "Ranking_GetMatchBinaryData_INVALID_MATCH_ID"},
{L2RC_Ranking_GetTotalScore_TITLE_NOT_IN_USE, "Ranking_GetTotalScore_TITLE_NOT_IN_USE", "Ranking_GetTotalScore_TITLE_NOT_IN_USE"},
{L2RC_Ranking_WipeScoresForPlayer_TITLE_NOT_IN_USE, "Ranking_WipeScoresForPlayer_TITLE_NOT_IN_USE", "Ranking_WipeScoresForPlayer_TITLE_NOT_IN_USE"},
{L2RC_Ranking_WipeMatches_TITLE_NOT_IN_USE, "Ranking_WipeMatches_TITLE_NOT_IN_USE", "Ranking_WipeMatches_TITLE_NOT_IN_USE"},
{L2RC_Ranking_UpdateRating_TITLE_NOT_IN_USE, "Ranking_UpdateRating_TITLE_NOT_IN_USE", "Ranking_UpdateRating_TITLE_NOT_IN_USE"},
{L2RC_Ranking_UpdateRating_UNKNOWN_TARGET_HANDLE, "Ranking_UpdateRating_UNKNOWN_TARGET_HANDLE", "Ranking_UpdateRating_UNKNOWN_TARGET_HANDLE"},
{L2RC_Ranking_WipeRatings_TITLE_NOT_IN_USE, "Ranking_WipeRatings_TITLE_NOT_IN_USE", "Ranking_WipeRatings_TITLE_NOT_IN_USE"},
{L2RC_Ranking_GetRating_TITLE_NOT_IN_USE, "Ranking_GetRating_TITLE_NOT_IN_USE", "Ranking_GetRating_TITLE_NOT_IN_USE"},
{L2RC_Ranking_GetRating_UNKNOWN_TARGET_HANDLE, "Ranking_GetRating_UNKNOWN_TARGET_HANDLE", "Ranking_GetRating_UNKNOWN_TARGET_HANDLE"},
{L2RC_Ranking_GetRating_NO_RATING, "Ranking_GetRating_NO_RATING", "Ranking_GetRating_NO_RATING"},
{L2RC_Clans_Create_CLAN_HANDLE_IN_USE, "Clans_Create_CLAN_HANDLE_IN_USE", "Clans_Create_CLAN_HANDLE_IN_USE"},
{L2RC_Clans_Create_ALREADY_IN_A_CLAN, "Clans_Create_ALREADY_IN_A_CLAN", "Clans_Create_ALREADY_IN_A_CLAN"},
{L2RC_Clans_SetProperties_UNKNOWN_CLAN, "Clans_SetProperties_UNKNOWN_CLAN", "Clans_SetProperties_UNKNOWN_CLAN"},
{L2RC_Clans_SetProperties_MUST_BE_LEADER, "Clans_SetProperties_MUST_BE_LEADER", "Clans_SetProperties_MUST_BE_LEADER"},
{L2RC_Clans_GetProperties_UNKNOWN_CLAN, "Clans_GetProperties_UNKNOWN_CLAN", "Clans_GetProperties_UNKNOWN_CLAN"},
{L2RC_Clans_SetMyMemberProperties_UNKNOWN_CLAN, "Clans_SetMyMemberProperties_UNKNOWN_CLAN", "Clans_SetMyMemberProperties_UNKNOWN_CLAN"},
{L2RC_Clans_SetMyMemberProperties_NOT_IN_CLAN, "Clans_SetMyMemberProperties_NOT_IN_CLAN", "Clans_SetMyMemberProperties_NOT_IN_CLAN"},
{L2RC_Clans_GrantLeader_UNKNOWN_CLAN, "Clans_GrantLeader_UNKNOWN_CLAN", "Clans_GrantLeader_UNKNOWN_CLAN"},
{L2RC_Clans_GrantLeader_NOT_IN_CLAN, "Clans_GrantLeader_NOT_IN_CLAN", "Clans_GrantLeader_NOT_IN_CLAN"},
{L2RC_Clans_GrantLeader_UNKNOWN_TARGET_HANDLE, "Clans_GrantLeader_UNKNOWN_TARGET_HANDLE", "Clans_GrantLeader_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_GrantLeader_MUST_BE_LEADER, "Clans_GrantLeader_MUST_BE_LEADER", "Clans_GrantLeader_MUST_BE_LEADER"},
{L2RC_Clans_GrantLeader_CANNOT_PERFORM_ON_SELF, "Clans_GrantLeader_CANNOT_PERFORM_ON_SELF", "Clans_GrantLeader_CANNOT_PERFORM_ON_SELF"},
{L2RC_Clans_GrantLeader_TARGET_NOT_IN_CLAN, "Clans_GrantLeader_TARGET_NOT_IN_CLAN", "Clans_GrantLeader_TARGET_NOT_IN_CLAN"},
{L2RC_Clans_SetSubleaderStatus_UNKNOWN_CLAN, "Clans_SetSubleaderStatus_UNKNOWN_CLAN", "Clans_SetSubleaderStatus_UNKNOWN_CLAN"},
{L2RC_Clans_SetSubleaderStatus_NOT_IN_CLAN, "Clans_SetSubleaderStatus_NOT_IN_CLAN", "Clans_SetSubleaderStatus_NOT_IN_CLAN"},
{L2RC_Clans_SetSubleaderStatus_UNKNOWN_TARGET_HANDLE, "Clans_SetSubleaderStatus_UNKNOWN_TARGET_HANDLE", "Clans_SetSubleaderStatus_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_SetSubleaderStatus_MUST_BE_LEADER, "Clans_SetSubleaderStatus_MUST_BE_LEADER", "Clans_SetSubleaderStatus_MUST_BE_LEADER"},
{L2RC_Clans_SetSubleaderStatus_TARGET_NOT_IN_CLAN, "Clans_SetSubleaderStatus_TARGET_NOT_IN_CLAN", "Clans_SetSubleaderStatus_TARGET_NOT_IN_CLAN"},
{L2RC_Clans_SetSubleaderStatus_CANNOT_PERFORM_ON_SELF, "Clans_SetSubleaderStatus_CANNOT_PERFORM_ON_SELF", "Clans_SetSubleaderStatus_CANNOT_PERFORM_ON_SELF"},
{L2RC_Clans_SetMemberRank_UNKNOWN_CLAN, "Clans_SetMemberRank_UNKNOWN_CLAN", "Clans_SetMemberRank_UNKNOWN_CLAN"},
{L2RC_Clans_SetMemberRank_NOT_IN_CLAN, "Clans_SetMemberRank_NOT_IN_CLAN", "Clans_SetMemberRank_NOT_IN_CLAN"},
{L2RC_Clans_SetMemberRank_UNKNOWN_TARGET_HANDLE, "Clans_SetMemberRank_UNKNOWN_TARGET_HANDLE", "Clans_SetMemberRank_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_SetMemberRank_MUST_BE_LEADER, "Clans_SetMemberRank_MUST_BE_LEADER", "Clans_SetMemberRank_MUST_BE_LEADER"},
{L2RC_Clans_SetMemberRank_CANNOT_PERFORM_ON_SELF, "Clans_SetMemberRank_CANNOT_PERFORM_ON_SELF", "Clans_SetMemberRank_CANNOT_PERFORM_ON_SELF"},
{L2RC_Clans_SetMemberRank_TARGET_NOT_IN_CLAN, "Clans_SetMemberRank_TARGET_NOT_IN_CLAN", "Clans_SetMemberRank_TARGET_NOT_IN_CLAN"},
{L2RC_Clans_GetMemberProperties_UNKNOWN_CLAN, "Clans_GetMemberProperties_UNKNOWN_CLAN", "Clans_GetMemberProperties_UNKNOWN_CLAN"},
{L2RC_Clans_GetMemberProperties_UNKNOWN_TARGET_HANDLE, "Clans_GetMemberProperties_UNKNOWN_TARGET_HANDLE", "Clans_GetMemberProperties_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_GetMemberProperties_TARGET_NOT_IN_CLAN, "Clans_GetMemberProperties_TARGET_NOT_IN_CLAN", "Clans_GetMemberProperties_TARGET_NOT_IN_CLAN"},
{L2RC_Clans_ChangeHandle_UNKNOWN_CLAN, "Clans_ChangeHandle_UNKNOWN_CLAN", "Clans_ChangeHandle_UNKNOWN_CLAN"},
{L2RC_Clans_ChangeHandle_NOT_IN_CLAN, "Clans_ChangeHandle_NOT_IN_CLAN", "Clans_ChangeHandle_NOT_IN_CLAN"},
{L2RC_Clans_ChangeHandle_NEW_HANDLE_IN_USE, "Clans_ChangeHandle_NEW_HANDLE_IN_USE", "Clans_ChangeHandle_NEW_HANDLE_IN_USE"},
{L2RC_Clans_ChangeHandle_MUST_BE_LEADER, "Clans_ChangeHandle_MUST_BE_LEADER", "Clans_ChangeHandle_MUST_BE_LEADER"},
{L2RC_Clans_ChangeHandle_HANDLE_NOT_CHANGED, "Clans_ChangeHandle_HANDLE_NOT_CHANGED", "Clans_ChangeHandle_HANDLE_NOT_CHANGED"},
{L2RC_Clans_Leave_UNKNOWN_CLAN, "Clans_Leave_UNKNOWN_CLAN", "Clans_Leave_UNKNOWN_CLAN"},
{L2RC_Clans_Leave_NOT_IN_CLAN, "Clans_Leave_NOT_IN_CLAN", "Clans_Leave_NOT_IN_CLAN"},
{L2RC_Clans_SendJoinInvitation_UNKNOWN_CLAN, "Clans_SendJoinInvitation_UNKNOWN_CLAN", "Clans_SendJoinInvitation_UNKNOWN_CLAN"},
{L2RC_Clans_SendJoinInvitation_NOT_IN_CLAN, "Clans_SendJoinInvitation_NOT_IN_CLAN", "Clans_SendJoinInvitation_NOT_IN_CLAN"},
{L2RC_Clans_SendJoinInvitation_UNKNOWN_TARGET_HANDLE, "Clans_SendJoinInvitation_UNKNOWN_TARGET_HANDLE", "Clans_SendJoinInvitation_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_SendJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER, "Clans_SendJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER", "Clans_SendJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_SendJoinInvitation_REQUEST_ALREADY_PENDING, "Clans_SendJoinInvitation_REQUEST_ALREADY_PENDING", "Clans_SendJoinInvitation_REQUEST_ALREADY_PENDING"},
{L2RC_Clans_SendJoinInvitation_CANNOT_PERFORM_ON_SELF, "Clans_SendJoinInvitation_CANNOT_PERFORM_ON_SELF", "Clans_SendJoinInvitation_CANNOT_PERFORM_ON_SELF"},
{L2RC_Clans_SendJoinInvitation_TARGET_ALREADY_REQUESTED, "Clans_SendJoinInvitation_TARGET_ALREADY_REQUESTED", "Clans_SendJoinInvitation_TARGET_ALREADY_REQUESTED"},
{L2RC_Clans_SendJoinInvitation_TARGET_IS_BANNED, "Clans_SendJoinInvitation_TARGET_IS_BANNED", "Clans_SendJoinInvitation_TARGET_IS_BANNED"},
{L2RC_Clans_SendJoinInvitation_TARGET_ALREADY_IN_CLAN, "Clans_SendJoinInvitation_TARGET_ALREADY_IN_CLAN", "Clans_SendJoinInvitation_TARGET_ALREADY_IN_CLAN"},
{L2RC_Clans_WithdrawJoinInvitation_UNKNOWN_CLAN, "Clans_WithdrawJoinInvitation_UNKNOWN_CLAN", "Clans_WithdrawJoinInvitation_UNKNOWN_CLAN"},
{L2RC_Clans_WithdrawJoinInvitation_NO_SUCH_INVITATION_EXISTS, "Clans_WithdrawJoinInvitation_NO_SUCH_INVITATION_EXISTS", "Clans_WithdrawJoinInvitation_NO_SUCH_INVITATION_EXISTS"},
{L2RC_Clans_WithdrawJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER, "Clans_WithdrawJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER", "Clans_WithdrawJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_WithdrawJoinInvitation_UNKNOWN_TARGET_HANDLE, "Clans_WithdrawJoinInvitation_UNKNOWN_TARGET_HANDLE", "Clans_WithdrawJoinInvitation_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_WithdrawJoinInvitation_CANNOT_PERFORM_ON_SELF, "Clans_WithdrawJoinInvitation_CANNOT_PERFORM_ON_SELF", "Clans_WithdrawJoinInvitation_CANNOT_PERFORM_ON_SELF"},
{L2RC_Clans_AcceptJoinInvitation_ALREADY_IN_CLAN, "Clans_AcceptJoinInvitation_ALREADY_IN_CLAN", "Clans_AcceptJoinInvitation_ALREADY_IN_CLAN"},
{L2RC_Clans_AcceptJoinInvitation_ALREADY_IN_DIFFERENT_CLAN, "Clans_AcceptJoinInvitation_ALREADY_IN_DIFFERENT_CLAN", "Clans_AcceptJoinInvitation_ALREADY_IN_DIFFERENT_CLAN"},
{L2RC_Clans_AcceptJoinInvitation_UNKNOWN_CLAN, "Clans_AcceptJoinInvitation_UNKNOWN_CLAN", "Clans_AcceptJoinInvitation_UNKNOWN_CLAN"},
{L2RC_Clans_AcceptJoinInvitation_NOT_IN_CLAN, "Clans_AcceptJoinInvitation_NOT_IN_CLAN", "Clans_AcceptJoinInvitation_NOT_IN_CLAN"},
{L2RC_Clans_AcceptJoinInvitation_NO_SUCH_INVITATION_EXISTS, "Clans_AcceptJoinInvitation_NO_SUCH_INVITATION_EXISTS", "Clans_AcceptJoinInvitation_NO_SUCH_INVITATION_EXISTS"},
{L2RC_Clans_RejectJoinInvitation_UNKNOWN_CLAN, "Clans_RejectJoinInvitation_UNKNOWN_CLAN", "Clans_RejectJoinInvitation_UNKNOWN_CLAN"},
{L2RC_Clans_RejectJoinInvitation_NO_SUCH_INVITATION_EXISTS, "Clans_RejectJoinInvitation_NO_SUCH_INVITATION_EXISTS", "Clans_RejectJoinInvitation_NO_SUCH_INVITATION_EXISTS"},
{L2RC_Clans_DownloadInvitationList_UNKNOWN_CLAN, "Clans_DownloadInvitationList_UNKNOWN_CLAN", "Clans_DownloadInvitationList_UNKNOWN_CLAN"},
{L2RC_Clans_SendJoinRequest_UNKNOWN_CLAN, "Clans_SendJoinRequest_UNKNOWN_CLAN", "Clans_SendJoinRequest_UNKNOWN_CLAN"},
{L2RC_Clans_SendJoinRequest_REQUEST_ALREADY_PENDING, "Clans_SendJoinRequest_REQUEST_ALREADY_PENDING", "Clans_SendJoinRequest_REQUEST_ALREADY_PENDING"},
{L2RC_Clans_SendJoinRequest_ALREADY_IN_CLAN, "Clans_SendJoinRequest_ALREADY_IN_CLAN", "Clans_SendJoinRequest_ALREADY_IN_CLAN"},
{L2RC_Clans_SendJoinRequest_BANNED, "Clans_SendJoinRequest_BANNED", "Clans_SendJoinRequest_BANNED"},
{L2RC_Clans_SendJoinRequest_ALREADY_INVITED, "Clans_SendJoinRequest_ALREADY_INVITED", "Clans_SendJoinRequest_ALREADY_INVITED"},
{L2RC_Clans_WithdrawJoinRequest_UNKNOWN_CLAN, "Clans_WithdrawJoinRequest_UNKNOWN_CLAN", "Clans_WithdrawJoinRequest_UNKNOWN_CLAN"},
{L2RC_Clans_WithdrawJoinRequest_ALREADY_IN_CLAN, "Clans_WithdrawJoinRequest_ALREADY_IN_CLAN", "Clans_WithdrawJoinRequest_ALREADY_IN_CLAN"},
{L2RC_Clans_WithdrawJoinRequest_NO_SUCH_INVITATION_EXISTS, "Clans_WithdrawJoinRequest_NO_SUCH_INVITATION_EXISTS", "Clans_WithdrawJoinRequest_NO_SUCH_INVITATION_EXISTS"},
{L2RC_Clans_AcceptJoinRequest_UNKNOWN_CLAN, "Clans_AcceptJoinRequest_UNKNOWN_CLAN", "Clans_AcceptJoinRequest_UNKNOWN_CLAN"},
{L2RC_Clans_AcceptJoinRequest_NOT_IN_CLAN, "Clans_AcceptJoinRequest_NOT_IN_CLAN", "Clans_AcceptJoinRequest_NOT_IN_CLAN"},
{L2RC_Clans_AcceptJoinRequest_MUST_BE_LEADER_OR_SUBLEADER, "Clans_AcceptJoinRequest_MUST_BE_LEADER_OR_SUBLEADER", "Clans_AcceptJoinRequest_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_AcceptJoinRequest_UNKNOWN_TARGET_HANDLE, "Clans_AcceptJoinRequest_UNKNOWN_TARGET_HANDLE", "Clans_AcceptJoinRequest_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_AcceptJoinRequest_CANNOT_PERFORM_ON_SELF, "Clans_AcceptJoinRequest_CANNOT_PERFORM_ON_SELF", "Clans_AcceptJoinRequest_CANNOT_PERFORM_ON_SELF"},
{L2RC_Clans_AcceptJoinRequest_TARGET_ALREADY_IN_CLAN, "Clans_AcceptJoinRequest_TARGET_ALREADY_IN_CLAN", "Clans_AcceptJoinRequest_TARGET_ALREADY_IN_CLAN"},
{L2RC_Clans_AcceptJoinRequest_TARGET_ALREADY_IN_DIFFERENT_CLAN, "Clans_AcceptJoinRequest_TARGET_ALREADY_IN_DIFFERENT_CLAN", "Clans_AcceptJoinRequest_TARGET_ALREADY_IN_DIFFERENT_CLAN"},
{L2RC_Clans_AcceptJoinRequest_TARGET_IS_BANNED, "Clans_AcceptJoinRequest_TARGET_IS_BANNED", "Clans_AcceptJoinRequest_TARGET_IS_BANNED"},
{L2RC_Clans_AcceptJoinRequest_REQUEST_NOT_PENDING, "Clans_AcceptJoinRequest_REQUEST_NOT_PENDING", "Clans_AcceptJoinRequest_REQUEST_NOT_PENDING"},
{L2RC_Clans_RejectJoinRequest_UNKNOWN_CLAN, "Clans_RejectJoinRequest_UNKNOWN_CLAN", "Clans_RejectJoinRequest_UNKNOWN_CLAN"},
{L2RC_Clans_RejectJoinRequest_NOT_IN_CLAN, "Clans_RejectJoinRequest_NOT_IN_CLAN", "Clans_RejectJoinRequest_NOT_IN_CLAN"},
{L2RC_Clans_RejectJoinRequest_MUST_BE_LEADER_OR_SUBLEADER, "Clans_RejectJoinRequest_MUST_BE_LEADER_OR_SUBLEADER", "Clans_RejectJoinRequest_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_RejectJoinRequest_REQUESTING_USER_HANDLE_UNKNOWN, "Clans_RejectJoinRequest_REQUESTING_USER_HANDLE_UNKNOWN", "Clans_RejectJoinRequest_REQUESTING_USER_HANDLE_UNKNOWN"},
{L2RC_Clans_RejectJoinRequest_NO_SUCH_INVITATION_EXISTS, "Clans_RejectJoinRequest_NO_SUCH_INVITATION_EXISTS", "Clans_RejectJoinRequest_NO_SUCH_INVITATION_EXISTS"},
{L2RC_Clans_KickAndBlacklistUser_UNKNOWN_CLAN, "Clans_KickAndBlacklistUser_UNKNOWN_CLAN", "Clans_KickAndBlacklistUser_UNKNOWN_CLAN"},
{L2RC_Clans_KickAndBlacklistUser_NOT_IN_CLAN, "Clans_KickAndBlacklistUser_NOT_IN_CLAN", "Clans_KickAndBlacklistUser_NOT_IN_CLAN"},
{L2RC_Clans_KickAndBlacklistUser_UNKNOWN_TARGET_HANDLE, "Clans_KickAndBlacklistUser_UNKNOWN_TARGET_HANDLE", "Clans_KickAndBlacklistUser_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_KickAndBlacklistUser_MUST_BE_LEADER_OR_SUBLEADER, "Clans_KickAndBlacklistUser_MUST_BE_LEADER_OR_SUBLEADER", "Clans_KickAndBlacklistUser_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_KickAndBlacklistUser_ALREADY_BLACKLISTED, "Clans_KickAndBlacklistUser_ALREADY_BLACKLISTED", "Clans_KickAndBlacklistUser_ALREADY_BLACKLISTED"},
{L2RC_Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_SELF, "Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_SELF", "Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_SELF"},
{L2RC_Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_LEADER, "Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_LEADER", "Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_LEADER"},
{L2RC_Clans_UnblacklistUser_UNKNOWN_CLAN, "Clans_UnblacklistUser_UNKNOWN_CLAN", "Clans_UnblacklistUser_UNKNOWN_CLAN"},
{L2RC_Clans_UnblacklistUser_NOT_IN_CLAN, "Clans_UnblacklistUser_NOT_IN_CLAN", "Clans_UnblacklistUser_NOT_IN_CLAN"},
{L2RC_Clans_UnblacklistUser_UNKNOWN_TARGET_HANDLE, "Clans_UnblacklistUser_UNKNOWN_TARGET_HANDLE", "Clans_UnblacklistUser_UNKNOWN_TARGET_HANDLE"},
{L2RC_Clans_UnblacklistUser_MUST_BE_LEADER_OR_SUBLEADER, "Clans_UnblacklistUser_MUST_BE_LEADER_OR_SUBLEADER", "Clans_UnblacklistUser_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_UnblacklistUser_NOT_BLACKLISTED, "Clans_UnblacklistUser_NOT_BLACKLISTED", "Clans_UnblacklistUser_NOT_BLACKLISTED"},
{L2RC_Clans_GetBlacklist_UNKNOWN_CLAN, "Clans_GetBlacklist_UNKNOWN_CLAN", "Clans_GetBlacklist_UNKNOWN_CLAN"},
{L2RC_Clans_GetMembers_UNKNOWN_CLAN, "Clans_GetMembers_UNKNOWN_CLAN", "Clans_GetMembers_UNKNOWN_CLAN"},
{L2RC_Clans_CreateBoard_UNKNOWN_CLAN, "Clans_CreateBoard_UNKNOWN_CLAN", "Clans_CreateBoard_UNKNOWN_CLAN"},
{L2RC_Clans_CreateBoard_NOT_IN_CLAN, "Clans_CreateBoard_NOT_IN_CLAN", "Clans_CreateBoard_NOT_IN_CLAN"},
{L2RC_Clans_CreateBoard_MUST_BE_LEADER_OR_SUBLEADER, "Clans_CreateBoard_MUST_BE_LEADER_OR_SUBLEADER", "Clans_CreateBoard_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_CreateBoard_BOARD_ALREADY_EXISTS, "Clans_CreateBoard_BOARD_ALREADY_EXISTS", "Clans_CreateBoard_BOARD_ALREADY_EXISTS"},
{L2RC_Clans_DestroyBoard_UNKNOWN_CLAN, "Clans_DestroyBoard_UNKNOWN_CLAN", "Clans_DestroyBoard_UNKNOWN_CLAN"},
{L2RC_Clans_DestroyBoard_NOT_IN_CLAN, "Clans_DestroyBoard_NOT_IN_CLAN", "Clans_DestroyBoard_NOT_IN_CLAN"},
{L2RC_Clans_DestroyBoard_MUST_BE_LEADER_OR_SUBLEADER, "Clans_DestroyBoard_MUST_BE_LEADER_OR_SUBLEADER", "Clans_DestroyBoard_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_DestroyBoard_BOARD_DOES_NOT_EXIST, "Clans_DestroyBoard_BOARD_DOES_NOT_EXIST", "Clans_DestroyBoard_BOARD_DOES_NOT_EXIST"},
{L2RC_Clans_CreateNewTopic_UNKNOWN_CLAN, "Clans_CreateNewTopic_UNKNOWN_CLAN", "Clans_CreateNewTopic_UNKNOWN_CLAN"},
{L2RC_Clans_CreateNewTopic_BOARD_DOES_NOT_EXIST, "Clans_CreateNewTopic_BOARD_DOES_NOT_EXIST", "Clans_CreateNewTopic_BOARD_DOES_NOT_EXIST"},
{L2RC_Clans_CreateNewTopic_PERMISSION_DENIED, "Clans_CreateNewTopic_PERMISSION_DENIED", "Clans_CreateNewTopic_PERMISSION_DENIED"},
{L2RC_Clans_ReplyToTopic_UNKNOWN_POST_ID, "Clans_ReplyToTopic_UNKNOWN_POST_ID", "Clans_ReplyToTopic_UNKNOWN_POST_ID"},
{L2RC_Clans_ReplyToTopic_PERMISSION_DENIED, "Clans_ReplyToTopic_PERMISSION_DENIED", "Clans_ReplyToTopic_PERMISSION_DENIED"},
{L2RC_Clans_RemovePost_UNKNOWN_POST_ID, "Clans_RemovePost_UNKNOWN_POST_ID", "Clans_RemovePost_UNKNOWN_POST_ID"},
{L2RC_Clans_RemovePost_NOT_IN_CLAN, "Clans_RemovePost_NOT_IN_CLAN", "Clans_RemovePost_NOT_IN_CLAN"},
{L2RC_Clans_RemovePost_MUST_BE_LEADER_OR_SUBLEADER, "Clans_RemovePost_MUST_BE_LEADER_OR_SUBLEADER", "Clans_RemovePost_MUST_BE_LEADER_OR_SUBLEADER"},
{L2RC_Clans_GetBoards_UNKNOWN_CLAN, "Clans_GetBoards_UNKNOWN_CLAN", "Clans_GetBoards_UNKNOWN_CLAN"},
{L2RC_Clans_GetTopics_UNKNOWN_CLAN, "Clans_GetTopics_UNKNOWN_CLAN", "Clans_GetTopics_UNKNOWN_CLAN"},
{L2RC_Clans_GetTopics_BOARD_DOES_NOT_EXIST, "Clans_GetTopics_BOARD_DOES_NOT_EXIST", "Clans_GetTopics_BOARD_DOES_NOT_EXIST"},
{L2RC_Clans_GetPosts_UNKNOWN_POST_ID, "Clans_GetPosts_UNKNOWN_POST_ID", "Clans_GetPosts_UNKNOWN_POST_ID"},
{L2RC_Console_JoinLobby_LOBBY_FULL, "Console_JoinLobby_LOBBY_FULL", "Console_JoinLobby_LOBBY_FULL"},
{L2RC_Console_JoinLobby_NO_SUCH_LOBBY, "Console_JoinLobby_NO_SUCH_LOBBY", "Console_JoinLobby_NO_SUCH_LOBBY"},
{L2RC_Console_GetRoomDetails_NO_ROOMS_FOUND, "Console_GetRoomDetails_NO_ROOMS_FOUND", "Console_GetRoomDetails_NO_ROOMS_FOUND"},
{L2RC_Console_SignIntoRoom_NO_USERS, "Console_SignIntoRoom_NO_USERS", "Console_SignIntoRoom_NO_USERS"},
{L2RC_Console_SignIntoRoom_NO_SUCH_ROOM, "Console_SignIntoRoom_NO_SUCH_ROOM", "Console_SignIntoRoom_NO_SUCH_ROOM"},
{L2RC_Console_SignIntoRoom_JOIN_ILLEGAL, "Console_SignIntoRoom_JOIN_ILLEGAL", "Console_SignIntoRoom_JOIN_ILLEGAL"},
{L2RC_Console_SignIntoRoom_REMOTE_JOIN_FAILED, "Console_SignIntoRoom_REMOTE_JOIN_FAILED", "Console_SignIntoRoom_REMOTE_JOIN_FAILED"},
{L2RC_Console_JoinRoom_ROOM_FULL, "Console_JoinRoom_ROOM_FULL", "Console_JoinRoom_ROOM_FULL"},
{L2RC_Console_JoinRoom_WRONG_PASSWORD, "Console_JoinRoom_WRONG_PASSWORD", "Console_JoinRoom_WRONG_PASSWORD"},
{L2RC_Console_JoinRoom_NO_SUCH_ROOM, "Console_JoinRoom_NO_SUCH_ROOM", "Console_JoinRoom_NO_SUCH_ROOM"},
{L2RC_Console_JoinRoom_SERVER_ERROR_BLOCKED, "Console_JoinRoom_SERVER_ERROR_BLOCKED", "Console_JoinRoom_SERVER_ERROR_BLOCKED"},
{L2RC_Console_JoinRoom_ALREADY_IN_ROOM, "Console_JoinRoom_ALREADY_IN_ROOM", "Console_JoinRoom_ALREADY_IN_ROOM"},
{L2RC_Console_JoinRoom_CONNECTION_TIMEOUT, "Console_JoinRoom_CONNECTION_TIMEOUT", "Console_JoinRoom_CONNECTION_TIMEOUT"},
{L2RC_Console_ModifyRoom_NO_SUCH_ROOM, "Console_ModifyRoom_NO_SUCH_ROOM", "Console_ModifyRoom_NO_SUCH_ROOM"},
{L2RC_Console_ModifyRoom_MUST_BE_HOST, "Console_ModifyRoom_MUST_BE_HOST", "Console_ModifyRoom_MUST_BE_HOST"},
{L2RC_Console_UpdateRoomParameters_ROOM_WAS_DELETED_WHILE_IN_PROGRESS, "Console_UpdateRoomParameters_ROOM_WAS_DELETED_WHILE_IN_PROGRESS", "Console_UpdateRoomParameters_ROOM_WAS_DELETED_WHILE_IN_PROGRESS"},
{L2RC_Console_LeaveRoom_NO_SUCH_ROOM, "Console_LeaveRoom_NO_SUCH_ROOM", "Console_LeaveRoom_NO_SUCH_ROOM"},
{L2RC_Console_LeaveRoom_ROOM_WAS_DELETED_WHILE_IN_PROGRESS, "Console_LeaveRoom_ROOM_WAS_DELETED_WHILE_IN_PROGRESS", "Console_LeaveRoom_ROOM_WAS_DELETED_WHILE_IN_PROGRESS"},
{L2RC_Console_StartGame_NO_SUCH_ROOM, "Console_StartGame_NO_SUCH_ROOM", "Console_StartGame_NO_SUCH_ROOM"},
{L2RC_Console_StartGame_MUST_BE_HOST, "Console_StartGame_MUST_BE_HOST", "Console_StartGame_MUST_BE_HOST"},
{L2RC_Console_StartGame_ALREADY_STARTED, "Console_StartGame_ALREADY_STARTED", "Console_StartGame_ALREADY_STARTED"},
{L2RC_Console_StartGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS, "Console_StartGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS", "Console_StartGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS"},
{L2RC_Console_EndGame_NO_SUCH_ROOM, "Console_EndGame_NO_SUCH_ROOM", "Console_EndGame_NO_SUCH_ROOM"},
{L2RC_Console_EndGame_MUST_BE_HOST, "Console_EndGame_MUST_BE_HOST", "Console_EndGame_MUST_BE_HOST"},
{L2RC_Console_EndGame_NOT_STARTED, "Console_EndGame_NOT_STARTED", "Console_EndGame_NOT_STARTED"},
{L2RC_Console_EndGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS, "Console_EndGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS", "Console_EndGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS"},
{L2RC_Notification_Console_CableDisconnected, "Notification_Console_CableDisconnected", "Notification_Console_CableDisconnected"},
{L2RC_Notification_ContextError_SignedOut, "Notification_ContextError_SignedOut", "Notification_ContextError_SignedOut"},
{L2RC_Notification_ContextError_SystemError, "Notification_ContextError_SystemError", "Notification_ContextError_SystemError"},
};
const char *Lobby2ResultCodeDescription::ToEnglish(Lobby2ResultCode result)
{
RakAssert(resultCodeDescriptions[result].resultCode==result);
return resultCodeDescriptions[result].englishDesc;
}
const char *Lobby2ResultCodeDescription::ToEnum(Lobby2ResultCode result)
{
RakAssert(resultCodeDescriptions[result].resultCode==result);
return resultCodeDescriptions[result].enumDesc;
}
void Lobby2ResultCodeDescription::Validate(void)
{
unsigned int i;
for (i=0; i < L2RC_COUNT; i++)
{
RakAssert(resultCodeDescriptions[i].resultCode==(Lobby2ResultCode)i);
}
}

View File

@ -0,0 +1,306 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017-2018, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_RESULT_CODE_H
#define __LOBBY_2_RESULT_CODE_H
#include "slikenet/defines.h" // used for SLNet -> RakNet namespace change in RAKNET_COMPATIBILITY mode
namespace SLNet
{
enum Lobby2ResultCode
{
L2RC_SUCCESS,
L2RC_PROCESSING,
L2RC_BUSY_EXCEEDED_PROCESSING_LIMIT,
L2RC_INVALID_PARAMETERS,
L2RC_GENERAL_ERROR,
L2RC_UNSUPPORTED_PLATFORM,
L2RC_OUT_OF_MEMORY,
L2RC_NOT_IMPLEMENTED,
L2RC_NOT_LOGGED_IN,
L2RC_DATABASE_CONSTRAINT_FAILURE,
L2RC_PROFANITY_FILTER_CHECK_FAILED,
L2RC_REQUIRES_ADMIN,
L2RC_REQUIRES_RANKING_PERMISSION,
L2RC_UNKNOWN_USER,
L2RC_HANDLE_IS_EMPTY,
L2RC_HANDLE_CONTAINS_NON_PRINTABLE,
L2RC_HANDLE_STARTS_WITH_SPACES,
L2RC_HANDLE_ENDS_WITH_SPACES,
L2RC_HANDLE_HAS_CONSECUTIVE_SPACES,
L2RC_HANDLE_IS_TOO_SHORT,
L2RC_HANDLE_IS_TOO_LONG,
L2RC_BINARY_DATA_LENGTH_EXCEEDED,
L2RC_BINARY_DATA_NULL_POINTER,
L2RC_REQUIRED_TEXT_IS_EMPTY,
L2RC_PASSWORD_IS_WRONG,
L2RC_PASSWORD_IS_EMPTY,
L2RC_PASSWORD_IS_TOO_SHORT,
L2RC_PASSWORD_IS_TOO_LONG,
L2RC_EMAIL_ADDRESS_IS_EMPTY,
L2RC_EMAIL_ADDRESS_IS_INVALID,
L2RC_System_CreateTitle_TITLE_ALREADY_IN_USE,
L2RC_System_DestroyTitle_TITLE_NOT_IN_USE,
L2RC_System_GetTitleBinaryData_TITLE_NOT_IN_USE,
L2RC_System_GetTitleRequiredAge_TITLE_NOT_IN_USE,
L2RC_System_RegisterProfanity_CANNOT_REGISTER_EMPTY_STRINGS,
L2RC_System_BanUser_INVALID_DURATION,
L2RC_System_BanUser_ALREADY_BANNED,
L2RC_System_UnbanUser_NOT_BANNED,
L2RC_System_DeleteAccount_INVALID_PASSWORD,
L2RC_CDKey_Add_TITLE_NOT_IN_USE,
L2RC_CDKey_GetStatus_TITLE_NOT_IN_USE,
L2RC_CDKey_GetStatus_UNKNOWN_CD_KEY,
L2RC_CDKey_Use_TITLE_NOT_IN_USE,
L2RC_CDKey_Use_UNKNOWN_CD_KEY,
L2RC_CDKey_Use_NOT_USABLE,
L2RC_CDKey_Use_CD_KEY_ALREADY_USED,
L2RC_CDKey_Use_CD_KEY_STOLEN,
L2RC_CDKey_FlagStolen_TITLE_NOT_IN_USE,
L2RC_CDKey_FlagStolen_UNKNOWN_CD_KEY,
L2RC_Client_Login_HANDLE_NOT_IN_USE_OR_BAD_SECRET_KEY,
L2RC_Client_Login_CANCELLED,
L2RC_Client_Login_CABLE_NOT_CONNECTED,
L2RC_Client_Login_NET_NOT_CONNECTED,
L2RC_Client_Login_BANNED,
L2RC_Client_Login_CDKEY_STOLEN,
L2RC_Client_Login_EMAIL_ADDRESS_NOT_VALIDATED,
L2RC_Client_Login_BAD_TITLE_OR_TITLE_SECRET_KEY,
L2RC_Client_Login_CONTEXT_CREATION_FAILURE, // PS3
L2RC_Client_RegisterAccount_HANDLE_ALREADY_IN_USE,
L2RC_Client_RegisterAccount_REQUIRED_AGE_NOT_MET,
L2RC_Client_RegisterAccount_INVALID_STATE,
L2RC_Client_RegisterAccount_INVALID_COUNTRY,
L2RC_Client_RegisterAccount_INVALID_RACE,
L2RC_Client_RegisterAccount_REQUIRES_CD_KEY,
L2RC_Client_RegisterAccount_REQUIRES_TITLE,
L2RC_Client_RegisterAccount_CD_KEY_ALREADY_USED,
L2RC_Client_RegisterAccount_CD_KEY_STOLEN,
L2RC_Client_RegisterAccount_CD_KEY_NOT_USABLE,
L2RC_Client_ValidateHandle_HANDLE_ALREADY_IN_USE,
L2RC_Client_GetPasswordByPasswordRecoveryAnswer_BAD_ANSWER,
L2RC_Client_ChangeHandle_NEW_HANDLE_ALREADY_IN_USE,
L2RC_Client_ChangeHandle_HANDLE_NOT_CHANGED,
L2RC_Client_ChangeHandle_INVALID_PASSWORD,
L2RC_Client_UpdateAccount_REQUIRED_AGE_NOT_MET,
L2RC_Client_StartIgnore_UNKNOWN_TARGET_HANDLE,
L2RC_Client_StartIgnore_CANNOT_PERFORM_ON_SELF,
L2RC_Client_StartIgnore_ALREADY_IGNORED,
L2RC_Client_StopIgnore_UNKNOWN_TARGET_HANDLE,
L2RC_Client_StopIgnore_CANNOT_PERFORM_ON_SELF,
L2RC_Client_PerTitleIntegerStorage_TITLE_NOT_IN_USE,
L2RC_Client_PerTitleIntegerStorage_ROW_EMPTY,
L2RC_Client_PerTitleBinaryStorage_TITLE_NOT_IN_USE,
L2RC_Client_PerTitleBinaryStorage_ROW_EMPTY,
L2RC_Friends_SendInvite_UNKNOWN_TARGET_HANDLE,
L2RC_Friends_SendInvite_CANNOT_PERFORM_ON_SELF,
L2RC_Friends_SendInvite_ALREADY_SENT_INVITE,
L2RC_Friends_SendInvite_ALREADY_FRIENDS,
L2RC_Friends_AcceptInvite_UNKNOWN_TARGET_HANDLE,
L2RC_Friends_AcceptInvite_CANNOT_PERFORM_ON_SELF,
L2RC_Friends_AcceptInvite_NO_INVITE,
L2RC_Friends_RejectInvite_UNKNOWN_TARGET_HANDLE,
L2RC_Friends_RejectInvite_CANNOT_PERFORM_ON_SELF,
L2RC_Friends_RejectInvite_NO_INVITE,
L2RC_Friends_GetFriends_UNKNOWN_TARGET_HANDLE,
L2RC_Friends_Remove_UNKNOWN_TARGET_HANDLE,
L2RC_Friends_Remove_CANNOT_PERFORM_ON_SELF,
L2RC_Friends_Remove_NOT_FRIENDS,
L2RC_BookmarkedUsers_Add_UNKNOWN_TARGET_HANDLE,
L2RC_BookmarkedUsers_Add_CANNOT_PERFORM_ON_SELF,
L2RC_BookmarkedUsers_Add_ALREADY_BOOKMARKED,
L2RC_BookmarkedUsers_Remove_UNKNOWN_TARGET_HANDLE,
L2RC_BookmarkedUsers_Remove_CANNOT_PERFORM_ON_SELF,
L2RC_Emails_Send_NO_RECIPIENTS,
L2RC_Emails_Send_CANNOT_PERFORM_ON_SELF,
L2RC_Emails_Delete_UNKNOWN_EMAIL_ID,
L2RC_Emails_Delete_ALREADY_DELETED,
L2RC_Emails_SetStatus_NOTHING_TO_DO,
L2RC_Emails_SetStatus_UNKNOWN_EMAIL_ID,
L2RC_Emails_SetStatus_WAS_DELETED,
L2RC_Ranking_SubmitMatch_TITLE_NOT_IN_USE,
L2RC_Ranking_SubmitMatch_NO_PARTICIPANTS,
L2RC_Ranking_GetMatches_TITLE_NOT_IN_USE,
L2RC_Ranking_GetMatchBinaryData_INVALID_MATCH_ID,
L2RC_Ranking_GetTotalScore_TITLE_NOT_IN_USE,
L2RC_Ranking_WipeScoresForPlayer_TITLE_NOT_IN_USE,
L2RC_Ranking_WipeMatches_TITLE_NOT_IN_USE,
L2RC_Ranking_UpdateRating_TITLE_NOT_IN_USE,
L2RC_Ranking_UpdateRating_UNKNOWN_TARGET_HANDLE,
L2RC_Ranking_WipeRatings_TITLE_NOT_IN_USE,
L2RC_Ranking_GetRating_TITLE_NOT_IN_USE,
L2RC_Ranking_GetRating_UNKNOWN_TARGET_HANDLE,
L2RC_Ranking_GetRating_NO_RATING,
L2RC_Clans_Create_CLAN_HANDLE_IN_USE,
L2RC_Clans_Create_ALREADY_IN_A_CLAN,
L2RC_Clans_SetProperties_UNKNOWN_CLAN,
L2RC_Clans_SetProperties_MUST_BE_LEADER,
L2RC_Clans_GetProperties_UNKNOWN_CLAN,
L2RC_Clans_SetMyMemberProperties_UNKNOWN_CLAN,
L2RC_Clans_SetMyMemberProperties_NOT_IN_CLAN,
L2RC_Clans_GrantLeader_UNKNOWN_CLAN,
L2RC_Clans_GrantLeader_NOT_IN_CLAN,
L2RC_Clans_GrantLeader_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_GrantLeader_MUST_BE_LEADER,
L2RC_Clans_GrantLeader_CANNOT_PERFORM_ON_SELF,
L2RC_Clans_GrantLeader_TARGET_NOT_IN_CLAN,
L2RC_Clans_SetSubleaderStatus_UNKNOWN_CLAN,
L2RC_Clans_SetSubleaderStatus_NOT_IN_CLAN,
L2RC_Clans_SetSubleaderStatus_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_SetSubleaderStatus_MUST_BE_LEADER,
L2RC_Clans_SetSubleaderStatus_TARGET_NOT_IN_CLAN,
L2RC_Clans_SetSubleaderStatus_CANNOT_PERFORM_ON_SELF,
L2RC_Clans_SetMemberRank_UNKNOWN_CLAN,
L2RC_Clans_SetMemberRank_NOT_IN_CLAN,
L2RC_Clans_SetMemberRank_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_SetMemberRank_MUST_BE_LEADER,
L2RC_Clans_SetMemberRank_CANNOT_PERFORM_ON_SELF,
L2RC_Clans_SetMemberRank_TARGET_NOT_IN_CLAN,
L2RC_Clans_GetMemberProperties_UNKNOWN_CLAN,
L2RC_Clans_GetMemberProperties_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_GetMemberProperties_TARGET_NOT_IN_CLAN,
L2RC_Clans_ChangeHandle_UNKNOWN_CLAN,
L2RC_Clans_ChangeHandle_NOT_IN_CLAN,
L2RC_Clans_ChangeHandle_NEW_HANDLE_IN_USE,
L2RC_Clans_ChangeHandle_MUST_BE_LEADER,
L2RC_Clans_ChangeHandle_HANDLE_NOT_CHANGED,
L2RC_Clans_Leave_UNKNOWN_CLAN,
L2RC_Clans_Leave_NOT_IN_CLAN,
L2RC_Clans_SendJoinInvitation_UNKNOWN_CLAN,
L2RC_Clans_SendJoinInvitation_NOT_IN_CLAN,
L2RC_Clans_SendJoinInvitation_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_SendJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_SendJoinInvitation_REQUEST_ALREADY_PENDING,
L2RC_Clans_SendJoinInvitation_CANNOT_PERFORM_ON_SELF,
L2RC_Clans_SendJoinInvitation_TARGET_ALREADY_REQUESTED,
L2RC_Clans_SendJoinInvitation_TARGET_IS_BANNED,
L2RC_Clans_SendJoinInvitation_TARGET_ALREADY_IN_CLAN,
L2RC_Clans_WithdrawJoinInvitation_UNKNOWN_CLAN,
L2RC_Clans_WithdrawJoinInvitation_NO_SUCH_INVITATION_EXISTS,
L2RC_Clans_WithdrawJoinInvitation_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_WithdrawJoinInvitation_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_WithdrawJoinInvitation_CANNOT_PERFORM_ON_SELF,
L2RC_Clans_AcceptJoinInvitation_ALREADY_IN_CLAN,
L2RC_Clans_AcceptJoinInvitation_ALREADY_IN_DIFFERENT_CLAN,
L2RC_Clans_AcceptJoinInvitation_UNKNOWN_CLAN,
L2RC_Clans_AcceptJoinInvitation_NOT_IN_CLAN,
L2RC_Clans_AcceptJoinInvitation_NO_SUCH_INVITATION_EXISTS,
L2RC_Clans_RejectJoinInvitation_UNKNOWN_CLAN,
L2RC_Clans_RejectJoinInvitation_NO_SUCH_INVITATION_EXISTS,
L2RC_Clans_DownloadInvitationList_UNKNOWN_CLAN,
L2RC_Clans_SendJoinRequest_UNKNOWN_CLAN,
L2RC_Clans_SendJoinRequest_REQUEST_ALREADY_PENDING,
L2RC_Clans_SendJoinRequest_ALREADY_IN_CLAN,
L2RC_Clans_SendJoinRequest_BANNED,
L2RC_Clans_SendJoinRequest_ALREADY_INVITED,
L2RC_Clans_WithdrawJoinRequest_UNKNOWN_CLAN,
L2RC_Clans_WithdrawJoinRequest_ALREADY_IN_CLAN,
L2RC_Clans_WithdrawJoinRequest_NO_SUCH_INVITATION_EXISTS,
L2RC_Clans_AcceptJoinRequest_UNKNOWN_CLAN,
L2RC_Clans_AcceptJoinRequest_NOT_IN_CLAN,
L2RC_Clans_AcceptJoinRequest_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_AcceptJoinRequest_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_AcceptJoinRequest_CANNOT_PERFORM_ON_SELF,
L2RC_Clans_AcceptJoinRequest_TARGET_ALREADY_IN_CLAN,
L2RC_Clans_AcceptJoinRequest_TARGET_ALREADY_IN_DIFFERENT_CLAN,
L2RC_Clans_AcceptJoinRequest_TARGET_IS_BANNED,
L2RC_Clans_AcceptJoinRequest_REQUEST_NOT_PENDING,
L2RC_Clans_RejectJoinRequest_UNKNOWN_CLAN,
L2RC_Clans_RejectJoinRequest_NOT_IN_CLAN,
L2RC_Clans_RejectJoinRequest_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_RejectJoinRequest_REQUESTING_USER_HANDLE_UNKNOWN,
L2RC_Clans_RejectJoinRequest_NO_SUCH_INVITATION_EXISTS,
L2RC_Clans_KickAndBlacklistUser_UNKNOWN_CLAN,
L2RC_Clans_KickAndBlacklistUser_NOT_IN_CLAN,
L2RC_Clans_KickAndBlacklistUser_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_KickAndBlacklistUser_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_KickAndBlacklistUser_ALREADY_BLACKLISTED,
L2RC_Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_SELF,
L2RC_Clans_KickAndBlacklistUser_CANNOT_PERFORM_ON_LEADER,
L2RC_Clans_UnblacklistUser_UNKNOWN_CLAN,
L2RC_Clans_UnblacklistUser_NOT_IN_CLAN,
L2RC_Clans_UnblacklistUser_UNKNOWN_TARGET_HANDLE,
L2RC_Clans_UnblacklistUser_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_UnblacklistUser_NOT_BLACKLISTED,
L2RC_Clans_GetBlacklist_UNKNOWN_CLAN,
L2RC_Clans_GetMembers_UNKNOWN_CLAN,
L2RC_Clans_CreateBoard_UNKNOWN_CLAN,
L2RC_Clans_CreateBoard_NOT_IN_CLAN,
L2RC_Clans_CreateBoard_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_CreateBoard_BOARD_ALREADY_EXISTS,
L2RC_Clans_DestroyBoard_UNKNOWN_CLAN,
L2RC_Clans_DestroyBoard_NOT_IN_CLAN,
L2RC_Clans_DestroyBoard_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_DestroyBoard_BOARD_DOES_NOT_EXIST,
L2RC_Clans_CreateNewTopic_UNKNOWN_CLAN,
L2RC_Clans_CreateNewTopic_BOARD_DOES_NOT_EXIST,
L2RC_Clans_CreateNewTopic_PERMISSION_DENIED,
L2RC_Clans_ReplyToTopic_UNKNOWN_POST_ID,
L2RC_Clans_ReplyToTopic_PERMISSION_DENIED,
L2RC_Clans_RemovePost_UNKNOWN_POST_ID,
L2RC_Clans_RemovePost_NOT_IN_CLAN,
L2RC_Clans_RemovePost_MUST_BE_LEADER_OR_SUBLEADER,
L2RC_Clans_GetBoards_UNKNOWN_CLAN,
L2RC_Clans_GetTopics_UNKNOWN_CLAN,
L2RC_Clans_GetTopics_BOARD_DOES_NOT_EXIST,
L2RC_Clans_GetPosts_UNKNOWN_POST_ID,
L2RC_Console_JoinLobby_LOBBY_FULL,
L2RC_Console_JoinLobby_NO_SUCH_LOBBY,
L2RC_Console_GetRoomDetails_NO_ROOMS_FOUND,
L2RC_Console_SignIntoRoom_NO_USERS,
L2RC_Console_SignIntoRoom_NO_SUCH_ROOM,
L2RC_Console_SignIntoRoom_JOIN_ILLEGAL,
L2RC_Console_SignIntoRoom_REMOTE_JOIN_FAILED,
L2RC_Console_JoinRoom_ROOM_FULL,
L2RC_Console_JoinRoom_WRONG_PASSWORD,
L2RC_Console_JoinRoom_NO_SUCH_ROOM,
L2RC_Console_JoinRoom_SERVER_ERROR_BLOCKED,
L2RC_Console_JoinRoom_ALREADY_IN_ROOM,
L2RC_Console_JoinRoom_CONNECTION_TIMEOUT,
L2RC_Console_ModifyRoom_NO_SUCH_ROOM,
L2RC_Console_ModifyRoom_MUST_BE_HOST,
L2RC_Console_UpdateRoomParameters_ROOM_WAS_DELETED_WHILE_IN_PROGRESS,
L2RC_Console_LeaveRoom_NO_SUCH_ROOM,
L2RC_Console_LeaveRoom_ROOM_WAS_DELETED_WHILE_IN_PROGRESS,
L2RC_Console_StartGame_NO_SUCH_ROOM,
L2RC_Console_StartGame_MUST_BE_HOST,
L2RC_Console_StartGame_ALREADY_STARTED,
L2RC_Console_StartGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS,
L2RC_Console_EndGame_NO_SUCH_ROOM,
L2RC_Console_EndGame_MUST_BE_HOST,
L2RC_Console_EndGame_NOT_STARTED,
L2RC_Console_EndGame_ROOM_WAS_DELETED_WHILE_IN_PROGRESS,
L2RC_Notification_Console_CableDisconnected,
L2RC_Notification_ContextError_SignedOut,
L2RC_Notification_ContextError_SystemError,
L2RC_COUNT,
};
struct Lobby2ResultCodeDescription
{
Lobby2ResultCode resultCode;
const char *enumDesc;
const char *englishDesc;
static const char *ToEnglish(Lobby2ResultCode result);
static const char *ToEnum(Lobby2ResultCode result);
static void Validate(void);
};
} // namespace SLNet
#endif

View File

@ -0,0 +1,735 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Server.h"
#include "slikenet/assert.h"
#include "slikenet/MessageIdentifiers.h"
//#define __INTEGRATE_LOBBY2_WITH_ROOMS_PLUGIN
#ifdef __INTEGRATE_LOBBY2_WITH_ROOMS_PLUGIN
#include "RoomsPlugin.h"
#endif
using namespace SLNet;
int Lobby2Server::UserCompByUsername( const RakString &key, Lobby2Server::User * const &data )
{
if (key < data->userName)
return -1;
if (key==data->userName)
return 0;
return 1;
}
Lobby2Server::Lobby2Server()
{
DataStructures::OrderedList<SystemAddress, SystemAddress>::IMPLEMENT_DEFAULT_COMPARISON();
DataStructures::OrderedList<RakString, RakString>::IMPLEMENT_DEFAULT_COMPARISON();
roomsPlugin=0;
roomsPluginAddress=UNASSIGNED_SYSTEM_ADDRESS;
}
Lobby2Server::~Lobby2Server()
{
Clear();
}
void Lobby2Server::SendMsg(Lobby2Message *msg, const DataStructures::List<SystemAddress> &recipients)
{
SLNet::BitStream bs;
bs.Write((MessageID)ID_LOBBY2_SEND_MESSAGE);
bs.Write((MessageID)msg->GetID());
msg->Serialize(true,true,&bs);
SendUnifiedToMultiple(&bs,packetPriority, RELIABLE_ORDERED, orderingChannel, recipients);
}
void Lobby2Server::Update(void)
{
while (threadActionQueue.Size())
{
threadActionQueueMutex.Lock();
if (threadActionQueue.Size())
{
ThreadAction ta = threadActionQueue.Pop();
threadActionQueueMutex.Unlock();
if (ta.action==L2MID_Client_Logoff)
{
OnLogoff(&ta.command, false);
}
else if (ta.action==L2MID_Client_Login)
{
OnLogin(&ta.command, false);
}
else if (ta.action==L2MID_Client_ChangeHandle)
{
OnChangeHandle(&ta.command, false);
}
}
else
{
threadActionQueueMutex.Unlock();
break;
}
}
if (threadPool.HasOutputFast() && threadPool.HasOutput())
{
Lobby2ServerCommand c = threadPool.GetOutput();
c.lobby2Message->ServerPostDBMemoryImpl(this, c.callingUserName);
if (c.returnToSender)
{
for (unsigned long i=0; i < callbacks.Size(); i++)
{
if (c.lobby2Message->callbackId==(uint32_t)-1 || c.lobby2Message->callbackId==callbacks[i]->callbackId)
c.lobby2Message->CallCallback(callbacks[i]);
}
SLNet::BitStream bs;
bs.Write((MessageID)ID_LOBBY2_SEND_MESSAGE);
bs.Write((MessageID)c.lobby2Message->GetID());
c.lobby2Message->Serialize(true,true,&bs);
// Have the ID to send to, but not the address. The ID came from the thread, such as notifying another user
if (c.callerSystemAddresses.Size()==0)
{
unsigned int i;
if (c.callerUserId!=0)
{
for (i=0; i < users.Size(); i++)
{
if (users[i]->callerUserId==c.callerUserId)
{
c.callerSystemAddresses=users[i]->systemAddresses;
c.callerGuids=users[i]->guids;
/*
if (c.requiredConnectionAddress!=UNASSIGNED_SYSTEM_ADDRESS)
{
// This message refers to another user that has to be logged on for it to be sent
bool objectExists;
unsigned int idx;
idx = users.GetIndexFromKey(c.callerSystemAddress,&objectExists);
if (objectExists==false)
{
if (c.deallocMsgWhenDone)
SLNet::OP_DELETE(c.lobby2Message, __FILE__, __LINE__);
return;
}
}
*/
break;
}
}
}
if (c.callerSystemAddresses.Size()==0 && c.callingUserName.IsEmpty()==false)
{
for (i=0; i < users.Size(); i++)
{
if (users[i]->callerUserId==c.callerUserId)
{
c.callerSystemAddresses=users[i]->systemAddresses;
c.callerGuids=users[i]->guids;
break;
}
}
}
}
else
{
bool objectExists;
unsigned int idx;
idx = users.GetIndexFromKey(c.callingUserName,&objectExists);
if (objectExists &&
c.callingUserName.IsEmpty()==false &&
users[idx]->userName!=c.callingUserName)
{
// Different user, same IP address. Abort the send.
if (c.deallocMsgWhenDone)
SLNet::OP_DELETE(c.lobby2Message, __FILE__, __LINE__);
return;
}
}
SendUnifiedToMultiple(&bs,packetPriority, RELIABLE_ORDERED, orderingChannel, c.callerSystemAddresses);
}
if (c.deallocMsgWhenDone)
SLNet::OP_DELETE(c.lobby2Message, __FILE__, __LINE__);
}
}
PluginReceiveResult Lobby2Server::OnReceive(Packet *packet)
{
RakAssert(packet);
switch (packet->data[0])
{
case ID_LOBBY2_SEND_MESSAGE:
OnMessage(packet);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
return RR_CONTINUE_PROCESSING;
}
void Lobby2Server::OnShutdown(void)
{
Clear();
}
void Lobby2Server::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
(void)rakNetGUID;
(void)lostConnectionReason;
unsigned int index = GetUserIndexBySystemAddress(systemAddress);
// If systemAddress is a user, then notify his friends about him logging off
if (index!=-1)
{
bool found=false;
User *user = users[index];
for (unsigned int i=0; i < user->systemAddresses.Size(); i++)
{
if (user->systemAddresses[i]==systemAddress)
{
found=true;
user->systemAddresses.RemoveAtIndexFast(i);
break;
}
}
if (found && user->systemAddresses.Size()==0)
{
// Log this logoff due to closed connection
Lobby2Message *lobby2Message = msgFactory->Alloc(L2MID_Client_Logoff);
Lobby2ServerCommand command;
command.lobby2Message=lobby2Message;
command.deallocMsgWhenDone=true;
command.returnToSender=true;
command.callerUserId=users[index]->callerUserId;
command.server=this;
ExecuteCommand(&command);
RemoveUser(index);
}
}
}
void Lobby2Server::OnMessage(Packet *packet)
{
SLNet::BitStream bs(packet->data,packet->length,false);
bs.IgnoreBytes(1); // ID_LOBBY2_SEND_MESSAGE
MessageID msgId;
bs.Read(msgId);
Lobby2MessageID lobby2MessageID = (Lobby2MessageID) msgId;
unsigned int index;
Lobby2Message *lobby2Message = msgFactory->Alloc(lobby2MessageID);
if (lobby2Message)
{
lobby2Message->Serialize(false,false,&bs);
Lobby2ServerCommand command;
command.lobby2Message=lobby2Message;
command.deallocMsgWhenDone=true;
command.returnToSender=true;
index=GetUserIndexBySystemAddress(packet->systemAddress);
if (index!=-1)
{
command.callingUserName=users[index]->userName;
command.callerUserId=users[index]->callerUserId;
}
else
{
if (lobby2Message->RequiresLogin())
{
SLNet::BitStream bs2;
bs2.Write((MessageID)ID_LOBBY2_SEND_MESSAGE);
bs2.Write((MessageID)lobby2Message->GetID());
lobby2Message->resultCode=L2RC_NOT_LOGGED_IN;
lobby2Message->Serialize(true,true,&bs2);
SendUnified(&bs2,packetPriority, RELIABLE_ORDERED, orderingChannel, packet->systemAddress, false);
return;
}
command.callerUserId=0;
}
command.callerSystemAddresses.Push(packet->systemAddress,__FILE__,__LINE__);
command.callerGuids.Push(packet->guid,__FILE__,__LINE__);
command.server=this;
ExecuteCommand(&command);
}
else
{
SLNet::BitStream out;
out.Write((MessageID)ID_LOBBY2_SERVER_ERROR);
out.Write((unsigned char) L2SE_UNKNOWN_MESSAGE_ID);
out.Write((unsigned int) msgId);
SendUnified(&bs,packetPriority, RELIABLE_ORDERED, orderingChannel, packet->systemAddress, false);
}
}
void Lobby2Server::Clear(void)
{
ClearAdminAddresses();
ClearRankingAddresses();
ClearUsers();
ClearConnections();
threadPool.StopThreads();
RakAssert(threadPool.NumThreadsWorking()==0);
unsigned i;
Lobby2ServerCommand c;
for (i=0; i < threadPool.InputSize(); i++)
{
c = threadPool.GetInputAtIndex(i);
if (c.deallocMsgWhenDone && c.lobby2Message)
SLNet::OP_DELETE(c.lobby2Message, __FILE__, __LINE__);
}
threadPool.ClearInput();
for (i=0; i < threadPool.OutputSize(); i++)
{
c = threadPool.GetOutputAtIndex(i);
if (c.deallocMsgWhenDone && c.lobby2Message)
SLNet::OP_DELETE(c.lobby2Message, __FILE__, __LINE__);
}
threadPool.ClearOutput();
threadActionQueueMutex.Lock();
threadActionQueue.Clear(__FILE__, __LINE__);
threadActionQueueMutex.Unlock();
}
void Lobby2Server::AddAdminAddress(SystemAddress addr)
{
adminAddresses.Insert(addr,addr,false, __FILE__, __LINE__ );
}
bool Lobby2Server::HasAdminAddress(const DataStructures::List<SystemAddress> &addresses)
{
if (addresses.Size()==0)
return true;
unsigned int j;
for (j=0; j < addresses.Size(); j++)
{
if (adminAddresses.HasData(addresses[j]))
return true;
}
return false;
}
void Lobby2Server::RemoveAdminAddress(SystemAddress addr)
{
adminAddresses.RemoveIfExists(addr);
}
void Lobby2Server::ClearAdminAddresses(void)
{
adminAddresses.Clear(false, __FILE__, __LINE__);
}
void Lobby2Server::AddRankingAddress(SystemAddress addr)
{
rankingAddresses.Insert(addr,addr,false, __FILE__, __LINE__ );
}
bool Lobby2Server::HasRankingAddress(const DataStructures::List<SystemAddress> &addresses)
{
if (addresses.Size()==0)
return true;
unsigned int j;
for (j=0; j < addresses.Size(); j++)
{
if (rankingAddresses.HasData(addresses[j]))
return true;
}
return false;
}
void Lobby2Server::RemoveRankingAddress(SystemAddress addr)
{
rankingAddresses.RemoveIfExists(addr);
}
void Lobby2Server::ClearRankingAddresses(void)
{
rankingAddresses.Clear(false, __FILE__, __LINE__);
}
void Lobby2Server::ExecuteCommand(Lobby2ServerCommand *command)
{
//SLNet::BitStream out;
if (command->lobby2Message->PrevalidateInput()==false)
{
SendMsg(command->lobby2Message, command->callerSystemAddresses);
if (command->deallocMsgWhenDone)
msgFactory->Dealloc(command->lobby2Message);
return;
}
if (command->lobby2Message->RequiresAdmin() && HasAdminAddress(command->callerSystemAddresses)==false)
{
command->lobby2Message->resultCode=L2RC_REQUIRES_ADMIN;
SendMsg(command->lobby2Message, command->callerSystemAddresses);
//SendUnifiedToMultiple(&out,packetPriority, RELIABLE_ORDERED, orderingChannel, command->callerSystemAddresses);
if (command->deallocMsgWhenDone)
msgFactory->Dealloc(command->lobby2Message);
return;
}
if (command->lobby2Message->RequiresRankingPermission() && HasRankingAddress(command->callerSystemAddresses)==false)
{
command->lobby2Message->resultCode=L2RC_REQUIRES_ADMIN;
SendMsg(command->lobby2Message, command->callerSystemAddresses);
//SendUnifiedToMultiple(&out,packetPriority, RELIABLE_ORDERED, orderingChannel, command->callerSystemAddresses);
if (command->deallocMsgWhenDone)
msgFactory->Dealloc(command->lobby2Message);
return;
}
if (command->lobby2Message->ServerPreDBMemoryImpl(this, command->callingUserName)==true)
{
SendMsg(command->lobby2Message, command->callerSystemAddresses);
if (command->deallocMsgWhenDone)
msgFactory->Dealloc(command->lobby2Message);
return;
}
command->server=this;
AddInputCommand(*command);
}
void Lobby2Server::SetRoomsPlugin(RoomsPlugin *rp)
{
roomsPlugin=rp;
roomsPluginAddress=UNASSIGNED_SYSTEM_ADDRESS;
}
void Lobby2Server::SetRoomsPluginAddress(SystemAddress address)
{
roomsPluginAddress=address;
roomsPlugin=0;
}
void Lobby2Server::ClearUsers(void)
{
unsigned int i;
for (i=0; i < users.Size(); i++)
SLNet::OP_DELETE(users[i], __FILE__, __LINE__);
users.Clear(false, __FILE__, __LINE__);
}
void Lobby2Server::LogoffFromRooms(User *user)
{
// Remove from the room too
#if defined(__INTEGRATE_LOBBY2_WITH_ROOMS_PLUGIN)
// Tell the rooms plugin about the logoff event
if (roomsPlugin)
{
roomsPlugin->LogoffRoomsParticipant(user->userName, UNASSIGNED_SYSTEM_ADDRESS);
}
else if (roomsPluginAddress!=UNASSIGNED_SYSTEM_ADDRESS)
{
SLNet::BitStream bs;
RoomsPlugin::SerializeLogoff(user->userName,&bs);
SendUnified(&bs,packetPriority, RELIABLE_ORDERED, orderingChannel, roomsPluginAddress, false);
}
#endif
}
void Lobby2Server::SendRemoteLoginNotification(SLNet::RakString handle, const DataStructures::List<SystemAddress>& recipients)
{
Notification_Client_RemoteLogin notification;
notification.handle=handle;
notification.resultCode=L2RC_SUCCESS;
SendMsg(&notification, recipients);
}
void Lobby2Server::OnLogin(Lobby2ServerCommand *command, bool calledFromThread)
{
if (calledFromThread)
{
ThreadAction ta;
ta.action=L2MID_Client_Login;
ta.command=*command;
threadActionQueueMutex.Lock();
threadActionQueue.Push(ta, __FILE__, __LINE__ );
threadActionQueueMutex.Unlock();
return;
}
bool objectExists;
unsigned int insertionIndex = users.GetIndexFromKey(command->callingUserName, &objectExists);
if (objectExists)
{
User * user = users[insertionIndex];
if (user->allowMultipleLogins==false)
{
SendRemoteLoginNotification(user->userName, user->systemAddresses);
LogoffFromRooms(user);
// Already logged in from this system address.
// Delete the existing entry, which will be reinserted.
SLNet::OP_DELETE(user,_FILE_AND_LINE_);
users.RemoveAtIndex(insertionIndex);
}
else
{
if (user->systemAddresses.GetIndexOf(command->callerSystemAddresses[0])==(unsigned int) -1)
{
// Just add system address and guid already in use to the list for this user
user->systemAddresses.Push(command->callerSystemAddresses[0], __FILE__, __LINE__);
user->guids.Push(command->callerGuids[0], __FILE__, __LINE__);
}
return;
}
}
else
{
// Different username, from the same IP address or RakNet instance
unsigned int idx2 = GetUserIndexByGUID(command->callerGuids[0]);
unsigned int idx3 = GetUserIndexBySystemAddress(command->callerSystemAddresses[0]);
if (idx2!=(unsigned int) -1)
{
User * user = users[idx2];
if (user->allowMultipleLogins==true)
return;
SendRemoteLoginNotification(user->userName, user->systemAddresses);
LogoffFromRooms(user);
SLNet::OP_DELETE(user,__FILE__,__LINE__);
users.RemoveAtIndex(idx2);
insertionIndex = users.GetIndexFromKey(command->callingUserName, &objectExists);
}
else if (idx3!=(unsigned int) -1)
{
User * user = users[idx3];
if (user->allowMultipleLogins==true)
return;
SendRemoteLoginNotification(user->userName, user->systemAddresses);
LogoffFromRooms(user);
SLNet::OP_DELETE(user,__FILE__,__LINE__);
users.RemoveAtIndex(idx3);
insertionIndex = users.GetIndexFromKey(command->callingUserName, &objectExists);
}
}
User *user = SLNet::OP_NEW<User>( __FILE__, __LINE__ );
user->userName=command->callingUserName;
user->systemAddresses=command->callerSystemAddresses;
user->guids=command->callerGuids;
user->callerUserId=command->callerUserId;
user->allowMultipleLogins=((Client_Login*)command->lobby2Message)->allowMultipleLogins;
users.InsertAtIndex(user, insertionIndex, __FILE__, __LINE__ );
#if defined(__INTEGRATE_LOBBY2_WITH_ROOMS_PLUGIN)
// Tell the rooms plugin about the login event
if (roomsPlugin)
{
roomsPlugin->LoginRoomsParticipant(user->userName, user->systemAddresses[0], user->guids[0], UNASSIGNED_SYSTEM_ADDRESS);
}
else if (roomsPluginAddress!=UNASSIGNED_SYSTEM_ADDRESS)
{
SLNet::BitStream bs;
RoomsPlugin::SerializeLogin(user->userName,user->systemAddresses[0], user->guids[0], &bs);
SendUnified(&bs,packetPriority, RELIABLE_ORDERED, orderingChannel, roomsPluginAddress, false);
}
#endif
}
void Lobby2Server::OnLogoff(Lobby2ServerCommand *command, bool calledFromThread)
{
if (calledFromThread)
{
ThreadAction ta;
ta.action=L2MID_Client_Logoff;
ta.command=*command;
threadActionQueueMutex.Lock();
threadActionQueue.Push(ta, __FILE__, __LINE__ );
threadActionQueueMutex.Unlock();
return;
}
RemoveUser(command->callingUserName);
}
void Lobby2Server::OnChangeHandle(Lobby2ServerCommand *command, bool calledFromThread)
{
if (calledFromThread)
{
ThreadAction ta;
ta.action=L2MID_Client_ChangeHandle;
ta.command=*command;
threadActionQueueMutex.Lock();
threadActionQueue.Push(ta, __FILE__, __LINE__ );
threadActionQueueMutex.Unlock();
return;
}
unsigned int i;
SLNet::RakString oldHandle;
for (i=0; i < users.Size(); i++)
{
if (users[i]->callerUserId==command->callerUserId)
{
oldHandle=users[i]->userName;
users[i]->userName=command->callingUserName;
break;
}
}
if (oldHandle.IsEmpty())
return;
#if defined(__INTEGRATE_LOBBY2_WITH_ROOMS_PLUGIN)
// Tell the rooms plugin about the handle change
if (roomsPlugin)
{
roomsPlugin->ChangeHandle(oldHandle, command->callingUserName);
}
else if (roomsPluginAddress!=UNASSIGNED_SYSTEM_ADDRESS)
{
SLNet::BitStream bs;
RoomsPlugin::SerializeChangeHandle(oldHandle,command->callingUserName,&bs);
SendUnified(&bs,packetPriority, RELIABLE_ORDERED, orderingChannel, roomsPluginAddress, false);
}
#endif
}
void Lobby2Server::RemoveUser(RakString userName)
{
bool objectExists;
unsigned int index = users.GetIndexFromKey(userName, &objectExists);
if (objectExists)
RemoveUser(index);
}
void Lobby2Server::RemoveUser(unsigned int index)
{
User *user = users[index];
Lobby2ServerCommand command;
Notification_Friends_StatusChange *notification = (Notification_Friends_StatusChange *) GetMessageFactory()->Alloc(L2MID_Notification_Friends_StatusChange);
notification->otherHandle=user->userName;
notification->op=Notification_Friends_StatusChange::FRIEND_LOGGED_OFF;
notification->resultCode=L2RC_SUCCESS;
command.server=this;
command.deallocMsgWhenDone=true;
command.lobby2Message=notification;
command.callerUserId=user->callerUserId;
command.callingUserName=user->userName;
ExecuteCommand(&command);
unsigned i;
i=0;
threadPool.LockInput();
while (i < threadPool.InputSize())
{
command = threadPool.GetInputAtIndex(i);
if (command.lobby2Message->CancelOnDisconnect()&& command.callerSystemAddresses.Size()>0 && user->systemAddresses.GetIndexOf(command.callerSystemAddresses[0])!=(unsigned int)-1)
{
if (command.deallocMsgWhenDone)
SLNet::OP_DELETE(command.lobby2Message, __FILE__, __LINE__);
threadPool.RemoveInputAtIndex(i);
}
else
i++;
}
threadPool.UnlockInput();
LogoffFromRooms(user);
SLNet::OP_DELETE(user,__FILE__,__LINE__);
users.RemoveAtIndex(index);
}
unsigned int Lobby2Server::GetUserIndexBySystemAddress(SystemAddress systemAddress) const
{
unsigned int idx1,idx2;
for (idx1=0; idx1 < users.Size(); idx1++)
{
for (idx2=0; idx2 < users[idx1]->systemAddresses.Size(); idx2++)
{
if (users[idx1]->systemAddresses[idx2]==systemAddress)
return idx1;
}
}
return (unsigned int) -1;
}
unsigned int Lobby2Server::GetUserIndexByGUID(RakNetGUID guid) const
{
unsigned int idx1,idx2;
for (idx1=0; idx1 < users.Size(); idx1++)
{
for (idx2=0; idx2 < users[idx1]->guids.Size(); idx2++)
{
if (users[idx1]->guids[idx2]==guid)
return idx1;
}
}
return (unsigned int) -1;
}
unsigned int Lobby2Server::GetUserIndexByUsername(SLNet::RakString userName) const
{
unsigned int idx;
bool objectExists;
idx = users.GetIndexFromKey(userName,&objectExists);
if (objectExists)
return idx;
return (unsigned int) -1;
}
void Lobby2Server::StopThreads(void)
{
threadPool.StopThreads();
}
void Lobby2Server::SetConfigurationProperties(ConfigurationProperties c)
{
configurationProperties=c;
}
const Lobby2Server::ConfigurationProperties *Lobby2Server::GetConfigurationProperties(void) const
{
return &configurationProperties;
}
void Lobby2Server::GetUserOnlineStatus(UsernameAndOnlineStatus &userInfo) const
{
unsigned int idx = GetUserIndexByUsername(userInfo.handle);
if (idx!=-1)
{
userInfo.isOnline=true;
userInfo.presence=users[idx]->presence;
}
else
{
userInfo.isOnline=false;
userInfo.presence.status=Lobby2Presence::NOT_ONLINE;
userInfo.presence.isVisible=false;
}
}
void Lobby2Server::SetPresence(const SLNet::Lobby2Presence &presence, SLNet::RakString userHandle)
{
unsigned int index = GetUserIndexByUsername(userHandle);
if (index!=-1)
{
User *user = users[index];
user->presence=presence;
// Push notify presence update to friends
Lobby2ServerCommand command;
Notification_Friends_PresenceUpdate *notification = (Notification_Friends_PresenceUpdate *) GetMessageFactory()->Alloc(L2MID_Notification_Friends_PresenceUpdate);
notification->newPresence=presence;
notification->otherHandle=user->userName;
notification->resultCode=L2RC_SUCCESS;
command.server=this;
command.deallocMsgWhenDone=true;
command.lobby2Message=notification;
command.callerUserId=user->callerUserId;
command.callingUserName=user->userName;
ExecuteCommand(&command);
}
}
void Lobby2Server::GetPresence(SLNet::Lobby2Presence &presence, SLNet::RakString userHandle)
{
unsigned int userIndex = GetUserIndexByUsername(userHandle);
if (userIndex!=-1)
{
presence=users[userIndex]->presence;
}
else
{
presence.status=Lobby2Presence::NOT_ONLINE;
}
}
void Lobby2Server::SendUnifiedToMultiple( const SLNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char curOrderingChannel, const DataStructures::List<SystemAddress> systemAddresses )
{
for (unsigned int i=0; i < systemAddresses.Size(); i++)
SendUnified(bitStream,priority,reliability,curOrderingChannel,systemAddresses[i],false);
}

View File

@ -0,0 +1,224 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017-2018, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_SERVER_H
#define __LOBBY_2_SERVER_H
#include "slikenet/Export.h"
#include "slikenet/types.h"
#include "Lobby2Plugin.h"
#include "slikenet/DS_OrderedList.h"
#include "slikenet/ThreadPool.h"
#include "Lobby2Presence.h"
//class PostgreSQLInterface;
namespace SLNet
{
struct Lobby2Message;
class RoomsPlugin;
/// Commands are either messages from remote systems, or can be run by the local system
/// \internal
struct Lobby2ServerCommand
{
Lobby2Message *lobby2Message;
bool deallocMsgWhenDone;
bool returnToSender;
unsigned int callerUserId;
SLNet::RakString callingUserName;
DataStructures::List<SystemAddress> callerSystemAddresses;
DataStructures::List<RakNetGUID> callerGuids;
//SystemAddress requiredConnectionAddress;
Lobby2Server *server;
};
/// \brief The base class for the lobby server, without database specific functionality
/// \details This is a plugin which will take incoming messages via Lobby2Client_PC::SendMsg(), process them, and send back the same messages with output and a result code
/// Unlike the first implementation of the lobby server, this is a thin plugin that mostly just sends messages to threads and sends back the results.
/// \ingroup LOBBY_2_SERVER
class RAK_DLL_EXPORT Lobby2Server : public SLNet::Lobby2Plugin, public ThreadDataInterface
{
public:
Lobby2Server();
virtual ~Lobby2Server();
/// \brief Connect to the database \a numWorkerThreads times using the connection string
/// \param[in] conninfo See the postgre docs
/// \return True on success, false on failure.
virtual bool ConnectToDB(const char *conninfo, int numWorkerThreads)=0;
/// \internal
virtual void AddInputFromThread(Lobby2Message *msg, unsigned int targetUserId, SLNet::RakString targetUserHandle)=0;
/// \internal
virtual void AddOutputFromThread(Lobby2Message *msg, unsigned int targetUserId, SLNet::RakString targetUserHandle)=0;
/// \brief Lobby2Message encapsulates a user command, containing both input and output data
/// \details This will serialize and transmit that command
void SendMsg(Lobby2Message *msg, const DataStructures::List<SystemAddress> &recipients);
/// \brief Add a command, which contains a message and other data such as who send the message.
/// \details The command will be processed according to its implemented virtual functions. Most likely it will be processed in a thread to run database commands
void ExecuteCommand(Lobby2ServerCommand *command);
/// \brief If Lobby2Message::RequiresAdmin() returns true, the message can only be processed from a remote system if the sender's system address is first added()
/// \details This is useful if you want to administrate the server remotely
void AddAdminAddress(SystemAddress addr);
/// \brief If AddAdminAddress() was previously called with \a addr then this returns true.
bool HasAdminAddress(const DataStructures::List<SystemAddress> &addresses);
/// \brief Removes a system address previously added with AddAdminAddress()
void RemoveAdminAddress(SystemAddress addr);
/// \brief Removes all system addresses previously added with AddAdminAddress()
void ClearAdminAddresses(void);
/// \brief If Lobby2Message::RequiresRankingPermission() returns true, then the system that sent the command must be registered with AddRankingAddress()
/// \param[in] addr Address to allow
void AddRankingAddress(SystemAddress addr);
/// Returns if an address was previously added with AddRankingAddress()
/// \param[in] addr Address to check
bool HasRankingAddress(const DataStructures::List<SystemAddress> &addresses);
/// Removes an addressed added with AddRankingAddress()
/// \param[in] addr Address to check
void RemoveRankingAddress(SystemAddress addr);
/// \brief Clears all addresses added with AddRankingAddress()
void ClearRankingAddresses(void);
/// \brief To use RoomsPlugin and Lobby2Server together, register RoomsPlugin with this funcrtion
/// \details The rooms plugin does not automatically handle users logging in and logging off, or renaming users.
/// You can have Lobby2Server manage this for you by calling SetRoomsPlugin() with a pointer to the rooms plugin, if it is on the local system.
/// This will call RoomsPlugin::LoginRoomsParticipant() and RoomsPlugin::LogoffRoomsParticipant() as the messages L2MID_Client_Login and L2MID_Client_Logoff arrive
/// This will use the pointer to RoomsPlugin directly. Setting this will disable SetRoomsPluginAddress()
/// \note This is an empty function. You must #define __INTEGRATE_LOBBY2_WITH_ROOMS_PLUGIN and link with RoomsPlugin.h to use it()
void SetRoomsPlugin(RoomsPlugin *rp);
/// \brief This is similar to SetRoomsPlugin(), except the plugin is on another system.
/// \details This will set the system address of that system to send the login and logoff commands to.
/// For this function to work, you must first call RoomsPlugin::AddLoginServerAddress() so that RoomsPlugin will accept the incoming login and logoff messages.
/// \note This is an empty function. You must #define __INTEGRATE_LOBBY2_WITH_ROOMS_PLUGIN and link with RoomsPlugin.h to use it()
void SetRoomsPluginAddress(SystemAddress address);
/// \brief Server configuration properties, to customize how the server runs specific commands
struct ConfigurationProperties
{
ConfigurationProperties() {requiresEmailAddressValidationToLogin=false; requiresTitleToLogin=false; accountRegistrationRequiredAgeYears=0;}
/// \brief If true, Client_Login will fail with Client_Login_EMAIL_ADDRESS_NOT_VALIDATED unless the email address registered with Client_RegisterAccount is verified with the command System_SetEmailAddressValidated
bool requiresEmailAddressValidationToLogin;
/// \brief If true Client_Login::titleName and Client_Login::titleSecretKey must be previously registered with System_CreateTitle or Client_Login will fail with L2RC_Client_Login_BAD_TITLE_OR_TITLE_SECRET_KEY
bool requiresTitleToLogin;
/// \brief If true, Client_RegisterAccount::cdKey must be previously registered with CDKey_Add or Client_RegisterAccount will fail with L2RC_Client_RegisterAccount_REQUIRES_CD_KEY or a related error message
bool accountRegistrationRequiresCDKey;
/// \brief The minimum age needed to register accounts. If Client_RegisterAccount::createAccountParameters::ageInDays is less than this, then the account registration will fail with L2RC_Client_RegisterAccount_REQUIRED_AGE_NOT_MET
/// \details Per-title age requirements can be handled client-side with System_CreateTitle::requiredAge and System_GetTitleRequiredAge
unsigned int accountRegistrationRequiredAgeYears;
};
/// \brief Set the desired configuration properties. This is read during runtime from threads.
void SetConfigurationProperties(ConfigurationProperties c);
/// \brief Get the previously set configuration properties.
const ConfigurationProperties *GetConfigurationProperties(void) const;
/// Set the presence of a logged in user
/// \param[in] presence Presence info of this user
void SetPresence(const SLNet::Lobby2Presence &presence, SLNet::RakString userHandle);
/// Get the presence of a logged in user, by handle
/// \param[out] presence Presence info of requested user
/// \param[in] userHandle Handle of the user
void GetPresence(SLNet::Lobby2Presence &presence, SLNet::RakString userHandle);
/// \internal Lets the plugin know that a user has logged on, so this user can be tracked and the message forwarded to RoomsPlugin
void OnLogin(Lobby2ServerCommand *command, bool calledFromThread);
/// \internal Lets the plugin know that a user has logged off, so this user can be tracked and the message forwarded to RoomsPlugin
void OnLogoff(Lobby2ServerCommand *command, bool calledFromThread);
/// \internal Lets the plugin know that a user has been renamed, so this user can be tracked and the message forwarded to RoomsPlugin
void OnChangeHandle(Lobby2ServerCommand *command, bool calledFromThread);
/// \internal
struct User
{
DataStructures::List<SystemAddress> systemAddresses;
DataStructures::List<RakNetGUID> guids;
unsigned int callerUserId;
SLNet::RakString userName;
Lobby2Presence presence;
bool allowMultipleLogins;
};
/// \internal
static int UserCompByUsername( const RakString &key, Lobby2Server::User * const &data );
/// \internal
struct ThreadAction
{
Lobby2MessageID action;
Lobby2ServerCommand command;
};
const DataStructures::OrderedList<RakString, User*, Lobby2Server::UserCompByUsername>& GetUsers(void) const {return users;}
void GetUserOnlineStatus(UsernameAndOnlineStatus &userInfo) const;
protected:
void Update(void);
PluginReceiveResult OnReceive(Packet *packet);
void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
void OnShutdown(void);
void OnMessage(Packet *packet);
void Clear(void);
void ClearUsers(void);
unsigned int GetUserIndexBySystemAddress(SystemAddress systemAddress) const;
unsigned int GetUserIndexByGUID(RakNetGUID guid) const;
unsigned int GetUserIndexByUsername(SLNet::RakString userName) const;
void StopThreads(void);
void SendRemoteLoginNotification(SLNet::RakString handle, const DataStructures::List<SystemAddress>& recipients);
/// \internal
void RemoveUser(RakString userName);
/// \internal
void RemoveUser(unsigned int index);
void LogoffFromRooms(User *user);
virtual void* PerThreadFactory(void *context)=0;
virtual void PerThreadDestructor(void* factoryResult, void *context)=0;
virtual void AddInputCommand(Lobby2ServerCommand command)=0;
virtual void ClearConnections(void) {};
DataStructures::OrderedList<SystemAddress, SystemAddress> adminAddresses;
DataStructures::OrderedList<SystemAddress, SystemAddress> rankingAddresses;
DataStructures::OrderedList<RakString, User*, Lobby2Server::UserCompByUsername> users;
RoomsPlugin *roomsPlugin;
SystemAddress roomsPluginAddress;
ThreadPool<Lobby2ServerCommand,Lobby2ServerCommand> threadPool;
SimpleMutex connectionPoolMutex;
ConfigurationProperties configurationProperties;
DataStructures::Queue<ThreadAction> threadActionQueue;
SimpleMutex threadActionQueueMutex;
//DataStructures::List<PostgreSQLInterface *> connectionPool;
//#med - rename curOrderingChannel back to orderingChannel and instead rename class member orderingChannel to m_orderingChannel
void SendUnifiedToMultiple( const SLNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char curOrderingChannel, const DataStructures::List<SystemAddress> systemAddresses );
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,531 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Message.h"
#include "Lobby2Server.h"
// libpq-fe.h is part of PostgreSQL which must be installed on this computer to use the PostgreRepository
#include "libpq-fe.h"
#include "PostgreSQLInterface.h"
#include "slikenet/EpochTimeToString.h"
#ifndef __LOBBY_2_MESSAGE_PGSQL_H
#define __LOBBY_2_MESSAGE_PGSQL_H
namespace SLNet
{
// --------------------------------------------- Database specific message implementations for the server --------------------------------------------
#define __L2_MSG_DB_HEADER(__NAME__,__DB__) \
struct __NAME__##_##__DB__ : public __NAME__
struct ClanMemberDescriptor
{
unsigned int userId;
SLNet::RakString name;
bool isSubleader;
ClanMemberState memberState;
SLNet::RakString banReason;
};
// Helper functions
unsigned int GetUserRowFromHandle(SLNet::RakString& userName, PostgreSQLInterface *pgsql);
unsigned int GetClanIdFromHandle(SLNet::RakString clanName, PostgreSQLInterface *pgsql);
bool IsClanLeader(SLNet::RakString clanName, unsigned int userId, PostgreSQLInterface *pgsql);
unsigned int GetClanLeaderId(unsigned int clanId, PostgreSQLInterface *pgsql);
bool IsClanLeader(unsigned int clanId, unsigned int userId, PostgreSQLInterface *pgsql);
ClanMemberState GetClanMemberState(unsigned int clanId, unsigned int userId, bool *isSubleader, PostgreSQLInterface *pgsql);
void GetClanMembers(unsigned int clanId, DataStructures::List<ClanMemberDescriptor> &clanMembers, PostgreSQLInterface *pgsql);
bool IsTitleInUse(SLNet::RakString titleName, PostgreSQLInterface *pgsql);
bool StringContainsProfanity(SLNet::RakString string, PostgreSQLInterface *pgsql);
bool IsValidCountry(SLNet::RakString string, bool *countryHasStates, PostgreSQLInterface *pgsql);
bool IsValidState(SLNet::RakString string, PostgreSQLInterface *pgsql);
bool IsValidRace(SLNet::RakString string, PostgreSQLInterface *pgsql);
void GetFriendIDs(unsigned int callerUserId, bool excludeIfIgnored, PostgreSQLInterface *pgsql, DataStructures::List<unsigned int> &output);
void GetClanMateIDs(unsigned int callerUserId, bool excludeIfIgnored, PostgreSQLInterface *pgsql, DataStructures::List<unsigned int> &output);
bool IsIgnoredByTarget(unsigned int callerUserId, unsigned int targetUserId, PostgreSQLInterface *pgsql);
void OutputFriendsNotification(SLNet::Notification_Friends_StatusChange::Status notificationType, Lobby2ServerCommand *command, PostgreSQLInterface *pgsql);
// This does NOT return the online status to output, as it is not threadsafe
void GetFriendInfosByStatus(unsigned int callerUserId, SLNet::RakString status, PostgreSQLInterface *pgsql, DataStructures::List<FriendInfo> &output, bool callerIsUserOne);
void SendEmail(DataStructures::List<SLNet::RakString> &recipientNames, unsigned int senderUserId, SLNet::RakString senderUserName, Lobby2Server *server, SLNet::RakString subject, SLNet::RakString body, RakNetSmartPtr<BinaryDataBlock>binaryData, int status, SLNet::RakString triggerString, PostgreSQLInterface *pgsql);
void SendEmail(DataStructures::List<unsigned int> &targetUserIds, unsigned int senderUserId, SLNet::RakString senderUserName, Lobby2Server *server, SLNet::RakString subject, SLNet::RakString body, RakNetSmartPtr<BinaryDataBlock>binaryData, int status, SLNet::RakString triggerString, PostgreSQLInterface *pgsql);
void SendEmail(unsigned int targetUserId, unsigned int senderUserId, SLNet::RakString senderUserName, Lobby2Server *server, SLNet::RakString subject, SLNet::RakString body, RakNetSmartPtr<BinaryDataBlock>binaryData, int status, SLNet::RakString triggerString, PostgreSQLInterface *pgsql);
int GetActiveClanCount(unsigned int userId, PostgreSQLInterface *pgsql);
bool CreateAccountParametersFailed( CreateAccountParameters &createAccountParameters, SLNet::Lobby2ResultCode &resultCode, Lobby2ServerCommand *command, PostgreSQLInterface *pgsql);
void UpdateAccountFromMissingCreationParameters(CreateAccountParameters &createAccountParameters, unsigned int userPrimaryKey, Lobby2ServerCommand *command, PostgreSQLInterface *pgsql);
__L2_MSG_DB_HEADER(Platform_Startup, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface ) { (void)command; (void)databaseInterface; return false; }};
__L2_MSG_DB_HEADER(Platform_Shutdown, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface ) { (void)command; (void)databaseInterface; return false; }};
__L2_MSG_DB_HEADER(System_CreateDatabase, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_DestroyDatabase, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_CreateTitle, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_DestroyTitle, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_GetTitleRequiredAge, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_GetTitleBinaryData, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_RegisterProfanity, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_BanUser, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_UnbanUser, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(CDKey_Add, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(CDKey_GetStatus, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(CDKey_Use, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(CDKey_FlagStolen, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_Login, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_Logoff, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_RegisterAccount, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_SetEmailAddressValidated, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_ValidateHandle, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_DeleteAccount, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(System_PruneAccounts, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_GetEmailAddress, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_GetPasswordRecoveryQuestionByHandle, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_GetPasswordByPasswordRecoveryAnswer, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_ChangeHandle, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_UpdateAccount, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_GetAccountDetails, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_StartIgnore, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_StopIgnore, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_GetIgnoreList, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Client_PerTitleIntegerStorage, PGSQL){
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );
virtual bool Write( Lobby2ServerCommand *command, void *databaseInterface );
virtual bool Read( Lobby2ServerCommand *command, void *databaseInterface );
virtual bool Delete( Lobby2ServerCommand *command, void *databaseInterface );
virtual bool Add( Lobby2ServerCommand *command, void *databaseInterface );
};
__L2_MSG_DB_HEADER(Client_SetPresence, PGSQL){virtual bool ServerPreDBMemoryImpl( Lobby2Server *server, RakString curUserHandle );};
__L2_MSG_DB_HEADER(Client_GetPresence, PGSQL){virtual bool ServerPreDBMemoryImpl( Lobby2Server *server, RakString curUserHandle );};
__L2_MSG_DB_HEADER(Client_PerTitleBinaryStorage, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Friends_SendInvite, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Friends_AcceptInvite, PGSQL){
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );
virtual void ServerPostDBMemoryImpl( Lobby2Server *server, RakString userHandle );
};
__L2_MSG_DB_HEADER(Friends_RejectInvite, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Friends_GetInvites, PGSQL){
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );
virtual void ServerPostDBMemoryImpl( Lobby2Server *server, RakString userHandle );
};
__L2_MSG_DB_HEADER(Friends_GetFriends, PGSQL){
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );
virtual void ServerPostDBMemoryImpl( Lobby2Server *server, RakString userHandle );
};
__L2_MSG_DB_HEADER(Friends_Remove, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(BookmarkedUsers_Add, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(BookmarkedUsers_Remove, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(BookmarkedUsers_Get, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Emails_Send, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Emails_Get, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Emails_Delete, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Emails_SetStatus, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_SubmitMatch, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_GetMatches, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_GetMatchBinaryData, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_GetTotalScore, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_WipeScoresForPlayer, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_WipeMatches, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_PruneMatches, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_UpdateRating, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_WipeRatings, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Ranking_GetRating, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_Create, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_SetProperties, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_GetProperties, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_SetMyMemberProperties, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_GrantLeader, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_SetSubleaderStatus, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_SetMemberRank, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_GetMemberProperties, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_ChangeHandle, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_Leave, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_Get, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_SendJoinInvitation, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_WithdrawJoinInvitation, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_AcceptJoinInvitation, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_RejectJoinInvitation, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_DownloadInvitationList, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_SendJoinRequest, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_WithdrawJoinRequest, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_AcceptJoinRequest, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_RejectJoinRequest, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_DownloadRequestList, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_KickAndBlacklistUser, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_UnblacklistUser, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_GetBlacklist, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_GetMembers, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_GetList, PGSQL){virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface );};
__L2_MSG_DB_HEADER(Clans_CreateBoard, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Clans_DestroyBoard, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Clans_CreateNewTopic, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Clans_ReplyToTopic, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Clans_RemovePost, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Clans_GetBoards, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Clans_GetTopics, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Clans_GetPosts, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
(void)command;
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
PGresult *result = pgsql->QueryVariadic("");
if (result!=0)
{
PQclear(result);
resultCode=L2RC_SUCCESS;
}
else
{
resultCode=L2RC_SUCCESS;
}
return true;
}
};
__L2_MSG_DB_HEADER(Notification_Friends_StatusChange, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
if (command->callerSystemAddresses.Size()==0)
{
OutputFriendsNotification(Notification_Friends_StatusChange::FRIEND_LOGGED_OFF, command, pgsql);
}
// Don't let the thread return this notification with SLNet::UNASSIGNED_SYSTEM_ADDRESS to the user. It's just a message to the thread.
return false;
}
virtual void ServerPostDBMemoryImpl( Lobby2Server *server, RakString userHandle )
{
switch (op)
{
case Notification_Friends_StatusChange::FRIEND_LOGGED_IN:
case Notification_Friends_StatusChange::FRIEND_LOGGED_IN_DIFFERENT_CONTEXT:
case Notification_Friends_StatusChange::THEY_ACCEPTED_OUR_INVITATION_TO_BE_FRIENDS:
server->GetPresence(presence,otherHandle);
break;
case Notification_Friends_StatusChange::FRIEND_LOGGED_OFF:
presence.isVisible=false;
presence.status=Lobby2Presence::NOT_ONLINE;
break;
case Notification_Friends_StatusChange::FRIEND_ACCOUNT_WAS_DELETED:
case Notification_Friends_StatusChange::YOU_WERE_REMOVED_AS_A_FRIEND:
case Notification_Friends_StatusChange::GOT_INVITATION_TO_BE_FRIENDS:
case Notification_Friends_StatusChange::THEY_REJECTED_OUR_INVITATION_TO_BE_FRIENDS:
presence.isVisible=false;
presence.status=Lobby2Presence::UNDEFINED;
break;
}
}
};
__L2_MSG_DB_HEADER(Notification_Friends_PresenceUpdate, PGSQL)
{
virtual bool ServerDBImpl( Lobby2ServerCommand *command, void *databaseInterface )
{
PostgreSQLInterface *pgsql = (PostgreSQLInterface *)databaseInterface;
// Tell all friends about this new login
DataStructures::List<unsigned int> output;
GetFriendIDs(command->callerUserId, true, pgsql, output);
unsigned int idx;
for (idx=0; idx < output.Size(); idx++)
{
Notification_Friends_PresenceUpdate *notification = (Notification_Friends_PresenceUpdate *) command->server->GetMessageFactory()->Alloc(L2MID_Notification_Friends_PresenceUpdate);
notification->otherHandle=command->callingUserName;
notification->newPresence=newPresence;
notification->resultCode=L2RC_SUCCESS;
command->server->AddOutputFromThread(notification, output[idx], "");
}
// Don't let the thread return this notification with SLNet::UNASSIGNED_SYSTEM_ADDRESS to the user. It's just a message to the thread.
return false;
}
};
// --------------------------------------------- Database specific factory class for all messages --------------------------------------------
#define __L2_MSG_FACTORY_IMPL(__NAME__,__DB__) {case L2MID_##__NAME__ : return SLNet::OP_NEW< __NAME__##_##__DB__ >( _FILE_AND_LINE_ ) ;}
struct Lobby2MessageFactory_PGSQL : public Lobby2MessageFactory
{
STATIC_FACTORY_DECLARATIONS(Lobby2MessageFactory_PGSQL)
virtual Lobby2Message *Alloc(Lobby2MessageID id)
{
switch (id)
{
__L2_MSG_FACTORY_IMPL(Platform_Startup, PGSQL);
__L2_MSG_FACTORY_IMPL(Platform_Shutdown, PGSQL);
__L2_MSG_FACTORY_IMPL(System_CreateDatabase, PGSQL);
__L2_MSG_FACTORY_IMPL(System_DestroyDatabase, PGSQL);
__L2_MSG_FACTORY_IMPL(System_CreateTitle, PGSQL);
__L2_MSG_FACTORY_IMPL(System_DestroyTitle, PGSQL);
__L2_MSG_FACTORY_IMPL(System_GetTitleRequiredAge, PGSQL);
__L2_MSG_FACTORY_IMPL(System_GetTitleBinaryData, PGSQL);
__L2_MSG_FACTORY_IMPL(System_RegisterProfanity, PGSQL);
__L2_MSG_FACTORY_IMPL(System_BanUser, PGSQL);
__L2_MSG_FACTORY_IMPL(System_UnbanUser, PGSQL);
__L2_MSG_FACTORY_IMPL(CDKey_Add, PGSQL);
__L2_MSG_FACTORY_IMPL(CDKey_GetStatus, PGSQL);
__L2_MSG_FACTORY_IMPL(CDKey_Use, PGSQL);
__L2_MSG_FACTORY_IMPL(CDKey_FlagStolen, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_Login, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_Logoff, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_RegisterAccount, PGSQL);
__L2_MSG_FACTORY_IMPL(System_SetEmailAddressValidated, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_ValidateHandle, PGSQL);
__L2_MSG_FACTORY_IMPL(System_DeleteAccount, PGSQL);
__L2_MSG_FACTORY_IMPL(System_PruneAccounts, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_GetEmailAddress, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_GetPasswordRecoveryQuestionByHandle, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_GetPasswordByPasswordRecoveryAnswer, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_ChangeHandle, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_UpdateAccount, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_GetAccountDetails, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_StartIgnore, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_StopIgnore, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_GetIgnoreList, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_PerTitleIntegerStorage, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_PerTitleBinaryStorage, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_SetPresence, PGSQL);
__L2_MSG_FACTORY_IMPL(Client_GetPresence, PGSQL);
__L2_MSG_FACTORY_IMPL(Friends_SendInvite, PGSQL);
__L2_MSG_FACTORY_IMPL(Friends_AcceptInvite, PGSQL);
__L2_MSG_FACTORY_IMPL(Friends_RejectInvite, PGSQL);
__L2_MSG_FACTORY_IMPL(Friends_GetInvites, PGSQL);
__L2_MSG_FACTORY_IMPL(Friends_GetFriends, PGSQL);
__L2_MSG_FACTORY_IMPL(Friends_Remove, PGSQL);
__L2_MSG_FACTORY_IMPL(BookmarkedUsers_Add, PGSQL);
__L2_MSG_FACTORY_IMPL(BookmarkedUsers_Remove, PGSQL);
__L2_MSG_FACTORY_IMPL(BookmarkedUsers_Get, PGSQL);
__L2_MSG_FACTORY_IMPL(Emails_Send, PGSQL);
__L2_MSG_FACTORY_IMPL(Emails_Get, PGSQL);
__L2_MSG_FACTORY_IMPL(Emails_Delete, PGSQL);
__L2_MSG_FACTORY_IMPL(Emails_SetStatus, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_SubmitMatch, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_GetMatches, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_GetMatchBinaryData, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_GetTotalScore, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_WipeScoresForPlayer, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_WipeMatches, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_PruneMatches, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_UpdateRating, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_WipeRatings, PGSQL);
__L2_MSG_FACTORY_IMPL(Ranking_GetRating, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_Create, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_SetProperties, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetProperties, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_SetMyMemberProperties, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GrantLeader, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_SetSubleaderStatus, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_SetMemberRank, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetMemberProperties, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_ChangeHandle, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_Leave, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_Get, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_SendJoinInvitation, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_WithdrawJoinInvitation, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_AcceptJoinInvitation, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_RejectJoinInvitation, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_DownloadInvitationList, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_SendJoinRequest, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_WithdrawJoinRequest, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_AcceptJoinRequest, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_RejectJoinRequest, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_DownloadRequestList, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_KickAndBlacklistUser, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_UnblacklistUser, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetBlacklist, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetMembers, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetList, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_CreateBoard, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_DestroyBoard, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_CreateNewTopic, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_ReplyToTopic, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_RemovePost, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetBoards, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetTopics, PGSQL);
__L2_MSG_FACTORY_IMPL(Clans_GetPosts, PGSQL);
__L2_MSG_FACTORY_BASE(Notification_Client_RemoteLogin);
__L2_MSG_FACTORY_BASE(Notification_Client_IgnoreStatus);
__L2_MSG_FACTORY_IMPL(Notification_Friends_StatusChange, PGSQL);
__L2_MSG_FACTORY_IMPL(Notification_Friends_PresenceUpdate, PGSQL);
__L2_MSG_FACTORY_BASE(Notification_User_ChangedHandle);
__L2_MSG_FACTORY_BASE(Notification_Friends_CreatedClan);
__L2_MSG_FACTORY_BASE(Notification_Emails_Received);
__L2_MSG_FACTORY_BASE(Notification_Clans_GrantLeader);
__L2_MSG_FACTORY_BASE(Notification_Clans_SetSubleaderStatus);
__L2_MSG_FACTORY_BASE(Notification_Clans_SetMemberRank);
__L2_MSG_FACTORY_BASE(Notification_Clans_ChangeHandle);
__L2_MSG_FACTORY_BASE(Notification_Clans_Leave);
__L2_MSG_FACTORY_BASE(Notification_Clans_PendingJoinStatus);
__L2_MSG_FACTORY_BASE(Notification_Clans_NewClanMember);
__L2_MSG_FACTORY_BASE(Notification_Clans_KickAndBlacklistUser);
__L2_MSG_FACTORY_BASE(Notification_Clans_UnblacklistUser);
__L2_MSG_FACTORY_BASE(Notification_Clans_Destroyed);
default:
return 0;
};
};
};
}; // namespace SLNet
#endif

View File

@ -0,0 +1,119 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Server_PGSQL.h"
#include "PostgreSQLInterface.h"
using namespace SLNet;
STATIC_FACTORY_DEFINITIONS(Lobby2Server_PGSQL,Lobby2Server_PGSQL);
Lobby2ServerCommand Lobby2ServerWorkerThread(Lobby2ServerCommand input, bool *returnOutput, void* perThreadData)
{
PostgreSQLInterface *postgreSQLInterface = (PostgreSQLInterface *) perThreadData;
input.returnToSender = input.lobby2Message->ServerDBImpl(&input, postgreSQLInterface);
*returnOutput=input.returnToSender;
if (input.deallocMsgWhenDone && input.returnToSender==false)
SLNet::OP_DELETE(input.lobby2Message, _FILE_AND_LINE_);
return input;
}
Lobby2Server_PGSQL::Lobby2Server_PGSQL()
{
}
Lobby2Server_PGSQL::~Lobby2Server_PGSQL()
{
Clear();
}
void Lobby2Server_PGSQL::AddInputFromThread(Lobby2Message *msg, unsigned int targetUserId, SLNet::RakString targetUserHandle)
{
Lobby2ServerCommand command;
command.lobby2Message=msg;
command.deallocMsgWhenDone=true;
command.returnToSender=true;
command.callerUserId=targetUserId;
command.callingUserName=targetUserHandle;
command.server=this;
AddInputCommand(command);
}
void Lobby2Server_PGSQL::AddInputCommand(Lobby2ServerCommand command)
{
threadPool.AddInput(Lobby2ServerWorkerThread, command);
}
void Lobby2Server_PGSQL::AddOutputFromThread(Lobby2Message *msg, unsigned int targetUserId, SLNet::RakString targetUserHandle)
{
Lobby2ServerCommand command;
command.lobby2Message=msg;
command.deallocMsgWhenDone=true;
command.returnToSender=true;
command.callerUserId=targetUserId;
command.callingUserName=targetUserHandle;
command.server=this;
msg->resultCode=L2RC_SUCCESS;
threadPool.AddOutput(command);
}
bool Lobby2Server_PGSQL::ConnectToDB(const char *conninfo, int numWorkerThreads)
{
if (numWorkerThreads<=0)
return false;
StopThreads();
int i;
PostgreSQLInterface *connection;
for (i=0; i < numWorkerThreads; i++)
{
connection = SLNet::OP_NEW<PostgreSQLInterface>( _FILE_AND_LINE_ );
if (connection->Connect(conninfo)==false)
{
SLNet::OP_DELETE(connection, _FILE_AND_LINE_);
ClearConnections();
return false;
}
connectionPoolMutex.Lock();
connectionPool.Insert(connection, _FILE_AND_LINE_ );
connectionPoolMutex.Unlock();
}
threadPool.SetThreadDataInterface(this,0);
threadPool.StartThreads(numWorkerThreads,0,0,0);
return true;
}
void* Lobby2Server_PGSQL::PerThreadFactory(void *context)
{
(void)context;
PostgreSQLInterface* p;
connectionPoolMutex.Lock();
p=connectionPool.Pop();
connectionPoolMutex.Unlock();
return p;
}
void Lobby2Server_PGSQL::PerThreadDestructor(void* factoryResult, void *context)
{
(void)context;
PostgreSQLInterface* p = (PostgreSQLInterface*)factoryResult;
SLNet::OP_DELETE(p, _FILE_AND_LINE_);
}
void Lobby2Server_PGSQL::ClearConnections(void)
{
unsigned int i;
connectionPoolMutex.Lock();
for (i=0; i < connectionPool.Size(); i++)
SLNet::OP_DELETE(connectionPool[i], _FILE_AND_LINE_);
connectionPool.Clear(false, _FILE_AND_LINE_);
connectionPoolMutex.Unlock();
}

View File

@ -0,0 +1,56 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_SERVER_PGSQL_H
#define __LOBBY_2_SERVER_PGSQL_H
#include "Lobby2Server.h"
class PostgreSQLInterface;
namespace SLNet
{
/// PostgreSQL specific functionality to the lobby server
class RAK_DLL_EXPORT Lobby2Server_PGSQL : public SLNet::Lobby2Server
{
public:
Lobby2Server_PGSQL();
virtual ~Lobby2Server_PGSQL();
STATIC_FACTORY_DECLARATIONS(Lobby2Server_PGSQL)
/// ConnectTo to the database \a numWorkerThreads times using the connection string
/// \param[in] conninfo See the postgre docs
/// \return True on success, false on failure.
virtual bool ConnectToDB(const char *conninfo, int numWorkerThreads);
/// Add input to the worker threads, from a thread already running
virtual void AddInputFromThread(Lobby2Message *msg, unsigned int targetUserId, SLNet::RakString targetUserHandle);
/// Add output from the worker threads, from a thread already running. This is in addition to the current message, so is used for notifications
virtual void AddOutputFromThread(Lobby2Message *msg, unsigned int targetUserId, SLNet::RakString targetUserHandle);
protected:
virtual void AddInputCommand(Lobby2ServerCommand command);
virtual void* PerThreadFactory(void *context);
virtual void PerThreadDestructor(void* factoryResult, void *context);
virtual void ClearConnections(void);
DataStructures::List<PostgreSQLInterface *> connectionPool;
};
}
#endif

View File

@ -0,0 +1,38 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "IntervalTimer.h"
void IntervalTimer::SetPeriod(SLNet::TimeMS period) {basePeriod=period; remaining=0;}
bool IntervalTimer::UpdateInterval(SLNet::TimeMS elapsed)
{
if (elapsed >= remaining)
{
SLNet::TimeMS difference = elapsed-remaining;
if (difference >= basePeriod)
{
remaining=basePeriod;
}
else
{
remaining=basePeriod-difference;
}
return true;
}
remaining-=elapsed;
return false;
}

View File

@ -0,0 +1,29 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __INTERVAL_TIMER_H
#define __INTERVAL_TIMER_H
#include "slikenet/types.h"
struct IntervalTimer
{
void SetPeriod(SLNet::TimeMS period);
bool UpdateInterval(SLNet::TimeMS elapsed);
SLNet::TimeMS basePeriod, remaining;
};
#endif

View File

@ -0,0 +1,164 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "ProfanityFilter.h"
#include "slikenet/Rand.h"
#include "slikenet/assert.h"
#include "slikenet/LinuxStrings.h"
#include "slikenet/linux_adapter.h"
#include "slikenet/osx_adapter.h"
#if defined(_WIN32)
#include <malloc.h> // alloca
#elif (defined(__GNUC__) || defined(__GCCXML__))
#include <alloca.h>
#else
#endif
using namespace SLNet;
char ProfanityFilter::BANCHARS[] = "!@#$%^&*()";
char ProfanityFilter::WORDCHARS[] = "abcdefghijklmnopqrstuvwxyz0123456789";
ProfanityFilter::ProfanityFilter()
{
}
ProfanityFilter::~ProfanityFilter()
{
}
char ProfanityFilter::RandomBanChar()
{
return BANCHARS[randomMT() % (sizeof(BANCHARS) - 1)];
}
bool ProfanityFilter::HasProfanity(const char *str)
{
return FilterProfanity(str, 0, 0,false) > 0;
}
int ProfanityFilter::FilterProfanity(const char *input, char *output, bool filter)
{
if (input == 0 || input[0] == 0)
return 0;
int count = 0;
char* b = (char *)alloca(strlen(input) + 1);
strcpy_s(b, strlen(input) + 1, input);
_strlwr(b);
char *start = b;
if (output)
strcpy(output, input);
start = strpbrk(start, WORDCHARS);
while (start != 0)
{
size_t len = strspn(start, WORDCHARS);
if (len > 0)
{
// we a have a word - let's check if it's a BAAAD one
char saveChar = start[len];
start[len] = '\0';
// loop through profanity list
for (unsigned int i = 0, size = words.Size(); i < size; i++)
{
if (_stricmp(start, words[i].C_String()) == 0)
{
count++;
// size_t len = words[i].size();
if (filter && output)
{
for (unsigned int j = 0; j < len; j++)
{
output[start + j - b] = RandomBanChar();
}
}
break;
}
}
start[len] = saveChar;
}
start += len;
start = strpbrk(start, WORDCHARS);
}
return count;
}
int ProfanityFilter::FilterProfanity(const char *input, char *output, size_t outputLength, bool filter)
{
if (input==0 || input[0]==0)
return 0;
int count = 0;
char* b = (char *) alloca(strlen(input) + 1);
strcpy_s(b, strlen(input) + 1, input);
_strlwr(b);
char *start = b;
if (output)
strcpy_s(output,outputLength,input);
start = strpbrk(start, WORDCHARS);
while (start != 0)
{
size_t len = strspn(start, WORDCHARS);
if (len > 0)
{
// we a have a word - let's check if it's a BAAAD one
char saveChar = start[len];
start[len] = '\0';
// loop through profanity list
for (unsigned int i = 0, size = words.Size(); i < size; i++)
{
if (_stricmp(start, words[i].C_String()) == 0)
{
count++;
// size_t len = words[i].size();
if (filter && output)
{
for (unsigned int j = 0; j < len; j++)
{
output[start + j - b] = RandomBanChar();
}
}
break;
}
}
start[len] = saveChar;
}
start += len;
start = strpbrk(start, WORDCHARS);
}
return count;
}
int ProfanityFilter::Count()
{
return words.Size();
}
void ProfanityFilter::AddWord(SLNet::RakString newWord)
{
words.Insert(newWord, _FILE_AND_LINE_ );
}

View File

@ -0,0 +1,52 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __PROFANITY_FILTER__H__
#define __PROFANITY_FILTER__H__
#include "slikenet/DS_List.h"
#include "slikenet/string.h"
namespace SLNet {
class ProfanityFilter
{
public:
ProfanityFilter();
~ProfanityFilter();
// Returns true if the string has profanity, false if not.
bool HasProfanity(const char *str);
// Removes profanity. Returns number of occurrences of profanity matches (including 0)
int FilterProfanity(const char *input, char *output, bool filter = true);
int FilterProfanity(const char *input, char *output, size_t outputLength, bool filter = true);
// Number of profanity words loaded
int Count();
void AddWord(SLNet::RakString newWord);
private:
DataStructures::List<SLNet::RakString> words;
char RandomBanChar();
static char BANCHARS[];
static char WORDCHARS[];
};
} // namespace SLNet
#endif // __PROFANITY__H__

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*/
#include "RoomTypes.h"
const char *RoomMemberModeToEnum(RoomMemberMode e)
{
switch (e)
{
case RMM_MODERATOR:
return "RMM_MODERATOR";
case RMM_PUBLIC:
return "RMM_PUBLIC";
case RMM_RESERVED:
return "RMM_RESERVED";
case RMM_SPECTATOR_PUBLIC:
return "RMM_SPECTATOR_PUBLIC";
case RMM_SPECTATOR_RESERVED:
return "RMM_SPECTATOR_RESERVED";
case RMM_ANY_PLAYABLE:
return "RMM_ANY_PLAYABLE";
case RMM_ANY_SPECTATOR:
return "RMM_ANY_SPECTATOR";
}
return "Error in RoomMemberModeToEnum";
}
static DefaultRoomColumns defaultRoomColumns[DefaultRoomColumns::TC_TABLE_COLUMNS_COUNT] =
{
{DefaultRoomColumns::TC_TITLE_NAME, "Title name", DataStructures::Table::STRING},
{DefaultRoomColumns::TC_TITLE_ID, "Title id", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_ROOM_NAME, "Room name", DataStructures::Table::STRING},
{DefaultRoomColumns::TC_ROOM_ID, "Room id", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_TOTAL_SLOTS, "Total slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_TOTAL_PUBLIC_PLUS_RESERVED_SLOTS, "Total Public plus reserved slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_USED_SLOTS, "Used slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_USED_PUBLIC_PLUS_RESERVED_SLOTS, "Used public plus reserved slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_REMAINING_SLOTS, "Remaining slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_REMAINING_PUBLIC_PLUS_RESERVED_SLOTS, "Remaining public plus reserved slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_TOTAL_PUBLIC_SLOTS, "Total public slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_TOTAL_RESERVED_SLOTS, "Total reserved slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_TOTAL_SPECTATOR_SLOTS, "Total spectator slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_USED_PUBLIC_SLOTS, "Used public slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_USED_RESERVED_SLOTS, "Used reserved slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_USED_SPECTATOR_SLOTS, "Used spectator slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_REMAINING_PUBLIC_SLOTS, "Remaining public slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_REMAINING_RESERVED_SLOTS, "Remaining reserved slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_REMAINING_SPECTATOR_SLOTS, "Remaining spectator slots", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_CREATION_TIME, "Creation time", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_DESTROY_ON_MODERATOR_LEAVE, "Destroy on moderator leave", DataStructures::Table::NUMERIC},
{DefaultRoomColumns::TC_LOBBY_ROOM_PTR, "Lobby room ptr [Internal]", DataStructures::Table::POINTER},
};
const char *DefaultRoomColumns::GetColumnName(int columnId) {return defaultRoomColumns[columnId].columnName;}
DataStructures::Table::ColumnType DefaultRoomColumns::GetColumnType(int columnId) {return defaultRoomColumns[columnId].columnType;}
bool DefaultRoomColumns::HasColumnName(const char *columnName)
{
unsigned i;
for (i=0; i < TC_TABLE_COLUMNS_COUNT; i++)
if (strcmp(columnName,GetColumnName(i))==0)
return true;
return false;
}
int DefaultRoomColumns::GetColumnIndex(const char *columnName)
{
unsigned i;
for (i=0; i < TC_TABLE_COLUMNS_COUNT; i++)
if (strcmp(columnName,GetColumnName(i))==0)
return i;
return -1;
}
void DefaultRoomColumns::AddDefaultColumnsToTable(DataStructures::Table *table)
{
unsigned i;
for (i=0; i < DefaultRoomColumns::TC_TABLE_COLUMNS_COUNT; i++)
table->AddColumn(DefaultRoomColumns::GetColumnName(i), DefaultRoomColumns::GetColumnType(i));
}
bool DefaultRoomColumns::HasDefaultColumns(DataStructures::Table *table)
{
unsigned i;
for (i=0; i < DefaultRoomColumns::TC_TABLE_COLUMNS_COUNT; i++)
{
if (table->ColumnIndex(DefaultRoomColumns::GetColumnName(i))!=-1)
return true;
}
return false;
}

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "slikenet/DS_Table.h"
#ifndef __ROOM_TYPES_H
#define __ROOM_TYPES_H
enum RoomMemberMode
{
/// The owner of the room, who is also a player in the room. The owner cannot be a spectator
RMM_MODERATOR,
/// The room member is a player in a public slot
RMM_PUBLIC,
/// The room member is a player in a reserved slot
RMM_RESERVED,
/// The room member is a spectator in a public slot.
RMM_SPECTATOR_PUBLIC,
/// The room member is a spectator in a reserved slot.
RMM_SPECTATOR_RESERVED,
/// Used as a query flag - join any slot that is playable (reserved or public)
RMM_ANY_PLAYABLE,
/// Used as a query flag - join any slot that is for a spectator (reserved or public)
RMM_ANY_SPECTATOR,
};
const char *RoomMemberModeToEnum(RoomMemberMode e);
struct DefaultRoomColumns
{
enum
{
TC_TITLE_NAME,
TC_TITLE_ID,
TC_ROOM_NAME,
TC_ROOM_ID,
TC_TOTAL_SLOTS,
TC_TOTAL_PUBLIC_PLUS_RESERVED_SLOTS,
TC_USED_SLOTS,
TC_USED_PUBLIC_PLUS_RESERVED_SLOTS,
TC_REMAINING_SLOTS,
TC_REMAINING_PUBLIC_PLUS_RESERVED_SLOTS,
TC_TOTAL_PUBLIC_SLOTS,
TC_TOTAL_RESERVED_SLOTS,
TC_TOTAL_SPECTATOR_SLOTS,
TC_USED_PUBLIC_SLOTS,
TC_USED_RESERVED_SLOTS,
TC_USED_SPECTATOR_SLOTS,
TC_REMAINING_PUBLIC_SLOTS,
TC_REMAINING_RESERVED_SLOTS,
TC_REMAINING_SPECTATOR_SLOTS,
TC_CREATION_TIME,
TC_DESTROY_ON_MODERATOR_LEAVE,
TC_LOBBY_ROOM_PTR,
TC_TABLE_COLUMNS_COUNT
} columnId;
const char *columnName;
DataStructures::Table::ColumnType columnType;
static const char *GetColumnName(int columnId);
static int GetColumnIndex(const char *columnName);
static DataStructures::Table::ColumnType GetColumnType(int columnId);
static bool HasColumnName(const char *columnName);
static void AddDefaultColumnsToTable(DataStructures::Table *table);
static bool HasDefaultColumns(DataStructures::Table *table);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,635 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_ROOM_H
#define __LOBBY_ROOM_H
#include "slikenet/DS_Map.h"
#include "slikenet/DS_Table.h"
#include "RoomsErrorCodes.h"
#include "slikenet/DS_List.h"
#include "slikenet/types.h"
#include "IntervalTimer.h"
#include "RoomTypes.h"
namespace SLNet
{
class ProfanityFilter;
class Room;
class PerGameRoomList;
class PerGameRoomsContainer;
class BitStream;
typedef unsigned int RoomID;
struct QuickJoinUser;
struct RoomMember;
class AllGamesRoomsContainer;
class RoomsParticipant
{
public:
RoomsParticipant() {room=0; inQuickJoin=false;}
~RoomsParticipant() {}
Room * GetRoom(void) const {return room;}
void SetPerGameRoomsContainer(PerGameRoomsContainer *p) {perGameRoomsContainer=p;}
void SetRoom(Room *_room) {room=_room; inQuickJoin=false;}
void SetInQuickJoin(bool b) {inQuickJoin=b; if (b) room=0;}
// Name is used for persistent invites and bans. Name should be unique among all participants or else the invites and bans will be applied to the wrong players
SLNet::RakString GetName(void) const {return name;}
void SetName(const char *str) {name = str;}
void SetSystemAddress(const SystemAddress &sa) {systemAddress=sa;}
SystemAddress GetSystemAddress(void) const {return systemAddress;}
void SetGUID(RakNetGUID g) {guid=g;}
RakNetGUID GetGUID(void) const {return guid;}
PerGameRoomsContainer *GetPerGameRoomsContainer(void) const {return perGameRoomsContainer;}
bool GetInQuickJoin(void) const {return inQuickJoin;}
protected:
SLNet::RakString name;
SystemAddress systemAddress;
RakNetGUID guid;
Room *room;
bool inQuickJoin;
PerGameRoomsContainer *perGameRoomsContainer;
};
typedef SLNet::RakString GameIdentifier;
enum RoomLockState
{
// Anyone can join or leave
RLS_NOT_LOCKED,
// Anyone can join as spectator or become spectator. New players are not allowed. You cannot leave spectator.
RLS_PLAYERS_LOCKED,
// No new players are allowed, and you cannot toggle spectator
RLS_ALL_LOCKED
};
enum ParticipantCanJoinRoomResult
{
PCJRR_SUCCESS,
PCJRR_BANNED,
PCJRR_NO_PUBLIC_SLOTS,
PCJRR_NO_PUBLIC_OR_RESERVED_SLOTS,
PCJRR_NO_SPECTATOR_SLOTS,
PCJRR_LOCKED,
PCJRR_SLOT_ALREADY_USED,
};
struct Slots
{
Slots();
~Slots();
unsigned int publicSlots;
unsigned int reservedSlots;
unsigned int spectatorSlots;
unsigned int GetTotalSlots(void) const {return publicSlots+reservedSlots+spectatorSlots;}
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
RoomsErrorCode Validate(void) const;
};
struct InvitedUser
{
InvitedUser() {room=0; roomId=0; invitedAsSpectator=false;}
Room *room;
RoomID roomId;
SLNet::RakString invitorName;
SystemAddress invitorSystemAddress;
SLNet::RakString target;
SLNet::RakString subject;
SLNet::RakString body;
bool invitedAsSpectator;
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
};
struct BannedUser
{
SLNet::RakString target;
SLNet::RakString reason;
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
};
struct RemoveUserResult
{
RemoveUserResult();
~RemoveUserResult();
// Why return a deleted pointer?
// RoomsParticipant *removedUser;
bool removedFromQuickJoin;
bool removedFromRoom;
SystemAddress removedUserAddress;
SLNet::RakString removedUserName;
// Following members only apply if removedFromRoom==true
Room *room;
RoomID roomId;
bool gotNewModerator; // If you were the moderator before, this is true
DataStructures::List<InvitedUser> clearedInvitations; // If invitations were cleared when you leave, these are the invitations
bool roomDestroyed; // Up to caller to deallocate
QuickJoinUser *qju;
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
};
struct RoomMemberDescriptor
{
SLNet::RakString name;
RoomMemberMode roomMemberMode;
bool isReady;
// Filled externally
SystemAddress systemAddress;
RakNetGUID guid;
void FromRoomMember(RoomMember *roomMember);
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
};
struct NetworkedRoomCreationParameters
{
NetworkedRoomCreationParameters() {hiddenFromSearches=false; destroyOnModeratorLeave=false; autoLockReadyStatus=false; inviteToRoomPermission=INVITE_MODE_ANYONE_CAN_INVITE; inviteToSpectatorSlotPermission=INVITE_MODE_ANYONE_CAN_INVITE; clearInvitesOnNewModerator=false;}
// Checked by Validate
Slots slots;
bool hiddenFromSearches;
bool destroyOnModeratorLeave;
bool autoLockReadyStatus; // When everyone is ready and (the room is full or the room is locked), don't allow users to set unready.
enum SendInvitePermission
{
INVITE_MODE_ANYONE_CAN_INVITE,
INVITE_MODE_MODERATOR_CAN_INVITE,
INVITE_MODE_PUBLIC_SLOTS_CAN_INVITE,
INVITE_MODE_RESERVED_SLOTS_CAN_INVITE,
INVITE_MODE_SPECTATOR_SLOTS_CAN_INVITE,
INVITE_MODE_MODERATOR_OR_PUBLIC_SLOTS_CAN_INVITE,
INVITE_MODE_MODERATOR_OR_PUBLIC_OR_RESERVED_SLOTS_CAN_INVITE,
} inviteToRoomPermission, inviteToSpectatorSlotPermission;
bool clearInvitesOnNewModerator; // Leave or change
SLNet::RakString roomName;
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
static const char *SendInvitePermissionToEnum(SendInvitePermission e);
};
struct RoomDescriptor
{
DataStructures::List<RoomMemberDescriptor> roomMemberList;
DataStructures::List<BannedUser> banList;
RoomLockState roomLockState;
RoomID lobbyRoomId;
bool autoLockReadyStatus;
bool hiddenFromSearches;
NetworkedRoomCreationParameters::SendInvitePermission inviteToRoomPermission;
NetworkedRoomCreationParameters::SendInvitePermission inviteToSpectatorSlotPermission;
DataStructures::Table roomProperties;
DataStructures::Table::Cell *GetProperty(const char* columnName)
{
return roomProperties.GetRowByIndex(0,0)->cells[roomProperties.ColumnIndex(columnName)];
}
DataStructures::Table::Cell *GetProperty(int index)
{
return roomProperties.GetRowByIndex(0,0)->cells[index];
}
void Clear(void)
{
roomMemberList.Clear(false, _FILE_AND_LINE_);
banList.Clear(false, _FILE_AND_LINE_);
roomProperties.Clear();
}
void FromRoom(Room *room, AllGamesRoomsContainer *agrc);
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
};
struct JoinedRoomResult
{
JoinedRoomResult() {roomOutput=0; acceptedInvitor=0; agrc=0; joiningMember=0;}
~JoinedRoomResult() {}
Room* roomOutput;
RoomDescriptor roomDescriptor;
RoomsParticipant* acceptedInvitor;
SLNet::RakString acceptedInvitorName;
SystemAddress acceptedInvitorAddress;
RoomsParticipant* joiningMember;
SLNet::RakString joiningMemberName;
SystemAddress joiningMemberAddress;
RakNetGUID joiningMemberGuid;
// Needed to serialize
AllGamesRoomsContainer *agrc;
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream );
};
struct RoomCreationParameters
{
RoomCreationParameters();
~RoomCreationParameters();
NetworkedRoomCreationParameters networkedRoomCreationParameters;
// Not checked
RoomsParticipant* firstUser;
GameIdentifier gameIdentifier;
// Output parameters:
// Was the room created?
bool createdRoom;
Room *roomOutput;
// May return REC_ROOM_CREATION_PARAMETERS_* or REC_SUCCESS
RoomsErrorCode Validate(
const DataStructures::List<SLNet::RakString> &otherRoomNames,
ProfanityFilter *profanityFilter) const;
};
struct RoomMember
{
RoomMember();
~RoomMember();
RoomsParticipant* roomsParticipant;
RoomMemberMode roomMemberMode;
SLNet::TimeMS joinTime;
bool isReady;
// Internal - set to false when a new member is added. When the other members have been told about this member, it is set to true
bool newMemberNotificationProcessed;
};
struct KickedUser
{
RoomsParticipant* roomsParticipant;
SLNet::RakString reason;
};
struct RoomQuery
{
RoomQuery();
~RoomQuery();
// Point to an externally allocated array of FilterQuery, or use the helper functions below to use a static array (not threadsafe to use the static array)
DataStructures::Table::FilterQuery *queries;
// Size of the queries array
unsigned int numQueries;
// Not used
bool queriesAllocated;
// Helper functions
// Easier to use, but not threadsafe
void AddQuery_NUMERIC(const char *columnName, double numericValue, DataStructures::Table::FilterQueryType op=DataStructures::Table::QF_EQUAL);
void AddQuery_STRING(const char *columnName, const char *charValue, DataStructures::Table::FilterQueryType op=DataStructures::Table::QF_EQUAL);
void AddQuery_BINARY(const char *columnName, const char *input, int inputLength, DataStructures::Table::FilterQueryType op=DataStructures::Table::QF_EQUAL);
void AddQuery_POINTER(const char *columnName, void *ptr, DataStructures::Table::FilterQueryType op=DataStructures::Table::QF_EQUAL);
RoomsErrorCode Validate(void);
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
/// \internal
void SetQueriesToStatic(void);
private:
static DataStructures::Table::FilterQuery fq[32];
static DataStructures::Table::Cell cells[32];
void SetupNextQuery(const char *columnName,DataStructures::Table::FilterQueryType op);
};
struct NetworkedQuickJoinUser
{
NetworkedQuickJoinUser() {timeout=60000; minimumPlayers=2;}
// How long to wait for
SLNet::TimeMS timeout;
// What queries to join the room on.
RoomQuery query;
// Minimum number of slots to join
int minimumPlayers;
void Serialize(bool writeToBitstream, SLNet::BitStream *bitStream);
};
struct QuickJoinUser
{
QuickJoinUser();
~QuickJoinUser();
NetworkedQuickJoinUser networkedQuickJoinUser;
// Total amount of time spent waiting
SLNet::TimeMS totalTimeWaiting;
// Which user
RoomsParticipant* roomsParticipant;
static int SortByTotalTimeWaiting( QuickJoinUser* const &key, QuickJoinUser* const &data );
static int SortByMinimumSlots( QuickJoinUser* const &key, QuickJoinUser* const &data );
};
int RoomPriorityComp( Room * const &key, Room * const &data );
// PerGameRoomsContainer, mapped by game id
class AllGamesRoomsContainer
{
public:
AllGamesRoomsContainer();
~AllGamesRoomsContainer();
static void UnitTest(void);
RoomsErrorCode CreateRoom(RoomCreationParameters *roomCreationParameters,
ProfanityFilter *profanityFilter);
// Enters a room based on the search queries. If no rooms are available to join, will create a room instead
RoomsErrorCode EnterRoom(RoomCreationParameters *roomCreationParameters,
RoomMemberMode roomMemberMode,
ProfanityFilter *profanityFilter,
RoomQuery *query,
JoinedRoomResult *joinRoomResult);
// Attempts to join a room by search query filters
// Returns REC_JOIN_BY_FILTER_*
RoomsErrorCode JoinByFilter(GameIdentifier gameIdentifier, RoomMemberMode roomMemberMode, RoomsParticipant* roomsParticipant, RoomID lastRoomJoined, RoomQuery *query, JoinedRoomResult *joinRoomResult);
// Add a new title to host games with
RoomsErrorCode AddTitle(GameIdentifier gameIdentifier);
// Get all pending invites to you
RoomsErrorCode GetInvitesToParticipant(RoomsParticipant* roomsParticipant, DataStructures::List<InvitedUser*> &invites);
RoomsErrorCode RemoveUser(RoomsParticipant* roomsParticipant, RemoveUserResult *removeMemberResult);
// ROOMS OPERATIONS, implicit room
RoomsErrorCode SendInvite(RoomsParticipant* roomsParticipant, RoomsParticipant* inviteeId, bool inviteToSpectatorSlot, SLNet::RakString subject, SLNet::RakString body);
RoomsErrorCode AcceptInvite(RoomID roomId, Room **room, RoomsParticipant* roomsParticipant, SLNet::RakString inviteSender);
RoomsErrorCode StartSpectating(RoomsParticipant* roomsParticipant);
RoomsErrorCode StopSpectating(RoomsParticipant* roomsParticipant);
RoomsErrorCode GrantModerator(RoomsParticipant* roomsParticipant, RoomsParticipant *newModerator, DataStructures::List<InvitedUser> &clearedInvites);
RoomsErrorCode ChangeSlotCounts(RoomsParticipant* roomsParticipant, Slots slots);
RoomsErrorCode SetCustomRoomProperties(RoomsParticipant* roomsParticipant, DataStructures::Table *table);
RoomsErrorCode ChangeRoomName(RoomsParticipant* roomsParticipant, SLNet::RakString newRoomName, ProfanityFilter *profanityFilter);
RoomsErrorCode SetHiddenFromSearches(RoomsParticipant* roomsParticipant, bool _hiddenFromSearches);
RoomsErrorCode SetDestroyOnModeratorLeave(RoomsParticipant* roomsParticipant, bool destroyOnModeratorLeave);
RoomsErrorCode SetReadyStatus(RoomsParticipant* roomsParticipant, bool isReady);
RoomsErrorCode GetReadyStatus( RoomID roomId, Room **room, DataStructures::List<RoomsParticipant*> &readyUsers, DataStructures::List<RoomsParticipant*> &unreadyUsers);
RoomsErrorCode SetRoomLockState(RoomsParticipant* roomsParticipant, RoomLockState _roomLockState);
RoomsErrorCode GetRoomLockState(RoomID roomId, Room **room, RoomLockState *roomLockState);
RoomsErrorCode AreAllMembersReady(RoomID roomId, Room **room, bool *allReady);
RoomsErrorCode KickMember(RoomsParticipant* roomsParticipant, RoomsParticipant *kickedParticipant, SLNet::RakString reason);
RoomsErrorCode UnbanMember(RoomsParticipant* roomsParticipant, SLNet::RakString name);
RoomsErrorCode GetBanReason( RoomID lobbyRoomId, Room **room, SLNet::RakString name, SLNet::RakString *reason);
RoomsErrorCode LeaveRoom(RoomsParticipant* roomsParticipant, RemoveUserResult *removeUserResult);
//RoomsErrorCode GetKickReason(RoomsParticipant* roomsParticipant, SLNet::RakString *kickReason);
void GetRoomProperties(RoomID roomId, Room **room, DataStructures::Table *table);
// Quick join algorithm:
//
// -- ROOM JOIN --
//
// For all rooms:
// 1. Clear all quickJoinWorkingList from all rooms
// For all quick join members
// 2. Use RoomPrioritySort to get all rooms they can potentially join
// 3. For each of these rooms, record that this member can potentially join by storing a copy of the pointer into quickJoinWorkingList, if minimumPlayers => total room slots
// For all rooms:
// 4. For each room where there are enough potential quick join members to fill the room, join all those members at once. Remove these members from the quick join list. Go to 1.
//
// -- ROOM CREATE --
//
// 5. Sort quick join members by minimumPlayers, excluding members where minimumPlayers > total number of quick join members
// From greatest minimumPlayers to least
// 6. If the current member created a room, find out how many subsequent members would join based on the custom filter
// 7. If this satisfies minimumPlayers, have that user create a room and those subsequent members join.
//
// -- EXPIRE
//
// 5. Remove from list if timeout has expired.
// 6. Return results of operation (List<timeoutExpired>, List<joinedARoom>, List<RoomsThatWereJoined>
//
// Returns false if processing skipped due to optimization timer
RoomsErrorCode ProcessQuickJoins(
DataStructures::List<QuickJoinUser*> &timeoutExpired,
DataStructures::List<JoinedRoomResult> &joinedRoomMembers,
DataStructures::List<QuickJoinUser*> &dereferencedPointers,
SLNet::TimeMS elapsedTime);
// Quick join - Store a list of all members waiting to quick join.
// Quick join ends when
// 1. An existing room can be fully populated using waiting quick join members.
// 2. Enough quick join members are waiting that a new room can be created with the number of members >= minimumPlayers for all members
// It also ends if timeToWaitMS expires.
// Returns REC_ADD_TO_QUICK_JOIN_*
// Passed pointer is stored on REC_SUCCESS, allocate, and do not deallocate unless not successful
RoomsErrorCode AddUserToQuickJoin(GameIdentifier gameIdentifier, QuickJoinUser *quickJoinMember);
// Returns REC_REMOVE_FROM_QUICK_JOIN_*
RoomsErrorCode RemoveUserFromQuickJoin(RoomsParticipant* roomsParticipant, QuickJoinUser **qju);
// Is this user in quick join?
bool IsInQuickJoin(RoomsParticipant* roomsParticipant);
// Get all rooms for a certain title
static int RoomsSortByName( Room* const &key, Room* const &data );
RoomsErrorCode SearchByFilter( GameIdentifier gameIdentifier, RoomsParticipant* roomsParticipant, RoomQuery *roomQuery, DataStructures::OrderedList<Room*, Room*, RoomsSortByName> &roomsOutput, bool onlyJoinable );
// Deallocate a room
void DestroyRoomIfDead(Room *room);
// If a handle changes, you have to tell the system here. Otherwise ban and invite names will be out of synch
// System does not verify that the handle is not currently in use since it does not necessarily know about all online players
// This is an invariant up to the caller to uphold. Failure to do so will result in the wrong players being banned or invited
void ChangeHandle(SLNet::RakString oldHandle, SLNet::RakString newHandle);
unsigned int GetPropertyIndex(RoomID lobbyRoomId, const char *propertyName) const;
DataStructures::Map<GameIdentifier, PerGameRoomsContainer*> perGamesRoomsContainers;
Room * GetRoomByLobbyRoomID(RoomID lobbyRoomID);
Room * GetRoomByName(SLNet::RakString roomName);
protected:
RoomID nextRoomId;
};
class PerGameRoomsContainer
{
public:
PerGameRoomsContainer();
~PerGameRoomsContainer();
// Has pointer column to class Room
DataStructures::Table roomsTable;
// Members that are waiting to quick join
DataStructures::List<QuickJoinUser*> quickJoinList;
static int RoomsSortByTimeThenTotalSlots( Room* const &key, Room* const &data );
protected:
RoomsErrorCode CreateRoom(RoomCreationParameters *roomCreationParameters,
ProfanityFilter *profanityFilter,
RoomID lobbyRoomId,
bool validate);
RoomsErrorCode LeaveRoom(RoomsParticipant* roomsParticipant, bool *gotNewModerator);
RoomsErrorCode JoinByFilter(RoomMemberMode roomMemberMode, RoomsParticipant* roomsParticipant, RoomID lastRoomJoined, RoomQuery *query, JoinedRoomResult *joinRoomResult);
RoomsErrorCode AddUserToQuickJoin(QuickJoinUser *quickJoinMember);
RoomsErrorCode RemoveUserFromQuickJoin(RoomsParticipant* roomsParticipant, QuickJoinUser **qju);
bool IsInQuickJoin(RoomsParticipant* roomsParticipant);
unsigned int GetQuickJoinIndex(RoomsParticipant* roomsParticipant);
void GetRoomNames(DataStructures::List<SLNet::RakString> &roomNames);
void GetAllRooms(DataStructures::List<Room*> &rooms);
// Looks for a particular room that has a particular ID
Room * GetRoomByLobbyRoomID(RoomID lobbyRoomID);
Room * GetRoomByName(SLNet::RakString roomName);
RoomsErrorCode GetInvitesToParticipant(RoomsParticipant* roomsParticipant, DataStructures::List<InvitedUser*> &invites);
bool DestroyRoomIfDead(Room *room);
void ChangeHandle(SLNet::RakString oldHandle, SLNet::RakString newHandle);
unsigned ProcessQuickJoins( DataStructures::List<QuickJoinUser*> &timeoutExpired,
DataStructures::List<JoinedRoomResult> &joinedRooms,
DataStructures::List<QuickJoinUser*> &dereferencedPointers,
SLNet::TimeMS elapsedTime,
RoomID startingRoomId);
// Sort an input list of rooms
// Rooms are sorted by time created (longest is higher priority). If within one minute, then subsorted by total playable slot count (lower is higher priority).
// When using EnterRoom or JoinByFilter, record the last roomOutput joined, and try to avoid rejoining the same roomOutput just left
void RoomPrioritySort( RoomsParticipant* roomsParticipant, RoomQuery *roomQuery, DataStructures::OrderedList<Room*, Room*, RoomsSortByTimeThenTotalSlots> &roomsOutput );
RoomsErrorCode SearchByFilter( RoomsParticipant* roomsParticipant, RoomQuery *roomQuery, DataStructures::OrderedList<Room*, Room*, AllGamesRoomsContainer::RoomsSortByName> &roomsOutput, bool onlyJoinable );
friend class AllGamesRoomsContainer;
IntervalTimer nextQuickJoinProcess;
};
// Holds all the members of a particular roomOutput
class Room
{
public:
Room( RoomID _roomId, RoomCreationParameters *roomCreationParameters, DataStructures::Table::Row *_row, RoomsParticipant* roomsParticipant );
~Room();
RoomsErrorCode SendInvite(RoomsParticipant* roomsParticipant, RoomsParticipant* inviteeId, bool inviteToSpectatorSlot, SLNet::RakString subject, SLNet::RakString body);
RoomsErrorCode AcceptInvite(RoomsParticipant* roomsParticipant, SLNet::RakString inviteSender);
RoomsErrorCode StartSpectating(RoomsParticipant* roomsParticipant);
RoomsErrorCode StopSpectating(RoomsParticipant* roomsParticipant);
RoomsErrorCode GrantModerator(RoomsParticipant* roomsParticipant, RoomsParticipant *newModerator, DataStructures::List<InvitedUser> &clearedInvites);
RoomsErrorCode ChangeSlotCounts(RoomsParticipant* roomsParticipant, Slots slots);
RoomsErrorCode SetCustomRoomProperties(RoomsParticipant* roomsParticipant, DataStructures::Table *table);
RoomsErrorCode ChangeRoomName(RoomsParticipant* roomsParticipant, SLNet::RakString newRoomName, ProfanityFilter *profanityFilter);
RoomsErrorCode SetHiddenFromSearches(RoomsParticipant* roomsParticipant, bool _hiddenFromSearches);
RoomsErrorCode SetDestroyOnModeratorLeave(RoomsParticipant* roomsParticipant, bool destroyOnModeratorLeave);
RoomsErrorCode SetReadyStatus(RoomsParticipant* roomsParticipant, bool isReady);
RoomsErrorCode GetReadyStatus(DataStructures::List<RoomsParticipant*> &readyUsers, DataStructures::List<RoomsParticipant*> &unreadyUsers);
RoomsErrorCode SetRoomLockState(RoomsParticipant* roomsParticipant, RoomLockState _roomLockState);
RoomsErrorCode GetRoomLockState(RoomLockState *_roomLockState);
RoomsErrorCode AreAllMembersReady(unsigned int exceptThisIndex, bool *allReady);
RoomsErrorCode KickMember(RoomsParticipant* roomsParticipant, RoomsParticipant *kickedParticipant, SLNet::RakString reason);
RoomsErrorCode UnbanMember(RoomsParticipant* roomsParticipant, SLNet::RakString name);
RoomsErrorCode GetBanReason(SLNet::RakString name, SLNet::RakString *reason);
RoomsErrorCode LeaveRoom(RoomsParticipant* roomsParticipant, RemoveUserResult *removeUserResult);
//RoomsErrorCode GetKickReason(RoomsParticipant* roomsParticipant, SLNet::RakString *kickReason);
RoomsErrorCode JoinByFilter(RoomsParticipant* roomsParticipant, RoomMemberMode roomMemberMode, JoinedRoomResult *joinRoomResult);
RoomsErrorCode JoinByQuickJoin(RoomsParticipant* roomsParticipant, RoomMemberMode roomMemberMode, JoinedRoomResult *joinRoomResult);
bool IsHiddenToParticipant(RoomsParticipant* roomsParticipant) const;
// Can this user join this roomOutput?
ParticipantCanJoinRoomResult ParticipantCanJoinAsPlayer( RoomsParticipant* roomsParticipant, bool asSpectator, bool checkHasInvite );
ParticipantCanJoinRoomResult ParticipantCanJoinRoom( RoomsParticipant* roomsParticipant, bool asSpectator, bool checkHasInvite );
// Returns true if there are only spectators, or nobody at all
bool IsRoomDead(void) const;
RoomsErrorCode GetInvitesToParticipant(RoomsParticipant* roomsParticipant, DataStructures::List<InvitedUser*> &invites);
RoomsParticipant* GetModerator(void) const;
// Gets the roomOutput ID
RoomID GetID(void) const;
double GetNumericProperty(RoomID lobbyRoomId, const char *propertyName) const;
const char *GetStringProperty(RoomID lobbyRoomId, const char *propertyName) const;
double GetNumericProperty(int index) const;
const char *GetStringProperty(int index) const;
void SetNumericProperty(int index, double value);
void SetStringProperty(int index, const char *value);
// Public for easy access
DataStructures::List<RoomMember*> roomMemberList;
DataStructures::List<InvitedUser> inviteList;
DataStructures::List<BannedUser> banList;
// Don't store - slow because when removing users I have to iterate through every room
// DataStructures::List<KickedUser> kickedList;
// Internal
DataStructures::List<QuickJoinUser*> quickJoinWorkingList;
static void UpdateRowSlots( DataStructures::Table::Row* row, Slots *totalSlots, Slots *usedSlots);
void ChangeHandle(SLNet::RakString oldHandle, SLNet::RakString newHandle);
protected:
Room();
// Updates the table row
RoomsErrorCode RemoveUser(RoomsParticipant* roomsParticipant,RemoveUserResult *removeUserResult);
bool IsRoomLockedToSpectators(void) const;
bool IsRoomLockedToPlayers(void) const;
bool IsInRoom(RoomsParticipant* roomsParticipant) const;
bool HasInvite(SLNet::RakString roomsParticipant);
unsigned int GetRoomIndex(RoomsParticipant* roomsParticipant) const;
unsigned int GetBannedIndex(SLNet::RakString username) const;
unsigned int GetInviteIndex(SLNet::RakString invitee, SLNet::RakString invitor) const;
unsigned int GetFirstInviteIndex(SLNet::RakString invitee) const;
bool AreAllPlayableSlotsFilled(void) const;
bool HasOpenPublicSlots(void) const;
bool HasOpenReservedSlots(void) const;
bool HasOpenSpectatorSlots(void) const;
void UpdateUsedSlots( void );
void UpdateUsedSlots( Slots *totalSlots, Slots *usedSlots );
static void UpdateUsedSlots( DataStructures::Table::Row* tableRow, Slots *totalSlots, Slots *usedSlots );
Slots GetTotalSlots(void) const;
void SetTotalSlots(Slots *totalSlots);
Slots GetUsedSlots(void) const;
RoomLockState roomLockState;
friend struct RoomDescriptor;
friend class PerGameRoomsContainer;
friend class AllGamesRoomsContainer;
RoomID lobbyRoomId;
DataStructures::Table::Row *tableRow;
bool autoLockReadyStatus;
bool hiddenFromSearches;
// bool destroyOnModeratorLeave;
bool clearInvitesOnNewModerator;
NetworkedRoomCreationParameters::SendInvitePermission inviteToRoomPermission, inviteToSpectatorSlotPermission;
bool roomDestroyed;
};
} // namespace Lobby2
#endif

View File

@ -0,0 +1,194 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017-2019, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "RoomsErrorCodes.h"
#include "slikenet/assert.h"
using namespace SLNet;
static RoomsErrorCodeDescription errorCodeDescriptions[ROOMS_ERROR_CODES_COUNT] =
{
{REC_SUCCESS, "REC_SUCCESS", "Success."},
{REC_USERNAME_IS_EMPTY, "REC_USERNAME_IS_EMPTY", "Username is empty."},
{REC_NOT_LOGGED_IN, "REC_NOT_LOGGED_IN", "Not logged in."},
{REC_ADD_TO_ROOM_NO_RESERVED_OR_PUBLIC, "REC_ADD_TO_ROOM_NO_RESERVED_OR_PUBLIC", "Failed to enter the room. Room has no reserved or public slots available to join."},
{REC_ADD_TO_ROOM_NO_PUBLIC, "REC_ADD_TO_ROOM_NO_PUBLIC", "Failed to enter the room. Room has no public slots available to join."},
{REC_ADD_TO_ROOM_NO_SPECTATOR, "REC_ADD_TO_ROOM_NO_SPECTATOR", "Failed to enter the room. Room has no spectator slots available to join."},
{REC_ADD_TO_ROOM_ALREADY_IN_THIS_ROOM, "REC_ADD_TO_ROOM_ALREADY_IN_THIS_ROOM", "Failed to enter the room. You are already in this room."},
{REC_ADD_TO_ROOM_ALREADY_IN_ANOTHER_ROOM, "REC_ADD_TO_ROOM_ALREADY_IN_ANOTHER_ROOM", "Failed to enter the room. You are already in a different room. Leave your existing room first."},
{REC_ADD_TO_ROOM_KICKED_OUT_OF_ROOM, "REC_ADD_TO_ROOM_KICKED_OUT_OF_ROOM", "Failed to enter the room. You have been banned from this room."},
{REC_CHANGE_MEMBER_TYPE_NO_SLOTS, "REC_CHANGE_MEMBER_TYPE_NO_SLOTS", "The room does not have free slots of the desired type."},
{REC_SEARCH_BY_FILTER_UNKNOWN_TITLE, "REC_SEARCH_BY_FILTER_UNKNOWN_TITLE", "Unknown title (Programmer error)."},
{REC_JOIN_BY_FILTER_UNKNOWN_TITLE, "REC_JOIN_BY_FILTER_UNKNOWN_TITLE", "Room join failed. Unknown title (Programmer error)."},
{REC_JOIN_BY_FILTER_NO_ROOMS, "REC_JOIN_BY_FILTER_NO_ROOMS", "Room join failed. There are no rooms, or no rooms that meet your search requirements."},
{REC_JOIN_BY_FILTER_CURRENTLY_IN_A_ROOM, "REC_JOIN_BY_FILTER_CURRENTLY_IN_A_ROOM", "Room join failed. You are already in a room."},
{REC_JOIN_BY_FILTER_CURRENTLY_IN_QUICK_JOIN, "REC_JOIN_BY_FILTER_CURRENTLY_IN_QUICK_JOIN", "Room join failed. You are currently in quick join. Leave quick join first."},
{REC_JOIN_BY_FILTER_CANNOT_JOIN_AS_MODERATOR, "REC_JOIN_BY_FILTER_CANNOT_JOIN_AS_MODERATOR", "Room join failed. You cannot join an existing room as a moderator. Create a new room instead."},
{REC_JOIN_BY_FILTER_ROOM_LOCKED, "REC_JOIN_BY_FILTER_ROOM_LOCKED", "Room join failed. The room is locked to new players."},
{REC_JOIN_BY_FILTER_BANNED, "REC_JOIN_BY_FILTER_BANNED", "Room join failed. You are banned from this room."},
{REC_JOIN_BY_FILTER_NO_SLOTS, "REC_JOIN_BY_FILTER_NO_SLOTS", "Room join failed. The room is full."},
{REC_JOIN_BY_QUICK_JOIN_CANNOT_JOIN_AS_MODERATOR, "REC_JOIN_BY_QUICK_JOIN_CANNOT_JOIN_AS_MODERATOR", "Quick join failed. You cannot join an existing room as a moderator. Create a new room instead."},
{REC_JOIN_BY_QUICK_JOIN_ROOM_LOCKED, "REC_JOIN_BY_QUICK_JOIN_ROOM_LOCKED", "Quick join failed. All rooms are locked to new players."},
{REC_JOIN_BY_QUICK_JOIN_BANNED, "REC_JOIN_BY_QUICK_JOIN_BANNED", "Quick join failed. You are banned from the only available rooms."},
{REC_JOIN_BY_QUICK_JOIN_NO_SLOTS, "REC_JOIN_BY_QUICK_JOIN_NO_SLOTS", "Quick join failed. All rooms are full."},
{REC_ADD_TO_QUICK_JOIN_CURRENTLY_IN_A_ROOM, "REC_ADD_TO_QUICK_JOIN_CURRENTLY_IN_A_ROOM", "Failed to quick join. You are currently in a room. Leave your existing room first."},
{REC_ADD_TO_QUICK_JOIN_UNKNOWN_TITLE, "REC_ADD_TO_QUICK_JOIN_UNKNOWN_TITLE", "Failed to quick join. Unknown title (Programmer error)."},
{REC_ADD_TO_QUICK_JOIN_ALREADY_THERE, "REC_ADD_TO_QUICK_JOIN_ALREADY_THERE", "Quick join is already in progress."},
{REC_ADD_TO_QUICK_JOIN_INVALID_TIMEOUT_TOO_LOW, "REC_ADD_TO_QUICK_JOIN_INVALID_TIMEOUT_TOO_LOW", "Failed to quick join. Tiebout is below the minimum threshold."},
{REC_ADD_TO_QUICK_JOIN_INVALID_TIMEOUT_TOO_HIGH, "REC_ADD_TO_QUICK_JOIN_INVALID_TIMEOUT_TOO_HIGH", "Failed to quick join. Timeout is above the minimum threshold."},
{REC_ADD_TO_QUICK_JOIN_MINIMUM_SLOTS_TOO_LOW, "REC_ADD_TO_QUICK_JOIN_MINIMUM_SLOTS_TOO_LOW", "Failed to quick join. Must have at least one slot for other players."},
{REC_ADD_TO_QUICK_JOIN_MINIMUM_SLOTS_TOO_HIGH, "REC_ADD_TO_QUICK_JOIN_MINIMUM_SLOTS_TOO_HIGH", "Failed to quick join. Too many player slots."},
{REC_REMOVE_FROM_QUICK_UNKNOWN_TITLE, "REC_REMOVE_FROM_QUICK_UNKNOWN_TITLE", "Failed to leave quick join. Unknown title (Programmer error)."},
{REC_REMOVE_FROM_QUICK_JOIN_NOT_THERE, "REC_REMOVE_FROM_QUICK_JOIN_NOT_THERE", "Failed to leave quick join. You are not in quick join to begin with."},
{REC_CREATE_ROOM_UNKNOWN_TITLE, "REC_CREATE_ROOM_UNKNOWN_TITLE", "Failed to create a room. Unknown title (Programmer error)."},
{REC_CREATE_ROOM_CURRENTLY_IN_QUICK_JOIN, "REC_CREATE_ROOM_CURRENTLY_IN_QUICK_JOIN", "Failed to create a room. You are currently in quick join. Leave quick join first."},
{REC_CREATE_ROOM_CURRENTLY_IN_A_ROOM, "REC_CREATE_ROOM_CURRENTLY_IN_A_ROOM", "Failed to create a room. You are already in a room."},
{REC_ROOM_CREATION_PARAMETERS_EMPTY_ROOM_NAME, "REC_ROOM_CREATION_PARAMETERS_EMPTY_ROOM_NAME", "You must specify a room name."},
{REC_ROOM_CREATION_PARAMETERS_RESERVED_QUICK_JOIN_ROOM_NAME, "REC_ROOM_CREATION_PARAMETERS_RESERVED_QUICK_JOIN_ROOM_NAME", "Invalid room creation parameters. The room name is reserved for quick join matches."},
{REC_ROOM_CREATION_PARAMETERS_ROOM_NAME_HAS_PROFANITY, "REC_ROOM_CREATION_PARAMETERS_ROOM_NAME_HAS_PROFANITY", "The desired room name cannot contain profanity."},
{REC_ROOM_CREATION_PARAMETERS_ROOM_NAME_IN_USE, "REC_ROOM_CREATION_PARAMETERS_ROOM_NAME_IN_USE", "The desired room name is already in use."},
{REC_ROOM_CREATION_PARAMETERS_NO_PLAYABLE_SLOTS, "REC_ROOM_CREATION_PARAMETERS_NO_PLAYABLE_SLOTS", "Invalid room creation parameters. The room must have at least one playable slot."},
{REC_SET_ROOM_PROPERTIES_UNKNOWN_ROOM, "REC_SET_ROOM_PROPERTIES_UNKNOWN_ROOM", "Unknown room."},
{REC_LEAVE_ROOM_UNKNOWN_ROOM_ID, "REC_LEAVE_ROOM_UNKNOWN_ROOM_ID", "Failed to leave a room. Your room no longer exists."},
{REC_LEAVE_ROOM_CURRENTLY_IN_QUICK_JOIN, "REC_LEAVE_ROOM_CURRENTLY_IN_QUICK_JOIN", "Failed to leave a room. You are currently in quick join. Leave quick join first."},
{REC_LEAVE_ROOM_NOT_IN_ROOM, "REC_LEAVE_ROOM_NOT_IN_ROOM", "You are not currently in a room."},
{REC_ENTER_ROOM_UNKNOWN_TITLE, "REC_ENTER_ROOM_UNKNOWN_TITLE", "Failed to enter a room. Unknown title (Programmer error)."},
{REC_ENTER_ROOM_CURRENTLY_IN_QUICK_JOIN, "REC_ENTER_ROOM_CURRENTLY_IN_QUICK_JOIN", "Failed to enter a room. You are currently in quick join. Leave quick join first."},
{REC_ENTER_ROOM_CURRENTLY_IN_A_ROOM, "REC_ENTER_ROOM_CURRENTLY_IN_A_ROOM", "Failed to enter a room. You are already in a room."},
{REC_PROCESS_QUICK_JOINS_UNKNOWN_TITLE, "REC_PROCESS_QUICK_JOINS_UNKNOWN_TITLE", "Unknown title (Programmer error)."},
{REC_ROOM_QUERY_TOO_MANY_QUERIES, "REC_ROOM_QUERY_TOO_MANY_QUERIES,", "Failed to process room query. Too many queries."},
{REC_ROOM_QUERY_INVALID_QUERIES_POINTER, "REC_ROOM_QUERY_INVALID_QUERIES_POINTER", "Failed to process room query. Query pointer is null."},
{REC_SEND_INVITE_UNKNOWN_ROOM_ID, "REC_SEND_INVITE_UNKNOWN_ROOM_ID", "Failed to send room invite. Your room no longer exists."},
{REC_SEND_INVITE_INVITEE_ALREADY_INVITED, "REC_SEND_INVITE_INVITEE_ALREADY_INVITED", "User was already invited to the room."},
{REC_SEND_INVITE_CANNOT_PERFORM_ON_SELF, "REC_SEND_INVITE_CANNOT_PERFORM_ON_SELF", "Cannot invite yourself."},
{REC_SEND_INVITE_INVITOR_ONLY_MODERATOR_CAN_INVITE, "REC_SEND_INVITE_INVITOR_ONLY_MODERATOR_CAN_INVITE", "Failed to send room invite. Room settings only allows the moderator to invite."},
{REC_SEND_INVITE_INVITOR_LACK_INVITE_PERMISSIONS, "REC_SEND_INVITE_INVITOR_LACK_INVITE_PERMISSIONS", "Failed to send room invite. Room settings does not allow invites to the desired slot type."},
{REC_SEND_INVITE_INVITOR_NOT_IN_ROOM, "REC_SEND_INVITE_INVITOR_NOT_IN_ROOM", "Failed to send room invite. You are not in the room you are trying to invite to."},
{REC_SEND_INVITE_NO_SLOTS, "REC_SEND_INVITE_NO_SLOTS", "Failed to send room invite. The room is full."},
{REC_SEND_INVITE_INVITEE_ALREADY_IN_THIS_ROOM, "REC_SEND_INVITE_INVITEE_ALREADY_IN_THIS_ROOM", "Failed to send room invite. This member is already in the room."},
{REC_SEND_INVITE_INVITEE_BANNED, "REC_SEND_INVITE_INVITEE_BANNED", "Failed to send room invite. The target member was banned from the room."},
{REC_SEND_INVITE_RECIPIENT_NOT_ONLINE, "REC_SEND_INVITE_RECIPIENT_NOT_ONLINE", "Failed to send room invite. The target member is not online."},
{REC_SEND_INVITE_ROOM_LOCKED, "REC_SEND_INVITE_ROOM_LOCKED", "Failed to send room invite. The room is locked to players of the intended slot."},
{REC_ACCEPT_INVITE_UNKNOWN_ROOM_ID, "REC_ACCEPT_INVITE_UNKNOWN_ROOM_ID", "Failed to accept room invite. Your room no longer exists."},
{REC_ACCEPT_INVITE_CURRENTLY_IN_A_ROOM, "REC_ACCEPT_INVITE_CURRENTLY_IN_A_ROOM", "Failed to accept room invite. You are already in a room. Leave the room first."},
{REC_ACCEPT_INVITE_CURRENTLY_IN_QUICK_JOIN, "REC_ACCEPT_INVITE_CURRENTLY_IN_QUICK_JOIN", "Failed to accept room invite. You are currently in quick join. Leave quick join first."},
{REC_ACCEPT_INVITE_BANNED, "REC_ACCEPT_INVITE_BANNED", "Failed to accept room invite. The moderator has banned you from the room."},
{REC_ACCEPT_INVITE_NO_SLOTS, "REC_ACCEPT_INVITE_NO_SLOTS", "Failed to accept room invite. The room is full for the specified slot type."},
{REC_ACCEPT_INVITE_ROOM_LOCKED, "REC_ACCEPT_INVITE_ROOM_LOCKED", "Failed to accept room invite. The room has been locked to the specified slot type."},
{REC_ACCEPT_INVITE_NO_SUCH_INVITE, "REC_ACCEPT_INVITE_NO_SUCH_INVITE", "Failed to accept room invite. You have no pending invites to this room."},
{REC_SLOTS_VALIDATION_NO_PLAYABLE_SLOTS, "REC_SLOTS_VALIDATION_NO_PLAYABLE_SLOTS", "Invalid room slots. The room must have at least one playable slot."},
{REC_SLOTS_VALIDATION_NEGATIVE_PUBLIC_SLOTS, "REC_SLOTS_VALIDATION_NEGATIVE_PUBLIC_SLOTS", "Invalid room slots. Public slots cannot be negative."},
{REC_SLOTS_VALIDATION_NEGATIVE_RESERVED_SLOTS, "REC_SLOTS_VALIDATION_NEGATIVE_RESERVED_SLOTS", "Invalid room slots. Reserved slots cannot be negative."},
{REC_SLOTS_VALIDATION_NEGATIVE_SPECTATOR_SLOTS, "REC_SLOTS_VALIDATION_NEGATIVE_SPECTATOR_SLOTS", "Invalid room slots. Spectator slots cannot be negative."},
{REC_START_SPECTATING_UNKNOWN_ROOM_ID, "REC_START_SPECTATING_UNKNOWN_ROOM_ID", "Failed to spectate. Your room no longer exists."},
{REC_START_SPECTATING_ALREADY_SPECTATING, "REC_START_SPECTATING_ALREADY_SPECTATING", "You are already spectating."},
{REC_START_SPECTATING_NO_SPECTATOR_SLOTS_AVAILABLE, "REC_START_SPECTATING_NO_SPECTATOR_SLOTS_AVAILABLE", "Failed to spectate. No spectator slots available."},
{REC_START_SPECTATING_NOT_IN_ROOM, "REC_START_SPECTATING_NOT_IN_ROOM", "Failed to spectate. Your room no longer exists."},
{REC_START_SPECTATING_REASSIGN_MODERATOR_BEFORE_SPECTATE, "REC_START_SPECTATING_REASSIGN_MODERATOR_BEFORE_SPECTATE", "The moderator cannot spectate wthout first granting moderator to another player."},
{REC_START_SPECTATING_ROOM_LOCKED, "REC_START_SPECTATING_ROOM_LOCKED", "Failed to spectate. The room has been locked."},
{REC_STOP_SPECTATING_UNKNOWN_ROOM_ID, "REC_STOP_SPECTATING_UNKNOWN_ROOM_ID", "Failed to stop spectating. Your room no longer exists."},
{REC_STOP_SPECTATING_NOT_IN_ROOM, "REC_STOP_SPECTATING_NOT_IN_ROOM", "Failed to stop spectating. You are not in a room."},
{REC_STOP_SPECTATING_NOT_CURRENTLY_SPECTATING, "REC_STOP_SPECTATING_NOT_CURRENTLY_SPECTATING", "Failed to stop spectating. You are not currently spectating."},
{REC_STOP_SPECTATING_NO_SLOTS, "REC_STOP_SPECTATING_NO_SLOTS", "Failed to stop spectating. All player slots are full."},
{REC_STOP_SPECTATING_ROOM_LOCKED, "REC_STOP_SPECTATING_ROOM_LOCKED", "Failed to stop spectating. The room has been locked."},
{REC_GRANT_MODERATOR_UNKNOWN_ROOM_ID, "REC_GRANT_MODERATOR_UNKNOWN_ROOM_ID", "Failed to grant moderator to another player. Your room no longer exists."},
{REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_ONLINE, "REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_ONLINE", "Failed to grant moderator to another player. The new moderator is not online."},
{REC_GRANT_MODERATOR_NOT_IN_ROOM, "REC_GRANT_MODERATOR_NOT_IN_ROOM", "Failed to grant moderator to another player. You are not in a room."},
{REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_IN_ROOM, "REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_IN_ROOM", "Failed to grant moderator to another player. The new moderator is not in the room."},
{REC_GRANT_MODERATOR_CANNOT_PERFORM_ON_SELF, "REC_GRANT_MODERATOR_CANNOT_PERFORM_ON_SELF", "You are already the moderator."},
{REC_GRANT_MODERATOR_MUST_BE_MODERATOR_TO_GRANT_MODERATOR, "REC_GRANT_MODERATOR_MUST_BE_MODERATOR_TO_GRANT_MODERATOR", "Failed to grant moderator to another player. You must be moderator to do this."},
{REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_IN_PLAYABLE_SLOT, "REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_IN_PLAYABLE_SLOT", "Failed to grant moderator to another player. The new moderator must be in a playable slot (not spectating)."},
{REC_CHANGE_SLOT_COUNTS_UNKNOWN_ROOM_ID, "REC_CHANGE_SLOT_COUNTS_UNKNOWN_ROOM_ID", "Failed to change slot counts. Your room no longer exists."},
{REC_CHANGE_SLOT_COUNTS_NOT_IN_ROOM, "REC_CHANGE_SLOT_COUNTS_NOT_IN_ROOM", "Failed to change slot counts. You are not in a room."},
{REC_CHANGE_SLOT_COUNTS_MUST_BE_MODERATOR, "REC_CHANGE_SLOT_COUNTS_MUST_BE_MODERATOR", "Failed to change slot counts. You must be moderator to do this."},
{REC_SET_CUSTOM_ROOM_PROPERTIES_UNKNOWN_ROOM_ID, "REC_SET_CUSTOM_ROOM_PROPERTIES_UNKNOWN_ROOM_ID", "Failed to set room properties. Your room no longer exists."},
{REC_SET_CUSTOM_ROOM_PROPERTIES_CONTAINS_DEFAULT_COLUMNS, "REC_SET_CUSTOM_ROOM_PROPERTIES_CONTAINS_DEFAULT_COLUMNS", "Failed to set custom room properties. Custom properties cannot contain default columns. Use the provided functions for this."},
{REC_SET_CUSTOM_ROOM_PROPERTIES_NOT_IN_ROOM, "REC_SET_CUSTOM_ROOM_PROPERTIES_NOT_IN_ROOM", "Failed to set room properties. You are not in a room."},
{REC_SET_CUSTOM_ROOM_PROPERTIES_MUST_BE_MODERATOR, "REC_SET_CUSTOM_ROOM_PROPERTIES_MUST_BE_MODERATOR", "Failed to set room properties. You must be moderator to do this."},
{REC_GET_ROOM_PROPERTIES_EMPTY_ROOM_NAME_AND_NOT_IN_A_ROOM, "REC_GET_ROOM_PROPERTIES_EMPTY_ROOM_NAME_AND_NOT_IN_A_ROOM", "Failed to get room properties. The room name is empty."},
{REC_GET_ROOM_PROPERTIES_UNKNOWN_ROOM_NAME, "REC_GET_ROOM_PROPERTIES_UNKNOWN_ROOM_NAME", "Failed to get room properties. Named room does not exist."},
{REC_CHANGE_ROOM_NAME_UNKNOWN_ROOM_ID, "REC_CHANGE_ROOM_NAME_UNKNOWN_ROOM_ID", "Failed to change the room's name. Your room no longer exists."},
{REC_CHANGE_ROOM_NAME_NOT_IN_ROOM, "REC_CHANGE_ROOM_NAME_NOT_IN_ROOM", "Failed to change the room's name. You are not in a room."},
{REC_CHANGE_ROOM_NAME_MUST_BE_MODERATOR, "REC_CHANGE_ROOM_NAME_MUST_BE_MODERATOR", "Failed to change the room's name. You must be moderator to do this."},
{REC_CHANGE_ROOM_NAME_HAS_PROFANITY, "REC_CHANGE_ROOM_NAME_HAS_PROFANITY", "Failed to change the room's name. The new name contains profanity."},
{REC_CHANGE_ROOM_NAME_EMPTY_ROOM_NAME, "REC_CHANGE_ROOM_NAME_EMPTY_ROOM_NAME", "Failed to change the room's name. The new name is empty."},
{REC_CHANGE_ROOM_NAME_NAME_ALREADY_IN_USE, "REC_CHANGE_ROOM_NAME_NAME_ALREADY_IN_USE", "Failed to change the room's name. The new name is already in use."},
{REC_SET_HIDDEN_FROM_SEARCHES_UNKNOWN_ROOM_ID, "REC_SET_HIDDEN_FROM_SEARCHES_UNKNOWN_ROOM_ID", "Failed to set the room hidden from searches. Your room no longer exists."},
{REC_SET_HIDDEN_FROM_SEARCHES_NOT_IN_ROOM, "REC_SET_HIDDEN_FROM_SEARCHES_NOT_IN_ROOM", "Failed to set the room hidden from searches. You are not in a room."},
{REC_SET_HIDDEN_FROM_SEARCHES_MUST_BE_MODERATOR, "REC_SET_HIDDEN_FROM_SEARCHES_MUST_BE_MODERATOR", "Failed to set the room hidden from searches. You must be moderator to do this."},
{REC_SET_DESTROY_ON_MODERATOR_LEAVE_UNKNOWN_ROOM_ID, "REC_SET_DESTROY_ON_MODERATOR_LEAVE_UNKNOWN_ROOM_ID", "Failed to set the room to be destroyed on moderator leave. Your room no longer exists."},
{REC_SET_DESTROY_ON_MODERATOR_LEAVE_NOT_IN_ROOM, "REC_SET_DESTROY_ON_MODERATOR_LEAVE_NOT_IN_ROOM", "Failed to set the room to be destroyed on moderator leave. You are not in a room."},
{REC_SET_DESTROY_ON_MODERATOR_LEAVE_MUST_BE_MODERATOR, "REC_SET_DESTROY_ON_MODERATOR_LEAVE_MUST_BE_MODERATOR", "Failed to set the room to be destroyed on moderator leave. You must be moderator to do this."},
{REC_SET_READY_STATUS_UNKNOWN_ROOM_ID, "REC_SET_READY_STATUS_UNKNOWN_ROOM_ID", "Failed to set ready status. Your room no longer exists."},
{REC_SET_READY_STATUS_NOT_IN_ROOM, "REC_SET_READY_STATUS_NOT_IN_ROOM,", "Failed to set ready status. You are not in a room."},
{REC_SET_READY_STATUS_NOT_IN_PLAYABLE_SLOT, "REC_SET_READY_STATUS_NOT_IN_PLAYABLE_SLOT", "Failed to set ready status. You are currently spectating. Only players can set ready status."},
{REC_SET_READY_STATUS_AUTO_LOCK_ALL_PLAYERS_READY, "REC_SET_READY_STATUS_AUTO_LOCK_ALL_PLAYERS_READY", "Failed to unready. The room is locked. Leave the room if you do not want to play."},
{REC_GET_READY_STATUS_NOT_IN_ROOM, "REC_GET_READY_STATUS_NOT_IN_ROOM", "Failed to get ready status for your existing room. You are not in a room."},
{REC_GET_READY_STATUS_UNKNOWN_ROOM_ID, "REC_GET_READY_STATUS_UNKNOWN_ROOM_ID,", "Failed to get ready status. Your room no longer exists."},
{REC_SET_ROOM_LOCK_STATE_UNKNOWN_ROOM_ID, "REC_SET_ROOM_LOCK_STATE_UNKNOWN_ROOM_ID", "Failed to set room lock state. Your room no longer exists."},
{REC_SET_ROOM_LOCK_STATE_NOT_IN_ROOM, "REC_SET_ROOM_LOCK_STATE_NOT_IN_ROOM", "Failed to set room lock state. You are not in a room."},
{REC_SET_ROOM_LOCK_STATE_MUST_BE_MODERATOR, "REC_SET_ROOM_LOCK_STATE_MUST_BE_MODERATOR", "Failed to set room lock state. You must be moderator to do this."},
{REC_SET_ROOM_LOCK_STATE_BAD_ENUMERATION_VALUE, "REC_SET_ROOM_LOCK_STATE_BAD_ENUMERATION_VALUE", "Failed to set room lock state. Bad enumeration (programmer error)."},
{REC_GET_ROOM_LOCK_STATE_UNKNOWN_ROOM_ID, "REC_GET_ROOM_LOCK_STATE_UNKNOWN_ROOM_ID", "Failed to get room lock state. Your room no longer exists."},
{REC_GET_ROOM_LOCK_STATE_NOT_IN_ROOM, "REC_GET_ROOM_LOCK_STATE_NOT_IN_ROOM", "Failed to get room lock state for your existing room. You are not in a room."},
{REC_ARE_ALL_MEMBERS_READY_UNKNOWN_ROOM_ID, "REC_ARE_ALL_MEMBERS_READY_UNKNOWN_ROOM_ID", "Failed to check member ready status. Your room no longer exists."},
{REC_ARE_ALL_MEMBERS_READY_NOT_IN_ROOM, "REC_ARE_ALL_MEMBERS_READY_NOT_IN_ROOM", "Failed to check member ready status for your existing room. You are not in a room."},
{REC_KICK_MEMBER_UNKNOWN_ROOM_ID, "REC_KICK_MEMBER_UNKNOWN_ROOM_ID", "Failed to kick member. Your room no longer exists."},
{REC_KICK_MEMBER_NOT_IN_ROOM, "REC_KICK_MEMBER_NOT_IN_ROOM", "Failed to kick member. You are not in a room."},
{REC_KICK_MEMBER_TARGET_NOT_ONLINE, "REC_KICK_MEMBER_TARGET_NOT_ONLINE", "Failed to kick member. The target member is not online."},
{REC_KICK_MEMBER_TARGET_NOT_IN_YOUR_ROOM, "REC_KICK_MEMBER_TARGET_NOT_IN_YOUR_ROOM", "Failed to kick member. Member is no longer in the room."},
{REC_KICK_MEMBER_MUST_BE_MODERATOR, "REC_KICK_MEMBER_MUST_BE_MODERATOR", "Failed to kick member. You must be moderator to do this."},
{REC_KICK_MEMBER_CANNOT_PERFORM_ON_SELF, "REC_KICK_MEMBER_CANNOT_PERFORM_ON_SELF", "Cannot kick yourself."},
{REC_GET_KICK_REASON_UNKNOWN_ROOM_ID, "REC_GET_KICK_REASON_UNKNOWN_ROOM_ID", "Failed to get kick reason. Your room no longer exists."},
{REC_GET_KICK_REASON_NOT_KICKED, "REC_GET_KICK_REASON_NOT_KICKED", "Specified user has not been kicked."},
{REC_REMOVE_USER_NOT_IN_ROOM, "REC_REMOVE_USER_NOT_IN_ROOM", "Failed to remove user from room. User is not in room."},
{REC_ADD_TITLE_ALREADY_IN_USE, "REC_ADD_TITLE_ALREADY_IN_USE", "Failed to add a title. This title is already in use."},
{REC_UNBAN_MEMBER_UNKNOWN_ROOM_ID, "REC_UNBAN_MEMBER_UNKNOWN_ROOM_ID", "Failed to unban member. Your room no longer exists."},
{REC_UNBAN_MEMBER_NOT_IN_ROOM, "REC_UNBAN_MEMBER_NOT_IN_ROOM", "Failed to unban member. You are not in a room."},
{REC_UNBAN_MEMBER_MUST_BE_MODERATOR, "REC_UNBAN_MEMBER_MUST_BE_MODERATOR", "Failed to unban member. You must be moderator to do this."},
{REC_UNBAN_MEMBER_NOT_BANNED, "REC_UNBAN_MEMBER_NOT_BANNED", "Specified member is not banned."},
{REC_GET_BAN_REASON_UNKNOWN_ROOM_ID, "REC_GET_BAN_REASON_UNKNOWN_ROOM_ID", "Failed to get ban reason. Room no longer exists."},
{REC_GET_BAN_REASON_NOT_BANNED, "REC_GET_BAN_REASON_NOT_BANNED", "This user is not banned."},
{REC_CHANGE_HANDLE_NEW_HANDLE_IN_USE, "REC_CHANGE_HANDLE_NEW_HANDLE_IN_USE", "The handle you are changing to is already in use."},
{REC_CHANGE_HANDLE_CONTAINS_PROFANITY, "REC_CHANGE_HANDLE_CONTAINS_PROFANITY", "The handle you are changing to contains profanity."},
{REC_CHAT_USER_NOT_IN_ROOM, "REC_CHAT_USER_NOT_IN_ROOM", "You must be in a room to send room chat messages."},
{REC_CHAT_RECIPIENT_NOT_ONLINE, "REC_CHAT_RECIPIENT_NOT_ONLINE,", "Chat recipient is not online."},
{REC_CHAT_RECIPIENT_NOT_IN_ANY_ROOM, "REC_CHAT_RECIPIENT_NOT_IN_ANY_ROOM", "Chat recipient is not in a room."},
{REC_CHAT_RECIPIENT_NOT_IN_YOUR_ROOM, "REC_CHAT_RECIPIENT_NOT_IN_YOUR_ROOM", "Chat recipient is not in your room."},
{REC_BITSTREAM_USER_NOT_IN_ROOM, "REC_BITSTREAM_USER_NOT_IN_ROOM", "You must be in a room to send bitstream messages."},
{REC_BITSTREAM_RECIPIENT_NOT_ONLINE, "REC_BITSTREAM_RECIPIENT_NOT_ONLINE", "Bitstream recipient is not online."},
{REC_BITSTREAM_RECIPIENT_NOT_IN_ANY_ROOM, "REC_BITSTREAM_RECIPIENT_NOT_IN_ANY_ROOM", "Bitstream recipient is not in a room."},
{REC_BITSTREAM_RECIPIENT_NOT_IN_YOUR_ROOM, "REC_BITSTREAM_RECIPIENT_NOT_IN_YOUR_ROOM", "Bitstream recipient is not in your room."},
};
const char *RoomsErrorCodeDescription::ToEnglish(RoomsErrorCode result)
{
RakAssert(errorCodeDescriptions[result].errorCode==result);
return errorCodeDescriptions[result].englishDesc;
}
const char *RoomsErrorCodeDescription::ToEnum(RoomsErrorCode result)
{
RakAssert(errorCodeDescriptions[result].errorCode==result);
return errorCodeDescriptions[result].enumDesc;
}
void RoomsErrorCodeDescription::Validate(void)
{
int i;
for (i=0; i < ROOMS_ERROR_CODES_COUNT; i++)
{
RakAssert(errorCodeDescriptions[i].errorCode==i);
}
}

View File

@ -0,0 +1,193 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017-2018, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __ROOMS_ERROR_CODES_H
#define __ROOMS_ERROR_CODES_H
#include "slikenet/defines.h" // used for SLNet -> RakNet namespace change in RAKNET_COMPATIBILITY mode
namespace SLNet
{
enum RoomsErrorCode
{
REC_SUCCESS,
REC_USERNAME_IS_EMPTY, // Generic error, when the requester of an operation did not define his username
REC_NOT_LOGGED_IN, // Generic error, when the requester of an operation is not logged in
REC_ADD_TO_ROOM_NO_RESERVED_OR_PUBLIC,
REC_ADD_TO_ROOM_NO_PUBLIC,
REC_ADD_TO_ROOM_NO_SPECTATOR,
REC_ADD_TO_ROOM_ALREADY_IN_THIS_ROOM,
REC_ADD_TO_ROOM_ALREADY_IN_ANOTHER_ROOM,
REC_ADD_TO_ROOM_KICKED_OUT_OF_ROOM,
REC_CHANGE_MEMBER_TYPE_NO_SLOTS,
REC_SEARCH_BY_FILTER_UNKNOWN_TITLE,
REC_JOIN_BY_FILTER_UNKNOWN_TITLE,
REC_JOIN_BY_FILTER_NO_ROOMS,
REC_JOIN_BY_FILTER_CURRENTLY_IN_A_ROOM,
REC_JOIN_BY_FILTER_CURRENTLY_IN_QUICK_JOIN,
REC_JOIN_BY_FILTER_CANNOT_JOIN_AS_MODERATOR,
REC_JOIN_BY_FILTER_ROOM_LOCKED,
REC_JOIN_BY_FILTER_BANNED,
REC_JOIN_BY_FILTER_NO_SLOTS,
REC_JOIN_BY_QUICK_JOIN_CANNOT_JOIN_AS_MODERATOR,
REC_JOIN_BY_QUICK_JOIN_ROOM_LOCKED,
REC_JOIN_BY_QUICK_JOIN_BANNED,
REC_JOIN_BY_QUICK_JOIN_NO_SLOTS,
REC_ADD_TO_QUICK_JOIN_CURRENTLY_IN_A_ROOM,
REC_ADD_TO_QUICK_JOIN_UNKNOWN_TITLE,
REC_ADD_TO_QUICK_JOIN_ALREADY_THERE,
REC_ADD_TO_QUICK_JOIN_INVALID_TIMEOUT_TOO_LOW,
REC_ADD_TO_QUICK_JOIN_INVALID_TIMEOUT_TOO_HIGH,
REC_ADD_TO_QUICK_JOIN_MINIMUM_SLOTS_TOO_LOW,
REC_ADD_TO_QUICK_JOIN_MINIMUM_SLOTS_TOO_HIGH,
REC_REMOVE_FROM_QUICK_UNKNOWN_TITLE,
REC_REMOVE_FROM_QUICK_JOIN_NOT_THERE,
REC_CREATE_ROOM_UNKNOWN_TITLE,
REC_CREATE_ROOM_CURRENTLY_IN_QUICK_JOIN,
REC_CREATE_ROOM_CURRENTLY_IN_A_ROOM,
REC_ROOM_CREATION_PARAMETERS_EMPTY_ROOM_NAME,
REC_ROOM_CREATION_PARAMETERS_RESERVED_QUICK_JOIN_ROOM_NAME,
REC_ROOM_CREATION_PARAMETERS_ROOM_NAME_HAS_PROFANITY,
REC_ROOM_CREATION_PARAMETERS_ROOM_NAME_IN_USE,
REC_ROOM_CREATION_PARAMETERS_NO_PLAYABLE_SLOTS,
REC_SET_ROOM_PROPERTIES_UNKNOWN_ROOM,
REC_LEAVE_ROOM_UNKNOWN_ROOM_ID,
REC_LEAVE_ROOM_CURRENTLY_IN_QUICK_JOIN,
REC_LEAVE_ROOM_NOT_IN_ROOM,
REC_ENTER_ROOM_UNKNOWN_TITLE,
REC_ENTER_ROOM_CURRENTLY_IN_QUICK_JOIN,
REC_ENTER_ROOM_CURRENTLY_IN_A_ROOM,
REC_PROCESS_QUICK_JOINS_UNKNOWN_TITLE,
REC_ROOM_QUERY_TOO_MANY_QUERIES,
REC_ROOM_QUERY_INVALID_QUERIES_POINTER,
REC_SEND_INVITE_UNKNOWN_ROOM_ID,
REC_SEND_INVITE_INVITEE_ALREADY_INVITED,
REC_SEND_INVITE_CANNOT_PERFORM_ON_SELF,
REC_SEND_INVITE_INVITOR_ONLY_MODERATOR_CAN_INVITE, // INVITE_MODE_MODERATOR_ONLY
REC_SEND_INVITE_INVITOR_LACK_INVITE_PERMISSIONS, // Any other INVITE_MODE
REC_SEND_INVITE_INVITOR_NOT_IN_ROOM,
REC_SEND_INVITE_NO_SLOTS,
REC_SEND_INVITE_INVITEE_ALREADY_IN_THIS_ROOM,
REC_SEND_INVITE_INVITEE_BANNED,
REC_SEND_INVITE_RECIPIENT_NOT_ONLINE,
REC_SEND_INVITE_ROOM_LOCKED,
REC_ACCEPT_INVITE_UNKNOWN_ROOM_ID,
REC_ACCEPT_INVITE_CURRENTLY_IN_A_ROOM,
REC_ACCEPT_INVITE_CURRENTLY_IN_QUICK_JOIN,
REC_ACCEPT_INVITE_BANNED,
REC_ACCEPT_INVITE_NO_SLOTS,
REC_ACCEPT_INVITE_ROOM_LOCKED,
REC_ACCEPT_INVITE_NO_SUCH_INVITE,
REC_SLOTS_VALIDATION_NO_PLAYABLE_SLOTS,
REC_SLOTS_VALIDATION_NEGATIVE_PUBLIC_SLOTS,
REC_SLOTS_VALIDATION_NEGATIVE_RESERVED_SLOTS,
REC_SLOTS_VALIDATION_NEGATIVE_SPECTATOR_SLOTS,
REC_START_SPECTATING_UNKNOWN_ROOM_ID,
REC_START_SPECTATING_ALREADY_SPECTATING,
REC_START_SPECTATING_NO_SPECTATOR_SLOTS_AVAILABLE,
REC_START_SPECTATING_NOT_IN_ROOM,
REC_START_SPECTATING_REASSIGN_MODERATOR_BEFORE_SPECTATE,
REC_START_SPECTATING_ROOM_LOCKED,
REC_STOP_SPECTATING_UNKNOWN_ROOM_ID,
REC_STOP_SPECTATING_NOT_IN_ROOM,
REC_STOP_SPECTATING_NOT_CURRENTLY_SPECTATING,
REC_STOP_SPECTATING_NO_SLOTS,
REC_STOP_SPECTATING_ROOM_LOCKED,
REC_GRANT_MODERATOR_UNKNOWN_ROOM_ID,
REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_ONLINE,
REC_GRANT_MODERATOR_NOT_IN_ROOM,
REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_IN_ROOM,
REC_GRANT_MODERATOR_CANNOT_PERFORM_ON_SELF,
REC_GRANT_MODERATOR_MUST_BE_MODERATOR_TO_GRANT_MODERATOR,
REC_GRANT_MODERATOR_NEW_MODERATOR_NOT_IN_PLAYABLE_SLOT,
REC_CHANGE_SLOT_COUNTS_UNKNOWN_ROOM_ID,
REC_CHANGE_SLOT_COUNTS_NOT_IN_ROOM,
REC_CHANGE_SLOT_COUNTS_MUST_BE_MODERATOR,
REC_SET_CUSTOM_ROOM_PROPERTIES_UNKNOWN_ROOM_ID,
REC_SET_CUSTOM_ROOM_PROPERTIES_CONTAINS_DEFAULT_COLUMNS,
REC_SET_CUSTOM_ROOM_PROPERTIES_NOT_IN_ROOM,
REC_SET_CUSTOM_ROOM_PROPERTIES_MUST_BE_MODERATOR,
REC_GET_ROOM_PROPERTIES_EMPTY_ROOM_NAME_AND_NOT_IN_A_ROOM,
REC_GET_ROOM_PROPERTIES_UNKNOWN_ROOM_NAME,
REC_CHANGE_ROOM_NAME_UNKNOWN_ROOM_ID,
REC_CHANGE_ROOM_NAME_NOT_IN_ROOM,
REC_CHANGE_ROOM_NAME_MUST_BE_MODERATOR,
REC_CHANGE_ROOM_NAME_HAS_PROFANITY,
REC_CHANGE_ROOM_NAME_EMPTY_ROOM_NAME,
REC_CHANGE_ROOM_NAME_NAME_ALREADY_IN_USE,
REC_SET_HIDDEN_FROM_SEARCHES_UNKNOWN_ROOM_ID,
REC_SET_HIDDEN_FROM_SEARCHES_NOT_IN_ROOM,
REC_SET_HIDDEN_FROM_SEARCHES_MUST_BE_MODERATOR,
REC_SET_DESTROY_ON_MODERATOR_LEAVE_UNKNOWN_ROOM_ID,
REC_SET_DESTROY_ON_MODERATOR_LEAVE_NOT_IN_ROOM,
REC_SET_DESTROY_ON_MODERATOR_LEAVE_MUST_BE_MODERATOR,
REC_SET_READY_STATUS_UNKNOWN_ROOM_ID,
REC_SET_READY_STATUS_NOT_IN_ROOM,
REC_SET_READY_STATUS_NOT_IN_PLAYABLE_SLOT,
REC_SET_READY_STATUS_AUTO_LOCK_ALL_PLAYERS_READY,
REC_GET_READY_STATUS_NOT_IN_ROOM,
REC_GET_READY_STATUS_UNKNOWN_ROOM_ID,
REC_SET_ROOM_LOCK_STATE_UNKNOWN_ROOM_ID,
REC_SET_ROOM_LOCK_STATE_NOT_IN_ROOM,
REC_SET_ROOM_LOCK_STATE_MUST_BE_MODERATOR,
REC_SET_ROOM_LOCK_STATE_BAD_ENUMERATION_VALUE,
REC_GET_ROOM_LOCK_STATE_UNKNOWN_ROOM_ID,
REC_GET_ROOM_LOCK_STATE_NOT_IN_ROOM,
REC_ARE_ALL_MEMBERS_READY_UNKNOWN_ROOM_ID,
REC_ARE_ALL_MEMBERS_READY_NOT_IN_ROOM,
REC_KICK_MEMBER_UNKNOWN_ROOM_ID,
REC_KICK_MEMBER_NOT_IN_ROOM,
REC_KICK_MEMBER_TARGET_NOT_ONLINE,
REC_KICK_MEMBER_TARGET_NOT_IN_YOUR_ROOM,
REC_KICK_MEMBER_MUST_BE_MODERATOR,
REC_KICK_MEMBER_CANNOT_PERFORM_ON_SELF,
REC_GET_KICK_REASON_UNKNOWN_ROOM_ID,
REC_GET_KICK_REASON_NOT_KICKED,
REC_REMOVE_USER_NOT_IN_ROOM,
REC_ADD_TITLE_ALREADY_IN_USE,
REC_UNBAN_MEMBER_UNKNOWN_ROOM_ID,
REC_UNBAN_MEMBER_NOT_IN_ROOM,
REC_UNBAN_MEMBER_MUST_BE_MODERATOR,
REC_UNBAN_MEMBER_NOT_BANNED,
REC_GET_BAN_REASON_UNKNOWN_ROOM_ID,
REC_GET_BAN_REASON_NOT_BANNED,
REC_CHANGE_HANDLE_NEW_HANDLE_IN_USE,
REC_CHANGE_HANDLE_CONTAINS_PROFANITY,
REC_CHAT_USER_NOT_IN_ROOM,
REC_CHAT_RECIPIENT_NOT_ONLINE,
REC_CHAT_RECIPIENT_NOT_IN_ANY_ROOM,
REC_CHAT_RECIPIENT_NOT_IN_YOUR_ROOM,
REC_BITSTREAM_USER_NOT_IN_ROOM,
REC_BITSTREAM_RECIPIENT_NOT_ONLINE,
REC_BITSTREAM_RECIPIENT_NOT_IN_ANY_ROOM,
REC_BITSTREAM_RECIPIENT_NOT_IN_YOUR_ROOM,
ROOMS_ERROR_CODES_COUNT
};
struct RoomsErrorCodeDescription
{
RoomsErrorCode errorCode;
const char *enumDesc;
const char *englishDesc;
static const char *ToEnglish(RoomsErrorCode result);
static const char *ToEnum(RoomsErrorCode result);
static void Validate(void);
};
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*/
// Code is in Lobby2Client_Steam_Impl.cpp

View File

@ -0,0 +1,50 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_CLIENT_STEAM_H
#define __LOBBY_2_CLIENT_STEAM_H
#include "Lobby2Plugin.h"
#include "slikenet/DS_OrderedList.h"
#include "slikenet/types.h"
namespace SLNet
{
// This is a pure interface for Lobby2Client_SteamImpl
class RAK_DLL_EXPORT Lobby2Client_Steam : public SLNet::Lobby2Plugin
{
public:
// GetInstance() and DestroyInstance(instance*)
STATIC_FACTORY_DECLARATIONS(Lobby2Client_Steam)
virtual ~Lobby2Client_Steam() {}
virtual void SendMsg(Lobby2Message *msg)=0;
virtual void GetRoomMembers(DataStructures::OrderedList<uint64_t, uint64_t> &_roomMembers)=0;
virtual const char * GetRoomMemberName(uint64_t memberId)=0;
virtual bool IsRoomOwner(const uint64_t cSteamID)=0;
virtual bool IsInRoom(void) const=0;
virtual uint64_t GetNumRoomMembers(const uint64_t roomid)=0;
virtual uint64_t GetMyUserID(void)=0;
virtual const char* GetMyUserPersonalName(void)=0;
virtual uint64_t GetRoomID(void) const=0;
protected:
};
};
#endif

View File

@ -0,0 +1,621 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017-2020, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Client_Steam_Impl.h"
#include "Lobby2Message_Steam.h"
#include <stdlib.h>
#include "slikenet/NativeTypes.h"
#include "slikenet/MTUSize.h"
#include <windows.h>
using namespace SLNet;
STATIC_FACTORY_DEFINITIONS(Lobby2Client_Steam,Lobby2Client_Steam_Impl)
DEFINE_MULTILIST_PTR_TO_MEMBER_COMPARISONS(Lobby2Message,uint64_t,requestId);
int Lobby2Client_Steam_Impl::SystemAddressAndRoomMemberComp( const SystemAddress &key, const Lobby2Client_Steam_Impl::RoomMember &data )
{
if (key<data.systemAddress)
return -1;
if (key==data.systemAddress)
return 0;
return 1;
}
int Lobby2Client_Steam_Impl::SteamIDAndRoomMemberComp( const uint64_t &key, const Lobby2Client_Steam_Impl::RoomMember &data )
{
if (key<data.steamIDRemote)
return -1;
if (key==data.steamIDRemote)
return 0;
return 1;
}
Lobby2Client_Steam_Impl::Lobby2Client_Steam_Impl() :
m_CallbackLobbyDataUpdated(nullptr, nullptr),
m_CallbackPersonaStateChange(nullptr, nullptr),
m_CallbackLobbyDataUpdate(nullptr, nullptr),
m_CallbackChatDataUpdate(nullptr, nullptr),
m_CallbackChatMessageUpdate(nullptr, nullptr),
m_CallbackP2PSessionRequest(nullptr, nullptr),
m_CallbackP2PSessionConnectFail(nullptr, nullptr)
{
// Must recompile RakNet with MAXIMUM_MTU_SIZE set to 1200 in the preprocessor settings
RakAssert(MAXIMUM_MTU_SIZE<=1200);
roomId=0;
m_CallbackLobbyDataUpdated.Register(this, &Lobby2Client_Steam_Impl::OnLobbyDataUpdatedCallback);
m_CallbackPersonaStateChange.Register(this, &Lobby2Client_Steam_Impl::OnPersonaStateChange);
m_CallbackLobbyDataUpdate.Register(this, &Lobby2Client_Steam_Impl::OnLobbyDataUpdate);
m_CallbackChatDataUpdate.Register(this, &Lobby2Client_Steam_Impl::OnLobbyChatUpdate);
m_CallbackChatMessageUpdate.Register(this, &Lobby2Client_Steam_Impl::OnLobbyChatMessage);
m_CallbackP2PSessionRequest.Register(this, &Lobby2Client_Steam_Impl::OnP2PSessionRequest);
m_CallbackP2PSessionConnectFail.Register(this, &Lobby2Client_Steam_Impl::OnP2PSessionConnectFail);
}
Lobby2Client_Steam_Impl::~Lobby2Client_Steam_Impl()
{
}
void Lobby2Client_Steam_Impl::SendMsg(Lobby2Message *msg)
{
if (msg->ClientImpl(this))
{
for (unsigned long i=0; i < callbacks.Size(); i++)
{
if (msg->callbackId==(uint32_t)-1 || msg->callbackId==callbacks[i]->callbackId)
msg->CallCallback(callbacks[i]);
}
}
else
{
// Won't be deleted by the user's call to Deref.
msg->resultCode=L2RC_PROCESSING;
msg->AddRef();
PushDeferredCallback(msg);
}
}
void Lobby2Client_Steam_Impl::Update(void)
{
SteamAPI_RunCallbacks();
/*
// sending data
// must be a handle to a connected socket
// data is all sent via UDP, and thus send sizes are limited to 1200 bytes; after this, many routers will start dropping packets
// use the reliable flag with caution; although the resend rate is pretty aggressive,
// it can still cause stalls in receiving data (like TCP)
virtual bool SendDataOnSocket( SNetSocket_t hSocket, void *pubData, uint32 cubData, bool bReliable ) = 0;
// receiving data
// returns false if there is no data remaining
// fills out *pcubMsgSize with the size of the next message, in bytes
virtual bool IsDataAvailableOnSocket( SNetSocket_t hSocket, uint32 *pcubMsgSize ) = 0;
// fills in pubDest with the contents of the message
// messages are always complete, of the same size as was sent (i.e. packetized, not streaming)
// if *pcubMsgSize < cubDest, only partial data is written
// returns false if no data is available
virtual bool RetrieveDataFromSocket( SNetSocket_t hSocket, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize ) = 0;
*/
}
void Lobby2Client_Steam_Impl::PushDeferredCallback(Lobby2Message *msg)
{
deferredCallbacks.Push(msg, msg->requestId, _FILE_AND_LINE_ );
}
void Lobby2Client_Steam_Impl::CallCBWithResultCode(Lobby2Message *msg, Lobby2ResultCode rc)
{
if (msg)
{
msg->resultCode=rc;
for (unsigned long i=0; i < callbacks.Size(); i++)
{
if (msg->callbackId==(uint32_t)-1 || msg->callbackId==callbacks[i]->callbackId)
msg->CallCallback(callbacks[i]);
}
}
}
void Lobby2Client_Steam_Impl::OnLobbyMatchListCallback( LobbyMatchList_t *pCallback, bool bIOFailure )
{
(void) bIOFailure;
uint32_t i;
for (i=0; i < deferredCallbacks.GetSize(); i++)
{
// Get any instance of Console_SearchRooms
if (deferredCallbacks[i]->GetID()==L2MID_Console_SearchRooms)
{
Console_SearchRooms_Steam *callbackResult = (Console_SearchRooms_Steam *) deferredCallbacks[i];
// iterate the returned lobbies with GetLobbyByIndex(), from values 0 to m_nLobbiesMatching-1
// lobbies are returned in order of closeness to the user, so add them to the list in that order
for ( uint32 iLobby = 0; iLobby < pCallback->m_nLobbiesMatching; iLobby++ )
{
CSteamID steamId = SteamMatchmaking()->GetLobbyByIndex( iLobby );
callbackResult->roomIds.Push(steamId.ConvertToUint64(), _FILE_AND_LINE_ );
SLNet::RakString s = SteamMatchmaking()->GetLobbyData( steamId, "name" );
callbackResult->roomNames.Push(s, _FILE_AND_LINE_ );
}
CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
msgFactory->Dealloc(callbackResult);
deferredCallbacks.RemoveAtIndex(i);
break;
}
}
}
void Lobby2Client_Steam_Impl::OnLobbyDataUpdatedCallback( LobbyDataUpdate_t *pCallback )
{
uint32_t i;
for (i=0; i < deferredCallbacks.GetSize(); i++)
{
if (deferredCallbacks[i]->GetID()==L2MID_Console_GetRoomDetails)
{
Console_GetRoomDetails_Steam *callbackResult = (Console_GetRoomDetails_Steam *) deferredCallbacks[i];
if (callbackResult->roomId==pCallback->m_ulSteamIDLobby)
{
const char *pchLobbyName = SteamMatchmaking()->GetLobbyData( pCallback->m_ulSteamIDLobby, "name" );
if ( pchLobbyName[0] )
{
callbackResult->roomName=pchLobbyName;
}
if (pCallback->m_bSuccess)
CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
else
CallCBWithResultCode(callbackResult, L2RC_Console_GetRoomDetails_NO_ROOMS_FOUND);
msgFactory->Dealloc(callbackResult);
deferredCallbacks.RemoveAtIndex(i);
break;
}
}
}
Console_GetRoomDetails_Steam notification;
const char *pchLobbyName = SteamMatchmaking()->GetLobbyData( pCallback->m_ulSteamIDLobby, "name" );
if ( pchLobbyName[0] )
{
notification.roomName=pchLobbyName;
}
notification.roomId=pCallback->m_ulSteamIDLobby;
CallCBWithResultCode(&notification, L2RC_SUCCESS);
}
void Lobby2Client_Steam_Impl::OnLobbyCreated( LobbyCreated_t *pCallback, bool bIOFailure )
{
(void) bIOFailure;
uint32_t i;
for (i=0; i < deferredCallbacks.GetSize(); i++)
{
if (deferredCallbacks[i]->GetID()==L2MID_Console_CreateRoom)
{
Console_CreateRoom_Steam *callbackResult = (Console_CreateRoom_Steam *) deferredCallbacks[i];
callbackResult->roomId=pCallback->m_ulSteamIDLobby;
SteamMatchmaking()->SetLobbyData( callbackResult->roomId, "name", callbackResult->roomName.C_String() );
roomId=pCallback->m_ulSteamIDLobby;
printf("\nNumber of Steam Lobby Members:%i in Lobby Name:%s\n", SteamMatchmaking()->GetNumLobbyMembers(roomId), callbackResult->roomName.C_String());
RoomMember roomMember;
roomMember.steamIDRemote=SteamMatchmaking()->GetLobbyOwner(roomId).ConvertToUint64();
roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
roomMembersByAddr.Insert(roomMember.systemAddress,roomMember,true,_FILE_AND_LINE_);
roomMembersById.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
callbackResult->extendedResultCode=pCallback->m_eResult;
if (pCallback->m_eResult==k_EResultOK)
{
CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
}
else
{
CallCBWithResultCode(callbackResult, L2RC_GENERAL_ERROR);
}
msgFactory->Dealloc(callbackResult);
deferredCallbacks.RemoveAtIndex(i);
// Commented out: Do not send the notification for yourself
// CallRoomCallbacks();
break;
}
}
}
void Lobby2Client_Steam_Impl::OnLobbyJoined( LobbyEnter_t *pCallback, bool bIOFailure )
{
(void) bIOFailure;
uint32_t i;
for (i=0; i < deferredCallbacks.GetSize(); i++)
{
if (deferredCallbacks[i]->GetID()==L2MID_Console_JoinRoom)
{
Console_JoinRoom_Steam *callbackResult = (Console_JoinRoom_Steam *) deferredCallbacks[i];
if (pCallback->m_EChatRoomEnterResponse==k_EChatRoomEnterResponseSuccess)
{
roomId=pCallback->m_ulSteamIDLobby;
CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
// First push to prevent being notified of ourselves
RoomMember roomMember;
roomMember.steamIDRemote=SteamUser()->GetSteamID().ConvertToUint64();
roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
roomMembersByAddr.Insert(roomMember.systemAddress,roomMember,true,_FILE_AND_LINE_);
roomMembersById.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
CallRoomCallbacks();
// In case the asynch lobby update didn't get it fast enough
uint64_t myId64=SteamUser()->GetSteamID().ConvertToUint64();
if (roomMembersById.HasData(myId64)==false)
{
roomMember.steamIDRemote=SteamMatchmaking()->GetLobbyOwner(roomId).ConvertToUint64();
roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
roomMembersByAddr.Insert(roomMember.systemAddress,roomMember,true,_FILE_AND_LINE_);
roomMembersById.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
}
}
else
{
CallCBWithResultCode(callbackResult, L2RC_Console_JoinRoom_NO_SUCH_ROOM);
}
msgFactory->Dealloc(callbackResult);
deferredCallbacks.RemoveAtIndex(i);
break;
}
}
}
bool Lobby2Client_Steam_Impl::IsCommandRunning( Lobby2MessageID msgId )
{
uint32_t i;
for (i=0; i < deferredCallbacks.GetSize(); i++)
{
if (deferredCallbacks[i]->GetID()==msgId)
{
return true;
}
}
return false;
}
void Lobby2Client_Steam_Impl::OnPersonaStateChange( PersonaStateChange_t *pCallback )
{
// callbacks are broadcast to all listeners, so we'll get this for every friend who changes state
// so make sure the user is in the lobby before acting
if ( !SteamFriends()->IsUserInSource( pCallback->m_ulSteamID, roomId ) )
return;
if ((pCallback->m_nChangeFlags & k_EPersonaChangeNameFirstSet) ||
(pCallback->m_nChangeFlags & k_EPersonaChangeName))
{
Notification_Friends_StatusChange_Steam notification;
notification.friendId=pCallback->m_ulSteamID;
const char *pchName = SteamFriends()->GetFriendPersonaName( notification.friendId );
notification.friendNewName=pchName;
CallCBWithResultCode(&notification, L2RC_SUCCESS);
}
}
void Lobby2Client_Steam_Impl::OnLobbyDataUpdate( LobbyDataUpdate_t *pCallback )
{
// callbacks are broadcast to all listeners, so we'll get this for every lobby we're requesting
if ( roomId != pCallback->m_ulSteamIDLobby )
return;
Notification_Console_UpdateRoomParameters_Steam notification;
notification.roomId=roomId;
notification.roomNewName=SteamMatchmaking()->GetLobbyData( roomId, "name" );
if (pCallback->m_bSuccess)
CallCBWithResultCode(&notification, L2RC_SUCCESS);
else
CallCBWithResultCode(&notification, L2RC_Console_GetRoomDetails_NO_ROOMS_FOUND);
}
void Lobby2Client_Steam_Impl::OnLobbyChatUpdate( LobbyChatUpdate_t *pCallback )
{
// callbacks are broadcast to all listeners, so we'll get this for every lobby we're requesting
if ( roomId != pCallback->m_ulSteamIDLobby )
return;
// Purpose: Handles users in the lobby joining or leaving ??????
CallRoomCallbacks();
}
void Lobby2Client_Steam_Impl::OnLobbyChatMessage( LobbyChatMsg_t *pCallback )
{
CSteamID speaker;
EChatEntryType entryType;
char data[2048];
int cubData=sizeof(data);
SteamMatchmaking()->GetLobbyChatEntry( roomId, pCallback->m_iChatID, &speaker, data, cubData, &entryType);
if (entryType==k_EChatEntryTypeChatMsg)
{
Notification_Console_RoomChatMessage_Steam notification;
notification.message=data;
CallCBWithResultCode(&notification, L2RC_SUCCESS);
}
}
void Lobby2Client_Steam_Impl::GetRoomMembers(DataStructures::OrderedList<uint64_t, uint64_t> &_roomMembers)
{
_roomMembers.Clear(true,_FILE_AND_LINE_);
int cLobbyMembers = SteamMatchmaking()->GetNumLobbyMembers( roomId );
for ( int i = 0; i < cLobbyMembers; i++ )
{
CSteamID steamIDLobbyMember = SteamMatchmaking()->GetLobbyMemberByIndex( roomId, i ) ;
uint64_t memberid=steamIDLobbyMember.ConvertToUint64();
_roomMembers.Insert(memberid,memberid,true,_FILE_AND_LINE_);
}
}
const char * Lobby2Client_Steam_Impl::GetRoomMemberName(uint64_t memberId)
{
return SteamFriends()->GetFriendPersonaName( memberId );
}
bool Lobby2Client_Steam_Impl::IsRoomOwner(const uint64_t cSteamID)
{
if(SteamUser()->GetSteamID() == SteamMatchmaking()->GetLobbyOwner(cSteamID))
return true;
return false;
}
bool Lobby2Client_Steam_Impl::IsInRoom(void) const
{
return roomMembersById.Size() > 0;
}
void Lobby2Client_Steam_Impl::CallRoomCallbacks()
{
DataStructures::OrderedList<uint64_t,uint64_t> currentMembers;
GetRoomMembers(currentMembers);
DataStructures::OrderedList<uint64_t, RoomMember, SteamIDAndRoomMemberComp> updatedRoomMembers;
bool anyChanges=false;
unsigned int currentMemberIndex=0, oldMemberIndex=0;
while (currentMemberIndex < currentMembers.Size() && oldMemberIndex < roomMembersById.Size())
{
if (currentMembers[currentMemberIndex]<roomMembersById[oldMemberIndex].steamIDRemote)
{
RoomMember roomMember;
roomMember.steamIDRemote=currentMembers[currentMemberIndex];
roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
updatedRoomMembers.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
anyChanges=true;
// new member
NotifyNewMember(currentMembers[currentMemberIndex], roomMember.systemAddress);
currentMemberIndex++;
}
else if (currentMembers[currentMemberIndex]>roomMembersById[oldMemberIndex].steamIDRemote)
{
anyChanges=true;
// dropped member
NotifyDroppedMember(roomMembersById[oldMemberIndex].steamIDRemote, roomMembersById[oldMemberIndex].systemAddress);
oldMemberIndex++;
}
else
{
updatedRoomMembers.Insert(roomMembersById[oldMemberIndex].steamIDRemote,roomMembersById[oldMemberIndex],true,_FILE_AND_LINE_);
currentMemberIndex++;
oldMemberIndex++;
}
}
while (oldMemberIndex < roomMembersById.Size())
{
anyChanges=true;
// dropped member
NotifyDroppedMember(roomMembersById[oldMemberIndex].steamIDRemote, roomMembersById[oldMemberIndex].systemAddress);
oldMemberIndex++;
}
while (currentMemberIndex < currentMembers.Size())
{
RoomMember roomMember;
roomMember.steamIDRemote=currentMembers[currentMemberIndex];
roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
updatedRoomMembers.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
anyChanges=true;
// new member
NotifyNewMember(currentMembers[currentMemberIndex], roomMember.systemAddress);
currentMemberIndex++;
}
if (anyChanges)
{
roomMembersById=updatedRoomMembers;
roomMembersByAddr.Clear(true, _FILE_AND_LINE_);
for (currentMemberIndex=0; currentMemberIndex < roomMembersById.Size(); currentMemberIndex++)
{
roomMembersByAddr.Insert(roomMembersById[currentMemberIndex].systemAddress, roomMembersById[currentMemberIndex], true, _FILE_AND_LINE_);
}
}
}
void Lobby2Client_Steam_Impl::NotifyNewMember(uint64_t memberId, SystemAddress remoteSystem)
{
// const char *pchName = SteamFriends()->GetFriendPersonaName( memberId );
Notification_Console_MemberJoinedRoom_Steam notification;
notification.roomId=roomId;
notification.srcMemberId=memberId;
notification.memberName=SteamFriends()->GetFriendPersonaName( memberId );
notification.remoteSystem=remoteSystem;
CallCBWithResultCode(&notification, L2RC_SUCCESS);
}
void Lobby2Client_Steam_Impl::NotifyDroppedMember(uint64_t memberId, SystemAddress remoteSystem)
{
/// const char *pchName = SteamFriends()->GetFriendPersonaName( memberId );
Notification_Console_MemberLeftRoom_Steam notification;
notification.roomId=roomId;
notification.srcMemberId=memberId;
notification.memberName=SteamFriends()->GetFriendPersonaName( memberId );
notification.remoteSystem=remoteSystem;
CallCBWithResultCode(&notification, L2RC_SUCCESS);
unsigned int i;
bool objectExists;
i = roomMembersById.GetIndexFromKey(memberId, &objectExists);
if (objectExists)
{
rakPeerInterface->CloseConnection(roomMembersById[i].systemAddress,false);
// Is this necessary?
SteamNetworking()->CloseP2PSessionWithUser( memberId );
}
}
void Lobby2Client_Steam_Impl::ClearRoom(void)
{
roomId=0;
if (SteamNetworking())
{
for (unsigned int i=0; i < roomMembersById.Size(); i++)
{
SteamNetworking()->CloseP2PSessionWithUser( roomMembersById[i].steamIDRemote );
}
}
roomMembersById.Clear(true,_FILE_AND_LINE_);
roomMembersByAddr.Clear(true,_FILE_AND_LINE_);
}
void Lobby2Client_Steam_Impl::OnP2PSessionRequest( P2PSessionRequest_t *pCallback )
{
// we'll accept a connection from anyone
SteamNetworking()->AcceptP2PSessionWithUser( pCallback->m_steamIDRemote );
}
void Lobby2Client_Steam_Impl::OnP2PSessionConnectFail( P2PSessionConnectFail_t *pCallback )
{
(void) pCallback;
// we've sent a packet to the user, but it never got through
// we can just use the normal timeout
}
void Lobby2Client_Steam_Impl::NotifyLeaveRoom(void)
{
ClearRoom();
}
int Lobby2Client_Steam_Impl::RakNetSendTo( const char *data, int length, const SystemAddress &systemAddress )
{
bool objectExists;
unsigned int i = roomMembersByAddr.GetIndexFromKey(systemAddress, &objectExists);
if (objectExists)
{
if (SteamNetworking()->SendP2PPacket(roomMembersByAddr[i].steamIDRemote, data, length, k_EP2PSendUnreliable))
return length;
else
return 0;
}
else if (systemAddress.GetPort()!=STEAM_UNUSED_PORT)
{
// return SocketLayer::SendTo_PC(s,data,length,systemAddress,_FILE_AND_LINE_);
return -1;
}
return 0;
}
int Lobby2Client_Steam_Impl::RakNetRecvFrom( char dataOut[ MAXIMUM_MTU_SIZE ], SystemAddress *senderOut, bool calledFromMainThread)
{
(void) calledFromMainThread;
uint32 pcubMsgSize;
if (SteamNetworking() && SteamNetworking()->IsP2PPacketAvailable(&pcubMsgSize))
{
CSteamID psteamIDRemote;
if (SteamNetworking()->ReadP2PPacket(dataOut, MAXIMUM_MTU_SIZE, &pcubMsgSize, &psteamIDRemote))
{
uint64_t steamIDRemote64=psteamIDRemote.ConvertToUint64();
unsigned int i;
bool objectExists;
i = roomMembersById.GetIndexFromKey(steamIDRemote64, &objectExists);
if (objectExists)
{
*senderOut=roomMembersById[i].systemAddress;
}
return pcubMsgSize;
}
}
return 0;
}
void Lobby2Client_Steam_Impl::OnRakPeerShutdown(void)
{
ClearRoom();
}
void Lobby2Client_Steam_Impl::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
(void) lostConnectionReason;
(void) rakNetGUID;
bool objectExists;
unsigned int i = roomMembersByAddr.GetIndexFromKey(systemAddress, &objectExists);
if (objectExists)
{
uint64_t steamIDRemote = roomMembersByAddr[i].steamIDRemote;
SteamNetworking()->CloseP2PSessionWithUser( steamIDRemote );
roomMembersByAddr.RemoveAtIndex(i);
i = roomMembersById.GetIndexFromKey(steamIDRemote, &objectExists);
RakAssert(objectExists);
roomMembersById.RemoveAtIndex(i);
}
}
void Lobby2Client_Steam_Impl::OnFailedConnectionAttempt(Packet *packet, PI2_FailedConnectionAttemptReason failedConnectionAttemptReason)
{
(void) failedConnectionAttemptReason;
bool objectExists;
unsigned int i = roomMembersByAddr.GetIndexFromKey(packet->systemAddress, &objectExists);
if (objectExists)
{
uint64_t steamIDRemote = roomMembersByAddr[i].steamIDRemote;
SteamNetworking()->CloseP2PSessionWithUser( steamIDRemote );
roomMembersByAddr.RemoveAtIndex(i);
i = roomMembersById.GetIndexFromKey(steamIDRemote, &objectExists);
RakAssert(objectExists);
roomMembersById.RemoveAtIndex(i);
}
}
void Lobby2Client_Steam_Impl::OnAttach(void)
{
nextFreeSystemAddress=(uint32_t) rakPeerInterface->GetMyGUID().g;
// If this asserts, call RakPeer::Startup() before attaching Lobby2Client_Steam
DataStructures::List<RakNetSocket2* > sockets;
rakPeerInterface->GetSockets(sockets);
RakAssert(sockets.Size());
((RNS2_Windows*)sockets[0])->SetSocketLayerOverride(this);
}
void Lobby2Client_Steam_Impl::OnDetach(void)
{
DataStructures::List<RakNetSocket2* > sockets;
rakPeerInterface->GetSockets(sockets);
RakAssert(sockets.Size());
((RNS2_Windows*)sockets[0])->SetSocketLayerOverride(nullptr);
}

View File

@ -0,0 +1,115 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_CLIENT_STEAM_IMPL_H
#define __LOBBY_2_CLIENT_STEAM_IMPL_H
#pragma warning( push )
#pragma warning(disable:4127) // conditional expression is constant (with Steamworks 1.23a)
#include "steam_api.h"
#pragma warning( pop )
#include "Lobby2Client_Steam.h"
#include "slikenet/DS_Multilist.h"
#include "slikenet/SocketLayer.h"
#include "slikenet/DS_OrderedList.h"
namespace SLNet
{
struct Lobby2Message;
#define STEAM_UNUSED_PORT 1
class RAK_DLL_EXPORT Lobby2Client_Steam_Impl : public Lobby2Client_Steam, public SocketLayerOverride
{
public:
Lobby2Client_Steam_Impl();
virtual ~Lobby2Client_Steam_Impl();
/// Send a command to the server
/// \param[in] msg The message that represents the command
virtual void SendMsg(Lobby2Message *msg);
// Base class implementation
virtual void Update(void);
virtual void OnLobbyMatchListCallback( LobbyMatchList_t *pCallback, bool bIOFailure );
virtual void OnLobbyCreated( LobbyCreated_t *pCallback, bool bIOFailure );
virtual void OnLobbyJoined( LobbyEnter_t *pCallback, bool bIOFailure );
virtual bool IsCommandRunning( Lobby2MessageID msgId );
virtual void GetRoomMembers(DataStructures::OrderedList<uint64_t, uint64_t> &_roomMembers);
virtual const char * GetRoomMemberName(uint64_t memberId);
virtual bool IsRoomOwner(const uint64_t cSteamID);
virtual bool IsInRoom(void) const;
virtual uint64_t GetNumRoomMembers(const uint64_t roomid){return SteamMatchmaking()->GetNumLobbyMembers(roomid);}
virtual uint64_t GetMyUserID(void){return SteamUser()->GetSteamID().ConvertToUint64();}
virtual const char* GetMyUserPersonalName(void) {return SteamFriends()->GetPersonaName();}
virtual void NotifyLeaveRoom(void);
// Returns 0 if none
virtual uint64_t GetRoomID(void) const {return roomId;}
/// Called when SendTo would otherwise occur.
virtual int RakNetSendTo( const char *data, int length, const SystemAddress &systemAddress );
/// Called when RecvFrom would otherwise occur. Return number of bytes read. Write data into dataOut
virtual int RakNetRecvFrom( char dataOut[ MAXIMUM_MTU_SIZE ], SystemAddress *senderOut, bool calledFromMainThread);
virtual void OnRakPeerShutdown(void);
virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
virtual void OnFailedConnectionAttempt(Packet *packet, PI2_FailedConnectionAttemptReason failedConnectionAttemptReason);
virtual void OnAttach(void);
virtual void OnDetach(void);
struct RoomMember
{
SystemAddress systemAddress;
uint64_t steamIDRemote;
};
static int SystemAddressAndRoomMemberComp( const SystemAddress &key, const RoomMember &data );
static int SteamIDAndRoomMemberComp( const uint64_t &key, const RoomMember &data );
protected:
void CallCBWithResultCode(Lobby2Message *msg, Lobby2ResultCode rc);
void PushDeferredCallback(Lobby2Message *msg);
void CallRoomCallbacks(void);
void NotifyNewMember(uint64_t memberId, SystemAddress remoteSystem);
void NotifyDroppedMember(uint64_t memberId, SystemAddress remoteSystem);
void CallCompletedCallbacks(void);
STEAM_CALLBACK( Lobby2Client_Steam_Impl, OnLobbyDataUpdatedCallback, LobbyDataUpdate_t, m_CallbackLobbyDataUpdated );
STEAM_CALLBACK( Lobby2Client_Steam_Impl, OnPersonaStateChange, PersonaStateChange_t, m_CallbackPersonaStateChange );
STEAM_CALLBACK( Lobby2Client_Steam_Impl, OnLobbyDataUpdate, LobbyDataUpdate_t, m_CallbackLobbyDataUpdate );
STEAM_CALLBACK( Lobby2Client_Steam_Impl, OnLobbyChatUpdate, LobbyChatUpdate_t, m_CallbackChatDataUpdate );
STEAM_CALLBACK( Lobby2Client_Steam_Impl, OnLobbyChatMessage, LobbyChatMsg_t, m_CallbackChatMessageUpdate );
STEAM_CALLBACK( Lobby2Client_Steam_Impl, OnP2PSessionRequest, P2PSessionRequest_t, m_CallbackP2PSessionRequest );
STEAM_CALLBACK( Lobby2Client_Steam_Impl, OnP2PSessionConnectFail, P2PSessionConnectFail_t, m_CallbackP2PSessionConnectFail );
DataStructures::Multilist<ML_UNORDERED_LIST, Lobby2Message *, uint64_t > deferredCallbacks;
uint64_t roomId;
DataStructures::OrderedList<SystemAddress, RoomMember, SystemAddressAndRoomMemberComp> roomMembersByAddr;
DataStructures::OrderedList<uint64_t, RoomMember, SteamIDAndRoomMemberComp> roomMembersById;
DataStructures::Multilist<ML_ORDERED_LIST, uint64_t> rooms;
void ClearRoom(void);
uint32_t nextFreeSystemAddress;
};
};
#endif

View File

@ -0,0 +1,150 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Lobby2Message_Steam.h"
#pragma warning( push )
#pragma warning(disable:4127) // conditional expression is constant (with Steamworks 1.23a)
#include "steam_api.h"
#pragma warning( pop )
#include "Lobby2Client_Steam_Impl.h"
using namespace SLNet;
bool Client_Login_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
(void) client;
if ( !SteamAPI_Init() )
resultCode=L2RC_GENERAL_ERROR;
else
resultCode=L2RC_SUCCESS;
return true; // Done immediately
}
bool Client_Logoff_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
Lobby2Client_Steam_Impl *steam = (Lobby2Client_Steam_Impl *)client;
steam->NotifyLeaveRoom();
resultCode=L2RC_SUCCESS;
SteamAPI_Shutdown();
return true; // Done immediately
}
Console_SearchRooms_Steam::Console_SearchRooms_Steam()
{
m_SteamCallResultLobbyMatchList = SLNet::OP_NEW<CCallResult<Lobby2Client_Steam_Impl, LobbyMatchList_t> > (_FILE_AND_LINE_);
}
Console_SearchRooms_Steam::~Console_SearchRooms_Steam()
{
// Cast to make sure destructor gets called
SLNet::OP_DELETE((CCallResult<Lobby2Client_Steam_Impl, LobbyMatchList_t>*)m_SteamCallResultLobbyMatchList, _FILE_AND_LINE_);
}
bool Console_SearchRooms_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
(void) client;
requestId = SteamMatchmaking()->RequestLobbyList();
((CCallResult<Lobby2Client_Steam_Impl, LobbyMatchList_t>*)m_SteamCallResultLobbyMatchList)->Set( requestId, (SLNet::Lobby2Client_Steam_Impl*) client, &Lobby2Client_Steam_Impl::OnLobbyMatchListCallback );
return false; // Asynch
}
void Console_SearchRooms_Steam::DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Console_SearchRooms::DebugMsg(out);
return;
}
out.Set("%i rooms found", roomNames.GetSize());
for (DataStructures::DefaultIndexType i=0; i < roomNames.GetSize(); i++)
{
out += SLNet::RakString("\n%i. %s. ID=%" PRINTF_64_BIT_MODIFIER "u", i+1, roomNames[i].C_String(), roomIds[i]);
}
}
bool Console_GetRoomDetails_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
(void) client;
SteamMatchmaking()->RequestLobbyData( roomId );
return false; // Asynch
}
Console_CreateRoom_Steam::Console_CreateRoom_Steam()
{
m_SteamCallResultLobbyCreated = SLNet::OP_NEW<CCallResult<Lobby2Client_Steam_Impl, LobbyCreated_t> >(_FILE_AND_LINE_);
}
Console_CreateRoom_Steam::~Console_CreateRoom_Steam()
{
// Cast to make sure destructor gets called
SLNet::OP_DELETE((CCallResult<Lobby2Client_Steam_Impl, LobbyCreated_t>*)m_SteamCallResultLobbyCreated, _FILE_AND_LINE_);
}
bool Console_CreateRoom_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
if (roomIsPublic)
requestId = SteamMatchmaking()->CreateLobby( k_ELobbyTypePublic, publicSlots );
else
requestId = SteamMatchmaking()->CreateLobby( k_ELobbyTypeFriendsOnly, publicSlots );
// set the function to call when this completes
((CCallResult<Lobby2Client_Steam_Impl, LobbyCreated_t>*)m_SteamCallResultLobbyCreated)->Set( requestId, (SLNet::Lobby2Client_Steam_Impl*) client, &Lobby2Client_Steam_Impl::OnLobbyCreated );
return false; // Asynch
}
Console_JoinRoom_Steam::Console_JoinRoom_Steam()
{
m_SteamCallResultLobbyEntered = SLNet::OP_NEW<CCallResult<Lobby2Client_Steam_Impl, LobbyEnter_t> > (_FILE_AND_LINE_);
}
Console_JoinRoom_Steam::~Console_JoinRoom_Steam()
{
// Cast to make sure destructor gets called
SLNet::OP_DELETE((CCallResult<Lobby2Client_Steam_Impl, LobbyEnter_t>*)m_SteamCallResultLobbyEntered, _FILE_AND_LINE_);
}
bool Console_JoinRoom_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
requestId = SteamMatchmaking()->JoinLobby( roomId );
// set the function to call when this completes
((CCallResult<Lobby2Client_Steam_Impl, LobbyEnter_t>*)m_SteamCallResultLobbyEntered)->Set( requestId, (SLNet::Lobby2Client_Steam_Impl*) client, &Lobby2Client_Steam_Impl::OnLobbyJoined );
return false; // Asynch
}
bool Console_LeaveRoom_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
SteamMatchmaking()->LeaveLobby( roomId );
Lobby2Client_Steam_Impl *steam = (Lobby2Client_Steam_Impl *)client;
steam->NotifyLeaveRoom();
resultCode=L2RC_SUCCESS;
return true; // Synchronous
}
bool Console_SendRoomChatMessage_Steam::ClientImpl(SLNet::Lobby2Plugin *client)
{
(void) client;
SteamMatchmaking()->SendLobbyChatMsg(roomId, message.C_String(), (int) message.GetLength()+1);
// ISteamMatchmaking.h
/*
// Broadcasts a chat message to the all the users in the lobby
// users in the lobby (including the local user) will receive a LobbyChatMsg_t callback
// returns true if the message is successfully sent
// pvMsgBody can be binary or text data, up to 4k
// if pvMsgBody is text, cubMsgBody should be strlen( text ) + 1, to include the null terminator
virtual bool SendLobbyChatMsg( CSteamID steamIDLobby, const void *pvMsgBody, int cubMsgBody ) = 0;
*/
resultCode=L2RC_SUCCESS;
return true; // Synchronous
}

View File

@ -0,0 +1,336 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifndef __LOBBY_2_MESSAGE_STEAM_H
#define __LOBBY_2_MESSAGE_STEAM_H
#include "Lobby2Message.h"
#include "slikenet/DS_Multilist.h"
#include "Lobby2Client_Steam.h"
namespace SLNet
{
#define __L2_MSG_DB_HEADER(__NAME__,__DB__) \
struct __NAME__##_##__DB__ : public __NAME__
__L2_MSG_DB_HEADER(Client_Login, Steam)
{
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Client_Login::DebugMsg(out);
return;
}
out.Set("Login success");
}
};
__L2_MSG_DB_HEADER(Client_Logoff, Steam)
{
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Client_Logoff::DebugMsg(out);
return;
}
out.Set("Logoff success");
}
};
__L2_MSG_DB_HEADER(Console_SearchRooms, Steam)
{
Console_SearchRooms_Steam();
virtual ~Console_SearchRooms_Steam();
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const;
// Output
// Use CConsoleCommand_GetRoomDetails to get room names for unknown rooms, which will have blank names
DataStructures::Multilist<ML_UNORDERED_LIST, SLNet::RakString> roomNames;
// Type of uint64_ts is uint64_t
DataStructures::Multilist<ML_UNORDERED_LIST, uint64_t> roomIds;
/// \internal
// uint32_t is LobbyMatchList_t
// CCallResult<Lobby2Client_Steam, uint32_t> m_SteamCallResultLobbyMatchList;
void *m_SteamCallResultLobbyMatchList;
};
__L2_MSG_DB_HEADER(Console_GetRoomDetails, Steam)
{
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Console_GetRoomDetails::DebugMsg(out);
return;
}
out.Set("GetRoomDetails: roomName=%s for id %" PRINTF_64_BIT_MODIFIER "u", roomName.C_String(), roomId);
}
/// Input
uint64_t roomId;
/// Output
SLNet::RakString roomName;
};
__L2_MSG_DB_HEADER(Console_CreateRoom, Steam)
{
Console_CreateRoom_Steam();
virtual ~Console_CreateRoom_Steam();
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Console_CreateRoom::DebugMsg(out);
return;
}
out.Set("Console_CreateRoom: roomName %s created for id %" PRINTF_64_BIT_MODIFIER "u", roomName.C_String(), roomId);
}
/// Input
/// If public, anyone can join. Else friends only
bool roomIsPublic;
SLNet::RakString roomName;
/// Output
uint64_t roomId;
/// \internal
// CCallResult<Lobby2Client_Steam, LobbyCreated_t> m_SteamCallResultLobbyCreated;
void *m_SteamCallResultLobbyCreated;
};
__L2_MSG_DB_HEADER(Console_JoinRoom, Steam)
{
Console_JoinRoom_Steam();
virtual ~Console_JoinRoom_Steam();
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Console_JoinRoom::DebugMsg(out);
return;
}
out.Set("Console_JoinRoom: Joined id %" PRINTF_64_BIT_MODIFIER "u", roomId);
}
/// Input
uint64_t roomId;
/// \internal
//CCallResult<Lobby2Client_Steam, LobbyEnter_t> m_SteamCallResultLobbyEntered;
void *m_SteamCallResultLobbyEntered;
};
__L2_MSG_DB_HEADER(Console_LeaveRoom, Steam)
{
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Console_LeaveRoom::DebugMsg(out);
return;
}
out.Set("Left room %" PRINTF_64_BIT_MODIFIER "u", roomId);
}
/// Input
uint64_t roomId;
};
__L2_MSG_DB_HEADER(Console_SendRoomChatMessage, Steam)
{
virtual bool ClientImpl(SLNet::Lobby2Plugin *client);
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Console_SendRoomChatMessage::DebugMsg(out);
return;
}
out.Set("Sent %s to room %" PRINTF_64_BIT_MODIFIER "u", message.C_String(), roomId);
}
/// Input
uint64_t roomId;
SLNet::RakString message;
};
__L2_MSG_DB_HEADER(Notification_Friends_StatusChange, Steam)
{
uint64_t friendId;
SLNet::RakString friendNewName;
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Notification_Friends_StatusChange::DebugMsg(out);
return;
}
out.Set("Friend renamed to %s with ID %" PRINTF_64_BIT_MODIFIER "u", friendNewName.C_String(), friendId);
}
};
__L2_MSG_DB_HEADER(Notification_Console_UpdateRoomParameters, Steam)
{
uint64_t roomId;
SLNet::RakString roomNewName;
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Notification_Console_UpdateRoomParameters::DebugMsg(out);
return;
}
out.Set("RoomStateChanged: Room named %s with ID %" PRINTF_64_BIT_MODIFIER "u", roomNewName.C_String(), roomId);
}
};
__L2_MSG_DB_HEADER(Notification_Console_MemberJoinedRoom, Steam)
{
uint64_t roomId;
uint64_t srcMemberId;
SLNet::RakString memberName;
SystemAddress remoteSystem;
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Notification_Console_MemberJoinedRoom::DebugMsg(out);
return;
}
out.Set("MemberJoinedRoom: Member named %s and ID %" PRINTF_64_BIT_MODIFIER "u joined room with ID %" PRINTF_64_BIT_MODIFIER "u", memberName.C_String(), srcMemberId, roomId);
}
};
__L2_MSG_DB_HEADER(Notification_Console_MemberLeftRoom, Steam)
{
uint64_t roomId;
uint64_t srcMemberId;
SLNet::RakString memberName;
SystemAddress remoteSystem;
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Notification_Console_MemberLeftRoom::DebugMsg(out);
return;
}
out.Set("MemberLeftRoom: Member named %s and ID %" PRINTF_64_BIT_MODIFIER "u left room with ID %" PRINTF_64_BIT_MODIFIER "u", memberName.C_String(), srcMemberId, roomId);
}
};
__L2_MSG_DB_HEADER(Notification_Console_RoomChatMessage, Steam)
{
SLNet::RakString message;
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Notification_Console_RoomChatMessage::DebugMsg(out);
return;
}
out=message;
}
};
/*
__L2_MSG_DB_HEADER(Notification_Console_RoomMemberConnectivityUpdate, Steam)
{
bool succeeded;
SystemAddress remoteSystem;
virtual void DebugMsg(SLNet::RakString &out) const
{
if (resultCode!=L2RC_SUCCESS)
{
Notification_Console_RoomMemberConnectivityUpdate::DebugMsg(out);
return;
}
if (succeeded)
{
out.Set("Signaling to %s succeeded.", remoteSystem.ToString(true));
}
else
{
out.Set("Signaling to %s failed.", remoteSystem.ToString(true));
}
}
};
*/
// --------------------------------------------- Database specific factory class for all messages --------------------------------------------
#define __L2_MSG_FACTORY_IMPL(__NAME__,__DB__) {case L2MID_##__NAME__ : Lobby2Message *m = SLNet::OP_NEW< __NAME__##_##__DB__ >(_FILE_AND_LINE_) ; return m;}
struct Lobby2MessageFactory_Steam : public Lobby2MessageFactory
{
Lobby2MessageFactory_Steam() {}
virtual ~Lobby2MessageFactory_Steam() {}
virtual Lobby2Message *Alloc(Lobby2MessageID id)
{
switch (id)
{
__L2_MSG_FACTORY_IMPL(Client_Login, Steam);
__L2_MSG_FACTORY_IMPL(Client_Logoff, Steam);
__L2_MSG_FACTORY_IMPL(Console_SearchRooms, Steam);
__L2_MSG_FACTORY_IMPL(Console_GetRoomDetails, Steam);
__L2_MSG_FACTORY_IMPL(Console_CreateRoom, Steam);
__L2_MSG_FACTORY_IMPL(Console_JoinRoom, Steam);
__L2_MSG_FACTORY_IMPL(Console_LeaveRoom, Steam);
__L2_MSG_FACTORY_IMPL(Console_SendRoomChatMessage, Steam);
__L2_MSG_FACTORY_IMPL(Notification_Friends_StatusChange, Steam);
__L2_MSG_FACTORY_IMPL(Notification_Console_UpdateRoomParameters, Steam);
__L2_MSG_FACTORY_IMPL(Notification_Console_MemberJoinedRoom, Steam);
__L2_MSG_FACTORY_IMPL(Notification_Console_MemberLeftRoom, Steam);
__L2_MSG_FACTORY_IMPL(Notification_Console_RoomChatMessage, Steam);
//__L2_MSG_FACTORY_IMPL(Notification_Console_RoomMemberConnectivityUpdate, Steam);
default:
return Lobby2MessageFactory::Alloc(id);
};
};
};
}; // namespace SLNet
#endif

View File

@ -0,0 +1,376 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D54E74A9-6874-425F-9FCE-6EF8C5563343}</ProjectGuid>
<RootNamespace>steamconsole</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\;..\;..\..\..\Source;C:\Steam\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;USE_STEAM_SOCKET_FUNCTIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>steam_api.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Steam\redistributable_bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>copy C:\Steam\redistributable_bin\*.dll .\
copy C:\Steam\SteamworksExample\steam_appid.txt .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.\;..\;..\..\..\Source;C:\Steam\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;USE_STEAM_SOCKET_FUNCTIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>steam_api.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Steam\redistributable_bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>copy C:\Steam\redistributable_bin\*.dll .\
copy C:\Steam\SteamworksExample\steam_appid.txt .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Source\src\_FindFirst.cpp" />
<ClCompile Include="..\..\..\Source\src\AsynchronousFileIO.cpp" />
<ClCompile Include="..\..\..\Source\src\AutoRPC.cpp" />
<ClCompile Include="..\..\..\Source\src\BigInt.cpp" />
<ClCompile Include="..\..\..\Source\src\BitStream.cpp" />
<ClCompile Include="..\..\..\Source\src\BitStream_NoTemplate.cpp" />
<ClCompile Include="..\..\..\Source\src\CheckSum.cpp" />
<ClCompile Include="..\..\..\Source\src\CommandParserInterface.cpp" />
<ClCompile Include="..\..\..\Source\src\ConnectionGraph.cpp" />
<ClCompile Include="..\..\..\Source\src\ConnectionGraph2.cpp" />
<ClCompile Include="..\..\..\Source\src\ConsoleServer.cpp" />
<ClCompile Include="..\..\..\Source\src\DataBlockEncryptor.cpp" />
<ClCompile Include="..\..\..\Source\src\DataCompressor.cpp" />
<ClCompile Include="..\..\..\Source\src\DirectoryDeltaTransfer.cpp" />
<ClCompile Include="..\..\..\Source\src\DS_BytePool.cpp" />
<ClCompile Include="..\..\..\Source\src\DS_ByteQueue.cpp" />
<ClCompile Include="..\..\..\Source\src\DS_HuffmanEncodingTree.cpp" />
<ClCompile Include="..\..\..\Source\src\DS_Table.cpp" />
<ClCompile Include="..\..\..\Source\src\EmailSender.cpp" />
<ClCompile Include="..\..\..\Source\src\EncodeClassName.cpp" />
<ClCompile Include="..\..\..\Source\src\EpochTimeToString.cpp" />
<ClCompile Include="..\..\..\Source\src\ExtendedOverlappedPool.cpp" />
<ClCompile Include="..\..\..\Source\src\FileList.cpp" />
<ClCompile Include="..\..\..\Source\src\FileListTransfer.cpp" />
<ClCompile Include="..\..\..\Source\src\FileOperations.cpp" />
<ClCompile Include="..\..\..\Source\src\FormatString.cpp" />
<ClCompile Include="..\..\..\Source\src\FullyConnectedMesh.cpp" />
<ClCompile Include="..\..\..\Source\src\FullyConnectedMesh2.cpp" />
<ClCompile Include="..\..\..\Source\src\FunctionThread.cpp" />
<ClCompile Include="..\..\..\Source\src\Gen_RPC8.cpp" />
<ClCompile Include="..\..\..\Source\src\GetTime.cpp" />
<ClCompile Include="..\..\..\Source\src\gettimeofday.cpp" />
<ClCompile Include="..\..\..\Source\src\GridSectorizer.cpp" />
<ClCompile Include="..\..\..\Source\src\HTTPConnection.cpp" />
<ClCompile Include="..\..\..\Source\src\IncrementalReadInterface.cpp" />
<ClCompile Include="..\..\..\Source\src\InlineFunctor.cpp" />
<ClCompile Include="..\..\..\Source\src\Itoa.cpp" />
<ClCompile Include="..\..\..\Source\src\LightweightDatabaseClient.cpp" />
<ClCompile Include="..\..\..\Source\src\LightweightDatabaseCommon.cpp" />
<ClCompile Include="..\..\..\Source\src\LightweightDatabaseServer.cpp" />
<ClCompile Include="..\..\..\Source\src\LinuxStrings.cpp" />
<ClCompile Include="..\..\..\Source\src\LogCommandParser.cpp" />
<ClCompile Include="..\..\..\Source\src\MessageFilter.cpp" />
<ClCompile Include="..\..\..\Source\src\NatPunchthroughClient.cpp" />
<ClCompile Include="..\..\..\Source\src\NatPunchthroughServer.cpp" />
<ClCompile Include="..\..\..\Source\src\NetworkIDManager.cpp" />
<ClCompile Include="..\..\..\Source\src\NetworkIDObject.cpp" />
<ClCompile Include="..\..\..\Source\src\PacketConsoleLogger.cpp" />
<ClCompile Include="..\..\..\Source\src\PacketFileLogger.cpp" />
<ClCompile Include="..\..\..\Source\src\PacketizedTCP.cpp" />
<ClCompile Include="..\..\..\Source\src\PacketLogger.cpp" />
<ClCompile Include="..\..\..\Source\src\PacketOutputWindowLogger.cpp" />
<ClCompile Include="..\..\..\Source\src\PluginInterface.cpp" />
<ClCompile Include="..\..\..\Source\src\PluginInterface2.cpp" />
<ClCompile Include="..\..\..\Source\src\RakMemoryOverride.cpp" />
<ClCompile Include="..\..\..\Source\src\RakNetCommandParser.cpp" />
<ClCompile Include="..\..\..\Source\src\RakNetSocket.cpp" />
<ClCompile Include="..\..\..\Source\src\RakNetStatistics.cpp" />
<ClCompile Include="..\..\..\Source\src\RakNetTransport.cpp" />
<ClCompile Include="..\..\..\Source\src\RakNetTransport2.cpp" />
<ClCompile Include="..\..\..\Source\src\RakNetTypes.cpp" />
<ClCompile Include="..\..\..\Source\src\RakNetworkFactory.cpp" />
<ClCompile Include="..\..\..\Source\src\RakPeer.cpp" />
<ClCompile Include="..\..\..\Source\src\RakSleep.cpp" />
<ClCompile Include="..\..\..\Source\src\RakString.cpp" />
<ClCompile Include="..\..\..\Source\src\RakThread.cpp" />
<ClCompile Include="..\..\..\Source\src\Rand.cpp" />
<ClCompile Include="..\..\..\Source\src\ReadyEvent.cpp" />
<ClCompile Include="..\..\..\Source\src\ReliabilityLayer.cpp" />
<ClCompile Include="..\..\..\Source\src\ReplicaManager.cpp" />
<ClCompile Include="..\..\..\Source\src\ReplicaManager2.cpp" />
<ClCompile Include="..\..\..\Source\src\ReplicaManager3.cpp" />
<ClCompile Include="..\..\..\Source\src\rijndael.cpp" />
<ClCompile Include="..\..\..\Source\src\Router.cpp" />
<ClCompile Include="..\..\..\Source\src\Router2.cpp" />
<ClCompile Include="..\..\..\Source\src\RPCMap.cpp" />
<ClCompile Include="..\..\..\Source\src\RSACrypt.cpp" />
<ClCompile Include="..\..\..\Source\src\DR_SHA1.cpp" />
<ClCompile Include="..\..\..\Source\src\SimpleMutex.cpp" />
<ClCompile Include="..\..\..\Source\src\SocketLayer.cpp" />
<ClCompile Include="..\..\..\Source\src\StringCompressor.cpp" />
<ClCompile Include="..\..\..\Source\src\StringTable.cpp" />
<ClCompile Include="..\..\..\Source\src\SuperFastHash.cpp" />
<ClCompile Include="..\..\..\Source\src\SystemAddressList.cpp" />
<ClCompile Include="..\..\..\Source\src\TableSerializer.cpp" />
<ClCompile Include="..\..\..\Source\src\TCPInterface.cpp" />
<ClCompile Include="..\..\..\Source\src\TelnetTransport.cpp" />
<ClCompile Include="..\..\..\Source\src\ThreadsafePacketLogger.cpp" />
<ClCompile Include="..\..\..\Source\src\UDPForwarder.cpp" />
<ClCompile Include="..\..\..\Source\src\UDPProxyClient.cpp" />
<ClCompile Include="..\..\..\Source\src\UDPProxyCoordinator.cpp" />
<ClCompile Include="..\..\..\Source\src\UDPProxyServer.cpp" />
<ClCompile Include="..\..\..\Source\src\WSAStartupSingleton.cpp" />
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Client.cpp" />
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Client_Steam.cpp" />
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Message.cpp" />
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Message_Steam.cpp" />
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Plugin.cpp" />
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2ResultCode.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Source\include\slikenet\_FindFirst.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\AsynchronousFileIO.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\AutopatcherPatchContext.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\AutopatcherRepositoryInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\AutoRPC.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\BigInt.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\BitStream.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\BitStream_NoTemplate.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\CheckSum.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ClientContextStruct.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\CommandParserInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ConnectionGraph.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ConnectionGraph2.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ConsoleServer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DataBlockEncryptor.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DataCompressor.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DirectoryDeltaTransfer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_BinarySearchTree.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_BPlusTree.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_BytePool.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_ByteQueue.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Heap.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_HuffmanEncodingTree.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_HuffmanEncodingTreeFactory.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_HuffmanEncodingTreeNode.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_LinkedList.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_List.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Map.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_MemoryPool.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Multilist.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_OrderedChannelHeap.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_OrderedList.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Queue.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_QueueLinkedList.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_RangeList.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Table.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Tree.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DS_WeightedGraph.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\EmailSender.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\EpochTimeToString.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Export.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ExtendedOverlappedPool.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FileList.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FileListNodeContext.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FileListTransfer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FileListTransferCBInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FileOperations.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FormatString.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FullyConnectedMesh.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FullyConnectedMesh2.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\FunctionThread.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Gen_RPC8.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\GetTime.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\gettimeofday.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\GridSectorizer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\HTTPConnection.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\IncrementalReadInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\InlineFunctor.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\InternalPacket.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Itoa.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Kbhit.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\LightweightDatabaseClient.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\LightweightDatabaseCommon.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\LightweightDatabaseServer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\LinuxStrings.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\LogCommandParser.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\MessageFilter.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\MessageIdentifiers.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\MTUSize.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\NativeTypes.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\NatPunchthroughClient.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\NatPunchthroughServer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\NetworkIDManager.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\NetworkIDObject.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PacketConsoleLogger.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PacketFileLogger.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PacketizedTCP.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PacketLogger.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PacketOutputWindowLogger.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PacketPool.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PacketPriority.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Platform.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PluginInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\PluginInterface2.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\alloca.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\assert.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\memoryoverride.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\commandparser.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\defines.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\smartptr.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\socket.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\statistics.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\time.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\transport.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\transport2.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\types.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\version.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\peer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\peerinterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\sleep.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\string.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\thread.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Rand.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ReadyEvent.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\RefCountedObj.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ReliabilityLayer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Replica.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaEnums.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaManager.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaManager2.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaManager3.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Rijndael-Boxes.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Rijndael.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Router.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\Router2.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\RouterInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\RPCMap.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\RPCNode.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\RSACrypt.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\DR_SHA1.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\SimpleMutex.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\SimpleTCPServer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\SingleProducerConsumer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\SocketIncludes.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\SocketLayer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\StringCompressor.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\StringTable.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\SuperFastHash.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\SystemAddressList.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\TableSerializer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\TCPInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\TelnetTransport.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ThreadPool.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\ThreadsafePacketLogger.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\TransportInterface.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\UDPForwarder.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyClient.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyCommon.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyCoordinator.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyServer.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\WindowsIncludes.h" />
<ClInclude Include="..\..\..\Source\include\slikenet\WSAStartupSingleton.h" />
<ClInclude Include="C:\Steam\public\steam\isteamapps.h" />
<ClInclude Include="C:\Steam\public\steam\isteamclient.h" />
<ClInclude Include="C:\Steam\public\steam\isteamfriends.h" />
<ClInclude Include="C:\Steam\public\steam\isteamgameserver.h" />
<ClInclude Include="C:\Steam\public\steam\isteammasterserverupdater.h" />
<ClInclude Include="C:\Steam\public\steam\isteammatchmaking.h" />
<ClInclude Include="C:\Steam\public\steam\isteamnetworking.h" />
<ClInclude Include="C:\Steam\public\steam\isteamremotestorage.h" />
<ClInclude Include="C:\Steam\public\steam\isteamuser.h" />
<ClInclude Include="C:\Steam\public\steam\isteamuserstats.h" />
<ClInclude Include="C:\Steam\public\steam\isteamutils.h" />
<ClInclude Include="C:\Steam\public\steam\matchmakingtypes.h" />
<ClInclude Include="C:\Steam\public\steam\steam_api.h" />
<ClInclude Include="C:\Steam\public\steam\steam_gameserver.h" />
<ClInclude Include="C:\Steam\public\steam\steamclientpublic.h" />
<ClInclude Include="C:\Steam\public\steam\steamtypes.h" />
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Client.h" />
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Client_Steam.h" />
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Message.h" />
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Message_Steam.h" />
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Plugin.h" />
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2ResultCode.h" />
</ItemGroup>
<ItemGroup>
<None Include="readme.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,811 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="RakNet">
<UniqueIdentifier>{e1041313-c177-4742-a818-f020c6aee669}</UniqueIdentifier>
</Filter>
<Filter Include="Steam">
<UniqueIdentifier>{2d9abebe-e69a-45df-9713-54f601e1913b}</UniqueIdentifier>
</Filter>
<Filter Include="Lobby2">
<UniqueIdentifier>{8c10e916-087a-4426-98dc-a3da5d86026a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Source\src\_FindFirst.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\AsynchronousFileIO.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\AutoRPC.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\BigInt.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\BitStream.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\BitStream_NoTemplate.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\CheckSum.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\CommandParserInterface.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ConnectionGraph.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ConnectionGraph2.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ConsoleServer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DataBlockEncryptor.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DataCompressor.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DirectoryDeltaTransfer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DS_BytePool.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DS_ByteQueue.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DS_HuffmanEncodingTree.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DS_Table.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\EmailSender.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\EncodeClassName.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\EpochTimeToString.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ExtendedOverlappedPool.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\FileList.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\FileListTransfer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\FileOperations.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\FormatString.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\FullyConnectedMesh.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\FullyConnectedMesh2.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\FunctionThread.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\Gen_RPC8.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\GetTime.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\gettimeofday.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\GridSectorizer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\HTTPConnection.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\IncrementalReadInterface.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\InlineFunctor.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\Itoa.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\LightweightDatabaseClient.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\LightweightDatabaseCommon.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\LightweightDatabaseServer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\LinuxStrings.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\LogCommandParser.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\MessageFilter.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\NatPunchthroughClient.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\NatPunchthroughServer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\NetworkIDManager.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\NetworkIDObject.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\PacketConsoleLogger.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\PacketFileLogger.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\PacketizedTCP.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\PacketLogger.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\PacketOutputWindowLogger.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\PluginInterface.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\PluginInterface2.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakMemoryOverride.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakNetCommandParser.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakNetSocket.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakNetStatistics.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakNetTransport.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakNetTransport2.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakNetTypes.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakNetworkFactory.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakPeer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakSleep.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakString.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RakThread.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\Rand.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ReadyEvent.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ReliabilityLayer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ReplicaManager.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ReplicaManager2.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ReplicaManager3.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\rijndael.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\Router.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\Router2.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RPCMap.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\RSACrypt.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\DR_SHA1.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\SimpleMutex.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\SocketLayer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\StringCompressor.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\StringTable.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\SuperFastHash.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\SystemAddressList.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\TableSerializer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\TCPInterface.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\TelnetTransport.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\ThreadsafePacketLogger.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\UDPForwarder.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\UDPProxyClient.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\UDPProxyCoordinator.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\UDPProxyServer.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\src\WSAStartupSingleton.cpp">
<Filter>RakNet</Filter>
</ClCompile>
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Client.cpp">
<Filter>Lobby2</Filter>
</ClCompile>
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Client_Steam.cpp">
<Filter>Lobby2</Filter>
</ClCompile>
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Message.cpp">
<Filter>Lobby2</Filter>
</ClCompile>
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Message_Steam.cpp">
<Filter>Lobby2</Filter>
</ClCompile>
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Plugin.cpp">
<Filter>Lobby2</Filter>
</ClCompile>
<ClCompile Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2ResultCode.cpp">
<Filter>Lobby2</Filter>
</ClCompile>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Source\include\slikenet\_FindFirst.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\AsynchronousFileIO.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\AutopatcherPatchContext.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\AutopatcherRepositoryInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\AutoRPC.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\BigInt.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\BitStream.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\BitStream_NoTemplate.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\CheckSum.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ClientContextStruct.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\CommandParserInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ConnectionGraph.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ConnectionGraph2.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ConsoleServer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DataBlockEncryptor.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DataCompressor.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DirectoryDeltaTransfer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_BinarySearchTree.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_BPlusTree.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_BytePool.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_ByteQueue.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Heap.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_HuffmanEncodingTree.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_HuffmanEncodingTreeFactory.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_HuffmanEncodingTreeNode.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_LinkedList.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_List.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Map.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_MemoryPool.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Multilist.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_OrderedChannelHeap.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_OrderedList.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Queue.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_QueueLinkedList.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_RangeList.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Table.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_Tree.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DS_WeightedGraph.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\EmailSender.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\EpochTimeToString.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Export.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ExtendedOverlappedPool.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FileList.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FileListNodeContext.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FileListTransfer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FileListTransferCBInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FileOperations.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FormatString.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FullyConnectedMesh.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FullyConnectedMesh2.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\FunctionThread.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Gen_RPC8.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\GetTime.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\gettimeofday.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\GridSectorizer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\HTTPConnection.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\IncrementalReadInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\InlineFunctor.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\InternalPacket.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Itoa.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Kbhit.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\LightweightDatabaseClient.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\LightweightDatabaseCommon.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\LightweightDatabaseServer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\LinuxStrings.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\LogCommandParser.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\MessageFilter.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\MessageIdentifiers.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\MTUSize.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\NativeTypes.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\NatPunchthroughClient.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\NatPunchthroughServer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\NetworkIDManager.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\NetworkIDObject.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PacketConsoleLogger.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PacketFileLogger.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PacketizedTCP.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PacketLogger.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PacketOutputWindowLogger.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PacketPool.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PacketPriority.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Platform.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PluginInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\PluginInterface2.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\alloca.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\assert.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\memoryoverride.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\commandparser.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\defines.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\smartptr.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\socket.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\statistics.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\time.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\transport.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\transport2.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\types.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\version.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\peer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\peerinterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\sleep.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\string.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\thread.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Rand.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ReadyEvent.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\RefCountedObj.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ReliabilityLayer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Replica.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaEnums.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaManager.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaManager2.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ReplicaManager3.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Rijndael-Boxes.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Rijndael.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Router.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\Router2.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\RouterInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\RPCMap.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\RPCNode.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\RSACrypt.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\DR_SHA1.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\SimpleMutex.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\SimpleTCPServer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\SingleProducerConsumer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\SocketIncludes.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\SocketLayer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\StringCompressor.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\StringTable.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\SuperFastHash.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\SystemAddressList.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\TableSerializer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\TCPInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\TelnetTransport.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ThreadPool.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\ThreadsafePacketLogger.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\TransportInterface.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\UDPForwarder.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyClient.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyCommon.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyCoordinator.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\UDPProxyServer.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\WindowsIncludes.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\include\slikenet\WSAStartupSingleton.h">
<Filter>RakNet</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamapps.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamclient.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamfriends.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamgameserver.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteammasterserverupdater.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteammatchmaking.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamnetworking.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamremotestorage.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamuser.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamuserstats.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\isteamutils.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\matchmakingtypes.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\steam_api.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\steam_gameserver.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\steamclientpublic.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="C:\Steam\public\steam\steamtypes.h">
<Filter>Steam</Filter>
</ClInclude>
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Client.h">
<Filter>Lobby2</Filter>
</ClInclude>
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Client_Steam.h">
<Filter>Lobby2</Filter>
</ClInclude>
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Message.h">
<Filter>Lobby2</Filter>
</ClInclude>
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Steam\Lobby2Message_Steam.h">
<Filter>Lobby2</Filter>
</ClInclude>
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2Plugin.h">
<Filter>Lobby2</Filter>
</ClInclude>
<ClInclude Include="X:\p4\ob1\Data\DHEngine\Code\sdks\RakNet\DependentExtensions\Lobby2\Lobby2ResultCode.h">
<Filter>Lobby2</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="readme.txt" />
</ItemGroup>
</Project>