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
347d30a8
Commit
347d30a8
authored
Feb 27, 2013
by
Daenyth
Browse files
Merge branch 'master' of
git://github.com/mbruker/Cockatrice
parents
af09d0d2
ce642e30
Changes
44
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
347d30a8
...
...
@@ -7,8 +7,11 @@ if (NOT WITHOUT_CLIENT)
add_subdirectory
(
cockatrice
)
add_subdirectory
(
oracle
)
endif
(
NOT WITHOUT_CLIENT
)
if
(
WITH_TESTCLIENT
)
add_subdirectory
(
testclient
)
endif
(
WITH_TESTCLIENT
)
FILE
(
GLOB sounds
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/sounds/*.raw"
)
INSTALL
(
FILES
${
sounds
}
DESTINATION share/cockatrice/sounds
)
FILE
(
GLOB zonebg
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/zonebg/*.*"
)
INSTALL
(
FILES
${
zonebg
}
DESTINATION share/cockatrice/zonebg
)
\ No newline at end of file
INSTALL
(
FILES
${
zonebg
}
DESTINATION share/cockatrice/zonebg
)
README.md
0 → 100644
View file @
347d30a8
# Cockatrice
Cockatrice is an open-source multiplatform software for playing card games,
such as Magic: The Gathering, over a network. It is fully client-server based
to prevent any kind of cheating, though it supports single-player games without
a network interface as well. Both client and server are written in Qt 4.
# License
Cockatrice is free software, licensed under the GPLv2; see COPYING for details.
# Building
Dependencies:
-
[
Qt
](
http://qt-project.org/
)
-
[
protobuf
](
http://code.google.com/p/protobuf/
)
-
[
CMake
](
http://www.cmake.org/
)
The server requires an additional dependency:
-
[
libgcrypt
](
http://www.gnu.org/software/libgcrypt/
)
```
mkdir build
cd build
cmake ..
make
make install
```
The following flags can be passed to
`cmake`
:
-
`-DWITH_SERVER=1`
build the server
-
`-DWITHOUT_CLIENT=1`
do not build the client
# Running
`oracle`
fetches card data
`cockatrice`
is the game client
`servatrice`
is the server
cockatrice/CMakeLists.txt
View file @
347d30a8
...
...
@@ -197,10 +197,16 @@ if (NOT QT_QTMULTIMEDIA_FOUND)
FIND_PACKAGE
(
QtMobility REQUIRED
)
endif
(
NOT QT_QTMULTIMEDIA_FOUND
)
FIND_PACKAGE
(
Protobuf REQUIRED
)
FIND_PACKAGE
(
Threads
)
set
(
CMAKE_CXX_FLAGS_DEBUG
"-ggdb -O0"
)
set
(
CMAKE_CXX_FLAGS_RELEASE
"-s -O2"
)
# paths
set
(
ICONDIR share/icons CACHE STRING
"icon dir"
)
set
(
DESKTOPDIR share/applications CACHE STRING
"desktop file destination"
)
QT4_WRAP_CPP
(
cockatrice_HEADERS_MOC
${
cockatrice_HEADERS
}
)
QT4_ADD_TRANSLATION
(
cockatrice_QM
${
cockatrice_TS
}
)
QT4_ADD_RESOURCES
(
cockatrice_RESOURCES_RCC
${
cockatrice_RESOURCES
}
)
...
...
@@ -214,13 +220,17 @@ INCLUDE_DIRECTORIES(${QT_MOBILITY_INCLUDE_DIR})
INCLUDE_DIRECTORIES
(
${
QT_MOBILITY_MULTIMEDIAKIT_INCLUDE_DIR
}
)
ADD_EXECUTABLE
(
cockatrice WIN32 MACOSX_BUNDLE
${
cockatrice_SOURCES
}
${
cockatrice_QM
}
${
cockatrice_RESOURCES_RCC
}
${
cockatrice_HEADERS_MOC
}
)
TARGET_LINK_LIBRARIES
(
cockatrice cockatrice_common
${
QT_LIBRARIES
}
${
QT_MOBILITY_MULTIMEDIAKIT_LIBRARY
}
)
TARGET_LINK_LIBRARIES
(
cockatrice cockatrice_common
${
QT_LIBRARIES
}
${
QT_MOBILITY_MULTIMEDIAKIT_LIBRARY
}
${
CMAKE_THREAD_LIBS_INIT
}
)
INSTALL
(
PROGRAMS
${
CMAKE_CURRENT_BINARY_DIR
}
/cockatrice DESTINATION bin
)
IF
(
NOT APPLE
)
INSTALL
(
PROGRAMS
${
CMAKE_CURRENT_BINARY_DIR
}
/cockatrice DESTINATION bin
)
ELSE
(
APPLE
)
INSTALL
(
PROGRAMS
${
CMAKE_CURRENT_BINARY_DIR
}
/cockatrice.app DESTINATION bin
)
ENDIF
(
NOT APPLE
)
if
(
NOT WIN32 AND NOT APPLE
)
INSTALL
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/resources/cockatrice.png DESTINATION
share/icons
/hicolor/48x48/apps
)
INSTALL
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/resources/cockatrice.svg DESTINATION
share/icons
/hicolor/scalable/apps
)
INSTALL
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/cockatrice.desktop DESTINATION
share/applications
)
INSTALL
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/resources/cockatrice.png DESTINATION
${
ICONDIR
}
/hicolor/48x48/apps
)
INSTALL
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/resources/cockatrice.svg DESTINATION
${
ICONDIR
}
/hicolor/scalable/apps
)
INSTALL
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/cockatrice.desktop DESTINATION
${
DESKTOPDIR
}
)
INSTALL
(
FILES
${
cockatrice_QM
}
DESTINATION share/cockatrice/translations
)
ENDIF
(
NOT WIN32 AND NOT APPLE
)
...
...
cockatrice/cockatrice.qrc
View file @
347d30a8
...
...
@@ -71,6 +71,7 @@
<file>resources/countries/es.svg</file>
<file>resources/countries/fi.svg</file>
<file>resources/countries/fr.svg</file>
<file>resources/countries/ge.svg</file>
<file>resources/countries/gr.svg</file>
<file>resources/countries/gt.svg</file>
<file>resources/countries/hr.svg</file>
...
...
cockatrice/resources/countries/ge.svg
0 → 100644
View file @
347d30a8
<?xml version="1.0" encoding="UTF-8"?>
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
width=
"900"
height=
"600"
viewBox=
"0 0 300 200"
>
<defs>
<g
id=
"smallcross"
><clipPath
id=
"vclip"
><path
d=
"M-109,104 a104,104 0 0,0 0,-208 H109 a104,104 0 0,0 0,208 z"
/></clipPath><path
id=
"varm"
d=
"M-55,74 a55,55 0 0,1 110,0 V-74 a55,55 0 0,1 -110,0 z"
clip-path=
"url(#vclip)"
/>
<use
xlink:href=
"#varm"
transform=
"rotate(90)"
/></g>
</defs>
<rect
width=
"300"
height=
"200"
style=
"fill:#fff"
/>
<path
d=
"m 130,0 0,80 -130,0 L 0,120 l 130,0 0,80 40,0 0,-80 130,0 0,-40 -130,0 L 170,0 130,0 z"
style=
"fill:#ff0000"
/>
<use
xlink:href=
"#smallcross"
transform=
"translate(64.45,39.45)"
fill=
"#f00"
/>
<use
xlink:href=
"#smallcross"
transform=
"translate(235.55,160.55)"
fill=
"#f00"
/>
<use
xlink:href=
"#smallcross"
transform=
"translate(235.55,39.45)"
fill=
"#f00"
/>
<use
xlink:href=
"#smallcross"
transform=
"translate(64.45,160.55)"
fill=
"#f00"
/>
</svg>
cockatrice/src/carddatabasemodel.cpp
View file @
347d30a8
...
...
@@ -117,7 +117,7 @@ bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex
{
CardInfo
const
*
info
=
static_cast
<
CardDatabaseModel
*>
(
sourceModel
())
->
getCard
(
sourceRow
);
if
(((
isToken
==
ShowTrue
)
&&
!
info
->
getIsToken
())
||
(
isToken
==
ShowFalse
)
&&
info
->
getIsToken
())
if
(((
isToken
==
ShowTrue
)
&&
!
info
->
getIsToken
())
||
(
(
isToken
==
ShowFalse
)
&&
info
->
getIsToken
())
)
return
false
;
if
(
!
cardNameBeginning
.
isEmpty
())
...
...
cockatrice/src/chatview.cpp
View file @
347d30a8
...
...
@@ -54,6 +54,35 @@ void ChatView::appendHtml(const QString &html)
verticalScrollBar
()
->
setValue
(
verticalScrollBar
()
->
maximum
());
}
void
ChatView
::
appendCardTag
(
QTextCursor
&
cursor
,
const
QString
&
cardName
)
{
QTextCharFormat
oldFormat
=
cursor
.
charFormat
();
QTextCharFormat
anchorFormat
=
oldFormat
;
anchorFormat
.
setForeground
(
Qt
::
blue
);
anchorFormat
.
setAnchor
(
true
);
anchorFormat
.
setAnchorHref
(
"card://"
+
cardName
);
cursor
.
setCharFormat
(
anchorFormat
);
cursor
.
insertText
(
cardName
);
cursor
.
setCharFormat
(
oldFormat
);
}
void
ChatView
::
appendUrlTag
(
QTextCursor
&
cursor
,
QString
url
)
{
if
(
!
url
.
contains
(
"://"
))
url
.
prepend
(
"http://"
);
QTextCharFormat
oldFormat
=
cursor
.
charFormat
();
QTextCharFormat
anchorFormat
=
oldFormat
;
anchorFormat
.
setForeground
(
Qt
::
blue
);
anchorFormat
.
setAnchor
(
true
);
anchorFormat
.
setAnchorHref
(
url
);
cursor
.
setCharFormat
(
anchorFormat
);
cursor
.
insertText
(
url
);
cursor
.
setCharFormat
(
oldFormat
);
}
void
ChatView
::
appendMessage
(
QString
message
,
QString
sender
,
UserLevelFlags
userLevel
,
bool
playerBold
)
{
bool
atBottom
=
verticalScrollBar
()
->
value
()
>=
verticalScrollBar
()
->
maximum
();
...
...
@@ -103,7 +132,7 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
message
=
message
.
mid
(
index
);
if
(
message
.
isEmpty
())
break
;
if
(
message
.
startsWith
(
"[card]"
))
{
message
=
message
.
mid
(
6
);
int
closeTagIndex
=
message
.
indexOf
(
"[/card]"
);
...
...
@@ -113,14 +142,17 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
else
message
=
message
.
mid
(
closeTagIndex
+
7
);
QTextCharFormat
tempFormat
=
messageFormat
;
tempFormat
.
setForeground
(
Qt
::
blue
);
tempFormat
.
setAnchor
(
true
);
tempFormat
.
setAnchorHref
(
"card://"
+
cardName
);
appendCardTag
(
cursor
,
cardName
);
}
else
if
(
message
.
startsWith
(
"[["
))
{
message
=
message
.
mid
(
2
);
int
closeTagIndex
=
message
.
indexOf
(
"]]"
);
QString
cardName
=
message
.
left
(
closeTagIndex
);
if
(
closeTagIndex
==
-
1
)
message
.
clear
();
else
message
=
message
.
mid
(
closeTagIndex
+
2
);
cursor
.
setCharFormat
(
tempFormat
);
cursor
.
insertText
(
cardName
);
cursor
.
setCharFormat
(
messageFormat
);
appendCardTag
(
cursor
,
cardName
);
}
else
if
(
message
.
startsWith
(
"[url]"
))
{
message
=
message
.
mid
(
5
);
int
closeTagIndex
=
message
.
indexOf
(
"[/url]"
);
...
...
@@ -130,17 +162,7 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
else
message
=
message
.
mid
(
closeTagIndex
+
6
);
if
(
!
url
.
contains
(
"://"
))
url
.
prepend
(
"http://"
);
QTextCharFormat
tempFormat
=
messageFormat
;
tempFormat
.
setForeground
(
Qt
::
blue
);
tempFormat
.
setAnchor
(
true
);
tempFormat
.
setAnchorHref
(
url
);
cursor
.
setCharFormat
(
tempFormat
);
cursor
.
insertText
(
url
);
cursor
.
setCharFormat
(
messageFormat
);
appendUrlTag
(
cursor
,
url
);
}
else
from
=
1
;
}
...
...
cockatrice/src/chatview.h
View file @
347d30a8
...
...
@@ -28,6 +28,8 @@ private:
QString
hoveredContent
;
QTextFragment
getFragmentUnderMouse
(
const
QPoint
&
pos
)
const
;
QTextCursor
prepareBlock
(
bool
same
=
false
);
void
appendCardTag
(
QTextCursor
&
cursor
,
const
QString
&
cardName
);
void
appendUrlTag
(
QTextCursor
&
cursor
,
QString
url
);
private
slots
:
void
openLink
(
const
QUrl
&
link
);
public:
...
...
cockatrice/src/dlg_filter_games.cpp
View file @
347d30a8
...
...
@@ -14,6 +14,7 @@ DlgFilterGames::DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *
:
QDialog
(
parent
)
{
unavailableGamesVisibleCheckBox
=
new
QCheckBox
(
tr
(
"Show &unavailable games"
));
passwordProtectedGamesVisibleCheckBox
=
new
QCheckBox
(
tr
(
"Show &password protected games"
));
QLabel
*
gameNameFilterLabel
=
new
QLabel
(
tr
(
"Game &description:"
));
gameNameFilterEdit
=
new
QLineEdit
;
...
...
@@ -68,6 +69,7 @@ DlgFilterGames::DlgFilterGames(const QMap<int, QString> &allGameTypes, QWidget *
leftGrid
->
addWidget
(
creatorNameFilterEdit
,
1
,
1
);
leftGrid
->
addWidget
(
maxPlayersGroupBox
,
2
,
0
,
1
,
2
);
leftGrid
->
addWidget
(
unavailableGamesVisibleCheckBox
,
3
,
0
,
1
,
2
);
leftGrid
->
addWidget
(
passwordProtectedGamesVisibleCheckBox
,
4
,
0
,
1
,
2
);
QVBoxLayout
*
leftColumn
=
new
QVBoxLayout
;
leftColumn
->
addLayout
(
leftGrid
);
...
...
@@ -102,6 +104,16 @@ void DlgFilterGames::setUnavailableGamesVisible(bool _unavailableGamesVisible)
unavailableGamesVisibleCheckBox
->
setChecked
(
_unavailableGamesVisible
);
}
bool
DlgFilterGames
::
getPasswordProtectedGamesVisible
()
const
{
return
passwordProtectedGamesVisibleCheckBox
->
isChecked
();
}
void
DlgFilterGames
::
setPasswordProtectedGamesVisible
(
bool
_passwordProtectedGamesVisible
)
{
passwordProtectedGamesVisibleCheckBox
->
setChecked
(
_passwordProtectedGamesVisible
);
}
QString
DlgFilterGames
::
getGameNameFilter
()
const
{
return
gameNameFilterEdit
->
text
();
...
...
cockatrice/src/dlg_filter_games.h
View file @
347d30a8
...
...
@@ -13,6 +13,7 @@ class DlgFilterGames : public QDialog {
Q_OBJECT
private:
QCheckBox
*
unavailableGamesVisibleCheckBox
;
QCheckBox
*
passwordProtectedGamesVisibleCheckBox
;
QLineEdit
*
gameNameFilterEdit
;
QLineEdit
*
creatorNameFilterEdit
;
QMap
<
int
,
QCheckBox
*>
gameTypeFilterCheckBoxes
;
...
...
@@ -23,6 +24,8 @@ public:
bool
getUnavailableGamesVisible
()
const
;
void
setUnavailableGamesVisible
(
bool
_unavailableGamesVisible
);
bool
getPasswordProtectedGamesVisible
()
const
;
void
setPasswordProtectedGamesVisible
(
bool
_passwordProtectedGamesVisible
);
QString
getGameNameFilter
()
const
;
void
setGameNameFilter
(
const
QString
&
_gameNameFilter
);
QString
getCreatorNameFilter
()
const
;
...
...
cockatrice/src/gameselector.cpp
View file @
347d30a8
...
...
@@ -82,6 +82,7 @@ void GameSelector::actSetFilter()
gameTypeMap
=
gameListModel
->
getGameTypes
().
value
(
room
->
getRoomId
());
DlgFilterGames
dlg
(
gameTypeMap
,
this
);
dlg
.
setUnavailableGamesVisible
(
gameListProxyModel
->
getUnavailableGamesVisible
());
dlg
.
setPasswordProtectedGamesVisible
(
gameListProxyModel
->
getPasswordProtectedGamesVisible
());
dlg
.
setGameNameFilter
(
gameListProxyModel
->
getGameNameFilter
());
dlg
.
setCreatorNameFilter
(
gameListProxyModel
->
getCreatorNameFilter
());
dlg
.
setGameTypeFilter
(
gameListProxyModel
->
getGameTypeFilter
());
...
...
@@ -93,6 +94,7 @@ void GameSelector::actSetFilter()
clearFilterButton
->
setEnabled
(
true
);
gameListProxyModel
->
setUnavailableGamesVisible
(
dlg
.
getUnavailableGamesVisible
());
gameListProxyModel
->
setPasswordProtectedGamesVisible
(
dlg
.
getPasswordProtectedGamesVisible
());
gameListProxyModel
->
setGameNameFilter
(
dlg
.
getGameNameFilter
());
gameListProxyModel
->
setCreatorNameFilter
(
dlg
.
getCreatorNameFilter
());
gameListProxyModel
->
setGameTypeFilter
(
dlg
.
getGameTypeFilter
());
...
...
cockatrice/src/gamesmodel.cpp
View file @
347d30a8
...
...
@@ -105,6 +105,12 @@ void GamesProxyModel::setUnavailableGamesVisible(bool _unavailableGamesVisible)
invalidateFilter
();
}
void
GamesProxyModel
::
setPasswordProtectedGamesVisible
(
bool
_passwordProtectedGamesVisible
)
{
passwordProtectedGamesVisible
=
_passwordProtectedGamesVisible
;
invalidateFilter
();
}
void
GamesProxyModel
::
setGameNameFilter
(
const
QString
&
_gameNameFilter
)
{
gameNameFilter
=
_gameNameFilter
;
...
...
@@ -133,6 +139,7 @@ void GamesProxyModel::setMaxPlayersFilter(int _maxPlayersFilterMin, int _maxPlay
void
GamesProxyModel
::
resetFilterParameters
()
{
unavailableGamesVisible
=
false
;
passwordProtectedGamesVisible
=
false
;
gameNameFilter
=
QString
();
creatorNameFilter
=
QString
();
gameTypeFilter
.
clear
();
...
...
@@ -158,6 +165,8 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourc
if
(
game
.
only_registered
())
return
false
;
}
if
(
!
passwordProtectedGamesVisible
&&
game
.
with_password
())
return
false
;
if
(
!
gameNameFilter
.
isEmpty
())
if
(
!
QString
::
fromStdString
(
game
.
description
()).
contains
(
gameNameFilter
,
Qt
::
CaseInsensitive
))
return
false
;
...
...
cockatrice/src/gamesmodel.h
View file @
347d30a8
...
...
@@ -33,6 +33,7 @@ class GamesProxyModel : public QSortFilterProxyModel {
private:
ServerInfo_User
*
ownUser
;
bool
unavailableGamesVisible
;
bool
passwordProtectedGamesVisible
;
QString
gameNameFilter
,
creatorNameFilter
;
QSet
<
int
>
gameTypeFilter
;
int
maxPlayersFilterMin
,
maxPlayersFilterMax
;
...
...
@@ -41,6 +42,8 @@ public:
bool
getUnavailableGamesVisible
()
const
{
return
unavailableGamesVisible
;
}
void
setUnavailableGamesVisible
(
bool
_unavailableGamesVisible
);
bool
getPasswordProtectedGamesVisible
()
const
{
return
passwordProtectedGamesVisible
;
}
void
setPasswordProtectedGamesVisible
(
bool
_passwordProtectedGamesVisible
);
QString
getGameNameFilter
()
const
{
return
gameNameFilter
;
}
void
setGameNameFilter
(
const
QString
&
_gameNameFilter
);
QString
getCreatorNameFilter
()
const
{
return
creatorNameFilter
;
}
...
...
cockatrice/src/tab_admin.cpp
View file @
347d30a8
...
...
@@ -4,6 +4,7 @@
#include
<QPushButton>
#include
<QGroupBox>
#include
<QMessageBox>
#include
<QDialogButtonBox>
#include
<QSpinBox>
#include
<QLabel>
#include
<QLineEdit>
...
...
@@ -24,24 +25,16 @@ ShutdownDialog::ShutdownDialog(QWidget *parent)
minutesEdit
->
setMinimum
(
0
);
minutesEdit
->
setValue
(
5
);
QPushButton
*
okButton
=
new
QPushButton
(
tr
(
"&OK"
));
okButton
->
setAutoDefault
(
true
);
okButton
->
setDefault
(
true
);
connect
(
okButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
accept
()));
QPushButton
*
cancelButton
=
new
QPushButton
(
tr
(
"&Cancel"
));
connect
(
cancelButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
reject
()));
QHBoxLayout
*
buttonLayout
=
new
QHBoxLayout
;
buttonLayout
->
addStretch
();
buttonLayout
->
addWidget
(
okButton
);
buttonLayout
->
addWidget
(
cancelButton
);
QDialogButtonBox
*
buttonBox
=
new
QDialogButtonBox
(
QDialogButtonBox
::
Ok
|
QDialogButtonBox
::
Cancel
);
connect
(
buttonBox
,
SIGNAL
(
accepted
()),
this
,
SLOT
(
accept
()));
connect
(
buttonBox
,
SIGNAL
(
rejected
()),
this
,
SLOT
(
reject
()));
QGridLayout
*
mainLayout
=
new
QGridLayout
;
mainLayout
->
addWidget
(
reasonLabel
,
0
,
0
);
mainLayout
->
addWidget
(
reasonEdit
,
0
,
1
);
mainLayout
->
addWidget
(
minutesLabel
,
1
,
0
);
mainLayout
->
addWidget
(
minutesEdit
,
1
,
1
);
mainLayout
->
add
Layou
t
(
button
Layout
,
2
,
0
,
1
,
2
);
mainLayout
->
add
Widge
t
(
button
Box
,
2
,
0
,
1
,
2
);
setLayout
(
mainLayout
);
setWindowTitle
(
tr
(
"Shut down server"
));
...
...
cockatrice/src/tab_deck_storage.cpp
View file @
347d30a8
...
...
@@ -306,6 +306,8 @@ void TabDeckStorage::actDeleteRemoteDeck()
QString
path
=
dir
->
getPath
();
if
(
path
.
isEmpty
())
return
;
if
(
QMessageBox
::
warning
(
this
,
tr
(
"Delete remote folder"
),
tr
(
"Are you sure you want to delete
\"
%1
\"
?"
).
arg
(
path
),
QMessageBox
::
Yes
|
QMessageBox
::
No
)
!=
QMessageBox
::
Yes
)
return
;
Command_DeckDelDir
cmd
;
cmd
.
set_path
(
path
.
toStdString
());
pend
=
client
->
prepareSessionCommand
(
cmd
);
...
...
cockatrice/src/tab_server.cpp
View file @
347d30a8
...
...
@@ -76,8 +76,10 @@ void RoomSelector::processListRoomsEvent(const Event_ListRooms &event)
twi
->
setData
(
0
,
Qt
::
DisplayRole
,
QString
::
fromStdString
(
room
.
name
()));
if
(
room
.
has_description
())
twi
->
setData
(
1
,
Qt
::
DisplayRole
,
QString
::
fromStdString
(
room
.
description
()));
twi
->
setData
(
2
,
Qt
::
DisplayRole
,
room
.
player_count
());
twi
->
setData
(
3
,
Qt
::
DisplayRole
,
room
.
game_count
());
if
(
room
.
has_player_count
())
twi
->
setData
(
2
,
Qt
::
DisplayRole
,
room
.
player_count
());
if
(
room
.
has_game_count
())
twi
->
setData
(
3
,
Qt
::
DisplayRole
,
room
.
game_count
());
return
;
}
}
...
...
@@ -91,6 +93,7 @@ void RoomSelector::processListRoomsEvent(const Event_ListRooms &event)
twi
->
setData
(
3
,
Qt
::
DisplayRole
,
room
.
game_count
());
twi
->
setTextAlignment
(
2
,
Qt
::
AlignRight
);
twi
->
setTextAlignment
(
3
,
Qt
::
AlignRight
);
roomList
->
addTopLevelItem
(
twi
);
if
(
room
.
has_auto_join
())
if
(
room
.
auto_join
())
...
...
common/server.cpp
View file @
347d30a8
...
...
@@ -36,7 +36,7 @@
#include
<QDebug>
Server
::
Server
(
bool
_threaded
,
QObject
*
parent
)
:
QObject
(
parent
),
threaded
(
_threaded
),
clientsLock
(
QReadWriteLock
::
Recursive
),
nextLocalGameId
(
0
)
:
QObject
(
parent
),
threaded
(
_threaded
),
nextLocalGameId
(
0
)
{
qRegisterMetaType
<
ServerInfo_Game
>
(
"ServerInfo_Game"
);
qRegisterMetaType
<
ServerInfo_Room
>
(
"ServerInfo_Room"
);
...
...
@@ -79,10 +79,9 @@ void Server::prepareDestroy()
clientsLock
.
unlock
();
}
while
(
!
done
);
}
else
{
clientsLock
.
lockForWrite
();
// no locking is needed in unthreaded mode
while
(
!
clients
.
isEmpty
())
clients
.
first
()
->
prepareDestroy
();
clientsLock
.
unlock
();
}
roomsLock
.
lockForWrite
();
...
...
@@ -141,7 +140,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
}
users
.
insert
(
name
,
session
);
qDebug
()
<<
"Server::loginUser:
name="
<<
name
;
qDebug
()
<<
"Server::loginUser:
"
<<
session
<<
"
name="
<<
name
;
data
.
set_session_id
(
databaseInterface
->
startSession
(
name
,
session
->
getAddress
()));
databaseInterface
->
unlockSessionTables
();
...
...
@@ -159,7 +158,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
clients
[
i
]
->
sendProtocolItem
(
*
se
);
delete
se
;
event
.
mutable_user_info
()
->
CopyFrom
(
session
->
copyUserInfo
(
true
,
true
));
event
.
mutable_user_info
()
->
CopyFrom
(
session
->
copyUserInfo
(
true
,
true
,
true
));
locker
.
unlock
();
se
=
Server_ProtocolHandler
::
prepareSessionEvent
(
event
);
...
...
@@ -187,6 +186,17 @@ QList<PlayerReference> Server::getPersistentPlayerReferences(const QString &user
return
persistentPlayers
.
values
(
userName
);
}
Server_AbstractUserInterface
*
Server
::
findUser
(
const
QString
&
userName
)
const
{
// Call this only with clientsLock set.
Server_AbstractUserInterface
*
userHandler
=
users
.
value
(
userName
);
if
(
userHandler
)
return
userHandler
;
else
return
externalUsers
.
value
(
userName
);
}
void
Server
::
addClient
(
Server_ProtocolHandler
*
client
)
{
QWriteLocker
locker
(
&
clientsLock
);
...
...
@@ -218,13 +228,13 @@ void Server::removeClient(Server_ProtocolHandler *client)
qDebug
()
<<
"closed session id:"
<<
sessionId
;
}
}
qDebug
()
<<
"Server::removeClient:"
<<
clients
.
size
()
<<
"clients; "
<<
users
.
size
()
<<
"users left"
;
qDebug
()
<<
"Server::removeClient:
removed"
<<
(
void
*
)
client
<<
";
"
<<
clients
.
size
()
<<
"clients; "
<<
users
.
size
()
<<
"users left"
;
}
void
Server
::
externalUserJoined
(
const
ServerInfo_User
&
userInfo
)
{
// This function is always called from the main thread via signal/slot.
QWrite
Lock
er
lock
er
(
&
clientsLock
);
clients
Lock
.
lock
ForWrite
(
);
Server_RemoteUserInterface
*
newUser
=
new
Server_RemoteUserInterface
(
this
,
ServerInfo_User_Container
(
userInfo
));
externalUsers
.
insert
(
QString
::
fromStdString
(
userInfo
.
name
()),
newUser
);
...
...
@@ -263,7 +273,7 @@ void Server::externalUserLeft(const QString &userName)
if
(
!
room
)
continue
;
Q
Mutex
Locker
roomGamesLocker
(
&
room
->
games
Mutex
);
Q
Read
Locker
roomGamesLocker
(
&
room
->
games
Lock
);
Server_Game
*
game
=
room
->
getGames
().
value
(
userGamesIterator
.
key
());
if
(
!
game
)
continue
;
...
...
@@ -389,7 +399,7 @@ void Server::externalGameCommandContainerReceived(const CommandContainer &cont,
throw
Response
::
RespNotInRoom
;
}
Q
Mutex
Locker
roomGamesLocker
(
&
room
->
games
Mutex
);
Q
Read
Locker
roomGamesLocker
(
&
room
->
games
Lock
);
Server_Game
*
game
=
room
->
getGames
().
value
(
cont
.
game_id
());
if
(
!
game
)
{
qDebug
()
<<
"externalGameCommandContainerReceived: game id="
<<
cont
.
game_id
()
<<
"not found"
;
...
...
@@ -499,7 +509,7 @@ int Server::getGamesCount() const
QMapIterator
<
int
,
Server_Room
*>
roomIterator
(
rooms
);
while
(
roomIterator
.
hasNext
())
{
Server_Room
*
room
=
roomIterator
.
next
().
value
();
Q
Mutex
Locker
roomLocker
(
&
room
->
games
Mutex
);
Q
Read
Locker
roomLocker
(
&
room
->
games
Lock
);
result
+=
room
->
getGames
().
size
();
}
return
result
;
...
...
common/server.h
View file @
347d30a8
...
...
@@ -42,9 +42,11 @@ public:
mutable
QReadWriteLock
clientsLock
,
roomsLock
;
// locking order: roomsLock before clientsLock
Server
(
bool
_threaded
,
QObject
*
parent
=
0
);
~
Server
();
void
setThreaded
(
bool
_threaded
)
{
threaded
=
_threaded
;
}
AuthenticationResult
loginUser
(
Server_ProtocolHandler
*
session
,
QString
&
name
,
const
QString
&
password
,
QString
&
reason
,
int
&
secondsLeft
);
const
QMap
<
int
,
Server_Room
*>
&
getRooms
()
{
return
rooms
;
}
Server_AbstractUserInterface
*
findUser
(
const
QString
&
userName
)
const
;
const
QMap
<
QString
,
Server_ProtocolHandler
*>
&
getUsers
()
const
{
return
users
;
}
const
QMap
<
qint64
,
Server_ProtocolHandler
*>
&
getUsersBySessionId
()
const
{
return
usersBySessionId
;
}
void
addClient
(
Server_ProtocolHandler
*
player
);
...
...
@@ -62,7 +64,6 @@ public:
Server_DatabaseInterface
*
getDatabaseInterface
()
const
;
int
getNextLocalGameId
()
{
QMutexLocker
locker
(
&
nextLocalGameIdMutex
);
return
++
nextLocalGameId
;
}
virtual
void
storeGameInformation
(
int
secondsElapsed
,
const
QSet
<
QString
>
&
allPlayersEver
,
const
QSet
<
QString
>
&
allSpectatorsEver
,
const
QList
<
GameReplay
*>
&
replays
)
{
}
void
sendIsl_Response
(
const
Response
&
item
,
int
serverId
=
-
1
,
qint64
sessionId
=
-
1
);
void
sendIsl_SessionEvent
(
const
SessionEvent
&
item
,
int
serverId
=
-
1
,
qint64
sessionId
=
-
1
);
...
...
common/server_abstractuserinterface.cpp
View file @
347d30a8
...
...
@@ -78,7 +78,7 @@ void Server_AbstractUserInterface::joinPersistentGames(ResponseContainer &rc)
Server_Room
*
room
=
server
->
getRooms
().
value
(
pr
.
getRoomId
());
if
(
!
room
)
continue
;
Q
Mutex
Locker
roomGamesLocker
(
&
room
->
games
Mutex
);
Q
Read
Locker
roomGamesLocker
(
&
room
->
games
Lock
);
Server_Game
*
game
=
room
->
getGames
().
value
(
pr
.
getGameId
());
if
(
!
game
)
...
...
common/server_cardzone.cpp
View file @
347d30a8
...
...
@@ -51,28 +51,78 @@ void Server_CardZone::shuffle()
playersWithWritePermission
.
clear
();
}
void
Server_CardZone
::
removeCardFromCoordMap
(
Server_Card
*
card
,
int
oldX
,
int
oldY
)
{
if
(
oldX
<
0
)
return
;
const
int
baseX
=
(
oldX
/
3
)
*
3
;
QMap
<
int
,
Server_Card
*>
&
coordMap
=
coordinateMap
[
oldY
];
if
(
coordMap
.
contains
(
baseX
)
&&
coordMap
.
contains
(
baseX
+
1
)
&&
coordMap
.
contains
(
baseX
+
2
))
// If the removal of this card has opened up a previously full pile...
freePilesMap
[
oldY
].
insert
(
coordMap
.
value
(
baseX
)
->
getName
(),
baseX
);
coordMap
.
remove
(
oldX
);
if
(
!
(
coordMap
.
contains
(
baseX
)
&&
coordMap
.
value
(
baseX
)
->
getName
()
==
card
->
getName
())
&&
!
(
coordMap
.
contains
(
baseX
+
1
)
&&
coordMap
.
value
(
baseX
+
1
)
->
getName
()
==
card
->
getName
())
&&
!
(
coordMap
.
contains
(
baseX
+
2
)
&&
coordMap
.
value
(
baseX
+
2
)
->
getName
()
==
card
->
getName
()))
// If this card was the last one with this name...
freePilesMap
[
oldY
].
remove
(
card
->
getName
(),
baseX
);
if
(
!
coordMap
.
contains
(
baseX
)
&&
!
coordMap
.
contains
(
baseX
+
1
)
&&
!
coordMap
.
contains
(
baseX
+
2
))
{
// If the removal of this card has freed a whole pile, i.e. it was the last card in it...
if
(
baseX
<
freeSpaceMap
[
oldY
])
freeSpaceMap
[
oldY
]
=
baseX
;
}
}
void
Server_CardZone
::
insertCardIntoCoordMap
(
Server_Card
*
card
,
int
x
,
int
y
)
{
if
(
x
<
0
)
return
;
coordinateMap
[
y
].
insert
(
x
,
card
);
if
(
!
(
x
%
3
))
{
if
(
!
freePilesMap
[
y
].
contains
(
card
->
getName
(),
x
)
&&
card
->
getAttachedCards
().
isEmpty
())
freePilesMap
[
y
].
insert
(
card
->
getName
(),
x
);
if
(
freeSpaceMap
[
y
]
==
x
)
{
int
nextFreeX
=
x
;
do
{
nextFreeX
+=
3
;
}
while
(
coordinateMap
[
y
].
contains
(
nextFreeX
)
||
coordinateMap
[
y
].
contains
(
nextFreeX
+
1
)
||
coordinateMap
[
y
].
contains
(
nextFreeX
+
2
));
freeSpaceMap
[
y
]
=
nextFreeX
;
}
}
else
if
(
!
((
x
-
2
)
%
3
))
{
const
int
baseX
=
(
x
/
3
)
*
3
;
freePilesMap
[
y
].
remove
(
coordinateMap
[
y
].
value
(
baseX
)
->
getName
(),
baseX
);
}
}
int
Server_CardZone
::
removeCard
(
Server_Card
*
card
)
{
int
index
=
cards
.
indexOf
(
card
);
cards
.
removeAt
(
index
);
if
(
has_coords
)
removeCardFromCoordMap
(
card
,
card
->
getX
(),
card
->
getY
());
card
->
setZone
(
0
);
return
index
;
}
Server_Card
*
Server_CardZone
::
getCard
(
int
id
,
int
*
position
)
Server_Card
*
Server_CardZone
::
getCard
(
int
id
,
int
*
position
,
bool
remove
)
{
if
(
type
!=
ServerInfo_Zone
::
HiddenZone
)
{
QListIterator
<
Server_Card
*>
CardIterator
(
cards
);
int
i
=
0
;
while
(
CardIterator
.
hasNext
())
{
Server_Card
*
tmp
=
CardIterator
.
next
();
for
(
int
i
=
0
;
i
<
cards
.
size
();
++
i
)
{
Server_Card
*
tmp
=
cards
[
i
];
if
(
tmp
->
getId
()
==
id
)
{
if
(
position
)
*
position
=
i
;
if
(
remove
)
{
cards
.
removeAt
(
i
);
tmp
->
setZone
(
0
);
}
return
tmp
;
}
i
++
;
}
return
NULL
;
}
else
{
...
...
@@ -81,30 +131,29 @@ Server_Card *Server_CardZone::getCard(int id, int *position)
Server_Card
*
tmp
=
cards
[
id
];
if
(
position
)
*
position
=
id
;
if
(
remove
)
{
cards
.
removeAt
(
id
);
tmp
->
setZone
(
0
);
}
return
tmp
;
}
}
int
Server_CardZone
::
getFreeGridColumn
(
int
x
,
int
y
,
const
QString
&
cardName
)
const
{
QMap
<
int
,
Server_Card
*>
coordMap
;
for
(
int
i
=
0
;
i
<
cards
.
size
();
++
i
)
if
(
cards
[
i
]
->
getY
()
==
y
)
coordMap
.
insert
(
cards
[
i
]
->
getX
(),
cards
[
i
]);
int
resultX
=
0
;
const
QMap
<
int
,
Server_Card
*>
&
coordMap
=
coordinateMap
.
value
(
y
);
if
(
x
==
-
1
)
{
for
(
int
i
=
0
;
i
<
cards
.
size
();
++
i
)
if
((
cards
[
i
]
->
getName
()
==
cardName
)
&&
!
(
cards
[
i
]
->
getX
()
%
3
)
&&
(
cards
[
i
]
->
getY
()
==
y
))
{
if
(
!
c
ards
[
i
]
->
getAttachedCards
().
isEmpty
(
))
continue
;
if
(
!
coordMap
.
value
(
cards
[
i
]
->
getX
()
+
1
))
return
cards
[
i
]
->
getX
()
+
1
;
if
(
!
coordMap
.
value
(
cards
[
i
]
->
getX
()
+
2
))
return
cards
[
i
]
->
getX
()
+
2
;
}
}
else
if
(
x
=
=
-
2
)
{
}
else
{
if
(
freePilesMap
[
y
].
contains
(
cardName
))
{
x
=
(
freePilesMap
[
y
].
value
(
cardName
)
/
3
)
*
3
;
if
(
!
c
oordMap
.
contains
(
x
))
return
x
;
else
if
(
!
coordMap
.
contains
(
x
+
1
))
return
x
+
1
;
else
return
x
+
2
;
}
}
else
if
(
x
>
=
0
)
{
int
resultX
=
0
;
x
=
(
x
/
3
)
*
3
;
if
(
!
coordMap
.
contains
(
x
))
resultX
=
x
;
...
...
@@ -119,13 +168,14 @@ int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) co
resultX
=
x
;
x
=
-
1
;
}
if
(
x
<
0
)
while
(
coordMap
.
contains
(
resultX
))
resultX
+=
3
;
return
resultX
;
}
if
(
x
<
0
)
while
(
coordMap
.
value
(
resultX
))
resultX
+=
3
;
return
resultX
;
return
freeSpaceMap
[
y
];
}
bool
Server_CardZone
::
isColumnStacked
(
int
x
,
int
y
)
const
...
...
@@ -133,12 +183,7 @@ bool Server_CardZone::isColumnStacked(int x, int y) const
if
(
!
has_coords
)
return
false
;
QMap
<
int
,
Server_Card
*>
coordMap
;
for
(
int
i
=
0
;
i
<
cards
.
size
();
++
i
)
if
(
cards
[
i
]
->
getY
()
==
y
)
coordMap
.
insert
(
cards
[
i
]
->
getX
(),
cards
[
i
]);
return
coordMap
.
contains
((
x
/
3
)
*
3
+
1
);
return
coordinateMap
[
y
].
contains
((
x
/
3
)
*
3
+
1
);
}
bool
Server_CardZone
::
isColumnEmpty
(
int
x
,
int
y
)
const
...
...
@@ -146,63 +191,68 @@ bool Server_CardZone::isColumnEmpty(int x, int y) const
if
(
!
has_coords
)
return
true
;
QMap
<
int
,
Server_Card
*>
coordMap
;
for
(
int
i
=
0
;
i
<
cards
.
size
();
++
i
)
if
(
cards
[
i
]
->
getY
()
==
y
)
coordMap
.
insert
(
cards
[
i
]
->
getX
(),
cards
[
i
]);
return
!
coordMap
.
contains
((
x
/
3
)
*
3
);
return
!
coordinateMap
[
y
].
contains
((
x
/
3
)
*
3
);
}
void
Server_CardZone
::
moveCard
(
GameEventStorage
&
ges
,
QMap
<
int
,
Server_Card
*>
&
coordMap
,
Server_Card
*
card
,
int
x
,
int
y
)
void
Server_CardZone
::
moveCard
InRow
(
GameEventStorage
&
ges
,
Server_Card
*
card
,
int
x
,
int
y
)
{
coordMap
.
remove
(
card
->
getY
()
*
10000
+
card
->
getX
());
CardToMove
*
cardToMove
=
new
CardToMove
;
cardToMove
->
set_card_id
(
card
->
getId
());
player
->
moveCard
(
ges
,
this
,
QList
<
const
CardToMove
*>
()
<<
cardToMove
,
this
,
x
,
y
,
false
,
false
);
delete
cardToMove
;
coordMap
.
insert
(
y
*
10000
+
x
,
card
);
}
void
Server_CardZone
::
fixFreeSpaces
(
GameEventStorage
&
ges
)
{
QMap
<
int
,
Server_Card
*>
coord
Map
;
QSet
<
int
>
placesToLook
;
for
(
int
i
=
0
;
i
<
cards
.
size
();
++
i
)
{
coordMap
.
insert
(
cards
[
i
]
->
getY
()
*
10000
+
cards
[
i
]
->
getX
(),
cards
[
i
])
;
placesToLook
.
insert
(
cards
[
i
]
->
getY
()
*
10000
+
(
cards
[
i
]
->
getX
()
/
3
)
*
3
);
}
if
(
!
has_
coord
s
)
return
;
QSet
<
QPair
<
int
,
int
>
>
placesToLook
;
for
(
int
i
=
0
;
i
<
cards
.
size
();
++
i
)
placesToLook
.
insert
(
QPair
<
int
,
int
>
((
cards
[
i
]
->
getX
()
/
3
)
*
3
,
cards
[
i
]
->
getY
()));
QSetIterator
<
int
>
placeIterator
(
placesToLook
);
QSetIterator
<
QPair
<
int
,
int
>
>
placeIterator
(
placesToLook
);
while
(
placeIterator
.
hasNext
())
{
int
foo
=
placeIterator
.
next
();
int
y
=
foo
/
10000
;
int
baseX
=
foo
-
y
*
10000
;
const
QPair
<
int
,
int
>
&
foo
=
placeIterator
.
next
();
int
baseX
=
foo
.
first
;
int
y
=
foo
.
second
;
if
(
!
coord
Map
.
contains
(
y
*
10000
+
baseX
))
{
if
(
coord
Map
.
contains
(
y
*
10000
+
baseX
+
1
))
moveCard
(
ges
,
coord
Map
,
coordMap
.
value
(
y
*
10000
+
baseX
+
1
),
baseX
,
y
);
else
if
(
coord
Map
.
contains
(
y
*
10000
+
baseX
+
2
))
{
moveCard
(
ges
,
coord
Map
,
coordMap
.
value
(
y
*
10000
+
baseX
+
2
),
baseX
,
y
);
if
(
!
coord
inateMap
[
y
].
contains
(
baseX
))
{
if
(
coord
inateMap
[
y
].
contains
(
baseX
+
1
))
moveCard
InRow
(
ges
,
coord
inateMap
[
y
].
value
(
baseX
+
1
),
baseX
,
y
);
else
if
(
coord
inateMap
[
y
].
contains
(
baseX
+
2
))
{
moveCard
InRow
(
ges
,
coord
inateMap
[
y
].
value
(
baseX
+
2
),
baseX
,
y
);
continue
;
}
else
continue
;
}
if
(
!
coord
Map
.
contains
(
y
*
10000
+
baseX
+
1
)
&&
coordMap
.
contains
(
y
*
10000
+
baseX
+
2
))
moveCard
(
ges
,
coord
Map
,
coordMap
.
value
(
y
*
10000
+
baseX
+
2
),
baseX
+
1
,
y
);
if
(
!
coord
inateMap
[
y
].
contains
(
baseX
+
1
)
&&
coordinateMap
[
y
].
contains
(
baseX
+
2
))
moveCard
InRow
(
ges
,
coord
inateMap
[
y
].
value
(
baseX
+
2
),
baseX
+
1
,
y
);
}
}
void
Server_CardZone
::
updateCardCoordinates
(
Server_Card
*
card
,
int
oldX
,
int
oldY
)
{
if
(
!
has_coords
)
return
;
if
(
oldX
!=
-
1
)
removeCardFromCoordMap
(
card
,
oldX
,
oldY
);
insertCardIntoCoordMap
(
card
,
card
->
getX
(),
card
->
getY
());
}
void
Server_CardZone
::
insertCard
(
Server_Card
*
card
,
int
x
,
int
y
)
{
if
(
hasCoords
())
{
card
->
setCoords
(
x
,
y
);
cards
.
append
(
card
);
insertCardIntoCoordMap
(
card
,
x
,
y
);
}
else
{
card
->
setCoords
(
0
,
0
);
cards
.
insert
(
x
,
card
);
if
(
x
==
-
1
)
cards
.
append
(
card
);
else
cards
.
insert
(
x
,
card
);
}
card
->
setZone
(
this
);
}
...
...
@@ -212,6 +262,9 @@ void Server_CardZone::clear()
for
(
int
i
=
0
;
i
<
cards
.
size
();
i
++
)
delete
cards
.
at
(
i
);
cards
.
clear
();
coordinateMap
.
clear
();
freePilesMap
.
clear
();
freeSpaceMap
.
clear
();
playersWithWritePermission
.
clear
();
}
...
...
Prev
1
2
3
Next
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