more ISL code: join, leave, and userMessage work on both sides
This commit is contained in:
parent
5963c2239c
commit
0ae18d7b2e
16 changed files with 363 additions and 112 deletions
|
@ -8,13 +8,16 @@ SET(common_SOURCES
|
|||
rng_qt.cpp
|
||||
rng_sfmt.cpp
|
||||
server.cpp
|
||||
server_abstractuserinterface.cpp
|
||||
server_card.cpp
|
||||
server_cardzone.cpp
|
||||
server_game.cpp
|
||||
server_player.cpp
|
||||
server_protocolhandler.cpp
|
||||
server_remoteuserinterface.cpp
|
||||
server_response_containers.cpp
|
||||
server_room.cpp
|
||||
serverinfo_user_container.cpp
|
||||
sfmt/SFMT.c
|
||||
)
|
||||
SET(common_HEADERS
|
||||
|
|
|
@ -19,4 +19,5 @@ message ServerInfo_User {
|
|||
optional string country = 6;
|
||||
optional bytes avatar_bmp = 7;
|
||||
optional sint32 id = 8 [default = -1];
|
||||
optional sint32 server_id = 9 [default = -1];
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "server_counter.h"
|
||||
#include "server_room.h"
|
||||
#include "server_protocolhandler.h"
|
||||
#include "server_remoteuserinterface.h"
|
||||
#include "pb/event_user_joined.pb.h"
|
||||
#include "pb/event_user_left.pb.h"
|
||||
#include "pb/event_list_rooms.pb.h"
|
||||
|
@ -100,7 +101,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
|
|||
for (int i = 0; i < clients.size(); ++i)
|
||||
if (clients[i]->getAcceptsUserListChanges())
|
||||
clients[i]->sendProtocolItem(*se);
|
||||
serverMutex.unlock();
|
||||
locker.unlock();
|
||||
|
||||
sendIslMessage(*se);
|
||||
delete se;
|
||||
|
@ -139,6 +140,36 @@ void Server::removeClient(Server_ProtocolHandler *client)
|
|||
qDebug() << "Server::removeClient:" << clients.size() << "clients; " << users.size() << "users left";
|
||||
}
|
||||
|
||||
void Server::externalUserJoined(ServerInfo_User userInfo)
|
||||
{
|
||||
// This function is always called from the main thread via signal/slot.
|
||||
QMutexLocker locker(&serverMutex);
|
||||
|
||||
externalUsers.insert(QString::fromStdString(userInfo.name()), new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo)));
|
||||
|
||||
Event_UserJoined event;
|
||||
event.mutable_user_info()->CopyFrom(userInfo);
|
||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||
for (int i = 0; i < clients.size(); ++i)
|
||||
if (clients[i]->getAcceptsUserListChanges())
|
||||
clients[i]->sendProtocolItem(*se);
|
||||
}
|
||||
|
||||
void Server::externalUserLeft(QString userName)
|
||||
{
|
||||
// This function is always called from the main thread via signal/slot.
|
||||
QMutexLocker locker(&serverMutex);
|
||||
|
||||
delete externalUsers.take(userName);
|
||||
|
||||
Event_UserLeft event;
|
||||
event.set_name(userName.toStdString());
|
||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||
for (int i = 0; i < clients.size(); ++i)
|
||||
if (clients[i]->getAcceptsUserListChanges())
|
||||
clients[i]->sendProtocolItem(*se);
|
||||
}
|
||||
|
||||
void Server::broadcastRoomUpdate()
|
||||
{
|
||||
QMutexLocker locker(&serverMutex);
|
||||
|
@ -184,6 +215,15 @@ int Server::getGamesCount() const
|
|||
return result;
|
||||
}
|
||||
|
||||
void Server::sendIslMessage(const Response &item, int serverId)
|
||||
{
|
||||
IslMessage msg;
|
||||
msg.set_message_type(IslMessage::RESPONSE);
|
||||
msg.mutable_response()->CopyFrom(item);
|
||||
|
||||
doSendIslMessage(msg, serverId);
|
||||
}
|
||||
|
||||
void Server::sendIslMessage(const SessionEvent &item, int serverId)
|
||||
{
|
||||
IslMessage msg;
|
||||
|
@ -192,3 +232,21 @@ void Server::sendIslMessage(const SessionEvent &item, int serverId)
|
|||
|
||||
doSendIslMessage(msg, serverId);
|
||||
}
|
||||
|
||||
void Server::sendIslMessage(const GameEventContainer &item, int serverId)
|
||||
{
|
||||
IslMessage msg;
|
||||
msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER);
|
||||
msg.mutable_game_event_container()->CopyFrom(item);
|
||||
|
||||
doSendIslMessage(msg, serverId);
|
||||
}
|
||||
|
||||
void Server::sendIslMessage(const RoomEvent &item, int serverId)
|
||||
{
|
||||
IslMessage msg;
|
||||
msg.set_message_type(IslMessage::ROOM_EVENT);
|
||||
msg.mutable_room_event()->CopyFrom(item);
|
||||
|
||||
doSendIslMessage(msg, serverId);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,13 @@
|
|||
class Server_Game;
|
||||
class Server_Room;
|
||||
class Server_ProtocolHandler;
|
||||
class Server_AbstractUserInterface;
|
||||
class GameReplay;
|
||||
class IslMessage;
|
||||
class Response;
|
||||
class SessionEvent;
|
||||
class GameEventContainer;
|
||||
class RoomEvent;
|
||||
|
||||
enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2, WouldOverwriteOldSession = 3, UserIsBanned = 4 };
|
||||
|
||||
|
@ -53,11 +57,22 @@ public:
|
|||
|
||||
virtual void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays) { }
|
||||
|
||||
void sendIslMessage(const Response &item, int serverId = -1);
|
||||
void sendIslMessage(const SessionEvent &item, int serverId = -1);
|
||||
void sendIslMessage(const GameEventContainer &item, int serverId = -1);
|
||||
void sendIslMessage(const RoomEvent &item, int serverId = -1);
|
||||
|
||||
void addExternalUser(const ServerInfo_User &userInfo);
|
||||
void removeExternalUser(const QString &userName);
|
||||
const QMap<QString, Server_AbstractUserInterface *> &getExternalUsers() const { return externalUsers; }
|
||||
protected slots:
|
||||
void externalUserJoined(ServerInfo_User userInfo);
|
||||
void externalUserLeft(QString userName);
|
||||
protected:
|
||||
void prepareDestroy();
|
||||
QList<Server_ProtocolHandler *> clients;
|
||||
QMap<QString, Server_ProtocolHandler *> users;
|
||||
QMap<QString, Server_AbstractUserInterface *> externalUsers;
|
||||
QMap<int, Server_Room *> rooms;
|
||||
|
||||
virtual int startSession(const QString &userName, const QString &address) { return -1; }
|
||||
|
|
19
common/server_abstractuserinterface.cpp
Normal file
19
common/server_abstractuserinterface.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include "server_abstractuserinterface.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
void Server_AbstractUserInterface::sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item)
|
||||
{
|
||||
switch (type) {
|
||||
case ServerMessage::RESPONSE: sendProtocolItem(static_cast<const Response &>(item)); break;
|
||||
case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast<const SessionEvent &>(item)); break;
|
||||
case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast<const GameEventContainer &>(item)); break;
|
||||
case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast<const RoomEvent &>(item)); break;
|
||||
}
|
||||
}
|
||||
|
||||
SessionEvent *Server_AbstractUserInterface::prepareSessionEvent(const ::google::protobuf::Message &sessionEvent)
|
||||
{
|
||||
SessionEvent *event = new SessionEvent;
|
||||
event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent);
|
||||
return event;
|
||||
}
|
31
common/server_abstractuserinterface.h
Normal file
31
common/server_abstractuserinterface.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef SERVER_ABSTRACTUSERINTERFACE
|
||||
#define SERVER_ABSTRACTUSERINTERFACE
|
||||
|
||||
#include "serverinfo_user_container.h"
|
||||
#include "pb/server_message.pb.h"
|
||||
|
||||
class Response;
|
||||
class SessionEvent;
|
||||
class GameEventContainer;
|
||||
class RoomEvent;
|
||||
|
||||
class Server;
|
||||
|
||||
class Server_AbstractUserInterface : public ServerInfo_User_Container {
|
||||
protected:
|
||||
Server *server;
|
||||
public:
|
||||
Server_AbstractUserInterface(Server *_server) : server(_server) { }
|
||||
Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other) : ServerInfo_User_Container(other), server(_server) { }
|
||||
virtual ~Server_AbstractUserInterface() { }
|
||||
|
||||
virtual void sendProtocolItem(const Response &item) = 0;
|
||||
virtual void sendProtocolItem(const SessionEvent &item) = 0;
|
||||
virtual void sendProtocolItem(const GameEventContainer &item) = 0;
|
||||
virtual void sendProtocolItem(const RoomEvent &item) = 0;
|
||||
void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item);
|
||||
|
||||
static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,6 +9,7 @@
|
|||
#include "server_game.h"
|
||||
#include "server_player.h"
|
||||
#include "decklist.h"
|
||||
#include "get_pb_extension.h"
|
||||
#include <QDateTime>
|
||||
#include "pb/serverinfo_zone.pb.h"
|
||||
#include "pb/commands.pb.h"
|
||||
|
@ -88,7 +89,7 @@
|
|||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
|
||||
: QObject(parent), server(_server), authState(NotLoggedIn), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), sessionId(-1), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive)
|
||||
: QObject(parent), Server_AbstractUserInterface(_server), authState(NotLoggedIn), acceptsUserListChanges(false), acceptsRoomListChanges(false), sessionId(-1), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive)
|
||||
{
|
||||
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
|
||||
}
|
||||
|
@ -126,29 +127,6 @@ void Server_ProtocolHandler::prepareDestroy()
|
|||
g->gameMutex.unlock();
|
||||
}
|
||||
gameListMutex.unlock();
|
||||
|
||||
delete userInfo;
|
||||
}
|
||||
|
||||
void Server_ProtocolHandler::setUserInfo(const ServerInfo_User &_userInfo)
|
||||
{
|
||||
userInfo = new ServerInfo_User;
|
||||
userInfo->CopyFrom(_userInfo);
|
||||
}
|
||||
|
||||
ServerInfo_User Server_ProtocolHandler::copyUserInfo(bool complete, bool moderatorInfo) const
|
||||
{
|
||||
ServerInfo_User result;
|
||||
if (userInfo) {
|
||||
result.CopyFrom(*userInfo);
|
||||
if (!moderatorInfo) {
|
||||
result.clear_address();
|
||||
result.clear_id();
|
||||
}
|
||||
if (!complete)
|
||||
result.clear_avatar_bmp();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game)
|
||||
|
@ -195,37 +173,13 @@ void Server_ProtocolHandler::sendProtocolItem(const RoomEvent &item)
|
|||
transmitProtocolItem(msg);
|
||||
}
|
||||
|
||||
void Server_ProtocolHandler::sendProtocolItem(ServerMessage::MessageType type, const ::google::protobuf::Message &item)
|
||||
{
|
||||
switch (type) {
|
||||
case ServerMessage::RESPONSE: sendProtocolItem(static_cast<const Response &>(item)); break;
|
||||
case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast<const SessionEvent &>(item)); break;
|
||||
case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast<const GameEventContainer &>(item)); break;
|
||||
case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast<const RoomEvent &>(item)); break;
|
||||
}
|
||||
}
|
||||
|
||||
SessionEvent *Server_ProtocolHandler::prepareSessionEvent(const ::google::protobuf::Message &sessionEvent)
|
||||
{
|
||||
SessionEvent *event = new SessionEvent;
|
||||
event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent);
|
||||
return event;
|
||||
}
|
||||
|
||||
Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
|
||||
{
|
||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||
for (int i = cont.session_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
const SessionCommand &sc = cont.session_command(i);
|
||||
std::vector< const ::google::protobuf::FieldDescriptor * > fieldList;
|
||||
sc.GetReflection()->ListFields(sc, &fieldList);
|
||||
int num = 0;
|
||||
for (unsigned int j = 0; j < fieldList.size(); ++j)
|
||||
if (fieldList[j]->is_extension()) {
|
||||
num = fieldList[j]->number();
|
||||
break;
|
||||
}
|
||||
const int num = getPbExtension(sc);
|
||||
if (num != SessionCommand::PING)
|
||||
emit logDebugMessage(QString::fromStdString(sc.ShortDebugString()), this);
|
||||
switch ((SessionCommand::SessionCommandType) num) {
|
||||
|
@ -270,14 +224,7 @@ Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const
|
|||
for (int i = cont.room_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
const RoomCommand &sc = cont.room_command(i);
|
||||
std::vector< const ::google::protobuf::FieldDescriptor * > fieldList;
|
||||
sc.GetReflection()->ListFields(sc, &fieldList);
|
||||
int num = 0;
|
||||
for (unsigned int j = 0; j < fieldList.size(); ++j)
|
||||
if (fieldList[j]->is_extension()) {
|
||||
num = fieldList[j]->number();
|
||||
break;
|
||||
}
|
||||
const int num = getPbExtension(sc);
|
||||
emit logDebugMessage(QString::fromStdString(sc.ShortDebugString()), this);
|
||||
switch ((RoomCommand::RoomCommandType) num) {
|
||||
case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break;
|
||||
|
@ -313,14 +260,7 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const
|
|||
for (int i = cont.game_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
const GameCommand &sc = cont.game_command(i);
|
||||
std::vector< const ::google::protobuf::FieldDescriptor * > fieldList;
|
||||
sc.GetReflection()->ListFields(sc, &fieldList);
|
||||
int num = 0;
|
||||
for (unsigned int j = 0; j < fieldList.size(); ++j)
|
||||
if (fieldList[j]->is_extension()) {
|
||||
num = fieldList[j]->number();
|
||||
break;
|
||||
}
|
||||
const int num = getPbExtension(sc);
|
||||
emit logDebugMessage(QString::fromStdString(sc.ShortDebugString()), this);
|
||||
switch ((GameCommand::GameCommandType) num) {
|
||||
case GameCommand::KICK_FROM_GAME: resp = cmdKickFromGame(sc.GetExtension(Command_KickFromGame::ext), game, player, rc, ges); break;
|
||||
|
@ -372,14 +312,7 @@ Response::ResponseCode Server_ProtocolHandler::processModeratorCommandContainer(
|
|||
for (int i = cont.moderator_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
const ModeratorCommand &sc = cont.moderator_command(i);
|
||||
std::vector< const ::google::protobuf::FieldDescriptor * > fieldList;
|
||||
sc.GetReflection()->ListFields(sc, &fieldList);
|
||||
int num = 0;
|
||||
for (unsigned int j = 0; j < fieldList.size(); ++j)
|
||||
if (fieldList[j]->is_extension()) {
|
||||
num = fieldList[j]->number();
|
||||
break;
|
||||
}
|
||||
const int num = getPbExtension(sc);
|
||||
emit logDebugMessage(QString::fromStdString(sc.ShortDebugString()), this);
|
||||
switch ((ModeratorCommand::ModeratorCommandType) num) {
|
||||
case ModeratorCommand::BAN_FROM_SERVER: resp = cmdBanFromServer(sc.GetExtension(Command_BanFromServer::ext), rc); break;
|
||||
|
@ -401,14 +334,7 @@ Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(cons
|
|||
for (int i = cont.admin_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
const AdminCommand &sc = cont.admin_command(i);
|
||||
std::vector< const ::google::protobuf::FieldDescriptor * > fieldList;
|
||||
sc.GetReflection()->ListFields(sc, &fieldList);
|
||||
int num = 0;
|
||||
for (unsigned int j = 0; j < fieldList.size(); ++j)
|
||||
if (fieldList[j]->is_extension()) {
|
||||
num = fieldList[j]->number();
|
||||
break;
|
||||
}
|
||||
const int num = getPbExtension(sc);
|
||||
emit logDebugMessage(QString::fromStdString(sc.ShortDebugString()), this);
|
||||
switch ((AdminCommand::AdminCommandType) num) {
|
||||
case AdminCommand::SHUTDOWN_SERVER: resp = cmdShutdownServer(sc.GetExtension(Command_ShutdownServer::ext), rc); break;
|
||||
|
@ -442,7 +368,7 @@ void Server_ProtocolHandler::processCommandContainer(const CommandContainer &con
|
|||
|
||||
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &preResponseQueue = responseContainer.getPreResponseQueue();
|
||||
for (int i = 0; i < preResponseQueue.size(); ++i)
|
||||
sendProtocolItem(preResponseQueue[i].first, *preResponseQueue[i].second);
|
||||
sendProtocolItemByType(preResponseQueue[i].first, *preResponseQueue[i].second);
|
||||
|
||||
Response response;
|
||||
response.set_cmd_id(cont.cmd_id());
|
||||
|
@ -454,7 +380,7 @@ void Server_ProtocolHandler::processCommandContainer(const CommandContainer &con
|
|||
|
||||
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > &postResponseQueue = responseContainer.getPostResponseQueue();
|
||||
for (int i = 0; i < postResponseQueue.size(); ++i)
|
||||
sendProtocolItem(postResponseQueue[i].first, *postResponseQueue[i].second);
|
||||
sendProtocolItemByType(postResponseQueue[i].first, *postResponseQueue[i].second);
|
||||
}
|
||||
|
||||
void Server_ProtocolHandler::pingClockTimeout()
|
||||
|
@ -577,11 +503,15 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message
|
|||
if (authState == NotLoggedIn)
|
||||
return Response::RespLoginNeeded;
|
||||
|
||||
server->serverMutex.lock();
|
||||
QMutexLocker locker(&server->serverMutex);
|
||||
|
||||
QString receiver = QString::fromStdString(cmd.user_name());
|
||||
Server_ProtocolHandler *userHandler = server->getUsers().value(receiver);
|
||||
if (!userHandler)
|
||||
Server_AbstractUserInterface *userInterface = server->getUsers().value(receiver);
|
||||
if (!userInterface) {
|
||||
userInterface = server->getExternalUsers().value(receiver);
|
||||
if (!userInterface)
|
||||
return Response::RespNameNotFound;
|
||||
}
|
||||
if (server->isInIgnoreList(receiver, QString::fromStdString(userInfo->name())))
|
||||
return Response::RespInIgnoreList;
|
||||
|
||||
|
@ -591,9 +521,8 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message
|
|||
event.set_message(cmd.message());
|
||||
|
||||
SessionEvent *se = prepareSessionEvent(event);
|
||||
userHandler->sendProtocolItem(*se);
|
||||
userInterface->sendProtocolItem(*se);
|
||||
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se);
|
||||
server->serverMutex.unlock();
|
||||
|
||||
return Response::RespOk;
|
||||
}
|
||||
|
@ -634,12 +563,18 @@ Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetU
|
|||
if (userName.isEmpty())
|
||||
re->mutable_user_info()->CopyFrom(*userInfo);
|
||||
else {
|
||||
server->serverMutex.lock();
|
||||
Server_ProtocolHandler *handler = server->getUsers().value(userName);
|
||||
if (!handler)
|
||||
|
||||
QMutexLocker locker(&server->serverMutex);
|
||||
|
||||
ServerInfo_User_Container *infoSource;
|
||||
if (server->getUsers().contains(userName))
|
||||
infoSource = server->getUsers().value(userName);
|
||||
else if (server->getExternalUsers().contains(userName))
|
||||
infoSource = server->getExternalUsers().value(userName);
|
||||
else
|
||||
return Response::RespNameNotFound;
|
||||
re->mutable_user_info()->CopyFrom(handler->copyUserInfo(true, userInfo->user_level() & ServerInfo_User::IsModerator));
|
||||
server->serverMutex.unlock();
|
||||
|
||||
re->mutable_user_info()->CopyFrom(infoSource->copyUserInfo(true, userInfo->user_level() & ServerInfo_User::IsModerator));
|
||||
}
|
||||
|
||||
rc.setResponseExtension(re);
|
||||
|
@ -699,6 +634,9 @@ Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUs
|
|||
QMapIterator<QString, Server_ProtocolHandler *> userIterator = server->getUsers();
|
||||
while (userIterator.hasNext())
|
||||
re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
|
||||
QMapIterator<QString, Server_AbstractUserInterface *> extIterator = server->getExternalUsers();
|
||||
while (extIterator.hasNext())
|
||||
re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false));
|
||||
server->serverMutex.unlock();
|
||||
|
||||
acceptsUserListChanges = true;
|
||||
|
@ -747,7 +685,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_Creat
|
|||
return Response::RespLoginNeeded;
|
||||
|
||||
if (server->getMaxGamesPerUser() > 0)
|
||||
if (room->getGamesCreatedByUser(getUserName()) >= server->getMaxGamesPerUser())
|
||||
if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser())
|
||||
return Response::RespContextError;
|
||||
|
||||
QList<int> gameTypes;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QObject>
|
||||
#include <QPair>
|
||||
#include "server.h"
|
||||
#include "server_abstractuserinterface.h"
|
||||
#include "pb/response.pb.h"
|
||||
#include "pb/server_message.pb.h"
|
||||
|
||||
|
@ -84,25 +85,21 @@ class Command_BanFromServer;
|
|||
class Command_UpdateServerMessage;
|
||||
class Command_ShutdownServer;
|
||||
|
||||
class Server_ProtocolHandler : public QObject {
|
||||
class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface {
|
||||
Q_OBJECT
|
||||
protected:
|
||||
Server *server;
|
||||
QMap<int, QPair<Server_Game *, Server_Player *> > games;
|
||||
QMap<int, Server_Room *> rooms;
|
||||
|
||||
Server *getServer() const { return server; }
|
||||
QPair<Server_Game *, Server_Player *> getGame(int gameId) const;
|
||||
|
||||
AuthenticationResult authState;
|
||||
bool acceptsUserListChanges;
|
||||
bool acceptsRoomListChanges;
|
||||
ServerInfo_User *userInfo;
|
||||
|
||||
void prepareDestroy();
|
||||
int sessionId;
|
||||
private:
|
||||
QString thisUserName;
|
||||
QList<int> messageSizeOverTime, messageCountOverTime;
|
||||
int timeRunning, lastDataReceived;
|
||||
QTimer *pingClock;
|
||||
|
@ -186,11 +183,7 @@ public:
|
|||
|
||||
bool getAcceptsUserListChanges() const { return acceptsUserListChanges; }
|
||||
bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; }
|
||||
ServerInfo_User *getUserInfo() const { return userInfo; }
|
||||
ServerInfo_User copyUserInfo(bool complete, bool moderatorInfo = false) const;
|
||||
const QString &getUserName() const { return thisUserName; }
|
||||
virtual QString getAddress() const = 0;
|
||||
void setUserInfo(const ServerInfo_User &_userInfo);
|
||||
int getSessionId() const { return sessionId; }
|
||||
void setSessionId(int _sessionId) { sessionId = _sessionId; }
|
||||
|
||||
|
@ -201,9 +194,6 @@ public:
|
|||
void sendProtocolItem(const SessionEvent &item);
|
||||
void sendProtocolItem(const GameEventContainer &item);
|
||||
void sendProtocolItem(const RoomEvent &item);
|
||||
void sendProtocolItem(ServerMessage::MessageType type, const ::google::protobuf::Message &item);
|
||||
|
||||
static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
22
common/server_remoteuserinterface.cpp
Normal file
22
common/server_remoteuserinterface.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "server_remoteuserinterface.h"
|
||||
#include "server.h"
|
||||
|
||||
void Server_RemoteUserInterface::sendProtocolItem(const Response &item)
|
||||
{
|
||||
server->sendIslMessage(item, userInfo->server_id());
|
||||
}
|
||||
|
||||
void Server_RemoteUserInterface::sendProtocolItem(const SessionEvent &item)
|
||||
{
|
||||
server->sendIslMessage(item, userInfo->server_id());
|
||||
}
|
||||
|
||||
void Server_RemoteUserInterface::sendProtocolItem(const GameEventContainer &item)
|
||||
{
|
||||
server->sendIslMessage(item, userInfo->server_id());
|
||||
}
|
||||
|
||||
void Server_RemoteUserInterface::sendProtocolItem(const RoomEvent &item)
|
||||
{
|
||||
server->sendIslMessage(item, userInfo->server_id());
|
||||
}
|
16
common/server_remoteuserinterface.h
Normal file
16
common/server_remoteuserinterface.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef SERVER_REMOTEUSERINTERFACE_H
|
||||
#define SERVER_REMOTEUSERINTERFACE_H
|
||||
|
||||
#include "server_abstractuserinterface.h"
|
||||
|
||||
class Server_RemoteUserInterface : public Server_AbstractUserInterface {
|
||||
public:
|
||||
Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer) : Server_AbstractUserInterface(_server, _userInfoContainer) { }
|
||||
|
||||
void sendProtocolItem(const Response &item);
|
||||
void sendProtocolItem(const SessionEvent &item);
|
||||
void sendProtocolItem(const GameEventContainer &item);
|
||||
void sendProtocolItem(const RoomEvent &item);
|
||||
};
|
||||
|
||||
#endif
|
46
common/serverinfo_user_container.cpp
Normal file
46
common/serverinfo_user_container.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include "serverinfo_user_container.h"
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
|
||||
ServerInfo_User_Container::ServerInfo_User_Container(ServerInfo_User *_userInfo)
|
||||
: userInfo(_userInfo)
|
||||
{
|
||||
}
|
||||
|
||||
ServerInfo_User_Container::ServerInfo_User_Container(const ServerInfo_User &_userInfo)
|
||||
: userInfo(new ServerInfo_User(_userInfo))
|
||||
{
|
||||
}
|
||||
|
||||
ServerInfo_User_Container::ServerInfo_User_Container(const ServerInfo_User_Container &other)
|
||||
{
|
||||
if (other.userInfo)
|
||||
userInfo = new ServerInfo_User(*other.userInfo);
|
||||
else
|
||||
userInfo = 0;
|
||||
}
|
||||
|
||||
ServerInfo_User_Container::~ServerInfo_User_Container()
|
||||
{
|
||||
delete userInfo;
|
||||
}
|
||||
|
||||
void ServerInfo_User_Container::setUserInfo(const ServerInfo_User &_userInfo)
|
||||
{
|
||||
userInfo = new ServerInfo_User;
|
||||
userInfo->CopyFrom(_userInfo);
|
||||
}
|
||||
|
||||
ServerInfo_User ServerInfo_User_Container::copyUserInfo(bool complete, bool moderatorInfo) const
|
||||
{
|
||||
ServerInfo_User result;
|
||||
if (userInfo) {
|
||||
result.CopyFrom(*userInfo);
|
||||
if (!moderatorInfo) {
|
||||
result.clear_address();
|
||||
result.clear_id();
|
||||
}
|
||||
if (!complete)
|
||||
result.clear_avatar_bmp();
|
||||
}
|
||||
return result;
|
||||
}
|
19
common/serverinfo_user_container.h
Normal file
19
common/serverinfo_user_container.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef SERVERINFO_USER_CONTAINER
|
||||
#define SERVERINFO_USER_CONTAINER
|
||||
|
||||
class ServerInfo_User;
|
||||
|
||||
class ServerInfo_User_Container {
|
||||
protected:
|
||||
ServerInfo_User *userInfo;
|
||||
public:
|
||||
ServerInfo_User_Container(ServerInfo_User *_userInfo = 0);
|
||||
ServerInfo_User_Container(const ServerInfo_User &_userInfo);
|
||||
ServerInfo_User_Container(const ServerInfo_User_Container &other);
|
||||
virtual ~ServerInfo_User_Container();
|
||||
ServerInfo_User *getUserInfo() const { return userInfo; }
|
||||
void setUserInfo(const ServerInfo_User &_userInfo);
|
||||
ServerInfo_User copyUserInfo(bool complete, bool moderatorInfo = false) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,8 +5,12 @@
|
|||
#include "server_protocolhandler.h"
|
||||
#include "server_room.h"
|
||||
|
||||
#include "get_pb_extension.h"
|
||||
#include "pb/isl_message.pb.h"
|
||||
#include "pb/event_server_complete_list.pb.h"
|
||||
#include "pb/event_user_message.pb.h"
|
||||
#include "pb/event_user_joined.pb.h"
|
||||
#include "pb/event_user_left.pb.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
void IslInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey)
|
||||
|
@ -37,6 +41,19 @@ IslInterface::~IslInterface()
|
|||
logger->logMessage("[ISL] session ended", this);
|
||||
|
||||
flushOutputBuffer();
|
||||
|
||||
QStringList usersToDelete;
|
||||
server->serverMutex.lock();
|
||||
QMapIterator<QString, Server_AbstractUserInterface *> extUsers = server->getExternalUsers();
|
||||
while (extUsers.hasNext()) {
|
||||
extUsers.next();
|
||||
if (extUsers.value()->getUserInfo()->server_id() == serverId)
|
||||
usersToDelete.append(extUsers.key());
|
||||
}
|
||||
server->serverMutex.unlock();
|
||||
|
||||
for (int i = 0; i < usersToDelete.size(); ++i)
|
||||
emit externalUserLeft(usersToDelete[i]);
|
||||
}
|
||||
|
||||
void IslInterface::initServer()
|
||||
|
@ -218,7 +235,63 @@ void IslInterface::transmitMessage(const IslMessage &item)
|
|||
emit outputBufferChanged();
|
||||
}
|
||||
|
||||
void IslInterface::sessionEvent_ServerCompleteList(const Event_ServerCompleteList &event)
|
||||
{
|
||||
for (int i = 0; i < event.user_list_size(); ++i) {
|
||||
ServerInfo_User temp(event.user_list(i));
|
||||
temp.set_server_id(serverId);
|
||||
emit externalUserJoined(temp);
|
||||
}
|
||||
}
|
||||
|
||||
void IslInterface::sessionEvent_UserMessage(const SessionEvent &sessionEvent, const Event_UserMessage &event)
|
||||
{
|
||||
QMutexLocker locker(&server->serverMutex);
|
||||
|
||||
Server_ProtocolHandler *userInterface = server->getUsers().value(QString::fromStdString(event.receiver_name()));
|
||||
if (userInterface)
|
||||
userInterface->sendProtocolItem(sessionEvent);
|
||||
}
|
||||
|
||||
void IslInterface::sessionEvent_UserJoined(const Event_UserJoined &event)
|
||||
{
|
||||
emit externalUserJoined(event.user_info());
|
||||
}
|
||||
|
||||
void IslInterface::sessionEvent_UserLeft(const Event_UserLeft &event)
|
||||
{
|
||||
emit externalUserLeft(QString::fromStdString(event.name()));
|
||||
}
|
||||
|
||||
void IslInterface::processSessionEvent(const SessionEvent &event)
|
||||
{
|
||||
switch (getPbExtension(event)) {
|
||||
case SessionEvent::SERVER_COMPLETE_LIST: sessionEvent_ServerCompleteList(event.GetExtension(Event_ServerCompleteList::ext)); break;
|
||||
case SessionEvent::USER_MESSAGE: sessionEvent_UserMessage(event, event.GetExtension(Event_UserMessage::ext)); break;
|
||||
case SessionEvent::USER_JOINED: sessionEvent_UserJoined(event.GetExtension(Event_UserJoined::ext)); break;
|
||||
case SessionEvent::USER_LEFT: sessionEvent_UserLeft(event.GetExtension(Event_UserLeft::ext)); break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
void IslInterface::processMessage(const IslMessage &item)
|
||||
{
|
||||
qDebug() << QString::fromStdString(item.DebugString());
|
||||
|
||||
switch (item.message_type()) {
|
||||
case IslMessage::SESSION_EVENT: processSessionEvent(item.session_event()); break;
|
||||
case IslMessage::RESPONSE: {
|
||||
break;
|
||||
}
|
||||
case IslMessage::GAME_COMMAND_CONTAINER: {
|
||||
break;
|
||||
}
|
||||
case IslMessage::GAME_EVENT_CONTAINER: {
|
||||
break;
|
||||
}
|
||||
case IslMessage::ROOM_EVENT: {
|
||||
break;
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,18 @@
|
|||
#include "servatrice.h"
|
||||
#include <QSslCertificate>
|
||||
#include <QWaitCondition>
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
|
||||
class Servatrice;
|
||||
class QSslSocket;
|
||||
class QSslKey;
|
||||
class IslMessage;
|
||||
|
||||
class Event_ServerCompleteList;
|
||||
class Event_UserMessage;
|
||||
class Event_UserJoined;
|
||||
class Event_UserLeft;
|
||||
|
||||
class IslInterface : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
|
@ -18,6 +24,9 @@ private slots:
|
|||
void flushOutputBuffer();
|
||||
signals:
|
||||
void outputBufferChanged();
|
||||
|
||||
void externalUserJoined(ServerInfo_User userInfo);
|
||||
void externalUserLeft(QString name);
|
||||
private:
|
||||
int serverId;
|
||||
int socketDescriptor;
|
||||
|
@ -33,6 +42,13 @@ private:
|
|||
bool messageInProgress;
|
||||
int messageLength;
|
||||
|
||||
void sessionEvent_ServerCompleteList(const Event_ServerCompleteList &event);
|
||||
void sessionEvent_UserMessage(const SessionEvent &sessionEvent, const Event_UserMessage &event);
|
||||
void sessionEvent_UserJoined(const Event_UserJoined &event);
|
||||
void sessionEvent_UserLeft(const Event_UserLeft &event);
|
||||
|
||||
void processSessionEvent(const SessionEvent &event);
|
||||
|
||||
void processMessage(const IslMessage &item);
|
||||
void sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey);
|
||||
public slots:
|
||||
|
|
|
@ -64,6 +64,8 @@ void Servatrice_IslServer::incomingConnection(int socketDescriptor)
|
|||
Servatrice::Servatrice(QSettings *_settings, QObject *parent)
|
||||
: Server(parent), dbMutex(QMutex::Recursive), settings(_settings), uptime(0), shutdownTimer(0)
|
||||
{
|
||||
qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
|
||||
|
||||
serverName = settings->value("server/name").toString();
|
||||
serverId = settings->value("server/id", 0).toInt();
|
||||
|
||||
|
@ -852,6 +854,8 @@ void Servatrice::addIslInterface(int serverId, IslInterface *interface)
|
|||
// Only call with islLock locked for writing
|
||||
|
||||
islInterfaces.insert(serverId, interface);
|
||||
connect(interface, SIGNAL(externalUserJoined(ServerInfo_User)), this, SLOT(externalUserJoined(ServerInfo_User)));
|
||||
connect(interface, SIGNAL(externalUserLeft(QString)), this, SLOT(externalUserLeft(QString)));
|
||||
}
|
||||
|
||||
void Servatrice::removeIslInterface(int serverId)
|
||||
|
@ -866,13 +870,10 @@ void Servatrice::doSendIslMessage(const IslMessage &msg, int serverId)
|
|||
{
|
||||
QReadLocker locker(&islLock);
|
||||
|
||||
qDebug() << "hallo";
|
||||
if (serverId == -1) {
|
||||
QMapIterator<int, IslInterface *> islIterator(islInterfaces);
|
||||
while (islIterator.hasNext()) {
|
||||
qDebug() << "welt";
|
||||
while (islIterator.hasNext())
|
||||
islIterator.next().value()->transmitMessage(msg);
|
||||
}
|
||||
} else {
|
||||
IslInterface *interface = islInterfaces.value(serverId);
|
||||
if (interface)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QSslKey>
|
||||
#include <QHostAddress>
|
||||
#include <QReadWriteLock>
|
||||
#include <QMetaType>
|
||||
#include "server.h"
|
||||
|
||||
class QSqlDatabase;
|
||||
|
@ -166,4 +167,6 @@ private:
|
|||
QMap<int, IslInterface *> islInterfaces;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ServerInfo_User)
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue