Friends List
Ignore List Instant Messaging
This commit is contained in:
16
Network/Event/NotifyFriendStatus.cpp
Normal file
16
Network/Event/NotifyFriendStatus.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "NotifyFriendStatus.h"
|
||||
|
||||
NotifyFriendStatus::NotifyFriendStatus( std::wstring handle, bool status ) : GenericMessage( 0x2F )
|
||||
{
|
||||
m_handle = handle;
|
||||
m_status = status;
|
||||
}
|
||||
|
||||
void NotifyFriendStatus::Serialize( ByteBuffer &out ) const
|
||||
{
|
||||
out.write_u16( m_packetId );
|
||||
out.write_u32( 0 );
|
||||
|
||||
out.write_utf16( m_handle );
|
||||
out.write_u8( m_status ? 1 : 0 );
|
||||
}
|
||||
13
Network/Event/NotifyFriendStatus.h
Normal file
13
Network/Event/NotifyFriendStatus.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../GenericNetMessage.h"
|
||||
|
||||
class NotifyFriendStatus : public GenericMessage {
|
||||
private:
|
||||
std::wstring m_handle;
|
||||
bool m_status;
|
||||
|
||||
public:
|
||||
NotifyFriendStatus( std::wstring handle, bool status );
|
||||
void Serialize( ByteBuffer &out ) const override;
|
||||
};
|
||||
16
Network/Event/NotifyInstantMessage.cpp
Normal file
16
Network/Event/NotifyInstantMessage.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "NotifyInstantMessage.h"
|
||||
|
||||
NotifyInstantMessage::NotifyInstantMessage( std::wstring chatHandle, std::wstring message ) : GenericMessage( 0x30 )
|
||||
{
|
||||
m_chatHandle = chatHandle;
|
||||
m_message = message;
|
||||
}
|
||||
|
||||
void NotifyInstantMessage::Serialize( ByteBuffer &out ) const
|
||||
{
|
||||
out.write_u16( m_packetId );
|
||||
out.write_u32( 0 );
|
||||
|
||||
out.write_utf16( m_chatHandle );
|
||||
out.write_utf16( m_message );
|
||||
}
|
||||
13
Network/Event/NotifyInstantMessage.h
Normal file
13
Network/Event/NotifyInstantMessage.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../GenericNetMessage.h"
|
||||
|
||||
class NotifyInstantMessage : public GenericMessage {
|
||||
private:
|
||||
std::wstring m_message;
|
||||
std::wstring m_chatHandle;
|
||||
|
||||
public:
|
||||
NotifyInstantMessage( std::wstring chatHandle, std::wstring message );
|
||||
void Serialize(ByteBuffer &out) const override;
|
||||
};
|
||||
61
Network/Event/RequestAddFriend.cpp
Normal file
61
Network/Event/RequestAddFriend.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "RequestAddFriend.h"
|
||||
|
||||
#include "../../Game/RealmUserManager.h"
|
||||
#include "../../Database/Database.h"
|
||||
#include "../../logging.h"
|
||||
|
||||
void RequestAddFriend::Deserialize( sptr_byte_stream stream )
|
||||
{
|
||||
DeserializeHeader( stream );
|
||||
|
||||
m_sessionId = stream->read_encrypted_utf16();
|
||||
m_chatHandle = stream->read_utf16();
|
||||
}
|
||||
|
||||
sptr_generic_response RequestAddFriend::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
|
||||
{
|
||||
Deserialize( stream );
|
||||
|
||||
auto user = UserManager::Get().FindUserBySocket( socket );
|
||||
if( user == nullptr )
|
||||
{
|
||||
return std::make_shared< ResultAddFriend >( this, FATAL_ERROR );
|
||||
}
|
||||
|
||||
if( user->IsFriend( m_chatHandle ) )
|
||||
{
|
||||
return std::make_shared< ResultAddFriend >( this, FRIEND_DUPLICATE );
|
||||
}
|
||||
|
||||
auto targetUser = UserManager::Get().FindUserByChatHandle( m_chatHandle );
|
||||
if( targetUser == nullptr )
|
||||
{
|
||||
return std::make_shared< ResultAddFriend >( this, FRIEND_INVALID );
|
||||
}
|
||||
|
||||
if( targetUser->IsIgnored( user->m_chatHandle ) )
|
||||
{
|
||||
return std::make_shared< ResultAddFriend >( this, FRIEND_IGNORING );
|
||||
}
|
||||
|
||||
if( !Database::Get().SaveFriend( user->m_accountId, targetUser->m_chatHandle ) )
|
||||
{
|
||||
return std::make_shared< ResultAddFriend >( this, DATABASE_ERROR );
|
||||
}
|
||||
|
||||
user->m_friendList.push_back( targetUser->m_chatHandle );
|
||||
|
||||
return std::make_shared< ResultAddFriend >( this, SUCCESS );
|
||||
}
|
||||
|
||||
ResultAddFriend::ResultAddFriend( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
|
||||
{
|
||||
m_reply = reply;
|
||||
}
|
||||
|
||||
void ResultAddFriend::Serialize( ByteBuffer &out ) const
|
||||
{
|
||||
out.write_u16( m_packetId );
|
||||
out.write_u32( m_trackId );
|
||||
out.write_u32( m_reply );
|
||||
}
|
||||
40
Network/Event/RequestAddFriend.h
Normal file
40
Network/Event/RequestAddFriend.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "../GenericNetRequest.h"
|
||||
#include "../GenericNetResponse.h"
|
||||
|
||||
class RequestAddFriend : public GenericRequest
|
||||
{
|
||||
private:
|
||||
std::wstring m_sessionId;
|
||||
std::wstring m_chatHandle;
|
||||
|
||||
enum ERROR_CODE {
|
||||
SUCCESS = 0,
|
||||
FATAL_ERROR,
|
||||
DATABASE_ERROR = 2,
|
||||
FRIEND_IGNORING = 19,
|
||||
FRIEND_INVALID = 20,
|
||||
FRIEND_DUPLICATE = 21,
|
||||
};
|
||||
public:
|
||||
static std::unique_ptr< RequestAddFriend > Create()
|
||||
{
|
||||
return std::make_unique< RequestAddFriend >();
|
||||
}
|
||||
|
||||
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
|
||||
void Deserialize( sptr_byte_stream stream ) override;
|
||||
};
|
||||
|
||||
class ResultAddFriend : public GenericResponse {
|
||||
private:
|
||||
int32_t m_reply;
|
||||
|
||||
public:
|
||||
ResultAddFriend( GenericRequest *request, int32_t reply );
|
||||
void Serialize( ByteBuffer &out ) const;
|
||||
};
|
||||
61
Network/Event/RequestAddIgnore.cpp
Normal file
61
Network/Event/RequestAddIgnore.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "RequestAddIgnore.h"
|
||||
|
||||
#include "../../Game/RealmUserManager.h"
|
||||
#include "../../Database/Database.h"
|
||||
#include "../../logging.h"
|
||||
|
||||
void RequestAddIgnore::Deserialize( sptr_byte_stream stream )
|
||||
{
|
||||
DeserializeHeader( stream );
|
||||
|
||||
m_sessionId = stream->read_encrypted_utf16();
|
||||
m_chatHandle = stream->read_utf16();
|
||||
}
|
||||
|
||||
sptr_generic_response RequestAddIgnore::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
|
||||
{
|
||||
Deserialize( stream );
|
||||
|
||||
auto user = UserManager::Get().FindUserBySocket( socket );
|
||||
if( user == nullptr )
|
||||
{
|
||||
return std::make_shared< ResultAddIgnore >( this, FATAL_ERROR );
|
||||
}
|
||||
|
||||
if( user->IsFriend( m_chatHandle ) )
|
||||
{
|
||||
return std::make_shared< ResultAddIgnore >( this, IGNORE_FRIEND );
|
||||
}
|
||||
|
||||
if( user->IsIgnored( m_chatHandle ) )
|
||||
{
|
||||
return std::make_shared< ResultAddIgnore >( this, IGNORE_DUPLICATE );
|
||||
}
|
||||
|
||||
auto targetUser = UserManager::Get().FindUserByChatHandle( m_chatHandle );
|
||||
if( targetUser == nullptr )
|
||||
{
|
||||
return std::make_shared< ResultAddIgnore >( this, IGNORE_INVALID );
|
||||
}
|
||||
|
||||
if( !Database::Get().SaveIgnore( user->m_accountId, targetUser->m_chatHandle ) )
|
||||
{
|
||||
return std::make_shared< ResultAddIgnore >( this, DATABASE_ERROR );
|
||||
}
|
||||
|
||||
user->m_ignoreList.push_back( targetUser->m_chatHandle );
|
||||
|
||||
return std::make_shared< ResultAddIgnore >( this, SUCCESS );
|
||||
}
|
||||
|
||||
ResultAddIgnore::ResultAddIgnore( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
|
||||
{
|
||||
m_reply = reply;
|
||||
}
|
||||
|
||||
void ResultAddIgnore::Serialize( ByteBuffer &out ) const
|
||||
{
|
||||
out.write_u16( m_packetId );
|
||||
out.write_u32( m_trackId );
|
||||
out.write_u32( m_reply );
|
||||
}
|
||||
41
Network/Event/RequestAddIgnore.h
Normal file
41
Network/Event/RequestAddIgnore.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "../GenericNetRequest.h"
|
||||
#include "../GenericNetResponse.h"
|
||||
|
||||
class RequestAddIgnore : public GenericRequest
|
||||
{
|
||||
private:
|
||||
std::wstring m_sessionId;
|
||||
std::wstring m_chatHandle;
|
||||
|
||||
enum ERROR_CODE {
|
||||
SUCCESS = 0,
|
||||
FATAL_ERROR,
|
||||
DATABASE_ERROR = 2,
|
||||
IGNORE_INVALID = 20,
|
||||
IGNORE_FRIEND = 24,
|
||||
IGNORE_DUPLICATE = 25,
|
||||
};
|
||||
|
||||
public:
|
||||
static std::unique_ptr< RequestAddIgnore > Create()
|
||||
{
|
||||
return std::make_unique< RequestAddIgnore >();
|
||||
}
|
||||
|
||||
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
|
||||
void Deserialize( sptr_byte_stream stream ) override;
|
||||
};
|
||||
|
||||
class ResultAddIgnore : public GenericResponse {
|
||||
private:
|
||||
int32_t m_reply;
|
||||
|
||||
public:
|
||||
ResultAddIgnore( GenericRequest *request, int32_t reply );
|
||||
void Serialize( ByteBuffer &out ) const;
|
||||
};
|
||||
54
Network/Event/RequestGetSocialListInitial.cpp
Normal file
54
Network/Event/RequestGetSocialListInitial.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "RequestGetSocialListInitial.h"
|
||||
|
||||
#include "../../Game/RealmUserManager.h"
|
||||
#include "../../Game/RealmUser.h"
|
||||
#include "../../logging.h"
|
||||
|
||||
void RequestGetSocialListInitial::Deserialize( sptr_byte_stream stream )
|
||||
{
|
||||
DeserializeHeader( stream );
|
||||
}
|
||||
|
||||
sptr_generic_response RequestGetSocialListInitial::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
|
||||
{
|
||||
Deserialize( stream );
|
||||
|
||||
auto user = UserManager::Get().FindUserBySocket( socket );
|
||||
if( user == nullptr )
|
||||
{
|
||||
Log::Error( "RequestGetFriendList::ProcessRequest() - User not found" );
|
||||
return std::make_shared< ResultGetSocialListInitial >( this );
|
||||
}
|
||||
|
||||
return std::make_shared< ResultGetSocialListInitial >( this, user );
|
||||
}
|
||||
|
||||
ResultGetSocialListInitial::ResultGetSocialListInitial( GenericRequest *request, sptr_user user ) : GenericResponse( *request )
|
||||
{
|
||||
m_user = user;
|
||||
}
|
||||
|
||||
void ResultGetSocialListInitial::Serialize( ByteBuffer &out ) const
|
||||
{
|
||||
out.write_u16( m_packetId );
|
||||
out.write_u32( m_trackId );
|
||||
out.write_u32( 0 );
|
||||
|
||||
// Friends
|
||||
out.write_u32( static_cast< uint32_t >( m_user->m_friendList.size() ) );
|
||||
for( const auto &friendHandle : m_user->m_friendList )
|
||||
{
|
||||
out.write_utf16( friendHandle );
|
||||
}
|
||||
|
||||
// ?
|
||||
out.write_u32(1);
|
||||
out.write_utf16(L"String_2");
|
||||
|
||||
// Ignore
|
||||
out.write_u32( static_cast< uint32_t >( m_user->m_ignoreList.size() ) );
|
||||
for( const auto &ignoreHandle : m_user->m_ignoreList )
|
||||
{
|
||||
out.write_utf16( ignoreHandle );
|
||||
}
|
||||
}
|
||||
30
Network/Event/RequestGetSocialListInitial.h
Normal file
30
Network/Event/RequestGetSocialListInitial.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "../GenericNetRequest.h"
|
||||
#include "../GenericNetResponse.h"
|
||||
#include "../../Common/ForwardDecl.h"
|
||||
|
||||
class RequestGetSocialListInitial : public GenericRequest
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr< RequestGetSocialListInitial > Create()
|
||||
{
|
||||
return std::make_unique< RequestGetSocialListInitial >();
|
||||
}
|
||||
|
||||
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
|
||||
void Deserialize( sptr_byte_stream stream ) override;
|
||||
};
|
||||
|
||||
class ResultGetSocialListInitial : public GenericResponse {
|
||||
private:
|
||||
int32_t m_reply;
|
||||
sptr_user m_user;
|
||||
|
||||
public:
|
||||
ResultGetSocialListInitial( GenericRequest *request, sptr_user user = nullptr );
|
||||
void Serialize( ByteBuffer &out ) const;
|
||||
};
|
||||
50
Network/Event/RequestGetSocialListUpdate.cpp
Normal file
50
Network/Event/RequestGetSocialListUpdate.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "RequestGetSocialListUpdate.h"
|
||||
|
||||
#include "../../Game/RealmUserManager.h"
|
||||
#include "../../Game/RealmUser.h"
|
||||
#include "../../logging.h"
|
||||
|
||||
void RequestGetSocialListUpdate::Deserialize( sptr_byte_stream stream )
|
||||
{
|
||||
DeserializeHeader( stream );
|
||||
}
|
||||
|
||||
sptr_generic_response RequestGetSocialListUpdate::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
|
||||
{
|
||||
Deserialize( stream );
|
||||
|
||||
auto user = UserManager::Get().FindUserBySocket( socket );
|
||||
if( user == nullptr )
|
||||
{
|
||||
Log::Error( "RequestGetFriendList::ProcessRequest() - User not found" );
|
||||
return std::make_shared< ResultGetSocialListUpdate >( this );
|
||||
}
|
||||
|
||||
return std::make_shared< ResultGetSocialListUpdate >( this, user );
|
||||
}
|
||||
|
||||
ResultGetSocialListUpdate::ResultGetSocialListUpdate( GenericRequest *request, sptr_user user ) : GenericResponse( *request )
|
||||
{
|
||||
m_user = user;
|
||||
}
|
||||
|
||||
void ResultGetSocialListUpdate::Serialize( ByteBuffer &out ) const
|
||||
{
|
||||
out.write_u16( m_packetId );
|
||||
out.write_u32( m_trackId );
|
||||
out.write_u32( 0 );
|
||||
|
||||
// Friends
|
||||
out.write_u32( static_cast< uint32_t >( m_user->m_friendList.size() ) );
|
||||
for( const auto &friendHandle : m_user->m_friendList )
|
||||
{
|
||||
out.write_utf16( friendHandle );
|
||||
}
|
||||
|
||||
// Ignore
|
||||
out.write_u32( static_cast< uint32_t >( m_user->m_ignoreList.size() ) );
|
||||
for( const auto &ignoreHandle : m_user->m_ignoreList )
|
||||
{
|
||||
out.write_utf16( ignoreHandle );
|
||||
}
|
||||
}
|
||||
30
Network/Event/RequestGetSocialListUpdate.h
Normal file
30
Network/Event/RequestGetSocialListUpdate.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "../GenericNetRequest.h"
|
||||
#include "../GenericNetResponse.h"
|
||||
#include "../../Common/ForwardDecl.h"
|
||||
|
||||
class RequestGetSocialListUpdate : public GenericRequest
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr< RequestGetSocialListUpdate > Create()
|
||||
{
|
||||
return std::make_unique< RequestGetSocialListUpdate >();
|
||||
}
|
||||
|
||||
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
|
||||
void Deserialize( sptr_byte_stream stream ) override;
|
||||
};
|
||||
|
||||
class ResultGetSocialListUpdate : public GenericResponse {
|
||||
private:
|
||||
int32_t m_reply;
|
||||
sptr_user m_user;
|
||||
|
||||
public:
|
||||
ResultGetSocialListUpdate( GenericRequest *request, sptr_user user = nullptr );
|
||||
void Serialize( ByteBuffer &out ) const;
|
||||
};
|
||||
@@ -42,7 +42,7 @@ sptr_generic_response RequestLogin::ProcessLoginRTA( sptr_user user )
|
||||
auto &Database = Database::Get();
|
||||
|
||||
// Verify the account exists
|
||||
auto accountId = Database.VerifyAccount( m_username, m_password );
|
||||
auto [ result, accountId, chatHandle ] = Database.VerifyAccount( m_username, m_password );
|
||||
|
||||
if( accountId < 0 )
|
||||
{
|
||||
@@ -59,19 +59,21 @@ sptr_generic_response RequestLogin::ProcessLoginRTA( sptr_user user )
|
||||
}
|
||||
}
|
||||
|
||||
auto [result, chatHandle] = Database.LoadAccount( accountId );
|
||||
|
||||
// Login Success
|
||||
user->m_isLoggedIn = true;
|
||||
user->m_username = m_username;
|
||||
user->m_accountId = accountId;
|
||||
user->m_chatHandle = chatHandle;
|
||||
user->m_sessionId = UserManager.GenerateSessionId();
|
||||
|
||||
Database.CreateSession(
|
||||
user->m_accountId,
|
||||
user->m_sessionId,
|
||||
user->sock->remote_ip );
|
||||
|
||||
// Load Friend List
|
||||
user->m_friendList = Database.LoadFriends( accountId );
|
||||
|
||||
// Load Ignore List
|
||||
user->m_ignoreList = Database.LoadIgnores( accountId );
|
||||
|
||||
// Notify friends about the user's online status
|
||||
UserManager.NotifyFriendsOnlineStatus( user, true );
|
||||
|
||||
return std::make_shared< ResultLogin >( this, SUCCESS, user->m_sessionId );
|
||||
}
|
||||
|
||||
54
Network/Event/RequestSendInstantMessage.cpp
Normal file
54
Network/Event/RequestSendInstantMessage.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "RequestSendInstantMessage.h"
|
||||
|
||||
#include "NotifyInstantMessage.h"
|
||||
#include "../../Game/RealmUserManager.h"
|
||||
#include "../../Game/ChatRoomManager.h"
|
||||
#include "../../logging.h"
|
||||
|
||||
void RequestSendInstantMessage::Deserialize( sptr_byte_stream stream )
|
||||
{
|
||||
DeserializeHeader( stream );
|
||||
|
||||
auto sessionId = stream->read_encrypted_utf16();
|
||||
m_chatHandle = stream->read_utf16();
|
||||
m_message = stream->read_utf16();
|
||||
}
|
||||
|
||||
sptr_generic_response RequestSendInstantMessage::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
|
||||
{
|
||||
Deserialize( stream );
|
||||
|
||||
const auto user = UserManager::Get().FindUserBySocket( socket );
|
||||
if( !user )
|
||||
{
|
||||
Log::Error( "User not found for socket!" );
|
||||
return std::make_shared< ResultSendInstantMessage >( this, GENERAL_ERROR );
|
||||
}
|
||||
|
||||
auto targetUser = UserManager::Get().FindUserByChatHandle( m_chatHandle );
|
||||
if( !targetUser )
|
||||
{
|
||||
return std::make_shared< ResultSendInstantMessage >( this, GENERAL_ERROR );
|
||||
}
|
||||
|
||||
if( targetUser->IsIgnored( user->m_chatHandle ) )
|
||||
{
|
||||
return std::make_shared< ResultSendInstantMessage >( this, USER_IGNORED );
|
||||
}
|
||||
|
||||
targetUser->sock->send( NotifyInstantMessage( user->m_chatHandle, m_message ) );
|
||||
|
||||
return std::make_shared< ResultSendInstantMessage >( this, SUCCESS );
|
||||
}
|
||||
|
||||
ResultSendInstantMessage::ResultSendInstantMessage( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
|
||||
{
|
||||
m_reply = reply;
|
||||
}
|
||||
|
||||
void ResultSendInstantMessage::Serialize( ByteBuffer &out ) const
|
||||
{
|
||||
out.write_u16( m_packetId );
|
||||
out.write_u32( m_trackId );
|
||||
out.write_u32( m_reply );
|
||||
}
|
||||
38
Network/Event/RequestSendInstantMessage.h
Normal file
38
Network/Event/RequestSendInstantMessage.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "../GenericNetRequest.h"
|
||||
#include "../GenericNetResponse.h"
|
||||
|
||||
class RequestSendInstantMessage : public GenericRequest
|
||||
{
|
||||
private:
|
||||
std::wstring m_chatHandle;
|
||||
std::wstring m_message;
|
||||
|
||||
enum ERROR_CODE {
|
||||
SUCCESS = 0,
|
||||
GENERAL_ERROR,
|
||||
USER_IGNORED = 19,
|
||||
};
|
||||
|
||||
public:
|
||||
static std::unique_ptr< RequestSendInstantMessage > Create()
|
||||
{
|
||||
return std::make_unique< RequestSendInstantMessage >();
|
||||
}
|
||||
|
||||
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
|
||||
void Deserialize( sptr_byte_stream stream ) override;
|
||||
};
|
||||
|
||||
class ResultSendInstantMessage : public GenericResponse {
|
||||
private:
|
||||
int32_t m_reply;
|
||||
|
||||
public:
|
||||
ResultSendInstantMessage( GenericRequest *request, int32_t reply );
|
||||
void Serialize( ByteBuffer &out ) const;
|
||||
};
|
||||
Reference in New Issue
Block a user