Revert the new bsonlobby.

Closes #3040.

Revert "Remove bson from project files."

This reverts commit 5c24f7b716.

Conflicts:

	lib/netplay/netlobby.h
	lib/netplay/netplay.vcxproj.filters
	src/Warzone2100.vcxproj

Revert "Merge branch 'refs/heads/topic/QJson'"

This reverts commit 6dd85baedf, reversing
changes made to 7d349eb214.

Conflicts:

	Makefile.am
	lib/netplay/netlobby.cpp
	macosx/Warzone.xcodeproj/project.pbxproj
	src/Makefile.am
Revert "Fix various build issues for both 'qtgame' and the bson /new lobby stuff"

This reverts commit f76e960f7d.

Conflicts:

	lib/framework/framework.vcxproj
	lib/gamelib/gamelib.vcxproj
	lib/gamelib/gtime.cpp
	lib/netplay/netplay.vcxproj
	lib/netplay/netplay.vcxproj.filters
	src/Warzone2100.vcxproj
	win32/Warzone2100.sln

Revert "Fix SSL errors on the Macs."

This reverts commit 4c387a199b.

Revert "Merge branch 'bsonlobby' into master"

This reverts commit 793c30a862, reversing
changes made to 5fa33b7209.

Conflicts:

	data/makefile.win32
	lib/netplay/netlobby.cpp
	lib/netplay/netlobby.h
	lib/netplay/netplay.cpp
	lib/widget/label.cpp
	macosx/Warzone.xcodeproj/project.pbxproj
	po/POTFILES.in
	src/configuration.cpp
	src/frontend.h
	src/multiint.cpp
master
vexed 2012-01-07 18:52:38 -05:00 committed by cybersphinx
parent 9cb0afa9b8
commit ac550acd58
28 changed files with 1193 additions and 1798 deletions

View File

