1 /***************************************************************************
2  *   Copyright (C) 2008 by Max-Wilhelm Bruker   *
3  *   brukie@laptop   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #include "server.h"
21 
22 #include "featureset.h"
23 #include "pb/event_connection_closed.pb.h"
24 #include "pb/event_list_rooms.pb.h"
25 #include "pb/event_user_joined.pb.h"
26 #include "pb/event_user_left.pb.h"
27 #include "pb/isl_message.pb.h"
28 #include "pb/session_event.pb.h"
29 #include "server_counter.h"
30 #include "server_database_interface.h"
31 #include "server_game.h"
32 #include "server_metatypes.h"
33 #include "server_player.h"
34 #include "server_protocolhandler.h"
35 #include "server_remoteuserinterface.h"
36 #include "server_room.h"
37 
38 #include <QCoreApplication>
39 #include <QDebug>
40 #include <QThread>
41 
Server(QObject * parent)42 Server::Server(QObject *parent) : QObject(parent), nextLocalGameId(0), tcpUserCount(0), webSocketUserCount(0)
43 {
44     qRegisterMetaType<ServerInfo_Ban>("ServerInfo_Ban");
45     qRegisterMetaType<ServerInfo_Game>("ServerInfo_Game");
46     qRegisterMetaType<ServerInfo_Room>("ServerInfo_Room");
47     qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
48     qRegisterMetaType<CommandContainer>("CommandContainer");
49     qRegisterMetaType<Response>("Response");
50     qRegisterMetaType<GameEventContainer>("GameEventContainer");
51     qRegisterMetaType<IslMessage>("IslMessage");
52     qRegisterMetaType<Command_JoinGame>("Command_JoinGame");
53 
54     connect(this, SIGNAL(sigSendIslMessage(IslMessage, int)), this, SLOT(doSendIslMessage(IslMessage, int)),
55             Qt::QueuedConnection);
56 }
57 
prepareDestroy()58 void Server::prepareDestroy()
59 {
60     roomsLock.lockForWrite();
61     QMapIterator<int, Server_Room *> roomIterator(rooms);
62     while (roomIterator.hasNext())
63         delete roomIterator.next().value();
64     rooms.clear();
65     roomsLock.unlock();
66 }
67 
setDatabaseInterface(Server_DatabaseInterface * _databaseInterface)68 void Server::setDatabaseInterface(Server_DatabaseInterface *_databaseInterface)
69 {
70     connect(this, SIGNAL(endSession(qint64)), _databaseInterface, SLOT(endSession(qint64)));
71     databaseInterfaces.insert(QThread::currentThread(), _databaseInterface);
72 }
73 
getDatabaseInterface() const74 Server_DatabaseInterface *Server::getDatabaseInterface() const
75 {
76     return databaseInterfaces.value(QThread::currentThread());
77 }
78 
loginUser(Server_ProtocolHandler * session,QString & name,const QString & password,QString & reasonStr,int & secondsLeft,QString & clientid,QString & clientVersion,QString &)79 AuthenticationResult Server::loginUser(Server_ProtocolHandler *session,
80                                        QString &name,
81                                        const QString &password,
82                                        QString &reasonStr,
83                                        int &secondsLeft,
84                                        QString &clientid,
85                                        QString &clientVersion,
86                                        QString & /* connectionType */)
87 {
88     if (name.size() > 35)
89         name = name.left(35);
90 
91     Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
92 
93     AuthenticationResult authState =
94         databaseInterface->checkUserPassword(session, name, password, clientid, reasonStr, secondsLeft);
95     if (authState == NotLoggedIn || authState == UserIsBanned || authState == UsernameInvalid ||
96         authState == UserIsInactive)
97         return authState;
98 
99     ServerInfo_User data = databaseInterface->getUserData(name, true);
100     data.set_address(session->getAddress().toStdString());
101     name = QString::fromStdString(data.name()); // Compensate for case indifference
102 
103     if (authState == PasswordRight) {
104         if (users.contains(name) || databaseInterface->userSessionExists(name)) {
105             if (users.contains(name)) {
106                 qDebug("Session already logged in, logging old session out");
107                 Event_ConnectionClosed event;
108                 event.set_reason(Event_ConnectionClosed::LOGGEDINELSEWERE);
109                 event.set_reason_str("You have been logged out due to logging in at another location.");
110                 event.set_end_time(QDateTime::currentDateTime().toTime_t());
111 
112                 SessionEvent *se = users.value(name)->prepareSessionEvent(event);
113                 users.value(name)->sendProtocolItem(*se);
114                 delete se;
115 
116                 users.value(name)->prepareDestroy();
117             } else {
118                 qDebug() << "Active session and sessions table inconsistent, please validate session table information "
119                             "for user "
120                          << name;
121             }
122         }
123 
124     } else if (authState == UnknownUser) {
125         // Change user name so that no two users have the same names,
126         // don't interfere with registered user names though.
127         if (getRegOnlyServerEnabled()) {
128             qDebug("Login denied: registration required");
129             databaseInterface->unlockSessionTables();
130             return RegistrationRequired;
131         }
132 
133         QString tempName = name;
134         int i = 0;
135         while (users.contains(tempName) || databaseInterface->activeUserExists(tempName) ||
136                databaseInterface->userSessionExists(tempName))
137             tempName = name + "_" + QString::number(++i);
138         name = tempName;
139         data.set_name(name.toStdString());
140     }
141 
142     QWriteLocker locker(&clientsLock);
143     databaseInterface->lockSessionTables();
144     users.insert(name, session);
145     qDebug() << "Server::loginUser:" << session << "name=" << name;
146 
147     data.set_session_id(static_cast<google::protobuf::uint64>(
148         databaseInterface->startSession(name, session->getAddress(), clientid, session->getConnectionType())));
149     databaseInterface->unlockSessionTables();
150 
151     usersBySessionId.insert(data.session_id(), session);
152 
153     qDebug() << "session id:" << data.session_id();
154     session->setUserInfo(data);
155 
156     Event_UserJoined event;
157     event.mutable_user_info()->CopyFrom(session->copyUserInfo(false));
158     SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
159     for (auto &client : clients)
160         if (client->getAcceptsUserListChanges())
161             client->sendProtocolItem(*se);
162     delete se;
163 
164     event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true));
165     locker.unlock();
166 
167     if (clientid.isEmpty()) {
168         // client id is empty, either out dated client or client has been modified
169         if (getClientIDRequiredEnabled())
170             return ClientIdRequired;
171     } else {
172         // update users database table with client id
173         databaseInterface->updateUsersClientID(name, clientid);
174     }
175 
176     databaseInterface->updateUsersLastLoginData(name, clientVersion);
177     se = Server_ProtocolHandler::prepareSessionEvent(event);
178     sendIsl_SessionEvent(*se);
179     delete se;
180 
181     return authState;
182 }
183 
addPersistentPlayer(const QString & userName,int roomId,int gameId,int playerId)184 void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
185 {
186     QWriteLocker locker(&persistentPlayersLock);
187     persistentPlayers.insert(userName, PlayerReference(roomId, gameId, playerId));
188 }
189 
removePersistentPlayer(const QString & userName,int roomId,int gameId,int playerId)190 void Server::removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
191 {
192     QWriteLocker locker(&persistentPlayersLock);
193     persistentPlayers.remove(userName, PlayerReference(roomId, gameId, playerId));
194 }
195 
getPersistentPlayerReferences(const QString & userName) const196 QList<PlayerReference> Server::getPersistentPlayerReferences(const QString &userName) const
197 {
198     QReadLocker locker(&persistentPlayersLock);
199     return persistentPlayers.values(userName);
200 }
201 
findUser(const QString & userName) const202 Server_AbstractUserInterface *Server::findUser(const QString &userName) const
203 {
204     // Call this only with clientsLock set.
205 
206     Server_AbstractUserInterface *userHandler = users.value(userName);
207     if (userHandler)
208         return userHandler;
209     else
210         return externalUsers.value(userName);
211 }
212 
addClient(Server_ProtocolHandler * client)213 void Server::addClient(Server_ProtocolHandler *client)
214 {
215     if (client->getConnectionType() == "tcp")
216         tcpUserCount++;
217 
218     if (client->getConnectionType() == "websocket")
219         webSocketUserCount++;
220 
221     QWriteLocker locker(&clientsLock);
222     clients << client;
223 }
224 
removeClient(Server_ProtocolHandler * client)225 void Server::removeClient(Server_ProtocolHandler *client)
226 {
227 
228     if (client->getConnectionType() == "tcp")
229         tcpUserCount--;
230 
231     if (client->getConnectionType() == "websocket")
232         webSocketUserCount--;
233 
234     QWriteLocker locker(&clientsLock);
235     clients.removeAt(clients.indexOf(client));
236     ServerInfo_User *data = client->getUserInfo();
237     if (data) {
238         Event_UserLeft event;
239         event.set_name(data->name());
240         SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
241         for (auto &client : clients)
242             if (client->getAcceptsUserListChanges())
243                 client->sendProtocolItem(*se);
244         sendIsl_SessionEvent(*se);
245         delete se;
246 
247         users.remove(QString::fromStdString(data->name()));
248         qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name());
249 
250         if (data->has_session_id()) {
251             const qint64 sessionId = data->session_id();
252             usersBySessionId.remove(sessionId);
253             emit endSession(sessionId);
254             qDebug() << "closed session id:" << sessionId;
255         }
256     }
257     qDebug() << "Server::removeClient: removed" << (void *)client << ";" << clients.size() << "clients; "
258              << users.size() << "users left";
259 }
260 
getOnlineModeratorList() const261 QList<QString> Server::getOnlineModeratorList() const
262 {
263     // clients list should be locked by calling function prior to iteration otherwise sigfaults may occur
264     QList<QString> results;
265     for (auto &client : clients) {
266         ServerInfo_User *data = client->getUserInfo();
267 
268         // TODO: this line should be updated in the event there is any type of new user level created
269         if (data &&
270             (data->user_level() & ServerInfo_User::IsModerator || data->user_level() & ServerInfo_User::IsAdmin))
271             results << QString::fromStdString(data->name()).simplified();
272     }
273     return results;
274 }
275 
externalUserJoined(const ServerInfo_User & userInfo)276 void Server::externalUserJoined(const ServerInfo_User &userInfo)
277 {
278     // This function is always called from the main thread via signal/slot.
279     clientsLock.lockForWrite();
280 
281     Server_RemoteUserInterface *newUser = new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo));
282     externalUsers.insert(QString::fromStdString(userInfo.name()), newUser);
283     externalUsersBySessionId.insert(userInfo.session_id(), newUser);
284 
285     Event_UserJoined event;
286     event.mutable_user_info()->CopyFrom(userInfo);
287 
288     SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
289     for (auto &client : clients)
290         if (client->getAcceptsUserListChanges())
291             client->sendProtocolItem(*se);
292     delete se;
293     clientsLock.unlock();
294 
295     ResponseContainer rc(-1);
296     newUser->joinPersistentGames(rc);
297     newUser->sendResponseContainer(rc, Response::RespNothing);
298 }
299 
externalUserLeft(const QString & userName)300 void Server::externalUserLeft(const QString &userName)
301 {
302     // This function is always called from the main thread via signal/slot.
303 
304     clientsLock.lockForWrite();
305     Server_AbstractUserInterface *user = externalUsers.take(userName);
306     externalUsersBySessionId.remove(user->getUserInfo()->session_id());
307     clientsLock.unlock();
308 
309     QMap<int, QPair<int, int>> userGames(user->getGames());
310     QMapIterator<int, QPair<int, int>> userGamesIterator(userGames);
311     roomsLock.lockForRead();
312     while (userGamesIterator.hasNext()) {
313         userGamesIterator.next();
314         Server_Room *room = rooms.value(userGamesIterator.value().first);
315         if (!room)
316             continue;
317 
318         QReadLocker roomGamesLocker(&room->gamesLock);
319         Server_Game *game = room->getGames().value(userGamesIterator.key());
320         if (!game)
321             continue;
322 
323         QMutexLocker gameLocker(&game->gameMutex);
324         Server_Player *player = game->getPlayers().value(userGamesIterator.value().second);
325         if (!player)
326             continue;
327 
328         player->disconnectClient();
329     }
330     roomsLock.unlock();
331 
332     delete user;
333 
334     Event_UserLeft event;
335     event.set_name(userName.toStdString());
336 
337     SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
338     clientsLock.lockForRead();
339     for (auto &client : clients)
340         if (client->getAcceptsUserListChanges())
341             client->sendProtocolItem(*se);
342     clientsLock.unlock();
343     delete se;
344 }
345 
externalRoomUserJoined(int roomId,const ServerInfo_User & userInfo)346 void Server::externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo)
347 {
348     // This function is always called from the main thread via signal/slot.
349     QReadLocker locker(&roomsLock);
350 
351     Server_Room *room = rooms.value(roomId);
352     if (!room) {
353         qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found";
354         return;
355     }
356     room->addExternalUser(userInfo);
357 }
358 
externalRoomUserLeft(int roomId,const QString & userName)359 void Server::externalRoomUserLeft(int roomId, const QString &userName)
360 {
361     // This function is always called from the main thread via signal/slot.
362     QReadLocker locker(&roomsLock);
363 
364     Server_Room *room = rooms.value(roomId);
365     if (!room) {
366         qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found";
367         return;
368     }
369     room->removeExternalUser(userName);
370 }
371 
externalRoomSay(int roomId,const QString & userName,const QString & message)372 void Server::externalRoomSay(int roomId, const QString &userName, const QString &message)
373 {
374     // This function is always called from the main thread via signal/slot.
375     QReadLocker locker(&roomsLock);
376 
377     Server_Room *room = rooms.value(roomId);
378     if (!room) {
379         qDebug() << "externalRoomSay: room id=" << roomId << "not found";
380         return;
381     }
382     room->say(userName, message, false);
383 
384     getDatabaseInterface()->logMessage(0, userName, "ISL", message, Server_DatabaseInterface::MessageTargetIslRoom,
385                                        room->getId(), room->getName());
386 }
387 
externalRoomGameListChanged(int roomId,const ServerInfo_Game & gameInfo)388 void Server::externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo)
389 {
390     // This function is always called from the main thread via signal/slot.
391     QReadLocker locker(&roomsLock);
392 
393     Server_Room *room = rooms.value(roomId);
394     if (!room) {
395         qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found";
396         return;
397     }
398     room->updateExternalGameList(gameInfo);
399 }
400 
externalJoinGameCommandReceived(const Command_JoinGame & cmd,int cmdId,int roomId,int serverId,qint64 sessionId)401 void Server::externalJoinGameCommandReceived(const Command_JoinGame &cmd,
402                                              int cmdId,
403                                              int roomId,
404                                              int serverId,
405                                              qint64 sessionId)
406 {
407     // This function is always called from the main thread via signal/slot.
408 
409     try {
410         QReadLocker roomsLocker(&roomsLock);
411         QReadLocker clientsLocker(&clientsLock);
412 
413         Server_Room *room = rooms.value(roomId);
414         if (!room) {
415             qDebug() << "externalJoinGameCommandReceived: room id=" << roomId << "not found";
416             throw Response::RespNotInRoom;
417         }
418         Server_AbstractUserInterface *userInterface = externalUsersBySessionId.value(sessionId);
419         if (!userInterface) {
420             qDebug() << "externalJoinGameCommandReceived: session id=" << sessionId << "not found";
421             throw Response::RespNotInRoom;
422         }
423 
424         ResponseContainer responseContainer(cmdId);
425         Response::ResponseCode responseCode = room->processJoinGameCommand(cmd, responseContainer, userInterface);
426         userInterface->sendResponseContainer(responseContainer, responseCode);
427     } catch (Response::ResponseCode &code) {
428         Response response;
429         response.set_cmd_id(static_cast<google::protobuf::uint64>(cmdId));
430         response.set_response_code(code);
431 
432         sendIsl_Response(response, serverId, sessionId);
433     }
434 }
435 
externalGameCommandContainerReceived(const CommandContainer & cont,int playerId,int serverId,qint64 sessionId)436 void Server::externalGameCommandContainerReceived(const CommandContainer &cont,
437                                                   int playerId,
438                                                   int serverId,
439                                                   qint64 sessionId)
440 {
441     // This function is always called from the main thread via signal/slot.
442 
443     try {
444         ResponseContainer responseContainer(static_cast<int>(cont.cmd_id()));
445         Response::ResponseCode finalResponseCode = Response::RespOk;
446 
447         QReadLocker roomsLocker(&roomsLock);
448         Server_Room *room = rooms.value(cont.room_id());
449         if (!room) {
450             qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found";
451             throw Response::RespNotInRoom;
452         }
453 
454         QReadLocker roomGamesLocker(&room->gamesLock);
455         Server_Game *game = room->getGames().value(cont.game_id());
456         if (!game) {
457             qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found";
458             throw Response::RespNotInRoom;
459         }
460 
461         QMutexLocker gameLocker(&game->gameMutex);
462         Server_Player *player = game->getPlayers().value(playerId);
463         if (!player) {
464             qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found";
465             throw Response::RespNotInRoom;
466         }
467 
468         GameEventStorage ges;
469         for (int i = cont.game_command_size() - 1; i >= 0; --i) {
470             const GameCommand &sc = cont.game_command(i);
471             qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString());
472 
473             Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges);
474 
475             if (resp != Response::RespOk)
476                 finalResponseCode = resp;
477         }
478         ges.sendToGame(game);
479 
480         if (finalResponseCode != Response::RespNothing) {
481             player->playerMutex.lock();
482             player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode);
483             player->playerMutex.unlock();
484         }
485     } catch (Response::ResponseCode code) {
486         Response response;
487         response.set_cmd_id(cont.cmd_id());
488         response.set_response_code(code);
489 
490         sendIsl_Response(response, serverId, sessionId);
491     }
492 }
493 
externalGameEventContainerReceived(const GameEventContainer & cont,qint64 sessionId)494 void Server::externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId)
495 {
496     // This function is always called from the main thread via signal/slot.
497 
498     QReadLocker usersLocker(&clientsLock);
499 
500     Server_ProtocolHandler *client = usersBySessionId.value(sessionId);
501     if (!client) {
502         qDebug() << "externalGameEventContainerReceived: session" << sessionId << "not found";
503         return;
504     }
505     client->sendProtocolItem(cont);
506 }
507 
externalResponseReceived(const Response & resp,qint64 sessionId)508 void Server::externalResponseReceived(const Response &resp, qint64 sessionId)
509 {
510     // This function is always called from the main thread via signal/slot.
511 
512     QReadLocker usersLocker(&clientsLock);
513 
514     Server_ProtocolHandler *client = usersBySessionId.value(sessionId);
515     if (!client) {
516         qDebug() << "externalResponseReceived: session" << sessionId << "not found";
517         return;
518     }
519     client->sendProtocolItem(resp);
520 }
521 
broadcastRoomUpdate(const ServerInfo_Room & roomInfo,bool sendToIsl)522 void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl)
523 {
524     // This function is always called from the main thread via signal/slot.
525 
526     Event_ListRooms event;
527     event.add_room_list()->CopyFrom(roomInfo);
528 
529     SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
530 
531     clientsLock.lockForRead();
532     for (auto &client : clients)
533         if (client->getAcceptsRoomListChanges())
534             client->sendProtocolItem(*se);
535     clientsLock.unlock();
536 
537     if (sendToIsl)
538         sendIsl_SessionEvent(*se);
539 
540     delete se;
541 }
542 
addRoom(Server_Room * newRoom)543 void Server::addRoom(Server_Room *newRoom)
544 {
545     QWriteLocker locker(&roomsLock);
546     qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName();
547     rooms.insert(newRoom->getId(), newRoom);
548     connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)),
549             Qt::QueuedConnection);
550 }
551 
getUsersCount() const552 int Server::getUsersCount() const
553 {
554     QReadLocker locker(&clientsLock);
555     return users.size();
556 }
557 
getGamesCount() const558 int Server::getGamesCount() const
559 {
560     int result = 0;
561     QReadLocker locker(&roomsLock);
562     QMapIterator<int, Server_Room *> roomIterator(rooms);
563     while (roomIterator.hasNext()) {
564         Server_Room *room = roomIterator.next().value();
565         QReadLocker roomLocker(&room->gamesLock);
566         result += room->getGames().size();
567     }
568     return result;
569 }
570 
sendIsl_Response(const Response & item,int serverId,qint64 sessionId)571 void Server::sendIsl_Response(const Response &item, int serverId, qint64 sessionId)
572 {
573     IslMessage msg;
574     msg.set_message_type(IslMessage::RESPONSE);
575     if (sessionId != -1)
576         msg.set_session_id(static_cast<google::protobuf::uint64>(sessionId));
577     msg.mutable_response()->CopyFrom(item);
578 
579     emit sigSendIslMessage(msg, serverId);
580 }
581 
sendIsl_SessionEvent(const SessionEvent & item,int serverId,qint64 sessionId)582 void Server::sendIsl_SessionEvent(const SessionEvent &item, int serverId, qint64 sessionId)
583 {
584     IslMessage msg;
585     msg.set_message_type(IslMessage::SESSION_EVENT);
586     if (sessionId != -1)
587         msg.set_session_id(static_cast<google::protobuf::uint64>(sessionId));
588     msg.mutable_session_event()->CopyFrom(item);
589 
590     emit sigSendIslMessage(msg, serverId);
591 }
592 
sendIsl_GameEventContainer(const GameEventContainer & item,int serverId,qint64 sessionId)593 void Server::sendIsl_GameEventContainer(const GameEventContainer &item, int serverId, qint64 sessionId)
594 {
595     IslMessage msg;
596     msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER);
597     if (sessionId != -1)
598         msg.set_session_id(static_cast<google::protobuf::uint64>(sessionId));
599     msg.mutable_game_event_container()->CopyFrom(item);
600 
601     emit sigSendIslMessage(msg, serverId);
602 }
603 
sendIsl_RoomEvent(const RoomEvent & item,int serverId,qint64 sessionId)604 void Server::sendIsl_RoomEvent(const RoomEvent &item, int serverId, qint64 sessionId)
605 {
606     IslMessage msg;
607     msg.set_message_type(IslMessage::ROOM_EVENT);
608     if (sessionId != -1)
609         msg.set_session_id(static_cast<google::protobuf::uint64>(sessionId));
610     msg.mutable_room_event()->CopyFrom(item);
611 
612     emit sigSendIslMessage(msg, serverId);
613 }
614 
sendIsl_GameCommand(const CommandContainer & item,int serverId,qint64 sessionId,int roomId,int playerId)615 void Server::sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId)
616 {
617     IslMessage msg;
618     msg.set_message_type(IslMessage::GAME_COMMAND_CONTAINER);
619     msg.set_session_id(static_cast<google::protobuf::uint64>(sessionId));
620     msg.set_player_id(playerId);
621 
622     CommandContainer *cont = msg.mutable_game_command();
623     cont->CopyFrom(item);
624     cont->set_room_id(static_cast<google::protobuf::uint32>(roomId));
625 
626     emit sigSendIslMessage(msg, serverId);
627 }
628 
sendIsl_RoomCommand(const CommandContainer & item,int serverId,qint64 sessionId,int roomId)629 void Server::sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId)
630 {
631     IslMessage msg;
632     msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER);
633     msg.set_session_id(static_cast<google::protobuf::uint64>(sessionId));
634 
635     CommandContainer *cont = msg.mutable_room_command();
636     cont->CopyFrom(item);
637     cont->set_room_id(static_cast<google::protobuf::uint32>(roomId));
638 
639     emit sigSendIslMessage(msg, serverId);
640 }
641