Files
glest-source/source/glest_game/main/main.cpp
andy5995 0f469061ec glest_game/main:reformat/restyle source code [skip ci]
* used 'indent -nut -i2 -bli0 -ppi 3 *`
2018-01-25 02:21:15 -06:00

9530 lines
326 KiB
C++

// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code 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
// ==============================================================
#ifdef WIN32
# include <winsock2.h>
# include <winsock.h>
# include <process.h>
# include <io.h>
#endif
#ifdef HAVE_GOOGLE_BREAKPAD
# include "handler/exception_handler.h"
#endif
#include "math_wrapper.h"
#include "main.h"
#include <string>
#include <cstdlib>
#include "steamshim_child.h"
#include "steam.h"
#include "game.h"
#include "main_menu.h"
#include "program.h"
#include "config.h"
#include "metrics.h"
#include "game_util.h"
#include "platform_util.h"
#include "platform_main.h"
#include "network_interface.h"
#include "ImageReaders.h"
#include "renderer.h"
#include "simple_threads.h"
//#include <memory>
#include "font.h"
#include <curl/curl.h>
#include "menu_state_masterserver.h"
#include "checksum.h"
#include <algorithm>
#include "sound_renderer.h"
#include "font_gl.h"
#include "FileReader.h"
#include "cache_manager.h"
#include <iterator>
#include "core_data.h"
#include "font_text.h"
#include <locale.h>
#include "string_utils.h"
#include "auto_test.h"
#include "lua_script.h"
#include "interpolation.h"
#include "common_scoped_ptr.h"
// To handle signal catching
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
# include <signal.h>
#endif
#if defined WIN32 && !defined(HAVE_GOOGLE_BREAKPAD)
# if defined(__WIN32__) && !defined(__GNUC__)
# include <eh.h>
# endif
# include <dbghelp.h>
#endif
#ifndef WIN32
# include <poll.h>
# define stricmp strcasecmp
# define strnicmp strncasecmp
# define _strnicmp strncasecmp
#endif
#include <stdlib.h>
#include "network_message.h"
#include "network_protocol.h"
#include "conversion.h"
#include "gen_uuid.h"
//#include "intro.h"
#include "leak_dumper.h"
#if defined(WIN32)
# ifndef _DEBUG
# ifndef __GNUC__
# define WIN32_STACK_TRACE
# endif
# endif
#endif
using namespace std;
using namespace
Shared::Platform;
using namespace Shared::Util;
using namespace Shared::Graphics;
using namespace Shared::Graphics::Gl;
using namespace Shared::Xml;
using namespace Shared;
/**
* @namespace Glest
* Namespace used for all %Glest related code.
*/
/**
* @namespace Game
* Namespace used for game related code.
*/
namespace
Glest
{
namespace
Game
{
static
string
tempDataLocation = getUserHome ();
static
string
mg_app_name = "";
static
string
mailStringSupport = "";
static
bool
sdl_quitCalled = false;
static
bool
disableheadless_console = false;
static
bool
disableBacktrace = false;
static
bool
gameInitialized = false;
static Program *
mainProgram = NULL;
static FileCRCPreCacheThread *
preCacheThread = NULL;
#ifdef WIN32
static
string
runtimeErrorMsg = "";
// keeps in scope for duration of the application
//SocketManager *winSockManager = NULL;
#endif
#ifdef HAVE_GOOGLE_BREAKPAD
auto_ptr <
google_breakpad::ExceptionHandler >
errorHandlerPtr;
#endif
class
NavtiveLanguageNameListCacheGenerator:
public
SimpleTaskCallbackInterface
{
virtual void
simpleTask (BaseThread * callingThread, void *userdata)
{
Lang & lang = Lang::getInstance ();
lang.
getDiscoveredLanguageList (true);
}
};
// =====================================================
// class ExceptionHandler
// =====================================================
class
ExceptionHandler:
public
PlatformExceptionHandler
{
public:
#if defined(__WIN32__) && !defined(__GNUC__)
virtual void
handle (LPEXCEPTION_POINTERS pointers);
#endif
virtual void
handle ();
static void
logError (const char *msg, bool confirmToConsole);
static void
handleRuntimeError (const megaglest_runtime_error & ex);
static void
handleRuntimeError (const char *msg, bool getStackTraceString);
static int
DisplayMessage (const char *msg, bool exitApp);
};
void
cleanupCRCThread ()
{
if (preCacheThread != NULL)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
const double
MAX_THREAD_WAIT = 60;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("START - shutting down crc threads\n");
time_t
elapsed = time (NULL);
preCacheThread->
signalQuit ();
for (; preCacheThread->canShutdown (false) == false &&
difftime ((long int) time (NULL), elapsed) <= MAX_THREAD_WAIT;)
{
}
if (difftime ((long int) time (NULL), elapsed) <= MAX_THREAD_WAIT)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("B - shutting down crc threads\n");
for (; preCacheThread->shutdownAndWait () == false &&
difftime ((long int) time (NULL), elapsed) <= MAX_THREAD_WAIT;)
{
}
if (preCacheThread->getRunningStatus () == false)
{
delete
preCacheThread;
preCacheThread = NULL;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("C - shutting down crc threads\n");
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__,
__LINE__);
}
else
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("D - shutting down crc threads\n");
if (preCacheThread->canShutdown (false) == true)
{
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
delete
preCacheThread;
preCacheThread = NULL;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("E - shutting down crc threads\n");
}
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("F - shutting down crc threads\n");
preCacheThread = NULL;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
}
static void
cleanupProcessObjects ()
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
showCursor (true);
restoreVideoMode (::Shared::Platform::Window::getSDLWindow (), true);
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("#1 IRCCLient Cache SHUTDOWN\n");
IRCThread *&
ircClient =
CacheManager::getCachedItem <
IRCThread * >(GameConstants::ircClientCacheLookupKey);
if (ircClient != NULL)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("#2 IRCCLient Cache SHUTDOWN\n");
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
enabled)
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
ircClient->disconnect ();
ircClient->signalQuit ();
ircClient = NULL;
sleep (0);
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("#4 IRCCLient Cache SHUTDOWN\n");
cleanupCRCThread ();
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
if (Renderer::isEnded () == false)
{
Renderer::getInstance ().end ();
CoreData & coreData = CoreData::getInstance ();
coreData.cleanup ();
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::Close ();
SystemFlags::SHUTDOWN_PROGRAM_MODE = true;
//printf("Closing IRC CLient %d\n",__LINE__);
Thread::shutdownThreads ();
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("start running threads = " MG_SIZE_T_SPECIFIER "\n",
Thread::getThreadList ().size ());
time_t
elapsed = time (NULL);
int
lastLazyThreadDump = 0;
for (; Thread::getThreadList ().size () > 0 &&
difftime ((long int) time (NULL), elapsed) <= 10;)
{
if (difftime ((long int) time (NULL), elapsed) > 1)
{
if (lastLazyThreadDump !=
(int) difftime ((long int) time (NULL), elapsed))
{
lastLazyThreadDump = difftime ((long int) time (NULL), elapsed);
printf ("Waiting for the following threads to exit ["
MG_SIZE_T_SPECIFIER "]:\n",
Thread::getThreadList ().size ());
for (int i = 0; i < (int) Thread::getThreadList ().size (); ++i)
{
BaseThread *
baseThread =
dynamic_cast < BaseThread * >(Thread::getThreadList ()[i]);
printf
("Thread index: %d ptr [%p] isBaseThread: %d, Name: [%s]\n",
i, baseThread, (baseThread != NULL ? 1 : 0),
(baseThread !=
NULL ? baseThread->getUniqueID ().c_str () : "<na>"));
}
}
}
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("end running threads = " MG_SIZE_T_SPECIFIER "\n",
Thread::getThreadList ().size ());
Thread::shutdownThreads ();
std::map < int,
Texture2D * >&
crcPlayerTextureCache = CacheManager::getCachedItem < std::map < int,
Texture2D * >>(GameConstants::playerTextureCacheLookupKey);
crcPlayerTextureCache.clear ();
std::map < string, Texture2D * >&crcFactionPreviewTextureCache =
CacheManager::getCachedItem < std::map < string,
Texture2D * > >(GameConstants::factionPreviewTextureCacheLookupKey);
crcFactionPreviewTextureCache.clear ();
std::map < string, vector < FileReader < Pixmap2D > const *>*>&
list2d = FileReader < Pixmap2D >::getFileReadersMap ();
deleteMapValues (list2d.begin (), list2d.end ());
std::map < string, vector < FileReader < Pixmap3D > const *>*>&
list3d = FileReader < Pixmap3D >::getFileReadersMap ();
deleteMapValues (list3d.begin (), list3d.end ());
#if defined(WANT_XERCES)
XmlIo::getInstance ().cleanup ();
#endif
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::globalCleanupHTTP ();
CacheManager::cleanupMutexes ();
}
#if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__)
void
fatal (const char *s, ...) // failure exit
{
static int
errors = 0;
errors++;
if (errors <= 5)
{ // print up to two extra recursive errors
defvformatstring (msg, s, s);
string
errText = string (msg) + " [" + runtimeErrorMsg + "]";
//puts(msg);
string
sErr = string (mg_app_name) + " fatal error";
SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n",
errText.c_str ());
SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n",
errText.c_str ());
if (errors <= 1)
{ // avoid recursion
if (SDL_WasInit (SDL_INIT_VIDEO))
{
SDL_SetRelativeMouseMode (SDL_FALSE);
}
# ifdef WIN32
LPWSTR
wstr = Ansi2WideString (errText.c_str ());
LPWSTR
wstr1 = Ansi2WideString (sErr.c_str ());
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
MessageBox (NULL, wstr, wstr1, MB_OK | MB_SYSTEMMODAL);
}
if (wstr)
delete[]wstr;
if (wstr1)
delete[]wstr1;
# endif
}
}
// Now try to shutdown threads if possible
delete
mainProgram;
mainProgram = NULL;
// END
if (sdl_quitCalled == false)
{
sdl_quitCalled = true;
SDL_Quit ();
}
exit (EXIT_FAILURE);
}
std::string get_module_path (HMODULE module = 0)
{
char
path_name[MAX_PATH] = { };
DWORD
size = GetModuleFileNameA (module, path_name, MAX_PATH);
return std::string (path_name, size);
}
void
write_module_name (string & out, HANDLE process, DWORD64 program_counter)
{
DWORD64
module_base = SymGetModuleBase64 (process, program_counter);
if (module_base)
{
std::string module_name =
get_module_path (reinterpret_cast < HMODULE > (module_base));
if (!module_name.empty ())
out += module_name + "|";
else
out += "Unknown module|";
}
else
{
out += "Unknown module|";
}
}
void
write_function_name (string & out, HANDLE process,
DWORD64 program_counter)
{
SYMBOL_INFO_PACKAGE
sym = {
sizeof (sym)
};
sym.si.MaxNameLen = MAX_SYM_NAME;
if (SymFromAddr (process, program_counter, 0, &sym.si))
{
out += string (sym.si.Name) + "()";
}
else
{
out += "Unknown function";
}
}
void
write_file_and_line (string & out, HANDLE process,
DWORD64 program_counter)
{
IMAGEHLP_LINE64
ih_line = {
sizeof (IMAGEHLP_LINE64)
};
DWORD
dummy = 0;
if (SymGetLineFromAddr64 (process, program_counter, &dummy, &ih_line))
{
out +=
string ("|") + string (ih_line.FileName) + ":" +
intToStr (ih_line.LineNumber);
}
}
void
generate_stack_trace (string & out, CONTEXT ctx, int skip)
{
STACKFRAME64
sf = {
};
# if !defined(_WIN64)
sf.AddrPC.Offset = ctx.Eip;
# else
sf.AddrPC.Offset = ctx.Rip;
# endif
sf.AddrPC.Mode = AddrModeFlat;
# if !defined(_WIN64)
sf.AddrStack.Offset = ctx.Esp;
# else
sf.AddrStack.Offset = ctx.Rsp;
# endif
sf.AddrStack.Mode = AddrModeFlat;
# if !defined(_WIN64)
sf.AddrFrame.Offset = ctx.Ebp;
# else
sf.AddrFrame.Offset = ctx.Rbp;
# endif
sf.AddrFrame.Mode = AddrModeFlat;
HANDLE
process = GetCurrentProcess ();
HANDLE
thread = GetCurrentThread ();
bool
tryThreadContext = true;
CONTEXT
threadContext;
memset (&threadContext, 0, sizeof (CONTEXT));
threadContext.ContextFlags = CONTEXT_FULL;
for (;;)
{
SetLastError (0);
# if !defined(_WIN64)
BOOL
stack_walk_ok = StackWalk64 (IMAGE_FILE_MACHINE_I386,
# else
BOOL
stack_walk_ok = StackWalk64 (IMAGE_FILE_MACHINE_AMD64,
# endif
process, thread, &sf,
(tryThreadContext ==
false ? &threadContext : &ctx),
0, &SymFunctionTableAccess64,
&SymGetModuleBase64, 0);
if (!stack_walk_ok || !sf.AddrFrame.Offset)
{
if (tryThreadContext == true)
{
tryThreadContext = false;
if (GetThreadContext (thread, &threadContext) != 0)
{
# if !defined(_WIN64)
sf.AddrPC.Offset = threadContext.Eip;
# else
sf.AddrPC.Offset = threadContext.Rip;
# endif
sf.AddrPC.Mode = AddrModeFlat;
# if !defined(_WIN64)
sf.AddrStack.Offset = threadContext.Esp;
# else
sf.AddrStack.Offset = threadContext.Rsp;
# endif
sf.AddrStack.Mode = AddrModeFlat;
# if !defined(_WIN64)
sf.AddrFrame.Offset = threadContext.Ebp;
# else
sf.AddrFrame.Offset = threadContext.Rbp;
# endif
sf.AddrFrame.Mode = AddrModeFlat;
}
else
{
return;
}
}
else
{
return;
}
}
if (skip)
{
--skip;
}
else
{
// write the address
out += intToStr (sf.AddrPC.Offset) + "|";
write_module_name (out, process, sf.AddrPC.Offset);
write_function_name (out, process, sf.AddrPC.Offset);
write_file_and_line (out, process, sf.AddrPC.Offset);
out += "\n";
}
}
}
struct UntypedException
{
explicit
UntypedException (const EXCEPTION_RECORD & er):
exception_object (reinterpret_cast <
void *>(er.ExceptionInformation[1])),
type_array (reinterpret_cast <
_ThrowInfo *
>(er.ExceptionInformation[2])->pCatchableTypeArray)
{
}
void *
exception_object;
_CatchableTypeArray *
type_array;
};
void *
exception_cast_worker (const UntypedException & e, const type_info & ti)
{
for (int i = 0; i < e.type_array->nCatchableTypes; ++i)
{
_CatchableType & type_i = *e.type_array->arrayOfCatchableTypes[i];
const
std::type_info &
ti_i = *reinterpret_cast < std::type_info * >(type_i.pType);
if (ti_i == ti)
{
char *
base_address = reinterpret_cast < char *>(e.exception_object);
base_address += type_i.thisDisplacement.mdisp;
return base_address;
}
}
return 0;
}
template < typename T > T * exception_cast (const UntypedException & e)
{
const
std::type_info &
ti = typeid (T);
return reinterpret_cast < T * >(exception_cast_worker (e, ti));
}
void
stackdumper (unsigned int type, EXCEPTION_POINTERS * ep, bool fatalExit)
{
# ifdef HAVE_GOOGLE_BREAKPAD
if (errorHandlerPtr.get () != NULL)
{
errorHandlerPtr->WriteMinidump ();
}
# endif
if (!ep)
{
fatal ("unknown type");
return;
}
EXCEPTION_RECORD *
er = ep->ExceptionRecord;
CONTEXT *
context = ep->ContextRecord;
string
out = "";
int
skip = 0;
switch (er->ExceptionCode)
{
case 0xE06D7363:
{ // C++ exception
UntypedException
ue (*er);
if (std::exception * e = exception_cast < std::exception > (ue))
{
const
std::type_info &
ti = typeid (*e);
out += string (ti.name ()) + ":" + string (e->what ());
}
else
{
out += "Unknown C++ exception thrown.";
}
skip = 2; // skip RaiseException and _CxxThrowException
}
break;
case EXCEPTION_ACCESS_VIOLATION:
{
out += string ("Access violation. Illegal ")
+ (er->ExceptionInformation[0] ? "write" : "read")
+ string (" by ")
+ intToStr ((int) er->ExceptionAddress)
+ string (" at ") + intToStr (er->ExceptionInformation[1]);
} break;
default:
{
out += "SEH exception thrown. Exception code: "
+ er->ExceptionCode
+ string (" at ") + intToStr ((int) er->ExceptionAddress);
}
}
generate_stack_trace (out, *context, skip);
if (fatalExit == true)
{
fatal (out.c_str ());
}
else
{
ExceptionHandler::logError (out.c_str (), true);
}
}
#endif
// =====================================================
// class ExceptionHandler
// =====================================================
#if defined(WIN32) && !defined(__GNUC__)
void
ExceptionHandler::handle (LPEXCEPTION_POINTERS pointers)
{
string
msg =
"#1 An error occurred and " + string (mg_app_name) +
" will close.\nPlease report this bug to: " + string (mailString);
msg +=
", attaching the generated " + getCrashDumpFileName () + " file.";
SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n",
msg.c_str ());
SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n",
msg.c_str ());
stackdumper (0, pointers, false);
if (mainProgram && gameInitialized == true)
{
mainProgram->showMessage (msg.c_str ());
}
message (msg.c_str (),
GlobalStaticFlags::getIsNonGraphicalModeEnabled (),
tempDataLocation);
}
#endif
void
ExceptionHandler::handle ()
{
string
msg =
"#1 An error occurred and " + string (mg_app_name) +
" will close.\nPlease report this bug to: " + string (mailString);
#ifdef WIN32
msg +=
", attaching the generated " + getCrashDumpFileName () + " file.";
#endif
SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n",
msg.c_str ());
SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n",
msg.c_str ());
if (mainProgram && gameInitialized == true)
{
mainProgram->showMessage (msg.c_str ());
}
message (msg.c_str (),
GlobalStaticFlags::getIsNonGraphicalModeEnabled (),
tempDataLocation);
}
void
ExceptionHandler::logError (const char *msg, bool confirmToConsole)
{
string
errorLogFile = "error.log";
if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) !=
"")
{
errorLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
errorLogFile;
}
else
{
string
userData = Config::getInstance ().getString ("UserData_Root", "");
if (userData != "")
{
endPathWithSlash (userData);
}
errorLogFile = userData + errorLogFile;
}
#if defined(WIN32) && !defined(__MINGW32__)
FILE *
fp = _wfopen (utf8_decode (errorLogFile).c_str (), L"w");
std::ofstream logFile (fp);
#else
std::ofstream logFile;
logFile.open (errorLogFile.c_str (), ios_base::out | ios_base::trunc);
#endif
if (logFile.is_open () == true)
{
//time_t curtime = time (NULL);
//struct tm *loctime = localtime (&curtime);
struct tm
loctime = threadsafe_localtime (systemtime_now ());
char
szBuf2[100] = "";
strftime (szBuf2, 100, "%Y-%m-%d %H:%M:%S", &loctime);
logFile << "[" << szBuf2 << "] Runtime Error information:" <<
std::endl;
logFile << "======================================================" <<
std::endl;
logFile << (msg != NULL ? msg : "null") << std::endl;
logFile.close ();
#if defined(WIN32) && !defined(__MINGW32__)
if (fp)
{
fclose (fp);
}
#endif
if (confirmToConsole == true)
{
printf ("Error saved to logfile [%s]\n", errorLogFile.c_str ());
fflush (stdout);
}
}
else
{
if (confirmToConsole == true)
{
printf ("COULD NOT SAVE TO ERROR logfile [%s]\n",
errorLogFile.c_str ());
fflush (stdout);
}
}
}
void
ExceptionHandler::handleRuntimeError (const megaglest_runtime_error & ex)
{
const char *
msg = ex.what ();
handleRuntimeError (msg, false);
}
void
ExceptionHandler::handleRuntimeError (const char *msg,
bool getStackTraceString)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
static
bool
inErrorNow = false;
if (inErrorNow == true)
{
printf ("\n=====================================\n");
printf ("\n** Already in error handler aborting, msg [%s]\n", msg);
fflush (stdout);
abort ();
//return;
}
inErrorNow = true;
logError (msg, true);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf
("In [%s::%s Line: %d] program = %p gameInitialized = %d msg [%s]\n",
__FILE__, __FUNCTION__, __LINE__, mainProgram, gameInitialized,
msg);
SystemFlags::OutputDebug (SystemFlags::debugError,
"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",
__FILE__, __FUNCTION__, __LINE__, msg,
gameInitialized, mainProgram);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",
__FILE__, __FUNCTION__, __LINE__, msg,
gameInitialized, mainProgram);
string
errMsg = (msg != NULL ? msg : "null");
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
bool
gotStackTrace = false;
if (getStackTraceString == true && disableBacktrace == false
&& sdl_quitCalled == false)
{
string
stackTrace = getStackTrace ();
errMsg += stackTrace;
gotStackTrace = true;
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
logError (errMsg.c_str (), false);
if (gotStackTrace == true)
{
SystemFlags::OutputDebug (SystemFlags::debugError,
"In [%s::%s Line: %d] [%s]\n", __FILE__,
__FUNCTION__, __LINE__, errMsg.c_str ());
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%s]\n", __FILE__,
__FUNCTION__, __LINE__, errMsg.c_str ());
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
//abort();
if (mainProgram && gameInitialized == true)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
if (mainProgram->getState () != NULL)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__,
__LINE__);
mainProgram->showMessage (errMsg.c_str ());
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__,
__LINE__);
if (glActiveTexture != NULL)
{
for (;
GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false
&& mainProgram->isMessageShowing ();)
{
::Shared::Platform::Window::handleEvent ();
try
{
mainProgram->loop ();
}
catch (const exception & e)
{
printf ("\n=====================================\n");
printf
("\n** Already in error handler exiting error rendering, msg [%s]\n",
e.what ());
fflush (stdout);
break;
}
}
}
}
else
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__,
__LINE__);
mainProgram->showMessage (errMsg.c_str ());
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__,
__LINE__);
if (glActiveTexture != NULL)
{
for (;
GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false
&& mainProgram->isMessageShowing ();)
{
::Shared::Platform::Window::handleEvent ();
try
{
mainProgram->loop ();
}
catch (const exception & e)
{
printf ("\n=====================================\n");
printf
("\n** Already in error handler exiting error rendering, msg [%s]\n",
e.what ());
fflush (stdout);
break;
}
}
}
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
}
else
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
string
err = "#2 An error occurred and ";
if (sdl_quitCalled == false)
{
err += mg_app_name;
}
err +=
" will close.\nError msg = [" + errMsg +
"]\n\nPlease report this bug to ";
if (sdl_quitCalled == false)
{
err += mailStringSupport;
}
#ifdef WIN32
err +=
string (", attaching the generated ") + getCrashDumpFileName () +
string (" file.");
#endif
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
message (err, GlobalStaticFlags::getIsNonGraphicalModeEnabled (),
tempDataLocation);
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
// Now try to shutdown threads if possible
delete
mainProgram;
mainProgram = NULL;
// END
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
#ifdef WIN32
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
showCursor (true);
restoreVideoMode (::Shared::Platform::Window::getSDLWindow (), true);
}
runtimeErrorMsg = errMsg;
inErrorNow = false;
throw
runtimeErrorMsg;
#endif
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
cleanupProcessObjects ();
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
if (sdl_quitCalled == false)
{
sdl_quitCalled = true;
SDL_Quit ();
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
inErrorNow = false;
abort ();
}
int
ExceptionHandler::DisplayMessage (const char *msg, bool exitApp)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__,
__FUNCTION__, __LINE__, msg, exitApp);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] msg [%s] exitApp = %d\n",
__FILE__, __FUNCTION__, __LINE__, msg,
exitApp);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__,
__FUNCTION__, __LINE__, msg, exitApp);
if (mainProgram && gameInitialized == true)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__,
__FUNCTION__, __LINE__, msg, exitApp);
mainProgram->showMessage (msg);
}
else
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__,
__FUNCTION__, __LINE__, msg, exitApp);
message (msg, GlobalStaticFlags::getIsNonGraphicalModeEnabled (),
tempDataLocation);
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__,
__FUNCTION__, __LINE__, msg, exitApp);
if (exitApp == true)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", msg);
// Now try to shutdown threads if possible
delete
mainProgram;
mainProgram = NULL;
// END
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__,
__FUNCTION__, __LINE__, msg, exitApp);
cleanupProcessObjects ();
if (sdl_quitCalled == false)
{
sdl_quitCalled = true;
SDL_Quit ();
}
exit (-1);
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__,
__FUNCTION__, __LINE__, msg, exitApp);
return 0;
}
// =====================================================
// class MainWindow
// =====================================================
MainWindow::MainWindow (Program * program):WindowGl (), popupMenu ("MainWindow",
"popupMenu")
{
this->program = program;
//this->popupMenu.registerGraphicComponentOnlyFontCallbacks("MainWindow", "popupMenu");
this->popupMenu.setEnabled (false);
this->popupMenu.setVisible (false);
this->triggerLanguageToggle = false;
this->triggerLanguage = "";
this->cancelLanguageSelection = -1;
}
MainWindow::~MainWindow ()
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
delete
program;
program = NULL;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
}
int
MainWindow::getDesiredScreenWidth ()
{
Config & config = Config::getInstance ();
return config.getInt ("ScreenWidth");
}
int
MainWindow::getDesiredScreenHeight ()
{
Config & config = Config::getInstance ();
return config.getInt ("ScreenHeight");
}
void
MainWindow::eventToggleFullScreen (bool isFullscreen)
{
WindowGl::eventToggleFullScreen (isFullscreen);
if (isFullscreen)
{
Metrics::reload (this->program->getWindow ()->getScreenWidth (),
this->program->getWindow ()->getScreenHeight ());
}
else
{
Config & config = Config::getInstance ();
Metrics::reload (config.getInt ("ScreenWidth"),
config.getInt ("ScreenHeight"));
//window->setText(config.getString("WindowTitle","MegaGlest"));
//this->mainMenu->init();
}
}
void
MainWindow::eventMouseDown (int x, int y, MouseButton mouseButton)
{
const
Metrics &
metrics = Metrics::getInstance ();
int
vx = metrics.toVirtualX (x);
int
vy = metrics.toVirtualY (getH () - y);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventMouseDown] ERROR, program == NULL!");
}
if (popupMenu.getVisible () == true && popupMenu.mouseClick (vx, vy))
{
std::pair < int,
string >
result = popupMenu.mouseClickedMenuItem (vx, vy);
popupMenu.setEnabled (false);
popupMenu.setVisible (false);
// Exit game
if (result.first != cancelLanguageSelection)
{
Lang & lang = Lang::getInstance ();
map < string, string > languageList =
lang.getDiscoveredLanguageList (true);
for (map < string, string >::iterator iterMap =
languageList.begin (); iterMap != languageList.end ();
++iterMap)
{
string
matchLanguage = iterMap->first + "-" + iterMap->second;
if (matchLanguage == result.second)
{
this->triggerLanguageToggle = true;
this->triggerLanguage = iterMap->first;
break;
}
}
}
return;
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
switch (mouseButton)
{
case mbLeft:
program->mouseDownLeft (vx, vy);
break;
case mbRight:
//program->mouseDownRight(vx, vy);
break;
case mbCenter:
//program->mouseDownCenter(vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
ProgramState *
programState = program->getState ();
if (programState != NULL)
{
switch (mouseButton)
{
case mbLeft:
programState->mouseDownLeft (vx, vy);
break;
case mbRight:
programState->mouseDownRight (vx, vy);
break;
case mbCenter:
programState->mouseDownCenter (vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
void
MainWindow::eventMouseUp (int x, int y, MouseButton mouseButton)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
const
Metrics &
metrics = Metrics::getInstance ();
int
vx = metrics.toVirtualX (x);
int
vy = metrics.toVirtualY (getH () - y);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventMouseUp] ERROR, program == NULL!");
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
ProgramState *
programState = program->getState ();
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
if (programState != NULL)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
switch (mouseButton)
{
case mbLeft:
programState->mouseUpLeft (vx, vy);
break;
case mbRight:
programState->mouseUpRight (vx, vy);
break;
case mbCenter:
programState->mouseUpCenter (vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
void
MainWindow::eventMouseDoubleClick (int x, int y, MouseButton mouseButton)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
const
Metrics &
metrics = Metrics::getInstance ();
int
vx = metrics.toVirtualX (x);
int
vy = metrics.toVirtualY (getH () - y);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventMouseDoubleClick] ERROR, program == NULL!");
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
ProgramState *
programState = program->getState ();
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
if (programState != NULL)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
switch (mouseButton)
{
case mbLeft:
programState->mouseDoubleClickLeft (vx, vy);
break;
case mbRight:
programState->mouseDoubleClickRight (vx, vy);
break;
case mbCenter:
programState->mouseDoubleClickCenter (vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
void
MainWindow::eventMouseMove (int x, int y, const MouseState * ms)
{
const
Metrics &
metrics = Metrics::getInstance ();
int
vx = metrics.toVirtualX (x);
int
vy = metrics.toVirtualY (getH () - y);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventMouseMove] ERROR, program == NULL!");
}
program->eventMouseMove (vx, vy, ms);
ProgramState *
programState = program->getState ();
if (programState != NULL)
{
programState->mouseMove (vx, vy, ms);
}
}
void
MainWindow::eventMouseWheel (int x, int y, int zDelta)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
const
Metrics &
metrics = Metrics::getInstance ();
int
vx = metrics.toVirtualX (x);
int
vy = metrics.toVirtualY (getH () - y);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventMouseMove] ERROR, program == NULL!");
}
ProgramState *
programState = program->getState ();
if (programState != NULL)
{
programState->eventMouseWheel (vx, vy, zDelta);
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
void
MainWindow::render ()
{
if (popupMenu.getVisible () == true)
{
Renderer & renderer = Renderer::getInstance ();
renderer.renderPopupMenu (&popupMenu);
}
}
void
MainWindow::showLanguages ()
{
Lang & lang = Lang::getInstance ();
std::vector < string > menuItems;
map < string, string > languageList =
lang.getDiscoveredLanguageList (true);
for (map < string, string >::iterator iterMap = languageList.begin ();
iterMap != languageList.end (); ++iterMap)
{
menuItems.push_back (iterMap->first + "-" + iterMap->second);
}
menuItems.push_back (lang.getString ("Exit"));
cancelLanguageSelection = (int) menuItems.size () - 1;
popupMenu.setW (100);
popupMenu.setH (100);
popupMenu.init (lang.getString ("GameMenuTitle"), menuItems);
popupMenu.setEnabled (true);
popupMenu.setVisible (true);
}
void
MainWindow::toggleLanguage (string language)
{
popupMenu.setEnabled (false);
popupMenu.setVisible (false);
this->triggerLanguageToggle = false;
this->triggerLanguage = "";
Lang & lang = Lang::getInstance ();
string
currentLanguage = lang.getLanguage ();
string
newLanguageSelected = language;
if (language == "")
{
newLanguageSelected = currentLanguage;
vector < string > langResults;
string
data_path =
getGameReadWritePath (GameConstants::path_data_CacheLookupKey);
string
userDataPath = getGameCustomCoreDataPath (data_path, "");
findAll (userDataPath + "data/lang/*.lng", langResults, true, false);
vector < string > langResults2;
findAll (data_path + "data/lang/*.lng", langResults2, true);
if (langResults2.empty () && langResults.empty ())
{
throw
megaglest_runtime_error ("There are no lang files");
}
for (unsigned int i = 0; i < langResults2.size (); ++i)
{
string
testLanguage = langResults2[i];
if (std::find (langResults.begin (), langResults.end (),
testLanguage) == langResults.end ())
{
langResults.push_back (testLanguage);
}
}
for (unsigned int i = 0; i < langResults.size (); ++i)
{
string
testLanguage = langResults[i];
if (testLanguage == currentLanguage)
{
if (i + 1 < langResults.size ())
{
newLanguageSelected = langResults[i + 1];
}
else
{
newLanguageSelected = langResults[0];
}
break;
}
}
}
if (newLanguageSelected != currentLanguage)
{
lang.loadGameStrings (newLanguageSelected);
program->reloadUI ();
program->consoleAddLine (lang.getString ("Language") + " " +
newLanguageSelected);
}
}
bool
MainWindow::eventTextInput (std::string text)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%s]\n", __FILE__,
__FUNCTION__, __LINE__, text.c_str ());
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventKeyDown] ERROR, program == NULL!");
}
bool
result = program->textInput (text);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] result = %d\n",
__FILE__, __FUNCTION__, __LINE__, result);
return result;
}
bool
MainWindow::eventSdlKeyDown (SDL_KeyboardEvent key)
{
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventKeyDown] ERROR, program == NULL!");
}
return program->sdlKeyDown (key);
}
void
MainWindow::eventKeyDown (SDL_KeyboardEvent key)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%d]\n", __FILE__,
__FUNCTION__, __LINE__, key.keysym.sym);
//printf("In mainwindow checking keypress for key [%d]\n",key.keysym.sym);
SDL_keysym
keystate = key.keysym;
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] key = [%c][%d]\n",
__FILE__, __FUNCTION__, __LINE__, key, key);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventKeyDown] ERROR, program == NULL!");
}
if (popupMenu.getVisible () == true
&& isKeyPressed (SDLK_ESCAPE, key) == true)
{
this->popupMenu.setEnabled (false);
this->popupMenu.setVisible (false);
return;
}
program->keyDown (key);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
if (keystate.mod & (KMOD_LALT | KMOD_RALT))
{
//if(key == vkReturn) {
if (isKeyPressed (SDLK_RETURN, key) == true)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] ALT-ENTER pressed\n",
__FILE__, __FUNCTION__, __LINE__);
// This stupidity only required in win32.
// We reload the textures so that the canvas paints textures properly
#ifdef WIN32
if (Window::getAllowAltEnterFullscreenToggle () == true)
{
Renderer & renderer = Renderer::getInstance ();
renderer.reinitAll ();
}
#endif
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
}
//printf("In mainwindow checking keypress for key [%d] mod [%d] modvalue: %d\n",key.keysym.sym,keystate.mod,(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)));
if (program != NULL && program->isInSpecialKeyCaptureEvent () == false)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
vector < int >
modifiersToCheck;
modifiersToCheck.push_back (KMOD_LCTRL);
modifiersToCheck.push_back (KMOD_RCTRL);
modifiersToCheck.push_back (KMOD_LALT);
modifiersToCheck.push_back (KMOD_RALT);
modifiersToCheck.push_back (KMOD_LSHIFT);
modifiersToCheck.push_back (KMOD_RSHIFT);
Config & configKeys =
Config::getInstance (std::pair < ConfigType,
ConfigType > (cfgMainKeys, cfgUserKeys));
if (isKeyPressed (configKeys.getSDLKey ("HotKeyShowDebug"), key) ==
true)
{
Renderer & renderer = Renderer::getInstance ();
if (keystate.mod & (KMOD_LALT | KMOD_RALT))
{
renderer.cycleShowDebugUILevel ();
printf ("**Cycled Debug UI level to: %d\n",
renderer.getShowDebugUILevel ());
}
else
{
bool
showDebugUI = renderer.getShowDebugUI ();
renderer.setShowDebugUI (!showDebugUI);
}
}
else if ((keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) &&
isKeyPressed (configKeys.getSDLKey ("SwitchLanguage"),
key) == true)
{
if ((keystate.mod & (KMOD_LSHIFT | KMOD_RSHIFT)))
{
this->triggerLanguageToggle = true;
this->triggerLanguage = "";
}
else
{
showLanguages ();
}
}
else
if (isKeyPressed
(configKeys.getSDLKey ("ReloadINI"), key,
modifiersToCheck) == true)
{
Config & config = Config::getInstance ();
config.reload ();
}
else
if (isKeyPressed
(configKeys.getSDLKey ("Screenshot"), key,
modifiersToCheck) == true)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Screenshot key pressed\n");
string
userData = Config::getInstance ().getString ("UserData_Root", "");
if (userData != "")
{
endPathWithSlash (userData);
}
string
path = userData + GameConstants::folder_path_screenshots;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Screenshot checking path [%s]\n", path.c_str ());
if (isdir (path.c_str ()) == false)
{
createDirectoryPaths (path);
}
if (isdir (path.c_str ()) == true)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Screenshot path [%s]\n", path.c_str ());
Config & config = Config::getInstance ();
string
fileFormat = config.getString ("ScreenShotFileType", "jpg");
unsigned int
queueSize = Renderer::getInstance ().getSaveScreenQueueSize ();
for (int i = 0; i < 5000; ++i)
{
path = userData + GameConstants::folder_path_screenshots;
path +=
string ("screen") + intToStr (i + queueSize) + string (".") +
fileFormat;
#ifdef WIN32
FILE *
f = _wfopen (utf8_decode (path).c_str (), L"rb");
#else
FILE *
f = fopen (path.c_str (), "rb");
#endif
if (f == NULL)
{
Lang & lang = Lang::getInstance ();
char
szBuf[8096] = "";
if (lang.getString ("ScreenshotSavedTo").length () > 0
&& lang.getString ("ScreenshotSavedTo")[0] != '?')
{
snprintf (szBuf, 8096,
lang.getString ("ScreenshotSavedTo").c_str (),
path.c_str ());
}
else
{
snprintf (szBuf, 8096, "Screenshot will be saved to: %s",
path.c_str ());
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__,
__LINE__, szBuf);
bool
showScreenshotSavedMsg =
Config::getInstance ().
getBool ("DisableScreenshotConsoleText", "false");
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Screenshot console showScreenshotSavedMsg = %d\n",
showScreenshotSavedMsg);
if (showScreenshotSavedMsg == false)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Screenshot console [%s]\n", szBuf);
program->consoleAddLine (szBuf);
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Screenshot save to [%s]\n", path.c_str ());
Renderer::getInstance ().saveScreen (path);
break;
}
else
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("CANNOT save Screenshot [%s]\n", path.c_str ());
fclose (f);
}
}
}
}
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
}
void
MainWindow::eventKeyUp (SDL_KeyboardEvent key)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%d]\n", __FILE__,
__FUNCTION__, __LINE__, key);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventKeyUp] ERROR, program == NULL!");
}
program->keyUp (key);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%d]\n", __FILE__,
__FUNCTION__, __LINE__, key);
}
void
MainWindow::eventKeyPress (SDL_KeyboardEvent c)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%d]\n", __FILE__,
__FUNCTION__, __LINE__, c);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventKeyPress] ERROR, program == NULL!");
}
program->keyPress (c);
if (program != NULL && program->isInSpecialKeyCaptureEvent () == false)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
Config & configKeys =
Config::getInstance (std::pair < ConfigType,
ConfigType > (cfgMainKeys, cfgUserKeys));
if (isKeyPressed
(configKeys.getSDLKey ("HotKeyToggleOSMouseEnabled"), c) == true)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
bool
showCursorState = false;
int
state = SDL_ShowCursor (SDL_QUERY);
if (state == SDL_DISABLE)
{
showCursorState = true;
}
showCursor (showCursorState);
Renderer & renderer = Renderer::getInstance ();
renderer.setNo2DMouseRendering (showCursorState);
Window::lastShowMouseState = SDL_ShowCursor (SDL_QUERY);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",
__FILE__, __FUNCTION__, __LINE__,
Window::lastShowMouseState);
}
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%d]\n", __FILE__,
__FUNCTION__, __LINE__, c);
}
void
MainWindow::eventWindowEvent (SDL_WindowEvent event)
{
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%d]\n", __FILE__,
__FUNCTION__, __LINE__, event.event);
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventKeyPress] ERROR, program == NULL!");
}
// if(program->getState() != NULL && dynamic_cast<Intro *>(program->getState()) != NULL) {
// printf("In eventWindowEvent skip\n");
// return;
// }
//Renderer &renderer= Renderer::getInstance();
switch (event.event)
{
case SDL_WINDOWEVENT_ENTER:
{
//printf("In SDL_WINDOWEVENT_ENTER\n");
// bool showCursorState = Window::lastShowMouseState;
// showCursor(showCursorState);
// renderer.setNo2DMouseRendering(showCursorState);
//
// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",
__FILE__, __FUNCTION__, __LINE__,
Window::lastShowMouseState);
}
break;
case SDL_WINDOWEVENT_LEAVE:
{
//printf("In SDL_WINDOWEVENT_LEAVE\n");
// bool showCursorState = false;
// int state = SDL_ShowCursor(SDL_QUERY);
// if(state == SDL_DISABLE) {
// showCursorState = true;
// }
// showCursor(showCursorState);
// renderer.setNo2DMouseRendering(showCursorState);
//
// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",
__FILE__, __FUNCTION__, __LINE__,
Window::lastShowMouseState);
}
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
{
//printf("SDL_WINDOWEVENT_FOCUS_GAINED\n");
// bool showCursorState = Window::lastShowMouseState;
// showCursor(showCursorState);
// renderer.setNo2DMouseRendering(showCursorState);
//
// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",
__FILE__, __FUNCTION__, __LINE__,
Window::lastShowMouseState);
}
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
{
//printf("SDL_WINDOWEVENT_FOCUS_LOST\n");
// bool showCursorState = false;
// int state = SDL_ShowCursor(SDL_QUERY);
// if(state == SDL_DISABLE) {
// showCursorState = true;
// }
// showCursor(showCursorState);
// renderer.setNo2DMouseRendering(showCursorState);
//
// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",
__FILE__, __FUNCTION__, __LINE__,
Window::lastShowMouseState);
}
break;
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] [%d]\n", __FILE__,
__FUNCTION__, __LINE__, event.event);
}
void
MainWindow::eventActivate (bool active)
{
if (!active)
{
//minimize();
}
}
void
MainWindow::eventResize (SizeState sizeState)
{
if (program == NULL)
{
throw
megaglest_runtime_error
("In [MainWindow::eventResize] ERROR, program == NULL!");
}
program->resize (sizeState);
}
void
MainWindow::eventClose ()
{
delete
program;
program = NULL;
}
void
MainWindow::setProgram (Program * program)
{
this->program = program;
}
// =====================================================
// Main
// =====================================================
SystemFlags
debugger;
void
print_SDL_version (const char *preamble, SDL_version * v)
{
printf ("%s %u.%u.%u\n", preamble, v->major, v->minor, v->patch);
}
int
setupGameItemPaths (int argc, char **argv, Config * config)
{
// Setup path cache for files and folders used in the game
std::map < string, string > &pathCache =
CacheManager::getCachedItem < std::map < string,
string > >(GameConstants::pathCacheLookupKey);
Properties
devProperties;
string
devPropertyFile = Properties::getApplicationPath () + "glest-dev.ini";
if (fileExists (devPropertyFile) == true)
{
devProperties.load (devPropertyFile);
if (devProperties.hasString ("ServerListPath") == true)
{
string
devItem = devProperties.getString ("ServerListPath");
if (devItem != "")
{
endPathWithSlash (devItem);
}
if (config != NULL)
{
config->setString ("ServerListPath", devItem, true);
}
}
if (devProperties.hasString ("GlestKeysIniPath") == true)
{
string
devItem = devProperties.getString ("GlestKeysIniPath");
if (devItem != "")
{
endPathWithSlash (devItem);
}
if (config != NULL)
{
config->setString ("GlestKeysIniPath", devItem, true);
}
}
}
//GAME_ARG_DATA_PATH
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_DATA_PATH]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_DATA_PATH]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_DATA_PATH]),
&foundParamIndIndex);
}
string
customPath = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (customPath, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
customPathValue = paramPartTokens[1];
Properties::applyTagsToValue (customPathValue);
if (customPathValue != "")
{
endPathWithSlash (customPathValue);
}
pathCache[GameConstants::path_data_CacheLookupKey] =
customPathValue;
Properties::setApplicationDataPath (pathCache
[GameConstants::
path_data_CacheLookupKey]);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Using custom data path [%s]\n",
customPathValue.c_str ());
}
else
{
printf
("\nInvalid path specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], false);
return 1;
}
}
else if (config != NULL)
{
bool
foundPath = false;
string
customPathValue = "";
if (fileExists (devPropertyFile) == true
&& devProperties.hasString ("DataPath") == true)
{
foundPath = true;
customPathValue = devProperties.getString ("DataPath", "");
}
else if (config->getString ("DataPath", "") != "")
{
foundPath = true;
customPathValue = config->getString ("DataPath", "");
}
if (foundPath == true)
{
pathCache[GameConstants::path_data_CacheLookupKey] =
customPathValue;
if (customPathValue != "")
{
endPathWithSlash (customPathValue);
}
Properties::setApplicationDataPath (pathCache
[GameConstants::
path_data_CacheLookupKey]);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Using ini specified data path [%s]\n",
config->getString ("DataPath", "").c_str ());
}
}
//GAME_ARG_INI_PATH
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_INI_PATH]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_INI_PATH]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_INI_PATH]),
&foundParamIndIndex);
}
string
customPath = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (customPath, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
customPathValue = paramPartTokens[1];
Properties::applyTagsToValue (customPathValue);
pathCache[GameConstants::path_ini_CacheLookupKey] = customPathValue;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Using custom ini path [%s]\n", customPathValue.c_str ());
}
else
{
printf
("\nInvalid path specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], false);
return 1;
}
}
//GAME_ARG_LOG_PATH
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LOG_PATH]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LOG_PATH]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LOG_PATH]),
&foundParamIndIndex);
}
string
customPath = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (customPath, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
customPathValue = paramPartTokens[1];
Properties::applyTagsToValue (customPathValue);
pathCache[GameConstants::path_logs_CacheLookupKey] =
customPathValue;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Using custom logs path [%s]\n",
customPathValue.c_str ());
}
else
{
printf
("\nInvalid path specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], false);
return 1;
}
}
else if (config != NULL)
{
bool
foundPath = false;
string
customPathValue = "";
if (fileExists (devPropertyFile) == true
&& devProperties.hasString ("LogPath") == true)
{
foundPath = true;
customPathValue = devProperties.getString ("LogPath", "");
}
else if (config->getString ("LogPath", "") != "")
{
foundPath = true;
customPathValue = config->getString ("LogPath", "");
}
if (foundPath == true)
{
pathCache[GameConstants::path_logs_CacheLookupKey] =
customPathValue;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Using ini specified logs path [%s]\n",
config->getString ("LogPath", "").c_str ());
}
}
Text::DEFAULT_FONT_PATH =
pathCache[GameConstants::path_data_CacheLookupKey];
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_FONT_PATH]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_FONT_PATH]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_FONT_PATH]),
&foundParamIndIndex);
}
string
customPath = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (customPath, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
customPathValue = paramPartTokens[1];
Properties::applyTagsToValue (customPathValue);
Text::DEFAULT_FONT_PATH_ABSOLUTE = customPathValue;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Using custom fonts path [%s]\n",
customPathValue.c_str ());
}
else
{
printf
("\nInvalid path specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], false);
return 1;
}
}
return 0;
}
void
setupLogging (Config & config, bool haveSpecialOutputCommandLineOption)
{
SystemFlags::getSystemSettingType (SystemFlags::debugSystem).enabled =
config.getBool ("DebugMode", "false");
SystemFlags::getSystemSettingType (SystemFlags::debugNetwork).enabled =
config.getBool ("DebugNetwork", "false");
SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
enabled = config.getBool ("DebugPerformance", "false");
SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch).
enabled = config.getBool ("DebugWorldSynch", "false");
SystemFlags::getSystemSettingType (SystemFlags::debugUnitCommands).
enabled = config.getBool ("DebugUnitCommands", "false");
SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder).
enabled = config.getBool ("DebugPathFinder", "false");
SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled =
config.getBool ("DebugLUA", "false");
LuaScript::setDebugModeEnabled (SystemFlags::
getSystemSettingType (SystemFlags::
debugLUA).
enabled);
SystemFlags::getSystemSettingType (SystemFlags::debugSound).enabled =
config.getBool ("DebugSound", "false");
SystemFlags::getSystemSettingType (SystemFlags::debugError).enabled =
config.getBool ("DebugError", "true");
string
userData = config.getString ("UserData_Root", "");
if (userData != "")
{
endPathWithSlash (userData);
}
#ifdef HAVE_GOOGLE_BREAKPAD
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("#1 In setting up errorHandlerPtr->set_dump_path [%p]...\n",
errorHandlerPtr.get ());
if (errorHandlerPtr.get () != NULL)
{
string
dumpFilePath;
if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) !=
"")
{
dumpFilePath =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey);
}
else
{
dumpFilePath = userData;
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("#2 In setting up errorHandlerPtr->set_dump_path...\n");
# if defined(WIN32)
wstring
dumpfilepath = utf8_decode (dumpFilePath);
if (SystemFlags::VERBOSE_MODE_ENABLED)
wprintf
(L"Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n",
dumpfilepath.c_str ());
errorHandlerPtr->set_dump_path (dumpfilepath);
# else
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf
("Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n",
dumpFilePath.c_str ());
//errorHandlerPtr->set_dump_path(dumpfilepath);
google_breakpad::MinidumpDescriptor descriptor (dumpFilePath);
errorHandlerPtr->set_minidump_descriptor (descriptor);
# endif
}
#endif
string
debugLogFile = config.getString ("DebugLogFile", "");
if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) !=
"")
{
debugLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugLogFile;
}
else
{
debugLogFile = userData + debugLogFile;
}
string
debugWorldSynchLogFile =
config.getString ("DebugLogFileWorldSynch", "");
if (debugWorldSynchLogFile == "")
{
debugWorldSynchLogFile = debugLogFile;
}
else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
debugWorldSynchLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugWorldSynchLogFile;
}
else
{
debugWorldSynchLogFile = userData + debugWorldSynchLogFile;
}
string
debugPerformanceLogFile =
config.getString ("DebugLogFilePerformance", "");
if (debugPerformanceLogFile == "")
{
debugPerformanceLogFile = debugLogFile;
}
else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
debugPerformanceLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugPerformanceLogFile;
}
else
{
debugPerformanceLogFile = userData + debugPerformanceLogFile;
}
string
debugNetworkLogFile = config.getString ("DebugLogFileNetwork", "");
if (debugNetworkLogFile == "")
{
debugNetworkLogFile = debugLogFile;
}
else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
debugNetworkLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugNetworkLogFile;
}
else
{
debugNetworkLogFile = userData + debugNetworkLogFile;
}
string
debugUnitCommandsLogFile =
config.getString ("DebugLogFileUnitCommands", "");
if (debugUnitCommandsLogFile == "")
{
debugUnitCommandsLogFile = debugLogFile;
}
else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
debugUnitCommandsLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugUnitCommandsLogFile;
}
else
{
debugUnitCommandsLogFile = userData + debugUnitCommandsLogFile;
}
string
debugPathFinderLogFile =
config.getString ("DebugLogFilePathFinder", "");
if (debugPathFinderLogFile == "")
{
debugPathFinderLogFile = debugLogFile;
}
else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
debugPathFinderLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugPathFinderLogFile;
}
else
{
debugPathFinderLogFile = userData + debugPathFinderLogFile;
}
string
debugLUALogFile = config.getString ("DebugLogFileLUA", "");
if (debugLUALogFile == "")
{
debugLUALogFile = debugLogFile;
}
else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
debugLUALogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugLUALogFile;
}
else
{
debugLUALogFile = userData + debugLUALogFile;
}
string
debugSoundLogFile = config.getString ("DebugLogFileSound", "");
if (debugSoundLogFile == "")
{
debugSoundLogFile = debugLogFile;
}
else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey)
!= "")
{
debugSoundLogFile =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) +
debugSoundLogFile;
}
else
{
debugSoundLogFile = userData + debugSoundLogFile;
}
string
debugErrorLogFile = config.getString ("DebugLogFileError", "");
SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
debugLogFileName = debugLogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugNetwork).
debugLogFileName = debugNetworkLogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
debugLogFileName = debugPerformanceLogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch).
debugLogFileName = debugWorldSynchLogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugUnitCommands).
debugLogFileName = debugUnitCommandsLogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder).
debugLogFileName = debugPathFinderLogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugLUA).
debugLogFileName = debugLUALogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugSound).
debugLogFileName = debugSoundLogFile;
SystemFlags::getSystemSettingType (SystemFlags::debugError).
debugLogFileName = debugErrorLogFile;
if (haveSpecialOutputCommandLineOption == false)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf
("--- Startup log settings are ---\ndebugSystem [%d][%s]\ndebugNetwork [%d][%s]\ndebugPerformance [%d][%s]\ndebugWorldSynch [%d][%s]\ndebugUnitCommands[%d][%s]\ndebugPathFinder[%d][%s]\ndebugLUA [%d][%s]\ndebugSound [%d][%s]\ndebugError [%d][%s]\n",
SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
enabled, debugLogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::debugNetwork).
enabled, debugNetworkLogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::
debugPerformance).enabled,
debugPerformanceLogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch).
enabled, debugWorldSynchLogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::
debugUnitCommands).enabled,
debugUnitCommandsLogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder).
enabled, debugPathFinderLogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::debugLUA).
enabled, debugLUALogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::debugSound).
enabled, debugSoundLogFile.c_str (),
SystemFlags::getSystemSettingType (SystemFlags::debugError).
enabled, debugErrorLogFile.c_str ());
}
}
void
runTilesetValidationForPath (string tilesetPath, string tilesetName,
World & world, bool purgeUnusedFiles,
bool purgeDuplicateFiles,
bool showDuplicateFiles, bool gitPurgeFiles,
double &purgedMegaBytes)
{
Checksum
checksum;
//bool techtree_errors = false;
std::map < string, vector < pair < string, string > > >loadedFileList;
vector < string > pathList;
pathList.push_back (tilesetPath);
world.loadTileset (pathList, tilesetName, &checksum, loadedFileList);
// Fixup paths with ..
{
std::map < string, vector < pair < string,
string > > >newLoadedFileList;
for (std::map < string, vector < pair < string,
string > > >::iterator iterMap = loadedFileList.begin ();
iterMap != loadedFileList.end (); ++iterMap)
{
string
loadedFile = iterMap->first;
replaceAll (loadedFile, "//", "/");
replaceAll (loadedFile, "\\\\", "\\");
updatePathClimbingParts (loadedFile);
if (newLoadedFileList.find (loadedFile) != newLoadedFileList.end ())
{
for (unsigned int xx1 = 0; xx1 < iterMap->second.size (); ++xx1)
{
pair < string, string > &newVal = iterMap->second[xx1];
replaceAll (newVal.first, "//", "/");
replaceAll (newVal.first, "\\\\", "\\");
updatePathClimbingParts (newVal.first);
replaceAll (newVal.second, "//", "/");
replaceAll (newVal.second, "\\\\", "\\");
updatePathClimbingParts (newVal.second);
newLoadedFileList[loadedFile].push_back (newVal);
}
}
else
{
for (unsigned int xx1 = 0; xx1 < iterMap->second.size (); ++xx1)
{
pair < string, string > &newVal = iterMap->second[xx1];
replaceAll (newVal.first, "//", "/");
replaceAll (newVal.first, "\\\\", "\\");
updatePathClimbingParts (newVal.first);
replaceAll (newVal.second, "//", "/");
replaceAll (newVal.second, "\\\\", "\\");
updatePathClimbingParts (newVal.second);
}
newLoadedFileList[loadedFile] = iterMap->second;
}
}
loadedFileList = newLoadedFileList;
}
// Validate the faction setup to ensure we don't have any bad associations
// std::vector<std::string> resultErrors = world.validateFactionTypes();
// Now check for unused files in the techtree
std::map < string, vector < pair < string, string > > >foundFileList;
for (unsigned int i = 0; i < pathList.size (); ++i)
{
string
path = pathList[i];
endPathWithSlash (path);
path = path + tilesetName + "/";
replaceAll (path, "//", "/");
replaceAll (path, "\\\\", "\\");
vector < string > foundFiles =
getFolderTreeContentsListRecursively (path + "*.", "");
for (unsigned int j = 0; j < foundFiles.size (); ++j)
{
string
file = foundFiles[j];
replaceAll (file, "//", "/");
replaceAll (file, "\\\\", "\\");
replaceAll (file, "//", "/");
replaceAll (file, "\\\\", "\\");
foundFileList[file].push_back (make_pair (path, path));
}
}
printf ("Found tileset filecount = " MG_SIZE_T_SPECIFIER ", used = "
MG_SIZE_T_SPECIFIER "\n", foundFileList.size (),
loadedFileList.size ());
int
purgeCount = 0;
bool
foundUnusedFile = false;
for (std::map < string, vector < pair < string,
string > > >::iterator iterMap = foundFileList.begin ();
iterMap != foundFileList.end (); ++iterMap)
{
string
foundFile = iterMap->first;
replaceAll (foundFile, "//", "/");
replaceAll (foundFile, "\\\\", "\\");
if (loadedFileList.find (foundFile) == loadedFileList.end () &&
foundFile.find ("lang/") == foundFile.npos)
{
if (foundUnusedFile == false)
{
printf
("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n",
__LINE__);
}
foundUnusedFile = true;
printf ("[%s]\n", foundFile.c_str ());
string
fileName = extractFileFromDirectoryPath (foundFile);
if (loadedFileList.find (fileName) != loadedFileList.end ())
{
printf ("possible match on [%s] ?\n",
loadedFileList.find (fileName)->first.c_str ());
}
else if (purgeUnusedFiles == true)
{
off_t
fileSize = getFileSize (foundFile);
// convert to MB
purgedMegaBytes += ((double) fileSize / 1048576.0);
purgeCount++;
if (gitPurgeFiles == true)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "git rm \"%s\"", foundFile.c_str ());
bool
gitOk = executeShellCommand (szBuf, 0);
if (gitOk == false)
{
throw
megaglest_runtime_error ("Call to command failed [" +
string (szBuf) + "]");
}
}
else
{
removeFile (foundFile);
}
}
}
}
if (foundUnusedFile == true)
{
if (purgedMegaBytes > 0)
{
printf ("Purged %.2f MB (%d) in files\n", purgedMegaBytes,
purgeCount);
}
printf
("\nLine ref: %d, Warning, unused files were detected - END:\n",
__LINE__);
}
if (showDuplicateFiles == true)
{
std::map < uint32, vector < string > >mapDuplicateFiles;
// Now check for duplicate data content
for (std::map < string, vector < pair < string,
string > > >::iterator iterMap = loadedFileList.begin ();
iterMap != loadedFileList.end (); ++iterMap)
{
string
fileName = iterMap->first;
Checksum
checksum;
checksum.addFile (fileName);
uint32
crcValue = checksum.getSum ();
mapDuplicateFiles[crcValue].push_back (fileName);
}
double
duplicateMegaBytesPurged = 0;
int
duplicateCountPurged = 0;
double
duplicateMegaBytes = 0;
int
duplicateCount = 0;
bool
foundDuplicates = false;
for (std::map < uint32, vector < string > >::iterator iterMap =
mapDuplicateFiles.begin (); iterMap != mapDuplicateFiles.end ();
++iterMap)
{
vector < string > &fileList = iterMap->second;
if (fileList.size () > 1)
{
if (foundDuplicates == false)
{
foundDuplicates = true;
printf
("\nWarning, duplicate files were detected - START:\n=====================\n");
}
map < string, int >
parentList;
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
if (idx > 0)
{
off_t
fileSize = getFileSize (duplicateFile);
// convert to MB
duplicateMegaBytes += ((double) fileSize / 1048576.0);
duplicateCount++;
}
else
{
printf ("\n");
}
printf ("[%s]\n", duplicateFile.c_str ());
std::map < string, vector < pair < string,
string > > >::iterator iterFind =
loadedFileList.find (duplicateFile);
if (iterFind != loadedFileList.end ())
{
for (unsigned int jdx = 0; jdx < iterFind->second.size ();
jdx++)
{
parentList[iterFind->second[jdx].first]++;
}
}
}
for (map < string, int >::iterator iterMap1 = parentList.begin ();
iterMap1 != parentList.end (); ++iterMap1)
{
if (iterMap1 == parentList.begin ())
{
printf ("\tParents:\n");
}
printf ("\t[%s]\n", iterMap1->first.c_str ());
}
if (purgeDuplicateFiles == true)
{
string
newCommonFileName = "";
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
off_t
fileSize = getFileSize (duplicateFile);
if (idx == 0)
{
newCommonFileName =
"$COMMONDATAPATH/sounds/" +
extractFileFromDirectoryPath (duplicateFile);
string
expandedNewCommonFileName = newCommonFileName;
std::map < string, string > mapExtraTagReplacementValues;
mapExtraTagReplacementValues =
Properties::getTagReplacementValues
(&mapExtraTagReplacementValues);
Properties::applyTagsToValue (expandedNewCommonFileName,
&mapExtraTagReplacementValues);
replaceAll (expandedNewCommonFileName, "//", "/");
createDirectoryPaths (extractDirectoryPathFromFile
(expandedNewCommonFileName));
if (gitPurgeFiles == true)
{
copyFileTo (duplicateFile, expandedNewCommonFileName);
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "git rm \"%s\"",
duplicateFile.c_str ());
bool
gitOk = executeShellCommand (szBuf, 0);
if (gitOk == false)
{
throw
megaglest_runtime_error ("Call to command failed ["
+ string (szBuf) + "]");
}
printf
("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n",
duplicateFile.c_str (),
expandedNewCommonFileName.c_str ());
}
else
{
//int result = 0;
int
result = rename (duplicateFile.c_str (),
expandedNewCommonFileName.c_str ());
if (result != 0)
{
char
szBuf[8096] = "";
char *
errmsg = strerror (errno);
snprintf (szBuf, 8096,
"!!! Error [%s] Could not rename [%s] to [%s]!",
errmsg, duplicateFile.c_str (),
expandedNewCommonFileName.c_str ());
throw
megaglest_runtime_error (szBuf);
}
else
{
printf
("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n",
duplicateFile.c_str (),
expandedNewCommonFileName.c_str ());
}
}
}
else
{
if (gitPurgeFiles == true)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "git rm \"%s\"",
duplicateFile.c_str ());
bool
gitOk = executeShellCommand (szBuf, 0);
if (gitOk == false)
{
throw
megaglest_runtime_error ("Call to command failed ["
+ string (szBuf) + "]");
}
printf ("*** Duplicate file:\n[%s]\nwas git rm\n",
duplicateFile.c_str ());
}
else
{
removeFile (duplicateFile);
}
printf ("*** Duplicate file:\n[%s]\nwas removed\n",
duplicateFile.c_str ());
// convert to MB
duplicateMegaBytesPurged +=
((double) fileSize / 1048576.0);
duplicateCountPurged++;
}
}
}
std::map < string, int >
mapUniqueParentList;
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
std::map < string, vector < pair < string,
string > > >::iterator iterFind2 =
loadedFileList.find (duplicateFile);
if (iterFind2 != loadedFileList.end ())
{
for (unsigned int jdx1 = 0;
jdx1 < iterFind2->second.size (); jdx1++)
{
string
parentFile = iterFind2->second[jdx1].first;
string
searchText = iterFind2->second[jdx1].second;
if (mapUniqueParentList.find (parentFile) ==
mapUniqueParentList.end ())
{
printf
("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",
parentFile.c_str (), searchText.c_str (),
newCommonFileName.c_str ());
bool
foundText =
searchAndReplaceTextInFile (parentFile, searchText,
newCommonFileName,
false);
printf ("foundText = %d\n", foundText);
if (foundText == false)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096,
"Line ref = %d, Error finding text [%s] in file [%s]",
__LINE__, searchText.c_str (),
parentFile.c_str ());
throw
megaglest_runtime_error (szBuf);
}
mapUniqueParentList[parentFile]++;
}
}
}
}
}
}
else
{
string
newCommonFileName = "";
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
//off_t fileSize = getFileSize(duplicateFile);
if (idx == 0)
{
newCommonFileName =
"$COMMONDATAPATH/sounds/" +
extractFileFromDirectoryPath (duplicateFile);
break;
}
}
}
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
std::map < string, vector < pair < string,
string > > >::iterator iterFind4 =
loadedFileList.find (duplicateFile);
if (iterFind4 != loadedFileList.end ())
{
for (unsigned int jdx = 0;
jdx < iterFind4->second.size (); jdx++)
{
string
parentFile = iterFind4->second[jdx].first;
string
searchText = iterFind4->second[jdx].second;
bool
foundText =
searchAndReplaceTextInFile (parentFile, searchText,
newCommonFileName, true);
if (foundText == false)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096,
"Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n",
__LINE__, searchText.c_str (),
parentFile.c_str (),
newCommonFileName.c_str ());
printf
("\n\n=================================================\n%s",
szBuf);
throw
megaglest_runtime_error (szBuf);
}
}
}
}
}
}
}
}
if (foundDuplicates == true)
{
printf ("Duplicates %.2f MB (%d) in files\n", duplicateMegaBytes,
duplicateCount);
printf ("Duplicates purged %.2f MB (%d) in files\n",
duplicateMegaBytesPurged, duplicateCountPurged);
printf ("\nWarning, duplicate files were detected - END:\n");
}
}
//if(techtree_errors == false) {
printf
("\nValidation found NO ERRORS for tilesetPath [%s] tilesetName [%s]:\n",
tilesetPath.c_str (), tilesetName.c_str ());
//}
printf
("----------------------------------------------------------------");
}
void
runTechValidationForPath (string techPath, string techName,
const std::vector < string >
&filteredFactionList, World & world,
bool purgeUnusedFiles, bool purgeDuplicateFiles,
bool showDuplicateFiles, bool gitPurgeFiles,
double &purgedMegaBytes)
{
string
techTreeFolder = techPath + techName;
string
techTreeFactionFolder = techTreeFolder + "/factions/";
vector < string > factionsList;
findDirs (techTreeFactionFolder, factionsList, false, false);
if (factionsList.empty () == false)
{
Checksum
checksum;
set < string > factions;
for (int j = 0; j < (int) factionsList.size (); ++j)
{
if (filteredFactionList.empty () == true ||
std::find (filteredFactionList.begin (),
filteredFactionList.end (),
factionsList[j]) != filteredFactionList.end ())
{
factions.insert (factionsList[j]);
}
}
printf
("\n----------------------------------------------------------------");
printf
("\nChecking techPath [%s] techName [%s] total faction count = %d\n",
techPath.c_str (), techName.c_str (), (int) factionsList.size ());
for (int j = 0; j < (int) factionsList.size (); ++j)
{
if (filteredFactionList.empty () == true ||
std::find (filteredFactionList.begin (),
filteredFactionList.end (),
factionsList[j]) != filteredFactionList.end ())
{
printf ("Using faction [%s]\n", factionsList[j].c_str ());
}
}
if (factions.empty () == false)
{
bool
techtree_errors = false;
std::map < string, vector < pair < string,
string > > >loadedFileList;
vector < string > pathList;
pathList.push_back (techPath);
Config & config = Config::getInstance ();
vector < string > otherTechPaths =
config.getPathListForType (ptTechs, "");
pathList.insert (pathList.end (), otherTechPaths.begin (),
otherTechPaths.end ());
try
{
world.loadTech (pathList, techName, factions, &checksum,
loadedFileList, true);
// Fixup paths with ..
{
std::map < string, vector < pair < string,
string > > >newLoadedFileList;
for (std::map < string, vector < pair < string,
string > > >::iterator iterMap = loadedFileList.begin ();
iterMap != loadedFileList.end (); ++iterMap)
{
string
loadedFile = iterMap->first;
replaceAll (loadedFile, "//", "/");
replaceAll (loadedFile, "\\\\", "\\");
updatePathClimbingParts (loadedFile);
if (newLoadedFileList.find (loadedFile) !=
newLoadedFileList.end ())
{
for (unsigned int xx1 = 0; xx1 < iterMap->second.size ();
++xx1)
{
pair < string, string > &newVal = iterMap->second[xx1];
replaceAll (newVal.first, "//", "/");
replaceAll (newVal.first, "\\\\", "\\");
updatePathClimbingParts (newVal.first);
replaceAll (newVal.second, "//", "/");
replaceAll (newVal.second, "\\\\", "\\");
updatePathClimbingParts (newVal.second);
newLoadedFileList[loadedFile].push_back (newVal);
}
}
else
{
for (unsigned int xx1 = 0; xx1 < iterMap->second.size ();
++xx1)
{
pair < string, string > &newVal = iterMap->second[xx1];
replaceAll (newVal.first, "//", "/");
replaceAll (newVal.first, "\\\\", "\\");
updatePathClimbingParts (newVal.first);
replaceAll (newVal.second, "//", "/");
replaceAll (newVal.second, "\\\\", "\\");
updatePathClimbingParts (newVal.second);
}
newLoadedFileList[loadedFile] = iterMap->second;
}
}
loadedFileList = newLoadedFileList;
}
// Validate the faction setup to ensure we don't have any bad associations
std::vector < std::string > resultErrors =
world.validateFactionTypes ();
if (resultErrors.empty () == false)
{
techtree_errors = true;
// Display the validation errors
string
errorText =
"\nErrors were detected:\n=====================\n";
for (int i = 0; i < (int) resultErrors.size (); ++i)
{
if (i > 0)
{
errorText += "\n";
}
errorText = errorText + resultErrors[i];
}
errorText += "\n=====================\n";
printf ("%s", errorText.c_str ());
}
// Validate the faction resource setup to ensure we don't have any bad associations
printf ("\nChecking resources, count = %d\n",
world.getTechTree ()->getResourceTypeCount ());
for (int i = 0; i < world.getTechTree ()->getResourceTypeCount ();
++i)
{
printf ("Found techtree resource [%s]\n",
world.getTechTree ()->getResourceType (i)->getName ().
c_str ());
}
resultErrors = world.validateResourceTypes ();
if (resultErrors.empty () == false)
{
techtree_errors = true;
// Display the validation errors
string
errorText =
"\nErrors were detected:\n=====================\n";
for (int i = 0; i < (int) resultErrors.size (); ++i)
{
if (i > 0)
{
errorText += "\n";
}
errorText = errorText + resultErrors[i];
}
errorText += "\n=====================\n";
printf ("%s", errorText.c_str ());
}
// Now check for unused files in the techtree
std::map < string, vector < pair < string,
string > > >foundFileList;
for (unsigned int i = 0; i < pathList.size (); ++i)
{
string
path = pathList[i];
endPathWithSlash (path);
path = path + techName + "/";
replaceAll (path, "//", "/");
replaceAll (path, "\\\\", "\\");
vector < string > foundFiles =
getFolderTreeContentsListRecursively (path + "*.", "");
for (unsigned int j = 0; j < foundFiles.size (); ++j)
{
string
file = foundFiles[j];
replaceAll (file, "//", "/");
replaceAll (file, "\\\\", "\\");
// ignore loading screen, preview screen and hud
if (file.find (GameConstants::LOADING_SCREEN_FILE) !=
string::npos
|| file.find (GameConstants::PREVIEW_SCREEN_FILE) !=
string::npos
|| file.find (GameConstants::HUD_SCREEN_FILE) !=
string::npos)
{
continue;
}
// ignore commondata since we are not loading all factions
if (filteredFactionList.size () > 0)
{
if (file.find ("/commondata/") != string::npos)
{
continue;
}
}
if (file.find ("/factions/") != string::npos)
{
bool
includeFaction = false;
for (set < string >::iterator it = factions.begin ();
it != factions.end (); ++it)
{
string
currentFaction = *it;
if (file.find ("/factions/" + currentFaction) !=
string::npos)
{
includeFaction = true;
break;
}
}
if (includeFaction == false)
{
continue;
}
}
replaceAll (file, "//", "/");
replaceAll (file, "\\\\", "\\");
foundFileList[file].push_back (make_pair (path, path));
}
}
printf ("Found techtree filecount = " MG_SIZE_T_SPECIFIER
", used = " MG_SIZE_T_SPECIFIER "\n",
foundFileList.size (), loadedFileList.size ());
int
purgeCount = 0;
bool
foundUnusedFile = false;
for (std::map < string, vector < pair < string,
string > > >::iterator iterMap = foundFileList.begin ();
iterMap != foundFileList.end (); ++iterMap)
{
string
foundFile = iterMap->first;
replaceAll (foundFile, "//", "/");
replaceAll (foundFile, "\\\\", "\\");
if (loadedFileList.find (foundFile) == loadedFileList.end () &&
foundFile.find ("lang/") == foundFile.npos)
{
if (foundUnusedFile == false)
{
printf
("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n",
__LINE__);
}
foundUnusedFile = true;
printf ("[%s]\n", foundFile.c_str ());
string
fileName = extractFileFromDirectoryPath (foundFile);
if (loadedFileList.find (fileName) != loadedFileList.end ())
{
printf ("possible match on [%s] ?\n",
loadedFileList.find (fileName)->first.c_str ());
}
else if (purgeUnusedFiles == true)
{
off_t
fileSize = getFileSize (foundFile);
// convert to MB
purgedMegaBytes += ((double) fileSize / 1048576.0);
purgeCount++;
if (gitPurgeFiles == true)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "git rm \"%s\"",
foundFile.c_str ());
bool
gitOk = executeShellCommand (szBuf, 0);
if (gitOk == false)
{
throw
megaglest_runtime_error ("Call to command failed [" +
string (szBuf) + "]");
}
}
else
{
removeFile (foundFile);
}
}
}
}
if (foundUnusedFile == true)
{
if (purgedMegaBytes > 0)
{
printf ("Purged %.2f MB (%d) in files\n", purgedMegaBytes,
purgeCount);
}
printf
("\nLine ref: %d, Warning, unused files were detected - END:\n",
__LINE__);
}
if (showDuplicateFiles == true)
{
std::map < uint32, vector < string > >mapDuplicateFiles;
// Now check for duplicate data content
for (std::map < string, vector < pair < string,
string > > >::iterator iterMap = loadedFileList.begin ();
iterMap != loadedFileList.end (); ++iterMap)
{
string
fileName = iterMap->first;
Checksum
checksum;
checksum.addFile (fileName);
uint32
crcValue = checksum.getSum ();
if (crcValue == 0)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096,
"Error calculating CRC for file [%s]",
fileName.c_str ());
throw
megaglest_runtime_error (szBuf);
}
mapDuplicateFiles[crcValue].push_back (fileName);
}
double
duplicateMegaBytesPurged = 0;
int
duplicateCountPurged = 0;
double
duplicateMegaBytes = 0;
int
duplicateCount = 0;
bool
foundDuplicates = false;
for (std::map < uint32, vector < string > >::iterator iterMap =
mapDuplicateFiles.begin ();
iterMap != mapDuplicateFiles.end (); ++iterMap)
{
vector < string > &fileList = iterMap->second;
if (fileList.size () > 1)
{
if (foundDuplicates == false)
{
foundDuplicates = true;
printf
("\nWarning, duplicate files were detected - START:\n=====================\n");
}
printf ("----- START duplicate files for CRC [%u] count ["
MG_SIZE_T_SPECIFIER "] first file is [%s]\n",
iterMap->first, fileList.size (),
fileList[0].c_str ());
map < string, int >
parentList;
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
if (idx > 0)
{
off_t
fileSize = getFileSize (duplicateFile);
// convert to MB
duplicateMegaBytes += ((double) fileSize / 1048576.0);
duplicateCount++;
}
else
{
printf ("\n");
}
printf ("[%s]\n", duplicateFile.c_str ());
std::map < string, vector < pair < string,
string > > >::iterator iterFind =
loadedFileList.find (duplicateFile);
if (iterFind != loadedFileList.end ())
{
for (unsigned int jdx = 0;
jdx < iterFind->second.size (); jdx++)
{
parentList[iterFind->second[jdx].first]++;
}
}
string
newCommonFileName =
"$COMMONDATAPATH/sounds/" +
extractFileFromDirectoryPath (duplicateFile);
string
expandedNewCommonFileName = newCommonFileName;
std::map < string, string > mapExtraTagReplacementValues;
string
techCommonData = techPath + techName + "/commondata/";
replaceAll (techCommonData, "//", "/");
mapExtraTagReplacementValues["$COMMONDATAPATH"] =
techCommonData;
mapExtraTagReplacementValues =
Properties::getTagReplacementValues
(&mapExtraTagReplacementValues);
Properties::applyTagsToValue (expandedNewCommonFileName,
&mapExtraTagReplacementValues);
replaceAll (expandedNewCommonFileName, "//", "/");
}
printf ("----- Finding parents for duplicate files ["
MG_SIZE_T_SPECIFIER "] first file is [%s]\n",
fileList.size (), fileList[0].c_str ());
for (map < string, int >::iterator iterMap1 =
parentList.begin (); iterMap1 != parentList.end ();
++iterMap1)
{
if (iterMap1 == parentList.begin ())
{
printf ("\tParents:\n");
}
printf ("\t[%s]\n", iterMap1->first.c_str ());
}
if (purgeDuplicateFiles == true)
{
printf ("----- move / remove duplicate files ["
MG_SIZE_T_SPECIFIER "] first file is [%s]\n",
fileList.size (), fileList[0].c_str ());
// First move first duplicate to commondata and delete all other copies
string
newCommonFileName = "";
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
off_t
fileSize = getFileSize (duplicateFile);
printf ("#1 [%u / " MG_SIZE_T_SPECIFIER
"] removing duplicate [%s]\n", idx,
fileList.size (), duplicateFile.c_str ());
if (idx == 0)
{
newCommonFileName =
"$COMMONDATAPATH/sounds/" +
extractFileFromDirectoryPath (duplicateFile);
string
expandedNewCommonFileName = newCommonFileName;
std::map < string,
string > mapExtraTagReplacementValues;
string
techCommonData =
techPath + techName + "/commondata/";
replaceAll (techCommonData, "//", "/");
mapExtraTagReplacementValues["$COMMONDATAPATH"] =
techCommonData;
mapExtraTagReplacementValues =
Properties::getTagReplacementValues
(&mapExtraTagReplacementValues);
Properties::applyTagsToValue
(expandedNewCommonFileName,
&mapExtraTagReplacementValues);
replaceAll (expandedNewCommonFileName, "//", "/");
createDirectoryPaths (extractDirectoryPathFromFile
(expandedNewCommonFileName));
if (gitPurgeFiles == true)
{
copyFileTo (duplicateFile,
expandedNewCommonFileName);
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "git rm \"%s\"",
duplicateFile.c_str ());
bool
gitOk = executeShellCommand (szBuf, 0);
if (gitOk == false)
{
throw
megaglest_runtime_error
("Call to command failed [" + string (szBuf) +
"]");
}
printf
("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n",
duplicateFile.c_str (),
expandedNewCommonFileName.c_str ());
}
else
{
printf
("moving duplicate [%s] to common data [%s] expanded to [%s]\n",
duplicateFile.c_str (),
newCommonFileName.c_str (),
expandedNewCommonFileName.c_str ());
int
result = rename (duplicateFile.c_str (),
expandedNewCommonFileName.c_str
());
if (result != 0)
{
char
szBuf[8096] = "";
char *
errmsg = strerror (errno);
snprintf (szBuf, 8096,
"!!! Error [%s] Could not rename [%s] to [%s]!",
errmsg, duplicateFile.c_str (),
expandedNewCommonFileName.c_str ());
throw
megaglest_runtime_error (szBuf);
}
else
{
printf
("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n",
duplicateFile.c_str (),
expandedNewCommonFileName.c_str ());
}
}
}
else
{
if (gitPurgeFiles == true)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "git rm \"%s\"",
duplicateFile.c_str ());
bool
gitOk = executeShellCommand (szBuf, 0);
if (gitOk == false)
{
throw
megaglest_runtime_error
("Call to command failed [" + string (szBuf) +
"]");
}
printf ("*** Duplicate file:\n[%s]\nwas git rm\n",
duplicateFile.c_str ());
}
else
{
printf ("removing duplicate [%s]\n",
duplicateFile.c_str ());
removeFile (duplicateFile);
}
printf ("*** Duplicate file:\n[%s]\nwas removed\n",
duplicateFile.c_str ());
// convert to MB
duplicateMegaBytesPurged +=
((double) fileSize / 1048576.0);
duplicateCountPurged++;
}
}
}
printf ("----- update XML files for duplicate files ["
MG_SIZE_T_SPECIFIER "] first file is [%s]\n",
fileList.size (), fileList[0].c_str ());
std::map < string, int >
mapUniqueParentList;
// Update the XML files to point to the new single copy in commondata
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
std::map < string, vector < pair < string,
string > > >::iterator iterFind2 =
loadedFileList.find (duplicateFile);
if (iterFind2 != loadedFileList.end ())
{
for (unsigned int jdx1 = 0;
jdx1 < iterFind2->second.size (); jdx1++)
{
string
parentFile = iterFind2->second[jdx1].first;
string
searchText = iterFind2->second[jdx1].second;
if (mapUniqueParentList.find (parentFile) ==
mapUniqueParentList.end ())
{
printf
("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",
parentFile.c_str (), searchText.c_str (),
newCommonFileName.c_str ());
bool
foundText =
searchAndReplaceTextInFile (parentFile,
searchText,
newCommonFileName,
false);
printf ("foundText = %d\n", foundText);
if (foundText == false)
{
string
techCommonData =
techPath + techName + "/commondata/";
replaceAll (techCommonData, "//", "/");
if (StartsWith (searchText, techCommonData) ==
true)
{
printf
("WARNING #1 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n",
foundText, parentFile.c_str (),
techCommonData.c_str (),
searchText.c_str (),
newCommonFileName.c_str ());
replaceAll (searchText, techCommonData,
"$COMMONDATAPATH/");
foundText =
searchAndReplaceTextInFile (parentFile,
searchText,
newCommonFileName,
false);
printf
("WARNING #2 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n",
foundText, parentFile.c_str (),
techCommonData.c_str (),
searchText.c_str (),
newCommonFileName.c_str ());
}
if (foundText == false)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096,
"Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n",
__LINE__, searchText.c_str (),
parentFile.c_str (),
newCommonFileName.c_str ());
printf
("\n\n=================================================\n%s",
szBuf);
throw
megaglest_runtime_error (szBuf);
}
}
mapUniqueParentList[parentFile]++;
}
}
}
}
}
}
else
{
string
newCommonFileName = "";
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
//off_t fileSize = getFileSize(duplicateFile);
if (idx == 0)
{
newCommonFileName =
"$COMMONDATAPATH/sounds/" +
extractFileFromDirectoryPath (duplicateFile);
break;
}
}
}
for (unsigned int idx = 0; idx < fileList.size (); ++idx)
{
string
duplicateFile = fileList[idx];
string
fileExt = extractExtension (duplicateFile);
if (fileExt == "wav" || fileExt == "ogg")
{
std::map < string, vector < pair < string,
string > > >::iterator iterFind4 =
loadedFileList.find (duplicateFile);
if (iterFind4 != loadedFileList.end ())
{
for (unsigned int jdx = 0;
jdx < iterFind4->second.size (); jdx++)
{
string
parentFile = iterFind4->second[jdx].first;
string
searchText = iterFind4->second[jdx].second;
bool
foundText =
searchAndReplaceTextInFile (parentFile,
searchText,
newCommonFileName,
true);
if (foundText == false)
{
string
techCommonData =
techPath + techName + "/commondata/";
replaceAll (techCommonData, "//", "/");
if (StartsWith (searchText, techCommonData) ==
true)
{
replaceAll (searchText, techCommonData,
"$COMMONDATAPATH/");
foundText =
searchAndReplaceTextInFile (parentFile,
searchText,
newCommonFileName,
true);
}
if (foundText == false)
{
// Check if the sound file already references commandata
foundText =
searchAndReplaceTextInFile (parentFile,
newCommonFileName,
newCommonFileName,
true);
if (foundText == false)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096,
"Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n",
__LINE__, searchText.c_str (),
parentFile.c_str (),
newCommonFileName.c_str ());
printf
("\n\n=================================================\n%s",
szBuf);
throw
megaglest_runtime_error (szBuf);
}
}
}
}
}
}
}
}
printf ("----- END duplicate files [" MG_SIZE_T_SPECIFIER
"] first file is [%s]\n", fileList.size (),
fileList[0].c_str ());
}
}
if (foundDuplicates == true)
{
printf ("Duplicates %.2f MB (%d) in files\n",
duplicateMegaBytes, duplicateCount);
printf ("Duplicates purged %.2f MB (%d) in files\n",
duplicateMegaBytesPurged, duplicateCountPurged);
printf ("\nWarning, duplicate files were detected - END:\n");
}
}
}
catch (const megaglest_runtime_error & ex)
{
techtree_errors = true;
printf
("\n\n****ERROR**** detected while validating the techName: %s\nMESSAGE: %s\n",
techName.c_str (), ex.what ());
}
if (techtree_errors == false)
{
printf
("\nValidation found NO ERRORS for techPath [%s] techName [%s] factions checked (count = %d):\n",
techPath.c_str (), techName.c_str (), (int) factions.size ());
for (set < string >::iterator it = factions.begin ();
it != factions.end (); ++it)
{
printf ("Faction [%s]\n", (*it).c_str ());
}
}
}
printf
("----------------------------------------------------------------");
}
else if (folderExists (techTreeFolder) == true)
{
printf
("\nWarning, No factions were found for the techtree located in: [%s]\n",
techTreeFolder.c_str ());
}
}
void
runTechTranslationExtractionForPath (string techPath, string techName,
const std::vector < string >
&filteredFactionList, World & world)
{
vector < string > factionsList;
findDirs (techPath + techName + "/factions/", factionsList, false,
false);
if (factionsList.empty () == false)
{
Checksum
checksum;
set < string > factions;
for (int j = 0; j < (int) factionsList.size (); ++j)
{
if (filteredFactionList.empty () == true ||
std::find (filteredFactionList.begin (),
filteredFactionList.end (),
factionsList[j]) != filteredFactionList.end ())
{
factions.insert (factionsList[j]);
}
}
printf
("\n----------------------------------------------------------------");
printf
("\nChecking techPath [%s] techName [%s] total faction count = %d\n",
techPath.c_str (), techName.c_str (), (int) factionsList.size ());
for (int j = 0; j < (int) factionsList.size (); ++j)
{
if (filteredFactionList.empty () == true ||
std::find (filteredFactionList.begin (),
filteredFactionList.end (),
factionsList[j]) != filteredFactionList.end ())
{
printf ("Using faction [%s]\n", factionsList[j].c_str ());
}
}
if (factions.empty () == false)
{
std::map < string, vector < pair < string,
string > > >loadedFileList;
vector < string > pathList;
pathList.push_back (techPath);
Config & config = Config::getInstance ();
vector < string > otherTechPaths =
config.getPathListForType (ptTechs, "");
pathList.insert (pathList.end (), otherTechPaths.begin (),
otherTechPaths.end ());
try
{
world.loadTech (pathList, techName, factions, &checksum,
loadedFileList, true);
const TechTree *
techtree = world.getTechTree ();
string
translationFile = techtree->getPath ();
endPathWithSlash (translationFile);
translationFile += "lang/" + techName + "_default.lng";
if (fileExists (translationFile) == false)
{
string
txFilePath = extractDirectoryPathFromFile (translationFile);
createDirectoryPaths (txFilePath);
#if defined(WIN32) && !defined(__MINGW32__)
FILE *
fp = _wfopen (utf8_decode (translationFile).c_str (), L"w");
std::ofstream txFile (fp);
#else
std::ofstream txFile;
txFile.open (translationFile.c_str (),
ios_base::out | ios_base::trunc);
#endif
if (txFile.is_open () == true)
{
string
_transl_TechTreeName = techName;
replaceAll (_transl_TechTreeName, "_", " ");
txFile << "; TechTree" << std::endl;
txFile << "TechTreeName=" << _transl_TechTreeName <<
std::endl;
txFile << "; -------------------------------------" <<
std::endl;
txFile << "; Types of Armor" << std::endl;
for (int index = 0; index < techtree->getArmorTypeCount ();
++index)
{
const ArmorType *
at = techtree->getArmorTypeByIndex (index);
string
_transl_ArmorTypeName = at->getName (false);
replaceAll (_transl_ArmorTypeName, "_", " ");
txFile << "ArmorTypeName_" << at->getName (false) << "=" <<
_transl_ArmorTypeName << std::endl;
}
txFile << "; --------------------" << std::endl;
txFile << "; Types of Attack" << std::endl;
for (int index = 0; index < techtree->getAttackTypeCount ();
++index)
{
const AttackType *
at = techtree->getAttackTypeByIndex (index);
string
_transl_AttackTypeName = at->getName (false);
replaceAll (_transl_AttackTypeName, "_", " ");
txFile << "AttackTypeName_" << at->getName (false) << "=" <<
_transl_AttackTypeName << std::endl;
}
txFile << "; --------------------" << std::endl;
txFile << "; Types of Resources" << std::endl;
for (int index = 0; index < techtree->getResourceTypeCount ();
++index)
{
const ResourceType *
rt = techtree->getResourceType (index);
string
_transl_ResourceTypeName = rt->getName (false);
replaceAll (_transl_ResourceTypeName, "_", " ");
txFile << "ResourceTypeName_" << rt->getName (false) << "="
<< _transl_ResourceTypeName << std::endl;
}
//txFile << "FactionName_" << GameConstants::OBSERVER_SLOTNAME << "=" << GameConstants::OBSERVER_SLOTNAME << std::endl;
//txFile << "FactionName_" << GameConstants::RANDOMFACTION_SLOTNAME << "=" << GameConstants::RANDOMFACTION_SLOTNAME << std::endl;
for (int index = 0; index < techtree->getTypeCount ();
++index)
{
const FactionType *
ft = techtree->getType (index);
string
_transl_FactionName = ft->getName (false);
replaceAll (_transl_FactionName, "_", " ");
txFile <<
"; -----------------------------------------------------------------------------"
<< std::endl;
txFile << "; Faction" << std::endl;
txFile << "FactionName_" << ft->getName (false) << "=" <<
_transl_FactionName << std::endl;
txFile << "; -------------------------------------" <<
std::endl;
txFile << "; Types of Upgrades for this Faction" <<
std::endl;
for (int upgradeIndex = 0;
upgradeIndex < ft->getUpgradeTypeCount ();
++upgradeIndex)
{
const UpgradeType *
upt = ft->getUpgradeType (upgradeIndex);
string
_transl_UpgradeTypeName = upt->getName (false);
replaceAll (_transl_UpgradeTypeName, "_", " ");
txFile << "UpgradeTypeName_" << upt->getName (false) <<
"=" << _transl_UpgradeTypeName << std::endl;
}
for (int unitIndex = 0; unitIndex < ft->getUnitTypeCount ();
++unitIndex)
{
const UnitType *
ut = ft->getUnitType (unitIndex);
string
_transl_UnitTypeName = ut->getName (false);
replaceAll (_transl_UnitTypeName, "_", " ");
txFile << "; -------------------------------------" <<
std::endl;
txFile << "; Unit" << std::endl;
txFile << "UnitTypeName_" << ut->getName (false) << "=" <<
_transl_UnitTypeName << std::endl;
txFile << "; --------------------" << std::endl;
txFile << "; Levels for this Unit" << std::endl;
for (int levelIndex = 0;
levelIndex < ut->getLevelCount (); ++levelIndex)
{
const Level *
level = ut->getLevel (levelIndex);
string
_transl_LevelName = level->getName (false);
replaceAll (_transl_LevelName, "_", " ");
txFile << "LevelName_" << level->getName (false) << "="
<< _transl_LevelName << std::endl;
}
txFile << "; --------------------" << std::endl;
txFile << "; Types of Commands for this Unit" <<
std::endl;
for (int commandIndex = 0;
commandIndex < ut->getCommandTypeCount ();
++commandIndex)
{
const CommandType *
ct = ut->getCommandType (commandIndex);
string
_transl_CommandName = ct->getName (false);
replaceAll (_transl_CommandName, "_", " ");
txFile << "CommandName_" << ct->getName (false) << "="
<< _transl_CommandName << std::endl;
}
}
}
txFile << "; -------------------------------------" <<
std::endl;
}
txFile.close ();
#if defined(WIN32) && !defined(__MINGW32__)
if (fp)
{
fclose (fp);
}
#endif
}
else
{
printf
("\n** Cannot product techtree translation file [%s] for techPath [%s] techName [%s] because the file already exists!\n",
translationFile.c_str (), techPath.c_str (),
techName.c_str ());
}
}
catch (const megaglest_runtime_error & ex)
{
printf
("\n\n****ERROR**** detected while loading the techName: %s\nMESSAGE: %s\n",
techName.c_str (), ex.what ());
}
}
printf
("----------------------------------------------------------------");
}
}
void
runTechTranslationExtraction (int argc, char **argv)
{
printf ("====== Started Translation Extraction ======\n");
Config & config = Config::getInstance ();
// Did the user pass a specific list of factions to validate?
std::vector < string > filteredFactionList;
vector < string > results;
findDirs (config.getPathListForType (ptTechs), results);
vector < string > techTreeFiles = results;
// Did the user pass a specific list of techtrees to validate?
std::vector < string > filteredTechTreeList;
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + string ("=")) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) +
string ("="), &foundParamIndIndex);
string
filterList = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (filterList, paramPartTokens, "=");
if (paramPartTokens.size () >= 2)
{
string
techtreeList = paramPartTokens[1];
Tokenize (techtreeList, filteredTechTreeList, ",");
if (filteredTechTreeList.empty () == false)
{
printf
("Filtering techtrees and only looking for the following:\n");
for (int idx = 0; idx < (int) filteredTechTreeList.size (); ++idx)
{
filteredTechTreeList[idx] = trim (filteredTechTreeList[idx]);
printf ("%s\n", filteredTechTreeList[idx].c_str ());
}
}
}
}
{
printf
("\n---------------- Loading factions inside world ----------------");
World
world;
vector < string > techPaths = config.getPathListForType (ptTechs);
for (int idx = 0; idx < (int) techPaths.size (); idx++)
{
string & techPath = techPaths[idx];
endPathWithSlash (techPath);
for (int idx2 = 0; idx2 < (int) techTreeFiles.size (); idx2++)
{
string & techName = techTreeFiles[idx2];
if (filteredTechTreeList.empty () == true ||
std::find (filteredTechTreeList.begin (),
filteredTechTreeList.end (),
techName) != filteredTechTreeList.end ())
{
runTechTranslationExtractionForPath (techPath, techName,
filteredFactionList,
world);
}
}
}
printf ("\n====== Finished Translation ======\n");
}
}
void
runTechValidationReport (int argc, char **argv)
{
printf ("====== Started Validation ======\n");
bool
purgeDuplicateFiles = false;
bool
showDuplicateFiles = true;
bool
purgeUnusedFiles = false;
bool
gitPurgeFiles = false;
double
purgedMegaBytes = 0;
Config & config = Config::getInstance ();
// Did the user pass a specific scenario to validate?
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string ("=")) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) +
string ("="), &foundParamIndIndex);
string
filterList = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (filterList, paramPartTokens, "=");
if (paramPartTokens.size () >= 2)
{
string
validateScenarioName = paramPartTokens[1];
printf ("Filtering scenario: %s\n", validateScenarioName.c_str ());
if (paramPartTokens.size () >= 3)
{
if (paramPartTokens[2] == "purgeunused")
{
purgeUnusedFiles = true;
printf ("*NOTE All unused scenario files will be deleted!\n");
}
}
{
printf
("\n---------------- Loading scenario inside world ----------------\n");
bool
scenarioFound = false;
World
world;
std::vector < string > filteredFactionList;
vector < string > scenarioPaths =
config.getPathListForType (ptScenarios);
for (int idx = 0; idx < (int) scenarioPaths.size (); idx++)
{
string & scenarioPath = scenarioPaths[idx];
endPathWithSlash (scenarioPath);
vector < string > scenarioList;
findDirs (scenarioPath, scenarioList, false, false);
for (int idx2 = 0; idx2 < (int) scenarioList.size (); idx2++)
{
string & scenarioName = scenarioList[idx2];
if (scenarioName == validateScenarioName)
{
scenarioFound = true;
string
file =
scenarioPath + scenarioName + "/" + scenarioName + ".xml";
XmlTree
xmlTree;
xmlTree.load (file, Properties::getTagReplacementValues ());
const XmlNode *
scenarioNode = xmlTree.getRootNode ();
string
techName =
scenarioNode->getChild ("tech-tree")->
getAttribute ("value")->getValue ();
// Self Contained techtree?
string
scenarioTechtree =
scenarioPath + scenarioName + "/" + techName + "/" +
techName + ".xml";
printf
("\nFound Scenario [%s] looking for techtree [%s]...\n",
scenarioName.c_str (), scenarioTechtree.c_str ());
if (fileExists (scenarioTechtree) == true)
{
string
techPath = scenarioPath + scenarioName + "/";
printf
("\nFound Scenario [%s] with custom techtree [%s] validating...\n",
scenarioName.c_str (), techName.c_str ());
runTechValidationForPath (techPath, techName,
filteredFactionList, world,
purgeUnusedFiles,
showDuplicateFiles, false,
false, purgedMegaBytes);
}
else
{
vector < string > techPaths =
config.getPathListForType (ptTechs);
for (int idx = 0; idx < (int) techPaths.size (); idx++)
{
string & techPath = techPaths[idx];
endPathWithSlash (techPath);
scenarioTechtree =
techPath + "/" + techName + "/" + techName + ".xml";
if (fileExists (scenarioTechtree) == true)
{
printf
("\nFound Scenario [%s] with techtree [%s] validating...\n",
scenarioName.c_str (), techName.c_str ());
runTechValidationForPath (techPath, techName,
filteredFactionList, world,
purgeUnusedFiles,
showDuplicateFiles, false,
false, purgedMegaBytes);
break;
}
}
}
}
}
}
if (scenarioFound == false)
{
printf ("\nWARNING, the scenario [%s] was NOT FOUND!\n",
validateScenarioName.c_str ());
}
printf ("\n====== Finished Validation ======\n");
}
return;
}
else
{
printf
("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return;
}
}
// Did the user pass a specific list of factions to validate?
std::vector < string > filteredFactionList;
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string ("=")) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) +
string ("="), &foundParamIndIndex);
string
filterList = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (filterList, paramPartTokens, "=");
if (paramPartTokens.size () >= 2)
{
string
factionList = paramPartTokens[1];
Tokenize (factionList, filteredFactionList, ",");
if (filteredFactionList.empty () == false)
{
printf
("Filtering factions and only looking for the following:\n");
for (int idx = 0; idx < (int) filteredFactionList.size (); ++idx)
{
filteredFactionList[idx] = trim (filteredFactionList[idx]);
printf ("%s\n", filteredFactionList[idx].c_str ());
}
}
if (paramPartTokens.size () >= 3)
{
if (paramPartTokens[2] == "purgeunused")
{
purgeUnusedFiles = true;
printf ("*NOTE All unused faction files will be deleted!\n");
}
}
}
}
vector < string > results;
findDirs (config.getPathListForType (ptTechs), results);
vector < string > techTreeFiles = results;
// Did the user pass a specific list of techtrees to validate?
std::vector < string > filteredTechTreeList;
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string ("=")) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) +
string ("="), &foundParamIndIndex);
string
filterList = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (filterList, paramPartTokens, "=");
if (paramPartTokens.size () >= 2)
{
string
techtreeList = paramPartTokens[1];
Tokenize (techtreeList, filteredTechTreeList, ",");
if (filteredTechTreeList.empty () == false)
{
printf
("Filtering techtrees and only looking for the following:\n");
for (int idx = 0; idx < (int) filteredTechTreeList.size (); ++idx)
{
filteredTechTreeList[idx] = trim (filteredTechTreeList[idx]);
printf ("%s\n", filteredTechTreeList[idx].c_str ());
}
}
if (paramPartTokens.size () >= 3)
{
if (paramPartTokens[2] == "purgeunused")
{
purgeUnusedFiles = true;
printf ("*NOTE All unused techtree files will be deleted!\n");
}
else if (paramPartTokens[2] == "purgeduplicates")
{
purgeDuplicateFiles = true;
printf ("*NOTE All duplicate techtree files will be merged!\n");
}
else if (paramPartTokens[2] == "gitdelete")
{
gitPurgeFiles = true;
printf
("*NOTE All unused / duplicate techtree files will be removed from git!\n");
}
else if (paramPartTokens[2] == "hideduplicates")
{
showDuplicateFiles = false;
printf
("*NOTE All duplicate techtree files will NOT be shown!\n");
}
}
if (paramPartTokens.size () >= 4)
{
if (paramPartTokens[3] == "purgeunused")
{
purgeUnusedFiles = true;
printf ("*NOTE All unused techtree files will be deleted!\n");
}
else if (paramPartTokens[3] == "purgeduplicates")
{
purgeDuplicateFiles = true;
printf ("*NOTE All duplicate techtree files will be merged!\n");
}
else if (paramPartTokens[3] == "gitdelete")
{
gitPurgeFiles = true;
printf
("*NOTE All unused / duplicate techtree files will be removed from git!\n");
}
else if (paramPartTokens[3] == "hideduplicates")
{
showDuplicateFiles = false;
printf
("*NOTE All duplicate techtree files will NOT be shown!\n");
}
}
if (paramPartTokens.size () >= 5)
{
if (paramPartTokens[4] == "purgeunused")
{
purgeUnusedFiles = true;
printf ("*NOTE All unused techtree files will be deleted!\n");
}
else if (paramPartTokens[4] == "purgeduplicates")
{
purgeDuplicateFiles = true;
printf ("*NOTE All duplicate techtree files will be merged!\n");
}
else if (paramPartTokens[4] == "gitdelete")
{
gitPurgeFiles = true;
printf
("*NOTE All unused / duplicate techtree files will be removed from git!\n");
}
else if (paramPartTokens[4] == "hideduplicates")
{
showDuplicateFiles = false;
printf
("*NOTE All duplicate techtree files will NOT be shown!\n");
}
}
}
}
{
printf
("\n---------------- Loading factions inside world ----------------");
World
world;
vector < string > techPaths = config.getPathListForType (ptTechs);
for (int idx = 0; idx < (int) techPaths.size (); idx++)
{
string & techPath = techPaths[idx];
endPathWithSlash (techPath);
for (int idx2 = 0; idx2 < (int) techTreeFiles.size (); idx2++)
{
string & techName = techTreeFiles[idx2];
if (filteredTechTreeList.empty () == true ||
std::find (filteredTechTreeList.begin (),
filteredTechTreeList.end (),
techName) != filteredTechTreeList.end ())
{
runTechValidationForPath (techPath, techName,
filteredFactionList, world,
purgeUnusedFiles, purgeDuplicateFiles,
showDuplicateFiles, gitPurgeFiles,
purgedMegaBytes);
}
}
}
printf ("\n====== Finished Validation ======\n");
}
}
void
runTilesetValidationReport (int argc, char **argv)
{
printf ("====== Started Validation ======\n");
Config & config = Config::getInstance ();
// Did the user pass a specific tileset to validate?
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + string ("=")) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) +
string ("="), &foundParamIndIndex);
string
filterList = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (filterList, paramPartTokens, "=");
if (paramPartTokens.size () >= 2)
{
string
validateTilesetName = paramPartTokens[1];
printf ("Filtering tileset: %s\n", validateTilesetName.c_str ());
bool
purgeUnusedFiles = false;
if (paramPartTokens.size () >= 3)
{
if (paramPartTokens[2] == "purgeunused")
{
purgeUnusedFiles = true;
printf ("*NOTE All unused tileset files will be deleted!\n");
}
}
{
printf
("\n---------------- Loading tileset inside world ----------------\n");
World
world;
double
purgedMegaBytes = 0;
bool
showDuplicateFiles = true;
bool
tilesetFound = false;
vector < string > tilesetPaths =
config.getPathListForType (ptTilesets);
for (int idx = 0; idx < (int) tilesetPaths.size (); idx++)
{
string & tilesetPath = tilesetPaths[idx];
endPathWithSlash (tilesetPath);
vector < string > tilesetList;
findDirs (tilesetPath, tilesetList, false, false);
for (int idx2 = 0; idx2 < (int) tilesetList.size (); idx2++)
{
string & tilesetName = tilesetList[idx2];
if (tilesetName == validateTilesetName)
{
tilesetFound = true;
runTilesetValidationForPath (tilesetPath, tilesetName,
world, purgeUnusedFiles,
showDuplicateFiles, false,
false, purgedMegaBytes);
}
}
}
if (tilesetFound == false)
{
printf ("*ERROR The specified tileset [%s] was NOT FOUND!\n",
validateTilesetName.c_str ());
}
printf ("\n====== Finished Validation ======\n");
}
return;
}
else
{
printf
("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return;
}
}
else
{
printf ("\nInvalid missing tileset specified on commandline\n\n");
return;
}
}
void
ShowINISettings (int argc, char **argv, Config & config,
Config & configKeys)
{
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true)
{
vector < string > filteredPropertyList;
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string ("=")) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) +
string ("="), &foundParamIndIndex);
string
filterList = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (filterList, paramPartTokens, "=");
if (paramPartTokens.size () >= 2)
{
string
tokenList = paramPartTokens[1];
Tokenize (tokenList, filteredPropertyList, ",");
if (filteredPropertyList.empty () == false)
{
printf
("Filtering properties and only looking for the following:\n");
for (int idx = 0; idx < (int) filteredPropertyList.size ();
++idx)
{
filteredPropertyList[idx] = trim (filteredPropertyList[idx]);
printf ("%s\n", filteredPropertyList[idx].c_str ());
}
}
}
}
printf ("\nMain settings report\n");
printf ("====================\n");
vector < pair < string, string > >mergedMainSettings =
config.getMergedProperties ();
vector < pair < string, string > >mergedKeySettings =
configKeys.getMergedProperties ();
// Figure out the max # of tabs we need to format display nicely
int
tabCount = 1;
for (int i = 0; i < (int) mergedMainSettings.size (); ++i)
{
const
pair <
string,
string > &
nameValue = mergedMainSettings[i];
bool
displayProperty = false;
if (filteredPropertyList.empty () == false)
{
if (find
(filteredPropertyList.begin (), filteredPropertyList.end (),
nameValue.first) != filteredPropertyList.end ())
{
displayProperty = true;
}
}
else
{
displayProperty = true;
}
if (displayProperty == true)
{
int
requredTabs = ((int) nameValue.first.length () / 8) + 1;
if (nameValue.first.length () % 8)
{
requredTabs++;
}
if (requredTabs > tabCount)
{
tabCount = requredTabs;
}
}
}
for (int i = 0; i < (int) mergedKeySettings.size (); ++i)
{
const
pair <
string,
string > &
nameValue = mergedKeySettings[i];
bool
displayProperty = false;
if (filteredPropertyList.empty () == false)
{
if (find
(filteredPropertyList.begin (), filteredPropertyList.end (),
nameValue.first) != filteredPropertyList.end ())
{
displayProperty = true;
}
}
else
{
displayProperty = true;
}
if (displayProperty == true)
{
int
requredTabs = ((int) nameValue.first.length () / 8) + 1;
if (nameValue.first.length () % 8)
{
requredTabs++;
}
if (requredTabs > tabCount)
{
tabCount = requredTabs;
}
}
}
// Output the properties
for (int i = 0; i < (int) mergedMainSettings.size (); ++i)
{
const
pair <
string,
string > &
nameValue = mergedMainSettings[i];
bool
displayProperty = false;
if (filteredPropertyList.empty () == false)
{
if (find
(filteredPropertyList.begin (), filteredPropertyList.end (),
nameValue.first) != filteredPropertyList.end ())
{
displayProperty = true;
}
}
else
{
displayProperty = true;
}
if (displayProperty == true)
{
printf ("Property Name [%s]", nameValue.first.c_str ());
int
tabs = ((int) nameValue.first.length () / 8) + 1;
for (int j = 0; j < (tabCount - tabs); ++j)
{
printf ("\t");
}
string
displayValue = nameValue.second;
if (nameValue.first == "TranslationGetURLPassword")
{
displayValue = "*****";
}
printf ("Value [%s]\n", displayValue.c_str ());
}
}
printf ("\n\nMain key binding settings report\n");
printf ("====================================\n");
for (int i = 0; i < (int) mergedKeySettings.size (); ++i)
{
const
pair <
string,
string > &
nameValue = mergedKeySettings[i];
bool
displayProperty = false;
if (filteredPropertyList.empty () == false)
{
if (find
(filteredPropertyList.begin (), filteredPropertyList.end (),
nameValue.first) != filteredPropertyList.end ())
{
displayProperty = true;
}
}
else
{
displayProperty = true;
}
if (displayProperty == true)
{
printf ("Property Name [%s]", nameValue.first.c_str ());
int
tabs = ((int) nameValue.first.length () / 8) + 1;
for (int j = 0; j < (tabCount - tabs); ++j)
{
printf ("\t");
}
printf ("Value [%s]\n", nameValue.second.c_str ());
}
}
}
}
Steam & initSteamInstance ()
{
Steam *&
steamInstance =
CacheManager::getCachedItem <
Steam * >(GameConstants::steamCacheInstanceKey);
if (steamInstance == NULL)
{
steamInstance = new Steam ();
}
return *steamInstance;
}
void
setupSteamSettings (bool steamEnabled, bool steamResetStats,
bool debugEnabled)
{
Config & config = Config::getInstance ();
config.setBool ("SteamEnabled", steamEnabled, true);
if (steamEnabled)
{
printf ("*NOTE: Steam Integration Enabled.\n");
if (debugEnabled)
{
printf ("*NOTE: Steam Debugging Enabled.\n");
}
Steam::setDebugEnabled (debugEnabled);
Steam & steam = initSteamInstance ();
// For Debugging purposes:
if (steamResetStats)
{
printf
("*WARNING: Steam Stats / Achievements are being RESET by request!\n");
steam.resetStats (true);
}
string
steamPlayerName = steam.userName ();
string
steamLang = steam.lang ();
printf
("Steam Integration Enabled!\nSteam User Name is [%s] Language is [%s]\n",
steamPlayerName.c_str (), steamLang.c_str ());
bool
needToSaveConfig = false;
string
currentPLayerName = config.getString ("NetPlayerName", "");
if (currentPLayerName == "newbie" || currentPLayerName == "")
{
config.setString ("NetPlayerName", steamPlayerName);
needToSaveConfig = true;
}
if (needToSaveConfig == true)
{
config.save ();
}
}
}
void
CheckForDuplicateData ()
{
Config & config = Config::getInstance ();
string
duplicateWarnings = "";
try
{
{
string
scenarioDir = "";
vector < string > pathList =
config.getPathListForType (ptMaps, scenarioDir);
vector < string > invalidMapList;
vector < string > maps =
MapPreview::findAllValidMaps (pathList, scenarioDir, false, true,
&invalidMapList);
std::sort (maps.begin (), maps.end ());
if (maps.empty () == true)
{
throw
megaglest_runtime_error ("No maps were found!", true);
}
else if (invalidMapList.empty () == false)
{
string
errorMsg =
"Warning invalid maps were detected (will be ignored):\n";
for (int i = 0; i < (int) invalidMapList.size (); ++i)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096, "map [%s]\n",
invalidMapList[i].c_str ());
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
}
vector < string > duplicateMapsToRename;
for (int i = 0; i < (int) maps.size (); ++i)
{
string
map1 = maps[i];
for (int j = 0; j < (int) maps.size (); ++j)
{
if (i != j)
{
string
map2 = maps[j];
if (map1 == map2)
{
if (std::find (duplicateMapsToRename.begin (),
duplicateMapsToRename.end (),
map1) == duplicateMapsToRename.end ())
{
duplicateMapsToRename.push_back (map1);
}
}
}
}
}
if (duplicateMapsToRename.empty () == false)
{
string
errorMsg =
"Warning duplicate maps were detected and renamed:\n";
for (int i = 0; i < (int) duplicateMapsToRename.size (); ++i)
{
string
currentPath = pathList[1];
endPathWithSlash (currentPath);
string
oldFile = currentPath + duplicateMapsToRename[i];
string
newFile = currentPath + duplicateMapsToRename[i];
string
ext = extractExtension (newFile);
newFile =
newFile.substr (0, newFile.length () - ext.length () - 1);
newFile = newFile + "_custom." + ext;
char
szBuf[8096] = "";
int
result = rename (oldFile.c_str (), newFile.c_str ());
if (result != 0)
{
char *
errmsg = strerror (errno);
snprintf (szBuf, 8096,
"Error [%s]\nCould not rename [%s] to [%s]!",
errmsg, oldFile.c_str (), newFile.c_str ());
throw
megaglest_runtime_error (szBuf, true);
}
else
{
snprintf (szBuf, 8096,
"map [%s] in [%s]\nwas renamed to [%s]",
duplicateMapsToRename[i].c_str (), oldFile.c_str (),
newFile.c_str ());
}
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
}
}
{
//tilesets
std::vector < std::string > tileSets;
vector < string > tilesetPaths =
config.getPathListForType (ptTilesets);
findDirs (tilesetPaths, tileSets, false, true);
if (tileSets.empty ())
{
throw
megaglest_runtime_error ("No tilesets were found!", true);
}
vector < string > duplicateTilesetsToRename;
for (int i = 0; i < (int) tileSets.size (); ++i)
{
string
tileSet1 = tileSets[i];
for (int j = 0; j < (int) tileSets.size (); ++j)
{
if (i != j)
{
string
tileSet2 = tileSets[j];
if (tileSet1 == tileSet2)
{
if (std::find (duplicateTilesetsToRename.begin (),
duplicateTilesetsToRename.end (),
tileSet1) ==
duplicateTilesetsToRename.end ())
{
duplicateTilesetsToRename.push_back (tileSet1);
}
}
}
}
}
if (duplicateTilesetsToRename.empty () == false)
{
string
errorMsg =
"Warning duplicate tilesets were detected and renamed:\n";
for (int i = 0; i < (int) duplicateTilesetsToRename.size (); ++i)
{
string
currentPath = tilesetPaths[1];
endPathWithSlash (currentPath);
string
oldFile = currentPath + duplicateTilesetsToRename[i];
string
newFile = currentPath + duplicateTilesetsToRename[i];
newFile = newFile + "_custom";
char
szBuf[8096] = "";
int
result = rename (oldFile.c_str (), newFile.c_str ());
if (result != 0)
{
char *
errmsg = strerror (errno);
snprintf (szBuf, 8096,
"Error [%s]\nCould not rename [%s] to [%s]!",
errmsg, oldFile.c_str (), newFile.c_str ());
throw
megaglest_runtime_error (szBuf, true);
}
else
{
snprintf (szBuf, 8096,
"tileset [%s] in [%s]\nwas renamed to [%s]",
duplicateTilesetsToRename[i].c_str (),
oldFile.c_str (), newFile.c_str ());
string
tilesetName = extractFileFromDirectoryPath (oldFile);
oldFile = newFile + "/" + tilesetName + ".xml";
newFile = newFile + "/" + tilesetName + "_custom.xml";
result = rename (oldFile.c_str (), newFile.c_str ());
if (result != 0)
{
char *
errmsg = strerror (errno);
snprintf (szBuf, 8096,
"Error [%s]\nCould not rename [%s] to [%s]!",
errmsg, oldFile.c_str (), newFile.c_str ());
throw
megaglest_runtime_error (szBuf, true);
}
}
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
}
}
{
vector < string > techPaths = config.getPathListForType (ptTechs);
vector < string > techTrees;
findDirs (techPaths, techTrees, false, true);
if (techTrees.empty ())
{
throw
megaglest_runtime_error ("No tech-trees were found (dup)!",
true);
}
vector < string > duplicateTechtreesToRename;
for (int i = 0; i < (int) techTrees.size (); ++i)
{
string
techtree1 = techTrees[i];
for (int j = 0; j < (int) techTrees.size (); ++j)
{
if (i != j)
{
string
techtree2 = techTrees[j];
if (techtree1 == techtree2)
{
if (std::find (duplicateTechtreesToRename.begin (),
duplicateTechtreesToRename.end (),
techtree1) ==
duplicateTechtreesToRename.end ())
{
duplicateTechtreesToRename.push_back (techtree1);
}
}
}
}
}
if (duplicateTechtreesToRename.empty () == false)
{
string
errorMsg =
"Warning duplicate techtrees were detected and renamed:\n";
for (int i = 0; i < (int) duplicateTechtreesToRename.size (); ++i)
{
string
currentPath = techPaths[1];
endPathWithSlash (currentPath);
string
oldFile = currentPath + duplicateTechtreesToRename[i];
string
newFile = currentPath + duplicateTechtreesToRename[i];
newFile = newFile + "_custom";
char
szBuf[8096] = "";
int
result = rename (oldFile.c_str (), newFile.c_str ());
if (result != 0)
{
char *
errmsg = strerror (errno);
snprintf (szBuf, 8096,
"Error [%s]\nCould not rename [%s] to [%s]!",
errmsg, oldFile.c_str (), newFile.c_str ());
throw
megaglest_runtime_error (szBuf, true);
}
else
{
snprintf (szBuf, 8096,
"techtree [%s] in [%s]\nwas renamed to [%s]",
duplicateTechtreesToRename[i].c_str (),
oldFile.c_str (), newFile.c_str ());
string
tilesetName = extractFileFromDirectoryPath (oldFile);
oldFile = newFile + "/" + tilesetName + ".xml";
newFile = newFile + "/" + tilesetName + "_custom.xml";
int
rename_result = rename (oldFile.c_str (), newFile.c_str ());
if (rename_result != 0)
{
printf ("Error renaming [%s] to [%s]\n", oldFile.c_str (),
newFile.c_str ());
}
}
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
}
}
}
catch (const megaglest_runtime_error & ex)
{
if (mainProgram)
{
mainProgram->getState ()->setForceMouseRender (true);
}
ExceptionHandler::DisplayMessage (ex.what (), false);
}
if (duplicateWarnings != "")
{
if (mainProgram)
{
mainProgram->getState ()->setForceMouseRender (true);
}
ExceptionHandler::DisplayMessage (duplicateWarnings.c_str (), false);
}
}
int
handleCreateDataArchivesCommand (int argc, char **argv)
{
int
return_value = 1;
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES])
+ string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS
[GAME_ARG_CREATE_DATA_ARCHIVES]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
compress_item = paramPartTokens[1];
bool
includeMainData = false;
if (paramPartTokens.size () >= 3
&& paramPartTokens[2] == "include_main")
{
includeMainData = true;
}
Config & config = Config::getInstance ();
string
fileArchiveExtension =
config.getString ("FileArchiveExtension", "");
string
fileArchiveCompressCommand =
config.getString ("FileArchiveCompressCommand", "");
string
fileArchiveCompressCommandParameters =
config.getString ("FileArchiveCompressCommandParameters", "");
int32
fileArchiveCompressCommandSuccessResult =
config.getInt ("FileArchiveCompressCommandSuccessResult", "0");
string
userData = config.getString ("UserData_Root", "");
if (userData != "")
{
endPathWithSlash (userData);
}
int
typesSelected = 0;
if (compress_item == "techtrees" || compress_item == "all")
{
typesSelected++;
vector < string > pathList =
config.getPathListForType (ptTechs, "");
vector < string > results;
findDirs (pathList, results);
printf
("Techtrees found:\n===========================================\n");
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
for (unsigned int j = 0; j < pathList.size (); ++j)
{
string
techPath = pathList[j];
if (techPath != "")
{
endPathWithSlash (techPath);
}
vector < string > results2;
findDirs (techPath + name + "/factions", results2, false,
true);
if (results2.empty () == false)
{
string
techtreePath = techPath + name;
if (includeMainData == false)
{
if (techtreePath.find (userData) == techPath.npos)
{
printf ("Skipping techtree: [%s]\n",
techtreePath.c_str ());
continue;
}
}
string
downloadArchive = techtreePath + fileArchiveExtension;
if (fileExists (downloadArchive) == true)
{
bool
removed = removeFile (downloadArchive);
if (removed == false)
{
printf ("Error could not remove old file: [%s]\n",
downloadArchive.c_str ());
}
}
string
compressCmd =
getFullFileArchiveCompressCommand
(fileArchiveCompressCommand,
fileArchiveCompressCommandParameters,
downloadArchive, techtreePath);
printf ("Running compression command: %s\n",
compressCmd.c_str ());
if (executeShellCommand
(compressCmd,
fileArchiveCompressCommandSuccessResult) == false)
{
printf ("Error could not create new file: [%s]\n",
downloadArchive.c_str ());
}
if (fileExists (downloadArchive) == true)
{
off_t
fileSize = getFileSize (downloadArchive);
// convert to MB
double
megaBytes = ((double) fileSize / 1048576.0);
printf ("%s [download archive %.2fMB]\n", name.c_str (),
megaBytes);
}
}
}
}
printf ("===========================================\nTotal: "
MG_SIZE_T_SPECIFIER "\n", results.size ());
}
if (compress_item == "tilesets" || compress_item == "all")
{
typesSelected++;
vector < string > pathList =
config.getPathListForType (ptTilesets, "");
vector < string > results;
findDirs (pathList, results);
printf
("Tilesets found:\n===========================================\n");
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
for (unsigned int j = 0; j < pathList.size (); ++j)
{
string
tilesetPath = pathList[j];
if (tilesetPath != "")
{
endPathWithSlash (tilesetPath);
}
if (fileExists (tilesetPath + name + "/" + name + ".xml") ==
true)
{
string
tilesetDataPath = tilesetPath + name;
if (includeMainData == false)
{
if (tilesetPath.find (userData) == tilesetPath.npos)
{
printf ("Skipping tileset data: [%s]\n",
tilesetDataPath.c_str ());
continue;
}
}
string
downloadArchive = tilesetDataPath + fileArchiveExtension;
if (fileExists (downloadArchive) == true)
{
bool
removed = removeFile (downloadArchive);
if (removed == false)
{
printf ("Error could not remove old file: [%s]\n",
downloadArchive.c_str ());
}
}
string
compressCmd =
getFullFileArchiveCompressCommand
(fileArchiveCompressCommand,
fileArchiveCompressCommandParameters,
downloadArchive, tilesetDataPath);
printf ("Running compression command: %s\n",
compressCmd.c_str ());
if (executeShellCommand
(compressCmd,
fileArchiveCompressCommandSuccessResult) == false)
{
printf ("Error could not create new file: [%s]\n",
downloadArchive.c_str ());
}
if (fileExists (downloadArchive) == true)
{
off_t
fileSize = getFileSize (downloadArchive);
// convert to MB
double
megaBytes = ((double) fileSize / 1048576.0);
printf ("%s [download archive %.2fMB]\n", name.c_str (),
megaBytes);
}
break;
}
}
}
printf ("===========================================\nTotal: "
MG_SIZE_T_SPECIFIER "\n", results.size ());
}
if (typesSelected == 0)
{
printf ("Compress item [%s] is not valid!\n",
compress_item.c_str ());
return_value = 1;
}
else
return_value = 0;
}
else
{
printf
("\nInvalid missing map specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return_value = 1;
}
}
return return_value;
}
int
handleShowCRCValuesCommand (int argc, char **argv)
{
int
return_value = 1;
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemName = paramPartTokens[1];
string
file = Config::getMapPath (itemName, "", false);
if (file != "")
{
Checksum
checksum;
checksum.addFile (file);
uint32
crcValue = checksum.getSum ();
printf ("CRC value for map [%s] file [%s] is [%u]\n",
itemName.c_str (), file.c_str (), crcValue);
return_value = 0;
}
else
{
printf ("Map [%s] was NOT FOUND\n", itemName.c_str ());
return_value = 1;
}
}
else
{
printf
("\nInvalid missing map specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return_value = 1;
}
}
else
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemName = paramPartTokens[1];
Config & config = Config::getInstance ();
uint32
crcValue =
getFolderTreeContentsCheckSumRecursively
(config.getPathListForType (ptTilesets, ""),
string ("/") + itemName + string ("/*"), ".xml", NULL, true);
if (crcValue != 0)
{
printf ("CRC value for tileset [%s] is [%u]\n", itemName.c_str (),
crcValue);
return_value = 0;
}
else
{
printf ("Tileset [%s] was NOT FOUND\n", itemName.c_str ());
return_value = 1;
}
}
else
{
printf
("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return_value = 1;
}
}
else
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemName = paramPartTokens[1];
Config & config = Config::getInstance ();
uint32
crcValue =
getFolderTreeContentsCheckSumRecursively
(config.getPathListForType (ptTechs, ""), "/" + itemName + "/*",
".xml", NULL, true);
if (crcValue != 0)
{
printf ("CRC value for techtree [%s] is [%u]\n",
itemName.c_str (), crcValue);
return_value = 0;
}
else
{
printf ("Techtree [%s] was NOT FOUND\n", itemName.c_str ());
return_value = 1;
}
}
else
{
printf
("\nInvalid missing techtree specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return_value = 1;
}
}
else
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemName = paramPartTokens[1];
Config & config = Config::getInstance ();
uint32
crcValue =
getFolderTreeContentsCheckSumRecursively
(config.getPathListForType (ptScenarios, ""),
"/" + itemName + "/*", ".xml", NULL, true);
if (crcValue != 0)
{
printf ("CRC value for scenario [%s] is [%u]\n",
itemName.c_str (), crcValue);
return_value = 0;
}
else
{
printf ("Scenario [%s] was NOT FOUND\n", itemName.c_str ());
return_value = 1;
}
}
else
{
printf
("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return_value = 0;
}
}
else
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SHOW_PATH_CRC])
== true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 3 && paramPartTokens[1].length () > 0)
{
string
itemName = paramPartTokens[1];
string
itemNameFilter = paramPartTokens[2];
uint32
crcValue =
getFolderTreeContentsCheckSumRecursively (itemName,
itemNameFilter, NULL,
true);
printf ("CRC value for path [%s] filter [%s] is [%u]\n",
itemName.c_str (), itemNameFilter.c_str (), crcValue);
return_value = 0;
}
else
{
if (paramPartTokens.size () < 2)
{
printf
("\nInvalid missing path and filter specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
}
if (paramPartTokens.size () < 3)
{
printf
("\nInvalid missing filter specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
3 ? paramPartTokens[2].c_str () : NULL));
}
return_value = 1;
}
}
return return_value;
}
int
handleListDataCommand (int argc, char **argv)
{
int
return_value = 1;
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LIST_MAPS]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_MAPS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_MAPS]),
&foundParamIndIndex);
}
Config & config = Config::getInstance ();
vector < string > pathList = config.getPathListForType (ptMaps, "");
vector < string > maps =
MapPreview::findAllValidMaps (pathList, "", false, true);
std::sort (maps.begin (), maps.end ());
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemNameFilter = paramPartTokens[1];
printf ("Using filter for maps list [%s]\n",
itemNameFilter.c_str ());
vector < string > filteredMaps;
for (unsigned int i = 0; i < maps.size (); ++i)
{
string
mapName = maps[i];
if (itemNameFilter.find ("*") != itemNameFilter.npos)
{
if (StartsWith
(mapName,
itemNameFilter.substr (0,
itemNameFilter.find ("*"))) == true)
{
filteredMaps.push_back (mapName);
}
}
else if (mapName == itemNameFilter)
{
filteredMaps.push_back (mapName);
}
}
maps = filteredMaps;
}
printf ("Maps found:\n===========================================\n");
for (unsigned int i = 0; i < maps.size (); ++i)
{
string
mapName = maps[i];
printf ("%s\n", mapName.c_str ());
}
printf ("===========================================\nTotal: "
MG_SIZE_T_SPECIFIER "\n", maps.size ());
return_value = 0;
}
else
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_TECHTRESS]),
&foundParamIndIndex);
}
Config & config = Config::getInstance ();
vector < string > pathList = config.getPathListForType (ptTechs, "");
vector < string > results;
findDirs (pathList, results);
bool
showfactions = false;
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
cmd = paramPartTokens[1];
if (cmd == "showfactions")
{
showfactions = true;
}
else
{
throw
megaglest_runtime_error ("unknown command for techtreelist [" +
cmd + "]");
}
printf ("Using special command for techtree list [%s]\n",
cmd.c_str ());
}
printf
("Techtrees found:\n===========================================\n");
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
for (unsigned int j = 0; j < pathList.size (); ++j)
{
string
techPath = pathList[j];
if (techPath != "")
{
endPathWithSlash (techPath);
}
vector < string > results2;
findDirs (techPath + name + "/factions", results2, false, true);
if (results2.empty () == false)
{
string
downloadArchive = techPath + name + ".7z";
if (fileExists (downloadArchive) == true)
{
off_t
fileSize = getFileSize (downloadArchive);
// convert to MB
double
megaBytes = ((double) fileSize / 1048576.0);
printf ("%s [download archive %.2fMB]\n", name.c_str (),
megaBytes);
}
else
{
printf ("%s\n", name.c_str ());
}
if (showfactions == true)
{
printf ("--> Factions:\n");
for (unsigned int k = 0; k < results2.size (); ++k)
{
string
name2 = results2[k];
printf ("--> %s\n", name2.c_str ());
}
printf ("--> Total Factions: " MG_SIZE_T_SPECIFIER "\n",
results2.size ());
break;
}
}
}
}
printf
("===========================================\nTotal Techtrees: "
MG_SIZE_T_SPECIFIER "\n", results.size ());
return_value = 0;
}
else
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_SCENARIOS]),
&foundParamIndIndex);
}
Config & config = Config::getInstance ();
vector < string > pathList =
config.getPathListForType (ptScenarios, "");
vector < string > results;
findDirs (pathList, results);
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemNameFilter = paramPartTokens[1];
printf ("Using filter for scenarios list [%s]\n",
itemNameFilter.c_str ());
vector < string > filtered;
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
if (itemNameFilter.find ("*") != itemNameFilter.npos)
{
if (StartsWith
(name,
itemNameFilter.substr (0,
itemNameFilter.find ("*"))) == true)
{
filtered.push_back (name);
}
}
else if (name == itemNameFilter)
{
filtered.push_back (name);
}
}
results = filtered;
}
printf
("Scenarios found:\n===========================================\n");
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
printf ("%s\n", name.c_str ());
}
printf ("===========================================\nTotal: "
MG_SIZE_T_SPECIFIER "\n", results.size ());
return_value = 0;
}
else
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LIST_TILESETS])
== true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_TILESETS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_TILESETS]),
&foundParamIndIndex);
}
Config & config = Config::getInstance ();
vector < string > pathList =
config.getPathListForType (ptTilesets, "");
vector < string > results;
findDirs (pathList, results);
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemNameFilter = paramPartTokens[1];
printf ("Using filter for tilesets list [%s]\n",
itemNameFilter.c_str ());
vector < string > filtered;
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
if (itemNameFilter.find ("*") != itemNameFilter.npos)
{
if (StartsWith
(name,
itemNameFilter.substr (0,
itemNameFilter.find ("*"))) == true)
{
filtered.push_back (name);
}
}
else if (name == itemNameFilter)
{
filtered.push_back (name);
}
}
results = filtered;
}
printf
("Tilesets found:\n===========================================\n");
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
for (unsigned int j = 0; j < pathList.size (); ++j)
{
string
tilesetPath = pathList[j];
if (tilesetPath != "")
{
endPathWithSlash (tilesetPath);
}
if (fileExists (tilesetPath + name + "/" + name + ".xml") == true)
{
string
downloadArchive = tilesetPath + name + ".7z";
if (fileExists (downloadArchive) == true)
{
off_t
fileSize = getFileSize (downloadArchive);
// convert to MB
double
megaBytes = ((double) fileSize / 1048576.0);
printf ("%s [download archive %.2fMB]\n", name.c_str (),
megaBytes);
}
else
{
printf ("%s\n", name.c_str ());
}
break;
}
}
}
printf ("===========================================\nTotal: "
MG_SIZE_T_SPECIFIER "\n", results.size ());
return_value = 0;
}
else
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LIST_TUTORIALS]),
&foundParamIndIndex);
}
Config & config = Config::getInstance ();
vector < string > pathList =
config.getPathListForType (ptTutorials, "");
vector < string > results;
findDirs (pathList, results);
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
itemNameFilter = paramPartTokens[1];
printf ("Using filter for tutorials list [%s]\n",
itemNameFilter.c_str ());
vector < string > filtered;
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
if (itemNameFilter.find ("*") != itemNameFilter.npos)
{
if (StartsWith
(name,
itemNameFilter.substr (0,
itemNameFilter.find ("*"))) == true)
{
filtered.push_back (name);
}
}
else if (name == itemNameFilter)
{
filtered.push_back (name);
}
}
results = filtered;
}
printf
("Tutorials found:\n===========================================\n");
for (unsigned int i = 0; i < results.size (); ++i)
{
string
name = results[i];
for (unsigned int j = 0; j < pathList.size (); ++j)
{
string
tutorialsPath = pathList[j];
if (tutorialsPath != "")
{
endPathWithSlash (tutorialsPath);
}
if (fileExists (tutorialsPath + name + "/" + name + ".xml") ==
true)
{
string
downloadArchive = tutorialsPath + name + ".7z";
if (fileExists (downloadArchive) == true)
{
off_t
fileSize = getFileSize (downloadArchive);
// convert to MB
double
megaBytes = ((double) fileSize / 1048576.0);
printf ("%s [download archive %.2fMB]\n", name.c_str (),
megaBytes);
}
else
{
printf ("%s\n", name.c_str ());
}
break;
}
}
}
printf ("===========================================\nTotal: "
MG_SIZE_T_SPECIFIER "\n", results.size ());
return_value = 0;
}
return return_value;
}
int
glestMain (int argc, char **argv)
{
#ifdef SL_LEAK_DUMP
//AllocInfo::set_application_binary(executable_path(argv[0],true));
string & app = AllocInfo::get_application_binary ();
app = executable_path (argv[0], true);
//want_full_leak_stacktrace = true;
//want_full_leak_stacktrace_line_numbers = true;
#endif
Thread::setMainThreadId ();
// printf("START ALLOC char 200\n");
//char *ptr = new char[200];
// printf("END ALLOC char 200\n");
// return -1;
SystemFlags::VERBOSE_MODE_ENABLED = false;
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_VERBOSE_MODE]) ==
true)
{
SystemFlags::VERBOSE_MODE_ENABLED = true;
Thread::setEnableVerboseMode (true);
//LuaScript::setDebugModeEnabled(true);
}
// DEbug testing threads
//Thread::setEnableVerboseMode(true);
PlatformExceptionHandler::application_binary =
executable_path (argv[0], true);
mg_app_name = GameConstants::application_name;
mailStringSupport = mailString;
SystemFlags::ENABLE_THREADED_LOGGING = false;
disableBacktrace = false;
bool
foundInvalidArgs = false;
preCacheThread = NULL;
Properties::setApplicationPath (executable_path (argv[0]));
Properties::setApplicationDataPath (executable_path (argv[0]));
Properties::setGameVersion (glestVersionString);
ServerSocket::setMaxPlayerCount (GameConstants::maxPlayers);
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]) == true)
{
disableBacktrace = true;
}
PlatformExceptionHandler::disableBacktrace = disableBacktrace;
#if defined(CUSTOM_DATA_INSTALL_PATH)
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("\n\nCUSTOM_DATA_INSTALL_PATH = [%s]\n\n",
formatPath (TOSTRING (CUSTOM_DATA_INSTALL_PATH)).c_str ());
#endif
const int
knownArgCount = sizeof (GAME_ARGS) / sizeof (GAME_ARGS[0]);
for (int idx = 1; idx < argc; ++idx)
{
if (hasCommandArgument
(knownArgCount, (char **) &GAME_ARGS[0], argv[idx], NULL, 0,
true) == false)
{
foundInvalidArgs = true;
printf ("\nInvalid argument: %s", argv[idx]);
}
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_HELP]) == true ||
foundInvalidArgs == true)
{
printParameterHelp (argv[0], foundInvalidArgs);
return 2;
}
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true)
{
//isMasterServerModeEnabled = true;
//Window::setMasterserverMode(isMasterServerModeEnabled);
GlobalStaticFlags::setIsNonGraphicalModeEnabled (true);
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
headless_command_list = paramPartTokens[1];
vector < string > paramHeadlessCommandList;
Tokenize (headless_command_list, paramHeadlessCommandList, ",");
for (unsigned int i = 0; i < paramHeadlessCommandList.size (); ++i)
{
string
headless_command = paramHeadlessCommandList[i];
if (headless_command == "exit")
{
printf ("Forcing quit after game has completed [%s]\n",
headless_command.c_str ());
Program::setWantShutdownApplicationAfterGame (true);
}
else if (headless_command == "vps")
{
printf ("Disabled reading from console [%s]\n",
headless_command.c_str ());
disableheadless_console = true;
}
else if (headless_command == "lan")
{
printf ("Forcing local LAN mode [%s]\n",
headless_command.c_str ());
GlobalStaticFlags::setFlag (gsft_lan_mode);
}
}
}
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SERVER_TITLE]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SERVER_TITLE]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SERVER_TITLE]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
Config & config = Config::getInstance ();
string
serverTitle = paramPartTokens[1];
printf ("Forcing serverTitle[%s]\n", serverTitle.c_str ());
config.setString ("ServerTitle", serverTitle, true);
}
else
{
printf
("\nInvalid missing server title specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
//#ifdef WIN32
//SocketManager winSockManager;
//#endif
bool
haveSpecialOutputCommandLineOption = false;
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SDL_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LUA_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_CURL_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_XERCES_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VERSION]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_MAPS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) ==
true)
{
haveSpecialOutputCommandLineOption = true;
}
if (haveSpecialOutputCommandLineOption == false ||
hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VERSION]) == true)
{
printf ("%s %s", extractFileFromDirectoryPath (argv[0]).c_str (),
getNetworkPlatformFreeVersionString ().c_str ());
// printf("\nCompiled using: %s on: %s platform: %s endianness: %s",getCompilerNameString().c_str(),getCompileDateTime().c_str(),getPlatformNameString().c_str(),(::Shared::PlatformByteOrder::isBigEndian() == true ? "big" : "little"));
printf ("\nCompiled using: %s platform: %s endianness: %s",
getCompilerNameString ().c_str (),
getPlatformNameString ().c_str (),
(::Shared::PlatformByteOrder::isBigEndian () ==
true ? "big" : "little"));
// printf("\n\nData type sizes int8 = " MG_SIZE_T_SPECIFIER " int16 = " MG_SIZE_T_SPECIFIER " int32 = " MG_SIZE_T_SPECIFIER " int64 = " MG_SIZE_T_SPECIFIER "\n\n",sizeof(int8),sizeof(int16),sizeof(int32),sizeof(int64));
//
// Config::getInstance().setBool("DebugNetworkPackets",true,true);
// NetworkMessageIntro data(424336, "mg_version_x","player_x", 3, nmgstOk,444444, 555555, "english");
// unsigned char *buf = data.packMessage();
// printf("\nSend packet size = %u\n%s\n",data.getPackedSize(),data.toString().c_str());
// data.dump_packet("Send data", buf, data.getPackedSize());
// //delete [] buf;
//
// NetworkMessageIntro data2;
// data2.unpackMessage(buf);
// printf("\nReceive packet size = %u\n%s\n",data2.getPackedSize(),data2.toString().c_str());
// data2.dump_packet("nReceive data", buf, data2.getPackedSize());
// delete [] buf;
// SwitchSetupRequest data("factionname", 3,-1,2,"softcoder",10, 11,"eng");
//
// unsigned char *buf = data.packMessage();
// printf("\nSend packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags());
// //delete [] buf;
//
// data.unpackMessage(buf);
// printf("\nGot packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags());
// delete [] buf;
// int8 a = 1;
// uint8 b = 2;
// int16 c = 3;
// uint16 d = 4;
// int32 e = 5;
// uint32 f = 6;
//
// printf("\nPack test #1: [%d][%u][%d][%u][%d][%u]\n,",a,b,c,d,e,f);
//
// unsigned char *buf = new unsigned char[100];
// unsigned int packedsize = pack(buf, "cChHlL",
// a,
// b,
// c,
// d,
// e,
// f);
//
// printf("Pack test #2: [%u][%s]\n,",packedsize,buf);
//
// int8 a1 = 0;
// uint8 b1 = 0;
// int16 c1 = 0;
// uint16 d1 = 0;
// int32 e1 = 0;
// uint32 f1 = 0;
//
// unpack(buf, "cChHlL",
// &a1,
// &b1,
// &c1,
// &d1,
// &e1,
// &f1);
//
// printf("UnPack test #3: [%d][%u][%d][%u][%d][%u]\n,",a1,b1,c1,d1,e1,f1);
if (SystemFlags::VERBOSE_MODE_ENABLED == true)
{
int8
testVar = 111;
printf ("\nEndian value = %d", testVar);
testVar =::Shared::PlatformByteOrder::toCommonEndian (testVar);
printf ("\nEndian to common value = %d", testVar);
testVar =::Shared::PlatformByteOrder::fromCommonEndian (testVar);
printf ("\nEndian from common value = %d", testVar);
printf ("\nint8 sizeof = " MG_SIZE_T_SPECIFIER "", sizeof (int8));
printf ("\nSwitchSetupRequest sizeof = " MG_SIZE_T_SPECIFIER "",
SwitchSetupRequest ().getDataSize ());
}
printf ("\nGIT: [%s]", getGITRevisionString ().c_str ());
#ifdef USE_STREFLOP
# if defined(STREFLOP_SSE)
const char *
instruction_set = "[SSE]";
# elif defined(STREFLOP_X87)
const char *
instruction_set = "[X87]";
# elif defined(STREFLOP_SOFT)
const char *
instruction_set = "[SOFTFLOAT]";
# else
const char *
instruction_set = "[none]";
# endif
# if defined(STREFLOP_NO_DENORMALS)
const char *
denormals = "[no-denormals]";
# else
const char *
denormals = "[denormals]";
# endif
printf (" - using STREFLOP %s - %s\n", instruction_set, denormals);
#else
printf ("\n");
#endif
}
setGameVersion (glestVersionString);
setGameGITVersion (getRAWGITRevisionString ());
#ifdef WIN32
CheckPacketThrottling ();
#endif
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SDL_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LUA_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_CURL_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_XERCES_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VERSION]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_MAPS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) ==
true)
{
VideoPlayer::setDisabled (true);
}
//throw megaglest_runtime_error("Test!");
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SDL_INFO]) ==
true)
{
SDL_version
ver;
// Prints the compile time version
SDL_VERSION (&ver);
print_SDL_version ("SDL compile-time version", &ver);
// Prints the run-time version
SDL_GetVersion (&ver);
print_SDL_version ("SDL runtime version", &ver);
//const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo();
//printf("Video card Memory: %u\n",vidInfo->video_mem);
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LUA_INFO]) ==
true)
{
printf ("LUA version: %s\n", LUA_RELEASE);
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_CURL_INFO]) ==
true)
{
curl_version_info_data *
curlVersion = curl_version_info (CURLVERSION_NOW);
printf ("CURL version: %s [%s] SSL enabled: %d\n",
curlVersion->version,
(curlVersion->ssl_version !=
NULL ? curlVersion->ssl_version : ""),
((curlVersion->features & CURL_VERSION_SSL) ==
CURL_VERSION_SSL ? true : false));
if (curlVersion->protocols != NULL
&& curlVersion->protocols[0] != NULL)
{
printf ("protocols: ");
for (unsigned int i = 0;
curlVersion->protocols != NULL
&& curlVersion->protocols[i] != NULL; ++i)
{
printf ("%s ", curlVersion->protocols[i]);
if (i > 0 && i % 10 == 0)
{
printf ("\n ");
}
}
printf ("\n");
}
}
#if defined(WANT_XERCES)
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_XERCES_INFO]) ==
true)
{
printf ("XERCES version: %s\n", XERCES_FULLVERSIONDOT);
}
#endif
if ((hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_VERSION]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SDL_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LUA_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_CURL_INFO]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_XERCES_INFO]) == true)
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_OPENGL_INFO]) == false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) ==
false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) ==
false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) ==
false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) ==
false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) ==
false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_MAPS]) == false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TILESETS]) == false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == false
&& hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) ==
false)
{
return 0;
}
if (hasCommandArgument (argc, argv, string (GAME_ARGS[GAME_ARG_MOD])) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_MOD]) + string ("="),
&foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv, string (GAME_ARGS[GAME_ARG_MOD]),
&foundParamIndIndex);
}
string
scenarioName = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (scenarioName, paramPartTokens, "=");
if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0)
{
string
autoloadModName = paramPartTokens[1];
if (Properties::applyTagsToValue (autoloadModName) == true)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Property key [%s] now has value [%s]\n",
Config::ACTIVE_MOD_PROPERTY_NAME,
autoloadModName.c_str ());
}
Config::setCustomRuntimeProperty (Config::ACTIVE_MOD_PROPERTY_NAME,
autoloadModName);
printf ("Setting mod active [%s]\n", autoloadModName.c_str ());
}
else
{
printf
("\nInvalid mod pathname specified on commandline [%s] mod [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], foundInvalidArgs);
return 1;
}
}
SystemFlags::init (haveSpecialOutputCommandLineOption);
//SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = true;
//SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = true;
MainWindow *
mainWindow = NULL;
Program *
program = NULL;
ExceptionHandler
exceptionHandler;
exceptionHandler.install (getCrashDumpFileName ());
int
shutdownFadeSoundMilliseconds = 1000;
Chrono
chronoshutdownFadeSound;
SimpleTaskThread *
soundThreadManager = NULL;
try
{
// Setup paths to game items (like data, logs, ini etc)
int
setupResult = setupGameItemPaths (argc, argv, NULL);
if (setupResult != 0)
{
return setupResult;
}
// Attempt to read ini files
Config & config = Config::getInstance ();
setupGameItemPaths (argc, argv, &config);
setupSteamSettings (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_STEAM]),
hasCommandArgument (argc, argv,
GAME_ARGS
[GAME_ARG_STEAM_RESET_STATS]),
hasCommandArgument (argc, argv,
GAME_ARGS
[GAME_ARG_STEAM_DEBUG]));
if (config.getString ("PlayerId", "") == "")
{
char
uuid_str[38];
get_uuid_string (uuid_str, sizeof (uuid_str));
config.setString ("PlayerId", uuid_str);
config.save ();
}
//printf("Players UUID: [%s]\n",config.getString("PlayerId","").c_str());
if (config.getBool ("DisableLuaSandbox", "false") == true)
{
LuaScript::setDisableSandbox (true);
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKETS]) == true)
{
printf ("*NOTE: debugging network packets.\n");
config.setBool ("DebugNetworkPackets", true, true);
}
if (hasCommandArgument
(argc, argv,
GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_SIZES]) == true)
{
printf ("*NOTE: debugging network packet SIZES.\n");
config.setBool ("DebugNetworkPacketSizes", true, true);
}
if (hasCommandArgument
(argc, argv,
GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_STATS]) == true)
{
printf ("*NOTE: debugging network packet STATISTICS.\n");
config.setBool ("DebugNetworkPacketStats", true, true);
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_ENABLE_NEW_PROTOCOL]) == true)
{
printf ("*NOTE: enabling new network protocol.\n");
NetworkMessage::useOldProtocol = false;
}
Socket::setBroadCastPort (config.getInt ("BroadcastPort",
intToStr
(Socket::getBroadCastPort
()).c_str ()));
Socket::disableNagle = config.getBool ("DisableNagle", "false");
if (Socket::disableNagle)
{
printf
("*WARNING users wants to disable the socket nagle algorithm.\n");
}
Socket::DEFAULT_SOCKET_SENDBUF_SIZE =
config.getInt ("DefaultSocketSendBufferSize",
intToStr (Socket::DEFAULT_SOCKET_SENDBUF_SIZE).
c_str ());
if (Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0)
{
printf
("*WARNING users wants to set default socket send buffer size to: %d\n",
Socket::DEFAULT_SOCKET_SENDBUF_SIZE);
}
Socket::DEFAULT_SOCKET_RECVBUF_SIZE =
config.getInt ("DefaultSocketReceiveBufferSize",
intToStr (Socket::DEFAULT_SOCKET_RECVBUF_SIZE).
c_str ());
if (Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0)
{
printf
("*WARNING users wants to set default socket receive buffer size to: %d\n",
Socket::DEFAULT_SOCKET_RECVBUF_SIZE);
}
shutdownFadeSoundMilliseconds =
config.getInt ("ShutdownFadeSoundMilliseconds",
intToStr (shutdownFadeSoundMilliseconds).c_str ());
string
userData = config.getString ("UserData_Root", "");
if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) !=
"")
{
userData =
getGameReadWritePath (GameConstants::path_logs_CacheLookupKey);
}
if (userData != "")
{
endPathWithSlash (userData);
}
string
data_path_check =
getGameReadWritePath (GameConstants::path_data_CacheLookupKey);
string
userDataPath_check =
getGameCustomCoreDataPath (data_path_check, "");
if (data_path_check == userDataPath_check)
{
printf
("****WARNING**** your game data path and user data path are the same.\nThis will likely create problems: %s\n",
data_path_check.c_str ());
throw
megaglest_runtime_error
("Regular and User data paths cannot have the same value [" +
userDataPath_check + "]");
}
if (userData != "")
{
if (isdir (userData.c_str ()) == false)
{
createDirectoryPaths (userData);
}
}
string
crcCachePath = userData + "cache/";
if (isdir (crcCachePath.c_str ()) == false)
{
createDirectoryPaths (crcCachePath);
}
setCRCCacheFilePath (crcCachePath);
string
savedGamePath = userData + "saved/";
if (isdir (savedGamePath.c_str ()) == false)
{
createDirectoryPaths (savedGamePath);
}
string
tempDataPath = userData + "temp/";
tempDataLocation = tempDataPath;
if (isdir (tempDataPath.c_str ()) == true)
{
removeFolder (tempDataPath);
}
createDirectoryPaths (tempDataPath);
string
binaryNameOld =
Properties::getApplicationPath () +
extractFileFromDirectoryPath
(PlatformExceptionHandler::application_binary) + "__REMOVE";
if (fileExists (binaryNameOld))
{
removeFile (binaryNameOld);
}
string
netInterfaces = config.getString ("NetworkInterfaces", "");
if (netInterfaces != "")
{
//printf("Using network interfaces: %s\n",netInterfaces.c_str());
std::vector < std::string > intfList;
Tokenize (netInterfaces, intfList, ",");
Socket::setIntfTypes (intfList);
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_PORTS]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_PORTS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_PORTS]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
portsToUse = paramPartTokens[1];
vector < string > paramPartPortsTokens;
Tokenize (portsToUse, paramPartPortsTokens, ",");
if (paramPartPortsTokens.size () >= 2
&& paramPartPortsTokens[1].length () > 0)
{
int
internalPort = strToInt (paramPartPortsTokens[0]);
int
externalPort = strToInt (paramPartPortsTokens[1]);
printf ("Forcing internal port# %d, external port# %d\n",
internalPort, externalPort);
config.setInt ("PortServer", internalPort, true);
config.setInt ("PortExternal", externalPort, true);
config.setInt ("FTPServerPort", internalPort + 1, true);
if (paramPartPortsTokens.size () >= 3
&& paramPartPortsTokens[2].length () > 0)
{
int
statusPort = strToInt (paramPartPortsTokens[2]);
printf ("Forcing status port# %d\n", statusPort);
config.setInt ("ServerAdminPort", statusPort, true);
}
}
else
{
printf
("\nInvalid ports specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
else
{
printf
("\nInvalid missing ports specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS])) == true)
{
Ip
ip ("localhost");
int
port = Config::getInstance ().getInt ("ServerAdminPort",
intToStr
(GameConstants::
serverAdminPort).c_str ());
ClientSocket
clientSocket;
clientSocket.setBlock (false);
clientSocket.connect (ip, port);
if (clientSocket.isConnected () == true)
{
clientSocket.setBlock (true);
char
szBuf[8096] = "";
clientSocket.receive (&szBuf[0], 8095, false);
std::cout << szBuf << std::endl;
}
else
{
std::cout <<
"Could not connect (possibly no clients connected) to host: " <<
ip.getString () << " port: " << port << std::endl;
}
return 0;
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_DISABLE_SOUND])
== true
|| hasCommandArgument (argc, argv,
string (GAME_ARGS
[GAME_ARG_MASTERSERVER_MODE])) ==
true)
{
config.setString ("FactorySound", "None", true);
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true)
{
//Logger::getInstance().setMasterserverMode(true);
//Model::setMasterserverMode(true);
//Shared::Sound::Sound::setMasterserverMode(true);
}
}
if (hasCommandArgument
(argc, argv,
GAME_ARGS[GAME_ARG_DISABLE_OPENGL_CAPS_CHECK]) == true
|| config.getBool ("CheckGlCaps") == false)
{
printf ("**WARNING** disabling opengl capability checking...\n");
config.setBool ("CheckGlCaps", false, true);
}
bool
enableATIHacks = config.getBool ("EnableATIHacks", "false");
if (enableATIHacks == true)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("**WARNING** Enabling ATI video card hacks\n");
TextureGl::setEnableATIHacks (enableATIHacks);
}
Renderer::renderText3DEnabled =
config.getBool ("Enable3DFontRendering",
intToStr (Renderer::renderText3DEnabled).c_str ());
if (config.getBool ("EnableLegacyFonts", "false") == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]) ==
true)
{
::Shared::Graphics::Font::forceLegacyFonts = true;
Renderer::renderText3DEnabled = false;
printf ("**WARNING** Forcing Legacy Fonts Enabled\n");
}
else
{
Renderer::renderText3DEnabled =
config.getBool ("Enable3DFontRendering",
intToStr (Renderer::renderText3DEnabled).
c_str ());
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_USE_RESOLUTION]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_RESOLUTION]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_RESOLUTION]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
settings = paramPartTokens[1];
printf ("Forcing resolution [%s]\n", settings.c_str ());
paramPartTokens.clear ();
Tokenize (settings, paramPartTokens, "x");
if (paramPartTokens.size () >= 2)
{
int
newScreenWidth = strToInt (paramPartTokens[0]);
config.setInt ("ScreenWidth", newScreenWidth, true);
int
newScreenHeight = strToInt (paramPartTokens[1]);
config.setInt ("ScreenHeight", newScreenHeight, true);
}
else
{
printf
("\nInvalid missing resolution settings specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
else
{
printf
("\nInvalid missing resolution setting specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_COLORBITS])
== true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_COLORBITS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_COLORBITS]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
settings = paramPartTokens[1];
printf ("Forcing colorbits [%s]\n", settings.c_str ());
int
newColorBits = strToInt (settings);
config.setInt ("ColorBits", newColorBits, true);
}
else
{
printf
("\nInvalid missing colorbits settings specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_DEPTHBITS])
== true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_DEPTHBITS]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
settings = paramPartTokens[1];
printf ("Forcing depthbits [%s]\n", settings.c_str ());
int
newDepthBits = strToInt (settings);
config.setInt ("DepthBits", newDepthBits, true);
}
else
{
printf
("\nInvalid missing depthbits setting specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_FULLSCREEN]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
settings = paramPartTokens[1];
printf ("Forcing fullscreen [%s]\n", settings.c_str ());
bool
newFullScreenMode = strToBool (settings);
config.setBool ("Windowed", !newFullScreenMode, true);
}
else
{
printf
("\nInvalid missing fullscreen setting specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SET_GAMMA]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SET_GAMMA]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_SET_GAMMA]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
settings = paramPartTokens[1];
printf ("Forcing gamma [%s]\n", settings.c_str ());
float
newGammaValue = strToFloat (settings);
config.setFloat ("GammaValue", newGammaValue, true);
}
else
{
printf
("\nInvalid missing gamma setting specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_DISABLE_VIDEOS]) == true)
{
VideoPlayer::setDisabled (true);
}
else if (config.getBool ("EnableVideos", "true") == false)
{
VideoPlayer::setDisabled (true);
}
// Set some statics based on ini entries
SystemFlags::ENABLE_THREADED_LOGGING =
config.getBool ("ThreadedLogging", "true");
FontGl::setDefault_fontType (config.getString ("DefaultFont",
FontGl::
getDefault_fontType ().
c_str ()));
UPNP_Tools::isUPNP = !config.getBool ("DisableUPNP", "false");
Texture::useTextureCompression =
config.getBool ("EnableTextureCompression", "false");
// 256 for English
// 30000 for Chinese
::Shared::Graphics::Font::charCount =
config.getInt ("FONT_CHARCOUNT",
intToStr (::Shared::Graphics::Font::charCount).
c_str ());
::Shared::Graphics::Font::fontTypeName =
config.
getString ("FONT_TYPENAME",::Shared::Graphics::Font::fontTypeName.
c_str ());
::Shared::Graphics::Font::fontIsMultibyte =
config.getBool ("FONT_MULTIBYTE",
intToStr (::Shared::Graphics::Font::
fontIsMultibyte).c_str ());
::Shared::Graphics::Font::fontIsRightToLeft =
config.getBool ("FONT_RIGHTTOLEFT",
intToStr (::Shared::Graphics::Font::
fontIsRightToLeft).c_str ());
::Shared::Graphics::Font::baseSize =
config.getInt ("FONT_BASE_SIZE",
intToStr (::Shared::Graphics::Font::baseSize).
c_str ());
::Shared::Graphics::Font::scaleFontValue =
config.getFloat ("FONT_SCALE_SIZE",
floatToStr (::Shared::Graphics::Font::
scaleFontValue).c_str ());
::Shared::Graphics::Font::scaleFontValueCenterHFactor =
config.getFloat ("FONT_SCALE_CENTERH_FACTOR",
floatToStr (::Shared::Graphics::Font::
scaleFontValueCenterHFactor).c_str ());
::Shared::Graphics::Font::langHeightText =
config.
getString ("FONT_HEIGHT_TEXT",::Shared::Graphics::Font::
langHeightText.c_str ());
::Shared::Graphics::Font::fontSupportMixedRightToLeft =
config.getBool ("FONT_RIGHTTOLEFT_MIXED_SUPPORT",
intToStr (::Shared::Graphics::Font::
fontSupportMixedRightToLeft).c_str ());
// Example values:
// DEFAULT_CHARSET (English) = 1
// GB2312_CHARSET (Chinese) = 134
::Shared::Platform::PlatformContextGl::charSet =
config.getInt ("FONT_CHARSET",
intToStr (::Shared::Platform::PlatformContextGl::
charSet).c_str ());
if (config.getBool ("No2DMouseRendering", "false") == false)
{
showCursor (false);
//showWindowCursorState = false;
}
if (config.getInt ("DEFAULT_HTTP_TIMEOUT",
intToStr (SystemFlags::
DEFAULT_HTTP_TIMEOUT).c_str ()) >= 0)
{
SystemFlags::DEFAULT_HTTP_TIMEOUT =
config.getInt ("DEFAULT_HTTP_TIMEOUT",
intToStr (SystemFlags::DEFAULT_HTTP_TIMEOUT).
c_str ());
}
bool
allowAltEnterFullscreenToggle =
config.getBool ("AllowAltEnterFullscreenToggle",
boolToStr (::Shared::Platform::Window::
getAllowAltEnterFullscreenToggle ()).
c_str ());
::Shared::Platform::Window::
setAllowAltEnterFullscreenToggle (allowAltEnterFullscreenToggle);
if (config.getBool ("noTeamColors", "false") == true)
{
MeshCallbackTeamColor::noTeamColors = true;
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LUA_DEBUG]) ==
true)
{
printf ("Forcing LUA debugging enabled!\n");
config.setBool ("DebugLUA", true, true);
}
// Setup debug logging etc
setupLogging (config, haveSpecialOutputCommandLineOption);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, fontIsRightToLeft = %d\n",
__FILE__, __FUNCTION__,
__LINE__,::Shared::Graphics::Font::
charCount,::Shared::Graphics::Font::
fontTypeName.
c_str (),::Shared::Platform::
PlatformContextGl::charSet,::Shared::
Graphics::Font::fontIsMultibyte,::Shared::
Graphics::Font::fontIsRightToLeft);
NetworkInterface::setDisplayMessageFunction (ExceptionHandler::
DisplayMessage);
MenuStateMasterserver::setDisplayMessageFunction (ExceptionHandler::
DisplayMessage);
#ifdef USE_STREFLOP
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"%s, STREFLOP enabled.\n",
getNetworkVersionString ().c_str ());
#else
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"%s, STREFLOP NOT enabled.\n",
getNetworkVersionString ().c_str ());
#endif
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, "START\n");
SystemFlags::OutputDebug (SystemFlags::debugPathFinder, "START\n");
// Setup hotkeys from key ini files
Config & configKeys =
Config::getInstance (std::pair < ConfigType,
ConfigType > (cfgMainKeys, cfgUserKeys),
std::pair < string,
string > (Config::glestkeys_ini_filename,
Config::glestuserkeys_ini_filename),
std::pair < bool, bool > (true, false),
config.getString ("GlestKeysIniPath", ""));
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true)
{
ShowINISettings (argc, argv, config, configKeys);
return 0;
}
// Explicitly disable VBO's
if (config.getBool ("DisableVBO", "false") == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true)
{
setVBOSupported (false);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("**INFO** Disabling VBOs\n");
}
if (config.getBool ("DisableVertexInterpolation", "false")
|| hasCommandArgument (argc, argv,
GAME_ARGS
[GAME_ARG_DISABLE_VERTEX_INTERPOLATION]))
{
InterpolationData::setEnableInterpolation (false);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("**INFO** Disabling Interpolation\n");
}
if (config.getBool ("EnableVSynch", "false") == true)
{
::Shared::Platform::Window::setTryVSynch (true);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("**ENABLED OPENGL VSYNCH**\n");
}
//float pingTime = Socket::getAveragePingMS("soft-haus.com");
//printf("Ping time = %f\n",pingTime);
// Load the language strings
Lang & lang = Lang::getInstance ();
string
language = config.getString ("Lang");
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_LANGUAGE])
== true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_LANGUAGE]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_LANGUAGE]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
language = paramPartTokens[1];
printf ("Forcing language [%s]\n", language.c_str ());
}
else
{
printf
("\nInvalid missing language specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
else
{
#ifdef _WIN32
int
localeBufferSize =
GetLocaleInfo (LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME,
NULL, 0);
wchar_t *
sysLocale = new wchar_t[localeBufferSize];
GetLocaleInfo (LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME,
sysLocale, localeBufferSize);
//String langValue(sysLocale);
//const char *lang_locale = langValue.c_str();
char
langValue[1024] = "";
wcstombs (langValue, sysLocale, 1023);
const char *
lang_locale = &langValue[0];
delete[]sysLocale;
#else
const char *
lang_locale = setlocale (LC_ALL, "");
#endif
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("Locale is: [%s]\n", lang_locale);
if (lang_locale != NULL && strlen (lang_locale) >= 2)
{
if (config.getBool ("AutoLocaleLanguageDetect", "true") == true)
{
language = lang_locale;
language = language.substr (0, 2);
printf ("Auto setting language [%s]\n", language.c_str ());
config.setString ("AutoLocaleLanguageDetect", "false");
config.save ();
}
}
}
if (hasCommandArgument
(argc, argv, string (GAME_ARGS[GAME_ARG_AUTO_TEST])) == true
|| Config::getInstance ().getBool ("AutoTest", "false") == true)
{
printf ("Running in auto test mode\n");
}
if (hasCommandArgument
(argc, argv, string (GAME_ARGS[GAME_ARG_AUTO_TEST])) == true)
{
Config::getInstance ().setBool ("AutoTest", true, true);
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_AUTO_TEST]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_AUTO_TEST]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
vector < string > paramPartTokens2;
Tokenize (paramPartTokens[1], paramPartTokens2, ",");
if (paramPartTokens2.empty () == false
&& paramPartTokens2[0].length () > 0)
{
string
newMaxSeconds = paramPartTokens2[0];
time_t
newTimeMaxSeconds = strToInt (newMaxSeconds);
AutoTest::setMaxGameTime (newTimeMaxSeconds);
printf
("Forcing maximum game time to [%ld] seconds (%.2f minutes)\n",
(long int) newTimeMaxSeconds,
((double) newTimeMaxSeconds / 60.0));
}
if (paramPartTokens2.size () >= 3
&& paramPartTokens2[2].length () > 0)
{
string
autoTestCmd = paramPartTokens2[2];
if (autoTestCmd == "exit")
{
printf
("Detected auto test command [%s], will exit after game.\n",
autoTestCmd.c_str ());
AutoTest::setWantExitGameWhenDone (true);
}
else
{
printf
("WARNING: Detected and UNKNOWN auto test command [%s].\n",
autoTestCmd.c_str ());
}
}
if (paramPartTokens2.size () >= 2
&& paramPartTokens2[1].length () > 0)
{
string
newGameSettingsFileToLoad = paramPartTokens2[1];
printf ("About to auto test using game settings file [%s]\n",
newGameSettingsFileToLoad.c_str ());
AutoTest::setLoadGameSettingsFile (newGameSettingsFileToLoad);
}
}
}
Renderer & renderer = Renderer::getInstance ();
lang.loadGameStrings (language, false, true);
if (lang.hasString ("FONT_HEIGHT_TEXT"))
{
::Shared::Graphics::Font::langHeightText =
config.
getString ("FONT_HEIGHT_TEXT",::Shared::Graphics::Font::
langHeightText.c_str ());
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_FONT_BASESIZE])
== true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_FONT_BASESIZE]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_FONT_BASESIZE]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
newfontBaseSize = paramPartTokens[1];
printf ("Forcing font base size[%s]\n", newfontBaseSize.c_str ());
::Shared::Graphics::Font::baseSize = strToInt (newfontBaseSize);
}
else
{
printf
("\nInvalid missing font base size specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",
__FILE__, __FUNCTION__,
__LINE__,::Shared::Graphics::Font::
charCount,::Shared::Graphics::Font::
fontTypeName.
c_str (),::Shared::Platform::
PlatformContextGl::charSet,::Shared::
Graphics::Font::fontIsMultibyte,::Shared::
Graphics::Font::fontIsRightToLeft);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf
("Using Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",::
Shared::Graphics::Font::charCount,::Shared::Graphics::Font::
fontTypeName.
c_str (),::Shared::Platform::PlatformContextGl::charSet,::
Shared::Graphics::Font::fontIsMultibyte,::Shared::Graphics::
Font::fontIsRightToLeft);
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_FONT]) ==
true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_FONT]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_USE_FONT]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
newfont = paramPartTokens[1];
Properties::applyTagsToValue (newfont);
printf ("Forcing font [%s]\n", newfont.c_str ());
#if defined(WIN32)
string
newEnvValue = "MEGAGLEST_FONT=" + newfont;
_putenv (newEnvValue.c_str ());
#else
setenv ("MEGAGLEST_FONT", newfont.c_str (), 1);
#endif
}
else
{
printf
("\nInvalid missing font specified on commandline [%s] value [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
return 1;
}
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true)
{
return handleCreateDataArchivesCommand (argc, argv);
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SHOW_MAP_CRC])
== true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) == true)
{
return handleShowCRCValuesCommand (argc, argv);
}
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LIST_MAPS]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) ==
true)
{
return handleListDataCommand (argc, argv);
}
program = new Program ();
mainProgram = program;
renderer.setProgram (program);
if (SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder).
enabled == true)
{
renderer.setAllowRenderUnitTitles (SystemFlags::getSystemSettingType
(SystemFlags::debugPathFinder).
enabled);
SystemFlags::OutputDebug (SystemFlags::debugPathFinder,
"In [%s::%s Line: %d] renderer.setAllowRenderUnitTitles = %d\n",
__FILE__, __FUNCTION__, __LINE__,
SystemFlags::
getSystemSettingType (SystemFlags::
debugPathFinder).
enabled);
}
renderer.setAllowRenderUnitTitles (true);
string
screenShotsPath = userData + GameConstants::folder_path_screenshots;
if (isdir (screenShotsPath.c_str ()) == false)
{
createDirectoryPaths (screenShotsPath);
}
// Cache Player textures - START
string
data_path =
getGameReadWritePath (GameConstants::path_data_CacheLookupKey);
std::map < int,
Texture2D * >&
crcPlayerTextureCache =
CacheManager::getCachedItem < std::map < int,
Texture2D * >>(GameConstants::playerTextureCacheLookupKey);
for (int index = 0; index < GameConstants::maxPlayers; ++index)
{
string
playerTexture =
getGameCustomCoreDataPath (data_path,
"data/core/faction_textures/faction" +
intToStr (index) + ".tga");
if (fileExists (playerTexture) == true)
{
Texture2D *
texture = Renderer::getInstance ().newTexture2D (rsGlobal);
if (texture)
{
texture->load (playerTexture);
}
crcPlayerTextureCache[index] = texture;
}
else
{
crcPlayerTextureCache[index] = NULL;
}
}
// Cache Player textures - END
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
mainWindow = new MainWindow (program);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
GameSettings
startupGameSettings;
//parse command line
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SERVER]) ==
true)
{
program->initServer (mainWindow, false, true);
gameInitialized = true;
}
else
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true)
{
program->initServer (mainWindow, false, true, true);
gameInitialized = true;
}
else
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true)
{
program->initServer (mainWindow, true, false);
gameInitialized = true;
}
else
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME])) ==
true)
{
string
fileName = "";
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS
[GAME_ARG_AUTOSTART_LAST_SAVED_GAME]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex >= 0)
{
string
loadfileName = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (loadfileName, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
fileName = paramPartTokens[1];
if (fileExists (fileName) == false)
{
// Save the file now
string
saveGameFile = "saved/" + fileName;
if (getGameReadWritePath
(GameConstants::path_logs_CacheLookupKey) != "")
{
saveGameFile =
getGameReadWritePath
(GameConstants::path_logs_CacheLookupKey) + saveGameFile;
}
else
{
saveGameFile = userData + saveGameFile;
}
if (fileExists (saveGameFile) == true)
{
fileName = saveGameFile;
}
}
if (fileExists (fileName) == false)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096,
"File specified for loading a saved game cannot be found: [%s]",
fileName.c_str ());
printf
("\n\n======================================================================================\n%s\n======================================================================================\n\n\n",
szBuf);
throw
megaglest_runtime_error (szBuf);
}
}
}
program->initSavedGame (mainWindow, false, fileName);
gameInitialized = true;
}
else
if (hasCommandArgument
(argc, argv, string (GAME_ARGS[GAME_ARG_PREVIEW_MAP])) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_PREVIEW_MAP]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_PREVIEW_MAP]),
&foundParamIndIndex);
}
string
mapName = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (mapName, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
vector < string > paramPartTokens2;
string
tileset = "forest";
Tokenize (paramPartTokens[1], paramPartTokens2, ",");
if (paramPartTokens2.size () >= 2
&& paramPartTokens2[1].length () > 0)
{
tileset = paramPartTokens2[1];
}
string
autoloadMapName = paramPartTokens2[0];
GameSettings *
gameSettings = &startupGameSettings;
gameSettings->setMap (autoloadMapName);
gameSettings->setTileset (tileset);
gameSettings->setTech ("megapack");
gameSettings->setDefaultUnits (false);
gameSettings->setDefaultResources (false);
gameSettings->setDefaultVictoryConditions (true);
gameSettings->setFogOfWar (false);
gameSettings->setAllowObservers (true);
gameSettings->setPathFinderType (pfBasic);
for (int i = 0; i < GameConstants::maxPlayers; ++i)
{
ControlType
ct = ctClosed;
gameSettings->setNetworkPlayerStatuses (i, npst_None);
gameSettings->setFactionControl (i, ct);
gameSettings->setStartLocationIndex (i, i);
gameSettings->setResourceMultiplierIndex (i, 10);
gameSettings->setNetworkPlayerName (i,
GameConstants::
NETWORK_SLOT_CLOSED_SLOTNAME);
}
ControlType
ct = ctHuman;
gameSettings->setNetworkPlayerStatuses (0, npst_None);
gameSettings->setFactionControl (0, ct);
gameSettings->setFactionTypeName (0,
formatString
(GameConstants::
OBSERVER_SLOTNAME));
gameSettings->setTeam (0,
GameConstants::maxPlayers + fpt_Observer -
1);
gameSettings->setStartLocationIndex (0, 0);
gameSettings->setNetworkPlayerName (0,
GameConstants::
OBSERVER_SLOTNAME);
gameSettings->setFactionCount (1);
Config & config = Config::getInstance ();
gameSettings->setEnableServerControlledAI (config.getBool
("ServerControlledAI",
"true"));
gameSettings->setNetworkFramePeriod (config.getInt
("NetworkSendFrameCount",
"20"));
program->initServer (mainWindow, gameSettings);
gameInitialized = true;
}
else
{
printf
("\nInvalid map name specified on commandline [%s] map [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], foundInvalidArgs);
delete
mainWindow;
mainWindow = NULL;
return 1;
}
}
else
if (hasCommandArgument
(argc, argv, string (GAME_ARGS[GAME_ARG_CONNECT])) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_CONNECT]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_CONNECT]),
&foundParamIndIndex);
}
string
serverToConnectTo = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (serverToConnectTo, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
autoConnectServer = paramPartTokens[1];
int
port = config.getInt ("PortServer",
intToStr (GameConstants::
serverPort).c_str ());
vector < string > paramPartTokens2;
Tokenize (autoConnectServer, paramPartTokens2, ":");
autoConnectServer = paramPartTokens2[0];
if (paramPartTokens2.size () >= 2
&& paramPartTokens2[1].length () > 0)
{
port = strToInt (paramPartTokens2[1]);
}
printf ("Connecting to host [%s] using port: %d\n",
autoConnectServer.c_str (), port);
if (autoConnectServer == "auto-connect")
{
program->initClientAutoFindHost (mainWindow);
}
else
{
program->initClient (mainWindow, autoConnectServer, port);
}
gameInitialized = true;
}
else
{
printf
("\nInvalid host specified on commandline [%s] host [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], foundInvalidArgs);
delete
mainWindow;
mainWindow = NULL;
return 1;
}
}
else
if (hasCommandArgument
(argc, argv, string (GAME_ARGS[GAME_ARG_CLIENT])) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_CLIENT]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_CLIENT]),
&foundParamIndIndex);
}
string
serverToConnectTo = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (serverToConnectTo, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
autoConnectServer = paramPartTokens[1];
if (autoConnectServer == "auto-connect")
{
program->initClientAutoFindHost (mainWindow);
}
else
{
program->initClient (mainWindow, autoConnectServer);
}
gameInitialized = true;
}
else
{
printf
("\nInvalid host specified on commandline [%s] host [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], foundInvalidArgs);
delete
mainWindow;
mainWindow = NULL;
return 1;
}
}
else
if (hasCommandArgument
(argc, argv, string (GAME_ARGS[GAME_ARG_LOADSCENARIO])) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LOADSCENARIO]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_LOADSCENARIO]),
&foundParamIndIndex);
}
string
scenarioName = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (scenarioName, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
autoloadScenarioName = paramPartTokens[1];
program->initScenario (mainWindow, autoloadScenarioName);
gameInitialized = true;
}
else
{
printf
("\nInvalid scenario name specified on commandline [%s] scenario [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], foundInvalidArgs);
delete
mainWindow;
mainWindow = NULL;
return 1;
}
}
else
{
program->initNormal (mainWindow);
}
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d] OpenGL Info:\n%s\n",
__FILE__, __FUNCTION__, __LINE__,
renderer.getGlInfo ().c_str ());
if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO])
== true)
{
printf ("%s", renderer.getGlInfo ().c_str ());
printf ("%s", renderer.getGlMoreInfo ().c_str ());
delete
mainWindow;
mainWindow = NULL;
return 0;
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_CONVERT_MODELS]) == true)
{
int
foundParamIndIndex = -1;
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_CONVERT_MODELS]) +
string ("="), &foundParamIndIndex);
if (foundParamIndIndex < 0)
{
hasCommandArgument (argc, argv,
string (GAME_ARGS[GAME_ARG_CONVERT_MODELS]),
&foundParamIndIndex);
}
string
paramValue = argv[foundParamIndIndex];
vector < string > paramPartTokens;
Tokenize (paramValue, paramPartTokens, "=");
if (paramPartTokens.size () >= 2
&& paramPartTokens[1].length () > 0)
{
string
modelFile = paramPartTokens[1];
printf ("About to convert model(s) [%s]\n", modelFile.c_str ());
string
textureFormat = "";
if (paramPartTokens.size () >= 3
&& paramPartTokens[1].length () > 0)
{
textureFormat = paramPartTokens[2];
printf ("About to convert using texture format [%s]\n",
textureFormat.c_str ());
}
bool
keepsmallest = false;
if (paramPartTokens.size () >= 4
&& paramPartTokens[1].length () > 0)
{
keepsmallest = (paramPartTokens[3] == "keepsmallest");
printf ("About to convert using keepsmallest = %d\n",
keepsmallest);
}
showCursor (true);
const
Metrics &
metrics = Metrics::getInstance ();
renderer.clearBuffers ();
renderer.clearZBuffer ();
renderer.reset2d ();
if (CoreData::getInstance ().getMenuFontBig3D () != NULL)
{
renderer.renderText3D ("Please wait, converting models...",
CoreData::getInstance ().
getMenuFontBig3D (), Vec3f (1.f, 1.f,
0.f),
(metrics.getScreenW () / 2) - 400,
(metrics.getScreenH () / 2), true);
}
else
{
renderer.renderText ("Please wait, converting models...",
CoreData::getInstance ().getMenuFontBig (),
Vec3f (1.f, 1.f, 0.f),
(metrics.getScreenW () / 2) - 400,
(metrics.getScreenH () / 2), true);
}
renderer.swapBuffers ();
std::vector < string > models;
if (isdir (modelFile.c_str ()) == true)
{
models =
getFolderTreeContentsListRecursively (modelFile, ".g3d");
}
else
{
models.push_back (modelFile);
}
sleep (0);
::Shared::Platform::Window::handleEvent ();
SDL_PumpEvents ();
int
result = 0;
char
szTextBuf[8096] = "";
for (unsigned int i = 0; i < models.size (); ++i)
{
string & file = models[i];
renderer.clearBuffers ();
renderer.clearZBuffer ();
renderer.reset2d ();
snprintf (szTextBuf, 8096,
"Please wait, converting models [%u of "
MG_SIZE_T_SPECIFIER "] ...", i, models.size ());
if (CoreData::getInstance ().getMenuFontBig3D () != NULL)
{
renderer.renderText3D (szTextBuf,
CoreData::getInstance ().
getMenuFontBig3D (), Vec3f (1.f, 1.f,
0.f),
(metrics.getScreenW () / 2) - 400,
(metrics.getScreenH () / 2), true);
}
else
{
renderer.renderText (szTextBuf,
CoreData::getInstance ().
getMenuFontBig (), Vec3f (1.f, 1.f, 0.f),
(metrics.getScreenW () / 2) - 400,
(metrics.getScreenH () / 2), true);
}
renderer.swapBuffers ();
sleep (0);
::Shared::Platform::Window::handleEvent ();
SDL_PumpEvents ();
try
{
printf ("About to load model [%s] [%u of " MG_SIZE_T_SPECIFIER
"]\n", file.c_str (), i, models.size ());
Model *
model = renderer.newModel (rsGlobal, file);
printf ("About to save converted model [%s]\n",
file.c_str ());
model->save (file, textureFormat, keepsmallest);
Renderer::getInstance ().endModel (rsGlobal, model);
}
catch (const exception & ex)
{
result = 1;
printf ("ERROR loading model [%s] message [%s]\n",
file.c_str (), ex.what ());
}
}
delete
mainWindow;
mainWindow = NULL;
return result;
}
else
{
printf
("\nInvalid model specified on commandline [%s] texture [%s]\n\n",
argv[foundParamIndIndex],
(paramPartTokens.size () >=
2 ? paramPartTokens[1].c_str () : NULL));
printParameterHelp (argv[0], foundInvalidArgs);
delete
mainWindow;
mainWindow = NULL;
return 1;
}
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) ==
true
|| hasCommandArgument (argc, argv,
GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) ==
true)
{
runTechValidationReport (argc, argv);
delete
mainWindow;
mainWindow = NULL;
return 0;
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true)
{
runTechTranslationExtraction (argc, argv);
delete
mainWindow;
mainWindow = NULL;
return 0;
}
if (hasCommandArgument
(argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true)
{
runTilesetValidationReport (argc, argv);
delete
mainWindow;
mainWindow = NULL;
return 0;
}
gameInitialized = true;
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
CheckForDuplicateData ();
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
//throw "BLAH!";
// START Test out SIGSEGV error handling
//int *foo = (int*)-1; // make a bad pointer
//printf("%d\n", *foo); // causes segfault
// END
bool
startCRCPrecacheThread =
config.getBool ("PreCacheCRCThread", "true");
//printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d] precache thread enabled = %d\n",
__FILE__, __FUNCTION__, __LINE__, startCRCPrecacheThread);
if (startCRCPrecacheThread == true
&& GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
static
string
mutexOwnerId =
string (extractFileFromDirectoryPath (__FILE__).c_str ()) +
string ("_") + intToStr (__LINE__);
vector < string > techDataPaths =
config.getPathListForType (ptTechs);
FileCRCPreCacheThread::setPreCacheThreadCacheLookupKey
(GameConstants::preCacheThreadCacheLookupKey);
FileCRCPreCacheThread *&
preCacheCRCThreadPtr =
CacheManager::getCachedItem <
FileCRCPreCacheThread *
>(GameConstants::preCacheThreadCacheLookupKey);
if (preCacheCRCThreadPtr == NULL)
{
preCacheCRCThreadPtr = new FileCRCPreCacheThread ();
}
preCacheThread = preCacheCRCThreadPtr;
preCacheThread->setUniqueID (mutexOwnerId);
preCacheThread->setTechDataPaths (techDataPaths);
//preCacheThread->setFileCRCPreCacheThreadCallbackInterface(&preCacheThreadGame);
preCacheThread->start ();
}
auto_ptr < NavtiveLanguageNameListCacheGenerator > lngCacheGen;
auto_ptr < SimpleTaskThread > languageCacheGen;
bool
startNativeLanguageNamesPrecacheThread =
config.getBool ("PreCacheNativeLanguageNamesThread", "true");
if (startNativeLanguageNamesPrecacheThread == true
&& GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
lngCacheGen.reset (new NavtiveLanguageNameListCacheGenerator ());
languageCacheGen.reset (new
SimpleTaskThread (lngCacheGen.get (), 1));
languageCacheGen->start ();
}
// test
//Shared::Platform::MessageBox(NULL,"Mark's test.","Test",0);
//throw megaglest_runtime_error("test!");
//ExceptionHandler::DisplayMessage("test!", false);
// Check for commands being input from stdin
string
command = "";
#ifndef WIN32
pollfd
cinfd[1];
#else
HANDLE
h = 0;
#endif
if (disableheadless_console == false)
{
#ifndef WIN32
// Theoretically this should always be 0, but one fileno call isn't going to hurt, and if
// we try to run somewhere that stdin isn't fd 0 then it will still just work
cinfd[0].fd = fileno (stdin);
cinfd[0].events = POLLIN;
#else
h = GetStdHandle (STD_INPUT_HANDLE);
//DWORD dwMode;
//GetConsoleMode(h, &dwMode);
//SetConsoleMode(h, dwMode & ~ENABLE_MOUSE_INPUT);
FlushConsoleInputBuffer (h);
#endif
}
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true)
{
printf ("Headless server is now running...\n");
printf ("To shutdown type: quit\n");
printf ("All commands require you to press ENTER\n");
}
//throw megaglest_runtime_error("Test!");
//printf("About to throw an exception...\n");
//throw 123;
//main loop
while (program->isShutdownApplicationEnabled () == false
&&::Shared::Platform::Window::handleEvent ())
{
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true)
{
if (disableheadless_console == false)
{
#ifndef WIN32
int
pollresult = poll (cinfd, 1, 0);
int
pollerror = errno;
if (pollresult)
#else
// This is problematic because input on Windows is not line-buffered so this will return
// even if getline may block. I haven't found a good way to fix it, so for the moment
// I just strongly suggest only running the server from the Python frontend, which does
// line buffer input. This does work okay as long as the user doesn't enter characters
// without pressing enter, and then try to end the server another way (say a remote
// console command), in which case we'll still be waiting for the stdin EOL and hang.
DWORD
saveMode;
GetConsoleMode (h, &saveMode);
DWORD
dwMode = saveMode;
dwMode &= ~ENABLE_MOUSE_INPUT;
dwMode &= ~ENABLE_WINDOW_INPUT;
SetConsoleMode (h, dwMode);
bool
gotData = (WaitForSingleObject (h, 0) == WAIT_OBJECT_0);
SetConsoleMode (h, saveMode);
if (gotData == true)
#endif
{
#ifdef WIN32
bool
skip = true;
DWORD
nNumberOfCharsToRead = 1024;
DWORD
nRead = 0;
INPUT_RECORD
irInRec[1025];
PeekConsoleInput (h, &irInRec[0], nNumberOfCharsToRead,
&nRead);
for (int i = 0; i < nRead; ++i)
{
INPUT_RECORD & inr = irInRec[i];
//printf("inr.EventType = %d\n",inr.EventType);
if (inr.EventType == KEY_EVENT)
{
if (inr.Event.KeyEvent.bKeyDown)
{
char
cHoldKey = inr.Event.KeyEvent.uChar.AsciiChar;
if (cHoldKey == '\r')
{
skip = false;
break;
}
}
}
}
#else
bool
skip = false;
#endif
if (skip == false)
{
getline (cin, command);
cin.clear ();
printf ("server command [%s]\n", command.c_str ());
if (command == "quit")
{
break;
}
#ifndef WIN32
if (cinfd[0].revents & POLLNVAL)
{
printf ("invalid file descriptor\n");
}
if (cinfd[0].revents & POLLERR)
{
printf ("error in file descriptor\n");
}
if (cinfd[0].revents & POLLHUP)
{
printf ("hang up in file descriptor\n");
}
if (pollresult < 0)
{
printf ("pollresult = %d errno = %d [%s]\n", pollresult,
pollerror, strerror (pollerror));
cinfd[0].fd = fileno (stdin);
cinfd[0].events = POLLIN;
}
#endif
}
}
}
//printf("looping\n");
}
program->loop ();
// Because OpenGL really doesn't do multi-threading well
// if(difftime(time(NULL),lastTextureLoadEvent) >= 3) {
// lastTextureLoadEvent = time(NULL);
// vector<Texture2D *> textureList = preCacheThread->getPendingTextureList(1);
// for(unsigned int i = 0; i < textureList.size(); ++i) {
// Texture2D * factionLogo = textureList[i];
// if(factionLogo != NULL) {
// printf("\n\n\n\n|||||||||||||||||||||||||| Load texture [%s]\n",factionLogo->getPath().c_str());
// //Renderer::findTexture(factionLogo);
// renderer.initTexture(rsGlobal,factionLogo);
// }
// }
// }
}
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true)
{
printf ("\nHeadless server is about to quit...\n");
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf
("In [%s::%s Line: %d] starting normal application shutdown\n",
__FILE__, __FUNCTION__, __LINE__);
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
soundThreadManager = program->getSoundThreadManager (true);
if (soundThreadManager)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start ();
}
}
cleanupCRCThread ();
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
showCursor (true);
//showWindowCursorState = true;
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
}
catch (const megaglest_runtime_error & e)
{
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
soundThreadManager =
(program != NULL ? program->getSoundThreadManager (true) : NULL);
if (soundThreadManager)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start ();
}
if (program != NULL &&
program->getTryingRendererInit () == true &&
program->getRendererInitOk () == false)
{
message (e.what (),
GlobalStaticFlags::getIsNonGraphicalModeEnabled (),
tempDataLocation);
}
}
if (program == NULL || program->getTryingRendererInit () == false ||
(program->getTryingRendererInit () == true &&
program->getRendererInitOk () == true))
{
ExceptionHandler::handleRuntimeError (e);
}
}
catch (const exception & e)
{
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
soundThreadManager =
(program != NULL ? program->getSoundThreadManager (true) : NULL);
if (soundThreadManager)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start ();
}
}
ExceptionHandler::handleRuntimeError (e.what (), true);
}
catch (const char *e)
{
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
soundThreadManager =
(program != NULL ? program->getSoundThreadManager (true) : NULL);
if (soundThreadManager)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start ();
}
}
ExceptionHandler::handleRuntimeError (e, true);
}
catch (const string & ex)
{
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
soundThreadManager =
(program != NULL ? program->getSoundThreadManager (true) : NULL);
if (soundThreadManager)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start ();
}
}
ExceptionHandler::handleRuntimeError (ex.c_str (), true);
}
#if !defined(HAVE_GOOGLE_BREAKPAD)
catch ( ...)
{
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
soundThreadManager =
(program != NULL ? program->getSoundThreadManager (true) : NULL);
if (soundThreadManager)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start ();
}
}
ExceptionHandler::handleRuntimeError ("Unknown error [main]!", true);
}
#endif
cleanupCRCThread ();
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
delete
mainWindow;
mainWindow = NULL;
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
GraphicComponent::clearRegisteredComponents ();
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
if (soundThreadManager)
{
SoundRenderer & soundRenderer = SoundRenderer::getInstance ();
if (Config::getInstance ().getString ("FactorySound", "") != "None" &&
soundRenderer.isVolumeTurnedOff () == false)
{
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__,
__LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
for (;
chronoshutdownFadeSound.getMillis () <=
shutdownFadeSoundMilliseconds;)
{
sleep (10);
}
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
BaseThread::shutdownAndWait (soundThreadManager);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
delete
soundThreadManager;
soundThreadManager = NULL;
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
SystemFlags::OutputDebug (SystemFlags::debugSystem,
"In [%s::%s Line: %d]\n", __FILE__,
__FUNCTION__, __LINE__);
return 0;
}
#if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD)
void
handleSIGSEGV (int sig)
{
char
szBuf[8096] = "";
snprintf (szBuf, 8096,
"In [%s::%s Line: %d] Error detected: signal %d:\n", __FILE__,
__FUNCTION__, __LINE__, sig);
printf ("%s", szBuf);
//abort();
ExceptionHandler::handleRuntimeError (szBuf, true);
}
#endif
#if defined(HAVE_GOOGLE_BREAKPAD)
# if defined(WIN32)
// Callback when minidump written.
static
bool
MinidumpCallback (const wchar_t * dump_path,
const wchar_t * minidump_id,
void *context,
EXCEPTION_POINTERS * exinfo,
MDRawAssertionInfo * assertion, bool succeeded)
{
printf ("\n======= In MinidumpCallback...\n");
wprintf
(L"\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s.dmp\nSucceeded: %d\n",
(dump_path != NULL ? dump_path : L"(null)"),
(minidump_id != NULL ? minidump_id : L"(null)"), succeeded);
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
wchar_t
szBuf[8096];
int
bufBytes = _snwprintf (szBuf, 8096,
L"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s.dmp",
dump_path, minidump_id);
szBuf[bufBytes] = '\0';
MessageBox (NULL, szBuf, L"Unhandled error", MB_OK | MB_SYSTEMMODAL);
}
return succeeded;
}
# else
// Callback when minidump written.
static
bool
MinidumpCallback (const google_breakpad::MinidumpDescriptor & descriptor,
void *context, bool succeeded)
{
printf ("\n======= In MinidumpCallback...\n");
printf
("\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s\nSucceeded: %d\n",
descriptor.directory ().c_str (), descriptor.path (), succeeded);
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false)
{
char
szBuf[8096];
snprintf (szBuf, 8096,
"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s",
descriptor.directory ().c_str (), descriptor.path ());
message (szBuf, GlobalStaticFlags::getIsNonGraphicalModeEnabled (),
tempDataLocation);
}
return succeeded;
}
# endif
#endif
#ifdef WIN32
void
EnableCrashingOnCrashes ()
{
typedef
BOOL (WINAPI * tGetPolicy) (LPDWORD lpFlags);
typedef
BOOL (WINAPI * tSetPolicy) (DWORD dwFlags);
const
DWORD
EXCEPTION_SWALLOWING = 0x1;
HMODULE
kernel32 = LoadLibraryA ("kernel32.dll");
if (kernel32 != 0)
{
tGetPolicy
pGetPolicy =
(tGetPolicy) GetProcAddress (kernel32,
"GetProcessUserModeExceptionPolicy");
tSetPolicy
pSetPolicy =
(tSetPolicy) GetProcAddress (kernel32,
"SetProcessUserModeExceptionPolicy");
if (pGetPolicy && pSetPolicy)
{
DWORD
dwFlags;
if (pGetPolicy (&dwFlags))
{
// Turn off the filter
pSetPolicy (dwFlags & ~EXCEPTION_SWALLOWING);
}
}
}
}
#endif
int
glestMainSEHWrapper (int argc, char **argv)
{
int
result = 0;
#ifdef WIN32_STACK_TRACE
//printf("Hooking up WIN32_STACK_TRACE...\n");
__try
{
#endif
//application_binary= executable_path(argv[0],true);
//printf("\n\nargv0 [%s] application_binary [%s]\n\n",argv[0],application_binary.c_str());
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
if (hasCommandArgument
(argc, argv,
string (GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER])) == false)
{
signal (SIGSEGV, handleSIGSEGV);
}
// http://developerweb.net/viewtopic.php?id=3013
//signal(SIGPIPE, SIG_IGN);
#endif
initSpecialStrings ();
IRCThread::setGlobalCacheContainerName
(GameConstants::ircClientCacheLookupKey);
result = glestMain (argc, argv);
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
cleanupProcessObjects ();
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
#ifdef WIN32
//delete winSockManager;
//winSockManager = NULL;
#endif
if (sdl_quitCalled == false)
{
sdl_quitCalled = true;
SDL_Quit ();
}
if (SystemFlags::VERBOSE_MODE_ENABLED)
printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
#ifdef WIN32_STACK_TRACE
}
__except (stackdumper (0, GetExceptionInformation (), true),
EXCEPTION_CONTINUE_SEARCH)
{
return 0;
}
#endif
return result;
}
int
glestMainWrapper (int argc, char **argv)
{
//setlocale(LC_ALL, "zh_TW.UTF-8");
//setlocale(LC_ALL, "");
#ifdef WIN32
EnableCrashingOnCrashes ();
#endif
#if defined(HAVE_GOOGLE_BREAKPAD)
/*
handler = new ExceptionHandler(const wstring& dump_path,
FilterCallback filter,
MinidumpCallback callback,
void* callback_context,
int handler_types,
MINIDUMP_TYPE dump_type,
const wchar_t* pipe_name,
const CustomClientInfo* custom_info);
*/
// See this link about swallowed exceptions in Win 7: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/
//DWORD dwFlags;
//if (GetProcessUserModeExceptionPolicy(&dwFlags)) {
// SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); // turn off bit 1
//}
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler...\n");
# if defined(WIN32)
wstring
dumpfilepath = utf8_decode (".");
//google_breakpad::ExceptionHandler handler(dumpfilepath, NULL, MinidumpCallback, NULL, true);
errorHandlerPtr.reset (new
google_breakpad::ExceptionHandler (dumpfilepath,
NULL,
MinidumpCallback,
NULL,
google_breakpad::ExceptionHandler::
HANDLER_ALL));
# else
google_breakpad::MinidumpDescriptor descriptor (".");
errorHandlerPtr.reset (new
google_breakpad::ExceptionHandler (descriptor,
NULL,
MinidumpCallback,
NULL, true,
-1));
# endif
// ExceptionHandler(const wstring& dump_path,
// FilterCallback filter,
// MinidumpCallback callback,
// void* callback_context,
// int handler_types);
#endif
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
//#ifdef DEBUG
//printf("MTRACE will be called...\n");
//mtrace ();
//#endif
#endif
#ifdef WIN32
//winSockManager = new SocketManager();
SocketManager
winSockManager;
#endif
bool
isSteamMode =
hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_STEAM]);
if (isSteamMode == true)
{
if (!STEAMSHIM_init ())
{
printf ("\nSteam API init failed, terminating.\n");
return 42;
}
}
int
result = glestMainSEHWrapper (argc, argv);
if (isSteamMode == true)
{
printf ("\nSteam API deinit.\n");
STEAMSHIM_deinit ();
}
return result;
}
}
} //end namespace
MAIN_FUNCTION (Glest::Game::glestMainWrapper)