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