1 // ==============================================================
2 //	This file is part of Glest (www.glest.org)
3 //
4 //	Copyright (C) 2001-2008 Martiño Figueroa
5 //
6 //	You can redistribute this code and/or modify it under
7 //	the terms of the GNU General Public License as published
8 //	by the Free Software Foundation; either version 2 of the
9 //	License, or (at your option) any later version
10 // ==============================================================
11 
12 #include "game_util.h"
13 
14 #include "util.h"
15 #include "lang.h"
16 #include "game_constants.h"
17 #include "config.h"
18 #include <stdlib.h>
19 #include "platform_util.h"
20 #include "conversion.h"
21 #include "cache_manager.h"
22 #include "errno.h"
23 #include "leak_dumper.h"
24 
25 using namespace Shared::Util;
26 using namespace Shared::Platform;
27 
28 namespace Glest { namespace Game {
29 
30 const char *mailString				= " http://bugs.megaglest.org";
31 
32 // !! Use minor versions !!  Only major and minor version control compatibility!
33 // typical version numbers look like this: v3.13-beta1.0   v3.12-dev   v3.12.1
34 // don't forget to update file: source/version.txt
35 const string glestVersionString 	= "v3.13.0";
36 const string lastCompatibleSaveGameVersionString 	= "v3.11.1";
37 
38 #if defined(GITVERSIONHEADER)
39 	#include "gitversion.h"
40 #endif
41 #if defined(GITVERSION) || defined(GITVERSIONHEADER)
42 	const string GIT_RawRev		= string(GITVERSION);
43 #else
44 	const string GIT_RawRev		= "$5604.3a5d459$";
45 #endif
46 const string GIT_Rev 			= string("Rev: ") + string(GIT_RawRev);
47 
getRAWGITRevisionString()48 string getRAWGITRevisionString() {
49 	return GIT_RawRev;
50 }
getCrashDumpFileName()51 string getCrashDumpFileName(){
52 	return "megaglest" + glestVersionString + ".dmp";
53 }
54 
getPlatformTypeNameString()55 string getPlatformTypeNameString() {
56 	static string platform;
57 	if(platform == "") {
58 #if defined(WIN32)
59 
60 	#if defined(__MINGW32__)
61 	platform = "W-Ming32";
62 	#else
63 	platform = "Windows";
64 	#endif
65 
66 #elif defined(__DragonFly__)
67 	platform = "FreeBSD";
68 #elif defined(__NetBSD__)
69 	platform = "NetBSD";
70 #elif defined(__OpenBSD__)
71 	platform = "OpenBSD";
72 
73 #elif defined(__APPLE__)
74 	platform = "MacOS";
75 #elif defined(_AIX)
76 	platform = "AIX";
77 #elif defined(__ANDROID__)
78 	platform = "Android";
79 #elif defined(__BEOS__)
80 	platform = "BEOS";
81 #elif defined(__gnu_linux__)
82 	platform = "Linux";
83 #elif defined(__sun)
84 	platform = "Solaris";
85 
86 #elif defined(__GNUC__)
87 
88 	#if defined(__MINGW32__)
89 	platform = "L-Ming32";
90 	#else
91 	platform = "GNU";
92 	#endif
93 
94 #else
95 	platform = "???";
96 #endif
97 	}
98 	return platform;
99 }
100 
getPlatformArchTypeNameString()101 string getPlatformArchTypeNameString() {
102 	static string platform;
103 	if(platform == "") {
104 
105 #if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64)
106 	platform = "-X64";
107 #elif defined(_M_ALPHA) || defined(__alpha__)
108 	platform = "-ALPHA";
109 #elif defined(_M_IA64) || defined(__ia64__)
110 	platform = "-IA64";
111 #elif defined(_M_MRX000) || defined(__mips__)
112 	platform = "-MIPS";
113 #elif defined(_M_PPC) || defined(__powerpc__)
114 	platform = "-POWERPC";
115 #elif defined(__sparc__)
116 	platform = "-SPARC";
117 #elif defined(_M_ARM_FP) || defined(__arm__) || defined(_M_ARM)
118 	platform = "-ARM";
119 
120 #endif
121 	}
122 	return platform;
123 }
124 
getPlatformNameString()125 string getPlatformNameString() {
126 	static string platform;
127 	if(platform == "") {
128 		platform = getPlatformTypeNameString() + getPlatformArchTypeNameString();
129 	}
130 	return platform;
131 }
132 
getGITRevisionString()133 string getGITRevisionString() {
134 	return GIT_Rev;
135 }
136 
getCompilerNameString()137 string getCompilerNameString() {
138 	static string version = "";
139 	if(version == "") {
140 #if defined(WIN32) && defined(_MSC_VER)
141 	version = "VC++: " + intToStr(_MSC_VER);
142 
143 
144 #elif defined(__clang__)
145 	version = "Clang: " + intToStr(__clang_major__) + "." + intToStr(__clang_minor__) + "." + intToStr(__clang_patchlevel__);
146 
147 #elif defined(__GNUC__)
148 	#if defined(__GNUC__)
149 	# if defined(__GNUC_PATCHLEVEL__)
150 	#  define __GNUC_VERSION__ (__GNUC__ * 10000 \
151 								+ __GNUC_MINOR__ * 100 \
152 								+ __GNUC_PATCHLEVEL__)
153 	# else
154 	#  define __GNUC_VERSION__ (__GNUC__ * 10000 \
155 								+ __GNUC_MINOR__ * 100)
156 	# endif
157 	#endif
158 	version = "GNUC";
159 
160 	#if defined(__MINGW32__)
161 	version += "-MINGW";
162 	#endif
163 
164 	version += ": " + intToStr(__GNUC_VERSION__);
165 
166 #else
167 	version = "???";
168 #endif
169 
170 #if defined(DEBUG) || defined(_DEBUG)
171 version += " [DEBUG]";
172 #endif
173 
174 #if defined(_M_X64) || defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64)
175 	version += " [64bit]";
176 #endif
177 	}
178 	return version;
179 }
180 
getNetworkVersionString()181 string getNetworkVersionString() {
182 	static string version = "";
183 	if(version == "") {
184 		version = glestVersionString+"-"+getCompilerNameString()+"-"+getCompileDateTime();
185 	}
186 	return version;
187 }
188 
getNetworkVersionGITString()189 string getNetworkVersionGITString() {
190 	static string version = "";
191 	if(version == "") {
192 		version = glestVersionString + "-" + getGITRevisionString() + "-" + getCompilerNameString();
193 	}
194 	return version;
195 }
196 
getCompileDateTime()197 string getCompileDateTime() {
198 	static string result = "";
199 //	if(result == "") {
200 //		result = string(__DATE__) + " " + string(__TIME__);
201 //	}
202 	return result;
203 }
204 
getNetworkPlatformFreeVersionString()205 string getNetworkPlatformFreeVersionString() {
206 	return glestVersionString;
207 }
208 
getAboutString1(int i)209 string getAboutString1(int i) {
210 	//case 1: return "Built: " + string(__DATE__) + " " + GIT_Rev;
211 	switch(i) {
212 	case 0: return "MegaGlest " + glestVersionString + " (" + "Shared Library " + sharedLibVersionString + ")";
213 	case 1: return GIT_Rev;
214 	case 2: return "Copyright 2001-2010 The Glest Team";
215 	case 3: return "Copyright 2010-2017 The MegaGlest Team";
216 	}
217 	return "";
218 }
219 
getAboutString2(int i)220 string getAboutString2(int i) {
221 	switch(i) {
222 	case 0: return "Web: http://megaglest.org";
223 	case 1: return "Bug reports: " + string(mailString);
224 	case 2: return "IRC: irc://irc.freenode.net/megaglest";
225 	}
226 	return "";
227 }
228 
getTeammateName(int i)229 string getTeammateName(int i) {
230 	switch(i) {
231     case 0: return "Martiño Figueroa";
232 	//case 0: return "Martino Figueroa";
233 	case 1: return "José Luis González";
234 	//case 1: return "Jose Luis Gonzalez";
235 	case 2: return "Tucho Fernández";
236 	//case 2: return "Tucho Fernandez";
237 	case 3: return "José Zanni";
238 	//case 3: return "Jose Zanni";
239 	case 4: return "Félix Menéndez";
240 	//case 4: return "Felix Menendez";
241 	case 5: return "Marcos Caruncho";
242 	case 6: return "Matthias Braun";
243 	case 7: return "Titus Tscharntke";
244 	case 8: return "Mark Vejvoda";
245 	}
246 	return "";
247 }
248 
getTeammateRole(int i)249 string getTeammateRole(int i) {
250 	Lang &lang = Lang::getInstance();
251 
252 	switch(i) {
253 	case 0: return lang.getString("Programming");
254 	case 1: return lang.getString("SoundAndMusic");
255 	case 2: return lang.getString("3dAnd2dArt");
256 	case 3: return lang.getString("2dArtAndWeb");
257 	case 4: return lang.getString("Animation");
258 	case 5: return lang.getString("3dArt");
259 	case 6: return lang.getString("LinuxPort");
260 	case 7: return lang.getString("Megaglest3d2dProgramming");
261 	case 8: return lang.getString("MegaglestProgramming");
262 	}
263 	return "";
264 }
265 
formatString(string str)266 string formatString(string str) {
267 	string outStr = str;
268 
269 	if(!outStr.empty()){
270 		outStr[0]= toupper(outStr[0]);
271 	}
272 
273 	bool afterSeparator= false;
274 	for(int i= 0; i < (int)str.size(); ++i){
275 		if(outStr[i]=='_'){
276 			outStr[i]= ' ';
277 		}
278 		else if(afterSeparator){
279 			outStr[i]= toupper(outStr[i]);
280 			afterSeparator= false;
281 		}
282 		if(outStr[i]=='\n' || outStr[i]=='(' || outStr[i]==' '){
283 			afterSeparator= true;
284 		}
285 	}
286 	return outStr;
287 }
288 
getGameCustomCoreDataPath(string originalBasePath,string uniqueFilePath)289 string getGameCustomCoreDataPath(string originalBasePath, string uniqueFilePath) {
290 	// original file path setup
291     if(originalBasePath != "") {
292     	endPathWithSlash(originalBasePath);
293     }
294     //
295 
296 	// mydata user data override
297 	Config &config = Config::getInstance();
298 	string data_path = config.getString("UserData_Root","");
299     if(data_path != "") {
300     	endPathWithSlash(data_path);
301     }
302     //
303 
304     // if set this is the current active mod
305     string custom_mod_path = config.getCustomRuntimeProperty(Config::ACTIVE_MOD_PROPERTY_NAME);
306     if(custom_mod_path != "") {
307     	endPathWithSlash(custom_mod_path);
308     }
309     //
310 
311     // decide which file to use
312     string result = "";
313 
314     if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for [%s] in\n#1: [%s]\n#2: [%s]\n#3: [%s]\n",uniqueFilePath.c_str(),custom_mod_path.c_str(),data_path.c_str(),originalBasePath.c_str());
315 
316 	if(custom_mod_path != "" &&
317 		(uniqueFilePath == "" || fileExists(custom_mod_path + uniqueFilePath) == true)) {
318 		result = custom_mod_path + uniqueFilePath;
319 	}
320 	else if(data_path != "" &&
321 		(uniqueFilePath == "" || fileExists(data_path + uniqueFilePath) == true)) {
322 		result = data_path + uniqueFilePath;
323 	}
324 	else {
325 		result = originalBasePath + uniqueFilePath;
326 	}
327 
328 	if (SystemFlags::VERBOSE_MODE_ENABLED) printf("result [%s]\n",result.c_str());
329 
330     return result;
331 }
332 
getGameReadWritePath(string lookupKey)333 string getGameReadWritePath(string lookupKey) {
334 	string path = "";
335 
336 	if(lookupKey != "") {
337         std::map<string,string> &pathCache = CacheManager::getCachedItem< std::map<string,string> >(GameConstants::pathCacheLookupKey);
338         std::map<string,string>::const_iterator iterFind = pathCache.find(lookupKey);
339         if(iterFind != pathCache.end()) {
340             path = iterFind->second;
341 
342             if(path != "" && EndsWith(path, "/") == false && EndsWith(path, "\\") == false) {
343                 path += "/";
344             }
345 
346             //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for [%s] files [%s]\n",__FILE__,__FUNCTION__,__LINE__,lookupKey.c_str(),path.c_str());
347         }
348 	}
349 
350     if(path == "") {
351         path = safeCharPtrCopy(getenv("GLESTHOME"),8095);
352         if(path != "" && EndsWith(path, "/") == false && EndsWith(path, "\\") == false) {
353             path += "/";
354         }
355 
356         //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str());
357     }
358 
359     return path;
360 }
361 
initSpecialStrings()362 void initSpecialStrings() {
363 	getCrashDumpFileName();
364 	getPlatformNameString();
365 	getGITRevisionString();
366 	getCompilerNameString();
367 	getNetworkVersionString();
368 	getNetworkVersionGITString();
369 	getNetworkPlatformFreeVersionString();
370 	getCompileDateTime();
371 }
372 
upgradeFilesInTemp()373 bool upgradeFilesInTemp() {
374 	// Get path to temp files
375 	string tempFilePath = "temp/";
376 	if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
377 		tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath;
378 	}
379 	else {
380 		Config &config = Config::getInstance();
381 		string userData = config.getString("UserData_Root","");
382 		if(userData != "") {
383 			endPathWithSlash(userData);
384 		}
385 		tempFilePath = userData + tempFilePath;
386 	}
387 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n",tempFilePath.c_str());
388 
389 	// Move all files into binary folder
390 	bool anyFailures = false;
391 	vector<string> fileList = getFolderTreeContentsListRecursively(tempFilePath, "", false, NULL);
392 	for(unsigned int index = 0; index < fileList.size(); ++index) {
393 		string fileName = fileList[index];
394 		string newFileName = Properties::getApplicationPath() + extractFileFromDirectoryPath(fileName);
395 		bool result = renameFile(fileName,newFileName);
396 		if(result == false) {
397 			printf("FAILED Rename: [%s] to [%s] result = %d errno = %d\n",fileName.c_str(),newFileName.c_str(),result,errno);
398 
399 			anyFailures = true;
400 		}
401 		if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",fileName.c_str(),newFileName.c_str(),result);
402 	}
403 
404 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Successfully updated!\n");
405 
406 	return (fileList.size() > 0 && anyFailures == false);
407 }
408 
409 }}//end namespace
410