@ -250,14 +250,6 @@ AS_IF([test "x$enable_sound" != "xyes"],[
AC_DEFINE([WZ_NOSOUND], [], [Causes sound to be disabled])
])
# Disables SSL for the Lobby
AC_ARG_ENABLE([ssl],
AS_HELP_STRING([--disable-ssl], [Disable SSL [no]]),
[ enable_ssl="${enableval}" ], [ enable_ssl="yes" ])
AS_IF([test "x$enable_ssl" != "xyes"],[
AC_DEFINE([NO_SSL], [], [Causes SSL to be disabled])
])
# -O0 turns off all optimizations; this is necessary for accurate debugging
# -Wno-unused-label is necessary because flex produces unused labels that we cannot fix
# Add later for stricter checking: -Wextra -Wmissing-declarations -Wstrict-prototypes
@ -393,8 +385,6 @@ AS_IF([test "x$enable_sound" = "xyes"],[
PKG_CHECK_MODULES([GLEW], [glew >= 1.5.2])
PKG_CHECK_MODULES([QJSON], [QJson >= 0.7.1])
# Checks for libraries:
# check for nearbyint()
@ -415,6 +405,7 @@ if test "x$host_os_mingw32" != "xyes" ; then
AC_CHECK_HEADER(X11/extensions/Xrandr.h, , AC_MSG_ERROR([Xrandr header not found.]))
fi
# Look for OpenGL
AC_CHECK_LIB(GL, main,
OPENGL_LIBS="-lGL",

View File

@ -12,8 +12,6 @@ BASELIST = \
palette.txt \
anims \
audio \
cacert.org-root.pem \
cacert.org-class3.pem \
challenges \
components \
effects \

View File

@ -1,35 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIGCDCCA/CgAwIBAgIBATANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
Y2FjZXJ0Lm9yZzAeFw0wNTEwMTQwNzM2NTVaFw0zMzAzMjgwNzM2NTVaMFQxFDAS
BgNVBAoTC0NBY2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5v
cmcxHDAaBgNVBAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCrSTURSHzSJn5TlM9Dqd0o10Iqi/OHeBlYfA+e2ol9
4fvrcpANdKGWZKufoCSZc9riVXbHF3v1BKxGuMO+f2SNEGwk82GcwPKQ+lHm9WkB
Y8MPVuJKQs/iRIwlKKjFeQl9RrmK8+nzNCkIReQcn8uUBByBqBSzmGXEQ+xOgo0J
0b2qW42S0OzekMV/CsLj6+YxWl50PpczWejDAz1gM7/30W9HxM3uYoNSbi4ImqTZ
FRiRpoWSR7CuSOtttyHshRpocjWr//AQXcD0lKdq1TuSfkyQBX6TwSyLpI5idBVx
bgtxA+qvFTia1NIFcm+M+SvrWnIl+TlG43IbPgTDZCciECqKT1inA62+tC4T7V2q
SNfVfdQqe1z6RgRQ5MwOQluM7dvyz/yWk+DbETZUYjQ4jwxgmzuXVjit89Jbi6Bb
6k6WuHzX1aCGcEDTkSm3ojyt9Yy7zxqSiuQ0e8DYbF/pCsLDpyCaWt8sXVJcukfV
m+8kKHA4IC/VfynAskEDaJLM4JzMl0tF7zoQCqtwOpiVcK01seqFK6QcgCExqa5g
eoAmSAC4AcCTY1UikTxW56/bOiXzjzFU6iaLgVn5odFTEcV7nQP2dBHgbbEsPyyG
kZlxmqZ3izRg0RS0LKydr4wQ05/EavhvE/xzWfdmQnQeiuP43NJvmJzLR5iVQAX7
6QIDAQABo4G/MIG8MA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUHAQEEUTBPMCMG
CCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggrBgEFBQcwAoYc
aHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBBMD8GCCsGAQQB
gZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZy9pbmRleC5w
aHA/aWQ9MTAwDQYJKoZIhvcNAQEEBQADggIBAH8IiKHaGlBJ2on7oQhy84r3HsQ6
tHlbIDCxRd7CXdNlafHCXVRUPIVfuXtCkcKZ/RtRm6tGpaEQU55tiKxzbiwzpvD0
nuB1wT6IRanhZkP+VlrRekF490DaSjrxC1uluxYG5sLnk7mFTZdPsR44Q4Dvmw2M
77inYACHV30eRBzLI++bPJmdr7UpHEV5FpZNJ23xHGzDwlVks7wU4vOkHx4y/CcV
Bc/dLq4+gmF78CEQGPZE6lM5+dzQmiDgxrvgu1pPxJnIB721vaLbLmINQjRBvP+L
ivVRIqqIMADisNS8vmW61QNXeZvo3MhN+FDtkaVSKKKs+zZYPumUK5FQhxvWXtaM
zPcPEAxSTtAWYeXlCmy/F8dyRlecmPVsYGN6b165Ti/Iubm7aoW8mA3t+T6XhDSU
rgCvoeXnkm5OvfPi2RSLXNLrAWygF6UtEOucekq9ve7O/e0iQKtwOIj1CodqwqsF
YMlIBdpTwd5Ed2qz8zw87YC8pjhKKSRf/lk7myV6VmMAZLldpGJ9VzZPrYPvH5JT
oI53V93lYRE9IwCQTDz6o2CTBKOvNfYOao9PSmCnhQVsRqGP9Md246FZV/dxssRu
FFxtbUFm3xuTsdQAw+7Lzzw9IYCpX2Nl/N3gX6T0K/CFcUHUZyX7GrGXrtaZghNB
0m6lG5kngOcLqagA
-----END CERTIFICATE-----

View File

@ -1,76 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIGCDCCA/CgAwIBAgIBATANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
Y2FjZXJ0Lm9yZzAeFw0wNTEwMTQwNzM2NTVaFw0zMzAzMjgwNzM2NTVaMFQxFDAS
BgNVBAoTC0NBY2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5v
cmcxHDAaBgNVBAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCrSTURSHzSJn5TlM9Dqd0o10Iqi/OHeBlYfA+e2ol9
4fvrcpANdKGWZKufoCSZc9riVXbHF3v1BKxGuMO+f2SNEGwk82GcwPKQ+lHm9WkB
Y8MPVuJKQs/iRIwlKKjFeQl9RrmK8+nzNCkIReQcn8uUBByBqBSzmGXEQ+xOgo0J
0b2qW42S0OzekMV/CsLj6+YxWl50PpczWejDAz1gM7/30W9HxM3uYoNSbi4ImqTZ
FRiRpoWSR7CuSOtttyHshRpocjWr//AQXcD0lKdq1TuSfkyQBX6TwSyLpI5idBVx
bgtxA+qvFTia1NIFcm+M+SvrWnIl+TlG43IbPgTDZCciECqKT1inA62+tC4T7V2q
SNfVfdQqe1z6RgRQ5MwOQluM7dvyz/yWk+DbETZUYjQ4jwxgmzuXVjit89Jbi6Bb
6k6WuHzX1aCGcEDTkSm3ojyt9Yy7zxqSiuQ0e8DYbF/pCsLDpyCaWt8sXVJcukfV
m+8kKHA4IC/VfynAskEDaJLM4JzMl0tF7zoQCqtwOpiVcK01seqFK6QcgCExqa5g
eoAmSAC4AcCTY1UikTxW56/bOiXzjzFU6iaLgVn5odFTEcV7nQP2dBHgbbEsPyyG
kZlxmqZ3izRg0RS0LKydr4wQ05/EavhvE/xzWfdmQnQeiuP43NJvmJzLR5iVQAX7
6QIDAQABo4G/MIG8MA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUHAQEEUTBPMCMG
CCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggrBgEFBQcwAoYc
aHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBBMD8GCCsGAQQB
gZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZy9pbmRleC5w
aHA/aWQ9MTAwDQYJKoZIhvcNAQEEBQADggIBAH8IiKHaGlBJ2on7oQhy84r3HsQ6
tHlbIDCxRd7CXdNlafHCXVRUPIVfuXtCkcKZ/RtRm6tGpaEQU55tiKxzbiwzpvD0
nuB1wT6IRanhZkP+VlrRekF490DaSjrxC1uluxYG5sLnk7mFTZdPsR44Q4Dvmw2M
77inYACHV30eRBzLI++bPJmdr7UpHEV5FpZNJ23xHGzDwlVks7wU4vOkHx4y/CcV
Bc/dLq4+gmF78CEQGPZE6lM5+dzQmiDgxrvgu1pPxJnIB721vaLbLmINQjRBvP+L
ivVRIqqIMADisNS8vmW61QNXeZvo3MhN+FDtkaVSKKKs+zZYPumUK5FQhxvWXtaM
zPcPEAxSTtAWYeXlCmy/F8dyRlecmPVsYGN6b165Ti/Iubm7aoW8mA3t+T6XhDSU
rgCvoeXnkm5OvfPi2RSLXNLrAWygF6UtEOucekq9ve7O/e0iQKtwOIj1CodqwqsF
YMlIBdpTwd5Ed2qz8zw87YC8pjhKKSRf/lk7myV6VmMAZLldpGJ9VzZPrYPvH5JT
oI53V93lYRE9IwCQTDz6o2CTBKOvNfYOao9PSmCnhQVsRqGP9Md246FZV/dxssRu
FFxtbUFm3xuTsdQAw+7Lzzw9IYCpX2Nl/N3gX6T0K/CFcUHUZyX7GrGXrtaZghNB
0m6lG5kngOcLqagA
-----END CERTIFICATE-----

View File

@ -91,7 +91,6 @@ static const char *code_part_names[] = {
"input",
"popup",
"console",
"lobby",
"last"
};

View File

@ -181,7 +181,6 @@ enum code_part
LOG_INPUT, // mouse / keyboard events
LOG_POPUP, // special, on by default, for both debug & release builds (used for OS dependent popup code)
LOG_CONSOLE, // send console messages to file
LOG_LOBBY,
LOG_LAST /**< _must_ be last! */
};

View File

@ -10,7 +10,6 @@ endif
noinst_LIBRARIES = libnetplay.a
noinst_HEADERS = \
netlobby.h \
netlog.h \
netplay.h \
netqueue.h \
@ -18,9 +17,9 @@ noinst_HEADERS = \
nettypes.h
libnetplay_a_SOURCES = \
netsocket.cpp \
netlobby.cpp \
netjoin_stub.cpp \
netlog.cpp \
netplay.cpp \
netqueue.cpp \
netsocket.cpp \
nettypes.cpp

View File

@ -0,0 +1,34 @@
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2011 Warzone 2100 Project
Warzone 2100 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.
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Net join.
* join related stuff
*/
#include "lib/framework/frame.h"
#include "netplay.h"
int32_t NETgetGameFlagsUnjoined(unsigned int gameid, unsigned int flag)
{
ASSERT(gameid < ARRAY_SIZE(NetPlay.games), "Out of range gameid: %u", gameid);
ASSERT(flag < ARRAY_SIZE(NetPlay.games[gameid].desc.dwUserFlags), "Out of range flag number: %u", flag);
return NetPlay.games[gameid].desc.dwUserFlags[flag];
}

View File

@ -1,617 +0,0 @@
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2011 Warzone 2100 Project
Warzone 2100 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.
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// Qt Core
#include <QtCore/QtEndian>
#include <QtCore/QFile>
// Debugging normaly commented.
// #include <QtCore/QDebug>
// QT Network
#include <QtNetwork/QSslCertificate>
// QJson
#include <qjson/parser.h>
#include <qjson/serializer.h>
// Self
#include "netlobby.h"
namespace Lobby
{
Client::Client()
{
// Set defaults
gameId_ = 0;
lastError_.code = LOBBY_NO_ERROR;
isAuthenticated_ = false;
useSSL_ = false;
useAuth_ = false;
}
void Client::stop()
{
debug(LOG_LOBBY, "Stopping");
// remove the game from the masterserver,
delGame();
freeError();
// and disconnect.
disconnect();
delete socket_;
}
RETURN_CODES Client::addGame(char** result, const uint32_t port, const uint32_t maxPlayers,
const char* description, const char* versionstring,
const uint32_t game_version_major, const uint32_t game_version_minor,
const bool isPrivate, const char* modlist,
const char* mapname, const char* hostplayer)
{
if (gameId_ != 0)
{
// Ignore server errors here.
if (delGame() != LOBBY_NO_ERROR)
{
freeError();
}
}
QVariantMap kwargs;
kwargs.insert("port", port);
kwargs.insert("description", description);
kwargs.insert("currentPlayers", 1);
kwargs.insert("maxPlayers", maxPlayers);
kwargs.insert("multiVer", versionstring);
kwargs.insert("wzVerMajor", game_version_major);
kwargs.insert("wzVerMinor", game_version_minor);
kwargs.insert("private", isPrivate);
kwargs.insert("modlist", modlist);
kwargs.insert("mapname", mapname);
kwargs.insert("hostplayer", hostplayer);
if (call_("addGame", kwargs) != LOBBY_NO_ERROR)
{
return lastError_.code;
}
QVariantMap resultMap = callResult_.result.toMap();
if (!resultMap.contains("gameId") || !resultMap.contains("result"))
{
freeCallResult_();
return setError_(INVALID_DATA, _("Received invalid addGame data."));
}
gameId_ = resultMap["gameId"].toLongLong();
asprintfNull(result, resultMap["result"].toString().toUtf8().constData());
freeCallResult_();
return LOBBY_NO_ERROR;
}
RETURN_CODES Client::delGame()
{
if (gameId_ == 0)
{
return LOBBY_NO_ERROR;
}
QVariantMap kwargs;
kwargs.insert("gameId", gameId_);
if (call_("delGame", kwargs) != LOBBY_NO_ERROR)
{
// Ignore a server side error and unset the local game.
gameId_ = 0;
return lastError_.code;
}
gameId_ = 0;
freeCallResult_();
return LOBBY_NO_ERROR;
}
RETURN_CODES Client::addPlayer(const unsigned int index, const char* name,
const char* username, const char* session)
{
if (gameId_ == 0 || gameId_ == -1)
{
return setError_(NO_GAME, _("Create a game first!"));
}
QVariantMap kwargs;
kwargs.insert("gameId", gameId_);
kwargs.insert("slot", index);
kwargs.insert("name", name);
kwargs.insert("username", username);
kwargs.insert("session", session);
if (call_("addPlayer", kwargs) != LOBBY_NO_ERROR)
{
return lastError_.code;
}
freeCallResult_();
return LOBBY_NO_ERROR;
}
RETURN_CODES Client::delPlayer(const unsigned int index)
{
if (gameId_ == 0 || gameId_ == -1)
{
return setError_(NO_GAME, _("Create a game first!"));
}
QVariantMap kwargs;
kwargs.insert("gameId", gameId_);
kwargs.insert("slot", index);
if (call_("delPlayer", kwargs) != LOBBY_NO_ERROR)
{
return lastError_.code;
}
freeCallResult_();
return LOBBY_NO_ERROR;
}
RETURN_CODES Client::updatePlayer(const unsigned int index, const char* name)
{
if (gameId_ == 0 || gameId_ == -1)
{
return setError_(NO_GAME, _("Create a game first!"));
}
QVariantMap kwargs;
kwargs.insert("gameId", gameId_);
kwargs.insert("slot", index);
kwargs.insert("name", name);
if (call_("updatePlayer", kwargs) != LOBBY_NO_ERROR)
{
return lastError_.code;
}
freeCallResult_();
return LOBBY_NO_ERROR;
}
RETURN_CODES Client::listGames(const int maxGames)
{
uint32_t gameCount = 0;
GAME game;
// Clear old games.
games.clear();
// Run "list" and retrieve its result
if (call_("list") != LOBBY_NO_ERROR)
return lastError_.code;
QVariantList resultList = callResult_.result.toList();
for (int i = 0; i < resultList.size() && gameCount < maxGames; ++i)
{
// FIXME: should clear "game"" here or initialize a new one each loop.
QVariantMap rawGame = resultList.at(i).toMap();
if (rawGame.contains("port"))
{
game.port = rawGame["port"].toInt();
}
if (rawGame.contains("host"))
{
game.host = rawGame["host"].toString().toStdString();
}
if (rawGame.contains("description"))
{
game.description = rawGame["description"].toString().toStdString();
}
if (rawGame.contains("currentPlayers"))
{
game.currentPlayers = rawGame["currentPlayers"].toInt();
}
if (rawGame.contains("maxPlayers"))
{
game.maxPlayers = rawGame["maxPlayers"].toInt();
}
if (rawGame.contains("multiVer"))
{
game.versionstring = rawGame["multiVer"].toString().toStdString();
}
if (rawGame.contains("wzVerMajor"))
{
game.game_version_major = rawGame["wzVerMajor"].toInt();
}
if (rawGame.contains("wzVerMinor"))
{
game.game_version_minor = rawGame["wzVerMinor"].toInt();
}
if (rawGame.contains("isPrivate"))
{
game.isPrivate = rawGame["isPrivate"].toInt();
}
if (rawGame.contains("modlist"))
{
game.modlist = rawGame["modlist"].toInt();
}
if (rawGame.contains("mapname"))
{
game.mapname = rawGame["mapname"].toString().toStdString();
}
if (rawGame.contains("hostplayer"))
{
game.hostplayer = rawGame["hostplayer"].toString().toStdString();
}
games.append(game);
gameCount++;
}
freeCallResult_();
return LOBBY_NO_ERROR;
}
inline bool Client::isConnected()
{
return (socket_ && socket_->state() == QAbstractSocket::ConnectedState);
}
Client& Client::addCACertificate(const QString& path)
{
#if defined(NO_SSL)
debug(LOG_LOBBY, "Cannot add an SSL Certificate as SSL is not compiled in.");
return *this;
#else
debug(LOG_LOBBY, "Adding the CA certificate %s.", path.toUtf8().constData());
QFile cafile(path);
if (!cafile.open(QIODevice::ReadOnly | QIODevice::Text))
{
debug(LOG_ERROR, "Cannot open the CA certificate %s!", path.toUtf8().constData());
return *this;
}
QSslCertificate certificate(&cafile, QSsl::Pem);
if (!certificate.isValid())
{
debug(LOG_ERROR, "Failed to load the CA certificate %s!", path.toUtf8().constData());
return *this;
}
cafile.close();
debug(LOG_LOBBY, "Cert common name: %s", certificate.subjectInfo(QSslCertificate::CommonName).toUtf8().constData());
cacerts_.append(certificate);
return *this;
#endif
}
RETURN_CODES Client::connect()
{
if (isConnected())
{
return LOBBY_NO_ERROR;
}
isAuthenticated_ = false;
callId_ = 0;
#if defined(NO_SSL)
socket_ = new QTcpSocket();
socket_->connectToHost(host_, port_);
#else
socket_ = new QSslSocket();
// Connect
if (useSSL_ == false)
{
debug(LOG_LOBBY, "Connecting to \"[%s]:%d\".", host_.toUtf8().constData(), port_);
socket_->connectToHost(host_, port_);
}
else
{
debug(LOG_LOBBY, "Connecting to \"[%s]:%d\" with SSL enabled.", host_.toUtf8().constData(), port_);
socket_->setCaCertificates(cacerts_);
socket_->connectToHostEncrypted(host_, port_);
}
#endif
#if defined(NO_SSL)
if (!socket_->waitForConnected())
{
#else
if ((useSSL_ && !socket_->waitForEncrypted())
|| (!useSSL_ && !socket_->waitForConnected()))
{
#endif
debug(LOG_ERROR, "Cannot connect to lobby \"[%s]:%d\": %s.",
host_.toUtf8().constData(), port_, socket_->errorString().toUtf8().constData());
return setError_(TRANSPORT_ERROR, "");
}
// Build the initial version command.
uchar buf[sizeof(qint32)] = { "\0" };
qToBigEndian<qint32>(PROTOCOL, buf);
QByteArray version;
version.append("version", sizeof("version"));
version.append((char *)buf, sizeof(buf));
// Send Version command
if (socket_->write(version) == -1)
{
debug(LOG_ERROR, "Cannot send version string to lobby \"%s:%d\": %s",
host_.toUtf8().constData(), port_, socket_->errorString().toUtf8().constData());
return setError_(TRANSPORT_ERROR, "");
}
// At last try to login
return login("");
}
RETURN_CODES Client::login(const QString& password)
{
if (isAuthenticated_ == true)
{
return LOBBY_NO_ERROR;
}
else if (useAuth_ == false)
{
debug(LOG_LOBBY, "Authentication is disabled.");
return LOBBY_NO_ERROR;
}
QVariantMap kwargs;
kwargs.insert("username", user_);
if (!token_.isEmpty())
{
kwargs.insert("token", token_);
}
else if (!password.isEmpty())
{
token_.clear();
kwargs.insert("password", password);
}
else
{
debug(LOG_LOBBY, "Not trying to login no password/token supplied.");
// Do not return an error for internal use.
return LOBBY_NO_ERROR;
}
if (call_("login", kwargs) != LOBBY_NO_ERROR)
{
// Reset login credentials on a wrong login
if (lastError_.code == WRONG_LOGIN)
{
debug(LOG_LOBBY, "Login failed!");
token_.clear();
session_.clear();
isAuthenticated_ = false;
}
return lastError_.code;
}
token_.clear();
session_.clear();
QVariantMap resultMap = callResult_.result.toMap();
if (!resultMap.contains("token") || !resultMap.contains("session"))
{
debug(LOG_LOBBY, "Login failed!");
freeCallResult_();
return setError_(INVALID_DATA, _("Received invalid login data."));
}
token_ = resultMap["token"].toString();
session_ = resultMap["session"].toString();
debug(LOG_LOBBY, "Received Session \"%s\"", session_.toUtf8().constData());
isAuthenticated_ = true;
freeCallResult_();
return LOBBY_NO_ERROR;
}
RETURN_CODES Client::logout()
{
// Remove a maybe hosted game.
if (delGame() != LOBBY_NO_ERROR)
{
freeError();
}
// Tell the lobby that we want to logout.
if (call_("logout") != LOBBY_NO_ERROR)
{
return lastError_.code;
}
// Clear auth data.
isAuthenticated_ = false;
user_.clear();
token_.clear();
session_.clear();
freeCallResult_();
return LOBBY_NO_ERROR;
}
bool Client::disconnect()
{
if (!isConnected())
{
return true;
}
socket_->close();
// Rest call id.
callId_ = 0;
// clear/free up games,
games.clear();
// clear auth data,
session_.clear();
isAuthenticated_ = false;
return true;
}
RETURN_CODES Client::call_(const char* command, const QVariantMap& kwargs)
{
// Connect to the lobby
if (isConnected() != true && connect() != LOBBY_NO_ERROR)
{
return lastError_.code;
}
debug(LOG_LOBBY, "Calling \"%s\" on the lobby", command);
callId_ += 1;
QVariantList callArgs;
callArgs << command << QVariantMap() << kwargs << callId_;
QVariantMap call;
call.insert("call", callArgs);
// Debug - needs QtCore/QDebug
//qDebug() << call;
QJson::Serializer serializer;
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out.setByteOrder(QDataStream::BigEndian);
out << serializer.serialize(call);
if (socket_->write(block) == -1)
{
debug(LOG_ERROR, "Failed sending command \"%s\" to the lobby: %s.",
command, socket_->errorString().toUtf8().constData());
return setError_(TRANSPORT_ERROR, _("Failed to communicate with the lobby."));
}
quint32 blockSize;
QDataStream in(socket_);
in.setVersion(QDataStream::Qt_4_0);
in.setByteOrder(QDataStream::BigEndian);
while (socket_->bytesAvailable() < sizeof(quint16))
{
if (!socket_->waitForReadyRead())
{
debug(LOG_ERROR, "Failed reading the results size for \"%s\" from the lobby: %s.",
command, socket_->errorString().toUtf8().constData());
return setError_(TRANSPORT_ERROR, _("Failed to communicate with the lobby."));
}
in >> blockSize;
while (socket_->bytesAvailable() < blockSize)
{
if (!socket_->waitForReadyRead())
{
debug(LOG_ERROR, "Failed reading the result for \"%s\" from the lobby: %s.",
command, socket_->errorString().toUtf8().constData());
return setError_(TRANSPORT_ERROR, _("Failed to communicate with the lobby."));
}
}
}
// FIXME: Lots copying here.
char* buffer = new char[blockSize];
in.readRawData(buffer, blockSize); // needed for "\0".
QByteArray jsonData(buffer, blockSize);
delete buffer;
QJson::Parser parser;
bool ok;
QVariantMap result = parser.parse(jsonData, &ok).toMap();
if (!ok)
{
debug(LOG_ERROR, "Received an invalid JSON Object, line %d, error: %s",
parser.errorLine(), parser.errorString().toUtf8().constData());
return setError_(INVALID_DATA, _("Failed to communicate with the lobby."));
}
// Debug - needs QtCore/QDebug
// qDebug() << result;
if (!result.contains("reply"))
{
debug(LOG_ERROR, "%s", "Received an invalid answer, no \"reply\" received.");
return setError_(INVALID_DATA, _("Failed to communicate with the lobby."));
}
QVariantList resultList = result["reply"].toList();
if (!resultList.size() == 3)
{
debug(LOG_ERROR,
"Received an invalid Answer %d number of list args instead of 3",
resultList.size());
return setError_(INVALID_DATA, _("Failed to communicate with the lobby."));
}
if (resultList.at(0).toInt() != LOBBY_NO_ERROR)
{
debug(LOG_LOBBY,
"Received: server error %d: %s",
resultList.at(0).toInt(),
resultList.at(1).toString().toUtf8().constData());
setError_(callResult_.code,
_("Got server error: %s"),
resultList.at(1).toString().toUtf8().constData());
return lastError_.code;
}
callResult_.code = (RETURN_CODES)resultList.at(0).toInt();
callResult_.result = resultList.at(1);
return LOBBY_NO_ERROR;
}
RETURN_CODES Client::setError_(const RETURN_CODES code, const char* message, ...)
{
char *buff;
va_list ap;
va_start(ap, message);
vasprintfNull(&buff, message, ap);
va_end(ap);
lastError_.code = code;
lastError_.message = buff;
free(buff);
return code;
}
} // namespace Lobby

View File

@ -1,248 +0,0 @@
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2011 Warzone 2100 Project
Warzone 2100 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.
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _netlobby_h
#define _netlobby_h
#if defined(_MSC_VER) && defined(NO_SSL)
#pragma message ("Note: openSSL is needed for SSL")
#endif
#if defined(NO_SSL)
#include <QtNetwork/QTcpSocket>
#else
#include <QtNetwork/QSslSocket>
#endif
#include <QtCore/QVariant>
#include "lib/framework/frame.h"
namespace Lobby
{
const qint32 PROTOCOL = 4;
/* NOTE: You also need to change this value in the
* masterservers settings - session_size!
*/
const int SESSION_SIZE = 16+1;
/* We limit usernames here to 40 chars,
* while the forums allows usernames with up to 255 characters.
*/
const int USERNAME_SIZE = 40+1;
enum RETURN_CODES
{
LOBBY_NO_ERROR = 0,
// Copied from XMLRPC for socketrpc
PARSE_ERROR = -32700,
SERVER_ERROR = -32600,
APPLICATION_ERROR = -32500,
TRANSPORT_ERROR = -32300,
// Specific errors.
UNSUPPORTED_ENCODING = -32701,
METHOD_NOT_FOUND = -32601,
// Custom error codes.
INVALID_DATA = -500,
LOGIN_REQUIRED = -405,
WRONG_LOGIN = -404,
NOT_ACCEPTABLE = -403,
NO_GAME = -402,
};
// FIXME: Not sure if std::string is a good idea here,
// as multiint is passing them to iV_DrawText.
struct GAME
{
uint32_t port; ///< Port hosting on.
std::string host; ///< IPv4, IPv6 or DNS Name of the host.
std::string description; ///< Game Description.
uint32_t currentPlayers; ///< Number of joined players.
uint32_t maxPlayers; ///< Maximum number of players.
std::string versionstring; ///< Version string.
uint32_t game_version_major; ///< Minor NETCODE version.
uint32_t game_version_minor; ///< Major NETCODE version.
bool isPrivate; ///< Password protected?
std::string modlist; ///< display string for mods.
std::string mapname; ///< name of map hosted.
std::string hostplayer; ///< hosts playername.
};
struct LOBBY_ERROR
{
RETURN_CODES code;
QString message;
};
struct CALL_RESULT
{
RETURN_CODES code;
QVariant result;
};
class Client {
public:
QList<GAME> games;
Client();
void stop();
RETURN_CODES connect();
bool disconnect();
bool isConnected();
RETURN_CODES login(const QString& password);
RETURN_CODES logout();
RETURN_CODES addGame(char** result, const uint32_t port, const uint32_t maxPlayers,
const char* description, const char* versionstring,
const uint32_t game_version_major, const uint32_t game_version_minor,
const bool isPrivate, const char* modlist,
const char* mapname, const char* hostplayer);
RETURN_CODES delGame();
RETURN_CODES addPlayer(const unsigned int index, const char* name, const char* username, const char* session);
RETURN_CODES delPlayer(const unsigned int index);
RETURN_CODES updatePlayer(const unsigned int index, const char* name);
RETURN_CODES listGames(const int maxGames);
Client& addCACertificate(const QString& path);
bool useSSL() {
return useSSL_;
}
bool useSSL(bool useSSL)
{
#if defined(NO_SSL)
if (useSSL == true)
{
debug(LOG_ERROR, "Cannot use SSL as its not compiled in.");
}
return false;
#else
useSSL_ = useSSL;
useAuth_ = useSSL;
return useSSL_;
#endif
}
bool useAuth() {
return useAuth_;
}
Client& setHost(const QString& host) {
host_ = host;
return *this;
}
QString getHost() const {
return host_;
}
Client& setPort(const quint16& port) {
port_ = port;
return *this;
}
quint16 getPort() {
return port_;
}
bool isAuthenticated() {
return isAuthenticated_;
}
bool hasAuthData() {
return (!user_.isEmpty() && !token_.isEmpty());
}
Client& setUser(const QString& user) {
user_ = user;
return *this;
}
QString getUser() const {
return user_;
}
Client& setToken(const QString& token) {
token_ = token;
return *this;
}
QString getToken() {
return token_;
}
QString getSession() const {
return session_;
}
LOBBY_ERROR* getError() {
return &lastError_;
}
void freeError()
{
lastError_.code = LOBBY_NO_ERROR;
lastError_.message.clear();
}
private:
qint64 gameId_;
qint64 callId_;
bool useSSL_;
#if !defined(NO_SSL)
QList<QSslCertificate> cacerts_;
#endif
bool useAuth_;
QString host_;
quint16 port_;
QString user_;
QString token_;
QString session_;
#if defined(NO_SSL)
QTcpSocket *socket_;
#else
QSslSocket *socket_;
#endif
bool isAuthenticated_;
LOBBY_ERROR lastError_;
CALL_RESULT callResult_;
RETURN_CODES call_(const char* command, const QVariantMap& kwargs = QVariantMap());
void freeCallResult_()
{
callResult_.code = LOBBY_NO_ERROR;
callResult_.result.clear();
}
RETURN_CODES setError_(const RETURN_CODES code, const char * message, ...);
}; // class Client
} // namespace Lobby
#endif // #ifndef _netlobby_h

View File

@ -57,7 +57,8 @@
#endif //WZ_OS_LINUX
// WARNING !!! This is initialised via configuration.c !!!
static unsigned int gameserver_port = 0;
char masterserver_name[255] = {'\0'};
static unsigned int masterserver_port = 0, gameserver_port = 0;
#define NET_TIMEOUT_DELAY 2500 // we wait this amount of time for socket activity
#define NET_READ_TIMEOUT 0
@ -75,6 +76,7 @@ static unsigned int gameserver_port = 0;
// Function prototypes
static void NETplayerLeaving(UDWORD player); // Cleanup sockets on player leaving (nicely)
static void NETplayerDropped(UDWORD player); // Broadcast NET_PLAYER_DROPPED & cleanup
static void NETregisterServer(int state);
static void NETallowJoining(void);
static void recvDebugSync(NETQUEUE queue);
static bool onBanList(const char *ip);
@ -108,6 +110,8 @@ struct NET_PLAYER_DATA
NETPLAY NetPlay;
PLAYER_IP *IPlist = NULL;
static bool allow_joining = false;
static bool server_not_there = false;
static GAMESTRUCT gamestruct;
// update flags
bool netPlayersUpdated;
@ -116,9 +120,10 @@ int mapDownloadProgress;
/**
* Socket used for these purposes:
* * Host a game, be a server.
* * Connect to the lobby server.
* * Join a server for a game.
*/
static Socket* tcp_socket = NULL; //socket used to talk to host machine
static Socket* tcp_socket = NULL; //socket used to talk to lobbyserver/ host machine
static Socket *bsocket = NULL; //buffered socket (holds tcp_socket) (clients only?)
static Socket *connected_bsocket[MAX_CONNECTED_PLAYERS] = { NULL };
@ -156,9 +161,6 @@ static char const *versionString = "version_getVersionString()";
static int NETCODE_VERSION_MAJOR = 5;
static int NETCODE_VERSION_MINOR = 1;
// The Lobby Client - declared external in netplay.h
Lobby::Client lobbyclient;
bool NETisCorrectVersion(uint32_t game_version_major, uint32_t game_version_minor)
{
return (NETCODE_VERSION_MAJOR == game_version_major && NETCODE_VERSION_MINOR == game_version_minor);
@ -167,6 +169,7 @@ bool NETisCorrectVersion(uint32_t game_version_major, uint32_t game_version_mino
void NETGameLocked( bool flag)
{
NetPlay.GamePassworded = flag;
gamestruct.privateGame = flag;
NETlogEntry("Password is", SYNC_FLAG, NetPlay.GamePassworded);
debug(LOG_NET, "Passworded game is %s", NetPlay.GamePassworded ? "TRUE" : "FALSE" );
}
@ -387,12 +390,12 @@ static void NET_DestroyPlayer(unsigned int index)
{
NetPlay.players[index].allocated = false;
NetPlay.playercount--;
// Inform the masterserver.
gamestruct.desc.dwCurrentPlayers = NetPlay.playercount;
if (allow_joining && NetPlay.isHost)
{
lobbyclient.delPlayer(index);
lobbyclient.freeError();
// Update player count in the lobby by disconnecting
// and reconnecting
NETregisterServer(2);
}
}
NET_InitPlayer(index, false); // reinitialize
@ -495,13 +498,6 @@ bool NETchangePlayerName(UDWORD index, char *newName)
sstrcpy(NetPlay.players[0].name, newName);
return true;
}
if (NetPlay.isHost && allow_joining)
{
lobbyclient.updatePlayer(index, newName);
lobbyclient.freeError();
}
debug(LOG_NET, "Requesting a change of player name for pid=%u to %s", index, newName);
NETlogEntry("Player wants a name change.", SYNC_FLAG, index);
sstrcpy(NetPlay.players[index].name, newName);
@ -600,6 +596,285 @@ bool NETsetGameFlags(UDWORD flag, SDWORD value)
return true;
}
/**
* @note \c game is being sent to the master server (if hosting)
* The implementation of NETsendGAMESTRUCT <em>must</em> guarantee to
* pack it in network byte order (big-endian).
*
* @return true on success, false when a socket error has occurred
*
* @see GAMESTRUCT,NETrecvGAMESTRUCT
*/
static bool NETsendGAMESTRUCT(Socket* sock, const GAMESTRUCT* ourgamestruct)
{
// A buffer that's guaranteed to have the correct size (i.e. it
// circumvents struct padding, which could pose a problem). Initialise
// to zero so that we can be sure we're not sending any (undefined)
// memory content across the network.
char buf[sizeof(ourgamestruct->GAMESTRUCT_VERSION) + sizeof(ourgamestruct->name) + sizeof(ourgamestruct->desc.host) + (sizeof(int32_t) * 8) +
sizeof(ourgamestruct->secondaryHosts) + sizeof(ourgamestruct->extra) + sizeof(ourgamestruct->mapname) + sizeof(ourgamestruct->hostname) + sizeof(ourgamestruct->versionstring) +
sizeof(ourgamestruct->modlist) + (sizeof(uint32_t) * 9) ] = { 0 };
char *buffer = buf;
unsigned int i;
ssize_t result;
// Now dump the data into the buffer
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->GAMESTRUCT_VERSION);
buffer += sizeof(uint32_t);
// Copy a string
strlcpy(buffer, ourgamestruct->name, sizeof(ourgamestruct->name));
buffer += sizeof(ourgamestruct->name);
// Copy 32bit large big endian numbers
*(int32_t*)buffer = htonl(ourgamestruct->desc.dwSize);
buffer += sizeof(int32_t);
*(int32_t*)buffer = htonl(ourgamestruct->desc.dwFlags);
buffer += sizeof(int32_t);
// Copy yet another string
strlcpy(buffer, ourgamestruct->desc.host, sizeof(ourgamestruct->desc.host));
buffer += sizeof(ourgamestruct->desc.host);
// Copy 32bit large big endian numbers
*(int32_t*)buffer = htonl(ourgamestruct->desc.dwMaxPlayers);
buffer += sizeof(int32_t);
*(int32_t*)buffer = htonl(ourgamestruct->desc.dwCurrentPlayers);
buffer += sizeof(int32_t);
for (i = 0; i < ARRAY_SIZE(ourgamestruct->desc.dwUserFlags); ++i)
{
*(int32_t*)buffer = htonl(ourgamestruct->desc.dwUserFlags[i]);
buffer += sizeof(int32_t);
}
// Copy a string
for (i = 0; i <ARRAY_SIZE(ourgamestruct->secondaryHosts); ++i)
{
strlcpy(buffer, ourgamestruct->secondaryHosts[i], sizeof(ourgamestruct->secondaryHosts[i]));
buffer += sizeof(ourgamestruct->secondaryHosts[i]);
}
// Copy a string
strlcpy(buffer, ourgamestruct->extra, sizeof(ourgamestruct->extra));
buffer += sizeof(ourgamestruct->extra);
// Copy a string
strlcpy(buffer, ourgamestruct->mapname, sizeof(ourgamestruct->mapname));
buffer += sizeof(ourgamestruct->mapname);
// Copy a string
strlcpy(buffer, ourgamestruct->hostname, sizeof(ourgamestruct->hostname));
buffer += sizeof(ourgamestruct->hostname);
// Copy a string
strlcpy(buffer, ourgamestruct->versionstring, sizeof(ourgamestruct->versionstring));
buffer += sizeof(ourgamestruct->versionstring);
// Copy a string
strlcpy(buffer, ourgamestruct->modlist, sizeof(ourgamestruct->modlist));
buffer += sizeof(ourgamestruct->modlist);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->game_version_major);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->game_version_minor);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->privateGame);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->pureGame);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->Mods);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->gameId);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->future2);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->future3);
buffer += sizeof(uint32_t);
// Copy 32bit large big endian numbers
*(uint32_t*)buffer = htonl(ourgamestruct->future4);
buffer += sizeof(uint32_t);
debug(LOG_NET, "sending GAMESTRUCT, size: %u", (unsigned int)sizeof(buf));
// Send over the GAMESTRUCT
result = writeAll(sock, buf, sizeof(buf));
if (result == SOCKET_ERROR)
{
const int err = getSockErr();
// If packet could not be sent, we should inform user of the error.
debug(LOG_ERROR, "Failed to send GAMESTRUCT. Reason: %s", strSockError(getSockErr()));
debug(LOG_ERROR, "Please make sure TCP ports %u & %u are open!", masterserver_port, gameserver_port);
setSockErr(err);
return false;
}
return true;
}
/**
* @note \c game is being retrieved from the master server (if browsing the
* lobby). The implementation of NETrecvGAMESTRUCT should assume the data
* to be packed in network byte order (big-endian).
*
* @see GAMESTRUCT,NETsendGAMESTRUCT
*/
static bool NETrecvGAMESTRUCT(GAMESTRUCT* ourgamestruct)
{
// A buffer that's guaranteed to have the correct size (i.e. it
// circumvents struct padding, which could pose a problem).
char buf[sizeof(ourgamestruct->GAMESTRUCT_VERSION) + sizeof(ourgamestruct->name) + sizeof(ourgamestruct->desc.host) + (sizeof(int32_t) * 8) +
sizeof(ourgamestruct->secondaryHosts) + sizeof(ourgamestruct->extra) + sizeof(ourgamestruct->mapname) + sizeof(ourgamestruct->hostname) + sizeof(ourgamestruct->versionstring) +
sizeof(ourgamestruct->modlist) + (sizeof(uint32_t) * 9) ] = { 0 };
char* buffer = buf;
unsigned int i;
ssize_t result = 0;
// Read a GAMESTRUCT from the connection
if (tcp_socket == NULL
|| socket_set == NULL
|| checkSockets(socket_set, NET_TIMEOUT_DELAY) <= 0
|| !socketReadReady(tcp_socket)
|| (result = readNoInt(tcp_socket, buf, sizeof(buf))) != sizeof(buf))
{
unsigned int time = wzGetTicks();
if (result == SOCKET_ERROR)
{
debug(LOG_ERROR, "Server socket (%p) ecountered error: %s", tcp_socket, strSockError(getSockErr()));
SocketSet_DelSocket(socket_set, tcp_socket); // mark it invalid
socketClose(tcp_socket);
tcp_socket = NULL;
return false;
}
i = result;
while (i < sizeof(buf) && wzGetTicks() < time + 2500)
{
result = readNoInt(tcp_socket, buf+i, sizeof(buf)-i);
if (result == SOCKET_ERROR
|| (result == 0 && socketReadDisconnected(tcp_socket)))
{
debug(LOG_ERROR, "Server socket (%p) ecountered error: %s", tcp_socket, strSockError(getSockErr()));
debug(LOG_ERROR, "GAMESTRUCT recv failed; received %u bytes out of %d", i, (int)sizeof(buf));
SocketSet_DelSocket(socket_set, tcp_socket); // mark it invalid
socketClose(tcp_socket);
tcp_socket = NULL;
return false;
}
i += result;
}
if (i != sizeof(buf))
{
debug(LOG_ERROR, "GAMESTRUCT recv size mismatch; received %u bytes; expecting %d", i, (int)sizeof(buf));
return false;
}
}
// Now dump the data into the game struct
// Copy 32bit large big endian numbers
ourgamestruct->GAMESTRUCT_VERSION = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
// Copy a string
sstrcpy(ourgamestruct->name, buffer);
buffer += sizeof(ourgamestruct->name);
// Copy 32bit large big endian numbers
ourgamestruct->desc.dwSize = ntohl(*(int32_t*)buffer);
buffer += sizeof(int32_t);
ourgamestruct->desc.dwFlags = ntohl(*(int32_t*)buffer);
buffer += sizeof(int32_t);
// Copy yet another string
sstrcpy(ourgamestruct->desc.host, buffer);
buffer += sizeof(ourgamestruct->desc.host);
// Copy 32bit large big endian numbers
ourgamestruct->desc.dwMaxPlayers = ntohl(*(int32_t*)buffer);
buffer += sizeof(int32_t);
ourgamestruct->desc.dwCurrentPlayers = ntohl(*(int32_t*)buffer);
buffer += sizeof(int32_t);
for (i = 0; i < ARRAY_SIZE(ourgamestruct->desc.dwUserFlags); ++i)
{
ourgamestruct->desc.dwUserFlags[i] = ntohl(*(int32_t*)buffer);
buffer += sizeof(int32_t);
}
// Copy a string
for (i = 0; i < ARRAY_SIZE(ourgamestruct->secondaryHosts); ++i)
{
sstrcpy(ourgamestruct->secondaryHosts[i], buffer);
buffer += sizeof(ourgamestruct->secondaryHosts[i]);
}
// Copy a string
sstrcpy(ourgamestruct->extra, buffer);
buffer += sizeof(ourgamestruct->extra);
// Copy a string
sstrcpy(ourgamestruct->mapname, buffer);
buffer += sizeof(ourgamestruct->mapname);
// Copy a string
sstrcpy(ourgamestruct->hostname, buffer);
buffer += sizeof(ourgamestruct->hostname);
// Copy a string
sstrcpy(ourgamestruct->versionstring, buffer);
buffer += sizeof(ourgamestruct->versionstring);
// Copy a string
sstrcpy(ourgamestruct->modlist, buffer);
buffer += sizeof(ourgamestruct->modlist);
// Copy 32bit large big endian numbers
ourgamestruct->game_version_major = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->game_version_minor = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->privateGame = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->pureGame = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->Mods = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->gameId = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->future2 = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->future3 = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
ourgamestruct->future4 = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
// cat the modstring (if there is one) to the version string to display it for the end-user
if (ourgamestruct->modlist[0] != '\0')
{
ssprintf(ourgamestruct->versionstring, "%s, Mods:%s", ourgamestruct->versionstring, ourgamestruct->modlist);
}
debug(LOG_NET, "received GAMESTRUCT");
return true;
}
static int upnp_init(void *asdf)
{
struct UPNPDev *devlist;
@ -736,22 +1011,22 @@ int NETinit(bool bFirstCall)
{
debug(LOG_NET, "NETPLAY: Init called, MORNIN'");
memset(&NetPlay.games, 0, sizeof(NetPlay.games));
// NOTE NetPlay.isUPNP is already set in configuration.c!
NetPlay.bComms = true;
NetPlay.GamePassworded = false;
NetPlay.ShowedMOTD = false;
NetPlay.isHostAlive = false;
NetPlay.gamePassword[0] = '\0';
NetPlay.MOTD = strdup("");
sstrcpy(NetPlay.gamePassword,_("Enter password here"));
NETstartLogging();
}
NetPlay.ShowedMOTD = false;
NetPlay.GamePassworded = false;
memset(&sync_counter, 0x0, sizeof(sync_counter)); //clear counters
// Add the certificate.
lobbyclient.addCACertificate("wz::cacert.org-root.pem");
lobbyclient.addCACertificate("wz::cacert.org-class3.pem");
return 0;
}
@ -762,10 +1037,6 @@ int NETshutdown(void)
{
debug( LOG_NET, "NETshutdown" );
NETlogEntry("NETshutdown", SYNC_FLAG, selectedPlayer);
// Stop the lobbyclient.
lobbyclient.stop();
NETstopLogging();
if (IPlist)
free(IPlist);
@ -787,11 +1058,13 @@ int NETclose(void)
unsigned int i;
// reset flag
NetPlay.ShowedMOTD = false;
NEThaltJoining();
debug(LOG_NET, "Terminating sockets.");
NetPlay.isHost = false;
server_not_there = false;
allow_joining = false;
if(bsocket)
@ -1652,6 +1925,183 @@ UBYTE NETrecvFile(NETQUEUE queue)
return ((currPos + bytesToRead) * 100) / fileSize;
}
static ssize_t readLobbyResponse(Socket* sock, unsigned int timeout)
{
uint32_t lobbyStatusCode;
uint32_t MOTDLength;
uint32_t buffer[2];
ssize_t result, received = 0;
// Get status and message length
result = readAll(sock, &buffer, sizeof(buffer), timeout);
if (result != sizeof(buffer))
goto error;
received += result;
lobbyStatusCode = ntohl(buffer[0]);
MOTDLength = ntohl(buffer[1]);
// Get status message
free(NetPlay.MOTD);
NetPlay.MOTD = (char *)malloc(MOTDLength + 1);
result = readAll(sock, NetPlay.MOTD, MOTDLength, timeout);
if (result != MOTDLength)
goto error;
received += result;
// NUL terminate string
NetPlay.MOTD[MOTDLength] = '\0';
if (lobbyStatusCode / 100 != 2) // Check whether status code is 2xx (success)
{
debug(LOG_ERROR, "Lobby error (%u): %s", (unsigned int)lobbyStatusCode, NetPlay.MOTD);
return received;
}
debug(LOG_NET, "Lobby success (%u): %s", (unsigned int)lobbyStatusCode, NetPlay.MOTD);
return received;
error:
if (result == SOCKET_ERROR)
{
free(NetPlay.MOTD);
if (asprintf(&NetPlay.MOTD, "Error while connecting to the lobby server: %s\nMake sure port %d can receive incoming connections.", strSockError(getSockErr()), gameserver_port) == -1)
NetPlay.MOTD = NULL;
debug(LOG_ERROR, "%s", NetPlay.MOTD);
}
else
{
free(NetPlay.MOTD);
if (asprintf(&NetPlay.MOTD, "Disconnected from lobby server. Failed to register game.") == -1)
NetPlay.MOTD = NULL;
debug(LOG_ERROR, "%s", NetPlay.MOTD);
}
return SOCKET_ERROR;
}
static void NETregisterServer(int state)
{
static Socket* rs_socket = NULL;
static int registered = 0;
if (server_not_there)
{
return;
}
if (state != registered)
{
switch(state)
{
// Update player counts
case 2:
{
if (!NETsendGAMESTRUCT(rs_socket, &gamestruct))
{
socketClose(rs_socket);
rs_socket = NULL;
}
}
break;
// Register a game with the lobby
case 1:
{
uint32_t gameId = 0;
SocketAddress *const hosts = resolveHost(masterserver_name, masterserver_port);
if (hosts == NULL)
{
debug(LOG_ERROR, "Cannot resolve masterserver \"%s\": %s", masterserver_name, strSockError(getSockErr()));
free(NetPlay.MOTD);
if (asprintf(&NetPlay.MOTD, _("Could not resolve masterserver name (%s)!"), masterserver_name) == -1)
NetPlay.MOTD = NULL;
server_not_there = true;
return;
}
// Close an existing socket.
if (rs_socket != NULL)
{
socketClose(rs_socket);
rs_socket = NULL;
}
// try each address from resolveHost until we successfully connect.
rs_socket = socketOpenAny(hosts, 1500);
deleteSocketAddress(hosts);
// No address succeeded.
if (rs_socket == NULL)
{
debug(LOG_ERROR, "Cannot connect to masterserver \"%s:%d\": %s", masterserver_name, masterserver_port, strSockError(getSockErr()));
free(NetPlay.MOTD);
if (asprintf(&NetPlay.MOTD, _("Could not communicate with lobby server! Is TCP port %u open for outgoing traffic?"), masterserver_port) == -1)
NetPlay.MOTD = NULL;
server_not_there = true;
return;
}
// Get a game ID
if (writeAll(rs_socket, "gaId", sizeof("gaId")) == SOCKET_ERROR
|| readAll(rs_socket, &gameId, sizeof(gameId), 10000) != sizeof(gameId))
{
free(NetPlay.MOTD);
if (asprintf(&NetPlay.MOTD, "Failed to retrieve a game ID: %s", strSockError(getSockErr())) == -1)
NetPlay.MOTD = NULL;
debug(LOG_ERROR, "%s", NetPlay.MOTD);
// The socket has been invalidated, so get rid of it. (using them now may cause SIGPIPE).
socketClose(rs_socket);
rs_socket = NULL;
server_not_there = true;
return;
}
gamestruct.gameId = ntohl(gameId);
debug(LOG_NET, "Using game ID: %u", (unsigned int)gamestruct.gameId);
// Register our game with the server
if (writeAll(rs_socket, "addg", sizeof("addg")) == SOCKET_ERROR
// and now send what the server wants
|| !NETsendGAMESTRUCT(rs_socket, &gamestruct))
{
debug(LOG_ERROR, "Failed to register game with server: %s", strSockError(getSockErr()));
socketClose(rs_socket);
rs_socket = NULL;
}
if (readLobbyResponse(rs_socket, NET_TIMEOUT_DELAY) == SOCKET_ERROR)
{
socketClose(rs_socket);
rs_socket = NULL;
return;
}
// Preserves another register
registered=state;
}
break;
// Unregister the game (close the socket)
case 0:
{
if (rs_socket != NULL)
{
// we don't need this anymore, so clean up
socketClose(rs_socket);
rs_socket = NULL;
server_not_there = true;
}
// Preserves another unregister
registered=state;
}
break;
}
}
}
// ////////////////////////////////////////////////////////////////////////
// Host a game with a given name and player name. & 4 user game flags
static void NETallowJoining(void)
@ -1666,6 +2116,16 @@ static void NETallowJoining(void)
if (allow_joining == false) return;
ASSERT(NetPlay.isHost, "Cannot receive joins if not host!");
NETregisterServer(1);
// This is here since we need to get the status, before we can show the info.
// FIXME: find better location to stick this?
if (!NetPlay.ShowedMOTD)
{
ShowMOTD();
NetPlay.ShowedMOTD = true;
}
if (tmp_socket_set == NULL)
{
// initialize server socket set
@ -1741,7 +2201,7 @@ static void NETallowJoining(void)
else
{
// Commented out as each masterserver check creates an error.
// debug(LOG_ERROR, "Received an invalid version \"%d.%d\".", major, minor);
debug(LOG_ERROR, "Received an invalid version \"%d.%d\".", major, minor);
result = htonl(ERROR_WRONGVERSION);
memcpy(&buffer, &result, sizeof(result));
writeAll(tmp_socket[i], &buffer, sizeof(result));
@ -1805,15 +2265,10 @@ static void NETallowJoining(void)
char ModList[modlist_string_size] = { '\0' };
char GamePassword[password_string_size] = { '\0' };
char *username = (char *)malloc(Lobby::USERNAME_SIZE);
char *session = (char *)malloc(Lobby::SESSION_SIZE);
NETbeginDecode(NETnetTmpQueue(i), NET_JOIN);
NETstring(name, sizeof(name));
NETstring(ModList, sizeof(ModList));
NETstring(GamePassword, sizeof(GamePassword));
NETstring(username, Lobby::USERNAME_SIZE);
NETstring(session, Lobby::SESSION_SIZE);
NETend();
tmp = NET_CreatePlayer(name);
@ -1864,7 +2319,7 @@ static void NETallowJoining(void)
// Wrong password. Reject.
rejected = (uint8_t)ERROR_WRONGPASSWORD;
}
else if ((int)NetPlay.playercount > NetPlay.maxPlayers)
else if ((int)NetPlay.playercount > gamestruct.desc.dwMaxPlayers)
{
// Game full. Reject.
rejected = (uint8_t)ERROR_FULL;
@ -1875,20 +2330,6 @@ static void NETallowJoining(void)
rejected = (uint8_t)ERROR_WRONGDATA;
}
// Now add the player to the lobbyserver if he isn't rejected
// and we are authenticated.
if (rejected == 0 && lobbyclient.isAuthenticated())
{
if (lobbyclient.addPlayer(index, name, username, session) != Lobby::LOBBY_NO_ERROR)
{
debug(LOG_INFO, "Lobby rejected player \"%s\", username \"%s\", session \"%s\", reason: %s",
name, username, session, lobbyclient.getError()->message.toUtf8().constData());
lobbyclient.freeError();
// Lobby didn't accept the player, Reject.
rejected = (uint8_t)ERROR_LOBBY_REJECTED;
}
}
if (rejected)
{
debug(LOG_INFO, "Rejecting new player, reason (%u).", (unsigned int) rejected);
@ -1924,6 +2365,9 @@ static void NETallowJoining(void)
debug(LOG_NET, "Player, %s, with index of %u has joined using socket %p", name, (unsigned int)index, connected_bsocket[index]);
// Increment player count
gamestruct.desc.dwCurrentPlayers++;
MultiPlayerJoin(index);
// Narrowcast to new player that everyone has joined.
@ -1951,6 +2395,10 @@ static void NETallowJoining(void)
}
NETfixDuplicatePlayerNames();
// Send the updated GAMESTRUCT to the masterserver
NETregisterServer(2);
// reset flags for new players
NetPlay.players[index].wzFile.isCancelled = false;
NetPlay.players[index].wzFile.isSending = false;
@ -1966,8 +2414,6 @@ bool NEThostGame(const char* SessionName, const char* PlayerName,
UDWORD plyrs) // # of players.
{
unsigned int i;
char* motd;
char* modlist;
debug(LOG_NET, "NEThostGame(%s, %s, %d, %d, %d, %d, %u)", SessionName, PlayerName,
one, two, three, four, plyrs);
@ -2020,14 +2466,40 @@ bool NEThostGame(const char* SessionName, const char* PlayerName,
}
NetPlay.isHost = true;
// FIXME: Is this the right place for this?
NetPlay.maxPlayers = plyrs;
NETlogEntry("Hosting game, resetting ban list.", SYNC_FLAG, 0);
if (IPlist)
{
free(IPlist);
IPlist = NULL;
}
sstrcpy(gamestruct.name, SessionName);
memset(&gamestruct.desc, 0, sizeof(gamestruct.desc));
gamestruct.desc.dwSize = sizeof(gamestruct.desc);
//gamestruct.desc.guidApplication = GAME_GUID;
memset(gamestruct.desc.host, 0, sizeof(gamestruct.desc.host));
gamestruct.desc.dwCurrentPlayers = 1;
gamestruct.desc.dwMaxPlayers = plyrs;
gamestruct.desc.dwFlags = 0;
gamestruct.desc.dwUserFlags[0] = one;
gamestruct.desc.dwUserFlags[1] = two;
gamestruct.desc.dwUserFlags[2] = three;
gamestruct.desc.dwUserFlags[3] = four;
memset(gamestruct.secondaryHosts, 0, sizeof(gamestruct.secondaryHosts));
sstrcpy(gamestruct.extra, "Extra"); // extra string (future use)
sstrcpy(gamestruct.mapname, game.map); // map we are hosting
sstrcpy(gamestruct.hostname, PlayerName);
sstrcpy(gamestruct.versionstring, versionString); // version (string)
sstrcpy(gamestruct.modlist, getModList()); // List of mods
gamestruct.GAMESTRUCT_VERSION = 3; // version of this structure
gamestruct.game_version_major = NETCODE_VERSION_MAJOR; // Netcode Major version
gamestruct.game_version_minor = NETCODE_VERSION_MINOR; // NetCode Minor version
// gamestruct.privateGame = 0; // if true, it is a private game
gamestruct.pureGame = 0; // NO mods allowed if true
gamestruct.Mods = 0; // number of concatenated mods?
gamestruct.gameId = 0;
gamestruct.future2 = 0xBAD02; // for future use
gamestruct.future3 = 0xBAD03; // for future use
gamestruct.future4 = 0xBAD04; // for future use
selectedPlayer= NET_CreatePlayer(PlayerName);
realSelectedPlayer = selectedPlayer;
@ -2044,45 +2516,10 @@ bool NEThostGame(const char* SessionName, const char* PlayerName,
changeColour(NET_HOST_ONLY, war_GetSPcolor());
}
// remove an existing game from the masterserver.
lobbyclient.delGame();
lobbyclient.freeError();
modlist = getModList();
std::string fullVersionString = versionString;
if (fullVersionString == "version_getVersionString()")
{
fullVersionString = version_getVersionString();
}
// Register the game on the masterserver
if (lobbyclient.addGame(&motd, (uint32_t)gameserver_port, (uint32_t)NetPlay.maxPlayers,
SessionName, fullVersionString.c_str(), NETCODE_VERSION_MAJOR, NETCODE_VERSION_MINOR,
NetPlay.GamePassworded, modlist, game.map, PlayerName) != Lobby::LOBBY_NO_ERROR)
{
Lobby::LOBBY_ERROR* error = lobbyclient.getError();
if (error->code == Lobby::LOGIN_REQUIRED)
{
asprintfNull(&motd, _("Game not in the lobby, please login first!"));
}
else
{
asprintfNull(&motd,
_("Error connecting to the lobby server: %s. Make sure port %d can receive incoming connections. If you're using a router configure it to use UPnP, or to forward the port to your system."),
lobbyclient.getHost().toUtf8().constData(),
gameserver_port
);
}
lobbyclient.freeError();
}
// Show the MOTD
showMOTD(motd);
free(motd);
allow_joining = true;
NETregisterServer(0);
debug(LOG_NET, "Hosting a server. We are player %d.", selectedPlayer);
return true;
@ -2095,46 +2532,137 @@ bool NEThaltJoining(void)
debug(LOG_NET, "temporarily locking game to prevent more players");
allow_joining = false;
if (lobbyclient.delGame() != Lobby::LOBBY_NO_ERROR)
{
lobbyclient.freeError();
}
// disconnect from the master server
NETregisterServer(0);
return true;
}
// ////////////////////////////////////////////////////////////////////////
// find games on open connection
bool NETfindGame(const int maxGames)
bool NETfindGame(void)
{
SocketAddress* hosts;
unsigned int gamecount = 0;
uint32_t gamesavailable;
int result = 0;
debug(LOG_NET, "Looking for games...");
if (getLobbyError() == ERROR_CHEAT || getLobbyError() == ERROR_KICKED)
{
return false;
}
setLobbyError(ERROR_NOERROR);
if (lobbyclient.listGames(maxGames) != Lobby::LOBBY_NO_ERROR)
NetPlay.games[0].desc.dwSize = 0;
NetPlay.games[0].desc.dwCurrentPlayers = 0;
NetPlay.games[0].desc.dwMaxPlayers = 0;
if(!NetPlay.bComms)
{
debug(LOG_ERROR, lobbyclient.getError()->message.toUtf8().constData());
if (lobbyclient.getError()->code == Lobby::LOGIN_REQUIRED)
selectedPlayer = NET_HOST_ONLY; // Host is always 0
NetPlay.isHost = true;
NetPlay.hostPlayer = NET_HOST_ONLY;
return true;
}
if ((hosts = resolveHost(masterserver_name, masterserver_port)) == NULL)
{
setLobbyError(ERROR_AUTHENTICATION);
debug(LOG_ERROR, "Cannot resolve hostname \"%s\": %s", masterserver_name, strSockError(getSockErr()));
setLobbyError(ERROR_CONNECTION);
return false;
}
if (tcp_socket != NULL)
{
debug(LOG_NET, "Deleting tcp_socket %p", tcp_socket);
if (socket_set)
{
SocketSet_DelSocket(socket_set, tcp_socket);
}
socketClose(tcp_socket);
tcp_socket = NULL;
}
tcp_socket = socketOpenAny(hosts, 15000);
deleteSocketAddress(hosts);
hosts = NULL;
if (tcp_socket == NULL)
{
debug(LOG_ERROR, "Cannot connect to \"%s:%d\": %s", masterserver_name, masterserver_port, strSockError(getSockErr()));
setLobbyError(ERROR_CONNECTION);
return false;
}
debug(LOG_NET, "New tcp_socket = %p", tcp_socket);
// client machines only need 1 socket set
socket_set = allocSocketSet();
if (socket_set == NULL)
{
debug(LOG_ERROR, "Cannot create socket set: %s", strSockError(getSockErr()));
setLobbyError(ERROR_CONNECTION);
return false;
}
debug(LOG_NET, "Created socket_set %p", socket_set);
SocketSet_AddSocket(socket_set, tcp_socket);
debug(LOG_NET, "Sending list cmd");
if (writeAll(tcp_socket, "list", sizeof("list")) != SOCKET_ERROR
&& checkSockets(socket_set, NET_TIMEOUT_DELAY) > 0
&& socketReadReady(tcp_socket)
&& (result = readNoInt(tcp_socket, &gamesavailable, sizeof(gamesavailable))))
{
gamesavailable = MIN(ntohl(gamesavailable), ARRAY_SIZE(NetPlay.games));
}
else
{
setLobbyError(ERROR_CONNECTION);
if (result == SOCKET_ERROR)
{
debug(LOG_NET, "Server socket ecountered error: %s", strSockError(getSockErr()));
}
lobbyclient.freeError();
else
{
debug(LOG_NET, "Server didn't respond (timeout)");
}
SocketSet_DelSocket(socket_set, tcp_socket); // mark it invalid
socketClose(tcp_socket);
tcp_socket = NULL;
// when we fail to receive a game count, bail out
setLobbyError(ERROR_CONNECTION);
return false;
}
debug(LOG_NET, "receiving info on %u game(s)", (unsigned int)gamesavailable);
// Clear old games from list.
memset(NetPlay.games, 0x00, sizeof(NetPlay.games));
while (gamecount < gamesavailable)
{
// Attempt to receive a game description structure
if (!NETrecvGAMESTRUCT(&NetPlay.games[gamecount]))
{
debug(LOG_NET, "only %u game(s) received", (unsigned int)gamecount);
// If we fail, success depends on the amount of games that we've read already
return gamecount;
}
if (NetPlay.games[gamecount].desc.host[0] == '\0')
{
strncpy(NetPlay.games[gamecount].desc.host, getSocketTextAddress(tcp_socket), sizeof(NetPlay.games[gamecount].desc.host));
}
++gamecount;
}
return true;
}
// ////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////
// Functions used to setup and join games.
// does setLobbyError on errors.
bool NETjoinGame(const char* host, uint32_t port, const char* playername)
{
SocketAddress *hosts = NULL;
@ -2223,25 +2751,12 @@ bool NETjoinGame(const char* host, uint32_t port, const char* playername)
bsocket = tcp_socket;
socketBeginCompression(bsocket);
char *username = (char *)malloc(Lobby::USERNAME_SIZE);
char *session = (char *)malloc(Lobby::SESSION_SIZE);
strlcpy(username, lobbyclient.getUser().toUtf8().constData(), Lobby::USERNAME_SIZE);
strlcpy(session, lobbyclient.getSession().toUtf8().constData(), Lobby::SESSION_SIZE);
debug(LOG_NET, "Sending username \"%s\", session \"%s\"", username, lobbyclient.getSession().toUtf8().constData());
// Send a join message to the host
NETbeginEncode(NETnetQueue(NET_HOST_ONLY), NET_JOIN);
NETstring(playername, 64);
NETstring(getModList(), modlist_string_size);
NETstring(NetPlay.gamePassword, sizeof(NetPlay.gamePassword));
NETstring(username, Lobby::USERNAME_SIZE);
NETstring(session, Lobby::SESSION_SIZE);
NETend();
free(username);
free(session);
if (bsocket == NULL)
{
return false; // Connection dropped while sending NET_JOIN.
@ -2315,6 +2830,40 @@ bool NETjoinGame(const char* host, uint32_t port, const char* playername)
}
}
/*!
* Set the masterserver name
* \param hostname The hostname of the masterserver to connect to
*/
void NETsetMasterserverName(const char* hostname)
{
sstrcpy(masterserver_name, hostname);
}
/**
* @return The hostname of the masterserver we will connect to.
*/
const char* NETgetMasterserverName()
{
return masterserver_name;
}
/*!
* Set the masterserver port
* \param port The port of the masterserver to connect to
*/
void NETsetMasterserverPort(unsigned int port)
{
masterserver_port = port;
}
/**
* @return The port of the masterserver we will connect to.
*/
unsigned int NETgetMasterserverPort()
{
return masterserver_port;
}
/*!
* Set the port we shall host games on
* \param port The port to listen to

View File

@ -27,7 +27,6 @@
#define _netplay_h
#include "nettypes.h"
#include "netlobby.h"
#include <physfs.h>
// Lobby Connection errors
@ -43,9 +42,7 @@ enum LOBBY_ERROR_TYPES
ERROR_WRONGPASSWORD,
ERROR_HOSTDROPPED,
ERROR_WRONGDATA,
ERROR_UNKNOWNFILEISSUE,
ERROR_AUTHENTICATION,
ERROR_LOBBY_REJECTED
ERROR_UNKNOWNFILEISSUE
};
enum CONNECTION_STATUS
@ -131,15 +128,61 @@ enum MESSAGE_TYPES
// @NOTE / FIXME: We need a way to detect what should happen if the msg buffer exceeds this.
#define MaxMsgSize 16384 // max size of a message in bytes.
#define StringSize 64 // size of strings used.
#define MaxGames 18 // max number of concurrently playable games to allow.
#define extra_string_size 159 // extra 199 char for future use
#define map_string_size 40
#define hostname_string_size 40
#define modlist_string_size 255 // For a concatenated list of mods
#define password_string_size 64 // longer passwords slow down the join code
#define SESSION_JOINDISABLED 1
#define MAX_CONNECTED_PLAYERS MAX_PLAYERS
#define MAX_TMP_SOCKETS 16
struct SESSIONDESC //Available game storage... JUST FOR REFERENCE!
{
int32_t dwSize;
int32_t dwFlags;
char host[40]; // host's ip address (can fit a full IPv4 and IPv6 address + terminating NUL)
int32_t dwMaxPlayers;
int32_t dwCurrentPlayers;
int32_t dwUserFlags[4];
};
/**
* @note when changing this structure, NETsendGAMESTRUCT, NETrecvGAMESTRUCT and
* the lobby server should be changed accordingly.
*/
struct GAMESTRUCT
{
/* Version of this structure and thus the binary lobby protocol.
* @NOTE: <em>MUST</em> be the first item of this struct.
*/
uint32_t GAMESTRUCT_VERSION;
char name[StringSize];
SESSIONDESC desc;
// END of old GAMESTRUCT format
// NOTE: do NOT save the following items in game.c--it will break savegames.
char secondaryHosts[2][40];
char extra[extra_string_size]; // extra string (future use)
char mapname[map_string_size]; // map server is hosting
char hostname[hostname_string_size]; // ...
char versionstring[StringSize]; //
char modlist[modlist_string_size]; // ???
uint32_t game_version_major; //
uint32_t game_version_minor; //
uint32_t privateGame; // if true, it is a private game
uint32_t pureGame; // NO mods allowed if true
uint32_t Mods; // number of concatenated mods?
// Game ID, used on the lobby server to link games with multiple address families to eachother
uint32_t gameId;
uint32_t future2; // for future use
uint32_t future3; // for future use
uint32_t future4; // for future use
};
// ////////////////////////////////////////////////////////////////////////
// Message information. ie. the packets sent between machines.
@ -222,8 +265,8 @@ struct PLAYER
// all the luvly Netplay info....
struct NETPLAY
{
GAMESTRUCT games[MaxGames]; ///< The collection of games
PLAYER players[MAX_PLAYERS]; ///< The array of players.
uint32_t maxPlayers; ///< Maximum number of players.
uint32_t playercount; ///< Number of players in game.
uint32_t hostPlayer; ///< Index of host in player array
uint32_t bComms; ///< Actually do the comms?
@ -233,6 +276,9 @@ struct NETPLAY
PHYSFS_file *pMapFileHandle;
char gamePassword[password_string_size]; //
bool GamePassworded; // if we have a password or not.
bool ShowedMOTD; // only want to show this once
char MOTDbuffer[255]; // buffer for MOTD
char* MOTD;
};
struct PLAYER_IP
@ -252,8 +298,6 @@ extern bool netPlayersUpdated;
extern int mapDownloadProgress;
extern char iptoconnect[PATH_MAX]; // holds IP/hostname from command line
extern Lobby::Client lobbyclient;
// ////////////////////////////////////////////////////////////////////////
// functions available to you.
extern int NETinit(bool bFirstCall); // init
@ -287,7 +331,7 @@ extern SDWORD NETgetGameFlags(UDWORD flag); // return one of the four flags(dw
extern int32_t NETgetGameFlagsUnjoined(unsigned int gameid, unsigned int flag); // return one of the four flags(dword) about the game.
extern bool NETsetGameFlags(UDWORD flag, SDWORD value); // set game flag(1-4) to value.
extern bool NEThaltJoining(void); // stop new players joining this game
extern bool NETfindGame(const int maxGames); // find games being played(uses GAME_GUID);
extern bool NETfindGame(void); // find games being played(uses GAME_GUID);
extern bool NETjoinGame(const char* host, uint32_t port, const char* playername); // join game given with playername
extern bool NEThostGame(const char* SessionName, const char* PlayerName,// host a game
SDWORD one, SDWORD two, SDWORD three, SDWORD four, UDWORD plyrs);
@ -296,6 +340,10 @@ void NETfixDuplicatePlayerNames(void); // Change a player's name aut
#include "netlog.h"
extern void NETsetMasterserverName(const char* hostname);
extern const char* NETgetMasterserverName(void);
extern void NETsetMasterserverPort(unsigned int port);
extern unsigned int NETgetMasterserverPort(void);
extern void NETsetGameserverPort(unsigned int port);
extern unsigned int NETgetGameserverPort(void);

View File

@ -203,7 +203,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\3rdparty\miniupnpc\connecthostport.c" />
<ClCompile Include="netlobby.cpp" />
<ClCompile Include="netjoin_stub.cpp" />
<ClCompile Include="netlog.cpp" />
<ClCompile Include="netplay.cpp" />
<ClCompile Include="netqueue.cpp" />
@ -247,7 +247,6 @@
<ClInclude Include="..\..\3rdparty\miniupnpc\upnpcommands.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\upnperrors.h" />
<ClInclude Include="..\..\3rdparty\miniupnpc\upnpreplyparse.h" />
<ClInclude Include="netlobby.h" />
<ClInclude Include="netlog.h" />
<ClInclude Include="netplay.h" />
<ClInclude Include="netqueue.h" />

View File

@ -65,7 +65,7 @@
<ClCompile Include="nettypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="netlobby.cpp">
<ClCompile Include="netjoin_stub.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@ -112,9 +112,6 @@
<ClInclude Include="..\..\3rdparty\miniupnpc\upnpreplyparse.h">
<Filter>Source Files\miniUPnP\header files</Filter>
</ClInclude>
<ClInclude Include="netlobby.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="netqueue.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -12,7 +12,6 @@
buildConfigurationList = 438B0C0E13773146008184FC /* Build configuration list for PBXAggregateTarget "Fetch Third Party Sources" */;
buildPhases = (
438B0C14137731C3008184FC /* GLExtensionWrangler - Fetch source */,
43329A2013CB5692005BE784 /* QJson - Fetch source */,
438B0C191377320A008184FC /* Zlib - Fetch source */,
438B0C26137732A5008184FC /* Ogg - Fetch source */,
438B0C1E13773258008184FC /* Png - Fetch source */,
@ -398,29 +397,6 @@
432BE3D810D9C90B00A486AB /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 432BE3C110D9C79400A486AB /* InfoPlist.strings */; };
432BE3F810D9CD4000A486AB /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 432BE3EE10D9CB4D00A486AB /* InfoPlist.strings */; };
432BE40210D9CF6F00A486AB /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 432BE3FE10D9CF1300A486AB /* InfoPlist.strings */; };
4332993013CB4FC5005BE784 /* json_parser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4332991C13CB4FC5005BE784 /* json_parser.cc */; };
4332993113CB4FC5005BE784 /* json_parser.hh in Headers */ = {isa = PBXBuildFile; fileRef = 4332991D13CB4FC5005BE784 /* json_parser.hh */; };
4332993213CB4FC5005BE784 /* json_scanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4332991E13CB4FC5005BE784 /* json_scanner.cpp */; };
4332993313CB4FC5005BE784 /* json_scanner.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332991F13CB4FC5005BE784 /* json_scanner.h */; settings = {ATTRIBUTES = (); }; };
4332993413CB4FC5005BE784 /* location.hh in Headers */ = {isa = PBXBuildFile; fileRef = 4332992013CB4FC5005BE784 /* location.hh */; };
4332993513CB4FC5005BE784 /* parser_p.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992113CB4FC5005BE784 /* parser_p.h */; settings = {ATTRIBUTES = (); }; };
4332993613CB4FC5005BE784 /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4332992213CB4FC5005BE784 /* parser.cpp */; };
4332993713CB4FC5005BE784 /* parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992313CB4FC5005BE784 /* parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
4332993813CB4FC5005BE784 /* parserrunnable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4332992413CB4FC5005BE784 /* parserrunnable.cpp */; };
4332993913CB4FC5005BE784 /* parserrunnable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992513CB4FC5005BE784 /* parserrunnable.h */; settings = {ATTRIBUTES = (Public, ); }; };
4332993A13CB4FC5005BE784 /* position.hh in Headers */ = {isa = PBXBuildFile; fileRef = 4332992613CB4FC5005BE784 /* position.hh */; };
4332993B13CB4FC5005BE784 /* qjson_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992713CB4FC5005BE784 /* qjson_debug.h */; settings = {ATTRIBUTES = (); }; };
4332993C13CB4FC5005BE784 /* qjson_export.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992813CB4FC5005BE784 /* qjson_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
4332993D13CB4FC5005BE784 /* qobjecthelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4332992913CB4FC5005BE784 /* qobjecthelper.cpp */; };
4332993E13CB4FC5005BE784 /* qobjecthelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992A13CB4FC5005BE784 /* qobjecthelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
4332993F13CB4FC5005BE784 /* serializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4332992B13CB4FC5005BE784 /* serializer.cpp */; };
4332994013CB4FC5005BE784 /* serializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992C13CB4FC5005BE784 /* serializer.h */; settings = {ATTRIBUTES = (Public, ); }; };
4332994113CB4FC5005BE784 /* serializerrunnable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4332992D13CB4FC5005BE784 /* serializerrunnable.cpp */; };
4332994213CB4FC5005BE784 /* serializerrunnable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4332992E13CB4FC5005BE784 /* serializerrunnable.h */; settings = {ATTRIBUTES = (Public, ); }; };
4332994313CB4FC5005BE784 /* stack.hh in Headers */ = {isa = PBXBuildFile; fileRef = 4332992F13CB4FC5005BE784 /* stack.hh */; };
4332994E13CB50C4005BE784 /* QtCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4333611E11A07FB900380F5E /* QtCore.framework */; };
433299CF13CB5516005BE784 /* parserrunnable.h in Sources */ = {isa = PBXBuildFile; fileRef = 4332992513CB4FC5005BE784 /* parserrunnable.h */; };
433299D013CB5516005BE784 /* serializerrunnable.h in Sources */ = {isa = PBXBuildFile; fileRef = 4332992E13CB4FC5005BE784 /* serializerrunnable.h */; };
4333612211A07FB900380F5E /* QtCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4333611E11A07FB900380F5E /* QtCore.framework */; };
4333661B11A07FFF00380F5E /* QtCore.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 4333611E11A07FB900380F5E /* QtCore.framework */; };
4336D8AA111DDF0F0012E8E4 /* random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4336D8A8111DDF0F0012E8E4 /* random.cpp */; };
@ -488,8 +464,12 @@
438BDDF31129DC9A00998660 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 438BDDD71129DC9A00998660 /* InfoPlist.strings */; };
43A6285B13A6C4A400C6B786 /* geometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A6285913A6C4A400C6B786 /* geometry.cpp */; };
43A8417811028EDD00733CCB /* pointtree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A8417611028EDD00733CCB /* pointtree.cpp */; };
43AA704313C7FD510015B52B /* QJson.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43AA702A13C7FC640015B52B /* QJson.framework */; };
43AA704413C7FD570015B52B /* QJson.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 43AA702A13C7FC640015B52B /* QJson.framework */; };
43AA704313C7FD510015B52B /* Bson.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43AA702A13C7FC640015B52B /* Bson.framework */; };
43AA704413C7FD570015B52B /* Bson.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 43AA702A13C7FC640015B52B /* Bson.framework */; };
43AA705513C801CF0015B52B /* bson.c in Sources */ = {isa = PBXBuildFile; fileRef = 43DD1BC613661FD5003AA9EC /* bson.c */; };
43AA705613C801D10015B52B /* bson.h in Headers */ = {isa = PBXBuildFile; fileRef = 43DD1BC713661FD5003AA9EC /* bson.h */; settings = {ATTRIBUTES = (Public, ); }; };
43AA705713C801D20015B52B /* numbers.c in Sources */ = {isa = PBXBuildFile; fileRef = 43DD1BC813661FD5003AA9EC /* numbers.c */; };
43AA705813C801D30015B52B /* platform_hacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 43DD1BC913661FD5003AA9EC /* platform_hacks.h */; settings = {ATTRIBUTES = (Public, ); }; };
43B8F285127C8F9D006F5A13 /* crc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43B8F282127C8F9D006F5A13 /* crc.cpp */; };
43B8F288127C8FDD006F5A13 /* netqueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43B8F286127C8FDD006F5A13 /* netqueue.cpp */; };
43B8FC9A127CB06C006F5A13 /* Zlib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02356D830BD3BB4100E9A019 /* Zlib.framework */; };
@ -782,20 +762,6 @@
remoteGlobalIDString = 4318434A1363942200BA2BC5;
remoteInfo = MiniUPnPc;
};
4332991813CB4F41005BE784 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 02356D660BD3BB2600E9A019 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 438B0C05137730FE008184FC;
remoteInfo = "Fetch Third Party Sources";
};
4332991A13CB4F6F005BE784 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 02356D660BD3BB2600E9A019 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 43FA570C10FF8E9B0074E914;
remoteInfo = "Setup Prebuilt Components";
};
43502D82134764BF00A02A1F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 02356D660BD3BB2600E9A019 /* Project object */;
@ -1549,26 +1515,6 @@
432BE3F010D9CB4D00A486AB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
432BE3FF10D9CF1300A486AB /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
432BE40010D9CF1300A486AB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4332991C13CB4FC5005BE784 /* json_parser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = json_parser.cc; path = "external/qjson-out/src/json_parser.cc"; sourceTree = "<group>"; };
4332991D13CB4FC5005BE784 /* json_parser.hh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = json_parser.hh; path = "external/qjson-out/src/json_parser.hh"; sourceTree = "<group>"; };
4332991E13CB4FC5005BE784 /* json_scanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = json_scanner.cpp; path = "external/qjson-out/src/json_scanner.cpp"; sourceTree = "<group>"; };
4332991F13CB4FC5005BE784 /* json_scanner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = json_scanner.h; path = "external/qjson-out/src/json_scanner.h"; sourceTree = "<group>"; };
4332992013CB4FC5005BE784 /* location.hh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = location.hh; path = "external/qjson-out/src/location.hh"; sourceTree = "<group>"; };
4332992113CB4FC5005BE784 /* parser_p.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = parser_p.h; path = "external/qjson-out/src/parser_p.h"; sourceTree = "<group>"; };
4332992213CB4FC5005BE784 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = parser.cpp; path = "external/qjson-out/src/parser.cpp"; sourceTree = "<group>"; };
4332992313CB4FC5005BE784 /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = parser.h; path = "external/qjson-out/src/parser.h"; sourceTree = "<group>"; };
4332992413CB4FC5005BE784 /* parserrunnable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = parserrunnable.cpp; path = "external/qjson-out/src/parserrunnable.cpp"; sourceTree = "<group>"; };
4332992513CB4FC5005BE784 /* parserrunnable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = parserrunnable.h; path = "external/qjson-out/src/parserrunnable.h"; sourceTree = "<group>"; };
4332992613CB4FC5005BE784 /* position.hh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = position.hh; path = "external/qjson-out/src/position.hh"; sourceTree = "<group>"; };
4332992713CB4FC5005BE784 /* qjson_debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qjson_debug.h; path = "external/qjson-out/src/qjson_debug.h"; sourceTree = "<group>"; };
4332992813CB4FC5005BE784 /* qjson_export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qjson_export.h; path = "external/qjson-out/src/qjson_export.h"; sourceTree = "<group>"; };
4332992913CB4FC5005BE784 /* qobjecthelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qobjecthelper.cpp; path = "external/qjson-out/src/qobjecthelper.cpp"; sourceTree = "<group>"; };
4332992A13CB4FC5005BE784 /* qobjecthelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qobjecthelper.h; path = "external/qjson-out/src/qobjecthelper.h"; sourceTree = "<group>"; };
4332992B13CB4FC5005BE784 /* serializer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = serializer.cpp; path = "external/qjson-out/src/serializer.cpp"; sourceTree = "<group>"; };
4332992C13CB4FC5005BE784 /* serializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = serializer.h; path = "external/qjson-out/src/serializer.h"; sourceTree = "<group>"; };
4332992D13CB4FC5005BE784 /* serializerrunnable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = serializerrunnable.cpp; path = "external/qjson-out/src/serializerrunnable.cpp"; sourceTree = "<group>"; };
4332992E13CB4FC5005BE784 /* serializerrunnable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = serializerrunnable.h; path = "external/qjson-out/src/serializerrunnable.h"; sourceTree = "<group>"; };
4332992F13CB4FC5005BE784 /* stack.hh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stack.hh; path = "external/qjson-out/src/stack.hh"; sourceTree = "<group>"; };
4333606E11A0731500380F5E /* wzapp_qt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wzapp_qt.h; path = ../lib/qtgame/wzapp_qt.h; sourceTree = SOURCE_ROOT; };
4333606F11A0731500380F5E /* wzapp_qt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = wzapp_qt.cpp; path = ../lib/qtgame/wzapp_qt.cpp; sourceTree = SOURCE_ROOT; };
4333607011A0731500380F5E /* wzapp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wzapp.h; path = ../lib/framework/wzapp.h; sourceTree = SOURCE_ROOT; };
@ -1691,10 +1637,10 @@
43A6285A13A6C4A400C6B786 /* geometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = geometry.h; path = ../lib/framework/geometry.h; sourceTree = SOURCE_ROOT; };
43A8417611028EDD00733CCB /* pointtree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pointtree.cpp; path = ../src/pointtree.cpp; sourceTree = SOURCE_ROOT; };
43A8417711028EDD00733CCB /* pointtree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pointtree.h; path = ../src/pointtree.h; sourceTree = SOURCE_ROOT; };
43AA702A13C7FC640015B52B /* QJson.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = QJson.framework; sourceTree = BUILT_PRODUCTS_DIR; };
43AA705F13C803DB0015B52B /* QJson-All.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "QJson-All.xcconfig"; path = "configs/QJson-All.xcconfig"; sourceTree = "<group>"; };
43AA706013C803DB0015B52B /* QJson-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "QJson-Debug.xcconfig"; path = "configs/QJson-Debug.xcconfig"; sourceTree = "<group>"; };
43AA706113C803DB0015B52B /* QJson-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "QJson-Release.xcconfig"; path = "configs/QJson-Release.xcconfig"; sourceTree = "<group>"; };
43AA702A13C7FC640015B52B /* Bson.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Bson.framework; sourceTree = BUILT_PRODUCTS_DIR; };
43AA705F13C803DB0015B52B /* Bson-All.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "Bson-All.xcconfig"; path = "configs/Bson-All.xcconfig"; sourceTree = "<group>"; };
43AA706013C803DB0015B52B /* Bson-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "Bson-Debug.xcconfig"; path = "configs/Bson-Debug.xcconfig"; sourceTree = "<group>"; };
43AA706113C803DB0015B52B /* Bson-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "Bson-Release.xcconfig"; path = "configs/Bson-Release.xcconfig"; sourceTree = "<group>"; };
43B8F282127C8F9D006F5A13 /* crc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crc.cpp; path = ../lib/framework/crc.cpp; sourceTree = SOURCE_ROOT; };
43B8F283127C8F9D006F5A13 /* crc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc.h; path = ../lib/framework/crc.h; sourceTree = SOURCE_ROOT; };
43B8F284127C8F9D006F5A13 /* opengl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = opengl.h; path = ../lib/framework/opengl.h; sourceTree = SOURCE_ROOT; };
@ -1765,6 +1711,10 @@
43D338561364F5A8005F6725 /* connecthostport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = connecthostport.c; sourceTree = "<group>"; };
43D338571364F5A8005F6725 /* connecthostport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = connecthostport.h; sourceTree = "<group>"; };
43D6167F12048D2D004B9630 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/InfoPlist.strings; sourceTree = "<group>"; };
43DD1BC613661FD5003AA9EC /* bson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson.c; path = ../3rdparty/bson/bson.c; sourceTree = SOURCE_ROOT; };
43DD1BC713661FD5003AA9EC /* bson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson.h; path = ../3rdparty/bson/bson.h; sourceTree = SOURCE_ROOT; };
43DD1BC813661FD5003AA9EC /* numbers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = numbers.c; path = ../3rdparty/bson/numbers.c; sourceTree = SOURCE_ROOT; };
43DD1BC913661FD5003AA9EC /* platform_hacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform_hacks.h; path = ../3rdparty/bson/platform_hacks.h; sourceTree = SOURCE_ROOT; };
43DD1BCC13662006003AA9EC /* netlobby.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = netlobby.cpp; path = ../lib/netplay/netlobby.cpp; sourceTree = SOURCE_ROOT; };
43DD1BCD13662006003AA9EC /* netlobby.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netlobby.h; path = ../lib/netplay/netlobby.h; sourceTree = SOURCE_ROOT; };
43DF5A8812BEE01B00DD5A37 /* cocoa_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cocoa_wrapper.h; path = ../lib/framework/cocoa_wrapper.h; sourceTree = SOURCE_ROOT; };
@ -1891,7 +1841,7 @@
43502D6D1347648300A02A1F /* GLExtensionWrangler.framework in Frameworks */,
43B8FD10127CB0BE006F5A13 /* Gettext.framework in Frameworks */,
4318439B1363955300BA2BC5 /* MiniUPnPc.framework in Frameworks */,
43AA704313C7FD510015B52B /* QJson.framework in Frameworks */,
43AA704313C7FD510015B52B /* Bson.framework in Frameworks */,
4366729613D2122700FE85BA /* QuesoGLC.framework in Frameworks */,
43B8FD2E127CB13F006F5A13 /* Carbon.framework in Frameworks */,
43B8FD2F127CB13F006F5A13 /* Cocoa.framework in Frameworks */,
@ -1977,7 +1927,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4332994E13CB50C4005BE784 /* QtCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2082,7 +2031,7 @@
97AEAB330E8C1B5200A10721 /* Theora.framework */,
43502D521347640700A02A1F /* GLExtensionWrangler.framework */,
4318434B1363942200BA2BC5 /* MiniUPnPc.framework */,
43AA702A13C7FC640015B52B /* QJson.framework */,
43AA702A13C7FC640015B52B /* Bson.framework */,
4366718213D1FD5600FE85BA /* QuesoGLC.framework */,
);
name = Products;
@ -2778,7 +2727,7 @@
02DDA8620BD3C1BB0049AB60 /* Vorbis sources */,
02DDA8DE0BD3C3930049AB60 /* PhysFS sources */,
9730E8000E8CEB3B009C9481 /* Theora sources */,
43DD1BC213661F84003AA9EC /* QJson sources */,
43DD1BC213661F84003AA9EC /* Mongo-C-Driver sources */,
4366712B13D1FC8600FE85BA /* QuesoGLC sources */,
);
name = "Third Party";
@ -3242,31 +3191,15 @@
name = coupled;
sourceTree = "<group>";
};
43DD1BC213661F84003AA9EC /* QJson sources */ = {
43DD1BC213661F84003AA9EC /* Mongo-C-Driver sources */ = {
isa = PBXGroup;
children = (
4332991C13CB4FC5005BE784 /* json_parser.cc */,
4332991D13CB4FC5005BE784 /* json_parser.hh */,
4332991E13CB4FC5005BE784 /* json_scanner.cpp */,
4332991F13CB4FC5005BE784 /* json_scanner.h */,
4332992013CB4FC5005BE784 /* location.hh */,
4332992113CB4FC5005BE784 /* parser_p.h */,
4332992213CB4FC5005BE784 /* parser.cpp */,
4332992313CB4FC5005BE784 /* parser.h */,
4332992413CB4FC5005BE784 /* parserrunnable.cpp */,
4332992513CB4FC5005BE784 /* parserrunnable.h */,
4332992613CB4FC5005BE784 /* position.hh */,
4332992713CB4FC5005BE784 /* qjson_debug.h */,
4332992813CB4FC5005BE784 /* qjson_export.h */,
4332992913CB4FC5005BE784 /* qobjecthelper.cpp */,
4332992A13CB4FC5005BE784 /* qobjecthelper.h */,
4332992B13CB4FC5005BE784 /* serializer.cpp */,
4332992C13CB4FC5005BE784 /* serializer.h */,
4332992D13CB4FC5005BE784 /* serializerrunnable.cpp */,
4332992E13CB4FC5005BE784 /* serializerrunnable.h */,
4332992F13CB4FC5005BE784 /* stack.hh */,
43DD1BC613661FD5003AA9EC /* bson.c */,
43DD1BC713661FD5003AA9EC /* bson.h */,
43DD1BC813661FD5003AA9EC /* numbers.c */,
43DD1BC913661FD5003AA9EC /* platform_hacks.h */,
);
name = "QJson sources";
name = "Mongo-C-Driver sources";
sourceTree = "<group>";
};
43F3008010D344B000707B6E /* x86 */ = {
@ -3517,19 +3450,8 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
4332993113CB4FC5005BE784 /* json_parser.hh in Headers */,
4332993313CB4FC5005BE784 /* json_scanner.h in Headers */,
4332993413CB4FC5005BE784 /* location.hh in Headers */,
4332993513CB4FC5005BE784 /* parser_p.h in Headers */,
4332993713CB4FC5005BE784 /* parser.h in Headers */,
4332993913CB4FC5005BE784 /* parserrunnable.h in Headers */,
4332993A13CB4FC5005BE784 /* position.hh in Headers */,
4332993B13CB4FC5005BE784 /* qjson_debug.h in Headers */,
4332993C13CB4FC5005BE784 /* qjson_export.h in Headers */,
4332993E13CB4FC5005BE784 /* qobjecthelper.h in Headers */,
4332994013CB4FC5005BE784 /* serializer.h in Headers */,
4332994213CB4FC5005BE784 /* serializerrunnable.h in Headers */,
4332994313CB4FC5005BE784 /* stack.hh in Headers */,
43AA705613C801D10015B52B /* bson.h in Headers */,
43AA705813C801D30015B52B /* platform_hacks.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3785,7 +3707,7 @@
};
43AA702913C7FC640015B52B /* QJson */ = {
isa = PBXNativeTarget;
buildConfigurationList = 43AA702F13C7FC660015B52B /* Build configuration list for PBXNativeTarget "QJson" */;
buildConfigurationList = 43AA702F13C7FC660015B52B /* Build configuration list for PBXNativeTarget "Bson" */;
buildPhases = (
43AA702513C7FC640015B52B /* Headers */,
43AA702613C7FC640015B52B /* Resources */,
@ -3793,15 +3715,12 @@
43AA702813C7FC640015B52B /* Frameworks */,
);
buildRules = (
433299A213CB5388005BE784 /* PBXBuildRule */,
);
dependencies = (
4332991913CB4F41005BE784 /* PBXTargetDependency */,
4332991B13CB4F6F005BE784 /* PBXTargetDependency */,
);
name = QJson;
name = Bson;
productName = Bson;
productReference = 43AA702A13C7FC640015B52B /* QJson.framework */;
productReference = 43AA702A13C7FC640015B52B /* Bson.framework */;
productType = "com.apple.product-type.framework";
};
97AEAAEA0E8C1B5200A10721 /* Theora */ = {
@ -4063,20 +3982,6 @@
shellPath = /bin/sh;
shellScript = "cd ${SRCROOT}/external/libpng\n\nscripts/pnglibconf.mak\nexit ${?}\n";
};
43329A2013CB5692005BE784 /* QJson - Fetch source */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "QJson - Fetch source";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "DirectorY=\"qjson\"\nOutDir=\"qjson-out\"\nFileName=\"qjson-0.7.1.tar.bz2\"\nSourceDLP=\"http://downloads.sourceforge.net/project/qjson/qjson/0.7.1/qjson-0.7.1.tar.bz2\"\nMD5Sum=\"5a833ad606c164ed8aa69f0873366ace\"\n\nconfigs/FetchSource.sh \"${DirectorY}\" \"${OutDir}\" \"${FileName}\" \"${SourceDLP}\" \"${MD5Sum}\"\nexit ${?}\n";
};
433360A711A0796D00380F5E /* Qt */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -4763,15 +4668,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
433299CF13CB5516005BE784 /* parserrunnable.h in Sources */,
433299D013CB5516005BE784 /* serializerrunnable.h in Sources */,
4332993013CB4FC5005BE784 /* json_parser.cc in Sources */,
4332993213CB4FC5005BE784 /* json_scanner.cpp in Sources */,
4332993613CB4FC5005BE784 /* parser.cpp in Sources */,
4332993813CB4FC5005BE784 /* parserrunnable.cpp in Sources */,
4332993D13CB4FC5005BE784 /* qobjecthelper.cpp in Sources */,
4332993F13CB4FC5005BE784 /* serializer.cpp in Sources */,
4332994113CB4FC5005BE784 /* serializerrunnable.cpp in Sources */,
43AA705513C801CF0015B52B /* bson.c in Sources */,
43AA705713C801D20015B52B /* numbers.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -4869,16 +4767,6 @@
target = 4318434A1363942200BA2BC5 /* MiniUPnPc */;
targetProxy = 431843891363954200BA2BC5 /* PBXContainerItemProxy */;
};
4332991913CB4F41005BE784 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 438B0C05137730FE008184FC /* Fetch Third Party Sources */;
targetProxy = 4332991813CB4F41005BE784 /* PBXContainerItemProxy */;
};
4332991B13CB4F6F005BE784 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 43FA570C10FF8E9B0074E914 /* Setup Prebuilt Components */;
targetProxy = 4332991A13CB4F6F005BE784 /* PBXContainerItemProxy */;
};
43502D83134764BF00A02A1F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 43502D511347640700A02A1F /* GLExtensionWrangler */;
@ -4941,7 +4829,7 @@
};
43AA707113C804580015B52B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 43AA702913C7FC640015B52B /* QJson */;
target = 43AA702913C7FC640015B52B /* Bson */;
targetProxy = 43AA707013C804580015B52B /* PBXContainerItemProxy */;
};
43AE78FD10F0F4F500FED5D3 /* PBXTargetDependency */ = {
@ -5318,21 +5206,21 @@
};
43AA702C13C7FC650015B52B /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 43AA706013C803DB0015B52B /* QJson-Debug.xcconfig */;
baseConfigurationReference = 43AA706013C803DB0015B52B /* Bson-Debug.xcconfig */;
buildSettings = {
};
name = Debug;
};
43AA702D13C7FC650015B52B /* StaticAnalyzer */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 43AA706013C803DB0015B52B /* QJson-Debug.xcconfig */;
baseConfigurationReference = 43AA706013C803DB0015B52B /* Bson-Debug.xcconfig */;
buildSettings = {
};
name = StaticAnalyzer;
};
43AA702E13C7FC650015B52B /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 43AA706113C803DB0015B52B /* QJson-Release.xcconfig */;
baseConfigurationReference = 43AA706113C803DB0015B52B /* Bson-Release.xcconfig */;
buildSettings = {
};
name = Release;
@ -5523,7 +5411,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
43AA702F13C7FC660015B52B /* Build configuration list for PBXNativeTarget "QJson" */ = {
43AA702F13C7FC660015B52B /* Build configuration list for PBXNativeTarget "Bson" */ = {
isa = XCConfigurationList;
buildConfigurations = (
43AA702C13C7FC650015B52B /* Debug */,

View File

@ -1,10 +0,0 @@
// QJson settings for all configurations
#include "Base-Framework.xcconfig"
PRODUCT_NAME = QJson
FRAMEWORK_SEARCH_PATHS = $(inherited) $(FRAMEWORK_SEARCH_PATHS_QUOTED_3)
GCC_PREPROCESSOR_DEFINITIONS = $(inherited)
WARNING_CFLAGS = -Wall

View File

@ -1,8 +0,0 @@
// QJson settings for Debug configuration
#include "QJson-All.xcconfig"
GCC_ENABLE_FIX_AND_CONTINUE = YES
GCC_DYNAMIC_NO_PIC = NO
GCC_OPTIMIZATION_LEVEL = 0

View File

@ -1,6 +0,0 @@
// QJson settings for Release configuration
#include "QJson-All.xcconfig"
GCC_ENABLE_FIX_AND_CONTINUE = NO

View File

@ -285,7 +285,7 @@ warzone2100_LIBS += $(top_builddir)/lib/sdl/libsdl.a
endif
warzone2100_LDADD = $(warzone2100_LIBS) $(LTLIBINTL) $(SDL_LIBS) $(PHYSFS_LIBS) $(PNG_LIBS) $(OGGVORBIS_LIBS) \
$(THEORA_LIBS) $(OPENAL_LIBS) $(OPENGLC_LIBS) $(OPENGL_LIBS) $(QT4_LIBS) $(QJSON_LIBS) $(GLEW_LIBS) \
$(THEORA_LIBS) $(OPENAL_LIBS) $(OPENGLC_LIBS) $(OPENGL_LIBS) $(QT4_LIBS) $(GLEW_LIBS) \
$(X_LIBS) $(X_EXTRA_LIBS) $(LDFLAGS)
if MINGW32

View File

@ -49,6 +49,7 @@
// ////////////////////////////////////////////////////////////////////////////
#define DEFAULTSCROLL 1000
#define MASTERSERVERPORT 9990
#define GAMESERVERPORT 2100
static const char *fileName = "config";
@ -80,9 +81,11 @@ bool loadConfig()
setMiddleClickRotate(ini.value("MiddleClickRotate", false).toBool());
rotateRadar = ini.value("rotateRadar", true).toBool();
war_SetPauseOnFocusLoss(ini.value("PauseOnFocusLoss", false).toBool());
NETsetMasterserverName(ini.value("masterserver_name", "lobby.wz2100.net").toString().toUtf8().constData());
iV_font(ini.value("fontname", "DejaVu Sans").toString().toUtf8().constData(),
ini.value("fontface", "Book").toString().toUtf8().constData(),
ini.value("fontfacebold", "Bold").toString().toUtf8().constData());
NETsetMasterserverPort(ini.value("masterserver_port", MASTERSERVERPORT).toInt());
NETsetGameserverPort(ini.value("gameserver_port", GAMESERVERPORT).toInt());
war_SetFMVmode((FMV_MODE)ini.value("FMVmode", FMV_FULLSCREEN).toInt());
war_setScanlineMode((SCANLINE_MODE)ini.value("scanlines", SCANLINES_OFF).toInt());
@ -134,31 +137,6 @@ bool loadConfig()
war_SetHeight(height);
if (ini.contains("bpp")) pie_SetVideoBufferDepth(ini.value("bpp").toInt());
/**
* Lobby
*/
lobbyclient.setHost(ini.value("lobby_host", "lobby.wz2100.net").toString());
if ((lobbyclient.getHost() == "lobby.wz2100.net" || lobbyclient.getHost() == "localhost")
&& ini.contains("lobby_ssl")
&& ini.value("lobby_ssl", true).toBool() == true)
{
lobbyclient.useSSL(true);
lobbyclient.setPort(ini.value("lobby_port", 9994).toInt());
lobbyclient.setUser(ini.value("lobby_user", "").toString());
lobbyclient.setToken(ini.value("lobby_token", "").toString());
}
else if (ini.value("lobby_ssl", true).toBool() == true)
{
lobbyclient.useSSL(true);
lobbyclient.setPort(ini.value("lobby_port", 9994).toInt());
}
else
{
lobbyclient.useSSL(false);
lobbyclient.setPort(ini.value("lobby_port", 9990).toInt());
}
return true;
}
@ -211,6 +189,8 @@ bool saveConfig()
ini.setValue("UPnP", (SDWORD)NetPlay.isUPNP);
ini.setValue("rotateRadar", rotateRadar);
ini.setValue("PauseOnFocusLoss", war_GetPauseOnFocusLoss());
ini.setValue("masterserver_name", NETgetMasterserverName());
ini.setValue("masterserver_port", NETgetMasterserverPort());
ini.setValue("gameserver_port", NETgetGameserverPort());
if (!bMultiPlayer)
{
@ -232,16 +212,6 @@ bool saveConfig()
}
ini.setValue("playerName", (char*)sPlayer); // player name
}
/**
* Lobby
*/
ini.setValue("lobby_host", lobbyclient.getHost());
ini.setValue("lobby_ssl", lobbyclient.useSSL());
ini.setValue("lobby_port", lobbyclient.getPort());
ini.setValue("lobby_user", lobbyclient.getUser());
ini.setValue("lobby_token", lobbyclient.getToken());
ini.sync();
return true;
}

View File

@ -364,6 +364,70 @@ bool runSinglePlayerMenu(void)
return true;
}
// ////////////////////////////////////////////////////////////////////////////
// Multi Player Menu
static bool startMultiPlayerMenu(void)
{
addBackdrop();
addTopForm();
addBottomForm();
addSideText (FRONTEND_SIDETEXT , FRONTEND_SIDEX,FRONTEND_SIDEY,_("MULTI PLAYER"));
addTextButton(FRONTEND_HOST, FRONTEND_POS2X,FRONTEND_POS2Y, _("Host Game"), WBUT_TXTCENTRE);
addTextButton(FRONTEND_JOIN, FRONTEND_POS3X,FRONTEND_POS3Y, _("Join Game"), WBUT_TXTCENTRE);
addMultiBut(psWScreen, FRONTEND_BOTFORM, FRONTEND_QUIT, 10, 10, 30, 29, P_("menu", "Return"), IMAGE_RETURN, IMAGE_RETURN_HI, IMAGE_RETURN_HI);
return true;
}
bool runMultiPlayerMenu(void)
{
UDWORD id;
id = widgRunScreen(psWScreen); // Run the current set of widgets
switch(id)
{
case FRONTEND_HOST:
// don't pretend we are running a network game. Really do it!
NetPlay.bComms = true; // use network = true
NETdiscoverUPnPDevices();
ingame.bHostSetup = true;
bMultiPlayer = true;
bMultiMessages = true;
game.type = SKIRMISH; // needed?
lastTitleMode = MULTI;
changeTitleMode(MULTIOPTION);
break;
case FRONTEND_JOIN:
ingame.bHostSetup = false;
if (getLobbyError() != ERROR_CHEAT && getLobbyError() != ERROR_KICKED)
{
setLobbyError(ERROR_NOERROR);
}
changeTitleMode(PROTOCOL);
break;
case FRONTEND_QUIT:
changeTitleMode(TITLE);
break;
default:
break;
}
widgDisplayScreen(psWScreen); // show the widgets currently running
if (CancelPressed())
{
changeTitleMode(TITLE);
}
return true;
}
// ////////////////////////////////////////////////////////////////////////////
// Options Menu
static bool startOptionsMenu(void)
@ -1629,7 +1693,6 @@ void addTextButton(UDWORD id, UDWORD PosX, UDWORD PosY, const char *txt, unsign
// Align
if ( !(style & WBUT_TXTCENTRE) )
{
iV_SetFont(font_large);
sButInit.width = (short)(iV_GetTextWidth(txt)+10);
sButInit.x+=35;
}
@ -1783,7 +1846,10 @@ void changeTitleMode(tMode mode)
startCreditsScreen();
break;
case MULTI:
startGameFind();
startMultiPlayerMenu(); // goto multiplayer menu
break;
case PROTOCOL:
startConnectionScreen();
break;
case MULTIOPTION:
if(oldMode == MULTILIMIT)
@ -1795,6 +1861,9 @@ void changeTitleMode(tMode mode)
startMultiOptions(false);
}
break;
case GAMEFIND:
startGameFind();
break;
case MULTILIMIT:
startLimitScreen();
break;
@ -1808,7 +1877,7 @@ void changeTitleMode(tMode mode)
case SHOWINTRO:
break;
default:
debug( LOG_FATAL, "Unknown title mode requested (%d)", mode);
debug( LOG_FATAL, "Unknown title mode requested" );
abort();
break;
}

View File

@ -26,24 +26,27 @@
// determines which option screen to use. when in GS_TITLE_SCREEN mode.
enum tMode
{
TITLE, ///< intro mode
SINGLE, ///< single player menu
MULTI, ///< multiplayer menu
OPTIONS, ///< options menu
GAME, ///<
TUTORIAL, ///< tutorial/fastplay
CREDITS, ///< credits
MULTIOPTION, ///< Host Screen
MULTILIMIT, ///< MULTIPLAYER, Limit the multistuff.
STARTGAME, ///< Fire up the game
SHOWINTRO, ///< reshow the intro
QUIT, ///< leaving game
LOADSAVEGAME, ///< loading a save game
KEYMAP, ///< keymap editor
GRAPHICS_OPTIONS, ///< graphics options menu
AUDIO_OPTIONS, ///< audio options menu
VIDEO_OPTIONS, ///< video options menu
MOUSE_OPTIONS, ///< mouse options menu
TITLE, // 0 intro mode
SINGLE, // 1 single player menu
MULTI, // 2 multiplayer menu
OPTIONS, // 3 options menu
GAME, // 4
TUTORIAL, // 5 tutorial/fastplay
CREDITS, // 6 credits
PROTOCOL, // 7 MULTIPLAYER, select proto
MULTIOPTION, // 8 MULTIPLAYER, select game options
FORCESELECT, // 9 MULTIPLAYER, Force design screen
GAMEFIND, // 10 MULTIPLAYER, gamefinder.
MULTILIMIT, // 11 MULTIPLAYER, Limit the multistuff.
STARTGAME, // 12 Fire up the game
SHOWINTRO, // 13 reshow the intro
QUIT, // 14 leaving game
LOADSAVEGAME, // 15 loading a save game
KEYMAP, // 16 keymap editor
GRAPHICS_OPTIONS, // 17 graphics options menu
AUDIO_OPTIONS, // 18 audio options menu
VIDEO_OPTIONS, // 19 video options menu
MOUSE_OPTIONS, // 20 mouse options menu
};
extern tMode titleMode; // the global case
@ -59,6 +62,7 @@ extern bool bLimiterLoaded;
void changeTitleMode(tMode mode);
bool runTitleMenu(void);
bool runSinglePlayerMenu(void);
bool runMultiPlayerMenu(void);
bool runGameOptionsMenu(void);
bool runOptionsMenu(void);
bool runGraphicsOptionsMenu(void);
@ -158,7 +162,6 @@ enum
FRONTEND_LOADCAM2, // loading via --GAME CAM_2A
FRONTEND_LOADCAM3, // loading via --GAME CAM_3A
FRONTEND_PASSWORDFORM,
FRONTEND_LOGINFORM,
FRONTEND_HYPERLINK,
// begin menu
FRONTEND_SINGLEPLAYER = 20100, // title screen
@ -172,7 +175,9 @@ enum
FRONTEND_LOADGAME,
FRONTEND_SKIRMISH,
FRONTEND_CHALLENGES,
FE_P0 = 20300, // player 0 buton
FRONTEND_HOST = 20300, //multiplayer menu options
FRONTEND_JOIN,
FE_P0, // player 0 buton
FE_P1, // player 1 buton
FE_P2, // player 2 buton
FE_P3, // player 3 buton
@ -236,7 +241,7 @@ enum
FRONTEND_MMROTATE_R,
FRONTEND_KEYMAP = 26000, // Keymap menu
FRONTEND_LOBBYERROR = 31666 // Shows an lobby error
FRONTEND_NOGAMESAVAILABLE = 31666 // Used when no games are available in lobby
};

View File

@ -1156,6 +1156,8 @@ int realmain(int argc, char *argv[])
loadConfig();
NETinit(true);
// parse the command line
if (!ParseCommandLine(utfargc, utfargv))
{
@ -1168,10 +1170,6 @@ int realmain(int argc, char *argv[])
// Find out where to find the data
scanDataDirs();
// This needs to be done after "scanDataDirs"
// for the root cert from cacert.
NETinit(true);
// Must be run before OpenGL driver is properly initialized due to
// strange conflicts - Per
if (selfTest)

View File

@ -25,7 +25,6 @@
* along with connection and game options.
*/
#include "lib/framework/frame.h" // LEAVE THIS ALONE, it *must* be first for compiler specific fixes.
#include "lib/framework/wzapp.h"
#include "lib/framework/wzconfig.h"
@ -143,6 +142,7 @@ static int aiChooserUp = -1;
static int difficultyChooserUp = -1;
static int positionChooserUp = -1;
static bool SettingsUp = false;
static UBYTE InitialProto = 0;
static W_SCREEN *psConScreen;
static SDWORD dwSelectedGame =0; //player[] and games[] indexes
static UDWORD gameNumber; // index to games icons
@ -153,10 +153,6 @@ static bool EnablePasswordPrompt = false; // if we need the password prompt
LOBBY_ERROR_TYPES LobbyError = ERROR_NOERROR;
static bool allowChangePosition = true;
static char tooltipbuffer[256] ={'\0'};
static bool loginDone = false;
static QString lobbyUser;
static QString lobbyPass;
/// end of globals.
// ////////////////////////////////////////////////////////////////////////////
// Function protos
@ -189,10 +185,6 @@ static void removeGames (void);
static void hidePasswordForm(void);
static void showPasswordForm(void);
// Login form
static void hideLoginForm(void);
static void showLoginForm(void);
// Game option functions
static void addGameOptions();
static void addChatBox (void);
@ -613,7 +605,7 @@ static bool OptionsInet(void) //internet options
sFormInit.pDisplay = intDisplayFeBox;
widgAddForm(psConScreen, &sFormInit);
addMultiBut(psConScreen, CON_SETTINGS,CON_IP_OK,CON_OKX,CON_OKY,MULTIOP_OKW,MULTIOP_OKH,
addMultiBut(psConScreen, CON_SETTINGS,CON_OK,CON_OKX,CON_OKY,MULTIOP_OKW,MULTIOP_OKH,
_("Accept Settings"),IMAGE_OK,IMAGE_OK,true);
addMultiBut(psConScreen, CON_SETTINGS,CON_IP_CANCEL,CON_OKX+MULTIOP_OKW+10,CON_OKY,MULTIOP_OKW,MULTIOP_OKH,
_("Cancel"),IMAGE_NO,IMAGE_NO,true);
@ -658,6 +650,99 @@ static bool OptionsInet(void) //internet options
return true;
}
// ////////////////////////////////////////////////////////////////////////////
// Draw the connections screen.
bool startConnectionScreen(void)
{
addBackdrop(); //background
addTopForm(); // logo
addBottomForm();
SettingsUp = false;
InitialProto = 0;
safeSearch = false;
// don't pretend we are running a network game. Really do it!
NetPlay.bComms = true; // use network = true
addSideText(FRONTEND_SIDETEXT, FRONTEND_SIDEX, FRONTEND_SIDEY,_("CONNECTION"));
addMultiBut(psWScreen,FRONTEND_BOTFORM,CON_CANCEL,10,10,MULTIOP_OKW,MULTIOP_OKH,
_("Return To Previous Screen"), IMAGE_RETURN, IMAGE_RETURN_HI, IMAGE_RETURN_HI); // goback buttpn levels
addTextButton(CON_TYPESID_START+0,FRONTEND_POS2X,FRONTEND_POS2Y, _("Lobby"), WBUT_TXTCENTRE);
addTextButton(CON_TYPESID_START+1,FRONTEND_POS3X,FRONTEND_POS3Y, _("IP"), WBUT_TXTCENTRE);
return true;
}
void runConnectionScreen(void)
{
UDWORD id;
static char addr[128];
if(SettingsUp == true)
{
id = widgRunScreen(psConScreen); // Run the current set of widgets
}
else
{
id = widgRunScreen(psWScreen); // Run the current set of widgets
}
switch(id)
{
case CON_CANCEL: //cancel
changeTitleMode(MULTI);
bMultiPlayer = false;
bMultiMessages = false;
break;
case CON_TYPESID_START+0: // Lobby button
if ((LobbyError != ERROR_KICKED) && (LobbyError != ERROR_CHEAT))
{
setLobbyError(ERROR_NOERROR);
}
changeTitleMode(GAMEFIND);
break;
case CON_TYPESID_START+1: // IP button
OptionsInet();
break;
case CON_OK:
sstrcpy(addr, widgGetString(psConScreen, CON_IP));
if (addr[0] == '\0')
{
sstrcpy(addr, "127.0.0.1"); // Default to localhost.
}
if(SettingsUp == true)
{
widgReleaseScreen(psConScreen);
SettingsUp = false;
}
joinGame(addr, 0);
break;
case CON_IP_CANCEL:
if (SettingsUp == true)
{
widgReleaseScreen(psConScreen);
SettingsUp = false;
}
break;
}
widgDisplayScreen(psWScreen); // show the widgets currently running
if(SettingsUp == true)
{
widgDisplayScreen(psConScreen); // show the widgets currently running
}
if (CancelPressed())
{
changeTitleMode(MULTI);
}
}
// ////////////////////////////////////////////////////////////////////////
// Lobby error reading
LOBBY_ERROR_TYPES getLobbyError(void)
@ -693,12 +778,6 @@ bool joinGame(const char* host, uint32_t port)
return false;
}
// Set playername to the used lobby username.
if (lobbyclient.isAuthenticated())
{
sstrcpy(sPlayer, lobbyclient.getUser().toUtf8().constData());
}
if (!NETjoinGame(host, port, (char*)sPlayer)) // join
{
// Save the error.
@ -710,7 +789,7 @@ bool joinGame(const char* host, uint32_t port)
else if (oldError == ERROR_WRONGPASSWORD)
{
// Change to GAMEFIND, screen with a password dialog.
changeTitleMode(MULTI);
changeTitleMode(GAMEFIND);
showPasswordForm();
id = widgRunScreen(psWScreen); // Run the current set of widgets
@ -727,7 +806,7 @@ bool joinGame(const char* host, uint32_t port)
hidePasswordForm();
// Change to GAMEFIND, screen.
changeTitleMode(MULTI);
changeTitleMode(GAMEFIND);
// Reset the error to the saved one.
setLobbyError(oldError);
@ -737,7 +816,6 @@ bool joinGame(const char* host, uint32_t port)
return false;
}
ingame.localJoiningInProgress = true;
loadMultiStats(sPlayer,&playerStats);
@ -751,21 +829,27 @@ bool joinGame(const char* host, uint32_t port)
// ////////////////////////////////////////////////////////////////////////////
// Game Chooser Screen.
static void addGames(void)
{
UDWORD i,gcount=0;
static const char *wrongVersionTip = "Your version of Warzone is incompatible with this game.";
static const char *badModTip = "Your loaded mods are incompatible with this game. (Check mods/autoload/?)";
//count games to see if need two columns.
for(i=0;i<MaxGames;i++) // draw games
{
if( NetPlay.games[i].desc.dwSize !=0)
{
gcount++;
}
}
W_BUTINIT sButInit;
sButInit.formID = FRONTEND_BOTFORM;
sButInit.width = GAMES_GAMEWIDTH;
sButInit.height = GAMES_GAMEHEIGHT;
sButInit.pDisplay = displayRemoteGame;
//count games to see if need two columns.
gcount = lobbyclient.games.size();
// we want the old games deleted, and only list games when we should
if (getLobbyError() || !gcount)
{
@ -776,47 +860,49 @@ static void addGames(void)
gcount = 0;
}
// in case they refresh, and a game becomes available.
widgDelete(psWScreen,FRONTEND_LOBBYERROR);
widgDelete(psWScreen,FRONTEND_NOGAMESAVAILABLE);
// only have to do this if we have any games available.
if (!getLobbyError() && gcount)
{
for (i=0; i < gcount; i++) // draw games
for (i=0; i<MaxGames; i++) // draw games
{
widgDelete(psWScreen, GAMES_GAMESTART+i); // remove old icon.
if (NetPlay.games[i].desc.dwSize !=0)
{
sButInit.id = GAMES_GAMESTART+i;
if (gcount < (MaxGames / 2)) // only center column needed.
if (gcount < 9) // only center column needed.
{
sButInit.x = 165;
sButInit.y = (UWORD)(75+((5+GAMES_GAMEHEIGHT)*i) );
sButInit.y = (UWORD)(30+((5+GAMES_GAMEHEIGHT)*i) );
}
else
{
if (i<(MaxGames / 2)) //column 1
if (i<9) //column 1
{
sButInit.x = 55;
sButInit.y = (UWORD)(75+((5+GAMES_GAMEHEIGHT)*i) );
sButInit.x = 50;
sButInit.y = (UWORD)(30+((5+GAMES_GAMEHEIGHT)*i) );
}
else //column 2
{
sButInit.x = 75+GAMES_GAMEWIDTH;
sButInit.y = (UWORD)(75+((5+GAMES_GAMEHEIGHT)*(i-(MaxGames / 2)) ) );
sButInit.x = 60+GAMES_GAMEWIDTH;
sButInit.y = (UWORD)(30+((5+GAMES_GAMEHEIGHT)*(i-9) ) );
}
}
// display the correct tooltip message.
if (!NETisCorrectVersion(lobbyclient.games.at(i).game_version_major, lobbyclient.games.at(i).game_version_minor))
if (!NETisCorrectVersion(NetPlay.games[i].game_version_minor, NetPlay.games[i].game_version_major))
{
sButInit.pTip = wrongVersionTip;
}
else if (strcmp(lobbyclient.games.at(i).modlist.c_str(), getModList()) != 0)
else if (strcmp(NetPlay.games[i].modlist,getModList()) != 0)
{
sButInit.pTip = badModTip;
}
else
{
ssprintf(tooltipbuffer, "Map:%s, Game:%s, Hosted by %s ", lobbyclient.games.at(i).mapname.c_str(), lobbyclient.games.at(i).description.c_str(), lobbyclient.games.at(i).hostplayer.c_str());
ssprintf(tooltipbuffer, "Map:%s, Game:%s, Hosted by %s ", NetPlay.games[i].mapname, NetPlay.games[i].name, NetPlay.games[i].hostname);
sButInit.pTip = tooltipbuffer;
}
sButInit.UserData = i;
@ -824,6 +910,7 @@ static void addGames(void)
widgAddButton(psWScreen, &sButInit);
}
}
}
else
{
// display lobby message based on results.
@ -836,12 +923,6 @@ static void addGames(void)
case ERROR_NOERROR:
txt = _("No games are available");
break;
case ERROR_AUTHENTICATION:
txt = _("Authentication failed or not Authenticated");
break;
case ERROR_LOBBY_REJECTED:
txt = _("The lobby rejected you!");
break;
case ERROR_FULL:
txt = _("Game is full");
break;
@ -873,13 +954,13 @@ static void addGames(void)
}
// delete old widget if necessary
widgDelete(psWScreen,FRONTEND_LOBBYERROR);
widgDelete(psWScreen,FRONTEND_NOGAMESAVAILABLE);
sButInit = W_BUTINIT();
sButInit.formID = FRONTEND_BOTFORM;
sButInit.id = FRONTEND_LOBBYERROR;
sButInit.x = 80;
sButInit.y = 150;
sButInit.id = FRONTEND_NOGAMESAVAILABLE;
sButInit.x = 70;
sButInit.y = 50;
sButInit.style = WBUT_TXTCENTRE;
sButInit.width = FRONTEND_BUTWIDTH;
sButInit.UserData = 0; // store disable state
@ -894,199 +975,94 @@ static void addGames(void)
static void removeGames(void)
{
for (int i = 0; i<MaxGames; i++)
int i;
for (i = 0; i<MaxGames; i++)
{
widgDelete(psWScreen, GAMES_GAMESTART+i); // remove old widget
}
widgDelete(psWScreen,FRONTEND_LOBBYERROR);
widgDelete(psWScreen,FRONTEND_NOGAMESAVAILABLE);
}
void runGameFind(void )
{
UDWORD id;
static char addr[128];
static UDWORD lastupdate=0;
static char game_password[64]; // check if StringSize is available
const Lobby::GAME* lGame;
if (!loginDone && !EnablePasswordPrompt)
{
showLoginForm();
}
if ((lastupdate > gameTime || gameTime-lastupdate > 6000)
&& !EnablePasswordPrompt)
if (lastupdate > gameTime) lastupdate = 0;
if (gameTime-lastupdate > 6000 && !EnablePasswordPrompt)
{
lastupdate = gameTime;
if(safeSearch && !loginDone)
if(safeSearch)
{
NETfindGame(MaxGames); // find games synchronously
NETfindGame(); // find games synchronously
}
addGames(); //redraw list
}
if (SettingsUp == true)
id = widgRunScreen(psWScreen); // Run the current set of widgets
if(id == CON_CANCEL) // ok
{
id = widgRunScreen(psConScreen); // Display ip box
}
else
{
id = widgRunScreen(psWScreen); // Display Gamefind
changeTitleMode(PROTOCOL);
}
switch (id)
if(id == MULTIOP_REFRESH)
{
case CON_HOST_GAME:
// don't pretend we are running a network game. Really do it!
NetPlay.bComms = true; // use network = true
NETdiscoverUPnPDevices();
ingame.bHostSetup = true;
bMultiPlayer = true;
bMultiMessages = true;
game.type = SKIRMISH; // needed?
lastTitleMode = MULTI;
changeTitleMode(MULTIOPTION);
break;
case CON_JOIN_IP:
OptionsInet();
break;
case CON_LOGIN:
showLoginForm();
break;
case CON_LOGOUT:
lobbyclient.logout();
setLobbyError(ERROR_AUTHENTICATION);
addGames();
break;
case CON_IP_OK: // IP OK
sstrcpy(addr, widgGetString(psConScreen, CON_IP));
if (addr[0] == '\0')
{
sstrcpy(addr, "127.0.0.1"); // Default to localhost.
}
if(SettingsUp == true)
{
widgReleaseScreen(psConScreen);
SettingsUp = false;
}
joinGame(addr, 0);
break;
case CON_IP_CANCEL:
if (SettingsUp == true)
{
widgReleaseScreen(psConScreen);
SettingsUp = false;
}
break;
case CON_CANCEL:
changeTitleMode(TITLE);
break;
case MULTIOP_REFRESH:
ingame.localOptionsReceived = true;
NETfindGame(MaxGames); // find games synchronously
NETfindGame(); // find games synchronously
addGames(); //redraw list.
break;
case CON_PASSWORD:
}
if (id == CON_PASSWORD)
{
sstrcpy(game_password, widgGetString(psWScreen, CON_PASSWORD));
NETsetGamePassword(game_password);
break;
case CON_PASSWORDYES:
lGame = &lobbyclient.games.at(gameNumber);
ingame.localOptionsReceived = false; // note we are awaiting options
sstrcpy(game.name, lGame->description.c_str()); // store name
joinGame(lGame->host.c_str(), lGame->port);
break;
case CON_PASSWORDNO:
hidePasswordForm();
break;
case CON_LOGIN_USER:
lobbyUser = widgGetString(psWScreen, CON_LOGIN_USER);
break;
case CON_LOGIN_PASS:
lobbyPass = widgGetString(psWScreen, CON_LOGIN_PASS);
break;
case CON_LOGIN_YES:
loginDone = true;
if (lobbyclient.setUser(lobbyUser).login(lobbyPass) != Lobby::LOBBY_NO_ERROR)
{
setLobbyError(ERROR_AUTHENTICATION);
addGames(); // Draws the error
disableLobbyRefresh = true;
}
else
{
NETfindGame(MaxGames);
addGames();
}
hideLoginForm();
// Clear given values.
lobbyUser.clear();
lobbyPass.clear();
break;
case CON_LOGIN_NO:
disableLobbyRefresh = true;
loginDone = true;
hideLoginForm();
// Clear maybe given values.
lobbyUser.clear();
lobbyPass.clear();
NETfindGame(MaxGames);
addGames(); // Draws the error
break;
default:
// A entry in the list has been clicked.
// below is when they hit a game box to connect to--ideally this would be where
// we would want a modal password entry box.
if (id >= GAMES_GAMESTART && id<=GAMES_GAMEEND)
{
gameNumber = id-GAMES_GAMESTART;
lGame = &lobbyclient.games.at(gameNumber);
if (lGame->isPrivate)
if (!(NetPlay.games[gameNumber].desc.dwFlags & SESSION_JOINDISABLED)) // if still joinable
{
if (NetPlay.games[gameNumber].privateGame)
{
showPasswordForm();
}
else
{
ingame.localOptionsReceived = false; // note we are awaiting options
sstrcpy(game.name, lGame->description.c_str()); // store name
sstrcpy(game.name, NetPlay.games[gameNumber].name); // store name
joinGame(lGame->host.c_str(), lGame->port);
joinGame(NetPlay.games[gameNumber].desc.host, 0);
}
}
}
else if (id == CON_PASSWORDYES)
{
ingame.localOptionsReceived = false; // note we are awaiting options
sstrcpy(game.name, NetPlay.games[gameNumber].name); // store name
joinGame(NetPlay.games[gameNumber].desc.host, 0);
}
else if (id == CON_PASSWORDNO)
{
hidePasswordForm();
}
widgDisplayScreen(psWScreen); // show the widgets currently running
if(SettingsUp == true)
if(safeSearch)
{
widgDisplayScreen(psConScreen); // show the widgets currently running
iV_SetFont(font_large);
iV_DrawText(_("Searching"), D_W+260, D_H+460);
}
if (CancelPressed())
{
changeTitleMode(TITLE);
changeTitleMode(PROTOCOL);
}
}
@ -1135,25 +1111,15 @@ void startGameFind(void)
sFormInit.height = 460;
sFormInit.pDisplay = intOpenPlainForm;
sFormInit.disableChildren = true;
widgAddForm(psWScreen, &sFormInit);
// Sidetext
addSideText(FRONTEND_SIDETEXT, MULTIOP_OPTIONSX-3, MULTIOP_OPTIONSY,_("GAMES"));
// cancel
addMultiBut(psWScreen,FRONTEND_BOTFORM,CON_CANCEL,10,5,MULTIOP_OKW,MULTIOP_OKH,_("Return To Previous Screen"),
IMAGE_RETURN, IMAGE_RETURN_HI, IMAGE_RETURN_HI);
// Host game
addTextButton(CON_HOST_GAME, 75, 15, _("Host Game"), 0);
// Join IP
addTextButton(CON_JOIN_IP, 305, 15, _("Connect IP"), 0);
// Login/out
addTextButton(CON_LOGIN, 75, 420, _("Login"), 0);
addTextButton(CON_LOGOUT, 305, 420, _("Logout"), 0);
//refresh
addMultiBut(psWScreen,FRONTEND_BOTFORM,MULTIOP_REFRESH, MULTIOP_CHATBOXW-MULTIOP_OKW-5,5,MULTIOP_OKW,MULTIOP_OKH,
_("Refresh Games List"),IMAGE_REFRESH,IMAGE_REFRESH,false); // Find Games button
@ -1162,8 +1128,8 @@ void startGameFind(void)
widgHide(psWScreen, MULTIOP_REFRESH);
}
// Host Game
NETfindGame();
addGames(); // now add games.
// Password stuff. Hidden by default.
@ -1209,6 +1175,7 @@ void startGameFind(void)
sFormInit.height = FRONTEND_TOPFORMH-40;
sFormInit.pDisplay = intOpenPlainForm;
sFormInit.disableChildren = true;
widgAddForm(psWScreen, &sFormInit);
widgHide(psWScreen, FRONTEND_PASSWORDFORM);
@ -1218,105 +1185,6 @@ void startGameFind(void)
widgHide(psWScreen, CON_PASSWORDNO);
EnablePasswordPrompt = false;
// Fetch games if we are authenticated.
if (lobbyclient.hasAuthData() == true
|| lobbyclient.useAuth() == false)
{
loginDone = true;
NETfindGame(MaxGames);
addGames();
}
else
{
// Allow login
loginDone = false;
lobbyUser = lobbyclient.getUser();
}
// START: Create a hidden login form
// draws the background of the password box
sFormInit = W_FORMINIT();
sFormInit.formID = FRONTEND_BACKDROP;
sFormInit.id = FRONTEND_LOGINFORM;
sFormInit.style = WFORM_PLAIN;
sFormInit.x = FRONTEND_BOTFORMX+40;
sFormInit.y = 160;
sFormInit.width = 300;
sFormInit.height = FRONTEND_TOPFORMH+120;
sFormInit.pDisplay = intOpenPlainForm;
// sFormInit.disableChildren = true;
widgAddForm(psWScreen, &sFormInit);
addSideText(CON_LOGIN_SIDETEXT, FRONTEND_SIDEX+65, FRONTEND_SIDEY-10, _("LOBBY LOGIN"));
// Draw username label
sLabInit.formID = FRONTEND_LOGINFORM;
sLabInit.id = CON_LOGIN_USER_LABEL;
sLabInit.style = WLAB_ALIGNCENTRE;
sLabInit.x = 50;
sLabInit.y = 50;
sLabInit.width = 200;
sLabInit.height = 20;
sLabInit.pText = _("Username:");
sLabInit.pDisplay = showPasswordLabel;
widgAddLabel(psWScreen, &sLabInit);
// Draw username entry box
sEdInit.formID = FRONTEND_LOGINFORM;
sEdInit.id = CON_LOGIN_USER;
sEdInit.x = 50;
sEdInit.y = 55;
sEdInit.width = 200;
sEdInit.height = 20;
sEdInit.pText = lobbyUser.toUtf8().constData();
sEdInit.pBoxDisplay = displayPasswordEditBox;
widgAddEditBox(psWScreen, &sEdInit);
// Draw password label
sLabInit.formID = FRONTEND_LOGINFORM;
sLabInit.id = CON_LOGIN_PASS_LABEL;
sLabInit.style = WLAB_ALIGNCENTRE;
sLabInit.x = 50;
sLabInit.y = 110;
sLabInit.width = 200;
sLabInit.height = 20;
sLabInit.pText = _("Password:");
sLabInit.pDisplay = showPasswordLabel;
widgAddLabel(psWScreen, &sLabInit);
// Draw password entry box
sEdInit.formID = FRONTEND_LOGINFORM;
sEdInit.id = CON_LOGIN_PASS;
sEdInit.x = 50;
sEdInit.y = 115;
sEdInit.width = 200;
sEdInit.height = 20;
sEdInit.pText = "";
sEdInit.pBoxDisplay = displayPasswordEditBox;
widgAddEditBox(psWScreen, &sEdInit);
// Info Text
sLabInit.formID = FRONTEND_LOGINFORM;
sLabInit.id = CON_LOGIN_INFOTEXT;
sLabInit.style = WLAB_ALIGNLEFT;
sLabInit.x = 30;
sLabInit.y = 150;
sLabInit.width = 300 - (30*2);
sLabInit.height = 20;
sLabInit.pText = _("Use your wz2100.net credentials here.");
sLabInit.pDisplay = labelDisplay;
widgAddLabel(psWScreen, &sLabInit);
addMultiBut(psWScreen, FRONTEND_LOGINFORM,CON_LOGIN_NO,50,210,MULTIOP_OKW,MULTIOP_OKH,
_("Cancel"),IMAGE_NO,IMAGE_NO,true);
addMultiBut(psWScreen, FRONTEND_LOGINFORM,CON_LOGIN_YES,210,210,MULTIOP_OKW,MULTIOP_OKH,
_("OK"),IMAGE_OK,IMAGE_OK,true);
// Now hide it.
widgHide(psWScreen, FRONTEND_LOGINFORM);
widgHide(psWScreen, CON_LOGIN_SIDETEXT);
// END: LOGIN FORM
}
static void hidePasswordForm(void)
@ -1366,50 +1234,6 @@ static void showPasswordForm(void)
widgGetFromID(psWScreen, CON_PASSWORD)->clicked(&sContext);
}
static void hideLoginForm(void)
{
EnablePasswordPrompt = false;
// Clear the text
widgSetString(psWScreen, CON_LOGIN_USER, "");
widgSetString(psWScreen, CON_LOGIN_PASS, "");
widgHide(psWScreen, FRONTEND_LOGINFORM);
widgHide(psWScreen, CON_LOGIN_SIDETEXT);
widgReveal(psWScreen, FRONTEND_SIDETEXT);
widgReveal(psWScreen, FRONTEND_BOTFORM);
widgReveal(psWScreen, CON_CANCEL);
if (!disableLobbyRefresh)
{
widgReveal(psWScreen, MULTIOP_REFRESH);
}
}
static void showLoginForm(void)
{
W_CONTEXT sContext;
EnablePasswordPrompt = true;
widgHide(psWScreen, FRONTEND_SIDETEXT);
widgHide(psWScreen, FRONTEND_BOTFORM);
widgHide(psWScreen, CON_CANCEL);
widgHide(psWScreen, MULTIOP_REFRESH);
removeGames();
widgReveal(psWScreen, FRONTEND_LOGINFORM);
widgReveal(psWScreen, CON_LOGIN_SIDETEXT);
// auto click in the password box
sContext.psScreen = psWScreen;
sContext.psForm = (W_FORM *)psWScreen->psForm;
sContext.xOffset = 0;
sContext.yOffset = 0;
sContext.mx = 0;
sContext.my = 0;
widgGetFromID(psWScreen, CON_LOGIN_USER)->clicked(&sContext);
}
// ////////////////////////////////////////////////////////////////////////////
// Game Options Screen.
@ -1562,21 +1386,9 @@ static void addGameOptions()
widgSetButtonState(psWScreen, MULTIOP_CAMPAIGN, WBUT_DISABLE); // full, cannot enable scavenger player
}
// Set the players name to his lobby username.
if (lobbyclient.isAuthenticated())
{
sstrcpy(sPlayer, lobbyclient.getUser().toUtf8().constData());
}
//just display the game options.
addMultiEditBox(MULTIOP_OPTIONS, MULTIOP_PNAME, MCOL0, MROW1, _("Select Player Name"), (char*) sPlayer, IMAGE_EDIT_PLAYER, IMAGE_EDIT_PLAYER_HI, MULTIOP_PNAME_ICON);
// Dont allow player name changes when he's authenticated to the lobby.
if (NetPlay.bComms && lobbyclient.isAuthenticated())
{
widgSetButtonState(psWScreen, MULTIOP_PNAME, WEDBS_DISABLE);
widgSetButtonState(psWScreen, MULTIOP_PNAME_ICON, WBUT_DISABLE);
}
// alliances
addBlueForm(MULTIOP_OPTIONS, MULTIOP_ALLIANCES, _("Alliances"), MCOL0, MROW6, MULTIOP_BLUEFORMW, 27);
@ -2696,7 +2508,7 @@ static void stopJoining(void)
if(NetPlay.bComms) // not even connected.
{
changeTitleMode(MULTI);
changeTitleMode(GAMEFIND);
}
else
{
@ -3782,16 +3594,15 @@ void displayRemoteGame(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGH
{
UDWORD x = xOffset+psWidget->x;
UDWORD y = yOffset+psWidget->y;
UDWORD gameNumber = psWidget->UserData;
UDWORD i = psWidget->UserData;
char tmp[80], gamename[StringSize];
unsigned int ping;
if (getLobbyError() != ERROR_NOERROR)
if (LobbyError != ERROR_NOERROR)
{
return;
}
const Lobby::GAME* lGame = &lobbyclient.games.at(gameNumber);
// Draw blue boxes.
drawBlueBox(x,y,psWidget->width,psWidget->height);
drawBlueBox(x,y,94,psWidget->height);
@ -3800,9 +3611,23 @@ void displayRemoteGame(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGH
//draw game info
iV_SetFont(font_regular); // font
if (NETisCorrectVersion(lGame->game_version_major, lGame->game_version_minor))
// get game info.
// TODO: Check whether this code is used at all in skirmish games, if not, remove it.
if ((NetPlay.games[i].desc.dwFlags & SESSION_JOINDISABLED)
|| strcmp(NetPlay.games[i].modlist,getModList()) != 0
|| (bMultiPlayer
&& !NetPlay.bComms
&& NETgetGameFlagsUnjoined(gameNumber,1) == SKIRMISH // the LAST bug...
&& NetPlay.games[gameNumber].desc.dwCurrentPlayers >= NetPlay.games[gameNumber].desc.dwMaxPlayers - 1))
{
if (lGame->currentPlayers >= lGame->maxPlayers)
iV_SetTextColour(WZCOL_TEXT_MEDIUM);
// FIXME: We should really use another way to indicate that the game is full than our current big fat cross.
// need some sort of closed thing here!
iV_DrawImage(FrontImages,IMAGE_NOJOIN,x+18,y+11);
}
else if (!NETisCorrectVersion(NetPlay.games[i].game_version_minor, NetPlay.games[i].game_version_major))
{
if (NetPlay.games[gameNumber].desc.dwCurrentPlayers >= NetPlay.games[gameNumber].desc.dwMaxPlayers)
{
iV_SetTextColour(WZCOL_TEXT_MEDIUM);
}
@ -3811,7 +3636,7 @@ void displayRemoteGame(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGH
iV_SetTextColour(WZCOL_FORM_TEXT);
}
iV_DrawText(_("Players"), x + 5, y + 18);
ssprintf(tmp, "%d/%d", lGame->currentPlayers, lGame->maxPlayers);
ssprintf(tmp, "%d/%d", NetPlay.games[i].desc.dwCurrentPlayers, NetPlay.games[i].desc.dwMaxPlayers);
iV_DrawText(tmp, x + 17, y + 33);
}
else
@ -3822,7 +3647,11 @@ void displayRemoteGame(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGH
}
//draw type overlay.
if (lGame->isPrivate) // check to see if it is a private game
if( NETgetGameFlagsUnjoined(i,1) == CAMPAIGN)
{
iV_DrawImage(FrontImages, IMAGE_ARENA_OVER, x + 59, y + 3);
}
else if (NetPlay.games[i].privateGame) // check to see if it is a private game
{
iV_DrawImage(FrontImages, IMAGE_LOCKED_NOBG, x+62, y+3); // lock icon
}
@ -3832,10 +3661,22 @@ void displayRemoteGame(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGH
}
// ping rating
ping = NETgetGameFlagsUnjoined(i, 2);
if (ping < PING_MED)
{
iV_DrawImage(FrontImages,IMAGE_LAMP_GREEN,x+70,y+26);
}
else if (ping >= PING_MED && ping < PING_HI)
{
iV_DrawImage(FrontImages,IMAGE_LAMP_AMBER,x+70,y+26);
}
else
{
iV_DrawImage(FrontImages,IMAGE_LAMP_RED,x+70,y+26);
}
//draw game name
sstrcpy(gamename, lGame->description.c_str());
sstrcpy(gamename, NetPlay.games[i].name);
while(iV_GetTextWidth(gamename) > (psWidget->width-110) )
{
gamename[strlen(gamename)-1]='\0';
@ -3843,7 +3684,7 @@ void displayRemoteGame(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGH
iV_DrawText(gamename, x + 100, y + 18); // name
iV_SetFont(font_small); // font
iV_DrawText(lGame->versionstring.c_str(), x + 100, y + 32); // version
iV_DrawText(NetPlay.games[i].versionstring, x + 100, y + 32); // version
}
void displayTeamChooser(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *pColours)

View File

@ -32,8 +32,6 @@
#define AI_CLOSED -1
#define AI_NOT_FOUND -99
#define MaxGames 14 // max number of concurrently playable games to allow.
void readAIs(); ///< step 1, load AI definition files
void loadMultiScripts(); ///< step 2, load the actual AI scripts
const char *getAIName(int player); ///< only run this -after- readAIs() is called
@ -43,6 +41,10 @@ int getNextAIAssignment(const char *name);
extern LOBBY_ERROR_TYPES getLobbyError(void);
extern void setLobbyError(LOBBY_ERROR_TYPES error_type);
extern void runConnectionScreen (void);
extern bool startConnectionScreen (void);
extern void intProcessConnection (UDWORD id);
extern void runGameFind (void);
extern void startGameFind (void);
@ -64,6 +66,9 @@ void loadMapPreview(bool hideInterface);
// ////////////////////////////////////////////////////////////////
// CONNECTION SCREEN
#define CON_CONTYPES 10103
#define CON_CONTYPESWIDTH 290
#define CON_CONTYPES_FORM 10104
#define CON_TYPESID_START 10105
#define CON_TYPESID_END 10128
@ -81,17 +86,16 @@ void loadMapPreview(bool hideInterface);
#define CON_OKY CON_SETTINGSHEIGHT-MULTIOP_OKH-3
#define CON_CANCEL 10102
#define CON_HOST_GAME 10103
#define CON_JOIN_IP 10104
#define CON_LOGOUT 10105
#define CON_LOGIN 10106
#define CON_PHONE 10132
#define CON_PHONEX 20
#define CON_PHONEY 45
#define CON_IP 10133
#define CON_IPX 20
#define CON_IPY 45
#define CON_IP_CANCEL 10134
#define CON_IP_OK 10135
//for clients
#define CON_PASSWORD 10139
@ -104,15 +108,6 @@ void loadMapPreview(bool hideInterface);
#define CON_H_PASSWORDX MCOL2
#define CON_H_PASSWORDY MROW10 +31
// Login form
#define CON_LOGIN_USER 10150
#define CON_LOGIN_PASS 10151
#define CON_LOGIN_YES 10152
#define CON_LOGIN_NO 10153
#define CON_LOGIN_USER_LABEL 10154
#define CON_LOGIN_PASS_LABEL 10155
#define CON_LOGIN_SIDETEXT 10156
#define CON_LOGIN_INFOTEXT 10157
// ////////////////////////////////////////////////////////////////
@ -298,9 +293,19 @@ void loadMapPreview(bool hideInterface);
// ///////////////////////////////
// Many Button Variations..
#define CON_NAMEBOXWIDTH CON_SETTINGSWIDTH-20
#define CON_BUTWIDTH 60
#define CON_BUTHEIGHT 46
#define CON_CONBUTW CON_CONTYPESWIDTH-15
#define CON_CONBUTH 46
#define CON_NAMEBOXWIDTH CON_SETTINGSWIDTH-CON_PHONEX
#define CON_NAMEBOXHEIGHT 15
#define CON_COMBUTWIDTH 37
#define CON_COMBUTHEIGHT 24
#define MULTIOP_OKW 37
#define MULTIOP_OKH 24

View File

@ -416,9 +416,9 @@ void setupNewPlayer(UDWORD player)
// While not the perfect place for this, it has to do when a HOST joins (hosts) game
// unfortunatly, we don't get the message until after the setup is done.
void showMOTD(const char* motd)
void ShowMOTD(void)
{
// when HOST joins the game, show server MOTD message first
addConsoleMessage(_("System message:"), DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
addConsoleMessage(motd, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
addConsoleMessage(NetPlay.MOTD, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
}

View File

@ -35,7 +35,7 @@ extern void clearPlayer (UDWORD player, bool quietly);// wipe a player off t
//extern bool ProcessDroidOrders (void);
//extern UDWORD arenaPlayersReceived;
extern void showMOTD(const char* motd);
extern void ShowMOTD(void);
extern bool recvDataCheck(NETQUEUE queue);
extern bool sendDataCheck(void);

View File

@ -161,12 +161,18 @@ TITLECODE titleLoop(void)
switch(titleMode) // run relevant title screen code.
{
// MULTIPLAYER screens
case PROTOCOL:
runConnectionScreen(); // multiplayer connection screen.
break;
case MULTIOPTION:
runMultiOptions();
break;
case MULTI:
case GAMEFIND:
runGameFind();
break;
case MULTI:
runMultiPlayerMenu();
break;
case MULTILIMIT:
runLimitScreen();
break;