initial commit
This commit is contained in:
commit
a11f93df4d
99 changed files with 7493 additions and 0 deletions
311
cockatrice/Doxyfile
Normal file
311
cockatrice/Doxyfile
Normal file
|
@ -0,0 +1,311 @@
|
|||
# Doxyfile 1.5.5-KDevelop
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = clienttest
|
||||
PROJECT_NUMBER = 0.1
|
||||
OUTPUT_DIRECTORY =
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH = /home/brukie/
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = /home/brukie/clienttest
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
*.cxx \
|
||||
*.cpp \
|
||||
*.c++ \
|
||||
*.d \
|
||||
*.java \
|
||||
*.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
*.inl \
|
||||
*.h \
|
||||
*.hh \
|
||||
*.hxx \
|
||||
*.hpp \
|
||||
*.h++ \
|
||||
*.idl \
|
||||
*.odl \
|
||||
*.cs \
|
||||
*.php \
|
||||
*.php3 \
|
||||
*.inc \
|
||||
*.m \
|
||||
*.mm \
|
||||
*.dox \
|
||||
*.py \
|
||||
*.f90 \
|
||||
*.f \
|
||||
*.vhd \
|
||||
*.vhdl \
|
||||
*.C \
|
||||
*.CC \
|
||||
*.C++ \
|
||||
*.II \
|
||||
*.I++ \
|
||||
*.H \
|
||||
*.HH \
|
||||
*.H++ \
|
||||
*.CS \
|
||||
*.PHP \
|
||||
*.PHP3 \
|
||||
*.M \
|
||||
*.MM \
|
||||
*.PY \
|
||||
*.F90 \
|
||||
*.F \
|
||||
*.VHD \
|
||||
*.VHDL \
|
||||
*.C \
|
||||
*.H \
|
||||
*.tlh \
|
||||
*.diff \
|
||||
*.patch \
|
||||
*.moc \
|
||||
*.xpm \
|
||||
*.dox
|
||||
RECURSIVE = yes
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NONE
|
||||
TREEVIEW_WIDTH = 250
|
||||
FORMULA_FONTSIZE = 10
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = yes
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE = clienttest.tag
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_FONTNAME = FreeSans
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = YES
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
15
cockatrice/clienttest.pro
Normal file
15
cockatrice/clienttest.pro
Normal file
|
@ -0,0 +1,15 @@
|
|||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) Sa Sep 6 14:27:18 2008
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += . src
|
||||
INCLUDEPATH += . src
|
||||
|
||||
QT += network opengl
|
||||
#QTPLUGIN += qjpeg
|
||||
|
||||
# Input
|
||||
HEADERS += src/counter.h src/dlg_games.h src/dlg_creategame.h src/dlg_connect.h src/gamesmodel.h src/client.h src/window.h src/servergame.h src/servereventdata.h src/serverresponse.h src/pendingcommand.h src/zonelist.h src/counterlist.h src/playerzone.h src/player.h src/cardlist.h src/carditem.h src/tablezone.h src/handzone.h src/playerlist.h src/game.h src/carddatabase.h src/gameview.h src/decklistmodel.h src/dlg_startgame.h src/cardinfowidget.h src/messagelogwidget.h src/serverzonecard.h src/zoneviewzone.h src/zoneviewwidget.h src/libraryzone.h src/gravezone.h src/rfgzone.h src/sideboardzone.h src/carddragitem.h src/zoneclosebutton.h src/zoneviewlayout.h
|
||||
SOURCES += src/counter.cpp src/dlg_games.cpp src/dlg_creategame.cpp src/dlg_connect.cpp src/client.cpp src/main.cpp src/window.cpp src/servereventdata.cpp src/gamesmodel.cpp src/player.cpp src/playerzone.cpp src/zonelist.cpp src/counterlist.cpp src/cardlist.cpp src/carditem.cpp src/tablezone.cpp src/handzone.cpp src/playerlist.cpp src/game.cpp src/carddatabase.cpp src/gameview.cpp src/decklistmodel.cpp src/dlg_startgame.cpp src/cardinfowidget.cpp src/messagelogwidget.cpp src/zoneviewzone.cpp src/zoneviewwidget.cpp src/libraryzone.cpp src/gravezone.cpp src/rfgzone.cpp src/sideboardzone.cpp src/carddragitem.cpp src/zoneclosebutton.cpp src/zoneviewlayout.cpp
|
340
cockatrice/copying
Normal file
340
cockatrice/copying
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
203
cockatrice/src/carddatabase.cpp
Normal file
203
cockatrice/src/carddatabase.cpp
Normal file
|
@ -0,0 +1,203 @@
|
|||
#include "carddatabase.h"
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
CardInfo::CardInfo(const QString &_name, const QString &_manacost, const QString &_cardtype, const QString &_powtough, const QStringList &_text)
|
||||
: name(_name), manacost(_manacost), cardtype(_cardtype), powtough(_powtough), text(_text), pixmap(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CardInfo::CardInfo(QDataStream &stream)
|
||||
: pixmap(NULL)
|
||||
{
|
||||
stream >> name
|
||||
>> editions
|
||||
>> manacost
|
||||
>> cardtype
|
||||
>> powtough
|
||||
>> text;
|
||||
}
|
||||
|
||||
CardInfo::~CardInfo()
|
||||
{
|
||||
if (pixmap)
|
||||
qDebug(QString("Deleting pixmap for %1").arg(name).toLatin1());
|
||||
delete pixmap;
|
||||
}
|
||||
|
||||
void CardInfo::addEdition(const QString &edition)
|
||||
{
|
||||
if (!editions.contains(edition))
|
||||
editions << edition;
|
||||
}
|
||||
|
||||
QPixmap *CardInfo::getPixmap()
|
||||
{
|
||||
if (pixmap)
|
||||
return pixmap;
|
||||
pixmap = new QPixmap();
|
||||
if (getName().isEmpty()) {
|
||||
pixmap->load("../pics/back.jpg");
|
||||
return pixmap;
|
||||
}
|
||||
qDebug(QString("CardDatabase: loading pixmap for %1").arg(getName()).toLatin1());
|
||||
for (int i = 0; i < editions.size(); i++) {
|
||||
/* Fire // Ice */
|
||||
if (pixmap->load(QString("../pics/%1/%2.full.jpg").arg(editions.at(i)).arg(getName().replace(" // ", ""))))
|
||||
return pixmap;
|
||||
if (pixmap->load(QString("../pics/%1/%2%3.full.jpg").arg(editions.at(i)).arg(getName().replace(" // ", "")).arg(1)))
|
||||
return pixmap;
|
||||
}
|
||||
pixmap->load("../pics/none.jpg");
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
void CardInfo::saveToStream(QDataStream &stream)
|
||||
{
|
||||
stream << name
|
||||
<< editions
|
||||
<< manacost
|
||||
<< cardtype
|
||||
<< powtough
|
||||
<< text;
|
||||
}
|
||||
|
||||
CardDatabase::CardDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
CardDatabase::~CardDatabase()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CardDatabase::clear()
|
||||
{
|
||||
QHashIterator<QString, CardInfo *> i(hash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
delete i.value();
|
||||
}
|
||||
hash.clear();
|
||||
}
|
||||
|
||||
CardInfo *CardDatabase::getCard(const QString &cardName)
|
||||
{
|
||||
if (hash.contains(cardName))
|
||||
return hash.value(cardName);
|
||||
else {
|
||||
qDebug(QString("CardDatabase: card not found: %1").arg(cardName).toLatin1());
|
||||
CardInfo *newCard = new CardInfo(cardName);
|
||||
newCard->addEdition("TK");
|
||||
hash.insert(cardName, newCard);
|
||||
return newCard;
|
||||
}
|
||||
}
|
||||
|
||||
void CardDatabase::importOracle()
|
||||
{
|
||||
clear();
|
||||
QDir dir("../db");
|
||||
|
||||
// XXX User soll selber auswählen können, welche Karten ihm am besten gefallen.
|
||||
// XXX Muss momentan schmutzig über Zahlen vor den Dateinamen gemacht werden.
|
||||
|
||||
dir.setSorting(QDir::Name | QDir::IgnoreCase);
|
||||
QFileInfoList files = dir.entryInfoList(QStringList() << "*.txt");
|
||||
for (int k = 0; k < files.size(); k++) {
|
||||
QFileInfo i = files[k];
|
||||
QString edition = i.fileName().mid(i.fileName().indexOf('_') + 1);
|
||||
edition = edition.left(edition.indexOf('.'));
|
||||
QFile file(i.filePath());
|
||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd()) {
|
||||
QString cardname = in.readLine();
|
||||
QString manacost = in.readLine();
|
||||
QString cardtype, powtough;
|
||||
QStringList text;
|
||||
if (manacost.contains("Land", Qt::CaseInsensitive)) {
|
||||
cardtype = manacost;
|
||||
manacost.clear();
|
||||
} else {
|
||||
cardtype = in.readLine();
|
||||
powtough = in.readLine();
|
||||
// Dirty hack.
|
||||
// Cards to test: Any creature, any basic land, Ancestral Vision, Fire // Ice.
|
||||
if (!powtough.contains("/") || powtough.size() > 5) {
|
||||
text << powtough;
|
||||
powtough = QString();
|
||||
}
|
||||
}
|
||||
QString line = in.readLine();
|
||||
while (!line.isEmpty()) {
|
||||
text << line;
|
||||
line = in.readLine();
|
||||
}
|
||||
CardInfo *card;
|
||||
if (hash.contains(cardname))
|
||||
card = hash.value(cardname);
|
||||
else {
|
||||
card = new CardInfo(cardname, manacost, cardtype, powtough, text);
|
||||
hash.insert(cardname, card);
|
||||
}
|
||||
card->addEdition(edition);
|
||||
}
|
||||
}
|
||||
|
||||
qDebug(QString("CardDatabase: %1 cards imported").arg(hash.size()).toLatin1());
|
||||
|
||||
CardInfo *empty = new CardInfo();
|
||||
empty->getPixmap(); // cache pixmap for card back
|
||||
hash.insert("", empty);
|
||||
}
|
||||
|
||||
int CardDatabase::loadFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QDataStream in(&file);
|
||||
in.setVersion(QDataStream::Qt_4_4);
|
||||
|
||||
quint32 _magicNumber, _fileVersion, cardCount;
|
||||
in >> _magicNumber
|
||||
>> _fileVersion
|
||||
>> cardCount;
|
||||
|
||||
if (_magicNumber != magicNumber)
|
||||
return -1;
|
||||
if (_fileVersion != fileVersion)
|
||||
return -2;
|
||||
|
||||
clear();
|
||||
hash.reserve(cardCount);
|
||||
for (unsigned int i = 0; i < cardCount; i++) {
|
||||
CardInfo *newCard = new CardInfo(in);
|
||||
hash.insert(newCard->getName(), newCard);
|
||||
}
|
||||
|
||||
return cardCount;
|
||||
}
|
||||
|
||||
bool CardDatabase::saveToFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QDataStream out(&file);
|
||||
out.setVersion(QDataStream::Qt_4_4);
|
||||
|
||||
out << (quint32) magicNumber
|
||||
<< (quint32) fileVersion
|
||||
<< (quint32) hash.size();
|
||||
|
||||
QHashIterator<QString, CardInfo *> i(hash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
i.value()->saveToStream(out);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
51
cockatrice/src/carddatabase.h
Normal file
51
cockatrice/src/carddatabase.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef CARDDATABASE_H
|
||||
#define CARDDATABASE_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QPixmap>
|
||||
#include <QDataStream>
|
||||
|
||||
class CardInfo {
|
||||
private:
|
||||
QString name;
|
||||
QStringList editions;
|
||||
QString manacost;
|
||||
QString cardtype;
|
||||
QString powtough;
|
||||
QStringList text;
|
||||
QPixmap *pixmap;
|
||||
public:
|
||||
CardInfo(const QString &_name = QString(),
|
||||
const QString &_manacost = QString(),
|
||||
const QString &_cardtype = QString(),
|
||||
const QString &_powtough = QString(),
|
||||
const QStringList &_text = QStringList());
|
||||
CardInfo(QDataStream &stream);
|
||||
~CardInfo();
|
||||
QString getName() const { return name; }
|
||||
QStringList getEditions() const { return editions; }
|
||||
QString getManacost() const { return manacost; }
|
||||
QString getCardType() const { return cardtype; }
|
||||
QString getPowTough() const { return powtough; }
|
||||
QStringList getText() const { return text; }
|
||||
void addEdition(const QString &edition);
|
||||
QPixmap *getPixmap();
|
||||
void saveToStream(QDataStream &stream);
|
||||
};
|
||||
|
||||
class CardDatabase {
|
||||
private:
|
||||
QHash<QString, CardInfo *> hash;
|
||||
static const unsigned int magicNumber = 0x12345678;
|
||||
static const unsigned int fileVersion = 1;
|
||||
public:
|
||||
CardDatabase();
|
||||
~CardDatabase();
|
||||
void clear();
|
||||
CardInfo *getCard(const QString &cardName = QString());
|
||||
void importOracle();
|
||||
int loadFromFile(const QString &fileName);
|
||||
bool saveToFile(const QString &fileName);
|
||||
};
|
||||
|
||||
#endif
|
97
cockatrice/src/carddragitem.cpp
Normal file
97
cockatrice/src/carddragitem.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include "carddragitem.h"
|
||||
#include "playerzone.h"
|
||||
#include <QtGui>
|
||||
|
||||
CardDragItem::CardDragItem(QGraphicsScene *scene, PlayerZone *_startZone, QPixmap *_image, int _id, const QPointF &_hotSpot, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), image(_image), id(_id), hotSpot(_hotSpot), startZone(_startZone)
|
||||
{
|
||||
if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) {
|
||||
qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1());
|
||||
hotSpot = QPointF();
|
||||
} else if ((hotSpot.x() > CARD_WIDTH) || (hotSpot.y() > CARD_HEIGHT)) {
|
||||
qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1());
|
||||
hotSpot = QPointF(CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
|
||||
setZValue(2000000000);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
|
||||
scene->addItem(this);
|
||||
}
|
||||
|
||||
CardDragItem::~CardDragItem()
|
||||
{
|
||||
qDebug("CardDragItem destructor");
|
||||
}
|
||||
|
||||
QRectF CardDragItem::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
|
||||
void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
// Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
QRectF foo = option->matrix.mapRect(boundingRect());
|
||||
QPixmap bar = image->scaled(foo.width(), foo.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
painter->drawPixmap(boundingRect(), bar, bar.rect());
|
||||
|
||||
// painter->drawPixmap(boundingRect(), *image, QRectF(0, 0, image->width(), image->height()));
|
||||
}
|
||||
|
||||
void CardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QPointF sp = event->scenePos();
|
||||
QList<QGraphicsItem *> colliding = scene()->items(sp);
|
||||
|
||||
PlayerZone *cursorZone = 0;
|
||||
for (int i = colliding.size() - 1; i >= 0; i--) {
|
||||
if ((cursorZone = qgraphicsitem_cast<PlayerZone *>(colliding.at(i)))) {
|
||||
if (cursorZone->getName() == "table") {
|
||||
QPointF cp = cursorZone->scenePos();
|
||||
QPointF localpos = sp - hotSpot - cp;
|
||||
setPos(QPointF(round(localpos.x() / RASTER_WIDTH) * RASTER_WIDTH, round(localpos.y() / RASTER_HEIGHT) * RASTER_HEIGHT) + cp);
|
||||
} else
|
||||
setPos(sp - hotSpot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
QGraphicsScene *sc = scene();
|
||||
QPointF sp = scenePos();
|
||||
sc->removeItem(this);
|
||||
QList<QGraphicsItem *> colliding = sc->items(event->scenePos());
|
||||
|
||||
qDebug(QString("drop: %1 collisions").arg(colliding.size()).toLatin1());
|
||||
PlayerZone *dropZone = 0;
|
||||
for (int i = colliding.size() - 1; i >= 0; i--) {
|
||||
QRectF bbox = colliding.at(i)->boundingRect();
|
||||
qDebug(QString("bbox x %1 y %2 w %3 h %4").arg(bbox.x()).arg(bbox.y()).arg(bbox.width()).arg(bbox.height()).toLatin1());
|
||||
|
||||
if ((dropZone = qgraphicsitem_cast<PlayerZone *>(colliding.at(i)))) {
|
||||
qDebug("zone found");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dropZone) {
|
||||
dropZone->handleDropEvent(id, startZone, (sp - dropZone->pos()).toPoint());
|
||||
QList<QGraphicsItem *> childList = childItems();
|
||||
for (int i = 0; i < childList.size(); i++) {
|
||||
CardDragItem *c = qgraphicsitem_cast<CardDragItem *>(childList.at(i));
|
||||
if (!c)
|
||||
QMessageBox::critical(0, "fehler", "null");
|
||||
dropZone->handleDropEvent(c->id, startZone, (sp - dropZone->pos() + c->pos()).toPoint());
|
||||
}
|
||||
} else
|
||||
QMessageBox::critical(0, "fehler", "fehler");
|
||||
|
||||
event->accept();
|
||||
}
|
28
cockatrice/src/carddragitem.h
Normal file
28
cockatrice/src/carddragitem.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef CARDDRAGITEM_H
|
||||
#define CARDDRAGITEM_H
|
||||
|
||||
#include "carditem.h"
|
||||
|
||||
class QGraphicsScene;
|
||||
class PlayerZone;
|
||||
|
||||
class CardDragItem : public QGraphicsItem {
|
||||
private:
|
||||
QPixmap *image;
|
||||
int id;
|
||||
QPointF hotSpot;
|
||||
PlayerZone *startZone;
|
||||
public:
|
||||
enum { Type = typeCardDrag };
|
||||
int type() const { return Type; }
|
||||
CardDragItem(QGraphicsScene *scene, PlayerZone *_startZone, QPixmap *_image, int _id, const QPointF &_hotSpot, QGraphicsItem *parent = 0);
|
||||
~CardDragItem();
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
QPointF getHotSpot() const { return hotSpot; }
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
};
|
||||
|
||||
#endif
|
61
cockatrice/src/cardinfowidget.cpp
Normal file
61
cockatrice/src/cardinfowidget.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "cardinfowidget.h"
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QTextEdit>
|
||||
|
||||
CardInfoWidget::CardInfoWidget(CardDatabase *_db, QWidget *parent)
|
||||
: QFrame(parent), db(_db), aspectratio(0)
|
||||
{
|
||||
cardPicture = new QLabel();
|
||||
cardPicture->setAlignment(Qt::AlignCenter);
|
||||
|
||||
nameLabel1 = new QLabel(tr("Name:"));
|
||||
nameLabel2 = new QLabel();
|
||||
manacostLabel1 = new QLabel(tr("Mana cost:"));
|
||||
manacostLabel2 = new QLabel();
|
||||
cardtypeLabel1 = new QLabel(tr("Card type:"));
|
||||
cardtypeLabel2 = new QLabel();
|
||||
powtoughLabel1 = new QLabel(tr("P / T:"));
|
||||
powtoughLabel2 = new QLabel();
|
||||
|
||||
textLabel = new QTextEdit();
|
||||
textLabel->setReadOnly(true);
|
||||
|
||||
QGridLayout *grid = new QGridLayout(this);
|
||||
grid->addWidget(cardPicture, 0, 0, 1, 2);
|
||||
grid->addWidget(nameLabel1, 1, 0);
|
||||
grid->addWidget(nameLabel2, 1, 1);
|
||||
grid->addWidget(manacostLabel1, 2, 0);
|
||||
grid->addWidget(manacostLabel2, 2, 1);
|
||||
grid->addWidget(cardtypeLabel1, 3, 0);
|
||||
grid->addWidget(cardtypeLabel2, 3, 1);
|
||||
grid->addWidget(powtoughLabel1, 4, 0);
|
||||
grid->addWidget(powtoughLabel2, 4, 1);
|
||||
grid->addWidget(textLabel, 5, 0, -1, 2);
|
||||
grid->setRowStretch(5, 1);
|
||||
|
||||
setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||
}
|
||||
|
||||
void CardInfoWidget::setCard(CardInfo *card)
|
||||
{
|
||||
if (!card)
|
||||
return;
|
||||
|
||||
QPixmap *pixmap = card->getPixmap();
|
||||
if (aspectratio == 0)
|
||||
aspectratio = (double) pixmap->height() / pixmap->width();
|
||||
double w = width() * 2.0 / 3.0;
|
||||
cardPicture->setPixmap(pixmap->scaled((int) w, (int) (w * aspectratio), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
|
||||
nameLabel2->setText(card->getName());
|
||||
manacostLabel2->setText(card->getManacost());
|
||||
cardtypeLabel2->setText(card->getCardType());
|
||||
powtoughLabel2->setText(card->getPowTough());
|
||||
textLabel->setText(card->getText().join("\n"));
|
||||
}
|
||||
|
||||
void CardInfoWidget::setCard(const QString &cardName)
|
||||
{
|
||||
setCard(db->getCard(cardName));
|
||||
}
|
29
cockatrice/src/cardinfowidget.h
Normal file
29
cockatrice/src/cardinfowidget.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CARDINFOWIDGET_H
|
||||
#define CARDINFOWIDGET_H
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include <QFrame>
|
||||
|
||||
class QLabel;
|
||||
class QTextEdit;
|
||||
|
||||
class CardInfoWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
private:
|
||||
CardDatabase *db;
|
||||
double aspectratio;
|
||||
|
||||
QLabel *cardPicture;
|
||||
QLabel *nameLabel1, *nameLabel2;
|
||||
QLabel *manacostLabel1, *manacostLabel2;
|
||||
QLabel *cardtypeLabel1, *cardtypeLabel2;
|
||||
QLabel *powtoughLabel1, *powtoughLabel2;
|
||||
QTextEdit *textLabel;
|
||||
public:
|
||||
CardInfoWidget(CardDatabase *_db, QWidget *parent = 0);
|
||||
public slots:
|
||||
void setCard(CardInfo *card);
|
||||
void setCard(const QString &cardName);
|
||||
};
|
||||
|
||||
#endif
|
202
cockatrice/src/carditem.cpp
Normal file
202
cockatrice/src/carditem.cpp
Normal file
|
@ -0,0 +1,202 @@
|
|||
#include <QApplication>
|
||||
#include <QtGui>
|
||||
#include "carditem.h"
|
||||
#include "carddragitem.h"
|
||||
#include "carddatabase.h"
|
||||
#include "playerzone.h"
|
||||
#include "tablezone.h"
|
||||
#include "player.h"
|
||||
|
||||
CardItem::CardItem(CardDatabase *_db, const QString &_name, int _cardid, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), db(_db), name(_name), id(_cardid), tapped(false), attacking(false), facedown(false), counters(0), dragItem(NULL)
|
||||
{
|
||||
width = CARD_WIDTH;
|
||||
height = CARD_HEIGHT;
|
||||
image = db->getCard(name)->getPixmap();
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
setFlag(ItemIsSelectable);
|
||||
setAcceptsHoverEvents(true);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
}
|
||||
|
||||
CardItem::~CardItem()
|
||||
{
|
||||
qDebug(QString("CardItem destructor: %1").arg(name).toLatin1());
|
||||
}
|
||||
|
||||
QRectF CardItem::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, width, height);
|
||||
}
|
||||
|
||||
void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
painter->save();
|
||||
QRectF foo = option->matrix.mapRect(boundingRect());
|
||||
qDebug(QString("%1: w=%2,h=%3").arg(name).arg(foo.width()).arg(foo.height()).toLatin1());
|
||||
QPixmap bar = image->scaled((int) foo.width(), (int) foo.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
// painter->drawPixmap(boundingRect(), *image, QRectF(0, 0, image->width(), image->height()));
|
||||
painter->drawPixmap(boundingRect(), bar, bar.rect());
|
||||
if (isSelected()) {
|
||||
painter->setPen(QPen(QColor("red")));
|
||||
painter->drawRect(QRectF(1, 1, width - 2, height - 2));
|
||||
}
|
||||
if (counters) {
|
||||
painter->setFont(QFont("Times", 32, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->setBackground(QBrush(QColor(255, 255, 255, 100)));
|
||||
painter->setBackgroundMode(Qt::OpaqueMode);
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(counters));
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void CardItem::setName(const QString &_name)
|
||||
{
|
||||
name = _name;
|
||||
image = db->getCard(name)->getPixmap();
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setTapped(bool _tapped)
|
||||
{
|
||||
tapped = _tapped;
|
||||
if (tapped)
|
||||
setTransform(QTransform().translate((float) width / 2, (float) height / 2).rotate(90).translate((float) -width / 2, (float) -height / 2));
|
||||
else
|
||||
setTransform(QTransform());
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setAttacking(bool _attacking)
|
||||
{
|
||||
attacking = _attacking;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setFacedown(bool _facedown)
|
||||
{
|
||||
facedown = _facedown;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setCounters(int _counters)
|
||||
{
|
||||
counters = _counters;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setAnnotation(const QString &_annotation)
|
||||
{
|
||||
annotation = _annotation;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::resetState()
|
||||
{
|
||||
attacking = false;
|
||||
facedown = false;
|
||||
counters = 0;
|
||||
annotation = QString();
|
||||
setTapped(false);
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
CardDragItem *CardItem::createDragItem(PlayerZone *startZone, int _id, const QPointF &_pos, const QPointF &_scenePos)
|
||||
{
|
||||
dragItem = new CardDragItem(scene(), startZone, image, _id, _pos);
|
||||
dragItem->setPos(_scenePos - dragItem->getHotSpot());
|
||||
|
||||
return dragItem;
|
||||
}
|
||||
|
||||
void CardItem::deleteDragItem()
|
||||
{
|
||||
delete dragItem;
|
||||
dragItem = NULL;
|
||||
}
|
||||
|
||||
void CardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!isSelected()) {
|
||||
scene()->clearSelection();
|
||||
setSelected(true);
|
||||
}
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
qgraphicsitem_cast<PlayerZone *>(parentItem())->getPlayer()->showCardMenu(event->screenPos());
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
createDragItem((PlayerZone *) parentItem(), id, event->pos(), event->scenePos());
|
||||
dragItem->grabMouse();
|
||||
|
||||
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
||||
for (int i = 0; i < sel.size(); i++) {
|
||||
CardItem *c = (CardItem *) sel.at(i);
|
||||
if (c == this)
|
||||
continue;
|
||||
CardDragItem *drag = new CardDragItem(scene(), (PlayerZone *) parentItem(), c->getImage(), c->getId(), QPointF(), dragItem);
|
||||
drag->setPos(c->pos() - pos());
|
||||
}
|
||||
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
if (!isSelected()) {
|
||||
// Unselect all items, then select this one
|
||||
scene()->setSelectionArea(QPainterPath());
|
||||
setSelected(true);
|
||||
}
|
||||
event->accept();
|
||||
|
||||
PlayerZone *zone = (PlayerZone *) parentItem();
|
||||
// Do nothing if the card belongs to another player
|
||||
if (!zone->getPlayer()->getLocal())
|
||||
return;
|
||||
|
||||
if (zone->getHasCardAttr())
|
||||
((TableZone *) zone)->toggleTapped();
|
||||
}
|
||||
|
||||
void CardItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
((PlayerZone *) parentItem())->hoverCardEvent(this);
|
||||
QGraphicsItem::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
void CardItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
QGraphicsItem::hoverLeaveEvent(event);
|
||||
}
|
||||
|
||||
QVariant CardItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemSelectedChange) {
|
||||
// XXX
|
||||
return value;
|
||||
} else if (change == ItemSelectedHasChanged) {
|
||||
update();
|
||||
return value;
|
||||
} else
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
81
cockatrice/src/carditem.h
Normal file
81
cockatrice/src/carditem.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef CARDITEM_H
|
||||
#define CARDITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
class CardDatabase;
|
||||
class CardDragItem;
|
||||
class PlayerZone;
|
||||
|
||||
|
||||
const int CARD_WIDTH = 72;
|
||||
const int CARD_HEIGHT = 102;
|
||||
const int RASTER_WIDTH = 36;
|
||||
const int RASTER_HEIGHT = 34;
|
||||
|
||||
/*
|
||||
const int CARD_WIDTH = 72;
|
||||
const int CARD_HEIGHT = 108;
|
||||
const int RASTER_WIDTH = 36;
|
||||
const int RASTER_HEIGHT = 36;
|
||||
*/
|
||||
|
||||
const int MAX_COUNTERS_ON_CARD = 999;
|
||||
|
||||
enum CardItemType {
|
||||
typeCard = QGraphicsItem::UserType + 1,
|
||||
typeCardDrag = QGraphicsItem::UserType + 2,
|
||||
typeZone = QGraphicsItem::UserType + 3,
|
||||
typeOther = QGraphicsItem::UserType + 4
|
||||
};
|
||||
|
||||
class CardItem : public QGraphicsItem {
|
||||
private:
|
||||
CardDatabase *db;
|
||||
QString name;
|
||||
int id;
|
||||
int width, height;
|
||||
QPixmap *image;
|
||||
bool tapped;
|
||||
bool attacking;
|
||||
bool facedown;
|
||||
int counters;
|
||||
QString annotation;
|
||||
CardDragItem *dragItem;
|
||||
public:
|
||||
enum { Type = typeCard };
|
||||
int type() const { return Type; }
|
||||
CardItem(CardDatabase *_db, const QString &_name, int _cardid, QGraphicsItem *parent = 0);
|
||||
~CardItem();
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
int getId() const { return id; }
|
||||
void setId(int _id) { id = _id; }
|
||||
QString getName() const { return name; }
|
||||
void setName(const QString &_name = QString());
|
||||
QPixmap *getImage() const { return image; }
|
||||
bool getTapped() const { return tapped; }
|
||||
void setTapped(bool _tapped);
|
||||
bool getAttacking() const { return attacking; }
|
||||
void setAttacking(bool _attacking);
|
||||
bool getFacedown() const { return facedown; }
|
||||
void setFacedown(bool _facedown);
|
||||
int getCounters() const { return counters; }
|
||||
void setCounters(int _counters);
|
||||
QString getAnnotation() const { return annotation; }
|
||||
void setAnnotation(const QString &_annotation);
|
||||
void resetState();
|
||||
|
||||
CardDragItem *createDragItem(PlayerZone *startZone, int _id, const QPointF &_pos, const QPointF &_scenePos);
|
||||
void deleteDragItem();
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
|
||||
};
|
||||
|
||||
#endif
|
31
cockatrice/src/cardlist.cpp
Normal file
31
cockatrice/src/cardlist.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "cardlist.h"
|
||||
|
||||
CardList::CardList(bool _contentsKnown)
|
||||
: QList<CardItem *>(), contentsKnown(_contentsKnown)
|
||||
{
|
||||
}
|
||||
|
||||
CardItem *CardList::findCard(const int id, const bool remove, int *position)
|
||||
{
|
||||
if (!contentsKnown) {
|
||||
if (empty())
|
||||
return 0;
|
||||
CardItem *temp = at(0);
|
||||
if (remove)
|
||||
removeAt(0);
|
||||
if (position)
|
||||
*position = id;
|
||||
return temp;
|
||||
} else
|
||||
for (int i = 0; i < size(); i++) {
|
||||
CardItem *temp = at(i);
|
||||
if (temp->getId() == id) {
|
||||
if (remove)
|
||||
removeAt(i);
|
||||
if (position)
|
||||
*position = i;
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
16
cockatrice/src/cardlist.h
Normal file
16
cockatrice/src/cardlist.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef CARDLIST_H
|
||||
#define CARDLIST_H
|
||||
|
||||
#include "carditem.h"
|
||||
#include <QList>
|
||||
|
||||
class CardList : public QList<CardItem *> {
|
||||
protected:
|
||||
bool contentsKnown;
|
||||
public:
|
||||
CardList(bool _contentsKnown);
|
||||
CardItem *findCard(const int id, const bool remove, int *position = NULL);
|
||||
bool getContentsKnown() const { return contentsKnown; }
|
||||
};
|
||||
|
||||
#endif
|
322
cockatrice/src/client.cpp
Normal file
322
cockatrice/src/client.cpp
Normal file
|
@ -0,0 +1,322 @@
|
|||
#include <QTimer>
|
||||
#include "client.h"
|
||||
|
||||
Client::Client(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(1000);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(checkTimeout()));
|
||||
|
||||
MsgId = 0;
|
||||
status = StatusDisconnected;
|
||||
socket = new QTcpSocket(this);
|
||||
socket->setTextModeEnabled(true);
|
||||
connect(socket, SIGNAL(connected()), this, SLOT(slotConnected()));
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readLine()));
|
||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotSocketError(QAbstractSocket::SocketError)));
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
delete socket;
|
||||
}
|
||||
|
||||
void Client::checkTimeout()
|
||||
{
|
||||
QListIterator<PendingCommand *> i(PendingCommands);
|
||||
while (i.hasNext()) {
|
||||
PendingCommand *c = i.next();
|
||||
c->incTime();
|
||||
if (c->timeout()) {
|
||||
disconnectFromServer();
|
||||
emit serverTimeout();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::slotSocketError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
emit logSocketError(socket->errorString());
|
||||
disconnectFromServer();
|
||||
}
|
||||
|
||||
void Client::slotConnected()
|
||||
{
|
||||
timer->start();
|
||||
setStatus(StatusAwaitingWelcome);
|
||||
}
|
||||
|
||||
void Client::readLine()
|
||||
{
|
||||
QString line;
|
||||
for (;;) {
|
||||
if (!socket->canReadLine())
|
||||
break;
|
||||
line = QString(socket->readLine()).trimmed();
|
||||
|
||||
if (line.isNull())
|
||||
break;
|
||||
qDebug(QString("readLine: %1").arg(line).toLatin1());
|
||||
QStringList values = line.split("|");
|
||||
QString prefix = values.takeFirst();
|
||||
// prefix is one of {welcome, private, public, resp, list_games, list_players, list_counters, list_zones, dump_zone}
|
||||
if (!(prefix.compare("private") && prefix.compare("public"))) {
|
||||
ServerEventData *event = new ServerEventData(line);
|
||||
if (event->getEventType() == eventPlayerId) {
|
||||
QStringList data = event->getEventData();
|
||||
if (data.size() != 2) {
|
||||
// XXX
|
||||
}
|
||||
bool ok;
|
||||
int id = data[0].toInt(&ok);
|
||||
if (!ok) {
|
||||
// XXX
|
||||
}
|
||||
delete event;
|
||||
emit playerIdReceived(id, data[1]);
|
||||
} else
|
||||
emit gameEvent(event);
|
||||
} else if (!prefix.compare("resp")) {
|
||||
bool ok;
|
||||
int msgid = values.takeFirst().toInt(&ok);
|
||||
if (!ok) {
|
||||
// XXX
|
||||
}
|
||||
|
||||
if (values.empty()) {
|
||||
// XXX
|
||||
}
|
||||
|
||||
ok = !values.takeFirst().compare("ok");
|
||||
|
||||
// XXX
|
||||
ServerErrorMessage message = msgNone;
|
||||
|
||||
// Update list of pending commands
|
||||
QListIterator<PendingCommand *> i(PendingCommands);
|
||||
bool found = false;
|
||||
PendingCommand *c;
|
||||
while (i.hasNext()) {
|
||||
c = i.next();
|
||||
if (c->getMsgId() == msgid) {
|
||||
found = true;
|
||||
|
||||
QString cmd = c->getCmd();
|
||||
if (cmd.startsWith("submit_deck"))
|
||||
readyStart();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
PendingCommands.removeAt(PendingCommands.indexOf(c));
|
||||
delete c;
|
||||
}
|
||||
|
||||
emit responseReceived(new ServerResponse(msgid, ok, message));
|
||||
} else if (!(prefix.compare("list_games")
|
||||
&& prefix.compare("list_players")
|
||||
&& prefix.compare("list_counters")
|
||||
&& prefix.compare("list_zones")
|
||||
&& prefix.compare("dump_zone")
|
||||
&& prefix.compare("welcome"))) {
|
||||
int cmdid = values.takeFirst().toInt();
|
||||
if (!values[0].compare(".")) {
|
||||
QListIterator<QStringList> i(msgbuf);
|
||||
QList<ServerGame *> gamelist;
|
||||
QList<ServerPlayer *> playerlist;
|
||||
QList<ServerZone *> zonelist;
|
||||
QList<ServerZoneCard *> zonedump;
|
||||
QStringList welcomemsg;
|
||||
while (i.hasNext()) {
|
||||
QStringList val = i.next();
|
||||
|
||||
// XXX Parametergültigkeit überprüfen
|
||||
if (!prefix.compare("list_games"))
|
||||
gamelist << new ServerGame(val[0], val[1], val[2].toInt(), val[3].toInt(), val[4].toInt());
|
||||
else if (!prefix.compare("list_players"))
|
||||
playerlist << new ServerPlayer(val[0].toInt(), val[1]);
|
||||
else if (!prefix.compare("list_counters"))
|
||||
{ }
|
||||
else if (!prefix.compare("list_zones"))
|
||||
zonelist << new ServerZone(val[0], val[1] == "1", val[2] == "1", val[3].toInt());
|
||||
else if (!prefix.compare("dump_zone"))
|
||||
zonedump << new ServerZoneCard(val[0].toInt(), val[1], val[2].toInt(), val[3].toInt(), val[4].toInt(), val[5] == "1", val[6]);
|
||||
else if (!prefix.compare("welcome"))
|
||||
welcomemsg << val[0];
|
||||
}
|
||||
if (!prefix.compare("list_games"))
|
||||
emit gameListReceived(gamelist);
|
||||
else if (!prefix.compare("list_players"))
|
||||
emit playerListReceived(playerlist);
|
||||
else if (!prefix.compare("list_counters"))
|
||||
{ }
|
||||
else if (!prefix.compare("list_zones"))
|
||||
emit zoneListReceived(cmdid, zonelist);
|
||||
else if (!prefix.compare("dump_zone"))
|
||||
emit zoneDumpReceived(cmdid, zonedump);
|
||||
else if (!prefix.compare("welcome")) {
|
||||
emit welcomeMsgReceived(welcomemsg);
|
||||
setStatus(StatusConnected);
|
||||
setName(PlayerName);
|
||||
}
|
||||
msgbuf.clear();
|
||||
} else
|
||||
msgbuf << values;
|
||||
} else {
|
||||
// XXX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::setStatus(const ProtocolStatus _status)
|
||||
{
|
||||
status = _status;
|
||||
emit statusChanged(_status);
|
||||
}
|
||||
|
||||
void Client::msg(const QString &s)
|
||||
{
|
||||
qDebug(QString("msg gibt aus: %1").arg(s).toLatin1());
|
||||
QTextStream stream(socket);
|
||||
stream.setCodec("UTF-8");
|
||||
stream << s << endl;
|
||||
stream.flush();
|
||||
socket->flush();
|
||||
}
|
||||
|
||||
int Client::cmd(const QString &s)
|
||||
{
|
||||
msg(QString("%1|%2").arg(++MsgId).arg(s));
|
||||
PendingCommands << new PendingCommand(s, MsgId);
|
||||
return MsgId;
|
||||
}
|
||||
|
||||
void Client::connectToServer(const QString &hostname, unsigned int port, const QString &playername)
|
||||
{
|
||||
PlayerName = playername;
|
||||
socket->connectToHost(hostname, port);
|
||||
setStatus(StatusConnecting);
|
||||
}
|
||||
|
||||
void Client::disconnectFromServer()
|
||||
{
|
||||
timer->stop();
|
||||
PendingCommands.clear();
|
||||
setStatus(StatusDisconnected);
|
||||
socket->close();
|
||||
}
|
||||
|
||||
int Client::listGames()
|
||||
{
|
||||
return cmd("list_games");
|
||||
}
|
||||
|
||||
int Client::listPlayers()
|
||||
{
|
||||
return cmd("list_players");
|
||||
}
|
||||
|
||||
int Client::createGame(const QString &name, const QString &description, const QString &password, unsigned int maxPlayers)
|
||||
{
|
||||
return cmd(QString("create_game|%1|%2|%3|%4").arg(name).arg(description).arg(password).arg(maxPlayers));
|
||||
}
|
||||
|
||||
int Client::joinGame(const QString &name, const QString &password)
|
||||
{
|
||||
return cmd(QString("join_game|%1|%2").arg(name).arg(password));
|
||||
}
|
||||
|
||||
int Client::leaveGame()
|
||||
{
|
||||
return cmd("leave_game");
|
||||
}
|
||||
|
||||
int Client::setName(const QString &name)
|
||||
{
|
||||
return cmd(QString("set_name|%1").arg(name));
|
||||
}
|
||||
|
||||
int Client::say(const QString &s)
|
||||
{
|
||||
return cmd(QString("say|%1").arg(s));
|
||||
}
|
||||
|
||||
int Client::shuffle()
|
||||
{
|
||||
return cmd("shuffle");
|
||||
}
|
||||
|
||||
int Client::rollDice(unsigned int sides)
|
||||
{
|
||||
return cmd(QString("roll_dice|%1").arg(sides));
|
||||
}
|
||||
|
||||
int Client::drawCards(unsigned int number)
|
||||
{
|
||||
return cmd(QString("draw_cards|%1").arg(number));
|
||||
}
|
||||
|
||||
int Client::moveCard(int cardid, const QString &startzone, const QString &targetzone, int x, int y)
|
||||
{
|
||||
// if startzone is public: cardid is the card's id
|
||||
// else: cardid is the position of the card in the zone (e.g. deck)
|
||||
return cmd(QString("move_card|%1|%2|%3|%4|%5").arg(cardid).arg(startzone).arg(targetzone).arg(x).arg(y));
|
||||
}
|
||||
|
||||
int Client::createToken(const QString &zone, const QString &name, const QString &powtough, int x, int y)
|
||||
{
|
||||
return cmd(QString("create_token|%1|%2|%3|%4|%5").arg(zone).arg(name).arg(powtough).arg(x).arg(y));
|
||||
}
|
||||
|
||||
int Client::setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue)
|
||||
{
|
||||
return cmd(QString("set_card_attr|%1|%2|%3|%4").arg(zone).arg(cardid).arg(aname).arg(avalue));
|
||||
}
|
||||
|
||||
int Client::submitDeck(const QStringList &deck)
|
||||
{
|
||||
int retval = cmd("submit_deck");
|
||||
QStringListIterator i(deck);
|
||||
while (i.hasNext())
|
||||
msg(i.next());
|
||||
msg(".");
|
||||
return retval;
|
||||
}
|
||||
|
||||
int Client::readyStart()
|
||||
{
|
||||
return cmd("ready_start");
|
||||
}
|
||||
|
||||
int Client::incCounter(const QString &counter, int delta)
|
||||
{
|
||||
return cmd(QString("inc_counter|%1|%2").arg(counter).arg(delta));
|
||||
}
|
||||
|
||||
int Client::setCounter(const QString &counter, int value)
|
||||
{
|
||||
return cmd(QString("set_counter|%1|%2").arg(counter).arg(value));
|
||||
}
|
||||
|
||||
int Client::delCounter(const QString &counter)
|
||||
{
|
||||
return cmd(QString("del_counter|%1").arg(counter));
|
||||
}
|
||||
|
||||
int Client::setActivePlayer(int player)
|
||||
{
|
||||
return cmd(QString("set_active_player|%1").arg(player));
|
||||
}
|
||||
|
||||
int Client::setActivePhase(int phase)
|
||||
{
|
||||
return cmd(QString("set_active_phase|%1").arg(phase));
|
||||
}
|
||||
|
||||
int Client::dumpZone(int player, const QString &zone, int numberCards)
|
||||
{
|
||||
return cmd(QString("dump_zone|%1|%2|%3").arg(player).arg(zone).arg(numberCards));
|
||||
}
|
86
cockatrice/src/client.h
Normal file
86
cockatrice/src/client.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include "servereventdata.h"
|
||||
#include "serverresponse.h"
|
||||
#include "servergame.h"
|
||||
#include "serverplayer.h"
|
||||
#include "serverzone.h"
|
||||
#include "serverzonecard.h"
|
||||
#include "pendingcommand.h"
|
||||
#include <QTcpSocket>
|
||||
|
||||
class QTimer;
|
||||
|
||||
// Connection state.
|
||||
// The protocol handler itself is stateless once the connection
|
||||
// has been established.
|
||||
enum ProtocolStatus { StatusDisconnected,
|
||||
StatusConnecting,
|
||||
StatusAwaitingWelcome,
|
||||
StatusConnected };
|
||||
|
||||
class Client : public QObject {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void statusChanged(ProtocolStatus _status);
|
||||
void welcomeMsgReceived(QStringList welcomeMsg);
|
||||
void gameListReceived(QList<ServerGame *> games);
|
||||
void playerListReceived(QList<ServerPlayer *> players);
|
||||
void zoneListReceived(int commandId, QList<ServerZone *> zones);
|
||||
void zoneDumpReceived(int commandId, QList<ServerZoneCard *> cards);
|
||||
void responseReceived(ServerResponse *response);
|
||||
void playerIdReceived(int id, QString name);
|
||||
void gameEvent(ServerEventData *msg);
|
||||
void serverTimeout();
|
||||
void logSocketError(const QString &errorString);
|
||||
|
||||
private slots:
|
||||
void slotConnected();
|
||||
void readLine();
|
||||
void checkTimeout();
|
||||
void slotSocketError(QAbstractSocket::SocketError error);
|
||||
|
||||
private:
|
||||
QTimer *timer;
|
||||
QList<PendingCommand *> PendingCommands;
|
||||
QTcpSocket *socket;
|
||||
ProtocolStatus status;
|
||||
QList<QStringList> msgbuf;
|
||||
QString PlayerName;
|
||||
unsigned int MsgId;
|
||||
void msg(const QString &s);
|
||||
int cmd(const QString &s);
|
||||
void setStatus(const ProtocolStatus _status);
|
||||
public:
|
||||
Client(QObject *parent = 0);
|
||||
~Client();
|
||||
ProtocolStatus getStatus() { return status; }
|
||||
QString peerName() const { return socket->peerName(); }
|
||||
|
||||
void connectToServer(const QString &hostname, unsigned int port, const QString &playername);
|
||||
void disconnectFromServer();
|
||||
int listGames();
|
||||
int listPlayers();
|
||||
int createGame(const QString &name, const QString &description, const QString &password, unsigned int maxPlayers);
|
||||
int joinGame(const QString &name, const QString &password);
|
||||
int leaveGame();
|
||||
int setName(const QString &name);
|
||||
int say(const QString &s);
|
||||
int shuffle();
|
||||
int rollDice(unsigned int sides);
|
||||
int drawCards(unsigned int number);
|
||||
int moveCard(int cardid, const QString &startzone, const QString &targetzone, int x, int y = 0);
|
||||
int createToken(const QString &zone, const QString &name, const QString &powtough, int x, int y);
|
||||
int setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue);
|
||||
int submitDeck(const QStringList &deck);
|
||||
int readyStart();
|
||||
int incCounter(const QString &counter, int delta);
|
||||
int setCounter(const QString &counter, int value);
|
||||
int delCounter(const QString &counter);
|
||||
int setActivePlayer(int player);
|
||||
int setActivePhase(int phase);
|
||||
int dumpZone(int player, const QString &zone, int numberCards);
|
||||
};
|
||||
|
||||
#endif
|
30
cockatrice/src/counter.cpp
Normal file
30
cockatrice/src/counter.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include "counter.h"
|
||||
#include "player.h"
|
||||
#include <QtGui>
|
||||
|
||||
Counter::Counter(Player *_player, const QString &_name, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), name(_name), value(0), player(_player)
|
||||
{
|
||||
player->addCounter(this);
|
||||
}
|
||||
|
||||
QRectF Counter::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 30);
|
||||
}
|
||||
|
||||
void Counter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QBrush(QColor("gray")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString("%1").arg(value));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void Counter::setValue(int _value)
|
||||
{
|
||||
value = _value;
|
||||
update(boundingRect());
|
||||
}
|
24
cockatrice/src/counter.h
Normal file
24
cockatrice/src/counter.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef COUNTER_H
|
||||
#define COUNTER_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
class Player;
|
||||
|
||||
class Counter : public QGraphicsItem {
|
||||
private:
|
||||
QString name;
|
||||
int value;
|
||||
protected:
|
||||
Player *player;
|
||||
public:
|
||||
Counter(Player *_player, const QString &_name, QGraphicsItem *parent = 0);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
QString getName() const { return name; }
|
||||
int getValue() const { return value; }
|
||||
void setValue(int _value);
|
||||
};
|
||||
|
||||
#endif
|
11
cockatrice/src/counterlist.cpp
Normal file
11
cockatrice/src/counterlist.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "counterlist.h"
|
||||
|
||||
Counter *CounterList::findCounter(const QString &name) const
|
||||
{
|
||||
for (int i = 0; i < size(); i++) {
|
||||
Counter *temp = at(i);
|
||||
if (!temp->getName().compare(name))
|
||||
return temp;
|
||||
}
|
||||
return 0;
|
||||
}
|
12
cockatrice/src/counterlist.h
Normal file
12
cockatrice/src/counterlist.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef COUNTERLIST_H
|
||||
#define COUNTERLIST_H
|
||||
|
||||
#include "counter.h"
|
||||
#include <QList>
|
||||
|
||||
class CounterList : public QList<Counter *> {
|
||||
public:
|
||||
Counter *findCounter(const QString &name) const;
|
||||
};
|
||||
|
||||
#endif
|
92
cockatrice/src/decklistmodel.cpp
Normal file
92
cockatrice/src/decklistmodel.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
#include "decklistmodel.h"
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
DeckListModel::~DeckListModel()
|
||||
{
|
||||
qDebug("DeckListModel destructor");
|
||||
cleanList();
|
||||
}
|
||||
|
||||
int DeckListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return deckList.size();
|
||||
}
|
||||
|
||||
int DeckListModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant DeckListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if ((index.row() >= deckList.size()) || (index.column() >= 2))
|
||||
return QVariant();
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
DecklistRow *r = deckList.at(index.row());
|
||||
switch (index.column()) {
|
||||
case 0: return r->getNumber();
|
||||
case 1: return r->getCard();
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant DeckListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
if (orientation != Qt::Horizontal)
|
||||
return QVariant();
|
||||
switch (section) {
|
||||
case 0: return QString(tr("Number"));
|
||||
case 1: return QString(tr("Card"));
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void DeckListModel::cleanList()
|
||||
{
|
||||
QListIterator<DecklistRow *> i(deckList);
|
||||
while (i.hasNext())
|
||||
delete i.next();
|
||||
deckList.clear();
|
||||
}
|
||||
|
||||
void DeckListModel::loadFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
QTextStream in(&file);
|
||||
cleanList();
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().simplified();
|
||||
bool isSideboard = false;
|
||||
if (line.startsWith("SB:")) {
|
||||
line = line.mid(3).trimmed();
|
||||
isSideboard = true;
|
||||
}
|
||||
int i = line.indexOf(' ');
|
||||
bool ok;
|
||||
int number = line.left(i).toInt(&ok);
|
||||
if (!ok)
|
||||
continue;
|
||||
DecklistRow *row = new DecklistRow(number, line.mid(i + 1), isSideboard);
|
||||
deckList << row;
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
DecklistRow *DeckListModel::getRow(int row) const
|
||||
{
|
||||
if (row >= deckList.size())
|
||||
return 0;
|
||||
return deckList.at(row);
|
||||
}
|
36
cockatrice/src/decklistmodel.h
Normal file
36
cockatrice/src/decklistmodel.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef DECKLISTMODEL_H
|
||||
#define DECKLISTMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
|
||||
class DecklistRow {
|
||||
private:
|
||||
int number;
|
||||
QString card;
|
||||
bool sideboard;
|
||||
public:
|
||||
DecklistRow(int _number, const QString &_card, bool _sideboard) : number(_number), card(_card), sideboard(_sideboard) { }
|
||||
int getNumber() const { return number; }
|
||||
QString getCard() const { return card; }
|
||||
bool isSideboard() const { return sideboard; }
|
||||
};
|
||||
|
||||
class DeckListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DeckListModel(QObject *parent = 0)
|
||||
: QAbstractListModel(parent) { }
|
||||
~DeckListModel();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
void loadFromFile(const QString &fileName);
|
||||
DecklistRow *getRow(int row) const;
|
||||
private:
|
||||
QList<DecklistRow *> deckList;
|
||||
void cleanList();
|
||||
};
|
||||
|
||||
#endif
|
61
cockatrice/src/dlg_connect.cpp
Normal file
61
cockatrice/src/dlg_connect.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include <QtGui>
|
||||
#include "dlg_connect.h"
|
||||
|
||||
DlgConnect::DlgConnect(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit("localhost");
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit("4747");
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit("Player");
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setDefault(true);
|
||||
cancelButton = new QPushButton(tr("&Cancel"));
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(hostLabel, 0, 0);
|
||||
grid->addWidget(hostEdit, 0, 1);
|
||||
grid->addWidget(portLabel, 1, 0);
|
||||
grid->addWidget(portEdit, 1, 1);
|
||||
grid->addWidget(playernameLabel, 2, 0);
|
||||
grid->addWidget(playernameEdit, 2, 1);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Connect to server"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
|
||||
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
}
|
||||
|
||||
QString DlgConnect::getHost()
|
||||
{
|
||||
return hostEdit->text();
|
||||
}
|
||||
|
||||
int DlgConnect::getPort()
|
||||
{
|
||||
return portEdit->text().toInt();
|
||||
}
|
||||
|
||||
QString DlgConnect::getPlayerName()
|
||||
{
|
||||
return playernameEdit->text();
|
||||
}
|
23
cockatrice/src/dlg_connect.h
Normal file
23
cockatrice/src/dlg_connect.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef DLG_CONNECT_H
|
||||
#define DLG_CONNECT_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
|
||||
class DlgConnect : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgConnect(QWidget *parent = 0);
|
||||
QString getHost();
|
||||
int getPort();
|
||||
QString getPlayerName();
|
||||
private:
|
||||
QLabel *hostLabel, *portLabel, *playernameLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit;
|
||||
QPushButton *okButton, *cancelButton;
|
||||
};
|
||||
|
||||
#endif
|
85
cockatrice/src/dlg_creategame.cpp
Normal file
85
cockatrice/src/dlg_creategame.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include <QtGui>
|
||||
#include "dlg_creategame.h"
|
||||
|
||||
DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent)
|
||||
: QDialog(parent), client(_client)
|
||||
{
|
||||
msgid = 0;
|
||||
|
||||
nameLabel = new QLabel(tr("&Name:"));
|
||||
nameEdit = new QLineEdit;
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
|
||||
descriptionLabel = new QLabel(tr("&Description:"));
|
||||
descriptionEdit = new QLineEdit;
|
||||
descriptionLabel->setBuddy(descriptionEdit);
|
||||
|
||||
passwordLabel = new QLabel(tr("&Password:"));
|
||||
passwordEdit = new QLineEdit;
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
|
||||
maxPlayersLabel = new QLabel(tr("&Max Players:"));
|
||||
maxPlayersEdit = new QLineEdit("2");
|
||||
maxPlayersLabel->setBuddy(maxPlayersEdit);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(nameLabel, 0, 0);
|
||||
grid->addWidget(nameEdit, 0, 1);
|
||||
grid->addWidget(descriptionLabel, 1, 0);
|
||||
grid->addWidget(descriptionEdit, 1, 1);
|
||||
grid->addWidget(passwordLabel, 2, 0);
|
||||
grid->addWidget(passwordEdit, 2, 1);
|
||||
grid->addWidget(maxPlayersLabel, 3, 0);
|
||||
grid->addWidget(maxPlayersEdit, 3, 1);
|
||||
|
||||
okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setDefault(true);
|
||||
cancelButton = new QPushButton(tr("&Cancel"));
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Create game"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
|
||||
connect(okButton, SIGNAL(clicked()), this, SLOT(actOK()));
|
||||
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(client, SIGNAL(responseReceived(ServerResponse *)), this, SLOT(checkResponse(ServerResponse *)));
|
||||
}
|
||||
|
||||
void DlgCreateGame::actOK()
|
||||
{
|
||||
bool ok;
|
||||
int maxPlayers = maxPlayersEdit->text().toInt(&ok);
|
||||
if (msgid)
|
||||
return;
|
||||
if (!ok) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid number of players."));
|
||||
return;
|
||||
}
|
||||
msgid = client->createGame(nameEdit->text(),
|
||||
descriptionEdit->text(),
|
||||
passwordEdit->text(),
|
||||
maxPlayers);
|
||||
}
|
||||
|
||||
void DlgCreateGame::checkResponse(ServerResponse *response)
|
||||
{
|
||||
if (response->getMsgId() != msgid)
|
||||
return;
|
||||
if (response->getOk())
|
||||
accept();
|
||||
else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("XXX"));
|
||||
msgid = 0;
|
||||
return;
|
||||
}
|
||||
}
|
28
cockatrice/src/dlg_creategame.h
Normal file
28
cockatrice/src/dlg_creategame.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef DLG_CREATEGAME_H
|
||||
#define DLG_CREATEGAME_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "client.h"
|
||||
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
|
||||
class DlgCreateGame : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgCreateGame(Client *_client, QWidget *parent = 0);
|
||||
private slots:
|
||||
void actOK();
|
||||
void checkResponse(ServerResponse *response);
|
||||
private:
|
||||
Client *client;
|
||||
int msgid;
|
||||
|
||||
QLabel *nameLabel, *descriptionLabel, *passwordLabel, *maxPlayersLabel;
|
||||
QLineEdit *nameEdit, *descriptionEdit, *passwordEdit, *maxPlayersEdit;
|
||||
QPushButton *okButton, *cancelButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
87
cockatrice/src/dlg_games.cpp
Normal file
87
cockatrice/src/dlg_games.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
#include <QtGui>
|
||||
#include "dlg_games.h"
|
||||
#include "dlg_creategame.h"
|
||||
|
||||
DlgGames::DlgGames(Client *_client, QWidget *parent)
|
||||
: QDialog(parent), client(_client)
|
||||
{
|
||||
msgid = 0;
|
||||
|
||||
tableView = new QTreeView;
|
||||
tableModel = new GamesModel(this);
|
||||
tableView->setModel(tableModel);
|
||||
|
||||
createButton = new QPushButton(tr("&Create"));
|
||||
refreshButton = new QPushButton(tr("&Refresh"));
|
||||
joinButton = new QPushButton(tr("&Join"));
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addWidget(createButton);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(refreshButton);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(joinButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(tableView);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Games"));
|
||||
setMinimumWidth(sizeHint().width());
|
||||
|
||||
connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
|
||||
connect(refreshButton, SIGNAL(clicked()), this, SLOT(actRefresh()));
|
||||
connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
|
||||
|
||||
connect(client, SIGNAL(gameListReceived(QList<ServerGame *>)), this, SLOT(gameListReceived(QList<ServerGame *>)));
|
||||
client->listGames();
|
||||
}
|
||||
|
||||
void DlgGames::actCreate()
|
||||
{
|
||||
DlgCreateGame dlg(client, this);
|
||||
if (dlg.exec())
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgGames::actRefresh()
|
||||
{
|
||||
client->listGames();
|
||||
}
|
||||
|
||||
void DlgGames::checkResponse(ServerResponse *response)
|
||||
{
|
||||
if (response->getMsgId() != msgid)
|
||||
return;
|
||||
if (response->getOk())
|
||||
accept();
|
||||
else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("XXX"));
|
||||
msgid = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DlgGames::actJoin()
|
||||
{
|
||||
if (msgid)
|
||||
return;
|
||||
|
||||
ServerGame *game = tableModel->getGame(tableView->currentIndex().row());
|
||||
QString password;
|
||||
if (game->getHasPassword()) {
|
||||
bool ok;
|
||||
password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
}
|
||||
|
||||
connect(client, SIGNAL(responseReceived(ServerResponse *)), this, SLOT(checkResponse(ServerResponse *)));
|
||||
msgid = client->joinGame(game->getName(), password);
|
||||
}
|
||||
|
||||
void DlgGames::gameListReceived(QList<ServerGame *> _gameList)
|
||||
{
|
||||
tableModel->setGameList(_gameList);
|
||||
}
|
32
cockatrice/src/dlg_games.h
Normal file
32
cockatrice/src/dlg_games.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef DLG_GAMES_H
|
||||
#define DLG_GAMES_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "gamesmodel.h"
|
||||
#include "servergame.h"
|
||||
#include "client.h"
|
||||
|
||||
class QPushButton;
|
||||
class QTreeView;
|
||||
|
||||
class DlgGames : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgGames(Client *_client, QWidget *parent = 0);
|
||||
private slots:
|
||||
void actCreate();
|
||||
void actRefresh();
|
||||
void actJoin();
|
||||
void gameListReceived(QList<ServerGame *> _gameList);
|
||||
void checkResponse(ServerResponse *response);
|
||||
private:
|
||||
Client *client;
|
||||
int msgid;
|
||||
|
||||
QTreeView *tableView;
|
||||
GamesModel *tableModel;
|
||||
QPushButton *refreshButton, *createButton, *joinButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
63
cockatrice/src/dlg_startgame.cpp
Normal file
63
cockatrice/src/dlg_startgame.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#include <QtGui>
|
||||
#include <QFileDialog>
|
||||
#include "dlg_startgame.h"
|
||||
#include "decklistmodel.h"
|
||||
#include "carddatabase.h"
|
||||
|
||||
DlgStartGame::DlgStartGame(CardDatabase *_db, QWidget *parent)
|
||||
: QDialog(parent), db(_db)
|
||||
{
|
||||
tableView = new QTreeView;
|
||||
tableModel = new DeckListModel(this);
|
||||
tableView->setModel(tableModel);
|
||||
|
||||
loadButton = new QPushButton(tr("&Load..."));
|
||||
okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setDefault(true);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addWidget(loadButton);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(tableView);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Start game"));
|
||||
setMinimumWidth(sizeHint().width());
|
||||
|
||||
connect(loadButton, SIGNAL(clicked()), this, SLOT(actLoad()));
|
||||
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
}
|
||||
|
||||
void DlgStartGame::actLoad()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Load deck"), QString(), tr("Deck files (*.dec)"));
|
||||
if (!fileName.isEmpty())
|
||||
tableModel->loadFromFile(fileName);
|
||||
|
||||
// Precache card pictures
|
||||
for (int i = 0; i < tableModel->rowCount(); i++) {
|
||||
QString cardName = tableModel->getRow(i)->getCard();
|
||||
CardInfo *card = db->getCard(cardName);
|
||||
if (!card) {
|
||||
qDebug(QString("Invalid card: %1").arg(cardName).toLatin1());
|
||||
continue;
|
||||
}
|
||||
card->getPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList DlgStartGame::getDeckList() const
|
||||
{
|
||||
QStringList result;
|
||||
for (int i = 0; i < tableModel->rowCount(); i++) {
|
||||
DecklistRow *temp = tableModel->getRow(i);
|
||||
for (int j = 0; j < temp->getNumber(); j++)
|
||||
result << QString("%1%2").arg(temp->isSideboard() ? "SB:" : "").arg(temp->getCard());
|
||||
}
|
||||
return result;
|
||||
}
|
26
cockatrice/src/dlg_startgame.h
Normal file
26
cockatrice/src/dlg_startgame.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef DLG_STARTGAME_H
|
||||
#define DLG_STARTGAME_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "decklistmodel.h"
|
||||
|
||||
class QTreeView;
|
||||
class QPushButton;
|
||||
class CardDatabase;
|
||||
|
||||
class DlgStartGame: public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgStartGame(CardDatabase *_db, QWidget *parent = 0);
|
||||
QStringList getDeckList() const;
|
||||
private slots:
|
||||
void actLoad();
|
||||
private:
|
||||
CardDatabase *db;
|
||||
QTreeView *tableView;
|
||||
DeckListModel *tableModel;
|
||||
|
||||
QPushButton *loadButton, *okButton;
|
||||
};
|
||||
|
||||
#endif
|
371
cockatrice/src/game.cpp
Normal file
371
cockatrice/src/game.cpp
Normal file
|
@ -0,0 +1,371 @@
|
|||
#include <QGraphicsScene>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include "serverplayer.h"
|
||||
#include "game.h"
|
||||
#include "servereventdata.h"
|
||||
#include "client.h"
|
||||
#include "tablezone.h"
|
||||
#include "handzone.h"
|
||||
#include "carddatabase.h"
|
||||
#include "dlg_startgame.h"
|
||||
|
||||
Game::Game(CardDatabase *_db, Client *_client, QGraphicsScene *_scene, QMenu *_actionsMenu, QMenu *_cardMenu, int playerId, const QString &playerName)
|
||||
: QObject(), actionsMenu(_actionsMenu), cardMenu(_cardMenu), db(_db), client(_client), scene(_scene), started(false)
|
||||
{
|
||||
QRectF sr = scene->sceneRect();
|
||||
localPlayer = addPlayer(playerId, playerName, QPointF(0, sr.y() + sr.height() / 2), true);
|
||||
|
||||
connect(client, SIGNAL(gameEvent(ServerEventData *)), this, SLOT(gameEvent(ServerEventData *)));
|
||||
connect(client, SIGNAL(playerListReceived(QList<ServerPlayer *>)), this, SLOT(playerListReceived(QList<ServerPlayer *>)));
|
||||
|
||||
aUntapAll = new QAction(tr("&Untap all permanents"), this);
|
||||
aUntapAll->setShortcut(tr("Ctrl+U"));
|
||||
connect(aUntapAll, SIGNAL(triggered()), this, SLOT(actUntapAll()));
|
||||
|
||||
aDecLife = new QAction(tr("&Decrement life"), this);
|
||||
aDecLife->setShortcut(tr("F11"));
|
||||
connect(aDecLife, SIGNAL(triggered()), this, SLOT(actDecLife()));
|
||||
aIncLife = new QAction(tr("&Increment life"), this);
|
||||
aIncLife->setShortcut(tr("F12"));
|
||||
connect(aIncLife, SIGNAL(triggered()), this, SLOT(actIncLife()));
|
||||
aSetLife = new QAction(tr("&Set life"), this);
|
||||
aSetLife->setShortcut(tr("Ctrl+L"));
|
||||
connect(aSetLife, SIGNAL(triggered()), this, SLOT(actSetLife()));
|
||||
|
||||
aShuffle = new QAction(tr("&Shuffle"), this);
|
||||
aShuffle->setShortcut(tr("Ctrl+S"));
|
||||
connect(aShuffle, SIGNAL(triggered()), this, SLOT(actShuffle()));
|
||||
aDraw = new QAction(tr("&Draw a card"), this);
|
||||
aDraw->setShortcut(tr("Ctrl+D"));
|
||||
connect(aDraw, SIGNAL(triggered()), this, SLOT(actDrawCard()));
|
||||
aDrawCards = new QAction(tr("D&raw cards..."), this);
|
||||
connect(aDrawCards, SIGNAL(triggered()), this, SLOT(actDrawCards()));
|
||||
aRollDice = new QAction(tr("R&oll dice..."), this);
|
||||
aRollDice->setShortcut(tr("Ctrl+I"));
|
||||
connect(aRollDice, SIGNAL(triggered()), this, SLOT(actRollDice()));
|
||||
|
||||
aCreateToken = new QAction(tr("&Create token..."), this);
|
||||
aCreateToken->setShortcut(tr("Ctrl+T"));
|
||||
connect(aCreateToken, SIGNAL(triggered()), this, SLOT(actCreateToken()));
|
||||
|
||||
actionsMenu->addAction(aUntapAll);
|
||||
actionsMenu->addSeparator();
|
||||
actionsMenu->addAction(aDecLife);
|
||||
actionsMenu->addAction(aIncLife);
|
||||
actionsMenu->addAction(aSetLife);
|
||||
actionsMenu->addSeparator();
|
||||
actionsMenu->addAction(aShuffle);
|
||||
actionsMenu->addAction(aDraw);
|
||||
actionsMenu->addAction(aDrawCards);
|
||||
actionsMenu->addAction(aRollDice);
|
||||
actionsMenu->addSeparator();
|
||||
actionsMenu->addAction(aCreateToken);
|
||||
|
||||
aTap = new QAction(tr("&Tap"), this);
|
||||
connect(aTap, SIGNAL(triggered()), this, SLOT(actTap()));
|
||||
aUntap = new QAction(tr("&Untap"), this);
|
||||
connect(aUntap, SIGNAL(triggered()), this, SLOT(actUntap()));
|
||||
aAddCounter = new QAction(tr("&Add counter"), this);
|
||||
connect(aAddCounter, SIGNAL(triggered()), this, SLOT(actAddCounter()));
|
||||
aRemoveCounter = new QAction(tr("&Remove counter"), this);
|
||||
connect(aRemoveCounter, SIGNAL(triggered()), this, SLOT(actRemoveCounter()));
|
||||
aSetCounters = new QAction(tr("&Set counters..."), this);
|
||||
connect(aSetCounters, SIGNAL(triggered()), this, SLOT(actSetCounters()));
|
||||
aRearrange = new QAction(tr("&Rearrange"), this);
|
||||
connect(aRearrange, SIGNAL(triggered()), this, SLOT(actRearrange()));
|
||||
|
||||
cardMenu->addAction(aTap);
|
||||
cardMenu->addAction(aUntap);
|
||||
cardMenu->addAction(aAddCounter);
|
||||
cardMenu->addAction(aRemoveCounter);
|
||||
cardMenu->addAction(aSetCounters);
|
||||
cardMenu->addSeparator();
|
||||
cardMenu->addAction(aRearrange);
|
||||
|
||||
dlgStartGame = new DlgStartGame(db);
|
||||
}
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
qDebug("Game destructor");
|
||||
for (int i = 0; i < players.size(); i++) {
|
||||
emit playerRemoved(players.at(i));
|
||||
delete players.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
Player *Game::addPlayer(int playerId, const QString &playerName, QPointF base, bool local)
|
||||
{
|
||||
Player *newPlayer = new Player(playerName, playerId, base, local, db, client);
|
||||
|
||||
const ZoneList *const z = newPlayer->getZones();
|
||||
for (int i = 0; i < z->size(); i++)
|
||||
scene->addItem(z->at(i));
|
||||
|
||||
const CounterList *const c = newPlayer->getCounters();
|
||||
for (int i = 0; i < c->size(); i++)
|
||||
scene->addItem(c->at(i));
|
||||
|
||||
connect(newPlayer, SIGNAL(hoverCard(QString)), this, SIGNAL(hoverCard(QString)));
|
||||
connect(newPlayer, SIGNAL(sigShowCardMenu(QPoint)), this, SLOT(showCardMenu(QPoint)));
|
||||
connect(newPlayer, SIGNAL(logMoveCard(QString, QString, QString, QString)), this, SIGNAL(logMoveCard(QString, QString, QString, QString)));
|
||||
connect(newPlayer, SIGNAL(logCreateToken(QString, QString)), this, SIGNAL(logCreateToken(QString, QString)));
|
||||
connect(newPlayer, SIGNAL(logSetCardCounters(QString, QString, int, int)), this, SIGNAL(logSetCardCounters(QString, QString, int, int)));
|
||||
connect(newPlayer, SIGNAL(logSetTapped(QString, QString, bool)), this, SIGNAL(logSetTapped(QString, QString, bool)));
|
||||
connect(newPlayer, SIGNAL(logSetCounter(QString, QString, int, int)), this, SIGNAL(logSetCounter(QString, QString, int, int)));
|
||||
|
||||
players << newPlayer;
|
||||
emit playerAdded(newPlayer);
|
||||
|
||||
return newPlayer;
|
||||
}
|
||||
|
||||
void Game::playerListReceived(QList<ServerPlayer *> playerList)
|
||||
{
|
||||
QListIterator<ServerPlayer *> i(playerList);
|
||||
QStringList nameList;
|
||||
while (i.hasNext()) {
|
||||
ServerPlayer *temp = i.next();
|
||||
nameList << temp->getName();
|
||||
int id = temp->getPlayerId();
|
||||
|
||||
if (id != localPlayer->getId())
|
||||
addPlayer(id, temp->getName(), QPointF(0, 0), false);
|
||||
|
||||
delete temp;
|
||||
}
|
||||
emit logPlayerListReceived(nameList);
|
||||
restartGameDialog();
|
||||
}
|
||||
|
||||
void Game::restartGameDialog()
|
||||
{
|
||||
dlgStartGame->exec();
|
||||
client->submitDeck(dlgStartGame->getDeckList());
|
||||
}
|
||||
|
||||
void Game::gameEvent(ServerEventData *msg)
|
||||
{
|
||||
if (!msg->getPublic())
|
||||
localPlayer->gameEvent(msg);
|
||||
else {
|
||||
Player *p = players.findPlayer(msg->getPlayerId());
|
||||
if (!p) {
|
||||
// XXX
|
||||
}
|
||||
|
||||
switch(msg->getEventType()) {
|
||||
case eventSay:
|
||||
emit logSay(p->getName(), msg->getEventData()[0]);
|
||||
break;
|
||||
case eventJoin: {
|
||||
emit logJoin(msg->getPlayerName());
|
||||
addPlayer(msg->getPlayerId(), msg->getPlayerName(), QPointF(0, 0), false);
|
||||
break;
|
||||
}
|
||||
case eventLeave:
|
||||
emit logLeave(msg->getPlayerName());
|
||||
// XXX Spieler natürlich noch rauswerfen
|
||||
break;
|
||||
case eventReadyStart:
|
||||
if (started) {
|
||||
started = false;
|
||||
emit logReadyStart(p->getName());
|
||||
if (!p->getLocal())
|
||||
restartGameDialog();
|
||||
}
|
||||
break;
|
||||
case eventGameStart:
|
||||
started = true;
|
||||
emit logGameStart();
|
||||
break;
|
||||
case eventShuffle:
|
||||
emit logShuffle(p->getName());
|
||||
break;
|
||||
case eventRollDice: {
|
||||
QStringList data = msg->getEventData();
|
||||
int sides = data[0].toInt();
|
||||
int roll = data[1].toInt();
|
||||
emit logRollDice(p->getName(), sides, roll);
|
||||
break;
|
||||
}
|
||||
case eventSetActivePlayer:
|
||||
break;
|
||||
case eventSetActivePhase:
|
||||
break;
|
||||
|
||||
case eventName:
|
||||
case eventCreateToken:
|
||||
case eventSetupZones:
|
||||
case eventSetCardAttr:
|
||||
case eventSetCounter:
|
||||
case eventDelCounter:
|
||||
case eventPlayerId: {
|
||||
p->gameEvent(msg);
|
||||
break;
|
||||
}
|
||||
case eventDumpZone: {
|
||||
QStringList data = msg->getEventData();
|
||||
emit logDumpZone(p->getName(), data[1], players.findPlayer(data[0].toInt())->getName(), data[2].toInt());
|
||||
break;
|
||||
}
|
||||
case eventMoveCard: {
|
||||
if (msg->getPlayerId() == localPlayer->getId())
|
||||
break;
|
||||
p->gameEvent(msg);
|
||||
break;
|
||||
}
|
||||
case eventDraw: {
|
||||
emit logDraw(p->getName(), msg->getEventData()[0].toInt());
|
||||
if (msg->getPlayerId() == localPlayer->getId())
|
||||
break;
|
||||
p->gameEvent(msg);
|
||||
break;
|
||||
}
|
||||
case eventInvalid:
|
||||
qDebug("Unhandled global event");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actUntapAll()
|
||||
{
|
||||
CardList *const cards = localPlayer->getZones()->findZone("table")->getCards();
|
||||
for (int i = 0; i < cards->size(); i++)
|
||||
client->setCardAttr("table", cards->at(i)->getId(), "tapped", "false");
|
||||
}
|
||||
|
||||
void Game::actIncLife()
|
||||
{
|
||||
client->incCounter("life", 1);
|
||||
}
|
||||
|
||||
void Game::actDecLife()
|
||||
{
|
||||
client->incCounter("life", -1);
|
||||
}
|
||||
|
||||
void Game::actSetLife()
|
||||
{
|
||||
bool ok;
|
||||
int life = QInputDialog::getInteger(0, tr("Set life"), tr("New life total:"), localPlayer->getCounters()->findCounter("life")->getValue(), 0, 2000000000, 1, &ok);
|
||||
client->setCounter("life", life);
|
||||
}
|
||||
|
||||
void Game::actShuffle()
|
||||
{
|
||||
client->shuffle();
|
||||
}
|
||||
|
||||
void Game::actRollDice()
|
||||
{
|
||||
bool ok;
|
||||
int sides = QInputDialog::getInteger(0, tr("Roll dice"), tr("Number of sides:"), 20, 2, 1000, 1, &ok);
|
||||
if (ok)
|
||||
client->rollDice(sides);
|
||||
}
|
||||
|
||||
void Game::actDrawCard()
|
||||
{
|
||||
client->drawCards(1);
|
||||
}
|
||||
|
||||
void Game::actDrawCards()
|
||||
{
|
||||
int number = QInputDialog::getInteger(0, tr("Draw cards"), tr("Number:"));
|
||||
if (number)
|
||||
client->drawCards(number);
|
||||
}
|
||||
|
||||
void Game::actCreateToken()
|
||||
{
|
||||
QString cardname = QInputDialog::getText(0, tr("Create token"), tr("Name:"));
|
||||
if (!db->getCard(cardname))
|
||||
QMessageBox::critical(0, "Error", "No such card");
|
||||
else
|
||||
client->createToken("table", cardname, QString(), 0, 0);
|
||||
}
|
||||
|
||||
void Game::showCardMenu(QPoint p)
|
||||
{
|
||||
cardMenu->exec(p);
|
||||
}
|
||||
|
||||
void Game::actTap()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "tapped", "1");
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actUntap()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "tapped", "0");
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actAddCounter()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
if (temp->getCounters() < MAX_COUNTERS_ON_CARD)
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(temp->getCounters() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actRemoveCounter()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
if (temp->getCounters())
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(temp->getCounters() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actSetCounters()
|
||||
{
|
||||
bool ok;
|
||||
int number = QInputDialog::getInteger(0, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(number));
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actRearrange()
|
||||
{
|
||||
// nur sinnvoll bei Karten auf dem Tisch -> Einschränkung einbauen
|
||||
int x, y, x_initial = 0, y_initial = 0;
|
||||
QList<QGraphicsItem *> list = scene->selectedItems();
|
||||
|
||||
// Find coordinates of leftmost card
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CardItem *temp = (CardItem *) list.at(i);
|
||||
if ((temp->pos().x() < x_initial) || (x_initial == 0)) {
|
||||
x_initial = (int) temp->pos().x();
|
||||
y_initial = (int) temp->pos().y();
|
||||
}
|
||||
}
|
||||
x = x_initial;
|
||||
y = y_initial;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CardItem *temp = (CardItem *) list.at(i);
|
||||
QString zoneName = qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName();
|
||||
x = x_initial + i * RASTER_WIDTH;
|
||||
y = y_initial + (i % 3) * RASTER_HEIGHT;
|
||||
client->moveCard(temp->getId(), zoneName, zoneName, x, y);
|
||||
}
|
||||
}
|
80
cockatrice/src/game.h
Normal file
80
cockatrice/src/game.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include "playerlist.h"
|
||||
|
||||
class ServerPlayer;
|
||||
class QGraphicsScene;
|
||||
class Player;
|
||||
class Client;
|
||||
class ServerEventData;
|
||||
class CardDatabase;
|
||||
class DlgStartGame;
|
||||
|
||||
class Game : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QMenu *actionsMenu, *cardMenu;
|
||||
QAction *aTap, *aUntap, *aAddCounter, *aRemoveCounter, *aSetCounters, *aRearrange,
|
||||
*aUntapAll, *aDecLife, *aIncLife, *aSetLife, *aShuffle, *aDraw, *aDrawCards, *aRollDice, *aCreateToken;
|
||||
DlgStartGame *dlgStartGame;
|
||||
|
||||
CardDatabase *db;
|
||||
Client *client;
|
||||
QGraphicsScene *scene;
|
||||
PlayerList players;
|
||||
Player *localPlayer;
|
||||
bool started;
|
||||
Player *addPlayer(int playerId, const QString &playerName, QPointF base, bool local);
|
||||
private slots:
|
||||
void actUntapAll();
|
||||
void actIncLife();
|
||||
void actDecLife();
|
||||
void actSetLife();
|
||||
void actShuffle();
|
||||
void actDrawCard();
|
||||
void actDrawCards();
|
||||
void actRollDice();
|
||||
void actCreateToken();
|
||||
|
||||
void showCardMenu(QPoint p);
|
||||
void actTap();
|
||||
void actUntap();
|
||||
void actAddCounter();
|
||||
void actRemoveCounter();
|
||||
void actSetCounters();
|
||||
void actRearrange();
|
||||
|
||||
void gameEvent(ServerEventData *msg);
|
||||
void playerListReceived(QList<ServerPlayer *> playerList);
|
||||
signals:
|
||||
void submitDecklist();
|
||||
void hoverCard(QString name);
|
||||
void playerAdded(Player *player);
|
||||
void playerRemoved(Player *player);
|
||||
|
||||
// Log events
|
||||
void logPlayerListReceived(QStringList players);
|
||||
void logJoin(QString playerName);
|
||||
void logLeave(QString playerName);
|
||||
void logReadyStart(QString playerName);
|
||||
void logGameStart();
|
||||
void logSay(QString playerName, QString text);
|
||||
void logShuffle(QString playerName);
|
||||
void logRollDice(QString playerName, int sides, int roll);
|
||||
void logDraw(QString playerName, int number);
|
||||
void logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone);
|
||||
void logCreateToken(QString playerName, QString cardName);
|
||||
void logSetCardCounters(QString playerName, QString cardName, int value, int oldValue);
|
||||
void logSetTapped(QString playerName, QString cardName, bool tapped);
|
||||
void logSetCounter(QString playerName, QString counterName, int value, int oldValue);
|
||||
void logDumpZone(QString playerName, QString zoneName, QString zoneOwner, int numberCards);
|
||||
public slots:
|
||||
void restartGameDialog();
|
||||
public:
|
||||
Game(CardDatabase *_db, Client *_client, QGraphicsScene *_scene, QMenu *_actionsMenu, QMenu *_cardMenu, int playerId, const QString &playerName);
|
||||
~Game();
|
||||
Player *getLocalPlayer() const { return localPlayer; }
|
||||
};
|
||||
|
||||
#endif
|
74
cockatrice/src/gamesmodel.cpp
Normal file
74
cockatrice/src/gamesmodel.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "gamesmodel.h"
|
||||
#include "servergame.h"
|
||||
|
||||
GamesModel::~GamesModel()
|
||||
{
|
||||
cleanList();
|
||||
}
|
||||
|
||||
int GamesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return gameList.size();
|
||||
}
|
||||
|
||||
int GamesModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
QVariant GamesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if ((index.row() >= gameList.size()) || (index.column() >= 4))
|
||||
return QVariant();
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
ServerGame *g = gameList.at(index.row());
|
||||
switch (index.column()) {
|
||||
case 0: return g->getName();
|
||||
case 1: return g->getDescription();
|
||||
case 2: return QString(g->getHasPassword() ? "yes" : "no");
|
||||
case 3: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers());
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
if (orientation != Qt::Horizontal)
|
||||
return QVariant();
|
||||
switch (section) {
|
||||
case 0: return QString("Name");
|
||||
case 1: return QString("Description");
|
||||
case 2: return QString("Password");
|
||||
case 3: return QString("Players");
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
ServerGame *GamesModel::getGame(int row)
|
||||
{
|
||||
if (row >= gameList.size())
|
||||
return 0;
|
||||
return gameList[row];
|
||||
}
|
||||
|
||||
void GamesModel::setGameList(const QList<ServerGame *> &_gameList)
|
||||
{
|
||||
cleanList();
|
||||
gameList = _gameList;
|
||||
reset();
|
||||
}
|
||||
|
||||
void GamesModel::cleanList()
|
||||
{
|
||||
QListIterator<ServerGame *> i(gameList);
|
||||
while (i.hasNext())
|
||||
delete i.next();
|
||||
gameList.clear();
|
||||
}
|
26
cockatrice/src/gamesmodel.h
Normal file
26
cockatrice/src/gamesmodel.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef GAMESMODEL_H
|
||||
#define GAMESMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include "servergame.h"
|
||||
|
||||
class GamesModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
GamesModel(QObject *parent = 0)
|
||||
: QAbstractListModel(parent) { }
|
||||
~GamesModel();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
void setGameList(const QList<ServerGame *> &_gameList);
|
||||
ServerGame *getGame(int row);
|
||||
private:
|
||||
QList<ServerGame *> gameList;
|
||||
void cleanList();
|
||||
};
|
||||
|
||||
#endif
|
33
cockatrice/src/gameview.cpp
Normal file
33
cockatrice/src/gameview.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "gameview.h"
|
||||
|
||||
GameView::GameView(QGraphicsScene *scene, QWidget *parent)
|
||||
: QGraphicsView(scene, parent)
|
||||
{
|
||||
setBackgroundBrush(QBrush(QColor(0, 0, 0)));
|
||||
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
setOptimizationFlags(/*DontClipPainter | */DontSavePainterState);
|
||||
setDragMode(RubberBandDrag);
|
||||
}
|
||||
|
||||
void GameView::scaleToScene()
|
||||
{
|
||||
// This function ensures that the bounding rectangles of card pictures
|
||||
// have integer sizes. This is achieved by using a scale factor of n / 6.
|
||||
QRectF sr = scene()->sceneRect();
|
||||
QRectF vr = QRectF(viewport()->rect().adjusted(2, 2, -2, -2));
|
||||
qreal scale_h = vr.width() / sr.width();
|
||||
qreal scale_v = vr.height() / sr.height();
|
||||
qreal scale_total = qMin(scale_h, scale_v);
|
||||
|
||||
qreal scale_corr = (qreal) ((int) (scale_total * 6)) / 6;
|
||||
|
||||
qDebug(QString("scale_corr = %1 / 6").arg(scale_corr * 6).toLatin1());
|
||||
setTransform(QTransform().scale(scale_corr, scale_corr));
|
||||
}
|
||||
|
||||
void GameView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
qDebug("GameView: resizeEvent");
|
||||
QGraphicsView::resizeEvent(event);
|
||||
scaleToScene();
|
||||
}
|
14
cockatrice/src/gameview.h
Normal file
14
cockatrice/src/gameview.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef GAMEVIEW_H
|
||||
#define GAMEVIEW_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
|
||||
class GameView : public QGraphicsView {
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
public:
|
||||
void scaleToScene();
|
||||
GameView(QGraphicsScene *scene, QWidget *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
53
cockatrice/src/gravezone.cpp
Normal file
53
cockatrice/src/gravezone.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <QtGui>
|
||||
#include "gravezone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
GraveZone::GraveZone(Player *_p)
|
||||
: PlayerZone(_p, "grave")
|
||||
{
|
||||
cards = new CardList(true);
|
||||
}
|
||||
|
||||
QRectF GraveZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void GraveZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("yellow"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GraveZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void GraveZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void GraveZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
17
cockatrice/src/gravezone.h
Normal file
17
cockatrice/src/gravezone.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef GRAVEZONE_H
|
||||
#define GRAVEZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class GraveZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
GraveZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
73
cockatrice/src/handzone.cpp
Normal file
73
cockatrice/src/handzone.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
#include <QtGui>
|
||||
#include "handzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
|
||||
HandZone::HandZone(Player *_p)
|
||||
: PlayerZone(_p, "hand")
|
||||
{
|
||||
cards = new CardList(player->getLocal());
|
||||
}
|
||||
|
||||
QRectF HandZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 100, 500);
|
||||
}
|
||||
|
||||
void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->fillRect(boundingRect(), QColor("green"));
|
||||
}
|
||||
|
||||
void HandZone::reorganizeCards()
|
||||
{
|
||||
if (cards->isEmpty())
|
||||
return;
|
||||
|
||||
int cardCount = cards->size();
|
||||
qreal totalWidth = boundingRect().width();
|
||||
qreal totalHeight = boundingRect().height();
|
||||
qreal cardWidth = cards->at(0)->boundingRect().width();
|
||||
qreal cardHeight = cards->at(0)->boundingRect().height();
|
||||
qreal x = (totalWidth - cardWidth) / 2;
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
CardItem *c = cards->at(i);
|
||||
// If the total height of the cards is smaller than the available height,
|
||||
// the cards do not need to overlap and are displayed in the center of the area.
|
||||
if (cardHeight * cardCount > totalHeight)
|
||||
c->setPos(x, ((qreal) i) * (totalHeight - cardHeight) / (cardCount - 1));
|
||||
else
|
||||
c->setPos(x, ((qreal) i) * cardHeight + (totalHeight - cardCount * cardHeight) / 2);
|
||||
c->setZValue(i);
|
||||
}
|
||||
}
|
||||
|
||||
void HandZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
Q_UNUSED(y);
|
||||
|
||||
if (x == -1)
|
||||
x = cards->size();
|
||||
cards->insert(x, card);
|
||||
|
||||
if (!cards->getContentsKnown()) {
|
||||
card->setId(-1);
|
||||
card->setName();
|
||||
}
|
||||
card->setParentItem(this);
|
||||
card->resetState();
|
||||
card->setVisible(true);
|
||||
card->update(card->boundingRect());
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void HandZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
Q_UNUSED(dropPoint);
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), cards->size(), 0);
|
||||
}
|
17
cockatrice/src/handzone.h
Normal file
17
cockatrice/src/handzone.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef HANDZONE_H
|
||||
#define HANDZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class HandZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
HandZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = -1, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
88
cockatrice/src/libraryzone.cpp
Normal file
88
cockatrice/src/libraryzone.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include <QtGui>
|
||||
#include "libraryzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "carddatabase.h"
|
||||
#include "carddragitem.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
LibraryZone::LibraryZone(Player *_p)
|
||||
: PlayerZone(_p, "deck")
|
||||
{
|
||||
cards = new CardList(false);
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
QRectF LibraryZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void LibraryZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("red"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void LibraryZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setId(-1);
|
||||
card->setName(QString());
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void LibraryZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void LibraryZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void LibraryZone::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
PlayerZone::mousePressEvent(event);
|
||||
if (event->isAccepted())
|
||||
return;
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
event->accept();
|
||||
} else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void LibraryZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
CardItem *card = cards->at(0);
|
||||
CardDragItem *drag = card->createDragItem(this, 0, event->pos(), event->scenePos());
|
||||
drag->grabMouse();
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void LibraryZone::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
21
cockatrice/src/libraryzone.h
Normal file
21
cockatrice/src/libraryzone.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef LIBRARYZONE_H
|
||||
#define LIBRARYZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class LibraryZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
LibraryZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
};
|
||||
|
||||
#endif
|
51
cockatrice/src/main.cpp
Normal file
51
cockatrice/src/main.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@gmx.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
#include <QtPlugin>
|
||||
#include "window.h"
|
||||
#include <stdio.h>
|
||||
|
||||
//Q_IMPORT_PLUGIN(qjpeg)
|
||||
|
||||
void myMessageOutput(QtMsgType type, const char *msg)
|
||||
{
|
||||
static FILE *f = NULL;
|
||||
if (!f)
|
||||
f = fopen("qdebug.txt", "w");
|
||||
fprintf(f, "%s\n", msg);
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
qInstallMsgHandler(myMessageOutput);
|
||||
QApplication app(argc, argv);
|
||||
app.addLibraryPath("plugins");
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
MainWindow *ui = new MainWindow;
|
||||
ui->show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
147
cockatrice/src/messagelogwidget.cpp
Normal file
147
cockatrice/src/messagelogwidget.cpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
#include "messagelogwidget.h"
|
||||
#include "game.h"
|
||||
#include <QScrollBar>
|
||||
|
||||
void MessageLogWidget::appendAndScroll(const QString &s)
|
||||
{
|
||||
append(s);
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
|
||||
}
|
||||
|
||||
void MessageLogWidget::logConnecting(QString hostname)
|
||||
{
|
||||
appendAndScroll(tr("Connecting to %1...").arg(hostname));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logConnected(const QStringList WelcomeMsg)
|
||||
{
|
||||
appendAndScroll(tr("Connected."));
|
||||
|
||||
QStringListIterator i(WelcomeMsg);
|
||||
while (i.hasNext())
|
||||
appendAndScroll(i.next());
|
||||
}
|
||||
|
||||
void MessageLogWidget::logDisconnected()
|
||||
{
|
||||
appendAndScroll(tr("Disconnected from server."));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSocketError(const QString &errorString)
|
||||
{
|
||||
appendAndScroll(errorString);
|
||||
}
|
||||
|
||||
void MessageLogWidget::logPlayerListReceived(QStringList players)
|
||||
{
|
||||
append("---");
|
||||
append(tr("You have joined the game. Player list:"));
|
||||
for (int i = 0; i < players.size(); i++)
|
||||
append(players.at(i));
|
||||
appendAndScroll("---");
|
||||
}
|
||||
|
||||
void MessageLogWidget::logJoin(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 has joined the game").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logLeave(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 has left the game").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logReadyStart(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 is ready to start a new game.").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logGameStart()
|
||||
{
|
||||
appendAndScroll(tr("Game has started."));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSay(QString playerName, QString message)
|
||||
{
|
||||
appendAndScroll(QString("<font color=\"red\">%1:</font> %2").arg(playerName).arg(message));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logShuffle(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 shuffles his/her library").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logRollDice(QString playerName, int sides, int roll)
|
||||
{
|
||||
appendAndScroll(tr("%1 rolled a %2 with a %3-sided dice").arg(playerName).arg(roll).arg(sides));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logDraw(QString playerName, int number)
|
||||
{
|
||||
if (number == 1)
|
||||
appendAndScroll(tr("%1 draws a card").arg(playerName));
|
||||
else
|
||||
appendAndScroll(tr("%1 draws %2 cards").arg(playerName).arg(number));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone)
|
||||
{
|
||||
appendAndScroll(tr("%1 moves %2 from %3 to %4").arg(playerName).arg(cardName).arg(startZone).arg(targetZone));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logCreateToken(QString playerName, QString cardName)
|
||||
{
|
||||
appendAndScroll(tr("%1 creates token: %2").arg(playerName).arg(cardName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSetCardCounters(QString playerName, QString cardName, int value, int oldValue)
|
||||
{
|
||||
if (value > oldValue)
|
||||
appendAndScroll(tr("%1 places %2 counters on %3 (now %4)").arg(playerName).arg(value - oldValue).arg(cardName).arg(value));
|
||||
else
|
||||
appendAndScroll(tr("%1 removes %2 counters from %3 (now %4)").arg(playerName).arg(oldValue - value).arg(cardName).arg(value));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSetTapped(QString playerName, QString cardName, bool tapped)
|
||||
{
|
||||
appendAndScroll(tr("%1 %2 %3").arg(playerName).arg(tapped ? "taps" : "untaps").arg(cardName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSetCounter(QString playerName, QString counterName, int value, int oldValue)
|
||||
{
|
||||
appendAndScroll(tr("%1 sets counter \"%2\" to %3 (%4%5)").arg(playerName).arg(counterName).arg(value).arg(value > oldValue ? "+" : "").arg(value - oldValue));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logDumpZone(QString playerName, QString zoneName, QString zoneOwner, int numberCards)
|
||||
{
|
||||
if (numberCards)
|
||||
appendAndScroll(tr("%1 is looking at the top %2 cards of %3's %4").arg(playerName).arg(numberCards).arg(zoneOwner).arg(zoneName));
|
||||
else
|
||||
appendAndScroll(tr("%1 is looking at %2's %3").arg(playerName).arg(zoneOwner).arg(zoneName));
|
||||
}
|
||||
|
||||
|
||||
void MessageLogWidget::connectToGame(Game *game)
|
||||
{
|
||||
connect(game, SIGNAL(logPlayerListReceived(QStringList)), this, SLOT(logPlayerListReceived(QStringList)));
|
||||
connect(game, SIGNAL(logJoin(QString)), this, SLOT(logJoin(QString)));
|
||||
connect(game, SIGNAL(logLeave(QString)), this, SLOT(logLeave(QString)));
|
||||
connect(game, SIGNAL(logReadyStart(QString)), this, SLOT(logReadyStart(QString)));
|
||||
connect(game, SIGNAL(logGameStart()), this, SLOT(logGameStart()));
|
||||
connect(game, SIGNAL(logSay(QString, QString)), this, SLOT(logSay(QString, QString)));
|
||||
connect(game, SIGNAL(logShuffle(QString)), this, SLOT(logShuffle(QString)));
|
||||
connect(game, SIGNAL(logRollDice(QString, int, int)), this, SLOT(logRollDice(QString, int, int)));
|
||||
connect(game, SIGNAL(logDraw(QString, int)), this, SLOT(logDraw(QString, int)));
|
||||
connect(game, SIGNAL(logMoveCard(QString, QString, QString, QString)), this, SLOT(logMoveCard(QString, QString, QString, QString)));
|
||||
connect(game, SIGNAL(logCreateToken(QString, QString)), this, SLOT(logCreateToken(QString, QString)));
|
||||
connect(game, SIGNAL(logSetCardCounters(QString, QString, int, int)), this, SLOT(logSetCardCounters(QString, QString, int, int)));
|
||||
connect(game, SIGNAL(logSetTapped(QString, QString, bool)), this, SLOT(logSetTapped(QString, QString, bool)));
|
||||
connect(game, SIGNAL(logSetCounter(QString, QString, int, int)), this, SLOT(logSetCounter(QString, QString, int, int)));
|
||||
connect(game, SIGNAL(logDumpZone(QString, QString, QString, int)), this, SLOT(logDumpZone(QString, QString, QString, int)));
|
||||
}
|
||||
|
||||
MessageLogWidget::MessageLogWidget(QWidget *parent)
|
||||
: QTextEdit(parent)
|
||||
{
|
||||
setReadOnly(true);
|
||||
}
|
39
cockatrice/src/messagelogwidget.h
Normal file
39
cockatrice/src/messagelogwidget.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef MESSAGELOGWIDGET_H
|
||||
#define MESSAGELOGWIDGET_H
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QAbstractSocket>
|
||||
|
||||
class Game;
|
||||
|
||||
class MessageLogWidget : public QTextEdit {
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void logConnecting(QString hostname);
|
||||
void logConnected(const QStringList WelcomeMsg);
|
||||
void logDisconnected();
|
||||
void logSocketError(const QString &errorString);
|
||||
private slots:
|
||||
void logPlayerListReceived(QStringList players);
|
||||
void logJoin(QString playerName);
|
||||
void logLeave(QString playerName);
|
||||
void logReadyStart(QString playerName);
|
||||
void logGameStart();
|
||||
void logSay(QString playerName, QString message);
|
||||
void logShuffle(QString playerName);
|
||||
void logRollDice(QString playerName, int sides, int roll);
|
||||
void logDraw(QString playerName, int number);
|
||||
void logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone);
|
||||
void logCreateToken(QString playerName, QString cardName);
|
||||
void logSetCardCounters(QString playerName, QString cardName, int value, int oldValue);
|
||||
void logSetTapped(QString playerName, QString cardName, bool tapped);
|
||||
void logSetCounter(QString playerName, QString counterName, int value, int oldValue);
|
||||
void logDumpZone(QString playerName, QString zoneName, QString zoneOwner, int numberCards);
|
||||
private:
|
||||
void appendAndScroll(const QString &s);
|
||||
public:
|
||||
void connectToGame(Game *game);
|
||||
MessageLogWidget(QWidget *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
19
cockatrice/src/pendingcommand.h
Normal file
19
cockatrice/src/pendingcommand.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef PENDINGCOMMAND_H
|
||||
#define PENDINGCOMMAND_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class PendingCommand {
|
||||
private:
|
||||
QString cmd;
|
||||
int msgid;
|
||||
int time;
|
||||
public:
|
||||
int getMsgId() const { return msgid; }
|
||||
QString getCmd() const { return cmd; }
|
||||
bool timeout() const { return time > 5; }
|
||||
void incTime() { ++time; }
|
||||
PendingCommand(const QString &_cmd, int _msgid) : cmd(_cmd), msgid(_msgid), time(0) { }
|
||||
};
|
||||
|
||||
#endif
|
296
cockatrice/src/player.cpp
Normal file
296
cockatrice/src/player.cpp
Normal file
|
@ -0,0 +1,296 @@
|
|||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "handzone.h"
|
||||
#include "tablezone.h"
|
||||
#include "libraryzone.h"
|
||||
#include "gravezone.h"
|
||||
#include "rfgzone.h"
|
||||
#include "sideboardzone.h"
|
||||
#include <QMenu>
|
||||
|
||||
Player::Player(const QString &_name, int _id, QPointF _base, bool _local, CardDatabase *_db, Client *_client)
|
||||
: QObject(), defaultNumberTopCards(3), name(_name), id(_id), base(_base), local(_local), db(_db), client(_client)
|
||||
{
|
||||
LibraryZone *deck = new LibraryZone(this);
|
||||
deck->setPos(_base);
|
||||
|
||||
// XXX
|
||||
qreal foo = deck->boundingRect().height();
|
||||
|
||||
GraveZone *grave = new GraveZone(this);
|
||||
grave->setPos(_base + QPointF(0, foo));
|
||||
|
||||
RfgZone *rfg = new RfgZone(this);
|
||||
rfg->setPos(_base + QPointF(0, 2 * foo));
|
||||
|
||||
SideboardZone *sb = new SideboardZone(this);
|
||||
sb->setPos(_base + QPointF(0, 3 * foo));
|
||||
|
||||
Counter *life = new Counter(this, "life");
|
||||
life->setPos(_base + QPointF(-50, 5 * foo));
|
||||
|
||||
_base += QPointF(deck->boundingRect().width(), 0);
|
||||
|
||||
PlayerZone *hand = new HandZone(this);
|
||||
hand->setPos(_base);
|
||||
_base += QPointF(hand->boundingRect().width(), 0);
|
||||
|
||||
PlayerZone *table = new TableZone(this);
|
||||
table->setPos(_base);
|
||||
|
||||
aMoveHandToTopLibrary = new QAction(tr("Move to &top of library"), this);
|
||||
connect(aMoveHandToTopLibrary, SIGNAL(triggered()), this, SLOT(actMoveHandToTopLibrary()));
|
||||
aMoveHandToBottomLibrary = new QAction(tr("Move to &bottom of library"), this);
|
||||
connect(aMoveHandToBottomLibrary, SIGNAL(triggered()), this, SLOT(actMoveHandToBottomLibrary()));
|
||||
|
||||
aViewLibrary = new QAction(tr("&View library"), this);
|
||||
if (local)
|
||||
aViewLibrary->setShortcut(tr("F5"));
|
||||
connect(aViewLibrary, SIGNAL(triggered()), this, SLOT(actViewLibrary()));
|
||||
aViewTopCards = new QAction(tr("View &top cards of library..."), this);
|
||||
connect(aViewTopCards, SIGNAL(triggered()), this, SLOT(actViewTopCards()));
|
||||
|
||||
aViewGraveyard = new QAction(tr("&View graveyard"), this);
|
||||
if (local)
|
||||
aViewGraveyard->setShortcut(tr("F6"));
|
||||
connect(aViewGraveyard, SIGNAL(triggered()), this, SLOT(actViewGraveyard()));
|
||||
|
||||
aViewRfg = new QAction(tr("&View removed cards"), this);
|
||||
connect(aViewRfg, SIGNAL(triggered()), this, SLOT(actViewRfg()));
|
||||
|
||||
aViewSideboard = new QAction(tr("&View sideboard"), this);
|
||||
connect(aViewSideboard, SIGNAL(triggered()), this, SLOT(actViewSideboard()));
|
||||
|
||||
playerMenu = new QMenu(tr("Player \"%1\"").arg(name));
|
||||
|
||||
QMenu *handMenu = playerMenu->addMenu(tr("&Hand"));
|
||||
handMenu->addAction(aMoveHandToTopLibrary);
|
||||
handMenu->addAction(aMoveHandToBottomLibrary);
|
||||
hand->setMenu(handMenu);
|
||||
|
||||
QMenu *libraryMenu = playerMenu->addMenu(tr("&Library"));
|
||||
libraryMenu->addAction(aViewLibrary);
|
||||
libraryMenu->addAction(aViewTopCards);
|
||||
deck->setMenu(libraryMenu);
|
||||
|
||||
QMenu *graveMenu = playerMenu->addMenu(tr("&Graveyard"));
|
||||
graveMenu->addAction(aViewGraveyard);
|
||||
grave->setMenu(graveMenu);
|
||||
|
||||
QMenu *rfgMenu = playerMenu->addMenu(tr("&Removed cards"));
|
||||
rfgMenu->addAction(aViewRfg);
|
||||
rfg->setMenu(rfgMenu);
|
||||
|
||||
QMenu *sbMenu = playerMenu->addMenu(tr("&Sideboard"));
|
||||
sbMenu->addAction(aViewSideboard);
|
||||
sb->setMenu(sbMenu);
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
{
|
||||
qDebug("Player destructor");
|
||||
|
||||
for (int i = 0; i < zones.size(); i++)
|
||||
delete zones.at(i);
|
||||
|
||||
for (int i = 0; i < counters.size(); i++)
|
||||
delete counters.at(i);
|
||||
}
|
||||
|
||||
void Player::actMoveHandToTopLibrary()
|
||||
{
|
||||
PlayerZone *library = zones.findZone("deck");
|
||||
zones.findZone("hand")->moveAllToZone(library->getName(), 0);
|
||||
}
|
||||
|
||||
void Player::actMoveHandToBottomLibrary()
|
||||
{
|
||||
PlayerZone *library = zones.findZone("deck");
|
||||
zones.findZone("hand")->moveAllToZone(library->getName(), library->getCards()->size());
|
||||
}
|
||||
|
||||
void Player::actViewLibrary()
|
||||
{
|
||||
emit addZoneView(this, "deck", 0);
|
||||
}
|
||||
|
||||
void Player::actViewTopCards()
|
||||
{
|
||||
bool ok;
|
||||
int number = QInputDialog::getInteger(0, tr("View top cards of library"), tr("Number of cards:"), defaultNumberTopCards, 1, 2000000000, 1, &ok);
|
||||
if (ok) {
|
||||
defaultNumberTopCards = number;
|
||||
emit addZoneView(this, "deck", number);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::actViewGraveyard()
|
||||
{
|
||||
emit addZoneView(this, "grave", 0);
|
||||
}
|
||||
|
||||
void Player::actViewRfg()
|
||||
{
|
||||
emit addZoneView(this, "rfg", 0);
|
||||
}
|
||||
|
||||
void Player::actViewSideboard()
|
||||
{
|
||||
emit addZoneView(this, "sb", 0);
|
||||
}
|
||||
|
||||
void Player::addZone(PlayerZone *z)
|
||||
{
|
||||
zones << z;
|
||||
}
|
||||
|
||||
void Player::addCounter(Counter *c)
|
||||
{
|
||||
counters << c;
|
||||
}
|
||||
|
||||
void Player::gameEvent(ServerEventData *event)
|
||||
{
|
||||
QStringList data = event->getEventData();
|
||||
switch (event->getEventType()) {
|
||||
case eventSetupZones: {
|
||||
// XXX Life counter
|
||||
int life = data[0].toInt();
|
||||
int deck_cards = data[1].toInt();
|
||||
int sb_cards = data[2].toInt();
|
||||
// XXX Fehlerbehandlung
|
||||
|
||||
// Clean up existing zones first
|
||||
for (int i = 0; i < zones.size(); i++)
|
||||
zones.at(i)->clearContents();
|
||||
|
||||
Counter *lifeCounter = counters.findCounter("life");
|
||||
lifeCounter->setValue(life);
|
||||
|
||||
PlayerZone *deck = zones.findZone("deck");
|
||||
for (; deck_cards; deck_cards--)
|
||||
deck->addCard(new CardItem(db, QString(), -1));
|
||||
deck->reorganizeCards();
|
||||
|
||||
PlayerZone *sb = zones.findZone("sb");
|
||||
for (; sb_cards; sb_cards--)
|
||||
sb->addCard(new CardItem(db, QString(), -1));
|
||||
sb->reorganizeCards();
|
||||
|
||||
break;
|
||||
}
|
||||
case eventDraw: {
|
||||
PlayerZone *deck = zones.findZone("deck");
|
||||
PlayerZone *hand = zones.findZone("hand");
|
||||
if (!event->getPublic()) {
|
||||
hand->addCard(deck->takeCard(0, data[0].toInt(), data[1]));
|
||||
} else {
|
||||
int number = data[0].toInt();
|
||||
for (; number; number--)
|
||||
hand->addCard(deck->takeCard(0, -1, QString()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eventMoveCard: {
|
||||
if (data.size() != 7) {
|
||||
qDebug("error");
|
||||
// XXX
|
||||
}
|
||||
int cardId = data[0].toInt();
|
||||
QString cardName = data[1];
|
||||
PlayerZone *startZone = zones.findZone(data[2]);
|
||||
if (!startZone)
|
||||
qDebug(QString("start zone invalid: %1").arg(data[2]).toLatin1());
|
||||
int position = data[3].toInt();
|
||||
PlayerZone *targetZone = zones.findZone(data[4]);
|
||||
if (!targetZone)
|
||||
qDebug(QString("target zone invalid: %1").arg(data[4]).toLatin1());
|
||||
int x = data[5].toInt();
|
||||
int y = data[6].toInt();
|
||||
// XXX Mehr Fehlerbehandlung
|
||||
|
||||
CardItem *card = startZone->takeCard(position, cardId, cardName);
|
||||
if (!card) // XXX
|
||||
qDebug("null");
|
||||
|
||||
card->deleteDragItem();
|
||||
|
||||
// The log event has to be sent before the card is added to the target zone
|
||||
// because the addCard function can modify the card object.
|
||||
emit logMoveCard(name, card->getName(), startZone->getName(), targetZone->getName());
|
||||
|
||||
targetZone->addCard(card, true, x, y);
|
||||
|
||||
break;
|
||||
}
|
||||
case eventCreateToken: {
|
||||
// zone, cardid, cardname, powtough, x, y
|
||||
if (data.size() != 6) {
|
||||
qDebug("error");
|
||||
}
|
||||
PlayerZone *zone = zones.findZone(data[0]);
|
||||
int cardid = data[1].toInt();
|
||||
QString cardname = data[2];
|
||||
QString powtough = data[3];
|
||||
int x = data[4].toInt();
|
||||
int y = data[5].toInt();
|
||||
|
||||
CardItem *card = new CardItem(db, cardname, cardid);
|
||||
|
||||
emit logCreateToken(name, card->getName());
|
||||
zone->addCard(card, true, x, y);
|
||||
|
||||
break;
|
||||
}
|
||||
case eventSetCardAttr: {
|
||||
if (data.size() != 4) {
|
||||
// XXX
|
||||
}
|
||||
PlayerZone *zone = zones.findZone(data[0]);
|
||||
int cardId = data[1].toInt();
|
||||
CardItem *card = zone->getCard(cardId, "");
|
||||
QString aname = data[2];
|
||||
QString avalue = data[3];
|
||||
// XXX Fehlerbehandlung
|
||||
|
||||
if (aname == "tapped") {
|
||||
bool tapped = avalue == "1";
|
||||
emit logSetTapped(name, card->getName(), tapped);
|
||||
card->setTapped(tapped);
|
||||
} else if (aname == "attacking")
|
||||
card->setAttacking(avalue == "1");
|
||||
else if (aname == "facedown")
|
||||
card->setFacedown(avalue == "1");
|
||||
else if (aname == "counters") {
|
||||
int value = avalue.toInt();
|
||||
emit logSetCardCounters(name, card->getName(), value, card->getCounters());
|
||||
card->setCounters(value);
|
||||
} else if (aname == "annotation")
|
||||
card->setAnnotation(avalue);
|
||||
break;
|
||||
}
|
||||
case eventSetCounter: {
|
||||
if (data.size() != 2) {
|
||||
// XXX
|
||||
}
|
||||
int value = data[1].toInt();
|
||||
Counter *c = counters.findCounter(data[0]);
|
||||
int oldValue = c->getValue();
|
||||
c->setValue(value);
|
||||
emit logSetCounter(name, c->getName(), value, oldValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qDebug("unhandled player event");
|
||||
}
|
||||
}
|
||||
|
||||
void Player::hoverCardEvent(CardItem *card)
|
||||
{
|
||||
emit hoverCard(card->getName());
|
||||
}
|
||||
|
||||
void Player::showCardMenu(const QPoint &p)
|
||||
{
|
||||
emit sigShowCardMenu(p);
|
||||
}
|
71
cockatrice/src/player.h
Normal file
71
cockatrice/src/player.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QPoint>
|
||||
#include "zonelist.h"
|
||||
#include "counterlist.h"
|
||||
#include "servereventdata.h"
|
||||
|
||||
class Client;
|
||||
class CardDatabase;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
|
||||
class Player : public QObject {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void moveCard(int cardId, QString startZone, QString targetZone, int x, int y);
|
||||
void hoverCard(QString name);
|
||||
void addZoneView(Player *player, QString zoneName, int number);
|
||||
void sigShowCardMenu(QPoint p);
|
||||
// Log events
|
||||
void logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone);
|
||||
void logCreateToken(QString playerName, QString cardName);
|
||||
void logSetCardCounters(QString playerName, QString cardName, int value, int oldValue);
|
||||
void logSetTapped(QString playerName, QString cardName, bool tapped);
|
||||
void logSetCounter(QString playerName, QString counterName, int value, int oldValue);
|
||||
private slots:
|
||||
void actMoveHandToTopLibrary();
|
||||
void actMoveHandToBottomLibrary();
|
||||
|
||||
void actViewLibrary();
|
||||
void actViewTopCards();
|
||||
|
||||
void actViewGraveyard();
|
||||
|
||||
void actViewRfg();
|
||||
|
||||
void actViewSideboard();
|
||||
private:
|
||||
QMenu *playerMenu;
|
||||
QAction *aMoveHandToTopLibrary, *aMoveHandToBottomLibrary,
|
||||
*aViewLibrary, *aViewTopCards, *aViewGraveyard, *aViewRfg, *aViewSideboard;
|
||||
|
||||
int defaultNumberTopCards;
|
||||
QString name;
|
||||
int id;
|
||||
QPointF base;
|
||||
bool local;
|
||||
ZoneList zones;
|
||||
CounterList counters;
|
||||
CardDatabase *db;
|
||||
public:
|
||||
Client *client;
|
||||
void addZone(PlayerZone *z);
|
||||
void addCounter(Counter *c);
|
||||
Player(const QString &_name, int _id, QPointF _base, bool _local, CardDatabase *_db, Client *_client);
|
||||
~Player();
|
||||
QMenu *getPlayerMenu() const { return playerMenu; }
|
||||
int getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
bool getLocal() const { return local; }
|
||||
const ZoneList *const getZones() const { return &zones; }
|
||||
const CounterList *const getCounters() const { return &counters; }
|
||||
void gameEvent(ServerEventData *event);
|
||||
void hoverCardEvent(CardItem *card);
|
||||
CardDatabase *getDb() const { return db; }
|
||||
void showCardMenu(const QPoint &p);
|
||||
};
|
||||
|
||||
#endif
|
11
cockatrice/src/playerlist.cpp
Normal file
11
cockatrice/src/playerlist.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "playerlist.h"
|
||||
|
||||
Player *PlayerList::findPlayer(int id) const
|
||||
{
|
||||
for (int i = 0; i < size(); i++) {
|
||||
Player *temp = at(i);
|
||||
if (temp->getId() == id)
|
||||
return temp;
|
||||
}
|
||||
return 0;
|
||||
}
|
12
cockatrice/src/playerlist.h
Normal file
12
cockatrice/src/playerlist.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef PLAYERLIST_H
|
||||
#define PLAYERLIST_H
|
||||
|
||||
#include "player.h"
|
||||
#include <QList>
|
||||
|
||||
class PlayerList : public QList<Player *> {
|
||||
public:
|
||||
Player *findPlayer(int id) const;
|
||||
};
|
||||
|
||||
#endif
|
98
cockatrice/src/playerzone.cpp
Normal file
98
cockatrice/src/playerzone.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include <QtGui>
|
||||
#include "playerzone.h"
|
||||
#include "carditem.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
PlayerZone::PlayerZone(Player *_p, const QString &_name, QGraphicsItem *parent, bool isView)
|
||||
: QGraphicsItem(parent), player(_p), name(_name), cards(NULL), menu(NULL), hasCardAttr(false)
|
||||
{
|
||||
if (!isView)
|
||||
player->addZone(this);
|
||||
}
|
||||
|
||||
PlayerZone::~PlayerZone()
|
||||
{
|
||||
qDebug(QString("PlayerZone destructor: %1").arg(name).toLatin1());
|
||||
while (!views.empty())
|
||||
delete views.at(0);
|
||||
|
||||
clearContents();
|
||||
delete cards;
|
||||
}
|
||||
|
||||
void PlayerZone::clearContents()
|
||||
{
|
||||
for (int i = 0; i < cards->size(); i++)
|
||||
delete cards->at(i);
|
||||
cards->clear();
|
||||
}
|
||||
|
||||
void PlayerZone::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
if (menu) {
|
||||
menu->exec(event->screenPos());
|
||||
event->accept();
|
||||
} else
|
||||
event->ignore();
|
||||
} else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
CardItem *PlayerZone::getCard(int cardId, const QString &cardName)
|
||||
{
|
||||
CardItem *c = cards->findCard(cardId, false);
|
||||
// If the card's id is -1, this zone is invisible,
|
||||
// so we need to give the card an id and a name as it comes out.
|
||||
// It can be assumed that in an invisible zone, all cards are equal.
|
||||
if ((c->getId() == -1) || (c->getName().isEmpty())) {
|
||||
c->setId(cardId);
|
||||
c->setName(cardName);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
CardItem *PlayerZone::takeCard(int position, int cardId, const QString &cardName)
|
||||
{
|
||||
CardItem *c = cards->takeAt(position);
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->removeCard(position);
|
||||
|
||||
if (c->getId() == -1) {
|
||||
c->setId(cardId);
|
||||
c->setName(cardName);
|
||||
}
|
||||
reorganizeCards();
|
||||
return c;
|
||||
}
|
||||
|
||||
void PlayerZone::setCardAttr(int cardId, const QString &aname, const QString &avalue)
|
||||
{
|
||||
if (hasCardAttr)
|
||||
player->client->setCardAttr(name, cardId, aname, avalue);
|
||||
}
|
||||
|
||||
void PlayerZone::hoverCardEvent(CardItem *card)
|
||||
{
|
||||
player->hoverCardEvent(card);
|
||||
}
|
||||
|
||||
void PlayerZone::addView(ZoneViewZone *view)
|
||||
{
|
||||
views.append(view);
|
||||
}
|
||||
|
||||
void PlayerZone::removeView(ZoneViewZone *view)
|
||||
{
|
||||
views.removeAt(views.indexOf(view));
|
||||
}
|
||||
|
||||
void PlayerZone::moveAllToZone(const QString &targetZone, int targetX)
|
||||
{
|
||||
// Cards need to be moved in reverse order so that the other
|
||||
// cards' list index doesn't change
|
||||
for (int i = cards->size() - 1; i >= 0; i--)
|
||||
player->client->moveCard(cards->at(i)->getId(), getName(), targetZone, targetX);
|
||||
}
|
47
cockatrice/src/playerzone.h
Normal file
47
cockatrice/src/playerzone.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef PLAYERZONE_H
|
||||
#define PLAYERZONE_H
|
||||
|
||||
#include <QString>
|
||||
#include "cardlist.h"
|
||||
|
||||
class Player;
|
||||
class ZoneViewZone;
|
||||
class QMenu;
|
||||
|
||||
class PlayerZone : public QGraphicsItem {
|
||||
protected:
|
||||
Player *player;
|
||||
QString name;
|
||||
CardList *cards;
|
||||
QList<ZoneViewZone *> views;
|
||||
QMenu *menu;
|
||||
bool hasCardAttr;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
public:
|
||||
enum { Type = typeZone };
|
||||
int type() const { return Type; }
|
||||
virtual void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint) = 0;
|
||||
PlayerZone(Player *_player, const QString &_name, QGraphicsItem *parent = 0, bool isView = false);
|
||||
~PlayerZone();
|
||||
void clearContents();
|
||||
bool getHasCardAttr() const { return hasCardAttr; }
|
||||
QMenu *getMenu() const { return menu; }
|
||||
void setMenu(QMenu *_menu) { menu = _menu; }
|
||||
QString getName() const { return name; }
|
||||
Player *getPlayer() const { return player; }
|
||||
bool contentsKnown() const { return cards->getContentsKnown(); }
|
||||
CardList *const getCards() const { return cards; }
|
||||
virtual void addCard(CardItem *card, bool reorganize = true, int x = -1, int y = -1) = 0;
|
||||
// getCard() finds a card by id.
|
||||
CardItem *getCard(int cardId, const QString &cardName);
|
||||
// takeCard() finds a card by position and removes it from the zone and from all of its views.
|
||||
CardItem *takeCard(int position, int cardId, const QString &cardName);
|
||||
void setCardAttr(int cardId, const QString &aname, const QString &avalue);
|
||||
void hoverCardEvent(CardItem *card);
|
||||
void addView(ZoneViewZone *view);
|
||||
void removeView(ZoneViewZone *view);
|
||||
virtual void reorganizeCards() = 0;
|
||||
void moveAllToZone(const QString &targetZone, int targetX);
|
||||
};
|
||||
|
||||
#endif
|
53
cockatrice/src/rfgzone.cpp
Normal file
53
cockatrice/src/rfgzone.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <QtGui>
|
||||
#include "rfgzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
RfgZone::RfgZone(Player *_p)
|
||||
: PlayerZone(_p, "rfg")
|
||||
{
|
||||
cards = new CardList(true);
|
||||
}
|
||||
|
||||
QRectF RfgZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void RfgZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("white"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void RfgZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void RfgZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void RfgZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
17
cockatrice/src/rfgzone.h
Normal file
17
cockatrice/src/rfgzone.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef RFGZONE_H
|
||||
#define RFGZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class RfgZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
RfgZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
49
cockatrice/src/servereventdata.cpp
Normal file
49
cockatrice/src/servereventdata.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "servereventdata.h"
|
||||
|
||||
// Message structure for server events:
|
||||
// {"private","public"}|PlayerId|PlayerName|EventType|EventData
|
||||
|
||||
const int event_count = 19;
|
||||
const event_string event_strings[event_count] = {
|
||||
{eventPlayerId, "player_id"},
|
||||
{eventSay, "say"},
|
||||
{eventName, "name"},
|
||||
{eventJoin, "join"},
|
||||
{eventLeave, "leave"},
|
||||
{eventReadyStart, "ready_start"},
|
||||
{eventSetupZones, "setup_zones"},
|
||||
{eventGameStart, "game_start"},
|
||||
{eventShuffle, "shuffle"},
|
||||
{eventRollDice, "roll_dice"},
|
||||
{eventDraw, "draw"},
|
||||
{eventMoveCard, "move_card"},
|
||||
{eventCreateToken, "create_token"},
|
||||
{eventSetCardAttr, "set_card_attr"},
|
||||
{eventSetCounter, "set_counter"},
|
||||
{eventDelCounter, "del_counter"},
|
||||
{eventSetActivePlayer, "set_active_player"},
|
||||
{eventSetActivePhase, "set_active_phase"},
|
||||
{eventDumpZone, "dump_zone"}
|
||||
};
|
||||
|
||||
ServerEventData::ServerEventData(const QString &line)
|
||||
{
|
||||
QStringList values = line.split("|");
|
||||
|
||||
IsPublic = !values.takeFirst().compare("public");
|
||||
PlayerId = values.takeFirst().toInt();
|
||||
PlayerName = values.takeFirst();
|
||||
|
||||
QString type = values.takeFirst();
|
||||
bool found = false;
|
||||
for (int i = 0; i < event_count; i++)
|
||||
if (!type.compare(event_strings[i].str)) {
|
||||
EventType = event_strings[i].type;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
EventType = eventInvalid;
|
||||
|
||||
EventData = values;
|
||||
}
|
54
cockatrice/src/servereventdata.h
Normal file
54
cockatrice/src/servereventdata.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef SERVEREVENTDATA_H
|
||||
#define SERVEREVENTDATA_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
|
||||
enum ServerEventType {
|
||||
eventInvalid,
|
||||
eventPlayerId,
|
||||
eventSay,
|
||||
eventName,
|
||||
eventJoin,
|
||||
eventLeave,
|
||||
eventReadyStart,
|
||||
eventSetupZones,
|
||||
eventGameStart,
|
||||
eventShuffle,
|
||||
eventRollDice,
|
||||
eventDraw,
|
||||
eventMoveCard,
|
||||
eventCreateToken,
|
||||
eventSetCardAttr,
|
||||
eventSetCounter,
|
||||
eventDelCounter,
|
||||
eventSetActivePlayer,
|
||||
eventSetActivePhase,
|
||||
eventDumpZone
|
||||
};
|
||||
|
||||
struct event_string {
|
||||
ServerEventType type;
|
||||
char *str;
|
||||
};
|
||||
|
||||
extern const int event_count;
|
||||
extern const event_string event_strings[];
|
||||
|
||||
class ServerEventData {
|
||||
private:
|
||||
bool IsPublic;
|
||||
int PlayerId;
|
||||
QString PlayerName;
|
||||
ServerEventType EventType;
|
||||
QStringList EventData;
|
||||
public:
|
||||
ServerEventData(const QString &line);
|
||||
bool getPublic() { return IsPublic; }
|
||||
int getPlayerId() { return PlayerId; }
|
||||
QString getPlayerName() { return PlayerName; }
|
||||
ServerEventType getEventType() { return EventType; }
|
||||
QStringList getEventData() { return EventData; }
|
||||
};
|
||||
|
||||
#endif
|
21
cockatrice/src/servergame.h
Normal file
21
cockatrice/src/servergame.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef SERVERGAME_H
|
||||
#define SERVERGAME_H
|
||||
|
||||
class ServerGame {
|
||||
private:
|
||||
QString name;
|
||||
QString description;
|
||||
bool hasPassword;
|
||||
unsigned char playerCount;
|
||||
unsigned char maxPlayers;
|
||||
public:
|
||||
ServerGame(const QString &_name, const QString &_description, bool _hasPassword, unsigned char _playerCount, unsigned char _maxPlayers)
|
||||
: name(_name), description(_description), hasPassword(_hasPassword), playerCount(_playerCount), maxPlayers(_maxPlayers) { }
|
||||
QString getName() { return name; }
|
||||
QString getDescription() { return description; }
|
||||
bool getHasPassword() { return hasPassword; }
|
||||
unsigned char getPlayerCount() { return playerCount; }
|
||||
unsigned char getMaxPlayers() { return maxPlayers; }
|
||||
};
|
||||
|
||||
#endif
|
17
cockatrice/src/serverplayer.h
Normal file
17
cockatrice/src/serverplayer.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef SERVERPLAYER_H
|
||||
#define SERVERPLAYER_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ServerPlayer {
|
||||
private:
|
||||
int PlayerId;
|
||||
QString name;
|
||||
public:
|
||||
ServerPlayer(int _PlayerId, const QString &_name)
|
||||
: PlayerId(_PlayerId), name(_name) { }
|
||||
int getPlayerId() { return PlayerId; }
|
||||
QString getName() { return name; }
|
||||
};
|
||||
|
||||
#endif
|
22
cockatrice/src/serverresponse.h
Normal file
22
cockatrice/src/serverresponse.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef SERVERRESPONSE_H
|
||||
#define SERVERRESPONSE_H
|
||||
|
||||
enum ServerErrorMessage {
|
||||
msgNone,
|
||||
msgSyntaxError
|
||||
};
|
||||
|
||||
class ServerResponse {
|
||||
private:
|
||||
int msgId;
|
||||
bool ok;
|
||||
ServerErrorMessage message;
|
||||
public:
|
||||
ServerResponse(int _msgId, bool _ok, ServerErrorMessage _message)
|
||||
: msgId(_msgId), ok(_ok), message(_message) { }
|
||||
int getMsgId() { return msgId; }
|
||||
bool getOk() { return ok; }
|
||||
ServerErrorMessage getMessage() { return message; }
|
||||
};
|
||||
|
||||
#endif
|
21
cockatrice/src/serverzone.h
Normal file
21
cockatrice/src/serverzone.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef SERVERZONE_H
|
||||
#define SERVERZONE_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ServerZone {
|
||||
private:
|
||||
QString name;
|
||||
bool isPublic;
|
||||
bool hasCoords;
|
||||
int cardCount;
|
||||
public:
|
||||
ServerZone(const QString &_name, bool _isPublic, bool _hasCoords, int _cardCount)
|
||||
: name(_name), isPublic(_isPublic), hasCoords(_hasCoords), cardCount(_cardCount) { }
|
||||
QString getName() const { return name; }
|
||||
bool getPublic() const { return isPublic; }
|
||||
bool getHasCoords() const { return hasCoords; }
|
||||
int getCardCount() const { return cardCount; }
|
||||
};
|
||||
|
||||
#endif
|
28
cockatrice/src/serverzonecard.h
Normal file
28
cockatrice/src/serverzonecard.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef SERVERZONECARD_H
|
||||
#define SERVERZONECARD_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ServerZoneCard {
|
||||
private:
|
||||
int id;
|
||||
QString name;
|
||||
int x, y;
|
||||
int counters;
|
||||
bool tapped;
|
||||
bool attacking;
|
||||
QString annotation;
|
||||
public:
|
||||
ServerZoneCard(int _id, const QString &_name, int _x, int _y, int _counters, bool _attacking, const QString &_annotation)
|
||||
: id(_id), name(_name), x(_x), y(_y), counters(_counters), attacking(_attacking), annotation(_annotation) { }
|
||||
int getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
int getX() const { return x; }
|
||||
int getY() const { return y; }
|
||||
int getCounters() const { return counters; }
|
||||
bool getTapped() const { return tapped; }
|
||||
bool getAttacking() const { return attacking; }
|
||||
QString getAnnotation() const { return annotation; }
|
||||
};
|
||||
|
||||
#endif
|
54
cockatrice/src/sideboardzone.cpp
Normal file
54
cockatrice/src/sideboardzone.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include <QtGui>
|
||||
#include "sideboardzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
SideboardZone::SideboardZone(Player *_p)
|
||||
: PlayerZone(_p, "sb")
|
||||
{
|
||||
cards = new CardList(false);
|
||||
}
|
||||
|
||||
QRectF SideboardZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void SideboardZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("blue"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void SideboardZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void SideboardZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void SideboardZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
||||
|
17
cockatrice/src/sideboardzone.h
Normal file
17
cockatrice/src/sideboardzone.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef SIDEBOARDZONE_H
|
||||
#define SIDEBOARDZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class SideboardZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
SideboardZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
56
cockatrice/src/tablezone.cpp
Normal file
56
cockatrice/src/tablezone.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <QtGui>
|
||||
#include "tablezone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
|
||||
TableZone::TableZone(Player *_p)
|
||||
: PlayerZone(_p, "table"), width(700), height(500)
|
||||
{
|
||||
cards = new CardList(true);
|
||||
hasCardAttr = true;
|
||||
}
|
||||
|
||||
QRectF TableZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, width, height);
|
||||
}
|
||||
|
||||
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->fillRect(boundingRect(), QColor("blue"));
|
||||
}
|
||||
|
||||
void TableZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
Q_UNUSED(reorganize);
|
||||
cards->append(card);
|
||||
if ((x != -1) && (y != -1)) {
|
||||
if (!player->getLocal())
|
||||
y = height - CARD_HEIGHT - y;
|
||||
card->setPos(x, y);
|
||||
}
|
||||
card->setZValue((y + CARD_HEIGHT) * width + x + 1000);
|
||||
card->setParentItem(this);
|
||||
card->setVisible(true);
|
||||
card->update(card->boundingRect());
|
||||
}
|
||||
|
||||
void TableZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), dropPoint.x(), dropPoint.y());
|
||||
}
|
||||
|
||||
void TableZone::reorganizeCards()
|
||||
{
|
||||
}
|
||||
|
||||
void TableZone::toggleTapped()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene()->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
setCardAttr(temp->getId(), "tapped", temp->getTapped() ? "0" : "1");
|
||||
}
|
||||
}
|
22
cockatrice/src/tablezone.h
Normal file
22
cockatrice/src/tablezone.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef TABLEZONE_H
|
||||
#define TABLEZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
const int GRID_WIDTH = 30;
|
||||
const int GRID_HEIGHT = 30;
|
||||
|
||||
class TableZone : public PlayerZone {
|
||||
private:
|
||||
int width, height;
|
||||
public:
|
||||
TableZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = -1, int y = -1);
|
||||
void reorganizeCards();
|
||||
void toggleTapped();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
258
cockatrice/src/window.cpp
Normal file
258
cockatrice/src/window.cpp
Normal file
|
@ -0,0 +1,258 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@gmx.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include <QtGui>
|
||||
#include <QtOpenGL>
|
||||
|
||||
#include "window.h"
|
||||
#include "dlg_connect.h"
|
||||
#include "dlg_games.h"
|
||||
#include "cardinfowidget.h"
|
||||
#include "messagelogwidget.h"
|
||||
|
||||
#include "gameview.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
#include "carddatabase.h"
|
||||
#include "zoneviewzone.h"
|
||||
#include "zoneviewwidget.h"
|
||||
#include "zoneviewlayout.h"
|
||||
|
||||
void MainWindow::hoverCard(QString name)
|
||||
{
|
||||
cardInfo->setCard(name);
|
||||
}
|
||||
|
||||
void MainWindow::playerAdded(Player *player)
|
||||
{
|
||||
menuBar()->addMenu(player->getPlayerMenu());
|
||||
connect(player, SIGNAL(addZoneView(Player *, QString, int)), zoneLayout, SLOT(addItem(Player *, QString, int)));
|
||||
}
|
||||
|
||||
void MainWindow::playerRemoved(Player *player)
|
||||
{
|
||||
menuBar()->removeAction(player->getPlayerMenu()->menuAction());
|
||||
}
|
||||
|
||||
void MainWindow::statusChanged(ProtocolStatus _status)
|
||||
{
|
||||
switch (_status) {
|
||||
case StatusConnecting:
|
||||
emit logConnecting(client->peerName());
|
||||
break;
|
||||
case StatusDisconnected:
|
||||
if (game) {
|
||||
delete game;
|
||||
game = 0;
|
||||
}
|
||||
aDisconnect->setEnabled(false);
|
||||
aGames->setEnabled(false);
|
||||
aRestartGame->setEnabled(false);
|
||||
aLeaveGame->setEnabled(false);
|
||||
emit logDisconnected();
|
||||
break;
|
||||
case StatusConnected:
|
||||
aDisconnect->setEnabled(true);
|
||||
aGames->setEnabled(true);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
void MainWindow::actConnect()
|
||||
{
|
||||
DlgConnect dlg(this);
|
||||
if (dlg.exec())
|
||||
client->connectToServer(dlg.getHost(), dlg.getPort(), dlg.getPlayerName());
|
||||
}
|
||||
|
||||
void MainWindow::actDisconnect()
|
||||
{
|
||||
client->disconnectFromServer();
|
||||
}
|
||||
|
||||
void MainWindow::actGames()
|
||||
{
|
||||
DlgGames dlg(client, this);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::actLeaveGame()
|
||||
{
|
||||
client->leaveGame();
|
||||
delete game;
|
||||
game = 0;
|
||||
aRestartGame->setEnabled(false);
|
||||
aLeaveGame->setEnabled(false);
|
||||
aGames->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::actExit()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void MainWindow::updateSceneSize()
|
||||
{
|
||||
QRectF sr = scene->sceneRect();
|
||||
QSizeF zoneSize = zoneLayout->size();
|
||||
qDebug(QString("updateSceneSize: width=%1").arg(850 + zoneSize.width()).toLatin1());
|
||||
scene->setSceneRect(sr.x(), sr.y(), 850 + zoneSize.width(), sr.height());
|
||||
view->scaleToScene();
|
||||
}
|
||||
|
||||
// Knöpfe
|
||||
|
||||
void MainWindow::buttonSay()
|
||||
{
|
||||
client->say(sayEdit->text());
|
||||
sayEdit->clear();
|
||||
}
|
||||
|
||||
void MainWindow::playerIdReceived(int id, QString name)
|
||||
{
|
||||
game = new Game(db, client, scene, actionsMenu, cardMenu, id, name);
|
||||
connect(game, SIGNAL(submitDecklist()), this, SLOT(decklistDialog()));
|
||||
connect(game, SIGNAL(hoverCard(QString)), this, SLOT(hoverCard(QString)));
|
||||
connect(game, SIGNAL(playerAdded(Player *)), this, SLOT(playerAdded(Player *)));
|
||||
connect(game, SIGNAL(playerRemoved(Player *)), this, SLOT(playerRemoved(Player *)));
|
||||
connect(aRestartGame, SIGNAL(triggered()), game, SLOT(restartGameDialog()));
|
||||
playerAdded(game->getLocalPlayer());
|
||||
|
||||
messageLog->connectToGame(game);
|
||||
aGames->setEnabled(false);
|
||||
aRestartGame->setEnabled(true);
|
||||
aLeaveGame->setEnabled(true);
|
||||
|
||||
client->listPlayers();
|
||||
}
|
||||
|
||||
void MainWindow::serverTimeout()
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Server timeout"));
|
||||
}
|
||||
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
aConnect = new QAction(tr("&Connect..."), this);
|
||||
connect(aConnect, SIGNAL(triggered()), this, SLOT(actConnect()));
|
||||
aDisconnect = new QAction(tr("&Disconnect"), this);
|
||||
aDisconnect->setEnabled(false);
|
||||
connect(aDisconnect, SIGNAL(triggered()), this, SLOT(actDisconnect()));
|
||||
aGames = new QAction(tr("&Games..."), this);
|
||||
aGames->setEnabled(false);
|
||||
connect(aGames, SIGNAL(triggered()), this, SLOT(actGames()));
|
||||
aRestartGame = new QAction(tr("&Restart game..."), this);
|
||||
aRestartGame->setShortcut(tr("F2"));
|
||||
aRestartGame->setEnabled(false);
|
||||
aLeaveGame = new QAction(tr("&Leave game"), this);
|
||||
aLeaveGame->setEnabled(false);
|
||||
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
aExit = new QAction(tr("&Exit"), this);
|
||||
connect(aExit, SIGNAL(triggered()), this, SLOT(actExit()));
|
||||
}
|
||||
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
gameMenu = menuBar()->addMenu(tr("&Game"));
|
||||
gameMenu->addAction(aConnect);
|
||||
gameMenu->addAction(aDisconnect);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aGames);
|
||||
gameMenu->addAction(aRestartGame);
|
||||
gameMenu->addAction(aLeaveGame);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aExit);
|
||||
|
||||
actionsMenu = menuBar()->addMenu(tr("&Actions"));
|
||||
|
||||
cardMenu = menuBar()->addMenu(tr("&Card"));
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), game(NULL)
|
||||
{
|
||||
// setWindowState(windowState() | Qt::WindowFullScreen);
|
||||
|
||||
QPixmapCache::setCacheLimit(200000);
|
||||
createActions();
|
||||
createMenus();
|
||||
|
||||
db = new CardDatabase;
|
||||
int cardCount = db->loadFromFile("../cards.dat");
|
||||
qDebug(QString("%1 cards loaded").arg(cardCount).toLatin1());
|
||||
|
||||
scene = new QGraphicsScene(0, 0, 850, 1000, this);
|
||||
view = new GameView(scene);
|
||||
|
||||
// view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
|
||||
// view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
|
||||
|
||||
zoneLayout = new ZoneViewLayout(db);
|
||||
zoneLayout->setPos(850, 0);
|
||||
scene->addItem(zoneLayout);
|
||||
connect(zoneLayout, SIGNAL(sizeChanged()), this, SLOT(updateSceneSize()));
|
||||
|
||||
cardInfo = new CardInfoWidget(db);
|
||||
messageLog = new MessageLogWidget;
|
||||
sayEdit = new QLineEdit;
|
||||
sayButton = new QPushButton(tr("&Say"));
|
||||
|
||||
QHBoxLayout *hLayout = new QHBoxLayout;
|
||||
hLayout->addWidget(sayEdit);
|
||||
hLayout->addWidget(sayButton);
|
||||
|
||||
QVBoxLayout *verticalLayout = new QVBoxLayout;
|
||||
verticalLayout->addWidget(cardInfo);
|
||||
verticalLayout->addWidget(messageLog);
|
||||
verticalLayout->addLayout(hLayout);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
mainLayout->addWidget(view);
|
||||
mainLayout->setStretchFactor(view, 10);
|
||||
mainLayout->addLayout(verticalLayout);
|
||||
|
||||
QWidget *centralWidget = new QWidget;
|
||||
centralWidget->setLayout(mainLayout);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(buttonSay()));
|
||||
connect(sayButton, SIGNAL(clicked()), this, SLOT(buttonSay()));
|
||||
|
||||
client = new Client(this);
|
||||
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
|
||||
connect(client, SIGNAL(statusChanged(ProtocolStatus)), this, SLOT(statusChanged(ProtocolStatus)));
|
||||
connect(client, SIGNAL(playerIdReceived(int, QString)), this, SLOT(playerIdReceived(int, QString)));
|
||||
|
||||
connect(this, SIGNAL(logConnecting(QString)), messageLog, SLOT(logConnecting(QString)));
|
||||
connect(client, SIGNAL(welcomeMsgReceived(const QStringList)), messageLog, SLOT(logConnected(const QStringList)));
|
||||
connect(this, SIGNAL(logDisconnected()), messageLog, SLOT(logDisconnected()));
|
||||
connect(client, SIGNAL(logSocketError(const QString &)), messageLog, SLOT(logSocketError(const QString &)));
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
delete game;
|
||||
|
||||
// db->importOracle();
|
||||
// db->saveToFile("../cards.dat");
|
||||
delete db;
|
||||
}
|
85
cockatrice/src/window.h
Normal file
85
cockatrice/src/window.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@gmx.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "client.h"
|
||||
|
||||
class QGraphicsScene;
|
||||
class GameView;
|
||||
class Game;
|
||||
class CardDatabase;
|
||||
class Player;
|
||||
|
||||
class CardInfoWidget;
|
||||
class MessageLogWidget;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class ServerZoneCard;
|
||||
class ZoneViewLayout;
|
||||
class ZoneViewWidget;
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void hoverCard(QString name);
|
||||
void playerAdded(Player *player);
|
||||
void playerRemoved(Player *player);
|
||||
void statusChanged(ProtocolStatus _status);
|
||||
void playerIdReceived(int id, QString name);
|
||||
void serverTimeout();
|
||||
|
||||
void buttonSay();
|
||||
|
||||
void actConnect();
|
||||
void actDisconnect();
|
||||
void actGames();
|
||||
void actLeaveGame();
|
||||
void actExit();
|
||||
|
||||
void updateSceneSize();
|
||||
signals:
|
||||
void logConnecting(QString hostname);
|
||||
void logDisconnected();
|
||||
private:
|
||||
void createActions();
|
||||
void createMenus();
|
||||
QMenu *gameMenu, *actionsMenu, *cardMenu;
|
||||
QAction *aConnect, *aDisconnect, *aGames, *aRestartGame, *aLeaveGame, *aExit;
|
||||
|
||||
CardInfoWidget *cardInfo;
|
||||
MessageLogWidget *messageLog;
|
||||
QLineEdit *sayEdit;
|
||||
QPushButton *sayButton;
|
||||
|
||||
Client *client;
|
||||
QGraphicsScene *scene;
|
||||
GameView *view;
|
||||
Game *game;
|
||||
CardDatabase *db;
|
||||
ZoneViewLayout *zoneLayout;
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
};
|
||||
|
||||
#endif
|
18
cockatrice/src/zoneclosebutton.cpp
Normal file
18
cockatrice/src/zoneclosebutton.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <QtGui>
|
||||
#include "zoneclosebutton.h"
|
||||
|
||||
void ZoneCloseButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
emit triggered();
|
||||
}
|
||||
|
||||
void ZoneCloseButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
painter->fillRect(rect(), QColor("red"));
|
||||
}
|
||||
|
||||
ZoneCloseButton::ZoneCloseButton(QGraphicsItem *parent)
|
||||
: QGraphicsWidget(parent)
|
||||
{
|
||||
resize(20, 20);
|
||||
}
|
17
cockatrice/src/zoneclosebutton.h
Normal file
17
cockatrice/src/zoneclosebutton.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef ZONECLOSEBUTTON_H
|
||||
#define ZONECLOSEBUTTON_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
|
||||
class ZoneCloseButton : public QGraphicsWidget {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void triggered();
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
public:
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
ZoneCloseButton(QGraphicsItem *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
11
cockatrice/src/zonelist.cpp
Normal file
11
cockatrice/src/zonelist.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "zonelist.h"
|
||||
|
||||
PlayerZone *ZoneList::findZone(const QString &name) const
|
||||
{
|
||||
for (int i = 0; i < size(); i++) {
|
||||
PlayerZone *temp = at(i);
|
||||
if (!temp->getName().compare(name))
|
||||
return temp;
|
||||
}
|
||||
return 0;
|
||||
}
|
12
cockatrice/src/zonelist.h
Normal file
12
cockatrice/src/zonelist.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef ZONELIST_H
|
||||
#define ZONELIST_H
|
||||
|
||||
#include "playerzone.h"
|
||||
#include <QList>
|
||||
|
||||
class ZoneList : public QList<PlayerZone *> {
|
||||
public:
|
||||
PlayerZone *findZone(const QString &name) const;
|
||||
};
|
||||
|
||||
#endif
|
36
cockatrice/src/zoneviewlayout.cpp
Normal file
36
cockatrice/src/zoneviewlayout.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "zoneviewlayout.h"
|
||||
#include "zoneviewwidget.h"
|
||||
#include "player.h"
|
||||
|
||||
ZoneViewLayout::ZoneViewLayout(CardDatabase *_db, QGraphicsItem *parent)
|
||||
: QGraphicsWidget(parent), db(_db)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZoneViewLayout::reorganize()
|
||||
{
|
||||
qDebug(QString("ZoneViewLayout: activate: count=%1").arg(views.size()).toLatin1());
|
||||
resize(views.size() * 150, 1000);
|
||||
for (int i = 0; i < views.size(); i++) {
|
||||
views.at(i)->setPos(i * 150, 0);
|
||||
}
|
||||
emit sizeChanged();
|
||||
}
|
||||
|
||||
void ZoneViewLayout::addItem(Player *player, const QString &zoneName, int numberCards)
|
||||
{
|
||||
ZoneViewWidget *item = new ZoneViewWidget(db, player, player->getZones()->findZone(zoneName), numberCards, this);
|
||||
views.append(item);
|
||||
connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeItem(ZoneViewWidget *)));
|
||||
reorganize();
|
||||
}
|
||||
|
||||
void ZoneViewLayout::removeItem(ZoneViewWidget *item)
|
||||
{
|
||||
qDebug("ZoneViewLayout::removeItem");
|
||||
views.removeAt(views.indexOf(item));
|
||||
scene()->removeItem(item);
|
||||
delete item;
|
||||
reorganize();
|
||||
}
|
25
cockatrice/src/zoneviewlayout.h
Normal file
25
cockatrice/src/zoneviewlayout.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef ZONEVIEWLAYOUT_H
|
||||
#define ZONEVIEWLAYOUT_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
|
||||
class CardDatabase;
|
||||
class ZoneViewWidget;
|
||||
class Player;
|
||||
|
||||
class ZoneViewLayout : public QGraphicsWidget {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void sizeChanged();
|
||||
private:
|
||||
QList<ZoneViewWidget *> views;
|
||||
CardDatabase *db;
|
||||
public:
|
||||
ZoneViewLayout(CardDatabase *_db, QGraphicsItem *parent = 0);
|
||||
void reorganize();
|
||||
public slots:
|
||||
void addItem(Player *player, const QString &zoneName, int numberCards = 0);
|
||||
void removeItem(ZoneViewWidget *item);
|
||||
};
|
||||
|
||||
#endif
|
45
cockatrice/src/zoneviewwidget.cpp
Normal file
45
cockatrice/src/zoneviewwidget.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <QtGui>
|
||||
|
||||
#include "zoneviewwidget.h"
|
||||
#include "carditem.h"
|
||||
#include "zoneviewzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneclosebutton.h"
|
||||
|
||||
ZoneViewWidget::ZoneViewWidget(CardDatabase *_db, Player *_player, PlayerZone *_origZone, int numberCards, QGraphicsItem *parent)
|
||||
: QGraphicsWidget(parent), db(_db), player(_player)
|
||||
{
|
||||
ZoneCloseButton *closeButton = new ZoneCloseButton(this);
|
||||
connect(closeButton, SIGNAL(triggered()), this, SLOT(slotClosePressed()));
|
||||
|
||||
resize(150, 1000);
|
||||
|
||||
zone = new ZoneViewZone(player, _origZone, numberCards, this);
|
||||
zone->setPos(0, 30);
|
||||
if (!zone->initializeCards()) {
|
||||
connect(player->client, SIGNAL(zoneDumpReceived(int, QList<ServerZoneCard *>)), this, SLOT(zoneDumpReceived(int, QList<ServerZoneCard *>)));
|
||||
cmdId = player->client->dumpZone(player->getId(), _origZone->getName(), numberCards);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneViewWidget::zoneDumpReceived(int commandId, QList<ServerZoneCard *> cards)
|
||||
{
|
||||
if (commandId != cmdId)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < cards.size(); i++) {
|
||||
ServerZoneCard *temp = cards[i];
|
||||
|
||||
CardItem *card = new CardItem(db, temp->getName(), i, zone);
|
||||
zone->addCard(card, false, i);
|
||||
|
||||
delete temp;
|
||||
}
|
||||
zone->reorganizeCards();
|
||||
}
|
||||
|
||||
void ZoneViewWidget::slotClosePressed()
|
||||
{
|
||||
emit closePressed(this);
|
||||
}
|
31
cockatrice/src/zoneviewwidget.h
Normal file
31
cockatrice/src/zoneviewwidget.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef ZONEVIEWWIDGET_H
|
||||
#define ZONEVIEWWIDGET_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsWidget>
|
||||
#include "serverzonecard.h"
|
||||
|
||||
class PlayerZone;
|
||||
class ZoneViewZone;
|
||||
class Player;
|
||||
class CardDatabase;
|
||||
|
||||
class ZoneViewWidget : public QGraphicsWidget {
|
||||
Q_OBJECT
|
||||
private:
|
||||
ZoneViewZone *zone;
|
||||
int cmdId;
|
||||
|
||||
CardDatabase *db;
|
||||
Player *player;
|
||||
signals:
|
||||
void closePressed(ZoneViewWidget *zv);
|
||||
private slots:
|
||||
void zoneDumpReceived(int commandId, QList<ServerZoneCard *> cards);
|
||||
void slotClosePressed();
|
||||
public:
|
||||
ZoneViewWidget(CardDatabase *_db, Player *_player, PlayerZone *_origZone, int numberCards = 0, QGraphicsItem *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
104
cockatrice/src/zoneviewzone.cpp
Normal file
104
cockatrice/src/zoneviewzone.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
#include <QtGui>
|
||||
#include "zoneviewzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
|
||||
ZoneViewZone::ZoneViewZone(Player *_p, PlayerZone *_origZone, int _numberCards, QGraphicsItem *parent)
|
||||
: PlayerZone(_p, _origZone->getName(), parent, true), numberCards(_numberCards), origZone(_origZone)
|
||||
{
|
||||
cards = new CardList(true);
|
||||
origZone->addView(this);
|
||||
}
|
||||
|
||||
ZoneViewZone::~ZoneViewZone()
|
||||
{
|
||||
qDebug("ZoneViewZone destructor");
|
||||
origZone->removeView(this);
|
||||
}
|
||||
|
||||
QRectF ZoneViewZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, CARD_WIDTH * 1.75, scene()->sceneRect().height());
|
||||
}
|
||||
|
||||
void ZoneViewZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
}
|
||||
|
||||
bool ZoneViewZone::initializeCards()
|
||||
{
|
||||
if (!origZone->contentsKnown())
|
||||
return false;
|
||||
|
||||
CardList *const c = origZone->getCards();
|
||||
int number = numberCards == 0 ? c->size() : (numberCards < c->size() ? numberCards : c->size());
|
||||
for (int i = 0; i < number; i++) {
|
||||
CardItem *card = c->at(i);
|
||||
addCard(new CardItem(player->getDb(), card->getName(), card->getId(), this), false, i);
|
||||
}
|
||||
reorganizeCards();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Because of boundingRect(), this function must not be called before the zone was added to a scene.
|
||||
void ZoneViewZone::reorganizeCards()
|
||||
{
|
||||
qDebug("reorganizeCards");
|
||||
|
||||
if (cards->isEmpty())
|
||||
return;
|
||||
|
||||
int cardCount = cards->size();
|
||||
qreal totalWidth = boundingRect().width();
|
||||
qreal totalHeight = boundingRect().height();
|
||||
qreal cardWidth = cards->at(0)->boundingRect().width();
|
||||
qreal cardHeight = cards->at(0)->boundingRect().height();
|
||||
qreal x1 = 0;
|
||||
qreal x2 = (totalWidth - cardWidth);
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
CardItem *c = cards->at(i);
|
||||
qreal x = i % 2 ? x2 : x1;
|
||||
// If the total height of the cards is smaller than the available height,
|
||||
// the cards do not need to overlap and are displayed in the center of the area.
|
||||
if (cardHeight * cardCount > totalHeight)
|
||||
c->setPos(x, ((qreal) i) * (totalHeight - cardHeight) / (cardCount - 1));
|
||||
else
|
||||
c->setPos(x, ((qreal) i) * cardHeight + (totalHeight - cardCount * cardHeight) / 2);
|
||||
if (!origZone->contentsKnown())
|
||||
c->setId(i);
|
||||
c->setZValue(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneViewZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
Q_UNUSED(y);
|
||||
qDebug(QString("ZoneViewZone: inserting '%1' at x=%2").arg(card->getName()).arg(x).toLatin1());
|
||||
cards->insert(x, card);
|
||||
card->setParentItem(this);
|
||||
card->update(card->boundingRect());
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void ZoneViewZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
Q_UNUSED(dropPoint);
|
||||
qDebug(QString("handleDropEvent id=%1").arg(cardId).toLatin1());
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void ZoneViewZone::removeCard(int position)
|
||||
{
|
||||
if (position >= cards->size())
|
||||
return;
|
||||
|
||||
CardItem *card = cards->at(position);
|
||||
cards->removeAt(position);
|
||||
delete card;
|
||||
reorganizeCards();
|
||||
}
|
27
cockatrice/src/zoneviewzone.h
Normal file
27
cockatrice/src/zoneviewzone.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef ZONEVIEWERZONE_H
|
||||
#define ZONEVIEWERZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
#include "serverzonecard.h"
|
||||
|
||||
class ZoneViewWidget;
|
||||
|
||||
class ZoneViewZone : public PlayerZone {
|
||||
private:
|
||||
int numberCards;
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
PlayerZone *origZone;
|
||||
signals:
|
||||
void removeZoneViewWidget(ZoneViewWidget *zv);
|
||||
public:
|
||||
ZoneViewZone(Player *_p, PlayerZone *_origZone, int _numberCards = 0, QGraphicsItem *parent = 0);
|
||||
~ZoneViewZone();
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
bool initializeCards();
|
||||
void removeCard(int position);
|
||||
};
|
||||
|
||||
#endif
|
311
servatrice/Doxyfile
Executable file
311
servatrice/Doxyfile
Executable file
|
@ -0,0 +1,311 @@
|
|||
# Doxyfile 1.5.5-KDevelop
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = servertest
|
||||
PROJECT_NUMBER = 0.1
|
||||
OUTPUT_DIRECTORY =
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH = /home/brukie/
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = /home/brukie/servertest
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
*.cxx \
|
||||
*.cpp \
|
||||
*.c++ \
|
||||
*.d \
|
||||
*.java \
|
||||
*.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
*.inl \
|
||||
*.h \
|
||||
*.hh \
|
||||
*.hxx \
|
||||
*.hpp \
|
||||
*.h++ \
|
||||
*.idl \
|
||||
*.odl \
|
||||
*.cs \
|
||||
*.php \
|
||||
*.php3 \
|
||||
*.inc \
|
||||
*.m \
|
||||
*.mm \
|
||||
*.dox \
|
||||
*.py \
|
||||
*.f90 \
|
||||
*.f \
|
||||
*.vhd \
|
||||
*.vhdl \
|
||||
*.C \
|
||||
*.CC \
|
||||
*.C++ \
|
||||
*.II \
|
||||
*.I++ \
|
||||
*.H \
|
||||
*.HH \
|
||||
*.H++ \
|
||||
*.CS \
|
||||
*.PHP \
|
||||
*.PHP3 \
|
||||
*.M \
|
||||
*.MM \
|
||||
*.PY \
|
||||
*.F90 \
|
||||
*.F \
|
||||
*.VHD \
|
||||
*.VHDL \
|
||||
*.C \
|
||||
*.H \
|
||||
*.tlh \
|
||||
*.diff \
|
||||
*.patch \
|
||||
*.moc \
|
||||
*.xpm \
|
||||
*.dox
|
||||
RECURSIVE = yes
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NONE
|
||||
TREEVIEW_WIDTH = 250
|
||||
FORMULA_FONTSIZE = 10
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = yes
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE = servertest.tag
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_FONTNAME = FreeSans
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = YES
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
340
servatrice/copying
Executable file
340
servatrice/copying
Executable file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
32
servatrice/servertest.pro
Executable file
32
servatrice/servertest.pro
Executable file
|
@ -0,0 +1,32 @@
|
|||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) Fr Sep 5 18:02:29 2008
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += . src
|
||||
INCLUDEPATH += . src
|
||||
|
||||
CONFIG += qt thread
|
||||
QT += network
|
||||
QT -= gui
|
||||
|
||||
# Input
|
||||
HEADERS += src/testserver.h src/testservergame.h src/testserversocket.h \
|
||||
src/playerzone.h \
|
||||
src/testcard.h \
|
||||
src/version.h \
|
||||
src/counter.h \
|
||||
src/testrandom.h \
|
||||
src/testservergamethread.h \
|
||||
src/returnmessage.h
|
||||
SOURCES += src/main.cpp \
|
||||
src/testserver.cpp \
|
||||
src/testservergame.cpp \
|
||||
src/testserversocket.cpp \
|
||||
src/playerzone.cpp \
|
||||
src/testcard.cpp \
|
||||
src/counter.cpp \
|
||||
src/testrandom.cpp \
|
||||
src/testservergamethread.cpp \
|
||||
src/returnmessage.cpp
|
21
servatrice/src/counter.cpp
Normal file
21
servatrice/src/counter.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "counter.h"
|
||||
|
37
servatrice/src/counter.h
Normal file
37
servatrice/src/counter.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef COUNTER_H
|
||||
#define COUNTER_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class Counter {
|
||||
protected:
|
||||
QString name;
|
||||
int count;
|
||||
public:
|
||||
Counter(QString _name, int _count = 0) : name(_name), count(_count) { }
|
||||
~Counter() { }
|
||||
int getCount() { return count; }
|
||||
void setCount(int _count) { count = _count; }
|
||||
QString getName() const { return name; }
|
||||
};
|
||||
|
||||
#endif
|
33
servatrice/src/main.cpp
Normal file
33
servatrice/src/main.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include "testserver.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
TestServer server;
|
||||
server.listen(QHostAddress::Any, 4747);
|
||||
|
||||
return app.exec();
|
||||
}
|
86
servatrice/src/playerzone.cpp
Normal file
86
servatrice/src/playerzone.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "playerzone.h"
|
||||
|
||||
PlayerZone::PlayerZone(QString _name, bool _has_coords, bool _is_public, bool _id_access)
|
||||
: name(_name), has_coords(_has_coords), is_public(_is_public), id_access(_id_access)
|
||||
{
|
||||
}
|
||||
|
||||
PlayerZone::~PlayerZone()
|
||||
{
|
||||
qDebug(QString("PlayerZone destructor: %1").arg(name).toLatin1());
|
||||
clear();
|
||||
}
|
||||
|
||||
void PlayerZone::shuffle(TestRandom *rnd)
|
||||
{
|
||||
QList<TestCard *> temp;
|
||||
for (int i = cards.size(); i; i--)
|
||||
temp.append(cards.takeAt(rnd->getNumber(0, i - 1)));
|
||||
cards = temp;
|
||||
}
|
||||
|
||||
TestCard *PlayerZone::getCard(int id, bool remove, int *position)
|
||||
{
|
||||
if (hasIdAccess()) {
|
||||
QListIterator<TestCard *> CardIterator(cards);
|
||||
int i = 0;
|
||||
while (CardIterator.hasNext()) {
|
||||
TestCard *tmp = CardIterator.next();
|
||||
if (tmp->getId() == id) {
|
||||
if (remove)
|
||||
cards.removeAt(i);
|
||||
if (position)
|
||||
*position = i;
|
||||
return tmp;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
if (id >= cards.size())
|
||||
return NULL;
|
||||
TestCard *tmp = cards[id];
|
||||
if (remove)
|
||||
cards.removeAt(id);
|
||||
if (position)
|
||||
*position = id;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerZone::insertCard(TestCard *card, int x, int y)
|
||||
{
|
||||
if (hasCoords()) {
|
||||
card->setCoords(x, y);
|
||||
cards.append(card);
|
||||
} else {
|
||||
card->setCoords(0, 0);
|
||||
cards.insert(x, card);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerZone::clear()
|
||||
{
|
||||
for (int i = 0; i < cards.size(); i++)
|
||||
delete cards.at(i);
|
||||
cards.clear();
|
||||
}
|
55
servatrice/src/playerzone.h
Normal file
55
servatrice/src/playerzone.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef PLAYERZONE_H
|
||||
#define PLAYERZONE_H
|
||||
|
||||
#include <QList>
|
||||
#include "testcard.h"
|
||||
#include "testrandom.h"
|
||||
|
||||
class PlayerZone {
|
||||
private:
|
||||
QString name;
|
||||
bool has_coords;
|
||||
bool is_public; // Contents of the zone are visible for anyone
|
||||
bool id_access; // getCard() finds by id, not by list index
|
||||
// Example: When moving a card from the library to the table,
|
||||
// the card has to be found by list index because the client
|
||||
// does not know the id. But when moving a card from the hand
|
||||
// to the table, the card can be found by id because the client
|
||||
// knows the id and the hand does not need to have a specific order.
|
||||
public:
|
||||
PlayerZone(QString _name, bool _has_coords, bool _is_public, bool _id_access);
|
||||
~PlayerZone();
|
||||
|
||||
TestCard *getCard(int id, bool remove, int *position = NULL);
|
||||
|
||||
bool isPublic() { return is_public; }
|
||||
bool hasCoords() { return has_coords; }
|
||||
bool hasIdAccess() { return id_access; }
|
||||
QString getName() { return name; }
|
||||
|
||||
QList<TestCard *> cards;
|
||||
void insertCard(TestCard *card, int x, int y);
|
||||
void shuffle(TestRandom *rnd);
|
||||
void clear();
|
||||
};
|
||||
|
||||
#endif
|
33
servatrice/src/returnmessage.cpp
Normal file
33
servatrice/src/returnmessage.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "returnmessage.h"
|
||||
#include "testserversocket.h"
|
||||
|
||||
void ReturnMessage::setMsgId(unsigned int _msg_id)
|
||||
{
|
||||
msg_id = _msg_id;
|
||||
}
|
||||
|
||||
bool ReturnMessage::send(const QString &args, bool success)
|
||||
{
|
||||
TestServerSocket *s = qobject_cast<TestServerSocket *>(parent());
|
||||
if (!s)
|
||||
return false;
|
||||
s->msg(QString("resp|%1|%2|%3").arg(msg_id)
|
||||
.arg(success ? "ok" : "err")
|
||||
.arg(args));
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ReturnMessage::sendList(const QStringList &args)
|
||||
{
|
||||
TestServerSocket *s = qobject_cast<TestServerSocket *>(parent());
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < args.size(); i++)
|
||||
s->msg(QString("%1|%2|%3").arg(cmd)
|
||||
.arg(msg_id)
|
||||
.arg(args[i]));
|
||||
s->msg(QString("%1|%2|.").arg(cmd).arg(msg_id));
|
||||
|
||||
return true;
|
||||
}
|
21
servatrice/src/returnmessage.h
Normal file
21
servatrice/src/returnmessage.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef RETURNMESSAGE_H
|
||||
#define RETURNMESSAGE_H
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
|
||||
class ReturnMessage : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
unsigned int msg_id;
|
||||
QString cmd;
|
||||
public:
|
||||
ReturnMessage(QObject *parent = 0) : QObject(parent), msg_id(0) { }
|
||||
unsigned int getMsgId() const { return msg_id; }
|
||||
void setMsgId(unsigned int _msg_id);
|
||||
void setCmd(const QString &_cmd) { cmd = _cmd; }
|
||||
bool send(const QString &args = QString(), bool success = true);
|
||||
bool sendList(const QStringList &args);
|
||||
};
|
||||
|
||||
#endif
|
62
servatrice/src/testcard.cpp
Normal file
62
servatrice/src/testcard.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "testcard.h"
|
||||
|
||||
TestCard::TestCard(QString _name, int _id, int _coord_x, int _coord_y)
|
||||
: id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), counters(0), tapped(false), attacking(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TestCard::~TestCard()
|
||||
{
|
||||
}
|
||||
|
||||
void TestCard::resetState()
|
||||
{
|
||||
setCoords(0, 0);
|
||||
setCounters(0);
|
||||
setTapped(false);
|
||||
setAttacking(false);
|
||||
setFaceDown(false);
|
||||
setAnnotation("");
|
||||
}
|
||||
|
||||
bool TestCard::setAttribute(const QString &aname, const QString &avalue)
|
||||
{
|
||||
if (!aname.compare("counters")) {
|
||||
bool ok;
|
||||
int tmp_int = avalue.toInt(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
setCounters(tmp_int);
|
||||
} else if (!aname.compare("tapped")) {
|
||||
setTapped(!avalue.compare("1"));
|
||||
} else if (!aname.compare("attacking")) {
|
||||
setAttacking(!avalue.compare("1"));
|
||||
} else if (!aname.compare("facedown")) {
|
||||
setFaceDown(!avalue.compare("1"));
|
||||
} else if (!aname.compare("annotation")) {
|
||||
setAnnotation(avalue);
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
63
servatrice/src/testcard.h
Normal file
63
servatrice/src/testcard.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef TESTCARD_H
|
||||
#define TESTCARD_H
|
||||
|
||||
#include <QString>
|
||||
/**
|
||||
@author Max-Wilhelm Bruker <brukie@laptop>
|
||||
*/
|
||||
class TestCard {
|
||||
private:
|
||||
int id;
|
||||
int coord_x, coord_y;
|
||||
QString name;
|
||||
int counters;
|
||||
bool tapped;
|
||||
bool attacking;
|
||||
bool facedown;
|
||||
QString annotation;
|
||||
public:
|
||||
TestCard(QString _name, int _id, int _coord_x, int _coord_y);
|
||||
~TestCard();
|
||||
|
||||
int getId() { return id; }
|
||||
int getX() { return coord_x; }
|
||||
int getY() { return coord_y; }
|
||||
QString getName() { return name; }
|
||||
int getCounters() { return counters; }
|
||||
bool getTapped() { return tapped; }
|
||||
bool getAttacking() { return attacking; }
|
||||
bool getFaceDown() { return facedown; }
|
||||
QString getAnnotation() { return annotation; }
|
||||
|
||||
void setCoords(int x, int y) { coord_x = x; coord_y = y; }
|
||||
void setName(const QString &_name) { name = _name; }
|
||||
void setCounters(int _counters) { counters = _counters; }
|
||||
void setTapped(bool _tapped) { tapped = _tapped; }
|
||||
void setAttacking(bool _attacking) { attacking = _attacking; }
|
||||
void setFaceDown(bool _facedown) { facedown = _facedown; }
|
||||
void setAnnotation(const QString &_annotation) { annotation = _annotation; }
|
||||
|
||||
void resetState();
|
||||
bool setAttribute(const QString &aname, const QString &avalue);
|
||||
};
|
||||
|
||||
#endif
|
18
servatrice/src/testrandom.cpp
Normal file
18
servatrice/src/testrandom.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "testrandom.h"
|
||||
#include <QThread>
|
||||
|
||||
void TestRandom::init()
|
||||
{
|
||||
if (initialized)
|
||||
return;
|
||||
int seed = QDateTime::currentDateTime().toTime_t();
|
||||
qDebug(QString("%1: qsrand(%2)").arg(thread()->metaObject()->className()).arg(seed).toLatin1());
|
||||
qsrand(seed);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
unsigned int TestRandom::getNumber(unsigned int min, unsigned int max)
|
||||
{
|
||||
int r = qrand();
|
||||
return min + (unsigned int) (((double) (max + 1 - min)) * r / (RAND_MAX + 1.0));
|
||||
}
|
18
servatrice/src/testrandom.h
Normal file
18
servatrice/src/testrandom.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef TESTRANDOM_H
|
||||
#define TESTRANDOM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
#include <stdlib.h>
|
||||
|
||||
class TestRandom : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
bool initialized;
|
||||
public:
|
||||
TestRandom(QObject *parent) : QObject(parent), initialized(false) { }
|
||||
void init();
|
||||
unsigned int getNumber(unsigned int min, unsigned int max);
|
||||
};
|
||||
|
||||
#endif
|
107
servatrice/src/testserver.cpp
Normal file
107
servatrice/src/testserver.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "testserver.h"
|
||||
|
||||
TestServer::TestServer(QObject *parent)
|
||||
: QTcpServer(parent)
|
||||
{
|
||||
}
|
||||
|
||||
TestServer::~TestServer()
|
||||
{
|
||||
}
|
||||
|
||||
void TestServer::gameCreated(TestServerGame *_game, TestServerSocket *_creator)
|
||||
{
|
||||
games << _game;
|
||||
_creator->moveToThread(_game->thread());
|
||||
_game->addPlayer(_creator);
|
||||
}
|
||||
|
||||
void TestServer::addGame(const QString name, const QString description, const QString password, const int maxPlayers, TestServerSocket *creator)
|
||||
{
|
||||
TestServerGameThread *newThread = new TestServerGameThread(name, description, password, maxPlayers, creator);
|
||||
connect(newThread, SIGNAL(gameCreated(TestServerGame *, TestServerSocket *)), this, SLOT(gameCreated(TestServerGame *, TestServerSocket *)));
|
||||
connect(newThread, SIGNAL(finished()), this, SLOT(gameClosed()));
|
||||
newThread->start();
|
||||
}
|
||||
|
||||
void TestServer::incomingConnection(int socketId)
|
||||
{
|
||||
TestServerSocket *socket = new TestServerSocket(this);
|
||||
socket->setSocketDescriptor(socketId);
|
||||
connect(socket, SIGNAL(createGame(const QString, const QString, const QString, const int, TestServerSocket *)), this, SLOT(addGame(const QString, const QString, const QString, const int, TestServerSocket *)));
|
||||
connect(socket, SIGNAL(joinGame(const QString, TestServerSocket *)), this, SLOT(addClientToGame(const QString, TestServerSocket *)));
|
||||
socket->initConnection();
|
||||
}
|
||||
|
||||
TestServerGame *TestServer::getGame(const QString &name)
|
||||
{
|
||||
QListIterator<TestServerGame *> i(games);
|
||||
while (i.hasNext()) {
|
||||
TestServerGame *tmp = i.next();
|
||||
if ((!tmp->name.compare(name, Qt::CaseSensitive)) && !tmp->getGameStarted())
|
||||
return tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QList<TestServerGame *> TestServer::listOpenGames()
|
||||
{
|
||||
QList<TestServerGame *> result;
|
||||
QListIterator<TestServerGame *> i(games);
|
||||
while (i.hasNext()) {
|
||||
TestServerGame *tmp = i.next();
|
||||
tmp->mutex->lock();
|
||||
if ((!tmp->getGameStarted())
|
||||
&& (tmp->getPlayerCount() < tmp->maxPlayers))
|
||||
result.append(tmp);
|
||||
tmp->mutex->unlock();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TestServer::checkGamePassword(const QString &name, const QString &password)
|
||||
{
|
||||
TestServerGame *tmp;
|
||||
if ((tmp = getGame(name))) {
|
||||
QMutexLocker locker(tmp->mutex);
|
||||
if ((!tmp->getGameStarted())
|
||||
&& (!tmp->password.compare(password, Qt::CaseSensitive))
|
||||
&& (tmp->getPlayerCount() < tmp->maxPlayers))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TestServer::addClientToGame(const QString name, TestServerSocket *client)
|
||||
{
|
||||
TestServerGame *tmp = getGame(name);
|
||||
client->moveToThread(tmp->thread());
|
||||
tmp->addPlayer(client);
|
||||
}
|
||||
|
||||
void TestServer::gameClosed()
|
||||
{
|
||||
qDebug("TestServer::gameClosed");
|
||||
TestServerGameThread *t = qobject_cast<TestServerGameThread *>(sender());
|
||||
games.removeAt(games.indexOf(t->getGame()));
|
||||
delete t;
|
||||
}
|
49
servatrice/src/testserver.h
Normal file
49
servatrice/src/testserver.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef TESTSERVER_H
|
||||
#define TESTSERVER_H
|
||||
|
||||
#include <QTcpServer>
|
||||
#include "testservergamethread.h"
|
||||
#include "testservergame.h"
|
||||
|
||||
class TestServerGame;
|
||||
class TestServerSocket;
|
||||
|
||||
class TestServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void addGame(const QString name, const QString description, const QString password, const int maxPlayers, TestServerSocket *creator);
|
||||
void addClientToGame(const QString name, TestServerSocket *client);
|
||||
void gameCreated(TestServerGame *_game, TestServerSocket *_creator);
|
||||
void gameClosed();
|
||||
public:
|
||||
TestServer(QObject *parent = 0);
|
||||
~TestServer();
|
||||
bool checkGamePassword(const QString &name, const QString &password);
|
||||
QList<TestServerGame *> listOpenGames();
|
||||
TestServerGame *getGame(const QString &name);
|
||||
private:
|
||||
void incomingConnection(int SocketId);
|
||||
QList<TestServerGame *> games;
|
||||
};
|
||||
|
||||
#endif
|
155
servatrice/src/testservergame.cpp
Normal file
155
servatrice/src/testservergame.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "testservergame.h"
|
||||
|
||||
TestServerGame::TestServerGame(QString _name, QString _description, QString _password, int _maxPlayers, QObject *parent)
|
||||
: QObject(parent), name(_name), description(_description), password(_password), maxPlayers(_maxPlayers)
|
||||
{
|
||||
gameStarted = false;
|
||||
mutex = new QMutex(QMutex::Recursive);
|
||||
rnd = NULL;
|
||||
}
|
||||
|
||||
TestServerGame::~TestServerGame()
|
||||
{
|
||||
if (rnd)
|
||||
delete rnd;
|
||||
delete mutex;
|
||||
qDebug("TestServerGame destructor");
|
||||
}
|
||||
|
||||
bool TestServerGame::getGameStarted()
|
||||
{
|
||||
return gameStarted;
|
||||
}
|
||||
|
||||
int TestServerGame::getPlayerCount()
|
||||
{
|
||||
QMutexLocker locker(mutex);
|
||||
return players.size();
|
||||
}
|
||||
|
||||
QStringList TestServerGame::getPlayerNames()
|
||||
{
|
||||
QMutexLocker locker(mutex);
|
||||
|
||||
QStringList result;
|
||||
QListIterator<TestServerSocket *> i(players);
|
||||
while (i.hasNext()) {
|
||||
TestServerSocket *tmp = i.next();
|
||||
result << QString("%1|%2").arg(tmp->getPlayerId()).arg(tmp->PlayerName);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
TestServerSocket *TestServerGame::getPlayer(int player_id)
|
||||
{
|
||||
QListIterator<TestServerSocket *> i(players);
|
||||
while (i.hasNext()) {
|
||||
TestServerSocket *tmp = i.next();
|
||||
if (tmp->getPlayerId() == player_id)
|
||||
return tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TestServerGame::msg(const QString &s)
|
||||
{
|
||||
QMutexLocker locker(mutex);
|
||||
|
||||
QListIterator<TestServerSocket *> i(players);
|
||||
while (i.hasNext())
|
||||
i.next()->msg(s);
|
||||
}
|
||||
|
||||
void TestServerGame::broadcastEvent(const QString &cmd, TestServerSocket *player)
|
||||
{
|
||||
if (player)
|
||||
msg(QString("public|%1|%2|%3").arg(player->getPlayerId()).arg(player->PlayerName).arg(cmd));
|
||||
else
|
||||
msg(QString("public|||%1").arg(cmd));
|
||||
}
|
||||
|
||||
void TestServerGame::startGameIfReady()
|
||||
{
|
||||
QMutexLocker locker(mutex);
|
||||
|
||||
if (players.size() < maxPlayers)
|
||||
return;
|
||||
for (int i = 0; i < players.size(); i++)
|
||||
if (players.at(i)->getStatus() != StatusReadyStart)
|
||||
return;
|
||||
|
||||
rnd = new TestRandom(this);
|
||||
rnd->init();
|
||||
|
||||
for (int i = 0; i < players.size(); i++)
|
||||
players.at(i)->setupZones();
|
||||
|
||||
activePlayer = 0;
|
||||
activePhase = 0;
|
||||
gameStarted = true;
|
||||
broadcastEvent("game_start", NULL);
|
||||
}
|
||||
|
||||
void TestServerGame::addPlayer(TestServerSocket *player)
|
||||
{
|
||||
QMutexLocker locker(mutex);
|
||||
|
||||
int max = -1;
|
||||
QListIterator<TestServerSocket *> i(players);
|
||||
while (i.hasNext()) {
|
||||
int tmp = i.next()->getPlayerId();
|
||||
if (tmp > max)
|
||||
max = tmp;
|
||||
}
|
||||
player->setPlayerId(max + 1);
|
||||
|
||||
player->setGame(this);
|
||||
player->msg(QString("private|||player_id|%1|%2").arg(max + 1).arg(player->PlayerName));
|
||||
broadcastEvent("join", player);
|
||||
|
||||
players << player;
|
||||
|
||||
connect(player, SIGNAL(broadcastEvent(const QString &, TestServerSocket *)), this, SLOT(broadcastEvent(const QString &, TestServerSocket *)));
|
||||
}
|
||||
|
||||
void TestServerGame::removePlayer(TestServerSocket *player)
|
||||
{
|
||||
QMutexLocker locker(mutex);
|
||||
|
||||
players.removeAt(players.indexOf(player));
|
||||
broadcastEvent("leave", player);
|
||||
if (!players.size())
|
||||
thread()->quit();
|
||||
}
|
||||
|
||||
void TestServerGame::setActivePlayer(int _activePlayer)
|
||||
{
|
||||
activePlayer = _activePlayer;
|
||||
broadcastEvent(QString("set_active_player|%1").arg(_activePlayer), NULL);
|
||||
setActivePhase(0);
|
||||
}
|
||||
|
||||
void TestServerGame::setActivePhase(int _activePhase)
|
||||
{
|
||||
activePhase = _activePhase;
|
||||
broadcastEvent(QString("set_active_phase|%1").arg(_activePhase), NULL);
|
||||
}
|
64
servatrice/src/testservergame.h
Normal file
64
servatrice/src/testservergame.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef TESTSERVERGAME_H
|
||||
#define TESTSERVERGAME_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QStringList>
|
||||
#include "testserversocket.h"
|
||||
#include "testrandom.h"
|
||||
|
||||
class TestServerSocket;
|
||||
|
||||
class TestServerGame : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QList<TestServerSocket *> players;
|
||||
bool gameStarted;
|
||||
int activePlayer;
|
||||
int activePhase;
|
||||
public slots:
|
||||
void broadcastEvent(const QString &event, TestServerSocket *player);
|
||||
public:
|
||||
QMutex *mutex;
|
||||
TestRandom *rnd;
|
||||
QString name;
|
||||
QString description;
|
||||
QString password;
|
||||
int maxPlayers;
|
||||
TestServerGame(QString _name, QString _description, QString _password, int _maxPlayers, QObject *parent = 0);
|
||||
~TestServerGame();
|
||||
bool getGameStarted();
|
||||
int getPlayerCount();
|
||||
QStringList getPlayerNames();
|
||||
TestServerSocket *getPlayer(int player_id);
|
||||
void addPlayer(TestServerSocket *player);
|
||||
void removePlayer(TestServerSocket *player);
|
||||
void startGameIfReady();
|
||||
void msg(const QString &s);
|
||||
int getActivePlayer() { return activePlayer; }
|
||||
int getActivePhase() { return activePhase; }
|
||||
void setActivePlayer(int _activePlayer);
|
||||
void setActivePhase(int _activePhase);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
20
servatrice/src/testservergamethread.cpp
Normal file
20
servatrice/src/testservergamethread.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "testservergamethread.h"
|
||||
|
||||
TestServerGameThread::TestServerGameThread(const QString _name, const QString _description, const QString _password, const int _maxPlayers, TestServerSocket *_creator, QObject *parent)
|
||||
: QThread(parent), name(_name), description(_description), password(_password), maxPlayers(_maxPlayers), creator(_creator), game(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TestServerGameThread::~TestServerGameThread()
|
||||
{
|
||||
if (game)
|
||||
delete game;
|
||||
}
|
||||
|
||||
void TestServerGameThread::run()
|
||||
{
|
||||
game = new TestServerGame(name, description, password, maxPlayers);
|
||||
emit gameCreated(game, creator);
|
||||
exec();
|
||||
}
|
30
servatrice/src/testservergamethread.h
Normal file
30
servatrice/src/testservergamethread.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef TESTSERVERGAMETHREAD_H
|
||||
#define TESTSERVERGAMETHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include "testservergame.h"
|
||||
#include "testserversocket.h"
|
||||
|
||||
class TestServerGame;
|
||||
class TestServerSocket;
|
||||
|
||||
class TestServerGameThread : public QThread {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void gameCreated(TestServerGame *_game, TestServerSocket *creator);
|
||||
private:
|
||||
QString name;
|
||||
QString description;
|
||||
QString password;
|
||||
int maxPlayers;
|
||||
TestServerSocket *creator;
|
||||
TestServerGame *game;
|
||||
public:
|
||||
TestServerGameThread(const QString _name, const QString _description, const QString _password, const int _maxPlayers, TestServerSocket *_creator, QObject *parent = 0);
|
||||
~TestServerGameThread();
|
||||
TestServerGame *getGame() { return game; }
|
||||
void run();
|
||||
};
|
||||
|
||||
#endif
|
595
servatrice/src/testserversocket.cpp
Normal file
595
servatrice/src/testserversocket.cpp
Normal file
|
@ -0,0 +1,595 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QStringList>
|
||||
#include "testserver.h"
|
||||
#include "testserversocket.h"
|
||||
#include "version.h"
|
||||
|
||||
TestServerSocket::TestServerSocket(TestServer *_server, QObject *parent)
|
||||
: QTcpSocket(parent), server(_server)
|
||||
{
|
||||
remsg = new ReturnMessage(this);
|
||||
connect(this, SIGNAL(readyRead()), this, SLOT(readClient()));
|
||||
connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
|
||||
connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(catchSocketError(QAbstractSocket::SocketError)));
|
||||
setTextModeEnabled(true);
|
||||
PlayerStatus = StatusNormal;
|
||||
game = 0;
|
||||
}
|
||||
|
||||
TestServerSocket::~TestServerSocket()
|
||||
{
|
||||
qDebug("TestServerSocket destructor");
|
||||
if (game)
|
||||
game->removePlayer(this);
|
||||
}
|
||||
|
||||
void TestServerSocket::setName(const QString &name)
|
||||
{
|
||||
emit broadcastEvent(QString("name|%1|%2").arg(PlayerName).arg(name), this);
|
||||
PlayerName = name;
|
||||
}
|
||||
|
||||
PlayerZone *TestServerSocket::getZone(const QString &name)
|
||||
{
|
||||
QListIterator<PlayerZone *> ZoneIterator(zones);
|
||||
while (ZoneIterator.hasNext()) {
|
||||
PlayerZone *temp = ZoneIterator.next();
|
||||
if (!temp->getName().compare(name))
|
||||
return temp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Counter *TestServerSocket::getCounter(const QString &name)
|
||||
{
|
||||
QListIterator<Counter *> CounterIterator(counters);
|
||||
while (CounterIterator.hasNext()) {
|
||||
Counter *temp = CounterIterator.next();
|
||||
if (!temp->getName().compare(name))
|
||||
return temp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TestServerSocket::setupZones()
|
||||
{
|
||||
// Delete existing zones and counters
|
||||
clearZones();
|
||||
|
||||
// This may need to be customized according to the game rules.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// Create zones
|
||||
PlayerZone *deck = new PlayerZone("deck", false, false, false);
|
||||
zones << deck;
|
||||
PlayerZone *sb = new PlayerZone("sb", false, false, false);
|
||||
zones << sb;
|
||||
zones << new PlayerZone("table", true, true, true);
|
||||
zones << new PlayerZone("hand", false, false, true);
|
||||
zones << new PlayerZone("grave", false, true, true);
|
||||
zones << new PlayerZone("rfg", false, true, true);
|
||||
|
||||
// Create life counter
|
||||
Counter *life = new Counter("life", 20);
|
||||
counters << life;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// Assign card ids and create deck from decklist
|
||||
QListIterator<QString> DeckIterator(DeckList);
|
||||
int i = 0;
|
||||
while (DeckIterator.hasNext())
|
||||
deck->cards.append(new TestCard(DeckIterator.next(), i++, 0, 0));
|
||||
deck->shuffle(game->rnd);
|
||||
|
||||
QListIterator<QString> SBIterator(SideboardList);
|
||||
while (SBIterator.hasNext())
|
||||
sb->cards.append(new TestCard(SBIterator.next(), i++, 0, 0));
|
||||
|
||||
nextCardId = i;
|
||||
|
||||
PlayerStatus = StatusPlaying;
|
||||
broadcastEvent(QString("setup_zones|%1|%2|%3").arg(getCounter("life")->getCount())
|
||||
.arg(deck->cards.size())
|
||||
.arg(getZone("sb")->cards.size()), this);
|
||||
}
|
||||
|
||||
void TestServerSocket::clearZones()
|
||||
{
|
||||
for (int i = 0; i < zones.size(); i++)
|
||||
delete zones.at(i);
|
||||
zones.clear();
|
||||
|
||||
for (int i = 0; i < counters.size(); i++)
|
||||
delete counters.at(i);
|
||||
counters.clear();
|
||||
}
|
||||
|
||||
void TestServerSocket::leaveGame()
|
||||
{
|
||||
if (!game)
|
||||
return;
|
||||
game->removePlayer(this);
|
||||
game = 0;
|
||||
PlayerStatus = StatusNormal;
|
||||
clearZones();
|
||||
moveToThread(server->thread());
|
||||
}
|
||||
|
||||
void TestServerSocket::readClient()
|
||||
{
|
||||
QTextStream *stream = new QTextStream(this);
|
||||
stream->setCodec("UTF-8");
|
||||
QStringList lines;
|
||||
|
||||
// Before parsing, everything has to be buffered so that the stream
|
||||
// can be deleted in order to avoid problems when moving the object
|
||||
// to another thread while this function is still running.
|
||||
for (;;) {
|
||||
QString line = stream->readLine();
|
||||
if (line.isNull())
|
||||
break;
|
||||
lines << line;
|
||||
}
|
||||
delete stream;
|
||||
|
||||
QStringListIterator i(lines);
|
||||
while (i.hasNext()) {
|
||||
QString line = i.next();
|
||||
|
||||
qDebug(QString("<<< %1").arg(line).toLatin1());
|
||||
switch (PlayerStatus) {
|
||||
case StatusNormal:
|
||||
case StatusReadyStart:
|
||||
case StatusPlaying:
|
||||
parseCommand(line);
|
||||
break;
|
||||
case StatusSubmitDeck:
|
||||
QString card = line;
|
||||
if (!card.compare(".")) {
|
||||
PlayerStatus = StatusNormal;
|
||||
remsg->send();
|
||||
} else if (card.startsWith("SB:"))
|
||||
SideboardList << card.mid(3);
|
||||
else
|
||||
DeckList << card;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TestServerSocket::parseCommand(QString line)
|
||||
{
|
||||
QStringList params = line.split("|");
|
||||
|
||||
// Extract message id
|
||||
bool conv_ok;
|
||||
int msgId = params.takeFirst().toInt(&conv_ok);
|
||||
if (!conv_ok) {
|
||||
remsg->setMsgId(0);
|
||||
return remsg->send("syntax", false);
|
||||
}
|
||||
remsg->setMsgId(msgId);
|
||||
|
||||
if (params.empty()) {
|
||||
remsg->setMsgId(0);
|
||||
return remsg->send("syntax", false);
|
||||
}
|
||||
|
||||
// Extract command
|
||||
QString cmd = params.takeFirst();
|
||||
remsg->setCmd(cmd);
|
||||
|
||||
// parse command
|
||||
|
||||
if (!cmd.compare("list_games", Qt::CaseInsensitive)) {
|
||||
remsg->send();
|
||||
QList<TestServerGame *> gameList = server->listOpenGames();
|
||||
QListIterator<TestServerGame *> gameListIterator(gameList);
|
||||
QStringList result;
|
||||
while (gameListIterator.hasNext()) {
|
||||
TestServerGame *tmp = gameListIterator.next();
|
||||
tmp->mutex->lock();
|
||||
result << QString("%1|%2|%3|%4|%5").arg(tmp->name)
|
||||
.arg(tmp->description)
|
||||
.arg(tmp->password == "" ? 0 : 1)
|
||||
.arg(tmp->getPlayerCount())
|
||||
.arg(tmp->maxPlayers);
|
||||
tmp->mutex->unlock();
|
||||
}
|
||||
remsg->sendList(result);
|
||||
} else if (!cmd.compare("create_game", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 4)
|
||||
return remsg->send("syntax", false);
|
||||
QString name = params[0];
|
||||
QString description = params[1];
|
||||
QString password = params[2];
|
||||
int maxPlayers = params[3].toInt();
|
||||
if (server->getGame(name))
|
||||
return remsg->send("name_not_found", false);
|
||||
remsg->send();
|
||||
leaveGame();
|
||||
|
||||
emit createGame(name, description, password, maxPlayers, this);
|
||||
} else if (!cmd.compare("join_game", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 2)
|
||||
return remsg->send("syntax", false);
|
||||
QString name = params[0];
|
||||
QString password = params[1];
|
||||
if (!server->checkGamePassword(name, password))
|
||||
return remsg->send("wrong_password", false);
|
||||
remsg->send();
|
||||
leaveGame();
|
||||
|
||||
emit joinGame(name, this);
|
||||
} else if (!cmd.compare("leave_game", Qt::CaseInsensitive)) {
|
||||
remsg->send();
|
||||
leaveGame();
|
||||
} else if (!cmd.compare("set_name", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
remsg->send();
|
||||
setName(params[0]);
|
||||
} else if (!cmd.compare("list_players", Qt::CaseInsensitive)) {
|
||||
if (!game)
|
||||
return remsg->send("game_state", false);
|
||||
|
||||
remsg->send();
|
||||
remsg->sendList(game->getPlayerNames());
|
||||
} else if (!cmd.compare("say", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
remsg->send();
|
||||
emit broadcastEvent(QString("say|%1").arg(params[0]), this);
|
||||
} else if (!cmd.compare("submit_deck", Qt::CaseInsensitive)) {
|
||||
PlayerStatus = StatusSubmitDeck;
|
||||
DeckList.clear();
|
||||
SideboardList.clear();
|
||||
} else if (!cmd.compare("shuffle", Qt::CaseInsensitive)) {
|
||||
if (!game)
|
||||
return remsg->send("game_state", false);
|
||||
if (!game->getGameStarted())
|
||||
return remsg->send("game_state", false);
|
||||
getZone("deck")->shuffle(game->rnd);
|
||||
remsg->send();
|
||||
emit broadcastEvent("shuffle", this);
|
||||
} else if (!cmd.compare("ready_start", Qt::CaseInsensitive)) {
|
||||
if (!game)
|
||||
return remsg->send("game_state", false);
|
||||
remsg->send();
|
||||
PlayerStatus = StatusReadyStart;
|
||||
emit broadcastEvent(QString("ready_start"), this);
|
||||
game->startGameIfReady();
|
||||
} else if (!cmd.compare("draw_cards", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int number = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
PlayerZone *deck = getZone("deck");
|
||||
PlayerZone *hand = getZone("hand");
|
||||
|
||||
if (deck->cards.size() < number)
|
||||
return remsg->send("game_state", false);
|
||||
remsg->send();
|
||||
|
||||
for (int i = 0; i < number; ++i) {
|
||||
TestCard *card = deck->cards.first();
|
||||
deck->cards.removeFirst();
|
||||
hand->cards.append(card);
|
||||
msg(QString("private|||draw|%1|%2").arg(card->getId()).arg(card->getName()));
|
||||
}
|
||||
|
||||
emit broadcastEvent(QString("draw|%1").arg(number), this);
|
||||
} else if (!cmd.compare("move_card", Qt::CaseInsensitive)) {
|
||||
// ID Karte, Startzone, Zielzone, Koordinaten X, Y
|
||||
if (params.size() != 5)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int cardid = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
PlayerZone *startzone = getZone(params[1]);
|
||||
PlayerZone *targetzone = getZone(params[2]);
|
||||
if ((!startzone) || (!targetzone))
|
||||
return remsg->send("game_state", false);
|
||||
|
||||
int position = -1;
|
||||
TestCard *card = startzone->getCard(cardid, true, &position);
|
||||
if (!card)
|
||||
return remsg->send("game_state", false);
|
||||
int x = params[3].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
int y = 0;
|
||||
if (targetzone->hasCoords()) {
|
||||
y = params[4].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
}
|
||||
targetzone->insertCard(card, x, y);
|
||||
remsg->send();
|
||||
msg(QString("private|||move_card|%1|%2|%3|%4|%5|%6|%7").arg(card->getId())
|
||||
.arg(card->getName())
|
||||
.arg(startzone->getName())
|
||||
.arg(position)
|
||||
.arg(targetzone->getName())
|
||||
.arg(x)
|
||||
.arg(y));
|
||||
// Was ist mit Facedown-Karten?
|
||||
if ((startzone->isPublic()) || (targetzone->isPublic()))
|
||||
emit broadcastEvent(QString("move_card|%1|%2|%3|%4|%5|%6|%7").arg(card->getId())
|
||||
.arg(card->getName())
|
||||
.arg(startzone->getName())
|
||||
.arg(position)
|
||||
.arg(targetzone->getName())
|
||||
.arg(x)
|
||||
.arg(y), this);
|
||||
else
|
||||
emit broadcastEvent(QString("move_card|||%1|%2|%3|%4|%5").arg(startzone->getName())
|
||||
.arg(position)
|
||||
.arg(targetzone->getName())
|
||||
.arg(x)
|
||||
.arg(y), this);
|
||||
} else if (!cmd.compare("create_token", Qt::CaseInsensitive)) {
|
||||
// zone, cardname, powtough, x, y
|
||||
// powtough wird erst mal ignoriert
|
||||
if (params.size() != 5)
|
||||
return remsg->send("syntax", false);
|
||||
PlayerZone *zone = getZone(params[0]);
|
||||
if (!zone)
|
||||
return remsg->send("game_state", false);
|
||||
QString cardname = params[1];
|
||||
int x = params[3].toInt();
|
||||
int y = params[4].toInt();
|
||||
int cardid = nextCardId++;
|
||||
QString powtough = params[2];
|
||||
|
||||
remsg->send();
|
||||
TestCard *card = new TestCard(cardname, cardid, x, y);
|
||||
zone->insertCard(card, x, y);
|
||||
emit broadcastEvent(QString("create_token|%1|%2|%3|%4|%5|%6").arg(zone->getName())
|
||||
.arg(cardid)
|
||||
.arg(cardname)
|
||||
.arg(powtough)
|
||||
.arg(x)
|
||||
.arg(y), this);
|
||||
} else if (!cmd.compare("set_card_attr", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 4)
|
||||
return remsg->send("syntax", false);
|
||||
// zone, card id, attr name, attr value
|
||||
// card id = -1 => affects all cards in the specified zone
|
||||
PlayerZone *zone = getZone(params[0]);
|
||||
if (!zone)
|
||||
return remsg->send("game_state", false);
|
||||
bool ok;
|
||||
int cardid = params[1].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
|
||||
if (cardid == -1) {
|
||||
QListIterator<TestCard *> CardIterator(zone->cards);
|
||||
while (CardIterator.hasNext())
|
||||
if (!CardIterator.next()->setAttribute(params[2], params[3]))
|
||||
return remsg->send("syntax", false);
|
||||
} else {
|
||||
TestCard *card = zone->getCard(cardid, false);
|
||||
if (!card)
|
||||
return remsg->send("game_state", false);
|
||||
if (!card->setAttribute(params[2], params[3]))
|
||||
return remsg->send("syntax", false);
|
||||
}
|
||||
remsg->send();
|
||||
emit broadcastEvent(QString("set_card_attr|%1|%2|%3|%4").arg(zone->getName()).arg(cardid).arg(params[2]).arg(params[3]), this);
|
||||
} else if (!cmd.compare("inc_counter", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 2)
|
||||
return remsg->send("syntax", false);
|
||||
Counter *c = getCounter(params[0]);
|
||||
if (!c)
|
||||
return remsg->send("game_state", false);
|
||||
bool ok;
|
||||
int delta = params[1].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
remsg->send();
|
||||
c->setCount(c->getCount() + delta);
|
||||
emit broadcastEvent(QString("set_counter|%1|%2").arg(params[0]).arg(c->getCount()), this);
|
||||
} else if (!cmd.compare("set_counter", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 2)
|
||||
return remsg->send("syntax", false);
|
||||
Counter *c = getCounter(params[0]);
|
||||
bool ok;
|
||||
int count = params[1].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
if (!c) {
|
||||
c = new Counter(params[0], count);
|
||||
counters << c;
|
||||
} else
|
||||
c->setCount(count);
|
||||
remsg->send();
|
||||
emit broadcastEvent(QString("set_counter|%1|%2").arg(params[0]).arg(count), this);
|
||||
} else if (!cmd.compare("del_counter", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
Counter *c = getCounter(params[0]);
|
||||
if (!c)
|
||||
return remsg->send("game_state", false);
|
||||
delete c;
|
||||
counters.removeAt(counters.indexOf(c));
|
||||
remsg->send();
|
||||
emit broadcastEvent(QString("del_counter|%1").arg(params[0]), this);
|
||||
} else if (!cmd.compare("list_counters", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int player_id = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
TestServerSocket *player = game->getPlayer(player_id);
|
||||
if (!player)
|
||||
return remsg->send("game_state", false);
|
||||
remsg->send();
|
||||
remsg->sendList(player->listCounters());
|
||||
} else if (!cmd.compare("list_zones", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int player_id = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
TestServerSocket *player = game->getPlayer(player_id);
|
||||
if (!player)
|
||||
return remsg->send("game_state", false);
|
||||
remsg->send();
|
||||
remsg->sendList(player->listZones());
|
||||
} else if (!cmd.compare("dump_zone", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 3)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int player_id = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
int number_cards = params[2].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
TestServerSocket *player = game->getPlayer(player_id);
|
||||
if (!player)
|
||||
return remsg->send("game_state", false);
|
||||
PlayerZone *zone = player->getZone(params[1]);
|
||||
if (!zone)
|
||||
return remsg->send("game_state", false);
|
||||
if (!(zone->isPublic() || (player_id == PlayerId)))
|
||||
return remsg->send("game_state", false);
|
||||
remsg->send();
|
||||
QListIterator<TestCard *> card_iterator(zone->cards);
|
||||
QStringList result;
|
||||
for (int i = 0; card_iterator.hasNext() && (i < number_cards || number_cards == 0); i++) {
|
||||
TestCard *tmp = card_iterator.next();
|
||||
// XXX Face down cards
|
||||
if (zone->hasIdAccess())
|
||||
result << QString("%1|%2|%3|%4|%5|%6|%7|%8").arg(tmp->getId())
|
||||
.arg(tmp->getName())
|
||||
.arg(tmp->getX())
|
||||
.arg(tmp->getY())
|
||||
.arg(tmp->getCounters())
|
||||
.arg(tmp->getTapped())
|
||||
.arg(tmp->getAttacking())
|
||||
.arg(tmp->getAnnotation());
|
||||
else
|
||||
result << QString("%1|%2||||||").arg(i).arg(tmp->getName());
|
||||
}
|
||||
remsg->sendList(result);
|
||||
emit broadcastEvent(QString("dump_zone|%1|%2|%3").arg(player_id).arg(zone->getName()).arg(number_cards), this);
|
||||
} else if (!cmd.compare("roll_dice", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int sides = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
remsg->send();
|
||||
emit broadcastEvent(QString("roll_dice|%1|%2").arg(sides).arg(game->rnd->getNumber(1, sides)), this);
|
||||
} else if (!cmd.compare("set_active_player", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int active_player = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
if (!game->getPlayer(active_player))
|
||||
return remsg->send("game_state", false);
|
||||
remsg->send();
|
||||
game->setActivePlayer(active_player);
|
||||
} else if (!cmd.compare("set_active_phase", Qt::CaseInsensitive)) {
|
||||
if (params.size() != 1)
|
||||
return remsg->send("syntax", false);
|
||||
bool ok;
|
||||
int active_phase = params[0].toInt(&ok);
|
||||
if (!ok)
|
||||
return remsg->send("syntax", false);
|
||||
// XXX Überprüfung, ob die Phase existiert...
|
||||
remsg->send();
|
||||
game->setActivePhase(active_phase);
|
||||
} else
|
||||
return remsg->send("syntax", false);
|
||||
return true;
|
||||
}
|
||||
|
||||
PlayerStatusEnum TestServerSocket::getStatus()
|
||||
{
|
||||
return PlayerStatus;
|
||||
}
|
||||
|
||||
void TestServerSocket::setStatus(PlayerStatusEnum status)
|
||||
{
|
||||
PlayerStatus = status;
|
||||
}
|
||||
|
||||
void TestServerSocket::setGame(TestServerGame *g)
|
||||
{
|
||||
game = g;
|
||||
}
|
||||
|
||||
QStringList TestServerSocket::listCounters()
|
||||
{
|
||||
QStringList counter_list;
|
||||
QListIterator<Counter *> i(counters);
|
||||
while (i.hasNext()) {
|
||||
Counter *tmp = i.next();
|
||||
counter_list << QString("%1|%2").arg(tmp->getName()).arg(tmp->getCount());
|
||||
}
|
||||
return counter_list;
|
||||
}
|
||||
|
||||
QStringList TestServerSocket::listZones()
|
||||
{
|
||||
QStringList zone_list;
|
||||
QListIterator<PlayerZone *> i(zones);
|
||||
while (i.hasNext()) {
|
||||
PlayerZone *tmp = i.next();
|
||||
zone_list << QString("%1|%2|%3|%4").arg(tmp->getName()).arg(tmp->isPublic()).arg(tmp->hasCoords()).arg(tmp->cards.size());
|
||||
}
|
||||
return zone_list;
|
||||
}
|
||||
|
||||
void TestServerSocket::msg(const QString &s)
|
||||
{
|
||||
qDebug(QString(">>> %1").arg(s).toLatin1());
|
||||
QTextStream stream(this);
|
||||
stream.setCodec("UTF-8");
|
||||
stream << s << endl;
|
||||
stream.flush();
|
||||
flush();
|
||||
}
|
||||
|
||||
void TestServerSocket::initConnection()
|
||||
{
|
||||
msg(QString("welcome||%1").arg(VERSION_STRING));
|
||||
msg("welcome||.");
|
||||
}
|
||||
|
||||
void TestServerSocket::catchSocketError(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug(QString("socket error: %1").arg(socketError).toLatin1());
|
||||
deleteLater();
|
||||
}
|
81
servatrice/src/testserversocket.h
Normal file
81
servatrice/src/testserversocket.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef TESTSERVERSOCKET_H
|
||||
#define TESTSERVERSOCKET_H
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include "testserver.h"
|
||||
#include "testservergame.h"
|
||||
#include "playerzone.h"
|
||||
#include "returnmessage.h"
|
||||
#include "counter.h"
|
||||
|
||||
class TestServer;
|
||||
class TestServerGame;
|
||||
class PlayerZone;
|
||||
|
||||
enum PlayerStatusEnum { StatusNormal, StatusSubmitDeck, StatusReadyStart, StatusPlaying };
|
||||
|
||||
class TestServerSocket : public QTcpSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void readClient();
|
||||
void catchSocketError(QAbstractSocket::SocketError socketError);
|
||||
signals:
|
||||
void createGame(const QString name, const QString description, const QString password, const int maxPlayers, TestServerSocket *creator);
|
||||
void joinGame(const QString name, TestServerSocket *player);
|
||||
void commandReceived(QString cmd, TestServerSocket *player);
|
||||
void broadcastEvent(const QString &event, TestServerSocket *player);
|
||||
void startGameIfReady();
|
||||
private:
|
||||
TestServer *server;
|
||||
TestServerGame *game;
|
||||
QList<QString> DeckList;
|
||||
QList<QString> SideboardList;
|
||||
QList<PlayerZone *> zones;
|
||||
QList<Counter *> counters;
|
||||
int PlayerId;
|
||||
int nextCardId;
|
||||
PlayerZone *getZone(const QString &name);
|
||||
Counter *getCounter(const QString &name);
|
||||
void setName(const QString &name);
|
||||
void clearZones();
|
||||
void leaveGame();
|
||||
bool parseCommand(QString line);
|
||||
PlayerStatusEnum PlayerStatus;
|
||||
ReturnMessage *remsg;
|
||||
public:
|
||||
QString PlayerName;
|
||||
TestServerSocket(TestServer *_server, QObject *parent = 0);
|
||||
~TestServerSocket();
|
||||
void msg(const QString &s);
|
||||
void setGame(TestServerGame *g);
|
||||
PlayerStatusEnum getStatus();
|
||||
void setStatus(PlayerStatusEnum status);
|
||||
void initConnection();
|
||||
int getPlayerId() { return PlayerId; }
|
||||
void setPlayerId(int _id) { PlayerId = _id; }
|
||||
QStringList listCounters();
|
||||
QStringList listZones();
|
||||
void setupZones();
|
||||
};
|
||||
|
||||
#endif
|
21
servatrice/src/version.h
Normal file
21
servatrice/src/version.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@laptop *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
const char *VERSION_STRING = "Testserver 0.20090304";
|
Loading…
Reference in a new issue