more ServerNetwork code

This commit is contained in:
Max-Wilhelm Bruker 2012-03-04 19:23:43 +01:00
parent 6bbc76af2b
commit c9b66e4239
21 changed files with 441 additions and 35 deletions

View file

@ -34,8 +34,6 @@ SET(common_HEADERS
FIND_PACKAGE(Qt4 REQUIRED)
FIND_PACKAGE(Protobuf REQUIRED)
set(CMAKE_BUILD_TYPE Release)
QT4_WRAP_CPP(common_HEADERS_MOC ${common_HEADERS})
INCLUDE(${QT_USE_FILE})
INCLUDE_DIRECTORIES(pb)

View file

@ -83,6 +83,7 @@ SET(PROTO_FILES
event_reveal_cards.proto
event_roll_die.proto
event_room_say.proto
event_server_complete_list.proto
event_server_identification.proto
event_server_message.proto
event_server_shutdown.proto
@ -132,6 +133,7 @@ SET(PROTO_FILES
serverinfo_room.proto
serverinfo_user.proto
serverinfo_zone.proto
servernetwork_message.proto
server_message.proto
session_commands.proto
session_event.proto

View file

@ -0,0 +1,12 @@
import "session_event.proto";
import "serverinfo_user.proto";
import "serverinfo_room.proto";
message Event_ServerCompleteList {
extend SessionEvent {
optional Event_ServerCompleteList ext = 600;
}
optional uint32 server_id = 1;
repeated ServerInfo_User user_list = 2;
repeated ServerInfo_Room room_list = 3;
}

View file

@ -0,0 +1,24 @@
import "response.proto";
import "session_event.proto";
import "commands.proto";
import "game_event_container.proto";
import "room_event.proto";
message ServerNetworkMessage {
enum MessageType {
RESPONSE = 0;
SESSION_EVENT = 1;
GAME_COMMAND_CONTAINER = 2;
GAME_EVENT_CONTAINER = 3;
ROOM_EVENT = 4;
}
optional MessageType message_type = 1;
optional sint32 game_id = 10;
optional Response response = 100;
optional SessionEvent session_event = 101;
optional CommandContainer game_command = 102;
optional GameEventContainer game_event_container = 103;
optional RoomEvent room_event = 104;
}

View file

@ -1,6 +1,7 @@
message SessionEvent {
enum SessionEventType {
SERVER_IDENTIFICATION = 500;
SERVER_COMPLETE_LIST = 600;
SERVER_MESSAGE = 1000;
SERVER_SHUTDOWN = 1001;
CONNECTION_CLOSED = 1002;

View file

@ -54,6 +54,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
QMutexLocker locker(&serverMutex);
if (name.size() > 35)
name = name.left(35);
AuthenticationResult authState = checkUserPassword(session, name, password, reasonStr);
if ((authState == NotLoggedIn) || (authState == UserIsBanned))
return authState;
@ -62,8 +63,10 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
data.set_address(session->getAddress().toStdString());
name = QString::fromStdString(data.name()); // Compensate for case indifference
lockSessionTables();
if (authState == PasswordRight) {
if (users.contains(name)) {
if (users.contains(name) || userSessionExists(name)) {
qDebug("Login denied: would overwrite old session");
return WouldOverwriteOldSession;
}
@ -72,7 +75,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
// don't interfere with registered user names though.
QString tempName = name;
int i = 0;
while (users.contains(tempName) || userExists(tempName))
while (users.contains(tempName) || userExists(tempName) || userSessionExists(tempName))
tempName = name + "_" + QString::number(++i);
name = tempName;
data.set_name(name.toStdString());
@ -83,7 +86,9 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
users.insert(name, session);
qDebug() << "Server::loginUser: name=" << name;
session->setSessionId(startSession(name, session->getAddress()));
session->setSessionId(startSession(name, session->getAddress()));
unlockSessionTables();
qDebug() << "session id:" << session->getSessionId();
Event_UserJoined event;

View file

@ -65,6 +65,11 @@ protected:
int getGamesCount() const;
int nextGameId, nextReplayId;
void addRoom(Server_Room *newRoom);
virtual void clearSessionTables() { }
virtual void lockSessionTables() { }
virtual void unlockSessionTables() { }
virtual bool userSessionExists(const QString &userName) { return false; }
};
#endif

View file

@ -270,6 +270,7 @@ void Server_Game::doStartGameIfReady()
activePlayer = -1;
nextTurn();
locker.unlock();
room->broadcastGameListUpdate(this);
}

View file

@ -577,6 +577,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message
if (authState == NotLoggedIn)
return Response::RespLoginNeeded;
server->serverMutex.lock();
QString receiver = QString::fromStdString(cmd.user_name());
Server_ProtocolHandler *userHandler = server->getUsers().value(receiver);
if (!userHandler)
@ -592,6 +593,8 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message
SessionEvent *se = prepareSessionEvent(event);
userHandler->sendProtocolItem(*se);
rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se);
server->serverMutex.unlock();
return Response::RespOk;
}
@ -631,10 +634,12 @@ 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)
return Response::RespNameNotFound;
re->mutable_user_info()->CopyFrom(handler->copyUserInfo(true, userInfo->user_level() & ServerInfo_User::IsModerator));
server->serverMutex.unlock();
}
rc.setResponseExtension(re);
@ -690,9 +695,11 @@ Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUs
return Response::RespLoginNeeded;
Response_ListUsers *re = new Response_ListUsers;
server->serverMutex.lock();
QMapIterator<QString, Server_ProtocolHandler *> userIterator = server->getUsers();
while (userIterator.hasNext())
re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
server->serverMutex.unlock();
acceptsUserListChanges = true;

View file

@ -24,7 +24,7 @@ Server_Room::~Server_Room()
delete gameList[i];
games.clear();
clear();
userList.clear();
}
Server *Server_Room::getServer() const
@ -39,7 +39,7 @@ ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool upd
ServerInfo_Room result;
result.set_room_id(id);
result.set_game_count(games.size());
result.set_player_count(size());
result.set_player_count(userList.size());
if (!updating) {
result.set_name(name.toStdString());
@ -52,8 +52,8 @@ ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool upd
while (gameIterator.hasNext())
result.add_game_list()->CopyFrom(gameIterator.next().value()->getInfo());
for (int i = 0; i < size(); ++i)
result.add_user_list()->CopyFrom(at(i)->copyUserInfo(false));
for (int i = 0; i < userList.size(); ++i)
result.add_user_list()->CopyFrom(userList[i]->copyUserInfo(false));
}
if (complete || showGameTypes)
for (int i = 0; i < gameTypes.size(); ++i) {
@ -75,21 +75,22 @@ RoomEvent *Server_Room::prepareRoomEvent(const ::google::protobuf::Message &room
void Server_Room::addClient(Server_ProtocolHandler *client)
{
QMutexLocker locker(&roomMutex);
Event_JoinRoom event;
event.mutable_user_info()->CopyFrom(client->copyUserInfo(false));
sendRoomEvent(prepareRoomEvent(event));
append(client);
roomMutex.lock();
userList.append(client);
roomMutex.unlock();
emit roomInfoChanged();
}
void Server_Room::removeClient(Server_ProtocolHandler *client)
{
QMutexLocker locker(&roomMutex);
removeAt(indexOf(client));
roomMutex.lock();
userList.removeAt(userList.indexOf(client));
roomMutex.unlock();
Event_LeaveRoom event;
event.set_name(client->getUserInfo()->name());
@ -110,8 +111,8 @@ void Server_Room::sendRoomEvent(RoomEvent *event)
{
QMutexLocker locker(&roomMutex);
for (int i = 0; i < size(); ++i)
at(i)->sendProtocolItem(*event);
for (int i = 0; i < userList.size(); ++i)
userList[i]->sendProtocolItem(*event);
delete event;
}

View file

@ -16,7 +16,7 @@ class ServerInfo_Game;
class Server_Game;
class Server;
class Server_Room : public QObject, public QList<Server_ProtocolHandler *> {
class Server_Room : public QObject {
Q_OBJECT
signals:
void roomInfoChanged();
@ -28,6 +28,7 @@ private:
QString joinMessage;
QStringList gameTypes;
QMap<int, Server_Game *> games;
QList<Server_ProtocolHandler *> userList;
public:
mutable QMutex roomMutex;
Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent);