Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Donald Haase
Cockatrice
Commits
d50d179b
Commit
d50d179b
authored
Feb 20, 2012
by
Max-Wilhelm Bruker
Browse files
server-side replay support
parent
7cec4426
Changes
13
Show whitespace changes
Inline
Side-by-side
cockatrice/src/localserver.h
View file @
d50d179b
...
...
@@ -11,23 +11,10 @@ class LocalServer : public Server
public:
LocalServer
(
QObject
*
parent
=
0
);
~
LocalServer
();
AuthenticationResult
checkUserPassword
(
Server_ProtocolHandler
*
/*handler*/
,
const
QString
&
/*user*/
,
const
QString
&
/*password*/
,
QString
&
/*reasonStr*/
)
{
return
UnknownUser
;
}
QString
getLoginMessage
()
const
{
return
QString
();
}
bool
getGameShouldPing
()
const
{
return
false
;
}
int
getMaxGameInactivityTime
()
const
{
return
9999999
;
}
int
getMaxPlayerInactivityTime
()
const
{
return
9999999
;
}
bool
getThreaded
()
const
{
return
false
;
}
LocalServerInterface
*
newConnection
();
protected:
int
startSession
(
const
QString
&
/*userName*/
,
const
QString
&
/*address*/
)
{
return
-
1
;
}
void
endSession
(
int
/*sessionId*/
)
{
}
bool
userExists
(
const
QString
&
/*name*/
)
{
return
false
;
}
ServerInfo_User
getUserData
(
const
QString
&
name
);
QMap
<
QString
,
ServerInfo_User
>
getBuddyList
(
const
QString
&
/*name*/
)
{
return
QMap
<
QString
,
ServerInfo_User
>
();
}
QMap
<
QString
,
ServerInfo_User
>
getIgnoreList
(
const
QString
&
/*name*/
)
{
return
QMap
<
QString
,
ServerInfo_User
>
();
}
bool
isInBuddyList
(
const
QString
&
/*whoseList*/
,
const
QString
&
/*who*/
)
{
return
false
;
}
bool
isInIgnoreList
(
const
QString
&
/*whoseList*/
,
const
QString
&
/*who*/
)
{
return
false
;
}
};
#endif
\ No newline at end of file
common/pb/CMakeLists.txt
View file @
d50d179b
...
...
@@ -95,6 +95,7 @@ SET(PROTO_FILES
game_event_container.proto
game_event_context.proto
game_event.proto
game_replay.proto
moderator_commands.proto
move_card_to_zone.proto
response_deck_download.proto
...
...
common/pb/game_event_container.proto
View file @
d50d179b
...
...
@@ -5,4 +5,5 @@ message GameEventContainer {
optional
uint32
game_id
=
1
;
repeated
GameEvent
event_list
=
2
;
optional
GameEventContext
context
=
3
;
optional
uint32
seconds_elapsed
=
4
;
}
common/pb/game_replay.proto
0 → 100644
View file @
d50d179b
import
"serverinfo_game.proto"
;
import
"game_event_container.proto"
;
message
GameReplay
{
optional
ServerInfo_Game
game_info
=
1
;
repeated
GameEventContainer
event_list
=
2
;
}
common/pb/serverinfo_game.proto
View file @
d50d179b
...
...
@@ -15,4 +15,5 @@ message ServerInfo_Game {
optional
bool
spectators_allowed
=
12
;
optional
bool
spectators_need_password
=
13
;
optional
uint32
spectators_count
=
14
;
optional
uint32
start_time
=
15
;
}
common/server.h
View file @
d50d179b
...
...
@@ -10,6 +10,7 @@
class
Server_Game
;
class
Server_Room
;
class
Server_ProtocolHandler
;
class
GameReplay
;
enum
AuthenticationResult
{
NotLoggedIn
=
0
,
PasswordRight
=
1
,
UnknownUser
=
2
,
WouldOverwriteOldSession
=
3
,
UserIsBanned
=
4
};
...
...
@@ -31,31 +32,33 @@ public:
const
QMap
<
QString
,
Server_ProtocolHandler
*>
&
getUsers
()
const
{
return
users
;
}
void
addClient
(
Server_ProtocolHandler
*
player
);
void
removeClient
(
Server_ProtocolHandler
*
player
);
virtual
QString
getLoginMessage
()
const
=
0
;
virtual
QString
getLoginMessage
()
const
{
return
QString
();
}
virtual
bool
getGameShouldPing
()
const
=
0
;
virtual
int
getMaxGameInactivityTime
()
const
=
0
;
virtual
int
getMaxPlayerInactivityTime
()
const
=
0
;
virtual
bool
getGameShouldPing
()
const
{
return
false
;
}
virtual
int
getMaxGameInactivityTime
()
const
{
return
9999999
;
}
virtual
int
getMaxPlayerInactivityTime
()
const
{
return
9999999
;
}
virtual
int
getMessageCountingInterval
()
const
{
return
0
;
}
virtual
int
getMaxMessageCountPerInterval
()
const
{
return
0
;
}
virtual
int
getMaxMessageSizePerInterval
()
const
{
return
0
;
}
virtual
int
getMaxGamesPerUser
()
const
{
return
0
;
}
virtual
bool
getThreaded
()
const
=
0
;
virtual
bool
getThreaded
()
const
{
return
false
;
}
virtual
QMap
<
QString
,
ServerInfo_User
>
getBuddyList
(
const
QString
&
name
)
=
0
;
virtual
QMap
<
QString
,
ServerInfo_User
>
getIgnoreList
(
const
QString
&
name
)
=
0
;
virtual
bool
isInBuddyList
(
const
QString
&
whoseList
,
const
QString
&
who
)
=
0
;
virtual
bool
isInIgnoreList
(
const
QString
&
whoseList
,
const
QString
&
who
)
=
0
;
virtual
QMap
<
QString
,
ServerInfo_User
>
getBuddyList
(
const
QString
&
name
)
{
return
QMap
<
QString
,
ServerInfo_User
>
();
}
virtual
QMap
<
QString
,
ServerInfo_User
>
getIgnoreList
(
const
QString
&
name
)
{
return
QMap
<
QString
,
ServerInfo_User
>
();
}
virtual
bool
isInBuddyList
(
const
QString
&
whoseList
,
const
QString
&
who
)
{
return
false
;
}
virtual
bool
isInIgnoreList
(
const
QString
&
whoseList
,
const
QString
&
who
)
{
return
false
;
}
virtual
void
storeGameInformation
(
int
secondsElapsed
,
const
QStringList
&
allPlayersEver
,
const
GameReplay
&
replay
)
{
}
protected:
void
prepareDestroy
();
QList
<
Server_ProtocolHandler
*>
clients
;
QMap
<
QString
,
Server_ProtocolHandler
*>
users
;
QMap
<
int
,
Server_Room
*>
rooms
;
virtual
int
startSession
(
const
QString
&
userName
,
const
QString
&
address
)
=
0
;
virtual
void
endSession
(
int
sessionId
)
=
0
;
virtual
bool
userExists
(
const
QString
&
user
)
=
0
;
virtual
AuthenticationResult
checkUserPassword
(
Server_ProtocolHandler
*
handler
,
const
QString
&
user
,
const
QString
&
password
,
QString
&
reason
)
=
0
;
virtual
int
startSession
(
const
QString
&
userName
,
const
QString
&
address
)
{
return
-
1
;
}
virtual
void
endSession
(
int
sessionId
)
{
}
virtual
bool
userExists
(
const
QString
&
user
)
{
return
false
;
}
virtual
AuthenticationResult
checkUserPassword
(
Server_ProtocolHandler
*
handler
,
const
QString
&
user
,
const
QString
&
password
,
QString
&
reason
)
{
return
UnknownUser
;
}
virtual
ServerInfo_User
getUserData
(
const
QString
&
name
)
=
0
;
int
getUsersCount
()
const
;
int
getGamesCount
()
const
;
...
...
common/server_game.cpp
View file @
d50d179b
...
...
@@ -39,13 +39,17 @@
#include
"pb/event_set_active_player.pb.h"
#include
"pb/event_set_active_phase.pb.h"
#include
"pb/serverinfo_playerping.pb.h"
#include
"pb/game_replay.pb.h"
#include
<google/protobuf/descriptor.h>
#include
<QTimer>
#include
<QDebug>
Server_Game
::
Server_Game
(
Server_ProtocolHandler
*
_creator
,
int
_gameId
,
const
QString
&
_description
,
const
QString
&
_password
,
int
_maxPlayers
,
const
QList
<
int
>
&
_gameTypes
,
bool
_onlyBuddies
,
bool
_onlyRegistered
,
bool
_spectatorsAllowed
,
bool
_spectatorsNeedPassword
,
bool
_spectatorsCanTalk
,
bool
_spectatorsSeeEverything
,
Server_Room
*
_room
)
:
QObject
(),
room
(
_room
),
hostId
(
0
),
creatorInfo
(
new
ServerInfo_User
(
_creator
->
copyUserInfo
(
false
))),
gameStarted
(
false
),
gameId
(
_gameId
),
description
(
_description
),
password
(
_password
),
maxPlayers
(
_maxPlayers
),
gameTypes
(
_gameTypes
),
activePlayer
(
-
1
),
activePhase
(
-
1
),
onlyBuddies
(
_onlyBuddies
),
onlyRegistered
(
_onlyRegistered
),
spectatorsAllowed
(
_spectatorsAllowed
),
spectatorsNeedPassword
(
_spectatorsNeedPassword
),
spectatorsCanTalk
(
_spectatorsCanTalk
),
spectatorsSeeEverything
(
_spectatorsSeeEverything
),
inactivityCounter
(
0
),
secondsElapsed
(
0
),
gameMutex
(
QMutex
::
Recursive
)
:
QObject
(),
room
(
_room
),
hostId
(
0
),
creatorInfo
(
new
ServerInfo_User
(
_creator
->
copyUserInfo
(
false
))),
gameStarted
(
false
),
gameId
(
_gameId
),
description
(
_description
),
password
(
_password
),
maxPlayers
(
_maxPlayers
),
gameTypes
(
_gameTypes
),
activePlayer
(
-
1
),
activePhase
(
-
1
),
onlyBuddies
(
_onlyBuddies
),
onlyRegistered
(
_onlyRegistered
),
spectatorsAllowed
(
_spectatorsAllowed
),
spectatorsNeedPassword
(
_spectatorsNeedPassword
),
spectatorsCanTalk
(
_spectatorsCanTalk
),
spectatorsSeeEverything
(
_spectatorsSeeEverything
),
inactivityCounter
(
0
),
secondsElapsed
(
0
),
startTime
(
QDateTime
::
currentDateTime
()),
gameMutex
(
QMutex
::
Recursive
)
{
replay
=
new
GameReplay
;
replay
->
mutable_game_info
()
->
CopyFrom
(
getInfo
());
connect
(
this
,
SIGNAL
(
sigStartGameIfReady
()),
this
,
SLOT
(
doStartGameIfReady
()),
Qt
::
QueuedConnection
);
addPlayer
(
_creator
,
false
,
false
);
...
...
@@ -59,8 +63,8 @@ Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QS
Server_Game
::~
Server_Game
()
{
QMutexLocker
roomLocker
(
&
room
->
roomMutex
);
Q
Mutex
Locker
locker
(
&
gameMutex
);
room
->
roomMutex
.
lock
(
);
game
Mutex
.
lock
(
);
sendGameEventContainer
(
prepareGameEvent
(
Event_GameClosed
(),
-
1
));
...
...
@@ -72,6 +76,13 @@ Server_Game::~Server_Game()
room
->
removeGame
(
this
);
delete
creatorInfo
;
creatorInfo
=
0
;
gameMutex
.
unlock
();
room
->
roomMutex
.
unlock
();
room
->
getServer
()
->
storeGameInformation
(
secondsElapsed
,
allPlayersEver
.
toList
(),
*
replay
);
delete
replay
;
qDebug
()
<<
"Server_Game destructor: gameId="
<<
gameId
;
}
...
...
@@ -146,6 +157,59 @@ int Server_Game::getSpectatorCount() const
return
result
;
}
void
Server_Game
::
sendGameStateToPlayers
()
{
// Prepare game state information that everyone can see
Event_GameStateChanged
gameStateChangedEvent
;
gameStateChangedEvent
.
set_seconds_elapsed
(
secondsElapsed
);
if
(
gameStarted
)
{
gameStateChangedEvent
.
set_game_started
(
true
);
gameStateChangedEvent
.
set_active_player_id
(
0
);
gameStateChangedEvent
.
set_active_phase
(
0
);
}
else
gameStateChangedEvent
.
set_game_started
(
false
);
// game state information for replay and omniscient spectators
Event_GameStateChanged
omniscientEvent
(
gameStateChangedEvent
);
QListIterator
<
ServerInfo_Player
>
omniscientGameStateIterator
(
getGameState
(
0
,
true
));
while
(
omniscientGameStateIterator
.
hasNext
())
omniscientEvent
.
add_player_list
()
->
CopyFrom
(
omniscientGameStateIterator
.
next
());
GameEventContainer
*
replayCont
=
prepareGameEvent
(
omniscientEvent
,
-
1
);
replayCont
->
set_seconds_elapsed
(
secondsElapsed
);
replayCont
->
clear_game_id
();
replay
->
add_event_list
()
->
CopyFrom
(
*
replayCont
);
delete
replayCont
;
// If spectators are not omniscient, we need an additional getGameState call, otherwise we can use the data we used for the replay.
// All spectators are equal, so we don't need to make a getGameState call for each one.
Event_GameStateChanged
spectatorEvent
(
spectatorsSeeEverything
?
omniscientEvent
:
gameStateChangedEvent
);
if
(
!
spectatorsSeeEverything
)
{
QListIterator
<
ServerInfo_Player
>
spectatorGameStateIterator
(
getGameState
(
0
,
false
));
while
(
spectatorGameStateIterator
.
hasNext
())
spectatorEvent
.
add_player_list
()
->
CopyFrom
(
spectatorGameStateIterator
.
next
());
}
// send game state info to clients according to their role in the game
QMapIterator
<
int
,
Server_Player
*>
playerIterator
(
players
);
while
(
playerIterator
.
hasNext
())
{
Server_Player
*
player
=
playerIterator
.
next
().
value
();
GameEventContainer
*
gec
;
if
(
player
->
getSpectator
())
gec
=
prepareGameEvent
(
spectatorEvent
,
-
1
);
else
{
Event_GameStateChanged
event
(
gameStateChangedEvent
);
QListIterator
<
ServerInfo_Player
>
gameStateIterator
(
getGameState
(
player
));
while
(
gameStateIterator
.
hasNext
())
event
.
add_player_list
()
->
CopyFrom
(
gameStateIterator
.
next
());
gec
=
prepareGameEvent
(
event
,
-
1
);
}
player
->
sendGameEvent
(
*
gec
);
delete
gec
;
}
}
void
Server_Game
::
doStartGameIfReady
()
{
QMutexLocker
locker
(
&
gameMutex
);
...
...
@@ -172,37 +236,9 @@ void Server_Game::doStartGameIfReady()
player
->
setConceded
(
false
);
player
->
setReadyStart
(
false
);
}
playerIterator
.
toFront
();
while
(
playerIterator
.
hasNext
())
{
Server_Player
*
player
=
playerIterator
.
next
().
value
();
Event_GameStateChanged
event
;
event
.
set_seconds_elapsed
(
secondsElapsed
);
event
.
set_game_started
(
true
);
event
.
set_active_player_id
(
0
);
event
.
set_active_phase
(
0
);
QListIterator
<
ServerInfo_Player
>
gameStateIterator
(
getGameState
(
player
));
while
(
gameStateIterator
.
hasNext
())
event
.
add_player_list
()
->
CopyFrom
(
gameStateIterator
.
next
());
player
->
sendGameEvent
(
prepareGameEvent
(
event
,
-
1
));
}
/* QSqlQuery query;
query.prepare("insert into games (id, descr, password, time_started) values(:id, :descr, :password, now())");
query.bindValue(":id", gameId);
query.bindValue(":descr", description);
query.bindValue(":password", !password.isEmpty());
query.exec();
sendGameStateToPlayers
();
QMapIterator<int, Server_Player *> playerIterator2(players);
while (playerIterator2.hasNext()) {
Server_Player *player = playerIterator2.next().value();
query.prepare("insert into games_players (id_game, player) values(:id, :player)");
query.bindValue(":id", gameId);
query.bindValue(":player", player->getPlayerName());
query.exec();
}
*/
activePlayer
=
-
1
;
nextTurn
();
...
...
@@ -237,18 +273,7 @@ void Server_Game::stopGameIfFinished()
p
->
setConceded
(
false
);
}
playerIterator
.
toFront
();
while
(
playerIterator
.
hasNext
())
{
Server_Player
*
player
=
playerIterator
.
next
().
value
();
Event_GameStateChanged
event
;
event
.
set_seconds_elapsed
(
secondsElapsed
);
event
.
set_game_started
(
false
);
QListIterator
<
ServerInfo_Player
>
gameStateIterator
(
getGameState
(
player
));
while
(
gameStateIterator
.
hasNext
())
event
.
add_player_list
()
->
CopyFrom
(
gameStateIterator
.
next
());
player
->
sendGameEvent
(
prepareGameEvent
(
event
,
-
1
));
}
sendGameStateToPlayers
();
}
Response
::
ResponseCode
Server_Game
::
checkJoin
(
ServerInfo_User
*
user
,
const
QString
&
_password
,
bool
spectator
,
bool
overrideRestrictions
)
...
...
@@ -296,9 +321,10 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
newPlayer
->
moveToThread
(
thread
());
Event_Join
joinEvent
;
joinEvent
.
mutable_player_properties
()
->
CopyFrom
(
newPlayer
->
getProperties
());
joinEvent
.
mutable_player_properties
()
->
CopyFrom
(
newPlayer
->
getProperties
(
true
));
sendGameEventContainer
(
prepareGameEvent
(
joinEvent
,
-
1
));
allPlayersEver
.
insert
(
QString
::
fromStdString
(
newPlayer
->
getUserInfo
()
->
name
()));
players
.
insert
(
playerId
,
newPlayer
);
if
(
newPlayer
->
getUserInfo
()
->
name
()
==
creatorInfo
->
name
())
{
hostId
=
playerId
;
...
...
@@ -410,7 +436,9 @@ bool Server_Game::kickPlayer(int playerId)
if
(
!
playerToKick
)
return
false
;
playerToKick
->
sendGameEvent
(
prepareGameEvent
(
Event_Kicked
(),
-
1
));
GameEventContainer
*
gec
=
prepareGameEvent
(
Event_Kicked
(),
-
1
);
playerToKick
->
sendGameEvent
(
*
gec
);
delete
gec
;
removePlayer
(
playerToKick
);
...
...
@@ -473,7 +501,7 @@ void Server_Game::nextTurn()
setActivePlayer
(
keys
[
listPos
]);
}
QList
<
ServerInfo_Player
>
Server_Game
::
getGameState
(
Server_Player
*
playerWhosAsking
)
const
QList
<
ServerInfo_Player
>
Server_Game
::
getGameState
(
Server_Player
*
playerWhosAsking
,
bool
omniscient
,
bool
withUserInfo
)
const
{
QMutexLocker
locker
(
&
gameMutex
);
...
...
@@ -483,7 +511,7 @@ QList<ServerInfo_Player> Server_Game::getGameState(Server_Player *playerWhosAski
Server_Player
*
player
=
playerIterator
.
next
().
value
();
ServerInfo_Player
playerInfo
;
playerInfo
.
mutable_properties
()
->
CopyFrom
(
player
->
getProperties
());
playerInfo
.
mutable_properties
()
->
CopyFrom
(
player
->
getProperties
(
withUserInfo
));
if
(
player
==
playerWhosAsking
)
if
(
player
->
getDeck
())
playerInfo
.
set_deck_list
(
player
->
getDeck
()
->
writeToString_Native
().
toStdString
());
...
...
@@ -528,7 +556,7 @@ QList<ServerInfo_Player> Server_Game::getGameState(Server_Player *playerWhosAski
zoneInfo
->
set_with_coords
(
zone
->
hasCoords
());
zoneInfo
->
set_card_count
(
zone
->
cards
.
size
());
if
(
(((
playerWhosAsking
==
player
)
||
(
playerWhosAsking
->
getSpectator
()
&&
spectatorsSeeEverything
)
)
&&
(
zone
->
getType
()
!=
ServerInfo_Zone
::
HiddenZone
))
(((
playerWhosAsking
==
player
)
||
omniscient
)
&&
(
zone
->
getType
()
!=
ServerInfo_Zone
::
HiddenZone
))
||
((
playerWhosAsking
!=
player
)
&&
(
zone
->
getType
()
==
ServerInfo_Zone
::
PublicZone
))
)
{
QListIterator
<
Server_Card
*>
cardIterator
(
zone
->
cards
);
...
...
@@ -590,7 +618,12 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont, GameEventStor
Server_Player
*
p
=
playerIterator
.
next
().
value
();
const
bool
playerPrivate
=
(
p
->
getPlayerId
()
==
privatePlayerId
)
||
(
p
->
getSpectator
()
&&
spectatorsSeeEverything
);
if
((
recipients
.
testFlag
(
GameEventStorageItem
::
SendToPrivate
)
&&
playerPrivate
)
||
(
recipients
.
testFlag
(
GameEventStorageItem
::
SendToOthers
)
&&
!
playerPrivate
))
p
->
sendGameEvent
(
cont
);
p
->
sendGameEvent
(
*
cont
);
}
if
(
recipients
.
testFlag
(
GameEventStorageItem
::
SendToPrivate
))
{
cont
->
set_seconds_elapsed
(
secondsElapsed
);
cont
->
clear_game_id
();
replay
->
add_event_list
()
->
CopyFrom
(
*
cont
);
}
delete
cont
;
...
...
@@ -631,6 +664,7 @@ ServerInfo_Game Server_Game::getInfo() const
result
.
set_spectators_allowed
(
getSpectatorsAllowed
());
result
.
set_spectators_need_password
(
getSpectatorsNeedPassword
());
result
.
set_spectators_count
(
getSpectatorCount
());
result
.
set_start_time
(
startTime
.
toTime_t
());
}
return
result
;
}
common/server_game.h
View file @
d50d179b
...
...
@@ -24,6 +24,8 @@
#include
<QPointer>
#include
<QObject>
#include
<QMutex>
#include
<QSet>
#include
<QDateTime>
#include
"server_player.h"
#include
"server_response_containers.h"
#include
"pb/response.pb.h"
...
...
@@ -32,6 +34,7 @@
class
QTimer
;
class
GameEventContainer
;
class
GameReplay
;
class
Server_Room
;
class
ServerInfo_User
;
...
...
@@ -42,6 +45,7 @@ private:
int
hostId
;
ServerInfo_User
*
creatorInfo
;
QMap
<
int
,
Server_Player
*>
players
;
QSet
<
QString
>
allPlayersEver
;
bool
gameStarted
;
int
gameId
;
QString
description
;
...
...
@@ -56,7 +60,9 @@ private:
bool
spectatorsSeeEverything
;
int
inactivityCounter
;
int
secondsElapsed
;
QDateTime
startTime
;
QTimer
*
pingClock
;
GameReplay
*
replay
;
signals:
void
sigStartGameIfReady
();
private
slots
:
...
...
@@ -98,7 +104,8 @@ public:
void
nextTurn
();
int
getSecondsElapsed
()
const
{
return
secondsElapsed
;
}
QList
<
ServerInfo_Player
>
getGameState
(
Server_Player
*
playerWhosAsking
)
const
;
void
sendGameStateToPlayers
();
QList
<
ServerInfo_Player
>
getGameState
(
Server_Player
*
playerWhosAsking
,
bool
omniscient
=
false
,
bool
withUserInfo
=
false
)
const
;
GameEventContainer
*
prepareGameEvent
(
const
::
google
::
protobuf
::
Message
&
gameEvent
,
int
playerId
,
GameEventContext
*
context
=
0
);
GameEventContext
prepareGameEventContext
(
const
::
google
::
protobuf
::
Message
&
gameEventContext
);
...
...
common/server_player.cpp
View file @
d50d179b
...
...
@@ -191,12 +191,13 @@ void Server_Player::clearZones()
lastDrawList
.
clear
();
}
ServerInfo_PlayerProperties
Server_Player
::
getProperties
()
ServerInfo_PlayerProperties
Server_Player
::
getProperties
(
bool
withUserInfo
)
{
QMutexLocker
locker
(
&
game
->
gameMutex
);
ServerInfo_PlayerProperties
result
;
result
.
set_player_id
(
playerId
);
if
(
withUserInfo
)
result
.
mutable_user_info
()
->
CopyFrom
(
*
userInfo
);
result
.
set_spectator
(
spectator
);
result
.
set_conceded
(
conceded
);
...
...
@@ -581,12 +582,12 @@ Response::ResponseCode Server_Player::setCardAttrHelper(GameEventStorage &ges, c
return
Response
::
RespOk
;
}
void
Server_Player
::
sendGameEvent
(
GameEventContainer
*
cont
)
void
Server_Player
::
sendGameEvent
(
const
GameEventContainer
&
cont
)
{
QMutexLocker
locker
(
&
playerMutex
);
if
(
handler
)
handler
->
sendProtocolItem
(
*
cont
);
handler
->
sendProtocolItem
(
cont
);
}
void
Server_Player
::
setProtocolHandler
(
Server_ProtocolHandler
*
_handler
)
...
...
common/server_player.h
View file @
d50d179b
...
...
@@ -70,7 +70,7 @@ public:
int
getPingTime
()
const
{
return
pingTime
;
}
void
setPingTime
(
int
_pingTime
)
{
pingTime
=
_pingTime
;
}
ServerInfo_PlayerProperties
getProperties
();
ServerInfo_PlayerProperties
getProperties
(
bool
withUserInfo
);
int
newCardId
();
int
newCounterId
()
const
;
...
...
@@ -92,7 +92,7 @@ public:
void
unattachCard
(
GameEventStorage
&
ges
,
Server_Card
*
card
);
Response
::
ResponseCode
setCardAttrHelper
(
GameEventStorage
&
ges
,
const
QString
&
zone
,
int
cardId
,
CardAttribute
attribute
,
const
QString
&
attrValue
);
void
sendGameEvent
(
GameEventContainer
*
event
);
void
sendGameEvent
(
const
GameEventContainer
&
event
);
};
#endif
common/server_protocolhandler.cpp
View file @
d50d179b
...
...
@@ -760,7 +760,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_Creat
rc
.
enqueuePreResponseItem
(
ServerMessage
::
SESSION_EVENT
,
prepareSessionEvent
(
event1
));
Event_GameStateChanged
event2
;
QListIterator
<
ServerInfo_Player
>
gameStateIterator
(
game
->
getGameState
(
creator
));
QListIterator
<
ServerInfo_Player
>
gameStateIterator
(
game
->
getGameState
(
creator
,
false
,
true
));
while
(
gameStateIterator
.
hasNext
())
event2
.
add_player_list
()
->
CopyFrom
(
gameStateIterator
.
next
());
event2
.
set_seconds_elapsed
(
0
);
...
...
@@ -807,7 +807,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGam
rc
.
enqueuePostResponseItem
(
ServerMessage
::
SESSION_EVENT
,
prepareSessionEvent
(
event1
));
Event_GameStateChanged
event2
;
QListIterator
<
ServerInfo_Player
>
gameStateIterator
(
g
->
getGameState
(
player
));
QListIterator
<
ServerInfo_Player
>
gameStateIterator
(
g
->
getGameState
(
player
,
false
,
true
));
while
(
gameStateIterator
.
hasNext
())
event2
.
add_player_list
()
->
CopyFrom
(
gameStateIterator
.
next
());
event2
.
set_seconds_elapsed
(
g
->
getSecondsElapsed
());
...
...
@@ -854,7 +854,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdDeckSelect(const Command_DeckS
player
->
setDeck
(
deck
);
Event_PlayerPropertiesChanged
event
;
event
.
mutable_player_properties
()
->
CopyFrom
(
player
->
getProperties
());
event
.
mutable_player_properties
()
->
set_deck_hash
(
deck
->
getDeckHash
().
toStdString
());
ges
.
enqueueGameEvent
(
event
,
player
->
getPlayerId
());
Context_DeckSelect
context
;
...
...
@@ -902,7 +902,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdConcede(const Command_Concede
player
->
clearZones
();
Event_PlayerPropertiesChanged
event
;
event
.
mutable_player_properties
()
->
CopyFrom
(
player
->
getProperties
()
);
event
.
mutable_player_properties
()
->
set_conceded
(
true
);
ges
.
enqueueGameEvent
(
event
,
player
->
getPlayerId
());
ges
.
setGameEventContext
(
Context_Concede
());
...
...
@@ -927,11 +927,13 @@ Response::ResponseCode Server_ProtocolHandler::cmdReadyStart(const Command_Ready
player
->
setReadyStart
(
cmd
.
ready
());
Event_PlayerPropertiesChanged
event
;
event
.
mutable_player_properties
()
->
CopyFrom
(
player
->
getProperties
());
event
.
mutable_player_properties
()
->
set_ready_start
(
cmd
.
ready
());
ges
.
enqueueGameEvent
(
event
,
player
->
getPlayerId
());
ges
.
setGameEventContext
(
Context_ReadyStart
());
if
(
cmd
.
ready
())
game
->
startGameIfReady
();
return
Response
::
RespOk
;
}
...
...
servatrice/src/servatrice.cpp
View file @
d50d179b
...
...
@@ -28,6 +28,7 @@
#include
"server_logger.h"
#include
"main.h"
#include
"passwordhasher.h"
#include
"pb/game_replay.pb.h"
#include
"pb/event_server_message.pb.h"
#include
"pb/event_server_shutdown.pb.h"
#include
"pb/event_connection_closed.pb.h"
...
...
@@ -535,6 +536,47 @@ void Servatrice::statusUpdate()
execSqlQuery
(
query
);
}
void
Servatrice
::
storeGameInformation
(
int
secondsElapsed
,
const
QStringList
&
allPlayersEver
,
const
GameReplay
&
replay
)
{
QStringList
gameTypes
;
for
(
int
i
=
replay
.
game_info
().
game_types_size
()
-
1
;
i
>=
0
;
--
i
)
gameTypes
.
append
(
QString
::
number
(
replay
.
game_info
().
game_types
(
i
)));
QByteArray
replayBlob
;
const
unsigned
int
size
=
replay
.
ByteSize
();
replayBlob
.
resize
(
size
);
replay
.
SerializeToArray
(
replayBlob
.
data
(),
size
);
QMutexLocker
locker
(
&
dbMutex
);
if
(
!
checkSql
())
return
;
QSqlQuery
query1
;
query1
.
prepare
(
"insert into "
+
dbPrefix
+
"_games (id_room, id, descr, creator_name, password, game_types, player_count, time_started, time_finished, replay) values (:id_room, :id_game, :descr, :creator_name, :password, :game_types, :player_count, date_sub(now(), interval :seconds second), now(), :replay)"
);
query1
.
bindValue
(
":id_room"
,
replay
.
game_info
().
room_id
());
query1
.
bindValue
(
":id_game"
,
replay
.
game_info
().
game_id
());
query1
.
bindValue
(
":descr"
,
QString
::
fromStdString
(
replay
.
game_info
().
description
()));
query1
.
bindValue
(
":creator_name"
,
QString
::
fromStdString
(
replay
.
game_info
().
creator_info
().
name
()));
query1
.
bindValue
(
":password"
,
replay
.
game_info
().
with_password
()
?
1
:
0
);
query1
.
bindValue
(
":game_types"
,
gameTypes
.
isEmpty
()
?
QString
(
""
)
:
gameTypes
.
join
(
","
));
query1
.
bindValue
(
":player_count"
,
replay
.
game_info
().
max_players
());
query1
.
bindValue
(
":seconds"
,
secondsElapsed
);
query1
.
bindValue
(
":replay"
,
replayBlob
);
if
(
!
execSqlQuery
(
query1
))
return
;
QSqlQuery
query2
;
query2
.
prepare
(
"insert into "
+
dbPrefix
+
"_games_players (id_game, player_name) values (:id_game, :player_name)"
);
QVariantList
gameIds
,
playerNames
;
for
(
int
i
=
allPlayersEver
.
size
()
-
1
;
i
>=
0
;
--
i
)
{
gameIds
.
append
(
replay
.
game_info
().
game_id
());
playerNames
.
append
(
allPlayersEver
[
i
]);
}
query2
.
bindValue
(
":id_game"
,
gameIds
);
query2
.
bindValue
(
":player_name"
,
playerNames
);
query2
.
execBatch
();
}
void
Servatrice
::
scheduleShutdown
(
const
QString
&
reason
,
int
minutes
)
{
QMutexLocker
locker
(
&
serverMutex
);
...
...
servatrice/src/servatrice.h
View file @
d50d179b
...
...
@@ -29,6 +29,7 @@ class QSettings;
class
QSqlQuery
;
class
QTimer
;
class
GameReplay
;
class
Servatrice
;
class
ServerSocketInterface
;
...
...
@@ -82,6 +83,7 @@ public:
void
incTxBytes
(
quint64
num
);
void
incRxBytes
(
quint64
num
);
int
getUserIdInDB
(
const
QString
&
name
);
void
storeGameInformation
(
int
secondsElapsed
,
const
QStringList
&
allPlayersEver
,
const
GameReplay
&
replay
);
protected:
int
startSession
(
const
QString
&
userName
,
const
QString
&
address
);
void
endSession
(
int
sessionId
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment