[springlobby] 01/05: New upstream version 0.257+dfsg
Markus Koschany
apo at moszumanska.debian.org
Sun Oct 1 18:37:58 UTC 2017
This is an automated email from the git hooks/post-receive script.
apo pushed a commit to branch master
in repository springlobby.
commit 7518400f4bf3ce405ec20c77989e90a4c19a0219
Author: Markus Koschany <apo at debian.org>
Date: Sun Oct 1 19:23:46 2017 +0200
New upstream version 0.257+dfsg
---
.travis.yml | 2 +-
ChangeLog | 3 +
VERSION | 2 +-
springlobby_config.h | 2 +-
src/CMakeLists.txt | 13 +-
src/autohostmanager.cpp | 10 +
src/autohostmanager.h | 3 +
src/downloader/lib/README.md | 2 +-
src/downloader/lib/src/FileSystem/FileSystem.cpp | 34 ++-
src/downloader/lib/src/FileSystem/FileSystem.h | 5 +-
src/downloader/lib/src/lib/minizip/unzip.c | 2 +-
src/downloader/lib/src/lib/minizip/zip.c | 22 +-
.../lib/src/lsl/lslunitsync/unitsync.cpp | 1 +
src/downloader/lib/src/main.cpp | 41 ++--
src/downloader/lib/src/pr-downloader.cpp | 22 +-
src/gui/basedataviewmodel.h | 1 -
src/gui/channel/autojoinchanneldialog.cpp | 5 +
src/gui/chatpanel.cpp | 1 -
src/gui/connectwindow.cpp | 17 +-
src/gui/connectwindow.h | 1 +
src/gui/hosting/battlemaptab.cpp | 5 +
src/gui/hosting/battlemaptab.h | 2 +-
...tleoptionstab.cpp => battlerestrictionstab.cpp} | 56 ++---
...{battleoptionstab.h => battlerestrictionstab.h} | 9 +-
src/gui/hosting/battleroomtab.cpp | 21 ++
src/gui/hosting/battleroomtab.h | 5 +-
src/gui/hosting/mainjoinbattletab.cpp | 14 +-
src/gui/hosting/mainjoinbattletab.h | 8 +-
src/gui/hosting/mainsingleplayertab.cpp | 6 +-
src/gui/hosting/mainsingleplayertab.h | 6 +-
src/gui/mapctrl.cpp | 33 +--
src/gui/singleplayertab.cpp | 3 +-
src/gui/ui.cpp | 25 ++-
src/gui/ui.h | 1 +
src/inetclass.h | 4 +
src/serverevents.cpp | 13 +-
src/serverevents.h | 1 +
src/settings.cpp | 56 +++--
src/settings.h | 14 +-
src/socket.cpp | 246 ++++++++++++++++++++-
src/socket.h | 27 ++-
src/tasserver.cpp | 31 ++-
src/tasserver.h | 1 +
tools/mxe_create_builddir.sh | 2 +-
44 files changed, 586 insertions(+), 192 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 38c1300..141fada 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,7 @@ cache: ccache
install:
- sudo apt-get install -y libwxgtk3.0-dev libboost-thread1.55-dev libboost-system1.55-dev
- - sudo apt-get install -y libboost-test1.55-dev libalure-dev cmake cmake-data
+ - sudo apt-get install -y libboost-test1.55-dev libalure-dev cmake cmake-data libssl-dev
before_script:
# optional dependencies
diff --git a/ChangeLog b/ChangeLog
index 1e6e152..01ac19a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
ChangeLog of Springlobby
+## 0.257
+ - fix unit restrictions
+ - add experimental tls support (default disabled)
## 0.256
- lazy init of unitsync (faster startup)
diff --git a/VERSION b/VERSION
index 020b4db..d6aadf1 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.256
+0.257
diff --git a/springlobby_config.h b/springlobby_config.h
index 85b59c4..3482b07 100644
--- a/springlobby_config.h
+++ b/springlobby_config.h
@@ -6,6 +6,6 @@
#undef VERSION
/* the git tag / commit we build from */
-#define VERSION "0.256"
+#define VERSION "0.257"
#endif /* SPRINGLOBBY_HEADERGUARD_CONFIG_H */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ae57c27..8f540af 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -33,6 +33,7 @@ endif()
FIND_PACKAGE(Boost 1.42.0 COMPONENTS thread system REQUIRED)
+
ADD_DEFINITIONS( -DLOCALE_INSTALL_DIR="${LOCALE_INSTALL_DIR}" )
@@ -227,7 +228,7 @@ set(springlobbySrc
gui/hosting/addbotdialog.cpp
gui/hosting/autobalancedialog.cpp
gui/hosting/battlemaptab.cpp
- gui/hosting/battleoptionstab.cpp
+ gui/hosting/battlerestrictionstab.cpp
gui/hosting/battleroomtab.cpp
gui/hosting/hostbattledialog.cpp
gui/hosting/mainjoinbattletab.cpp
@@ -344,6 +345,16 @@ ADD_EXECUTABLE(springlobby WIN32 MACOSX_BUNDLE
${springlobby_RC_FILE}
)
+FIND_PACKAGE(OpenSSL)
+if(OPENSSL_FOUND)
+ message(STATUS "Building with OpenSSL support: ${OPENSSL_VERSION}")
+ target_compile_definitions(springlobby PRIVATE -DSSL_SUPPORT)
+ target_include_directories(springlobby PRIVATE ${OPENSSL_INCLUDE_DIR})
+ target_link_libraries(springlobby ${OPENSSL_LIBRARIES})
+else()
+ message(WARNING "SSL support disabled!")
+endif()
+
IF( LIBNOTIFY_FOUND AND OPTION_NOTIFY )
TARGET_LINK_LIBRARIES(springlobby ${LIBNOTIFY_LIBRARIES} ${GLIB_LIBRARIES} )
target_include_directories(springlobby PRIVATE ${LIBNOTIFY_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS})
diff --git a/src/autohostmanager.cpp b/src/autohostmanager.cpp
index f2de69f..5ac5bd9 100644
--- a/src/autohostmanager.cpp
+++ b/src/autohostmanager.cpp
@@ -82,6 +82,11 @@ void SpringieHandler::Notify()
Send("!notify");
}
+void SpringieHandler::Promote()
+{
+ // TODO
+}
+
void SpringieHandler::Start()
{
Send("!start");
@@ -129,6 +134,11 @@ void SpadsHandler::Notify()
Send("!notify");
}
+void SpadsHandler::Promote()
+{
+ Send("!promote");
+}
+
void SpadsHandler::Start()
{
Send("!start");
diff --git a/src/autohostmanager.h b/src/autohostmanager.h
index 4fdf35a..342471f 100644
--- a/src/autohostmanager.h
+++ b/src/autohostmanager.h
@@ -19,6 +19,7 @@ public:
virtual void ClearStartBoxes(){};
virtual void AddStartBox(int /*posx*/, int /*posy*/, int /*w*/, int /*h*/){};
virtual void Notify(){};
+ virtual void Promote(){};
virtual void Start(){};
void SetBattle(IBattle* battle);
@@ -45,6 +46,7 @@ public:
void ClearStartBoxes() override;
void AddStartBox(int posx, int posy, int w, int h) override;
void Notify() override;
+ void Promote() override;
void Start() override;
};
@@ -60,6 +62,7 @@ public:
void ClearStartBoxes() override;
void AddStartBox(int posx, int posy, int w, int h) override;
void Notify() override;
+ void Promote() override;
void Start() override;
};
diff --git a/src/downloader/lib/README.md b/src/downloader/lib/README.md
index d4a32aa..3235e67 100644
--- a/src/downloader/lib/README.md
+++ b/src/downloader/lib/README.md
@@ -1,4 +1,4 @@
-#pr-downloader - tool to download maps and games for the Spring engine
+# pr-downloader - tool to download maps and games for the Spring engine
on the springrts.com wiki you can find [compile instructions and usage](https://springrts.com/wiki/pr-downloader).
diff --git a/src/downloader/lib/src/FileSystem/FileSystem.cpp b/src/downloader/lib/src/FileSystem/FileSystem.cpp
index ef6d613..57f1417 100644
--- a/src/downloader/lib/src/FileSystem/FileSystem.cpp
+++ b/src/downloader/lib/src/FileSystem/FileSystem.cpp
@@ -26,9 +26,12 @@
#ifndef SHGFP_TYPE_CURRENT
#define SHGFP_TYPE_CURRENT 0
#endif
+#else
+#include <sys/statvfs.h>
+#include <errno.h>
#endif
-CFileSystem* CFileSystem::singleton = NULL;
+static CFileSystem* singleton = NULL;
FILE* CFileSystem::propen(const std::string& filename,
const std::string& mode) const
@@ -216,8 +219,9 @@ void CFileSystem::Shutdown()
tmpFileSystem = NULL;
}
-const std::string& CFileSystem::getSpringDir()
+const std::string CFileSystem::getSpringDir()
{
+ assert(!springdir.empty());
if (springdir.empty())
(setWritePath(""));
return springdir;
@@ -713,3 +717,29 @@ std::string CFileSystem::EscapeFilename(const std::string& str)
}
return s;
}
+
+unsigned long CFileSystem::getMBsFree(const std::string& path)
+{
+#ifdef WIN32
+ ULARGE_INTEGER freespace;
+ BOOL res = GetDiskFreeSpaceEx(s2ws(path).c_str(), &freespace, nullptr, nullptr);
+ if (!res) {
+ LOG_ERROR("Error getting free disk space on %s: %d", path.c_str(), GetLastError());
+ return 0;
+ }
+ return freespace.QuadPart / (1024 * 1024);
+#else
+ struct statvfs st;
+ const int ret = statvfs(path.c_str(), &st);
+ if (ret != 0) {
+ const char *errstr = strerror(errno);
+ LOG_ERROR("Error getting free disk space on %s: %s", path.c_str(), errstr);
+ return 0;
+ }
+ if (st.f_frsize) {
+ return ((uint64_t)st.f_frsize * st.f_bavail) / (1024 * 1024);
+ }
+ return ((uint64_t)st.f_bsize * st.f_bavail) / (1024 * 1024);
+#endif
+}
+
diff --git a/src/downloader/lib/src/FileSystem/FileSystem.h b/src/downloader/lib/src/FileSystem/FileSystem.h
index 9030c5a..0a29dff 100644
--- a/src/downloader/lib/src/FileSystem/FileSystem.h
+++ b/src/downloader/lib/src/FileSystem/FileSystem.h
@@ -20,8 +20,6 @@ struct _FILETIME;
class CFileSystem
{
- static CFileSystem* singleton;
-
public:
static CFileSystem* GetInstance();
static void Shutdown();
@@ -40,7 +38,7 @@ public:
/**
returns the spring writeable directory
*/
- const std::string& getSpringDir();
+ const std::string getSpringDir();
/**
checks if a directory exists
@@ -136,6 +134,7 @@ public:
dir/filename -> dir
*/
static std::string DirName(const std::string& path);
+ static unsigned long getMBsFree(const std::string& path);
private:
bool portableDownload;
diff --git a/src/downloader/lib/src/lib/minizip/unzip.c b/src/downloader/lib/src/lib/minizip/unzip.c
index 9093504..bcfb941 100644
--- a/src/downloader/lib/src/lib/minizip/unzip.c
+++ b/src/downloader/lib/src/lib/minizip/unzip.c
@@ -200,7 +200,7 @@ typedef struct
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
+ IN assertion: the stream s has been successfully opened for reading.
*/
diff --git a/src/downloader/lib/src/lib/minizip/zip.c b/src/downloader/lib/src/lib/minizip/zip.c
index ea54853..44e88a9 100644
--- a/src/downloader/lib/src/lib/minizip/zip.c
+++ b/src/downloader/lib/src/lib/minizip/zip.c
@@ -15,7 +15,7 @@
Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
It is used when recreting zip archive with RAW when deleting items from a zip.
- ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
+ ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed.
Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
@@ -116,7 +116,7 @@ typedef struct linkedlist_datablock_internal_s
struct linkedlist_datablock_internal_s* next_datablock;
uLong avail_in_this_block;
uLong filled_in_this_block;
- uLong unused; /* for future use and alignement */
+ uLong unused; /* for future use and alignment */
unsigned char data[SIZEDATA_INDATABLOCK];
} linkedlist_datablock_internal;
@@ -171,7 +171,7 @@ typedef struct
curfile64_info ci; /* info on the file curretly writing */
ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
- ZPOS64_T add_position_when_writting_offset;
+ ZPOS64_T add_position_when_writing_offset;
ZPOS64_T number_entry;
#ifndef NO_ADDFILEINEXISTINGZIP
@@ -807,7 +807,7 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
}
byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
- pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
+ pziinit->add_position_when_writing_offset = byte_before_the_zipfile;
{
ZPOS64_T size_central_dir_to_read = size_central_dir;
@@ -875,7 +875,7 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl
ziinit.in_opened_file_inzip = 0;
ziinit.ci.stream_initialised = 0;
ziinit.number_entry = 0;
- ziinit.add_position_when_writting_offset = 0;
+ ziinit.add_position_when_writing_offset = 0;
init_linkedlist(&(ziinit.central_dir));
@@ -1164,7 +1164,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
if(zi->ci.pos_local_header >= 0xffffffff)
zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
else
- zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
+ zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4);
for (i=0;i<size_filename;i++)
*(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
@@ -1755,7 +1755,7 @@ extern int ZEXPORT zipCloseFileInZip (zipFile file)
int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
{
int err = ZIP_OK;
- ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
+ ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset;
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
@@ -1808,7 +1808,7 @@ int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centra
if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
{
- ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
}
return err;
@@ -1849,13 +1849,13 @@ int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
{
- ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
if(pos >= 0xffffffff)
{
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
}
else
- err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4);
}
return err;
@@ -1921,7 +1921,7 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
}
free_linkedlist(&(zi->central_dir));
- pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+ pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
{
ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
diff --git a/src/downloader/lib/src/lsl/lslunitsync/unitsync.cpp b/src/downloader/lib/src/lsl/lslunitsync/unitsync.cpp
index 27e2bcf..2df9380 100644
--- a/src/downloader/lib/src/lsl/lslunitsync/unitsync.cpp
+++ b/src/downloader/lib/src/lsl/lslunitsync/unitsync.cpp
@@ -575,6 +575,7 @@ StringVector Unitsync::GetUnitsList(const std::string& gamename)
{
assert(!gamename.empty());
StringVector cache;
+ GetGameHash(gamename);
if (!GameExists(gamename))
return cache;
const std::string cachefile = GetUnitsCacheFilePath(gamename);
diff --git a/src/downloader/lib/src/main.cpp b/src/downloader/lib/src/main.cpp
index 90b558f..e64a3b6 100644
--- a/src/downloader/lib/src/main.cpp
+++ b/src/downloader/lib/src/main.cpp
@@ -122,9 +122,35 @@ int main(int argc, char** argv)
bool res = true;
bool removeinvalid = false;
+ bool fsset = false;
+
while (true) {
- int option_index = 0;
- int c = getopt_long(argc, argv, "", long_options, &option_index);
+ const int c = getopt_long(argc, argv, "", long_options, nullptr);
+ if (c == -1)
+ break;
+ switch(c) {
+ case RAPID_VALIDATE_DELETE: {
+ removeinvalid = true;
+ break;
+ }
+ case FILESYSTEM_WRITEPATH: {
+ fsset = true;
+ DownloadSetConfig(CONFIG_FILESYSTEM_WRITEPATH, optarg);
+ break;
+ }
+ case DISABLE_LOGGING:
+ DownloadDisableLogging(true);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!fsset) {
+ DownloadSetConfig(CONFIG_FILESYSTEM_WRITEPATH, "");
+ }
+
+ while (true) {
+ const int c = getopt_long(argc, argv, "", long_options, nullptr);
if (c == -1)
break;
switch (c) {
@@ -136,10 +162,6 @@ int main(int argc, char** argv)
DownloadRapidValidate(removeinvalid);
break;
}
- case RAPID_VALIDATE_DELETE: {
- removeinvalid = true;
- break;
- }
case FILESYSTEM_DUMPSDP: {
DownloadDumpSDP(optarg);
break;
@@ -148,10 +170,6 @@ int main(int argc, char** argv)
ValidateSDP(optarg);
break;
}
- case FILESYSTEM_WRITEPATH: {
- DownloadSetConfig(CONFIG_FILESYSTEM_WRITEPATH, optarg);
- break;
- }
case DOWNLOAD_MAP: {
if (!download(DownloadEnum::CAT_MAP, optarg)) {
LOG_ERROR("No map found for %s", optarg);
@@ -176,9 +194,6 @@ int main(int argc, char** argv)
}
break;
}
- case DISABLE_LOGGING:
- DownloadDisableLogging(true);
- break;
case HELP:
default: {
show_help(argv[0]);
diff --git a/src/downloader/lib/src/pr-downloader.cpp b/src/downloader/lib/src/pr-downloader.cpp
index df56c8e..5213070 100644
--- a/src/downloader/lib/src/pr-downloader.cpp
+++ b/src/downloader/lib/src/pr-downloader.cpp
@@ -166,9 +166,13 @@ void DownloadShutdown()
bool DownloadSetConfig(CONFIG type, const void* value)
{
switch (type) {
- case CONFIG_FILESYSTEM_WRITEPATH:
- fileSystem->setWritePath((const char*)value);
+ case CONFIG_FILESYSTEM_WRITEPATH: {
+ std::string path((const char*)value);
+ fileSystem->setWritePath(path);
+ path = fileSystem->getSpringDir();
+ LOG_INFO("Free disk space: %d MB", CFileSystem::getMBsFree(path));
return true;
+ }
case CONFIG_FETCH_DEPENDS:
fetchDepends = (const bool*)value;
return true;
@@ -238,13 +242,27 @@ int DownloadStart()
int res = 0;
std::list<IDownload*> dls;
std::list<int>::iterator it;
+ const std::string dldir = fileSystem->getSpringDir();
+ const unsigned long MBsFree = CFileSystem::getMBsFree(dldir);
+ unsigned long dlsize = 0;
for (it = downloads.begin(); it != downloads.end(); ++it) {
IDownload* dl = GetIDownloadByID(searchres, *it);
+ if (dl->size > 0) {
+ dlsize += dl->size;
+ }
if (dl == NULL) {
continue;
}
dls.push_back(dl);
}
+ // at least 1024MB free disk space are required (else fragmentation will make file access way to slow!)
+ const unsigned long MBsNeeded = (dlsize / (1024 * 1024)) + 1024;
+
+ if (MBsFree < MBsNeeded) {
+ LOG_ERROR("Insuffcient free disk space (%u MiB) on %s: %u MiB needed", MBsFree, dldir.c_str(), MBsNeeded);
+ return 5;
+ }
+
if (fetchDepends) {
addDepends(dls);
}
diff --git a/src/gui/basedataviewmodel.h b/src/gui/basedataviewmodel.h
index 2d46804..5be269a 100644
--- a/src/gui/basedataviewmodel.h
+++ b/src/gui/basedataviewmodel.h
@@ -161,7 +161,6 @@ inline bool BaseDataViewModel<DataType>::IsListModel() const
template <class DataType>
inline bool BaseDataViewModel<DataType>::ContainsItem(const DataType& checkedItem) const
{
- assert(&checkedItem != nullptr);
const DataType* checkItemPointer = &checkedItem;
return m_ModelData.find(checkItemPointer) != m_ModelData.end();
diff --git a/src/gui/channel/autojoinchanneldialog.cpp b/src/gui/channel/autojoinchanneldialog.cpp
index 72ec98c..c54644c 100644
--- a/src/gui/channel/autojoinchanneldialog.cpp
+++ b/src/gui/channel/autojoinchanneldialog.cpp
@@ -13,7 +13,9 @@
#include <wx/event.h>
#include <wx/statline.h>
#include <wx/stattext.h>
+#include "servermanager.h"
#include "settings.h"
+#include "utils/conversion.h"
BEGIN_EVENT_TABLE(AutojoinChannelDialog, wxDialog)
@@ -77,6 +79,9 @@ void AutojoinChannelDialog::OnOk(wxCommandEvent& /*unused*/)
else
chan = line;
wxString key = line.AfterFirst(_T(' '));
+
+ if (ServerManager::Instance()->IsConnected())
+ ServerManager::Instance()->JoinChannel(STD_STRING(chan), STD_STRING(key));
sett().AddChannelJoin(chan, key);
}
sett().SaveSettings();
diff --git a/src/gui/chatpanel.cpp b/src/gui/chatpanel.cpp
index 4eca171..6dd9b8b 100644
--- a/src/gui/chatpanel.cpp
+++ b/src/gui/chatpanel.cpp
@@ -830,7 +830,6 @@ const Channel* ChatPanel::GetChannel() const
void ChatPanel::SetChannel(Channel* chan)
{
- ASSERT_LOGIC(this, "this==null");
ASSERT_LOGIC(m_type == CPT_Channel, "Not of type channel");
if ((chan == 0) && (m_channel != 0)) {
diff --git a/src/gui/connectwindow.cpp b/src/gui/connectwindow.cpp
index 3e9d1ca..0bf8e57 100644
--- a/src/gui/connectwindow.cpp
+++ b/src/gui/connectwindow.cpp
@@ -51,14 +51,17 @@ ConnectWindow::ConnectWindow(wxWindow* parent, Ui& ui)
wxString password;
bool savepass;
bool autoconnect;
+ bool tls;
SetIcon(wxIcon(connect_xpm));
server = sett().GetDefaultServer();
- username = sett().GetServerAccountNick(sett().GetDefaultServer());
- password = sett().GetServerAccountPass(sett().GetDefaultServer());
- savepass = sett().GetServerAccountSavePass(sett().GetDefaultServer());
+ username = sett().GetServerAccountNick(server);
+ password = sett().GetServerAccountPass(server);
+ savepass = sett().GetServerAccountSavePass(server);
autoconnect = cfg().ReadBool(_T( "/Server/Autoconnect" ));
+ tls = sett().IsServerTLS(STD_STRING(server));
+
// Create all UI elements.
m_tabs = new wxNotebook(this, -1);
m_login_tab = new wxPanel(m_tabs, -1);
@@ -78,8 +81,12 @@ ConnectWindow::ConnectWindow(wxWindow* parent, Ui& ui)
m_autoconnect_check = new wxCheckBox(m_login_tab, -1, _("Autoconnect next time"));
m_autoconnect_check->SetToolTip(_("remember connection details and automatically connect to server on next lobby startup"));
+ m_tls_check = new wxCheckBox(m_login_tab, -1, _("TLS"));
+ m_tls_check->SetToolTip(_("Use encrypted connection to connect to the Lobby server"));
+
m_rpass_check->SetValue(savepass);
m_autoconnect_check->SetValue(autoconnect);
+ m_tls_check->SetValue(tls);
m_acc_note_line = new wxStaticLine(m_login_tab);
@@ -111,6 +118,7 @@ ConnectWindow::ConnectWindow(wxWindow* parent, Ui& ui)
m_rpass_sizer->Add(m_rpass_check, 2, wxEXPAND | wxALL | wxALIGN_RIGHT, 4);
m_rpass_sizer->Add(m_autoconnect_check, 2, wxEXPAND | wxALL | wxALIGN_RIGHT, 4);
+ m_rpass_sizer->Add(m_tls_check, 2, wxEXPAND | wxALL | wxALIGN_RIGHT, 4);
m_pass_sizer->Add(m_pass_lbl, 1, wxALL | wxALIGN_CENTER_VERTICAL, 4);
m_pass_sizer->Add(m_pass_text, 2, wxEXPAND | wxALL, 4);
@@ -255,10 +263,11 @@ void ConnectWindow::OnOk(wxCommandEvent&)
OnLoginDenied(_T("Port number out of range.\n\nIt must be an integer between 1 and 65535"));
return;
}
- sett().SetServer(HostAddress, serverString[0], port);
+ sett().SetServer(HostAddress, serverString[0], port, "");
}
sett().SetDefaultServer(HostAddress);
cfg().Write(_T( "/Server/Autoconnect" ), m_autoconnect_check->IsChecked());
+ sett().SetServerTLS(STD_STRING(HostAddress), m_tls_check->IsChecked());
//if autoconnect enabled force saving of pw, actual saving is done in Ui::DoConnect
diff --git a/src/gui/connectwindow.h b/src/gui/connectwindow.h
index 5222344..fa1fc6f 100644
--- a/src/gui/connectwindow.h
+++ b/src/gui/connectwindow.h
@@ -57,6 +57,7 @@ private:
wxTextCtrl* m_pass_text; //!< Textbox where user can input password
wxCheckBox* m_rpass_check; //!< Checkbox where user can chose if he wants his password to be saved.
wxCheckBox* m_autoconnect_check; //!< Checkbox where user can chose if he wants to autoconnect.
+ wxCheckBox* m_tls_check; //!< Checkbox where user can chose if he wants the connection to be encrypted.
wxStaticLine* m_acc_note_line; //!< Line that separates the account settings from the note
diff --git a/src/gui/hosting/battlemaptab.cpp b/src/gui/hosting/battlemaptab.cpp
index 55155e9..be1dfc4 100644
--- a/src/gui/hosting/battlemaptab.cpp
+++ b/src/gui/hosting/battlemaptab.cpp
@@ -169,6 +169,11 @@ void BattleMapTab::Update(const wxString& Tag)
{
if (!m_battle)
return;
+ if (Tag.empty()) {
+ Update();
+ return;
+ }
+
long type;
Tag.BeforeFirst('_').ToLong(&type);
const std::string key = STD_STRING(Tag.AfterFirst('_'));
diff --git a/src/gui/hosting/battlemaptab.h b/src/gui/hosting/battlemaptab.h
index 4f002ef..f3ad2d4 100644
--- a/src/gui/hosting/battlemaptab.h
+++ b/src/gui/hosting/battlemaptab.h
@@ -33,7 +33,6 @@ public:
void UpdateUser(User& user);
- void Update();
void Update(const wxString& Tag);
void ReloadMaplist();
@@ -45,6 +44,7 @@ private:
{
return m_battle;
}
+ void Update();
void OnMapSelect(wxCommandEvent& event);
void OnMapBrowse(wxCommandEvent& event);
void OnStartTypeSelect(wxCommandEvent& event);
diff --git a/src/gui/hosting/battleoptionstab.cpp b/src/gui/hosting/battlerestrictionstab.cpp
similarity index 83%
rename from src/gui/hosting/battleoptionstab.cpp
rename to src/gui/hosting/battlerestrictionstab.cpp
index ebdc1a1..253fb6f 100644
--- a/src/gui/hosting/battleoptionstab.cpp
+++ b/src/gui/hosting/battlerestrictionstab.cpp
@@ -1,10 +1,10 @@
/* This file is part of the Springlobby (GPL v2 or later), see COPYING */
//
-// Class: BattleOptionsTab
+// Class: BattleRestrictionsTab
//
-#include "battleoptionstab.h"
+#include "battlerestrictionstab.h"
#include <wx/splitter.h>
#include <wx/intl.h>
@@ -20,7 +20,6 @@
#include <wx/checklst.h>
#include <wx/numdlg.h>
-#include "battleoptionstab.h"
#include "ibattle.h"
#include "gui/controls.h"
#include "utils/conversion.h"
@@ -31,16 +30,16 @@
#include "aui/auimanager.h"
-BEGIN_EVENT_TABLE(BattleOptionsTab, wxPanel)
+BEGIN_EVENT_TABLE(BattleRestrictionsTab, wxPanel)
-EVT_BUTTON(BOPTS_RESTRICT, BattleOptionsTab::OnRestrict)
-EVT_BUTTON(BOPTS_ALLOW, BattleOptionsTab::OnAllow)
-EVT_BUTTON(BOPTS_CLEARRES, BattleOptionsTab::OnClearRestrictions)
+EVT_BUTTON(BOPTS_RESTRICT, BattleRestrictionsTab::OnRestrict)
+EVT_BUTTON(BOPTS_ALLOW, BattleRestrictionsTab::OnAllow)
+EVT_BUTTON(BOPTS_CLEARRES, BattleRestrictionsTab::OnClearRestrictions)
END_EVENT_TABLE()
-BattleOptionsTab::BattleOptionsTab(wxWindow* parent, IBattle* battle)
+BattleRestrictionsTab::BattleRestrictionsTab(wxWindow* parent, IBattle* battle)
: wxScrolledWindow(parent, -1)
, m_battle(battle)
{
@@ -114,27 +113,14 @@ BattleOptionsTab::BattleOptionsTab(wxWindow* parent, IBattle* battle)
}
-BattleOptionsTab::~BattleOptionsTab()
+BattleRestrictionsTab::~BattleRestrictionsTab()
{
if (GetAui().manager)
GetAui().manager->DetachPane(this);
}
-void BattleOptionsTab::UpdateBattle(const wxString& Tag)
-{
- if (!m_battle)
- return;
- long type;
- Tag.BeforeFirst('_').ToLong(&type);
- wxString key = Tag.AfterFirst('_');
- if (type == LSL::Enum::PrivateOptions) {
- if (key == _T( "restrictions" ))
- ReloadRestrictions();
- }
-}
-
-void BattleOptionsTab::ReloadRestrictions()
+void BattleRestrictionsTab::ReloadRestrictions()
{
if (!m_battle)
return;
@@ -155,7 +141,7 @@ void BattleOptionsTab::ReloadRestrictions()
}
-int BattleOptionsTab::GetAllowedUnitIndex(const wxString& name)
+int BattleRestrictionsTab::GetAllowedUnitIndex(const wxString& name)
{
if (!m_battle)
return -1;
@@ -170,7 +156,7 @@ int BattleOptionsTab::GetAllowedUnitIndex(const wxString& name)
}
-int BattleOptionsTab::GetRestrictedUnitIndex(const wxString& name)
+int BattleRestrictionsTab::GetRestrictedUnitIndex(const wxString& name)
{
if (!m_battle)
return -1;
@@ -185,13 +171,13 @@ int BattleOptionsTab::GetRestrictedUnitIndex(const wxString& name)
}
-bool BattleOptionsTab::IsRestricted(const wxString& name)
+bool BattleRestrictionsTab::IsRestricted(const wxString& name)
{
return (GetRestrictedUnitIndex(name) >= 0);
}
-void BattleOptionsTab::Restrict(const wxString& name, int count)
+void BattleRestrictionsTab::Restrict(const wxString& name, int count)
{
if (!m_battle)
return;
@@ -200,7 +186,7 @@ void BattleOptionsTab::Restrict(const wxString& name, int count)
}
-void BattleOptionsTab::Allow(const wxString& name)
+void BattleRestrictionsTab::Allow(const wxString& name)
{
if (!m_battle)
return;
@@ -209,7 +195,7 @@ void BattleOptionsTab::Allow(const wxString& name)
}
-void BattleOptionsTab::Restrict(int index, int count)
+void BattleRestrictionsTab::Restrict(int index, int count)
{
if (!m_battle)
return;
@@ -221,7 +207,7 @@ void BattleOptionsTab::Restrict(int index, int count)
}
-void BattleOptionsTab::Allow(int index)
+void BattleRestrictionsTab::Allow(int index)
{
if (!m_battle)
return;
@@ -238,7 +224,7 @@ void BattleOptionsTab::Allow(int index)
//////////////////////////////////////////////////////////////////////////
-void BattleOptionsTab::OnRestrict(wxCommandEvent& /*unused*/)
+void BattleRestrictionsTab::OnRestrict(wxCommandEvent& /*unused*/)
{
if (!m_battle)
return;
@@ -263,7 +249,7 @@ void BattleOptionsTab::OnRestrict(wxCommandEvent& /*unused*/)
}
-void BattleOptionsTab::OnAllow(wxCommandEvent& /*unused*/)
+void BattleRestrictionsTab::OnAllow(wxCommandEvent& /*unused*/)
{
if (!m_battle)
return;
@@ -286,7 +272,7 @@ void BattleOptionsTab::OnAllow(wxCommandEvent& /*unused*/)
}
-void BattleOptionsTab::OnClearRestrictions(wxCommandEvent& /*unused*/)
+void BattleRestrictionsTab::OnClearRestrictions(wxCommandEvent& /*unused*/)
{
if (!m_battle)
return;
@@ -294,7 +280,7 @@ void BattleOptionsTab::OnClearRestrictions(wxCommandEvent& /*unused*/)
ReloadRestrictions();
}
-void BattleOptionsTab::SetBattle(IBattle* battle)
+void BattleRestrictionsTab::SetBattle(IBattle* battle)
{
m_battle = battle;
bool isBattleEnabled = (battle != nullptr);
@@ -316,7 +302,7 @@ void BattleOptionsTab::SetBattle(IBattle* battle)
}
}
-IBattle* BattleOptionsTab::GetBattle()
+IBattle* BattleRestrictionsTab::GetBattle()
{
return m_battle;
}
diff --git a/src/gui/hosting/battleoptionstab.h b/src/gui/hosting/battlerestrictionstab.h
similarity index 89%
rename from src/gui/hosting/battleoptionstab.h
rename to src/gui/hosting/battlerestrictionstab.h
index c9a35da..5599253 100644
--- a/src/gui/hosting/battleoptionstab.h
+++ b/src/gui/hosting/battlerestrictionstab.h
@@ -19,13 +19,12 @@ class wxCheckListBox;
/** \brief manipulate "standard" engine options, unit restriction list
* \todo DOCMEMORE */
-class BattleOptionsTab : public wxScrolledWindow
+class BattleRestrictionsTab : public wxScrolledWindow
{
public:
- BattleOptionsTab(wxWindow* parent, IBattle* battle);
- ~BattleOptionsTab();
+ BattleRestrictionsTab(wxWindow* parent, IBattle* battle);
+ ~BattleRestrictionsTab();
- void UpdateBattle(const wxString& Tag);
void ReloadRestrictions();
void SetBattle(IBattle* battle);
@@ -44,8 +43,6 @@ private:
void OnAllow(wxCommandEvent& event);
void OnClearRestrictions(wxCommandEvent& event);
- void UpdateBattle();
-
IBattle* m_battle;
wxStaticText* m_aloowed_lbl;
diff --git a/src/gui/hosting/battleroomtab.cpp b/src/gui/hosting/battleroomtab.cpp
index a8cabc5..7233ad1 100644
--- a/src/gui/hosting/battleroomtab.cpp
+++ b/src/gui/hosting/battleroomtab.cpp
@@ -63,6 +63,7 @@
BEGIN_EVENT_TABLE(BattleRoomTab, wxPanel)
+EVT_BUTTON(BROOM_PROMOTE, BattleRoomTab::OnPromote)
EVT_BUTTON(BROOM_START, BattleRoomTab::OnStart)
EVT_BUTTON(BROOM_LEAVE, BattleRoomTab::OnLeave)
EVT_BUTTON(BROOM_ADDBOT, BattleRoomTab::OnAddBot)
@@ -180,6 +181,8 @@ BattleRoomTab::BattleRoomTab(wxWindow* parent, IBattle* battle)
m_host_new_btn->SetToolTip(_("Host a new battle"));
m_leave_btn = new wxButton(this, BROOM_LEAVE, _("Leave"), wxDefaultPosition, wxSize(-1, CONTROL_HEIGHT));
m_leave_btn->SetToolTip(_("Leave the battle and return to the battle list"));
+ m_promote_btn = new wxButton(this, BROOM_PROMOTE, _("Promote"), wxDefaultPosition, wxSize(-1, CONTROL_HEIGHT));
+ m_promote_btn->SetToolTip(_("Promote the battle in some chat channels"));
m_start_btn = new wxButton(this, BROOM_START, _("Start"), wxDefaultPosition, wxSize(-1, CONTROL_HEIGHT));
m_start_btn->SetToolTip(_("Start the battle"));
@@ -347,6 +350,7 @@ BattleRoomTab::BattleRoomTab(wxWindow* parent, IBattle* battle)
m_buttons_sizer->Add(m_autolock_chk, 0, wxEXPAND | wxALL, 2);
m_buttons_sizer->Add(m_lock_chk, 0, wxEXPAND | wxALL, 2);
m_buttons_sizer->Add(m_manage_players_btn, 0, wxEXPAND | wxALL, 2);
+ m_buttons_sizer->Add(m_promote_btn, 0, wxEXPAND | wxALL, 2);
m_buttons_sizer->Add(m_start_btn, 0, wxEXPAND | wxALL, 2);
m_main_sizer->Add(m_top_sizer, 1, wxEXPAND);
@@ -446,6 +450,10 @@ void BattleRoomTab::UpdateBattleInfo(const wxString& Tag)
{
if (!m_battle)
return;
+ if (Tag.empty()) {
+ UpdateBattleInfo();
+ return;
+ }
if (m_opt_list_map.find(Tag) == m_opt_list_map.end()) {
wxLogWarning("Tag %s not found in options list", STD_STRING(Tag).c_str());
@@ -592,6 +600,18 @@ ChatPanel& BattleRoomTab::GetChatPanel()
return *m_chat;
}
+void BattleRoomTab::OnPromote(wxCommandEvent& /*unused*/)
+{
+ if (!m_battle)
+ return;
+
+ if (m_battle->IsFounderMe()) {
+ customMessageBoxModal(SL_MAIN_ICON, _("You need to be in an autohost for this to work."), _("Error"));
+ } else {
+ m_battle->m_autohost_manager->GetAutohostHandler().Promote();
+ }
+}
+
void BattleRoomTab::OnStart(wxCommandEvent& /*unused*/)
{
if (!m_battle)
@@ -1152,6 +1172,7 @@ void BattleRoomTab::SetBattle(IBattle* battle)
m_players->Enable(isBattleEnabled);
m_leave_btn->Enable(isBattleEnabled);
+ m_promote_btn->Enable(isBattleEnabled);
m_start_btn->Enable(isBattleEnabled);
m_addbot_btn->Enable(isBattleEnabled);
m_manage_players_btn->Enable(isBattleEnabled);
diff --git a/src/gui/hosting/battleroomtab.h b/src/gui/hosting/battleroomtab.h
index 7d1e04d..ac55d08 100644
--- a/src/gui/hosting/battleroomtab.h
+++ b/src/gui/hosting/battleroomtab.h
@@ -48,7 +48,6 @@ public:
IBattle* GetBattle();
ChatPanel& GetChatPanel();
- void UpdateBattleInfo();
void UpdateBattleInfo(const wxString& Tag);
@@ -71,10 +70,12 @@ public:
void PrintAllySetup();
private:
+ void UpdateBattleInfo();
void RegenerateOptionsList();
void UpdateStatsLabels();
void UpdateMapInfoSummary();
+ void OnPromote(wxCommandEvent& event);
void OnStart(wxCommandEvent& event);
void OnHostNew(wxCommandEvent& event);
void OnLeave(wxCommandEvent& event);
@@ -177,6 +178,7 @@ private:
wxStaticLine* m_command_line;
wxButton* m_leave_btn;
+ wxButton* m_promote_btn;
wxButton* m_start_btn;
wxButton* m_addbot_btn;
wxButton* m_manage_players_btn;
@@ -216,6 +218,7 @@ private:
BROOM_ALLYSEL,
BROOM_COLOURSEL,
BROOM_SIDESEL,
+ BROOM_PROMOTE,
BROOM_START,
BROOM_ADDBOT,
BROOM_BALANCE,
diff --git a/src/gui/hosting/mainjoinbattletab.cpp b/src/gui/hosting/mainjoinbattletab.cpp
index 61580af..f5cb531 100644
--- a/src/gui/hosting/mainjoinbattletab.cpp
+++ b/src/gui/hosting/mainjoinbattletab.cpp
@@ -16,7 +16,7 @@
#include "mainjoinbattletab.h"
#include "battleroomtab.h"
#include "battlemaptab.h"
-#include "battleoptionstab.h"
+#include "battlerestrictionstab.h"
#include "utils/conversion.h"
#include "battleroommmoptionstab.h"
#include "aui/auimanager.h"
@@ -60,7 +60,7 @@ MainJoinBattleTab::MainJoinBattleTab(wxWindow* parent)
m_mm_opts_tab = new BattleroomMMOptionsTab(0, m_tabs);
m_tabs->InsertPage(2, m_mm_opts_tab, _("Options"), false, wxIcon(battle_settings_xpm));
- m_opts_tab = new BattleOptionsTab(m_tabs, 0);
+ m_opts_tab = new BattleRestrictionsTab(m_tabs, 0);
m_tabs->InsertPage(3, m_opts_tab, _("Unit Restrictions"), false, wxIcon(battle_settings_xpm));
m_main_sizer->Add(m_tabs, 1, wxEXPAND);
@@ -89,17 +89,11 @@ ChatPanel* MainJoinBattleTab::GetActiveChatPanel()
return NULL;
}
-void MainJoinBattleTab::UpdateCurrentBattle()
-{
- GetBattleRoomTab().UpdateBattleInfo();
- GetBattleMapTab().Update();
-}
-
void MainJoinBattleTab::UpdateCurrentBattle(const wxString& Tag)
{
GetBattleRoomTab().UpdateBattleInfo(Tag);
GetBattleMapTab().Update(Tag);
- GetOptionsTab().UpdateBattle(Tag);
+ GetOptionsTab().ReloadRestrictions();
GetMMOptionsTab().UpdateOptControls(Tag);
}
@@ -166,7 +160,7 @@ BattleMapTab& MainJoinBattleTab::GetBattleMapTab()
}
-BattleOptionsTab& MainJoinBattleTab::GetOptionsTab()
+BattleRestrictionsTab& MainJoinBattleTab::GetOptionsTab()
{
ASSERT_EXCEPTION(m_opts_tab, _T( "m_opts_tab == 0" ));
return *m_opts_tab;
diff --git a/src/gui/hosting/mainjoinbattletab.h b/src/gui/hosting/mainjoinbattletab.h
index 153e7d1..631ef07 100644
--- a/src/gui/hosting/mainjoinbattletab.h
+++ b/src/gui/hosting/mainjoinbattletab.h
@@ -10,7 +10,7 @@ class IBattle;
class User;
class BattleRoomTab;
class BattleMapTab;
-class BattleOptionsTab;
+class BattleRestrictionsTab;
class wxBoxSizer;
class wxImageList;
class SLNotebook;
@@ -25,8 +25,6 @@ public:
void HostBattle(IBattle& battle);
void JoinBattle(IBattle& battle);
- //void UpdateCurrentBattle();
- void UpdateCurrentBattle();
void UpdateCurrentBattle(const wxString& Tag);
void LeaveCurrentBattle(bool called_from_join = false);
void OnDisconnected()
@@ -47,7 +45,7 @@ public:
private:
BattleMapTab& GetBattleMapTab();
- BattleOptionsTab& GetOptionsTab();
+ BattleRestrictionsTab& GetOptionsTab();
BattleroomMMOptionsTab& GetMMOptionsTab();
wxBoxSizer* m_main_sizer;
@@ -57,7 +55,7 @@ private:
BattleRoomTab* m_battle_tab;
BattleMapTab* m_map_tab;
- BattleOptionsTab* m_opts_tab;
+ BattleRestrictionsTab* m_opts_tab;
BattleroomMMOptionsTab* m_mm_opts_tab;
enum {
diff --git a/src/gui/hosting/mainsingleplayertab.cpp b/src/gui/hosting/mainsingleplayertab.cpp
index 4a6d93a..6267479 100644
--- a/src/gui/hosting/mainsingleplayertab.cpp
+++ b/src/gui/hosting/mainsingleplayertab.cpp
@@ -12,7 +12,7 @@
#include "aui/auimanager.h"
#include "gui/slbook.h"
#include "gui/singleplayertab.h"
-#include "gui/hosting/battleoptionstab.h"
+#include "gui/hosting/battlerestrictionstab.h"
#include "gui/hosting/mainsingleplayertab.h"
#include "gui/hosting/battleroommmoptionstab.h"
#include "utils/conversion.h"
@@ -39,7 +39,7 @@ MainSinglePlayerTab::MainSinglePlayerTab(wxWindow* parent)
m_tabs->AddPage(m_sp_tab, _("Game"), true, wxNullBitmap);
m_mm_opts_tab = new BattleroomMMOptionsTab(&m_sp_tab->GetBattle(), m_tabs);
m_tabs->InsertPage(1, m_mm_opts_tab, _("Options"), false, wxIcon(battle_settings_xpm));
- m_opts_tab = new BattleOptionsTab(m_tabs, &m_sp_tab->GetBattle());
+ m_opts_tab = new BattleRestrictionsTab(m_tabs, &m_sp_tab->GetBattle());
m_tabs->InsertPage(2, m_opts_tab, _("Unit Restrictions"), false, wxIcon(battle_settings_xpm));
m_main_sizer->Add(m_tabs, 1, wxEXPAND);
@@ -123,7 +123,7 @@ SinglePlayerTab& MainSinglePlayerTab::GetSinglePlayerTab()
return *m_sp_tab;
}
-BattleOptionsTab& MainSinglePlayerTab::GetOptionsTab()
+BattleRestrictionsTab& MainSinglePlayerTab::GetOptionsTab()
{
ASSERT_EXCEPTION(m_opts_tab, _T( "m_opts_tab == 0" ));
return *m_opts_tab;
diff --git a/src/gui/hosting/mainsingleplayertab.h b/src/gui/hosting/mainsingleplayertab.h
index 35c8394..ce0ad11 100644
--- a/src/gui/hosting/mainsingleplayertab.h
+++ b/src/gui/hosting/mainsingleplayertab.h
@@ -11,7 +11,7 @@ class SLNotebook;
class wxImageList;
class wxBoxSizer;
class SinglePlayerTab;
-class BattleOptionsTab;
+class BattleRestrictionsTab;
class MainSinglePlayerTab : public wxPanel
{
@@ -28,7 +28,7 @@ public:
void ReloadPresetList();
SinglePlayerTab& GetSinglePlayerTab();
- BattleOptionsTab& GetOptionsTab();
+ BattleRestrictionsTab& GetOptionsTab();
BattleroomMMOptionsTab& GetMMOptionsTab();
void LoadPerspective(const wxString& perspective_name = wxEmptyString);
@@ -40,7 +40,7 @@ private:
SLNotebook* m_tabs;
SinglePlayerTab* m_sp_tab;
- BattleOptionsTab* m_opts_tab;
+ BattleRestrictionsTab* m_opts_tab;
BattleroomMMOptionsTab* m_mm_opts_tab;
};
diff --git a/src/gui/mapctrl.cpp b/src/gui/mapctrl.cpp
index 1bd2f6e..705ffd2 100644
--- a/src/gui/mapctrl.cpp
+++ b/src/gui/mapctrl.cpp
@@ -1013,8 +1013,6 @@ void MapCtrl::DrawUserPositions(wxDC& dc)
User* bot = 0;
for (unsigned int bi = 0; bi < m_battle->GetNumUsers(); bi++) {
User& tbot = m_battle->GetUser(bi);
- if (&tbot == 0)
- continue;
if (tbot.BattleStatus().spectator)
continue;
if ((tbot.BattleStatus().pos.x == m_map.info.positions[i].x) && (tbot.BattleStatus().pos.y == m_map.info.positions[i].y)) {
@@ -1031,8 +1029,6 @@ void MapCtrl::DrawUserPositions(wxDC& dc)
int previousteam = -1;
for (unsigned int i = 0; i < m_battle->GetNumUsers(); i++) {
User& usr = m_battle->GetUser(i);
- if (&usr == 0)
- continue;
if (usr.BattleStatus().spectator)
continue;
int currentteam = usr.BattleStatus().team;
@@ -1111,11 +1107,6 @@ void MapCtrl::OnMouseMove(wxMouseEvent& event)
return;
if (m_maction == Moved) {
User& user = *m_user_expanded;
- try {
- ASSERT_LOGIC(&user != 0, "MapCtrl::OnMouseMove(): user = 0");
- } catch (...) {
- return;
- }
m_map = m_battle->LoadMap();
wxRect mr = GetMinimapRect();
@@ -1141,13 +1132,8 @@ void MapCtrl::OnMouseMove(wxMouseEvent& event)
if (!m_user_expanded || !m_battle->UserExists(m_user_expanded->GetNick()))
m_user_expanded = 0;
- if (m_user_expanded) {
+ if (m_user_expanded != nullptr) {
User& user = *m_user_expanded;
- try {
- ASSERT_LOGIC(&user != 0, "MapCtrl::OnMouseMove(): user = 0");
- } catch (...) {
- return;
- }
wxRect r = GetUserRect(user, true);
if (r.Contains(event.GetX(), event.GetY())) {
RectangleArea last = m_rect_area;
@@ -1161,8 +1147,6 @@ void MapCtrl::OnMouseMove(wxMouseEvent& event)
} else {
for (unsigned int i = 0; i < m_battle->GetNumUsers(); i++) {
User& user = m_battle->GetUser(i);
- if (&user == 0)
- continue;
wxRect r = GetUserRect(user, false);
if (r.Contains(event.GetX(), event.GetY())) {
m_rect_area = GetUserRectArea(r, event.GetX(), event.GetY());
@@ -1317,12 +1301,9 @@ void MapCtrl::OnLeftDown(wxMouseEvent& event)
m_maction = Moved;
else
m_maction = None;
- User& user = *m_user_expanded;
- try {
- ASSERT_LOGIC(&user != 0, "MapCtrl::OnLeftDown(): user = 0");
- } catch (...) {
+ if (m_user_expanded == nullptr)
return;
- }
+ User& user = *m_user_expanded;
RefreshRect(GetUserRect(user, true), false);
return;
}
@@ -1390,16 +1371,11 @@ void MapCtrl::OnLeftUp(wxMouseEvent& event)
const long longval = LSL::Util::FromIntString(m_battle->CustomBattleOptions()
.getSingleValue("startpostype", LSL::Enum::EngineOption));
if (longval == IBattle::ST_Pick) {
- if (!m_user_expanded)
+ if (m_user_expanded == nullptr)
return;
if (m_rect_area != m_mdown_area)
return;
User& user = *m_user_expanded;
- try {
- ASSERT_LOGIC(&user != 0, "MapCtrl::OnLeftUp(): user == 0");
- } catch (...) {
- return;
- }
if ((m_mdown_area == Move) && (m_maction == Moved)) {
m_battle->UserPositionChanged(user);
} else if (m_mdown_area == UpAllyButton) {
@@ -1531,7 +1507,6 @@ void MapCtrl::OnRightUp(wxMouseEvent& event)
bs.ally = m_battle->GetFreeAlly();
bs.colour = m_battle->GetNewColour();
User& bot = m_battle->OnBotAdded(STD_STRING(dlg.GetNick()), bs);
- ASSERT_LOGIC(&bot != 0, "bot == 0");
bot.BattleStatus().pos.x = x;
bot.BattleStatus().pos.y = y;
RefreshRect(GetUserRect(bot, false), false);
diff --git a/src/gui/singleplayertab.cpp b/src/gui/singleplayertab.cpp
index 8685fed..0d03b84 100644
--- a/src/gui/singleplayertab.cpp
+++ b/src/gui/singleplayertab.cpp
@@ -399,8 +399,7 @@ void SinglePlayerTab::OnAddBot(wxCommandEvent& /*unused*/)
bs.team = m_battle.GetFreeTeam();
bs.ally = m_battle.GetFreeAlly();
bs.colour = m_battle.GetNewColour();
- User& bot = m_battle.OnBotAdded(STD_STRING(dlg.GetNick()), bs);
- ASSERT_LOGIC(&bot != 0, "bot == 0");
+ m_battle.OnBotAdded(STD_STRING(dlg.GetNick()), bs);
m_minimap->UpdateMinimap();
}
}
diff --git a/src/gui/ui.cpp b/src/gui/ui.cpp
index 98cac82..46a0c68 100644
--- a/src/gui/ui.cpp
+++ b/src/gui/ui.cpp
@@ -66,6 +66,7 @@ SLCONFIG("/General/LastUpdateCheck", 0L, "Last time springlobby checked for an u
SLCONFIG("/GUI/StartTab", (long)MainWindow::PAGE_SINGLE, "which tab to show on startup");
SLCONFIG("/Chat/BroadcastEverywhere", true, "setting to spam the server messages in all channels");
SLCONFIG("/Server/Autoconnect", false, "Connect to server on startup");
+SLCONFIG("/Server/TLS", false, "Use encrypted connection to the lobby server");
static unsigned int s_reconnect_delay_ms = 6 * 1000; //initial reconnect delay
@@ -319,10 +320,6 @@ void Ui::OnDisconnected(IServer& server, bool wasonline)
if (m_main_win == 0)
return;
slLogDebugFunc("");
- if (!&server) {
- wxLogError(_T("WTF got null reference!!!"));
- return;
- }
mw().GetJoinTab().OnDisconnected();
mw().GetBattleListTab().OnDisconnected();
@@ -592,10 +589,7 @@ void Ui::OnBattleInfoUpdated(IBattle& battle, const wxString& Tag)
return;
mw().GetBattleListTab().UpdateBattle(battle);
if (mw().GetJoinTab().GetCurrentBattle() == &battle) {
- if (Tag.IsEmpty())
- mw().GetJoinTab().UpdateCurrentBattle();
- else
- mw().GetJoinTab().UpdateCurrentBattle(Tag);
+ mw().GetJoinTab().UpdateCurrentBattle(Tag);
}
}
@@ -968,3 +962,18 @@ bool Ui::NeedsDownload(const IBattle* battle, bool uiprompt, DownloadEnum::Categ
return true;
}
+
+void Ui::OnInvalidFingerprintReceived(const std::string& fingerprint, const std::string& expected_fingerprint)
+{
+ int answer = wxCANCEL;
+ if (expected_fingerprint.empty()) {
+ answer = customMessageBox(SL_MAIN_ICON, _("The certificate by the server is unkown. Do you want to trust it? Please verify the fingerprint:\n") + TowxString(fingerprint) , _("Unknown Certificate"), wxYES_NO | wxCANCEL);
+ } else {
+ answer = customMessageBox(SL_MAIN_ICON, _("The certificate by the server is invalid! Maybe there is a MITM ongoing. Do you want ignore this warning?:\n") + TowxString(fingerprint) , _("Unknown Certificate"), wxYES_NO | wxCANCEL);
+ }
+ if (answer != wxYES) {
+ return;
+ }
+
+ sett().SetServerFingerprint(m_serv->GetServerName(), fingerprint);
+}
diff --git a/src/gui/ui.h b/src/gui/ui.h
index df69e2d..a1d2e0a 100644
--- a/src/gui/ui.h
+++ b/src/gui/ui.h
@@ -118,6 +118,7 @@ public:
void FirstRunWelcome();
void CheckForUpdates(bool show);
void EnableDebug(bool enable);
+ void OnInvalidFingerprintReceived(const std::string& fingerprint, const std::string& expected_fingerprint);
private:
void OnLobbyDownloaded(wxCommandEvent& /*data*/);
diff --git a/src/inetclass.h b/src/inetclass.h
index 7516a94..45ece42 100644
--- a/src/inetclass.h
+++ b/src/inetclass.h
@@ -33,6 +33,10 @@ public:
virtual void Ping()
{
}
+
+ virtual void OnInvalidFingerprintReceived(const std::string& /*fingerprint*/)
+ {
+ }
};
#endif // SPRINGLOBBY_HEADERGUARD_INETCLASS_H
diff --git a/src/serverevents.cpp b/src/serverevents.cpp
index 5ff6d4b..e2c33d7 100644
--- a/src/serverevents.cpp
+++ b/src/serverevents.cpp
@@ -403,6 +403,7 @@ void ServerEvents::OnBattleInfoUpdated(int battleid, int spectators, bool locked
ui().OnBattleInfoUpdated(battle, wxEmptyString);
} catch (assert_exception) {
+ wxLogWarning("Exception in OnBattleInfoUpdated");
}
}
@@ -553,6 +554,7 @@ void ServerEvents::OnBattleInfoUpdated(int battleid)
IBattle& battle = m_serv.GetBattle(battleid);
ui().OnBattleInfoUpdated(battle, wxEmptyString);
} catch (assert_exception) {
+ wxLogWarning("Exception in OnBattleInfoUpdated(%d)", battleid);
}
}
@@ -576,6 +578,7 @@ void ServerEvents::OnBattleDisableUnit(int battleid, const std::string& unitname
try {
IBattle& battle = m_serv.GetBattle(battleid);
battle.RestrictUnit(unitname, count);
+ wxLogDebug("OnBattleDisableUnit %d %s %d", battleid, unitname.c_str(), count);
} catch (assert_exception) {
}
}
@@ -775,7 +778,6 @@ void ServerEvents::OnBattleAddBot(int battleid, const std::string& nick, UserBat
IBattle& battle = m_serv.GetBattle(battleid);
battle.OnBotAdded(nick, status);
User& bot = battle.GetUser(nick);
- ASSERT_LOGIC(&bot != 0, "Bot null after add.");
ui().OnUserJoinedBattle(battle, bot);
} catch (assert_exception) {
}
@@ -900,7 +902,7 @@ void ServerEvents::OnKickedFromBattle()
void ServerEvents::OnRedirect(const std::string& address, unsigned int port, const std::string& CurrentNick, const std::string& CurrentPassword)
{
const std::string name = stdprintf("%s:%d", address.c_str(), port);
- sett().SetServer(name, TowxString(address), port);
+ sett().SetServer(name, TowxString(address), port, "");
//TODO: Rework this. Server calls it`s own method through another object!
ServerManager::Instance()->DoConnectToServer(name, CurrentNick, CurrentPassword);
}
@@ -999,3 +1001,10 @@ void ServerEvents::OnLoginDenied(const std::string& reason)
{
ui().OnLoginDenied(reason);
}
+
+void ServerEvents::OnInvalidFingerprintReceived(const std::string& fingerprint, const std::string& expected_fingerprint)
+{
+ ui().OnInvalidFingerprintReceived(fingerprint, expected_fingerprint);
+}
+
+
diff --git a/src/serverevents.h b/src/serverevents.h
index e6c19a0..40890ec 100644
--- a/src/serverevents.h
+++ b/src/serverevents.h
@@ -130,6 +130,7 @@ public:
void RegistrationAccepted(const std::string& user, const std::string& pass);
void RegistrationDenied(const std::string& reason);
void OnLoginDenied(const std::string& reason);
+ void OnInvalidFingerprintReceived(const std::string& fingerprint, const std::string& expected_fingerprint);
private:
IServer& m_serv;
diff --git a/src/settings.cpp b/src/settings.cpp
index c354d5e..8e0bb8d 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -35,6 +35,8 @@
const wxChar sep = wxFileName::GetPathSeparator();
const wxString sepstring = wxString(sep);
+const long CACHE_VERSION = 15;
+const long SETTINGS_VERSION = 32;
SLCONFIG("/General/SettingsVersion", SETTINGS_VERSION, "version of settings file");
SLCONFIG("/General/CacheVersion", CACHE_VERSION, "version of used cache");
SLCONFIG("/General/firstrun", true, "true if app is run first time");
@@ -107,7 +109,7 @@ void Settings::ConvertSettings(wxTranslationHelper* translationhelper, long sett
//the dummy column hack was removed on win
cfg().DeleteGroup(_T("/GUI/ColumnWidths/"));
}
- case 21: {
+ case 19: case 20: case 21: {
if (translationhelper) {
// add locale's language code to autojoin
if (translationhelper->GetLocale()) {
@@ -122,13 +124,7 @@ void Settings::ConvertSettings(wxTranslationHelper* translationhelper, long sett
case 22: {
ConvertLists();
}
- case 23: {
- DeleteServer(_T("Backup server"));
- DeleteServer(_T("Backup server 1"));
- DeleteServer(_T("Backup server 2"));
- SetDefaultServerSettings();
- }
- case 24: {
+ case 23: case 24: {
SetDisableSpringVersionCheck(false);
}
case 25: { // language id before was stored by index, now its stored by the id
@@ -140,14 +136,17 @@ void Settings::ConvertSettings(wxTranslationHelper* translationhelper, long sett
case 27: {
RemoveChannelJoin(_("main"));
}
- case 28: {
- SetDefaultServerSettings();
- }
- case 30: {
+ case 28: case 29: case 30: {
#ifdef WIN32 // https://github.com/springlobby/springlobby/issues/385
cfg().Write(_T("/GUI/UseNotificationPopups"), true);
#endif
}
+ case 31: {
+ DeleteServer(_T("Backup server 1"));
+ DeleteServer(_T("Backup server 2"));
+ SetDefaultServerSettings();
+ }
+
default: {
}
}
@@ -241,10 +240,8 @@ bool Settings::ShouldAddDefaultServerSettings()
//! @brief Restores default settings
void Settings::SetDefaultServerSettings()
{
- SetServer(DEFSETT_DEFAULT_SERVER_NAME, DEFSETT_DEFAULT_SERVER_HOST, DEFSETT_DEFAULT_SERVER_PORT);
- SetServer(_T( "Backup server 1" ), _T( "lobby1.springlobby.info" ), 8200);
- SetServer(_T( "Backup server 2" ), _T( "lobby2.springlobby.info" ), 8200);
- SetServer(_T( "Test server" ), _T( "lobby.springrts.com" ), 7000);
+ SetServer(DEFSETT_DEFAULT_SERVER_NAME, DEFSETT_DEFAULT_SERVER_HOST, DEFSETT_DEFAULT_SERVER_PORT, "0124dc0f4295b401a2d81ade3dc81b7a467eb9a70b0a4912b5e15fede735fe73");
+ SetServer("Test server", "lobby.springrts.com", 7000, "bafee3142009baa105ade65b0f712ca5fcf30de8e91664a8825e0185a609277c");
SetDefaultServer(DEFSETT_DEFAULT_SERVER_NAME);
}
@@ -290,10 +287,12 @@ wxString Settings::GetServerHost(const wxString& server_name)
//! @param server_name the server name/alias
//! @param the host url address
//! @param the port where the service is run
-void Settings::SetServer(const wxString& server_name, const wxString& url, int port)
+void Settings::SetServer(const wxString& server_name, const wxString& url, int port, const wxString& fingerprint)
{
cfg().Write(_T( "/Server/Servers/" ) + server_name + _T( "/Host" ), url);
cfg().Write(_T( "/Server/Servers/" ) + server_name + _T( "/Port" ), port);
+ cfg().Write(_T( "/Server/Servers/" ) + server_name + _T( "/TLS" ), true);
+ cfg().Write(_T( "/Server/Servers/" ) + server_name + _T( "/Certificate" ), fingerprint);
}
//! @brief Deletes a server from the list.
@@ -366,7 +365,7 @@ void Settings::SetServerAccountPass(const wxString& server_name, const wxString&
//! @todo Implement
bool Settings::GetServerAccountSavePass(const wxString& server_name)
{
- return cfg().Read(_T( "/Server/Servers/" ) + server_name + _T( "/savepass" ), (long int)false);
+ return cfg().Read(_T( "/Server/Servers/" ) + server_name + _T( "/savepass" ), (long int)DEFSETT_SAVE_PASSWORD);
}
@@ -1506,3 +1505,24 @@ unsigned int Settings::GetNotificationPopupDisplayTime()
{
return cfg().Read(_T("/GUI/NotificationPopupDisplayTime"), 5l);
}
+
+bool Settings::IsServerTLS(const std::string& server_name)
+{
+ return cfg().Read(_T( "/Server/Servers/" ) + TowxString(server_name) + _T( "/TLS" ), true);
+}
+
+void Settings::SetServerTLS(const std::string& server_name, bool enabled)
+{
+ cfg().Write(_T( "/Server/Servers/" ) + TowxString(server_name) + _T( "/TLS" ), enabled);
+}
+
+std::string Settings::GetServerFingerprint(const std::string& server_name)
+{
+ return STD_STRING(cfg().Read(_T( "/Server/Servers/" ) + TowxString(server_name) + _T( "/Certificate" ), ""));
+}
+
+void Settings::SetServerFingerprint(const std::string& server_name, const std::string& fingerprint)
+{
+ cfg().Write(_T( "/Server/Servers/" ) + TowxString(server_name) + _T( "/Certificate" ), TowxString(fingerprint));
+}
+
diff --git a/src/settings.h b/src/settings.h
index 9ac11eb..3dcf13d 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -12,15 +12,12 @@
#include "useractions.h"
#include "utils/sortutil.h"
-const long CACHE_VERSION = 15;
-const long SETTINGS_VERSION = 31;
-
const wxString DEFSETT_DEFAULT_SERVER_NAME = _T("Official server");
const wxString DEFSETT_DEFAULT_SERVER_HOST = _T("lobby.springrts.com");
const wxString BattlePostfix = _T("_battle");
const int DEFSETT_DEFAULT_SERVER_PORT = 8200;
-const bool DEFSETT_SAVE_PASSWORD = false;
+const bool DEFSETT_SAVE_PASSWORD = true;
const unsigned int DEFSETT_SPRING_PORT = 8452;
const long SET_MODE_EXPERT = 5000;
@@ -172,10 +169,17 @@ public:
wxArrayString GetServers();
bool ServerExists(const wxString& server_name);
- void SetServer(const wxString& server_name, const wxString& url, int port);
+ void SetServer(const wxString& server_name, const wxString& url, int port, const wxString& fingerprint);
void DeleteServer(const wxString& server_name);
bool ShouldAddDefaultServerSettings();
+
+ bool IsServerTLS(const std::string& server_name);
+ void SetServerTLS(const std::string& server_name, bool enabled);
+
+ std::string GetServerFingerprint(const std::string& server_name);
+ void SetServerFingerprint(const std::string& serve_name, const std::string& fingerprint);
+
/**@}*/
/* ================================================================ */
diff --git a/src/socket.cpp b/src/socket.cpp
index ab541df..c4ffcb4 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -37,6 +37,13 @@ lsl/networking/socket.cpp
#include <net/if.h>
#endif
+#ifdef SSL_SUPPORT
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#endif
+
#ifdef __WXMSW__
bool GetMac(std::vector<unsigned char>& mac)
@@ -161,9 +168,147 @@ Socket::Socket(iNetClass& netclass)
, m_net_class(netclass)
, m_rate(-1)
, m_sent(0)
+
+{
+#ifdef SSL_SUPPORT
+m_starttls = false;
+m_verified = false;
+m_sslctx = nullptr;
+m_ssl = nullptr;
+#endif
+
+}
+
+#ifdef SSL_SUPPORT
+
+// http://roxlu.com/2014/042/using-openssl-with-memory-bios
+
+void Socket::StopTLS()
+{
+ m_starttls = false;
+ m_verified = false;
+ if (m_ssl != nullptr) {
+ SSL_free(m_ssl);
+ m_ssl = nullptr;
+ SSL_CTX_free(m_sslctx);
+ m_sslctx = nullptr;
+ }
+ ERR_free_strings();
+ EVP_cleanup();
+}
+
+void Socket::DoSSLHandshake()
{
+ const int ret = SSL_do_handshake(m_ssl);
+ wxLogDebug("SSL_do_handshake(): ret %d", ret);
+ if (ret < 0) { // fatal error
+ const int r = SSL_get_error(m_ssl, ret);
+ if (SSL_ERROR_WANT_READ == r) {
+ wxLogDebug("SSL_ERROR_WANT_READ");
+ int pending = BIO_ctrl_pending(m_outbio);
+ if (pending > 0) {
+ wxLogDebug("SSL_do_handshake(): m_outbio pending == %d", pending);
+ char buf[4096];
+ const int read = BIO_read(m_outbio, buf, sizeof(buf));
+ if (read > 0) {
+ wxLogDebug("BIO_read() m_outbio: %d", read);
+ m_sock.Write(buf, read);
+ }
+ }
+ pending = BIO_ctrl_pending(m_inbio);
+ if (pending > 0) {
+ wxLogWarning("SSL_do_handshake(): m_inbio pending == %d", pending);
+ }
+
+ } else {
+ wxLogError("SSL_get_error(): %d", r);
+ Disconnect();
+ }
+ } else if (ret == 2) { //controlled shutdown
+ } // ret == 1 is successful
+}
+
+void Socket::StartTLS(const std::string& fingerprint)
+{
+ wxLogMessage("Starting TLS...");
+ m_excepted_fingerprint = fingerprint;
+ assert(!m_starttls);
+ m_starttls = true;
+ SSL_load_error_strings();
+ SSL_library_init();
+ ERR_load_BIO_strings();
+ OpenSSL_add_all_algorithms();
+ m_sslctx = SSL_CTX_new(SSLv23_client_method());
+ SSL_CTX_set_options(m_sslctx, SSL_OP_NO_SSLv3);
+ m_ssl = SSL_new(m_sslctx);
+ SSL_set_connect_state(m_ssl);
+ m_inbio = BIO_new(BIO_s_mem());
+ m_outbio = BIO_new(BIO_s_mem());
+
+ BIO_set_mem_eof_return(m_inbio, -1);
+ BIO_set_mem_eof_return(m_outbio, -1);
+ SSL_set_bio(m_ssl, m_inbio, m_outbio);
+
+ DoSSLHandshake();
+
+}
+
+bool Socket::VerifyCertificate()
+{
+ if (m_verified) {
+ return true;
+ }
+
+ X509* cert = SSL_get_peer_certificate(m_ssl);
+ if (cert == nullptr) {
+ return false;
+ }
+
+ const EVP_MD *fprint_type = EVP_sha256();
+ unsigned char fprint[EVP_MAX_MD_SIZE];
+ unsigned int fprint_size = 0;
+
+ if (!X509_digest(cert, fprint_type, fprint, &fprint_size)) {
+ return false;
+ }
+
+ std::string fingerprint;
+ char buf[4];
+ for(size_t i=0; i<fprint_size; i++) {
+ snprintf(buf, sizeof(buf), "%02x", fprint[i]);
+ fingerprint += buf[0];
+ fingerprint += buf[1];
+ }
+ m_fingerprint = fingerprint;
+ wxLogMessage("Certificate fingerprint: %s", m_fingerprint.c_str());
+
+ const char* version = SSL_get_version(m_ssl);
+ wxLogMessage("Using %s", version);
+
+ const char* name = SSL_get_cipher_name(m_ssl);
+ wxLogMessage("Using cipher %s", name);
+
+ //FIXME: read from config and prompt when missmatch / doesn't exist
+ if (fingerprint != m_excepted_fingerprint) {
+ m_net_class.OnInvalidFingerprintReceived(fingerprint);
+ return false;
+ }
+
+/* // we prefer certificate pinnig
+
+ long res = SSL_get_verify_result(ssl);
+ if(!(X509_V_OK == res)) {
+ }
+*/
+
+
+ X509_free(cert);
+ m_verified = true;
+ return true;
}
+#endif
+
//! @brief Destructor
Socket::~Socket()
@@ -198,6 +343,8 @@ void Socket::Connect(const wxString& addr, const int port)
}
InitSocket(m_sock);
+
+
m_sock.Connect(wxaddr, false);
m_sock.SetTimeout(40);
}
@@ -210,6 +357,11 @@ void Socket::SetTimeout(const int seconds)
//! @brief Disconnect from remote host if connected.
void Socket::Disconnect()
{
+#ifdef SSL_SUPPORT
+ if (m_starttls) {
+ StopTLS();
+ }
+#endif
const bool wasconnected = m_sock.IsConnected();
m_buffer.clear();
m_sock.Close();
@@ -221,6 +373,7 @@ void Socket::Disconnect()
//! @brief Send data over connection.
bool Socket::Send(const std::string& data)
{
+ wxLogDebug("Socket::Send");
m_buffer += (const char*)data.c_str();
int crop = m_buffer.length();
if (m_rate > 0) {
@@ -229,14 +382,48 @@ bool Socket::Send(const std::string& data)
crop = max;
}
std::string send = m_buffer.substr(0, crop);
+#ifdef SSL_SUPPORT
+ if (m_starttls) {
+ int res = 0;
+ if(!SSL_is_init_finished(m_ssl)) {
+ DoSSLHandshake();
+ } else {
+ if (!VerifyCertificate()) {
+ wxLogWarning("Couldn't verify certificate, closing connection");
+ Disconnect();
+ }
+ }
+
+ if (send.length() > 0) {
+ const int ret = SSL_write(m_ssl, send.c_str(), send.length());
+ if (ret > 0) {
+ res += ret;
+ } else if (ret == 0) {
+ wxLogDebug("SSL_read(); %d", ret);
+ } else {
+ wxLogWarning("SSL_read(); %d", ret);
+ }
+ }
+ if (BIO_ctrl_pending(m_outbio) > 0) {
+ char outbuf[4096];
+ const int read = BIO_read(m_outbio, outbuf, sizeof(outbuf));
+ assert(read > 0);
+ m_sock.Write(outbuf, read);
+ }
+ m_buffer.erase(0, res);
+ m_sent += res;
+ return true;
+ }
//wxLogMessage( _T("send: %d sent: %d max: %d : buff: %d"), send.length() , m_sent, max, m_buffer.length() );
+#endif
m_sock.Write(send.c_str(), send.length());
- if (!m_sock.Error()) {
- wxUint32 sentdata = m_sock.LastCount();
- m_buffer.erase(0, sentdata);
- m_sent += sentdata;
+ if (m_sock.Error()) {
+ return false;
}
- return !m_sock.Error();
+ wxUint32 sentdata = m_sock.LastCount();
+ m_buffer.erase(0, sentdata);
+ m_sent += sentdata;
+ return true;
}
@@ -282,20 +469,59 @@ wxString convert(char* buff, const int len)
//! @brief Receive data from connection
wxString Socket::Receive()
{
- wxString ret;
- static const int chunk_size = 1500;
+ wxLogDebug("Socket::Receive");
+ wxString res;
+ static const int chunk_size = 4096;
char buf[chunk_size];
int readnum = 0;
do {
m_sock.Read(buf, chunk_size);
readnum = m_sock.LastCount();
- if (readnum > 0) {
- ret += convert(buf, readnum);
+#ifdef SSL_SUPPORT
+ if (!m_starttls && (readnum == 0)) {
+ return res;
}
+#endif
+ wxLogDebug("Receive() %d", readnum);
+#ifdef SSL_SUPPORT
+ if (m_starttls) {
+ if (readnum > 0) {
+ const int written = BIO_write(m_inbio, buf, readnum);
+ if (written <= 0) {
+ wxLogDebug("BIO_write(): %d", written);
+ }
+ }
+ if(!SSL_is_init_finished(m_ssl)) {
+ DoSSLHandshake();
+ } else {
+ if (!VerifyCertificate()) {
+ wxLogWarning("Couldn't verify certificate, closing connection");
+ Disconnect();
+ return wxEmptyString;
+ }
+ int ret = 0;
+ do {
+ ret = SSL_read(m_ssl, buf, chunk_size);
+ if (ret >= 0) {
+ const std::string str(buf, ret);
+ res += convert(buf, ret);
+ } else if (ret == 0) {
+ wxLogWarning("SSL_read(); %d", ret);
+ } else {
+ wxLogDebug("SSL_read(): %d", ret);
+ }
+ } while(ret > 0);
+ }
+ } else {
+#endif
+ res += convert(buf, readnum);
+#ifdef SSL_SUPPORT
+ }
+#endif
} while (readnum > 0);
- return ret;
+ return res;
}
//! @brief Get curent socket state
diff --git a/src/socket.h b/src/socket.h
index fa13e95..8a2a6c2 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -23,6 +23,15 @@ lsl/networking/socket.h
class iNetClass;
class wxCriticalSection;
+#ifdef SSL_SUPPORT
+#include <openssl/ssl.h>
+
+//win compile hack
+#ifdef GetUserName
+#undef GetUserName
+#endif
+#endif
+
enum SockState {
SS_Closed,
SS_Connecting,
@@ -72,7 +81,10 @@ public:
void Update(int mselapsed);
void SetTimeout(const int seconds);
-
+#ifdef SSL_SUPPORT
+ void StartTLS(const std::string& fingerprint);
+ bool IsTLS() { return m_starttls; }
+#endif
private:
void OnSocketEvent(wxSocketEvent& event);
void InitSocket(wxSocketClient& socket);
@@ -87,6 +99,19 @@ private:
int m_rate;
int m_sent;
std::string m_buffer;
+#ifdef SSL_SUPPORT
+ void StopTLS();
+ void DoSSLHandshake();
+ bool VerifyCertificate();
+ bool m_verified;
+ bool m_starttls;
+ SSL_CTX *m_sslctx;
+ SSL *m_ssl;
+ BIO *m_inbio;
+ BIO *m_outbio;
+ std::string m_fingerprint;
+ std::string m_excepted_fingerprint;
+#endif
DECLARE_EVENT_TABLE();
};
diff --git a/src/tasserver.cpp b/src/tasserver.cpp
index 5e7fd8d..23209ce 100644
--- a/src/tasserver.cpp
+++ b/src/tasserver.cpp
@@ -35,7 +35,6 @@ lsl/networking/tasserver.cpp
#include "utils/version.h"
#include <lslutils/misc.h>
-
SLCONFIG("/Server/ExitMessage", "Using http://springlobby.info/", "Message which is send when leaving server");
// times in milliseconds
@@ -399,7 +398,6 @@ void TASServer::RequestChannels()
void TASServer::AcceptAgreement()
{
SendCmd("CONFIRMAGREEMENT");
- Login();
}
@@ -532,12 +530,21 @@ void TASServer::ExecuteCommand(const std::string& cmd, const std::string& inpara
UserBattleStatus bstatus;
if (cmd == "TASSERVER") {
- m_ser_ver = GetIntParam(params);
- const std::string supported_spring_version = GetWordParam(params);
- m_nat_helper_port = (unsigned long)GetIntParam(params);
- const bool lanmode = GetBoolParam(params);
- m_server_lanmode = lanmode;
- m_se->OnConnected(m_serverinfo.description, "", (m_ser_ver > 0), supported_spring_version, lanmode);
+#ifdef SSL_SUPPORT
+ if (!m_sock->IsTLS() && sett().IsServerTLS(GetServerName()) ) {
+ SendCmd("STARTTLS", "");
+ m_sock->StartTLS(sett().GetServerFingerprint(GetServerName()));
+ } else {
+#endif
+ m_ser_ver = GetIntParam(params);
+ const std::string supported_spring_version = GetWordParam(params);
+ m_nat_helper_port = (unsigned long)GetIntParam(params);
+ const bool lanmode = GetBoolParam(params);
+ m_server_lanmode = lanmode;
+ m_se->OnConnected(m_serverinfo.description, "", (m_ser_ver > 0), supported_spring_version, lanmode);
+#ifdef SSL_SUPPORT
+ }
+#endif
} else if (cmd == "ACCEPTED") {
SetUsername(params);
m_se->OnLogin();
@@ -1733,7 +1740,6 @@ void TASServer::RemoveBot(int battleid, User& bot)
}
IBattle& battle = GetBattle(battleid);
- ASSERT_LOGIC(&bot != 0, "Bot does not exist.");
if (!(battle.IsFounderMe() || (bot.BattleStatus().owner == GetMe().GetNick()))) {
DoActionBattle(battleid, "thinks the bot " + bot.GetNick() + " should be removed.");
@@ -2024,3 +2030,10 @@ bool TASServer::IsCurrentBattle(int battle_id)
}
return true;
}
+
+void TASServer::OnInvalidFingerprintReceived(const std::string& fingerprint)
+{
+ const std::string expected_fingerprint = sett().GetServerFingerprint(GetServerName());
+ m_se->OnInvalidFingerprintReceived(fingerprint, expected_fingerprint);
+}
+
diff --git a/src/tasserver.h b/src/tasserver.h
index 0848ee8..07f3d73 100644
--- a/src/tasserver.h
+++ b/src/tasserver.h
@@ -147,6 +147,7 @@ private:
void OnDisconnected(wxSocketError err) override;
void OnDataReceived() override;
void OnError(const std::string& err) override;
+ void OnInvalidFingerprintReceived(const std::string& fingerprint) override;
void UDPPing(); /// used for nat travelsal
/// generic udp "ping" function
diff --git a/tools/mxe_create_builddir.sh b/tools/mxe_create_builddir.sh
index e01746f..adf1b6a 100755
--- a/tools/mxe_create_builddir.sh
+++ b/tools/mxe_create_builddir.sh
@@ -18,7 +18,7 @@ git reset --hard $COMMIT
(
echo 'JOBS := 2'
echo 'MXE_TARGETS := i686-w64-mingw32.static'
- echo 'LOCAL_PKG_LIST := boost curl wxwidgets'
+ echo 'LOCAL_PKG_LIST := openssl boost curl wxwidgets'
echo '.DEFAULT local-pkg-list:'
echo 'local-pkg-list: $(LOCAL_PKG_LIST)'
) > settings.mk
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/springlobby.git
More information about the Pkg-games-commits
mailing list