198 lines
7.8 KiB
C++
198 lines
7.8 KiB
C++
#include "abstractclient.h"
|
|
|
|
#include "featureset.h"
|
|
#include "get_pb_extension.h"
|
|
#include "pb/commands.pb.h"
|
|
#include "pb/event_add_to_list.pb.h"
|
|
#include "pb/event_connection_closed.pb.h"
|
|
#include "pb/event_game_joined.pb.h"
|
|
#include "pb/event_list_rooms.pb.h"
|
|
#include "pb/event_notify_user.pb.h"
|
|
#include "pb/event_remove_from_list.pb.h"
|
|
#include "pb/event_replay_added.pb.h"
|
|
#include "pb/event_server_identification.pb.h"
|
|
#include "pb/event_server_message.pb.h"
|
|
#include "pb/event_server_shutdown.pb.h"
|
|
#include "pb/event_user_joined.pb.h"
|
|
#include "pb/event_user_left.pb.h"
|
|
#include "pb/event_user_message.pb.h"
|
|
#include "pb/server_message.pb.h"
|
|
#include "pending_command.h"
|
|
|
|
#include <google/protobuf/descriptor.h>
|
|
|
|
AbstractClient::AbstractClient(QObject *parent)
|
|
: QObject(parent), nextCmdId(0), status(StatusDisconnected), serverSupportsPasswordHash(false)
|
|
{
|
|
qRegisterMetaType<QVariant>("QVariant");
|
|
qRegisterMetaType<CommandContainer>("CommandContainer");
|
|
qRegisterMetaType<Response>("Response");
|
|
qRegisterMetaType<Response::ResponseCode>("Response::ResponseCode");
|
|
qRegisterMetaType<ClientStatus>("ClientStatus");
|
|
qRegisterMetaType<RoomEvent>("RoomEvent");
|
|
qRegisterMetaType<GameEventContainer>("GameEventContainer");
|
|
qRegisterMetaType<Event_ServerIdentification>("Event_ServerIdentification");
|
|
qRegisterMetaType<Event_ConnectionClosed>("Event_ConnectionClosed");
|
|
qRegisterMetaType<Event_ServerShutdown>("Event_ServerShutdown");
|
|
qRegisterMetaType<Event_AddToList>("Event_AddToList");
|
|
qRegisterMetaType<Event_RemoveFromList>("Event_RemoveFromList");
|
|
qRegisterMetaType<Event_UserJoined>("Event_UserJoined");
|
|
qRegisterMetaType<Event_UserLeft>("Event_UserLeft");
|
|
qRegisterMetaType<Event_ServerMessage>("Event_ServerMessage");
|
|
qRegisterMetaType<Event_ListRooms>("Event_ListRooms");
|
|
qRegisterMetaType<Event_GameJoined>("Event_GameJoined");
|
|
qRegisterMetaType<Event_UserMessage>("Event_UserMessage");
|
|
qRegisterMetaType<Event_NotifyUser>("Event_NotifyUser");
|
|
qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
|
|
qRegisterMetaType<QList<ServerInfo_User>>("QList<ServerInfo_User>");
|
|
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
|
|
qRegisterMetaType<QList<QString>>("missingFeatures");
|
|
qRegisterMetaType<PendingCommand *>("pendingCommand");
|
|
|
|
FeatureSet features;
|
|
features.initalizeFeatureList(clientFeatures);
|
|
|
|
connect(this, SIGNAL(sigQueuePendingCommand(PendingCommand *)), this, SLOT(queuePendingCommand(PendingCommand *)));
|
|
}
|
|
|
|
AbstractClient::~AbstractClient()
|
|
{
|
|
}
|
|
|
|
void AbstractClient::processProtocolItem(const ServerMessage &item)
|
|
{
|
|
switch (item.message_type()) {
|
|
case ServerMessage::RESPONSE: {
|
|
const Response &response = item.response();
|
|
const int cmdId = response.cmd_id();
|
|
|
|
PendingCommand *pend = pendingCommands.value(cmdId, 0);
|
|
if (!pend)
|
|
return;
|
|
pendingCommands.remove(cmdId);
|
|
|
|
pend->processResponse(response);
|
|
pend->deleteLater();
|
|
break;
|
|
}
|
|
case ServerMessage::SESSION_EVENT: {
|
|
const SessionEvent &event = item.session_event();
|
|
switch ((SessionEvent::SessionEventType)getPbExtension(event)) {
|
|
case SessionEvent::SERVER_IDENTIFICATION:
|
|
emit serverIdentificationEventReceived(event.GetExtension(Event_ServerIdentification::ext));
|
|
break;
|
|
case SessionEvent::SERVER_MESSAGE:
|
|
emit serverMessageEventReceived(event.GetExtension(Event_ServerMessage::ext));
|
|
break;
|
|
case SessionEvent::SERVER_SHUTDOWN:
|
|
emit serverShutdownEventReceived(event.GetExtension(Event_ServerShutdown::ext));
|
|
break;
|
|
case SessionEvent::CONNECTION_CLOSED:
|
|
emit connectionClosedEventReceived(event.GetExtension(Event_ConnectionClosed::ext));
|
|
break;
|
|
case SessionEvent::USER_MESSAGE:
|
|
emit userMessageEventReceived(event.GetExtension(Event_UserMessage::ext));
|
|
break;
|
|
case SessionEvent::NOTIFY_USER:
|
|
emit notifyUserEventReceived(event.GetExtension(Event_NotifyUser::ext));
|
|
break;
|
|
case SessionEvent::LIST_ROOMS:
|
|
emit listRoomsEventReceived(event.GetExtension(Event_ListRooms::ext));
|
|
break;
|
|
case SessionEvent::ADD_TO_LIST:
|
|
emit addToListEventReceived(event.GetExtension(Event_AddToList::ext));
|
|
break;
|
|
case SessionEvent::REMOVE_FROM_LIST:
|
|
emit removeFromListEventReceived(event.GetExtension(Event_RemoveFromList::ext));
|
|
break;
|
|
case SessionEvent::USER_JOINED:
|
|
emit userJoinedEventReceived(event.GetExtension(Event_UserJoined::ext));
|
|
break;
|
|
case SessionEvent::USER_LEFT:
|
|
emit userLeftEventReceived(event.GetExtension(Event_UserLeft::ext));
|
|
break;
|
|
case SessionEvent::GAME_JOINED:
|
|
emit gameJoinedEventReceived(event.GetExtension(Event_GameJoined::ext));
|
|
break;
|
|
case SessionEvent::REPLAY_ADDED:
|
|
emit replayAddedEventReceived(event.GetExtension(Event_ReplayAdded::ext));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case ServerMessage::GAME_EVENT_CONTAINER: {
|
|
emit gameEventContainerReceived(item.game_event_container());
|
|
break;
|
|
}
|
|
case ServerMessage::ROOM_EVENT: {
|
|
emit roomEventReceived(item.room_event());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AbstractClient::setStatus(const ClientStatus _status)
|
|
{
|
|
QMutexLocker locker(&clientMutex);
|
|
if (_status != status) {
|
|
status = _status;
|
|
emit statusChanged(_status);
|
|
}
|
|
}
|
|
|
|
void AbstractClient::sendCommand(const CommandContainer &cont)
|
|
{
|
|
sendCommand(new PendingCommand(cont));
|
|
}
|
|
|
|
void AbstractClient::sendCommand(PendingCommand *pend)
|
|
{
|
|
pend->moveToThread(thread());
|
|
emit sigQueuePendingCommand(pend);
|
|
}
|
|
|
|
void AbstractClient::queuePendingCommand(PendingCommand *pend)
|
|
{
|
|
// This function is always called from the client thread via signal/slot.
|
|
const int cmdId = getNewCmdId();
|
|
pend->getCommandContainer().set_cmd_id(cmdId);
|
|
|
|
pendingCommands.insert(cmdId, pend);
|
|
|
|
sendCommandContainer(pend->getCommandContainer());
|
|
}
|
|
|
|
PendingCommand *AbstractClient::prepareSessionCommand(const ::google::protobuf::Message &cmd)
|
|
{
|
|
CommandContainer cont;
|
|
SessionCommand *c = cont.add_session_command();
|
|
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
|
return new PendingCommand(cont);
|
|
}
|
|
|
|
PendingCommand *AbstractClient::prepareRoomCommand(const ::google::protobuf::Message &cmd, int roomId)
|
|
{
|
|
CommandContainer cont;
|
|
RoomCommand *c = cont.add_room_command();
|
|
cont.set_room_id(roomId);
|
|
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
|
return new PendingCommand(cont);
|
|
}
|
|
|
|
PendingCommand *AbstractClient::prepareModeratorCommand(const ::google::protobuf::Message &cmd)
|
|
{
|
|
CommandContainer cont;
|
|
ModeratorCommand *c = cont.add_moderator_command();
|
|
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
|
return new PendingCommand(cont);
|
|
}
|
|
|
|
PendingCommand *AbstractClient::prepareAdminCommand(const ::google::protobuf::Message &cmd)
|
|
{
|
|
CommandContainer cont;
|
|
AdminCommand *c = cont.add_admin_command();
|
|
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
|
return new PendingCommand(cont);
|
|
}
|