1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tools/installer/GamesList.cpp Sun Oct 28 20:15:51 2007 +0000
1.3 @@ -0,0 +1,496 @@
1.4 +#include "GamesList.h"
1.5 +#include "InstallerUtil.h"
1.6 +#include "InstallerMain.h"
1.7 +#include <stdio.h>
1.8 +
1.9 +mod_info_t *g_mod_list = NULL;
1.10 +unsigned int g_mod_count = 0;
1.11 +
1.12 +int IsValidFolder(const TCHAR *path)
1.13 +{
1.14 + DWORD attr;
1.15 + TCHAR gameinfo_file[MAX_PATH];
1.16 +
1.17 + UTIL_PathFormat(gameinfo_file, sizeof(gameinfo_file), _T("%s\\gameinfo.txt"), path);
1.18 +
1.19 + if ((attr = GetFileAttributes(gameinfo_file)) == INVALID_FILE_ATTRIBUTES)
1.20 + {
1.21 + return GAMEINFO_DOES_NOT_EXIST;
1.22 + }
1.23 +
1.24 + if ((attr & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)
1.25 + {
1.26 + return GAMEINFO_IS_READ_ONLY;
1.27 + }
1.28 +
1.29 + if ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
1.30 + {
1.31 + return GAMEINFO_DOES_NOT_EXIST;
1.32 + }
1.33 +
1.34 + return GAMEINFO_IS_USABLE;
1.35 +}
1.36 +
1.37 +void DisplayBadFolderDialog(HWND hDlg, int reason)
1.38 +{
1.39 + TCHAR message_string[255];
1.40 + UINT resource;
1.41 +
1.42 + if (reason == GAMEINFO_DOES_NOT_EXIST)
1.43 + {
1.44 + resource = IDS_NO_GAMEINFO;
1.45 + }
1.46 + else if (reason == GAMEINFO_IS_READ_ONLY)
1.47 + {
1.48 + resource = IDS_READONLY_GAMEINFO;
1.49 + }
1.50 + else
1.51 + {
1.52 + return;
1.53 + }
1.54 +
1.55 + if (LoadString(g_hInstance,
1.56 + resource,
1.57 + message_string,
1.58 + sizeof(message_string) / sizeof(TCHAR)
1.59 + ) == 0)
1.60 + {
1.61 + return;
1.62 + }
1.63 +
1.64 + MessageBox(hDlg,
1.65 + message_string,
1.66 + _T("SourceMod Installer"),
1.67 + MB_OK|MB_ICONWARNING);
1.68 +}
1.69 +
1.70 +void AddModToList(mod_info_t **mod_list,
1.71 + unsigned int *total_mods,
1.72 + const mod_info_t *mod_info)
1.73 +{
1.74 + mod_info_t *mods = *mod_list;
1.75 + unsigned int total = *total_mods;
1.76 +
1.77 + if (mods == NULL)
1.78 + {
1.79 + mods = (mod_info_t *)malloc(sizeof(mod_info_t));
1.80 + }
1.81 + else
1.82 + {
1.83 + mods = (mod_info_t *)realloc(mods, sizeof(mod_info_t) * (total + 1));
1.84 + }
1.85 +
1.86 + memcpy(&mods[total], mod_info, sizeof(mod_info_t));
1.87 + total++;
1.88 +
1.89 + *mod_list = mods;
1.90 + *total_mods = total;
1.91 +}
1.92 +
1.93 +void TryToAddMod(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigned *total_mods)
1.94 +{
1.95 + FILE *fp;
1.96 + TCHAR gameinfo_path[MAX_PATH];
1.97 +
1.98 + UTIL_PathFormat(gameinfo_path,
1.99 + sizeof(gameinfo_path),
1.100 + _T("%s\\gameinfo.txt"),
1.101 + path);
1.102 +
1.103 + if ((fp = _tfopen(gameinfo_path, _T("rt"))) == NULL)
1.104 + {
1.105 + return;
1.106 + }
1.107 +
1.108 + int pos;
1.109 + char buffer[512];
1.110 + char key[256], value[256];
1.111 + while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL)
1.112 + {
1.113 + if ((pos = BreakStringA(buffer, key, sizeof(key))) == -1)
1.114 + {
1.115 + continue;
1.116 + }
1.117 + if ((pos = BreakStringA(&buffer[pos], value, sizeof(value))) == -1)
1.118 + {
1.119 + continue;
1.120 + }
1.121 + if (strcmp(key, "game") == 0)
1.122 + {
1.123 + mod_info_t mod;
1.124 + AnsiToUnicode(value, mod.name, sizeof(mod.name));
1.125 + UTIL_Format(mod.mod_path, sizeof(mod.mod_path), _T("%s"), path);
1.126 + mod.source_engine = eng_type;
1.127 + AddModToList(mod_list, total_mods, &mod);
1.128 + }
1.129 + }
1.130 +
1.131 + fclose(fp);
1.132 +}
1.133 +
1.134 +void AddModsFromFolder(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigned int *total_mods)
1.135 +{
1.136 + HANDLE hFind;
1.137 + WIN32_FIND_DATA fd;
1.138 + TCHAR temp_path[MAX_PATH];
1.139 + TCHAR search_path[MAX_PATH];
1.140 +
1.141 + UTIL_Format(search_path,
1.142 + sizeof(search_path),
1.143 + _T("%s\\*.*"),
1.144 + path);
1.145 +
1.146 + if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
1.147 + {
1.148 + return;
1.149 + }
1.150 +
1.151 + do
1.152 + {
1.153 + if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
1.154 + {
1.155 + continue;
1.156 + }
1.157 +
1.158 + if (tstrcasecmp(fd.cFileName, _T(".")) == 0
1.159 + || tstrcasecmp(fd.cFileName, _T("..")) == 0)
1.160 + {
1.161 + continue;
1.162 + }
1.163 +
1.164 + UTIL_PathFormat(temp_path,
1.165 + sizeof(temp_path),
1.166 + _T("%s\\%s"),
1.167 + path,
1.168 + fd.cFileName);
1.169 + TryToAddMod(temp_path, eng_type, mod_list, total_mods);
1.170 +
1.171 + } while (FindNextFile(hFind, &fd));
1.172 +
1.173 + FindClose(hFind);
1.174 +}
1.175 +
1.176 +void AddValveModsFromFolder(const TCHAR *path,
1.177 + unsigned int game_type,
1.178 + mod_info_t **mod_list,
1.179 + unsigned int *total_mods)
1.180 +{
1.181 + HANDLE hFind;
1.182 + WIN32_FIND_DATA fd;
1.183 + TCHAR temp_path[MAX_PATH];
1.184 + TCHAR search_path[MAX_PATH];
1.185 +
1.186 + UTIL_PathFormat(search_path,
1.187 + sizeof(search_path) / sizeof(TCHAR),
1.188 + _T("%s\\*.*"),
1.189 + path);
1.190 +
1.191 + if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
1.192 + {
1.193 + return;
1.194 + }
1.195 +
1.196 + do
1.197 + {
1.198 + if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
1.199 + {
1.200 + continue;
1.201 + }
1.202 +
1.203 + if (tstrcasecmp(fd.cFileName, _T(".")) == 0
1.204 + || tstrcasecmp(fd.cFileName, _T("..")) == 0)
1.205 + {
1.206 + continue;
1.207 + }
1.208 +
1.209 + TCHAR *mod_folder = NULL;
1.210 + int eng_type = SOURCE_ENGINE_UNKNOWN;
1.211 +
1.212 + if (game_type == GAMES_LISTEN)
1.213 + {
1.214 + if (tstrcasecmp(fd.cFileName, _T( "counter-strike source")) == 0)
1.215 + {
1.216 + mod_folder = _T("cstrike");
1.217 + }
1.218 + else if (tstrcasecmp(fd.cFileName, _T("day of defeat source")) == 0)
1.219 + {
1.220 + mod_folder = _T("dod");
1.221 + }
1.222 + else if (tstrcasecmp(fd.cFileName, _T("half-life 2 deathmatch")) == 0)
1.223 + {
1.224 + mod_folder = _T("hl2mp");
1.225 + }
1.226 + else if (tstrcasecmp(fd.cFileName, _T("half-life deathmatch source")) == 0)
1.227 + {
1.228 + mod_folder = _T("hl1mp");
1.229 + }
1.230 + else if (tstrcasecmp(fd.cFileName, _T("team fortress 2")) == 0)
1.231 + {
1.232 + mod_folder = _T("tf");
1.233 + eng_type = SOURCE_ENGINE_2007;
1.234 + }
1.235 + }
1.236 + else if (game_type == GAMES_DEDICATED)
1.237 + {
1.238 + if (tstrcasecmp(fd.cFileName, _T("source dedicated server")) == 0)
1.239 + {
1.240 + UTIL_PathFormat(temp_path,
1.241 + sizeof(temp_path) / sizeof(TCHAR),
1.242 + _T("%s\\%s"),
1.243 + path,
1.244 + fd.cFileName);
1.245 + AddModsFromFolder(temp_path, SOURCE_ENGINE_2004, mod_list, total_mods);
1.246 + }
1.247 + else if (tstrcasecmp(fd.cFileName, _T("source 2007 dedicated server")) == 0)
1.248 + {
1.249 + UTIL_PathFormat(temp_path,
1.250 + sizeof(temp_path) / sizeof(TCHAR),
1.251 + _T("%s\\%s"),
1.252 + path,
1.253 + fd.cFileName);
1.254 + AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, mod_list, total_mods);
1.255 + }
1.256 + }
1.257 +
1.258 + if (mod_folder != NULL)
1.259 + {
1.260 + UTIL_PathFormat(temp_path,
1.261 + sizeof(temp_path) / sizeof(TCHAR),
1.262 + _T("%s\\%s\\%s"),
1.263 + path,
1.264 + fd.cFileName,
1.265 + mod_folder);
1.266 + TryToAddMod(temp_path, eng_type, mod_list, total_mods);
1.267 + }
1.268 +
1.269 + } while (FindNextFile(hFind, &fd));
1.270 +
1.271 + FindClose(hFind);
1.272 +}
1.273 +
1.274 +int BuildGameList(unsigned int game_type, mod_info_t **mod_list)
1.275 +{
1.276 + unsigned int total_mods = 0;
1.277 +
1.278 + if (game_type == GAMES_LISTEN
1.279 + || game_type == GAMES_DEDICATED)
1.280 + {
1.281 + HKEY hkPath;
1.282 + DWORD dwLen, dwType;
1.283 + HANDLE hFind;
1.284 + WIN32_FIND_DATA fd;
1.285 + TCHAR temp_path[MAX_PATH];
1.286 + TCHAR steam_path[MAX_PATH];
1.287 + TCHAR steamapps_path[MAX_PATH];
1.288 +
1.289 + if (RegOpenKeyEx(HKEY_CURRENT_USER,
1.290 + _T("Software\\Valve\\Steam"),
1.291 + 0,
1.292 + KEY_READ,
1.293 + &hkPath) != ERROR_SUCCESS)
1.294 + {
1.295 + DWORD err = GetLastError();
1.296 + return GAME_LIST_CANT_READ;
1.297 + }
1.298 +
1.299 + dwLen = sizeof(steam_path) / sizeof(TCHAR);
1.300 + if (RegQueryValueEx(hkPath,
1.301 + _T("SteamPath"),
1.302 + NULL,
1.303 + &dwType,
1.304 + (LPBYTE)steam_path,
1.305 + &dwLen) != ERROR_SUCCESS)
1.306 + {
1.307 + RegCloseKey(hkPath);
1.308 + return GAME_LIST_CANT_READ;
1.309 + }
1.310 +
1.311 + UTIL_PathFormat(steamapps_path,
1.312 + sizeof(steamapps_path) / sizeof(TCHAR),
1.313 + _T("%s\\steamapps\\*.*"),
1.314 + steam_path);
1.315 +
1.316 + if ((hFind = FindFirstFile(steamapps_path, &fd)) == INVALID_HANDLE_VALUE)
1.317 + {
1.318 + RegCloseKey(hkPath);
1.319 + return GAME_LIST_CANT_READ;
1.320 + }
1.321 +
1.322 + do
1.323 + {
1.324 + if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
1.325 + {
1.326 + continue;
1.327 + }
1.328 +
1.329 + if (tstrcasecmp(fd.cFileName, _T(".")) == 0
1.330 + || tstrcasecmp(fd.cFileName, _T("..")) == 0)
1.331 + {
1.332 + continue;
1.333 + }
1.334 +
1.335 + /* If we get a folder called "SourceMods," look for third party mods */
1.336 + if (game_type == GAMES_LISTEN
1.337 + && tstrcasecmp(fd.cFileName, _T("SourceMods")) == 0)
1.338 + {
1.339 + UTIL_PathFormat(temp_path,
1.340 + sizeof(temp_path) / sizeof(TCHAR),
1.341 + _T("%s\\steamapps\\%s"),
1.342 + steam_path,
1.343 + fd.cFileName);
1.344 + AddModsFromFolder(temp_path, SOURCE_ENGINE_UNKNOWN, mod_list, &total_mods);
1.345 + }
1.346 + else
1.347 + {
1.348 + UTIL_PathFormat(temp_path,
1.349 + sizeof(temp_path) / sizeof(TCHAR),
1.350 + _T("%s\\steamapps\\%s"),
1.351 + steam_path,
1.352 + fd.cFileName);
1.353 + AddValveModsFromFolder(temp_path, game_type, mod_list, &total_mods);
1.354 + }
1.355 +
1.356 + } while (FindNextFile(hFind, &fd));
1.357 +
1.358 + FindClose(hFind);
1.359 + RegCloseKey(hkPath);
1.360 + }
1.361 + else if (game_type == GAMES_STANDALONE)
1.362 + {
1.363 + HKEY hkPath;
1.364 + int eng_type = SOURCE_ENGINE_UNKNOWN;
1.365 + DWORD dwLen, dwType, dwAttr;
1.366 + TCHAR temp_path[MAX_PATH];
1.367 + TCHAR hlds_path[MAX_PATH];
1.368 +
1.369 + if (RegOpenKeyEx(HKEY_CURRENT_USER,
1.370 + _T("Software\\Valve\\HLServer"),
1.371 + 0,
1.372 + KEY_READ,
1.373 + &hkPath) != ERROR_SUCCESS)
1.374 + {
1.375 + return GAME_LIST_CANT_READ;
1.376 + }
1.377 +
1.378 + dwLen = sizeof(hlds_path) / sizeof(TCHAR);
1.379 + if (RegQueryValueEx(hkPath,
1.380 + _T("InstallPath"),
1.381 + NULL,
1.382 + &dwType,
1.383 + (LPBYTE)hlds_path,
1.384 + &dwLen) != ERROR_SUCCESS)
1.385 + {
1.386 + RegCloseKey(hkPath);
1.387 + return GAME_LIST_CANT_READ;
1.388 + }
1.389 +
1.390 + /* Make sure there is a "srcds.exe" file */
1.391 + UTIL_PathFormat(temp_path,
1.392 + sizeof(temp_path) / sizeof(TCHAR),
1.393 + _T("%s\\srcds.exe"),
1.394 + hlds_path);
1.395 + dwAttr = GetFileAttributes(temp_path);
1.396 + if (dwAttr == INVALID_FILE_ATTRIBUTES)
1.397 + {
1.398 + return GAME_LIST_HALFLIFE1;
1.399 + }
1.400 +
1.401 + /* If there is an "orangebox" sub folder, we can make a better guess
1.402 + * at the engine state.
1.403 + */
1.404 + UTIL_PathFormat(temp_path,
1.405 + sizeof(temp_path) / sizeof(TCHAR),
1.406 + _T("%s\\orangebox"),
1.407 + hlds_path);
1.408 + dwAttr = GetFileAttributes(temp_path);
1.409 + if (dwAttr != INVALID_FILE_ATTRIBUTES
1.410 + && ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
1.411 + {
1.412 + eng_type = SOURCE_ENGINE_2004;
1.413 + AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, mod_list, &total_mods);
1.414 + }
1.415 +
1.416 + /* Add everything from the server */
1.417 + AddModsFromFolder(hlds_path, eng_type, mod_list, &total_mods);
1.418 +
1.419 + RegCloseKey(hkPath);
1.420 + }
1.421 +
1.422 + return (g_mod_list == NULL) ? GAME_LIST_NO_GAMES : (int)total_mods;
1.423 +}
1.424 +
1.425 +void FreeGameList(mod_info_t *mod_list)
1.426 +{
1.427 + free(mod_list);
1.428 +}
1.429 +
1.430 +int _SortModList(const void *item1, const void *item2)
1.431 +{
1.432 + const mod_info_t *mod1 = (const mod_info_t *)item1;
1.433 + const mod_info_t *mod2 = (const mod_info_t *)item2;
1.434 +
1.435 + return tstrcasecmp(mod1->name, mod2->name);
1.436 +}
1.437 +
1.438 +int FindGames(unsigned int game_type)
1.439 +{
1.440 + int reason;
1.441 +
1.442 + ReleaseGamesList();
1.443 +
1.444 + if ((reason = BuildGameList(game_type, &g_mod_list)) > 0)
1.445 + {
1.446 + g_mod_count = (unsigned)reason;
1.447 + qsort(g_mod_list, g_mod_count, sizeof(mod_info_t), _SortModList);
1.448 + }
1.449 +
1.450 + return reason;
1.451 +}
1.452 +
1.453 +void ReleaseGamesList()
1.454 +{
1.455 + if (g_mod_list == NULL)
1.456 + {
1.457 + return;
1.458 + }
1.459 +
1.460 + free(g_mod_list);
1.461 + g_mod_list = NULL;
1.462 + g_mod_count = 0;
1.463 +}
1.464 +
1.465 +void DisplayBadGamesDialog(HWND hWnd, unsigned int game_type, int reason)
1.466 +{
1.467 + TCHAR message[256];
1.468 + UINT idc = 0;
1.469 +
1.470 + if (reason == GAME_LIST_CANT_READ)
1.471 + {
1.472 + idc = IDS_GAME_FAIL_READ;
1.473 + }
1.474 + else if (reason == GAME_LIST_HALFLIFE1)
1.475 + {
1.476 + idc = IDS_GAME_FAIL_HL1;
1.477 + }
1.478 + else if (reason == GAME_LIST_NO_GAMES)
1.479 + {
1.480 + idc = IDS_GAME_FAIL_NONE;
1.481 + }
1.482 + else
1.483 + {
1.484 + return;
1.485 + }
1.486 +
1.487 + if (LoadString(g_hInstance,
1.488 + idc,
1.489 + message,
1.490 + sizeof(message) / sizeof(TCHAR)) == 0)
1.491 + {
1.492 + return;
1.493 + }
1.494 +
1.495 + MessageBox(hWnd,
1.496 + message,
1.497 + _T("SourceMod Installer"),
1.498 + MB_OK|MB_ICONWARNING);
1.499 +}