tools/installer/GamesList.cpp
changeset 1723 befc8cfb4f3c
parent 1651 077571ea8942
child 2289 44045ead61cd
     1.1 --- a/tools/installer/GamesList.cpp	Sun Nov 25 04:46:18 2007 +0000
     1.2 +++ b/tools/installer/GamesList.cpp	Sun Nov 25 18:03:59 2007 +0000
     1.3 @@ -3,8 +3,30 @@
     1.4  #include "InstallerMain.h"
     1.5  #include <stdio.h>
     1.6  
     1.7 -mod_info_t *g_mod_list = NULL;
     1.8 -unsigned int g_mod_count = 0;
     1.9 +game_database_t g_games = 
    1.10 +{
    1.11 +	NULL, 0, 
    1.12 +	{NULL, 0, GAME_LIST_NO_GAMES}, 
    1.13 +	{NULL, 0, GAME_LIST_NO_GAMES}, 
    1.14 +	{NULL, 0, GAME_LIST_NO_GAMES}
    1.15 +};
    1.16 +
    1.17 +valve_game_t valve_game_list[] = 
    1.18 +{
    1.19 +	{_T("counter-strike source"),		_T("cstrike"),	SOURCE_ENGINE_2004},
    1.20 +	{_T("day of defeat source"),		_T("dod"),		SOURCE_ENGINE_2004},
    1.21 +	{_T("half-life 2 deathmatch"),		_T("hl2mp"),	SOURCE_ENGINE_2004},
    1.22 +	{_T("half-life deathmatch source"),	_T("hl1mp"),	SOURCE_ENGINE_2004},
    1.23 +	{_T("team fortress 2"),				_T("tf"),		SOURCE_ENGINE_2007},
    1.24 +	{NULL,								NULL,			0},
    1.25 +};
    1.26 +
    1.27 +valve_game_t valve_server_list[] = 
    1.28 +{
    1.29 +	{_T("source dedicated server"),		NULL,			SOURCE_ENGINE_2004},
    1.30 +	{_T("source 2007 dedicated server"), NULL,			SOURCE_ENGINE_2007},
    1.31 +	{NULL,								NULL,			0},
    1.32 +};
    1.33  
    1.34  int IsValidFolder(const TCHAR *path)
    1.35  {
    1.36 @@ -64,30 +86,80 @@
    1.37  		MB_OK|MB_ICONWARNING);
    1.38  }
    1.39  
    1.40 -void AddModToList(mod_info_t **mod_list,
    1.41 -				  unsigned int *total_mods,
    1.42 -				  const mod_info_t *mod_info)
    1.43 +game_list_t *MakeGameList(const TCHAR *name)
    1.44  {
    1.45 -	mod_info_t *mods = *mod_list;
    1.46 -	unsigned int total = *total_mods;
    1.47 +	game_list_t *gl = (game_list_t *)malloc(sizeof(game_list_t));
    1.48 +
    1.49 +	UTIL_Format(gl->root_name, 
    1.50 +		sizeof(gl->root_name) / sizeof(TCHAR),
    1.51 +		_T("%s"),
    1.52 +		name);
    1.53 +	gl->game_count = 0;
    1.54 +	gl->games = NULL;
    1.55  
    1.56 -	if (mods == NULL)
    1.57 +	return gl;
    1.58 +}
    1.59 +
    1.60 +void AttachGameListToGroup(game_group_t *group, game_list_t *gl)
    1.61 +{
    1.62 +	if (group->lists == NULL)
    1.63  	{
    1.64 -		mods = (mod_info_t *)malloc(sizeof(mod_info_t));
    1.65 +		group->lists = (game_list_t **)malloc(sizeof(game_list_t *));
    1.66  	}
    1.67  	else
    1.68  	{
    1.69 -		mods = (mod_info_t *)realloc(mods, sizeof(mod_info_t) * (total + 1));
    1.70 +		group->lists = (game_list_t **)realloc(group->lists,
    1.71 +			sizeof(game_list_t *) * (group->list_count + 1));
    1.72 +	}
    1.73 +
    1.74 +	group->lists[group->list_count] = gl;
    1.75 +	group->list_count++;
    1.76 +}
    1.77 +
    1.78 +void AttachModToGameList(game_list_t *gl, unsigned int mod_id)
    1.79 +{
    1.80 +	if (gl->games == NULL)
    1.81 +	{
    1.82 +		gl->games = (unsigned int *)malloc(sizeof(unsigned int));
    1.83 +	}
    1.84 +	else
    1.85 +	{
    1.86 +		gl->games = (unsigned int *)realloc(gl->games, 
    1.87 +			sizeof(unsigned int) * (gl->game_count + 1));
    1.88  	}
    1.89  
    1.90 -	memcpy(&mods[total], mod_info, sizeof(mod_info_t));
    1.91 -	total++;
    1.92 -
    1.93 -	*mod_list = mods;
    1.94 -	*total_mods = total;
    1.95 +	gl->games[gl->game_count] = mod_id;
    1.96 +	gl->game_count++;
    1.97  }
    1.98  
    1.99 -void TryToAddMod(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigned *total_mods)
   1.100 +unsigned int AddModToList(game_database_t *db, const game_info_t *mod_info)
   1.101 +{
   1.102 +	/* Check if a matching game already exists */
   1.103 +	for (unsigned int i = 0; i < db->game_count; i++)
   1.104 +	{
   1.105 +		if (tstrcasecmp(mod_info->game_path, db->game_list[i].game_path) == 0)
   1.106 +		{
   1.107 +			return i;
   1.108 +		}
   1.109 +	}
   1.110 +
   1.111 +	if (db->game_list == NULL)
   1.112 +	{
   1.113 +		db->game_list = (game_info_t *)malloc(sizeof(game_info_t));
   1.114 +	}
   1.115 +	else
   1.116 +	{
   1.117 +		db->game_list = (game_info_t *)realloc(db->game_list, 
   1.118 +			sizeof(game_info_t) * (db->game_count + 1));
   1.119 +	}
   1.120 +
   1.121 +	memcpy(&db->game_list[db->game_count], mod_info, sizeof(game_info_t));
   1.122 +	db->game_count++;
   1.123 +
   1.124 +	return db->game_count - 1;
   1.125 +}
   1.126 +
   1.127 +bool TryToAddMod(const TCHAR *path, int eng_type, game_database_t *db, unsigned int *id)
   1.128  {
   1.129  	FILE *fp;
   1.130  	TCHAR gameinfo_path[MAX_PATH];
   1.131 @@ -99,7 +171,7 @@
   1.132  
   1.133  	if ((fp = _tfopen(gameinfo_path, _T("rt"))) == NULL)
   1.134  	{
   1.135 -		return;
   1.136 +		return false;
   1.137  	}
   1.138  
   1.139  	int pos;
   1.140 @@ -117,23 +189,41 @@
   1.141  		}
   1.142  		if (strcmp(key, "game") == 0)
   1.143  		{
   1.144 -			mod_info_t mod;
   1.145 +			game_info_t mod;
   1.146 +			unsigned int got_id;
   1.147 +
   1.148  			AnsiToUnicode(value, mod.name, sizeof(mod.name));
   1.149 -			UTIL_Format(mod.mod_path, sizeof(mod.mod_path), _T("%s"), path);
   1.150 +			UTIL_Format(mod.game_path, sizeof(mod.game_path), _T("%s"), path);
   1.151  			mod.source_engine = eng_type;
   1.152 -			AddModToList(mod_list, total_mods, &mod);
   1.153 +
   1.154 +			got_id = AddModToList(db, &mod);
   1.155 +
   1.156 +			if (id != NULL)
   1.157 +			{
   1.158 +				*id = got_id;
   1.159 +			}
   1.160 +
   1.161 +			fclose(fp);
   1.162 +
   1.163 +			return true;
   1.164  		}
   1.165  	}
   1.166  
   1.167  	fclose(fp);
   1.168 +
   1.169 +	return false;
   1.170  }
   1.171  
   1.172 -void AddModsFromFolder(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigned int *total_mods)
   1.173 +void AddModsFromFolder(const TCHAR *path,
   1.174 +					   int eng_type,
   1.175 +					   game_database_t *db,
   1.176 +					   game_list_t *gl)
   1.177  {
   1.178  	HANDLE hFind;
   1.179  	WIN32_FIND_DATA fd;
   1.180  	TCHAR temp_path[MAX_PATH];
   1.181  	TCHAR search_path[MAX_PATH];
   1.182 +	unsigned int mod_id;
   1.183  
   1.184  	UTIL_Format(search_path,
   1.185  		sizeof(search_path),
   1.186 @@ -163,30 +253,60 @@
   1.187  			_T("%s\\%s"),
   1.188  			path,
   1.189  			fd.cFileName);
   1.190 -		TryToAddMod(temp_path, eng_type, mod_list, total_mods);
   1.191 -
   1.192 +		if (TryToAddMod(temp_path, eng_type, db, &mod_id))
   1.193 +		{
   1.194 +			AttachModToGameList(gl, mod_id);
   1.195 +		}
   1.196  	} while (FindNextFile(hFind, &fd));
   1.197  
   1.198  	FindClose(hFind);
   1.199  }
   1.200  
   1.201 -void AddValveModsFromFolder(const TCHAR *path,
   1.202 -							unsigned int game_type,
   1.203 -							mod_info_t **mod_list,
   1.204 -							unsigned int *total_mods)
   1.205 +void GetSteamGames(game_database_t *db)
   1.206  {
   1.207 +	HKEY hkPath;
   1.208 +	DWORD dwLen, dwType;
   1.209  	HANDLE hFind;
   1.210  	WIN32_FIND_DATA fd;
   1.211  	TCHAR temp_path[MAX_PATH];
   1.212 -	TCHAR search_path[MAX_PATH];
   1.213 +	TCHAR steam_path[MAX_PATH];
   1.214 +	TCHAR steamapps_path[MAX_PATH];
   1.215 +
   1.216 +	if (RegOpenKeyEx(HKEY_CURRENT_USER,
   1.217 +		_T("Software\\Valve\\Steam"),
   1.218 +		0,
   1.219 +		KEY_READ,
   1.220 +		&hkPath) != ERROR_SUCCESS)
   1.221 +	{
   1.222 +		db->listen.error_code = GAME_LIST_CANT_READ;
   1.223 +		db->dedicated.error_code = GAME_LIST_CANT_READ;
   1.224 +		return;
   1.225 +	}
   1.226  
   1.227 -	UTIL_PathFormat(search_path,
   1.228 -		sizeof(search_path) / sizeof(TCHAR),
   1.229 -		_T("%s\\*.*"),
   1.230 -		path);
   1.231 +	dwLen = sizeof(steam_path) / sizeof(TCHAR);
   1.232 +	if (RegQueryValueEx(hkPath,
   1.233 +		_T("SteamPath"),
   1.234 +		NULL,
   1.235 +		&dwType,
   1.236 +		(LPBYTE)steam_path,
   1.237 +		&dwLen) != ERROR_SUCCESS)
   1.238 +	{
   1.239 +		RegCloseKey(hkPath);
   1.240 +		db->listen.error_code = GAME_LIST_CANT_READ;
   1.241 +		db->dedicated.error_code = GAME_LIST_CANT_READ;
   1.242 +		return;
   1.243 +	}
   1.244  
   1.245 -	if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
   1.246 +	UTIL_PathFormat(steamapps_path,
   1.247 +		sizeof(steamapps_path) / sizeof(TCHAR),
   1.248 +		_T("%s\\steamapps\\*.*"),
   1.249 +		steam_path);
   1.250 +
   1.251 +	if ((hFind = FindFirstFile(steamapps_path, &fd)) == INVALID_HANDLE_VALUE)
   1.252  	{
   1.253 +		RegCloseKey(hkPath);
   1.254 +		db->listen.error_code = GAME_LIST_CANT_READ;
   1.255 +		db->dedicated.error_code = GAME_LIST_CANT_READ;
   1.256  		return;
   1.257  	}
   1.258  
   1.259 @@ -203,263 +323,163 @@
   1.260  			continue;
   1.261  		}
   1.262  
   1.263 -		TCHAR *mod_folder = NULL;
   1.264 -		int eng_type = SOURCE_ENGINE_UNKNOWN;
   1.265 -
   1.266 -		if (game_type == GAMES_LISTEN)
   1.267 +		/* If we get a folder called "SourceMods," look for third party mods */
   1.268 +		if (tstrcasecmp(fd.cFileName, _T("SourceMods")) == 0)
   1.269  		{
   1.270 -			if (tstrcasecmp(fd.cFileName, _T( "counter-strike source")) == 0)
   1.271 +			game_list_t *gl = MakeGameList(_T("Third-Party Games"));
   1.272 +
   1.273 +			UTIL_PathFormat(temp_path,
   1.274 +				sizeof(temp_path) / sizeof(TCHAR),
   1.275 +				_T("%s\\steamapps\\%s"),
   1.276 +				steam_path,
   1.277 +				fd.cFileName);
   1.278 +
   1.279 +			AddModsFromFolder(temp_path, SOURCE_ENGINE_UNKNOWN, db, gl);
   1.280 +
   1.281 +			if (gl->game_count)
   1.282  			{
   1.283 -				mod_folder = _T("cstrike");
   1.284 -			}
   1.285 -			else if (tstrcasecmp(fd.cFileName, _T("day of defeat source")) == 0)
   1.286 -			{
   1.287 -				mod_folder = _T("dod");
   1.288 +				AttachGameListToGroup(&db->listen, gl);
   1.289  			}
   1.290 -			else if (tstrcasecmp(fd.cFileName, _T("half-life 2 deathmatch")) == 0)
   1.291 -			{
   1.292 -				mod_folder = _T("hl2mp");
   1.293 -			}
   1.294 -			else if (tstrcasecmp(fd.cFileName, _T("half-life deathmatch source")) == 0)
   1.295 +			else
   1.296  			{
   1.297 -				mod_folder = _T("hl1mp");
   1.298 -			}
   1.299 -			else if (tstrcasecmp(fd.cFileName, _T("team fortress 2")) == 0)
   1.300 -			{
   1.301 -				mod_folder = _T("tf");
   1.302 -				eng_type = SOURCE_ENGINE_2007;
   1.303 +				free(gl);
   1.304  			}
   1.305  		}
   1.306 -		else if (game_type == GAMES_DEDICATED)
   1.307 +		else
   1.308  		{
   1.309 -			if (tstrcasecmp(fd.cFileName, _T("source dedicated server")) == 0)
   1.310 +			/* Look for listenserver games */
   1.311 +			game_list_t *gl = MakeGameList(fd.cFileName);
   1.312 +
   1.313 +			for (unsigned int i = 0; valve_game_list[i].folder != NULL; i++)
   1.314 +			{
   1.315 +				unsigned int mod_id;
   1.316 +				UTIL_PathFormat(temp_path,
   1.317 +					sizeof(temp_path) / sizeof(TCHAR),
   1.318 +					_T("%s\\steamapps\\%s\\%s\\%s"),
   1.319 +					steam_path,
   1.320 +					fd.cFileName,
   1.321 +					valve_game_list[i].folder,
   1.322 +					valve_game_list[i].subfolder);
   1.323 +				if (TryToAddMod(temp_path, valve_game_list[i].eng_type, db, &mod_id))
   1.324 +				{
   1.325 +					AttachModToGameList(gl, mod_id);
   1.326 +				}
   1.327 +			}
   1.328 +
   1.329 +			if (gl->game_count)
   1.330 +			{
   1.331 +				AttachGameListToGroup(&db->listen, gl);
   1.332 +			}
   1.333 +			else
   1.334 +			{
   1.335 +				free(gl);
   1.336 +			}
   1.337 +
   1.338 +			/* Look for dedicated games */
   1.339 +			gl = MakeGameList(fd.cFileName);
   1.340 +
   1.341 +			for (unsigned int i = 0; valve_server_list[i].folder != NULL; i++)
   1.342  			{
   1.343  				UTIL_PathFormat(temp_path,
   1.344  					sizeof(temp_path) / sizeof(TCHAR),
   1.345 -					_T("%s\\%s"),
   1.346 -					path,
   1.347 -					fd.cFileName);
   1.348 -				AddModsFromFolder(temp_path, SOURCE_ENGINE_2004, mod_list, total_mods);
   1.349 +					_T("%s\\steamapps\\%s\\%s"),
   1.350 +					steam_path,
   1.351 +					fd.cFileName,
   1.352 +					valve_server_list[i].folder);
   1.353 +				AddModsFromFolder(temp_path, valve_server_list[i].eng_type, db, gl);
   1.354  			}
   1.355 -			else if (tstrcasecmp(fd.cFileName, _T("source 2007 dedicated server")) == 0)
   1.356 +
   1.357 +			if (gl->game_count)
   1.358  			{
   1.359 -				UTIL_PathFormat(temp_path,
   1.360 -					sizeof(temp_path) / sizeof(TCHAR),
   1.361 -					_T("%s\\%s"),
   1.362 -					path,
   1.363 -					fd.cFileName);
   1.364 -				AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, mod_list, total_mods);
   1.365 +				AttachGameListToGroup(&db->dedicated, gl);
   1.366  			}
   1.367 -		}
   1.368 -
   1.369 -		if (mod_folder != NULL)
   1.370 -		{
   1.371 -			UTIL_PathFormat(temp_path,
   1.372 -				sizeof(temp_path) / sizeof(TCHAR),
   1.373 -				_T("%s\\%s\\%s"),
   1.374 -				path,
   1.375 -				fd.cFileName,
   1.376 -				mod_folder);
   1.377 -			TryToAddMod(temp_path, eng_type, mod_list, total_mods);
   1.378 +			else
   1.379 +			{
   1.380 +				free(gl);
   1.381 +			}
   1.382  		}
   1.383  
   1.384  	} while (FindNextFile(hFind, &fd));
   1.385  
   1.386  	FindClose(hFind);
   1.387 +	RegCloseKey(hkPath);
   1.388  }
   1.389  
   1.390 -int BuildGameList(unsigned int game_type, mod_info_t **mod_list)
   1.391 +void GetStandaloneGames(game_database_t *db)
   1.392  {
   1.393 -	unsigned int total_mods = 0;
   1.394 -	
   1.395 -	if (game_type == GAMES_LISTEN
   1.396 -		|| game_type == GAMES_DEDICATED)
   1.397 -	{
   1.398 -		HKEY hkPath;
   1.399 -		DWORD dwLen, dwType;
   1.400 -		HANDLE hFind;
   1.401 -		WIN32_FIND_DATA fd;
   1.402 -		TCHAR temp_path[MAX_PATH];
   1.403 -		TCHAR steam_path[MAX_PATH];
   1.404 -		TCHAR steamapps_path[MAX_PATH];
   1.405 -
   1.406 -		if (RegOpenKeyEx(HKEY_CURRENT_USER,
   1.407 -			_T("Software\\Valve\\Steam"),
   1.408 -			0,
   1.409 -			KEY_READ,
   1.410 -			&hkPath) != ERROR_SUCCESS)
   1.411 -		{
   1.412 -			DWORD err = GetLastError();
   1.413 -			return GAME_LIST_CANT_READ;
   1.414 -		}
   1.415 -
   1.416 -		dwLen = sizeof(steam_path) / sizeof(TCHAR);
   1.417 -		if (RegQueryValueEx(hkPath,
   1.418 -			_T("SteamPath"),
   1.419 -			NULL,
   1.420 -			&dwType,
   1.421 -			(LPBYTE)steam_path,
   1.422 -			&dwLen) != ERROR_SUCCESS)
   1.423 -		{
   1.424 -			RegCloseKey(hkPath);
   1.425 -			return GAME_LIST_CANT_READ;
   1.426 -		}
   1.427 -
   1.428 -		UTIL_PathFormat(steamapps_path,
   1.429 -			sizeof(steamapps_path) / sizeof(TCHAR),
   1.430 -			_T("%s\\steamapps\\*.*"),
   1.431 -			steam_path);
   1.432 -
   1.433 -		if ((hFind = FindFirstFile(steamapps_path, &fd)) == INVALID_HANDLE_VALUE)
   1.434 -		{
   1.435 -			RegCloseKey(hkPath);
   1.436 -			return GAME_LIST_CANT_READ;
   1.437 -		}
   1.438 -
   1.439 -		do 
   1.440 -		{
   1.441 -			if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
   1.442 -			{
   1.443 -				continue;
   1.444 -			}
   1.445 -
   1.446 -			if (tstrcasecmp(fd.cFileName, _T(".")) == 0
   1.447 -				|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
   1.448 -			{
   1.449 -				continue;
   1.450 -			}
   1.451 +	HKEY hkPath;
   1.452 +	DWORD dwLen, dwType, dwAttr;
   1.453 +	TCHAR temp_path[MAX_PATH];
   1.454 +	TCHAR hlds_path[MAX_PATH];
   1.455 +	game_list_t *games_standalone;
   1.456  
   1.457 -			/* If we get a folder called "SourceMods," look for third party mods */
   1.458 -			if (game_type == GAMES_LISTEN 
   1.459 -				&& tstrcasecmp(fd.cFileName, _T("SourceMods")) == 0)
   1.460 -			{
   1.461 -				UTIL_PathFormat(temp_path,
   1.462 -					sizeof(temp_path) / sizeof(TCHAR),
   1.463 -					_T("%s\\steamapps\\%s"),
   1.464 -					steam_path,
   1.465 -					fd.cFileName);
   1.466 -				AddModsFromFolder(temp_path, SOURCE_ENGINE_UNKNOWN, mod_list, &total_mods);
   1.467 -			}
   1.468 -			else
   1.469 -			{
   1.470 -				UTIL_PathFormat(temp_path,
   1.471 -					sizeof(temp_path) / sizeof(TCHAR),
   1.472 -					_T("%s\\steamapps\\%s"),
   1.473 -					steam_path,
   1.474 -					fd.cFileName);
   1.475 -				AddValveModsFromFolder(temp_path, game_type, mod_list, &total_mods);
   1.476 -			}
   1.477 -
   1.478 -		} while (FindNextFile(hFind, &fd));
   1.479 -
   1.480 -		FindClose(hFind);
   1.481 -		RegCloseKey(hkPath);
   1.482 -	}
   1.483 -	else if (game_type == GAMES_STANDALONE)
   1.484 +	if (RegOpenKeyEx(HKEY_CURRENT_USER,
   1.485 +		_T("Software\\Valve\\HLServer"),
   1.486 +		0,
   1.487 +		KEY_READ,
   1.488 +		&hkPath) != ERROR_SUCCESS)
   1.489  	{
   1.490 -		HKEY hkPath;
   1.491 -		int eng_type = SOURCE_ENGINE_UNKNOWN;
   1.492 -		DWORD dwLen, dwType, dwAttr;
   1.493 -		TCHAR temp_path[MAX_PATH];
   1.494 -		TCHAR hlds_path[MAX_PATH];
   1.495 -
   1.496 -		if (RegOpenKeyEx(HKEY_CURRENT_USER,
   1.497 -			_T("Software\\Valve\\HLServer"),
   1.498 -			0,
   1.499 -			KEY_READ,
   1.500 -			&hkPath) != ERROR_SUCCESS)
   1.501 -		{
   1.502 -			return GAME_LIST_CANT_READ;
   1.503 -		}
   1.504 -
   1.505 -		dwLen = sizeof(hlds_path) / sizeof(TCHAR);
   1.506 -		if (RegQueryValueEx(hkPath,
   1.507 -			_T("InstallPath"),
   1.508 -			NULL,
   1.509 -			&dwType,
   1.510 -			(LPBYTE)hlds_path,
   1.511 -			&dwLen) != ERROR_SUCCESS)
   1.512 -		{
   1.513 -			RegCloseKey(hkPath);
   1.514 -			return GAME_LIST_CANT_READ;
   1.515 -		}
   1.516 -
   1.517 -		/* Make sure there is a "srcds.exe" file */
   1.518 -		UTIL_PathFormat(temp_path,
   1.519 -			sizeof(temp_path) / sizeof(TCHAR), 
   1.520 -			_T("%s\\srcds.exe"), 
   1.521 -			hlds_path);
   1.522 -		dwAttr = GetFileAttributes(temp_path);
   1.523 -		if (dwAttr == INVALID_FILE_ATTRIBUTES)
   1.524 -		{
   1.525 -			return GAME_LIST_HALFLIFE1;
   1.526 -		}
   1.527 -
   1.528 -		/* If there is an "orangebox" sub folder, we can make a better guess 
   1.529 -		 * at the engine state.
   1.530 -		 */
   1.531 -		UTIL_PathFormat(temp_path,
   1.532 -			sizeof(temp_path) / sizeof(TCHAR), 
   1.533 -			_T("%s\\orangebox"), 
   1.534 -			hlds_path);
   1.535 -		dwAttr = GetFileAttributes(temp_path);
   1.536 -		if (dwAttr != INVALID_FILE_ATTRIBUTES
   1.537 -			&& ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
   1.538 -		{
   1.539 -			eng_type = SOURCE_ENGINE_2004;
   1.540 -			AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, mod_list, &total_mods);
   1.541 -		}
   1.542 -
   1.543 -		/* Add everything from the server */
   1.544 -		AddModsFromFolder(hlds_path, eng_type, mod_list, &total_mods);
   1.545 -
   1.546 -		RegCloseKey(hkPath);
   1.547 +		db->standalone.error_code = GAME_LIST_CANT_READ;
   1.548 +		return;
   1.549  	}
   1.550  
   1.551 -	return (g_mod_list == NULL) ? GAME_LIST_NO_GAMES : (int)total_mods;
   1.552 -}
   1.553 -
   1.554 -void FreeGameList(mod_info_t *mod_list)
   1.555 -{
   1.556 -	free(mod_list);
   1.557 -}
   1.558 -
   1.559 -int _SortModList(const void *item1, const void *item2)
   1.560 -{
   1.561 -	const mod_info_t *mod1 = (const mod_info_t *)item1;
   1.562 -	const mod_info_t *mod2 = (const mod_info_t *)item2;
   1.563 -
   1.564 -	return tstrcasecmp(mod1->name, mod2->name);
   1.565 -}
   1.566 -
   1.567 -int FindGames(unsigned int game_type)
   1.568 -{
   1.569 -	int reason;
   1.570 -
   1.571 -	ReleaseGamesList();
   1.572 -
   1.573 -	if ((reason = BuildGameList(game_type, &g_mod_list)) > 0)
   1.574 +	dwLen = sizeof(hlds_path) / sizeof(TCHAR);
   1.575 +	if (RegQueryValueEx(hkPath,
   1.576 +		_T("InstallPath"),
   1.577 +		NULL,
   1.578 +		&dwType,
   1.579 +		(LPBYTE)hlds_path,
   1.580 +		&dwLen) != ERROR_SUCCESS)
   1.581  	{
   1.582 -		g_mod_count = (unsigned)reason;
   1.583 -		qsort(g_mod_list, g_mod_count, sizeof(mod_info_t), _SortModList);
   1.584 -	}
   1.585 -
   1.586 -	return reason;
   1.587 -}
   1.588 -
   1.589 -void ReleaseGamesList()
   1.590 -{
   1.591 -	if (g_mod_list == NULL)
   1.592 -	{
   1.593 +		RegCloseKey(hkPath);
   1.594 +		db->standalone.error_code = GAME_LIST_CANT_READ;
   1.595  		return;
   1.596  	}
   1.597  
   1.598 -	free(g_mod_list);
   1.599 -	g_mod_list = NULL;
   1.600 -	g_mod_count = 0;
   1.601 +	/* Make sure there is a "srcds.exe" file */
   1.602 +	UTIL_PathFormat(temp_path,
   1.603 +		sizeof(temp_path) / sizeof(TCHAR), 
   1.604 +		_T("%s\\srcds.exe"), 
   1.605 +		hlds_path);
   1.606 +	dwAttr = GetFileAttributes(temp_path);
   1.607 +	if (dwAttr == INVALID_FILE_ATTRIBUTES)
   1.608 +	{
   1.609 +		db->standalone.error_code = GAME_LIST_HALFLIFE1;
   1.610 +		return;
   1.611 +	}
   1.612 +
   1.613 +	games_standalone = MakeGameList(_T("Standalone"));
   1.614 +
   1.615 +	/* If there is an "orangebox" sub folder, we can make a better guess 
   1.616 +	 * at the engine state.
   1.617 +	 */
   1.618 +	UTIL_PathFormat(temp_path,
   1.619 +		sizeof(temp_path) / sizeof(TCHAR), 
   1.620 +		_T("%s\\orangebox"), 
   1.621 +		hlds_path);
   1.622 +	dwAttr = GetFileAttributes(temp_path);
   1.623 +	if (dwAttr != INVALID_FILE_ATTRIBUTES
   1.624 +		&& ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
   1.625 +	{
   1.626 +		AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, db, games_standalone);
   1.627 +	}
   1.628 +
   1.629 +	/* Add everything from the server */
   1.630 +	AddModsFromFolder(hlds_path, SOURCE_ENGINE_2004, db, games_standalone);
   1.631 +
   1.632 +	if (games_standalone->game_count)
   1.633 +	{
   1.634 +		AttachGameListToGroup(&db->standalone, games_standalone);
   1.635 +	}
   1.636 +	else
   1.637 +	{
   1.638 +		free(games_standalone);
   1.639 +	}
   1.640 +
   1.641 +	RegCloseKey(hkPath);
   1.642  }
   1.643  
   1.644 -void DisplayBadGamesDialog(HWND hWnd, unsigned int game_type, int reason)
   1.645 +void DisplayBadGamesDialog(HWND hWnd, int reason)
   1.646  {
   1.647  	TCHAR message[256];
   1.648  	UINT idc = 0;
   1.649 @@ -494,3 +514,61 @@
   1.650  		_T("SourceMod Installer"),
   1.651  		MB_OK|MB_ICONWARNING);
   1.652  }
   1.653 +
   1.654 +int _ModIdCompare(const void *item1, const void *item2)
   1.655 +{
   1.656 +	unsigned int mod_id1 = *(unsigned int *)item1;
   1.657 +	unsigned int mod_id2 = *(unsigned int *)item2;
   1.658 +
   1.659 +	return tstrcasecmp(g_games.game_list[mod_id1].name, g_games.game_list[mod_id2].name);
   1.660 +}
   1.661 +
   1.662 +int _GroupCompare(const void *item1, const void *item2)
   1.663 +{
   1.664 +	game_list_t *g1 = *(game_list_t **)item1;
   1.665 +	game_list_t *g2 = *(game_list_t **)item2;
   1.666 +
   1.667 +	return tstrcasecmp(g1->root_name, g2->root_name);
   1.668 +}
   1.669 +
   1.670 +void SortGameGroup(game_group_t *group)
   1.671 +{
   1.672 +	qsort(group->lists, group->list_count, sizeof(game_list_t *), _GroupCompare);
   1.673 +
   1.674 +	for (unsigned int i = 0; i < group->list_count; i++)
   1.675 +	{
   1.676 +		qsort(group->lists[i]->games,
   1.677 +			  group->lists[i]->game_count,
   1.678 +			  sizeof(unsigned int),
   1.679 +			  _ModIdCompare);
   1.680 +	}
   1.681 +}
   1.682 +
   1.683 +void BuildGameDB()
   1.684 +{
   1.685 +	ReleaseGameDB();
   1.686 +	GetStandaloneGames(&g_games);
   1.687 +	GetSteamGames(&g_games);
   1.688 +	SortGameGroup(&g_games.dedicated);
   1.689 +	SortGameGroup(&g_games.listen);
   1.690 +	SortGameGroup(&g_games.standalone);
   1.691 +}
   1.692 +
   1.693 +void ReleaseGameGroup(game_group_t *group)
   1.694 +{
   1.695 +	for (unsigned int i = 0; i < group->list_count; i++)
   1.696 +	{
   1.697 +		free(group->lists[i]->games);
   1.698 +		free(group->lists[i]);
   1.699 +	}
   1.700 +	free(group->lists);
   1.701 +}
   1.702 +
   1.703 +void ReleaseGameDB()
   1.704 +{
   1.705 +	ReleaseGameGroup(&g_games.dedicated);
   1.706 +	ReleaseGameGroup(&g_games.listen);
   1.707 +	ReleaseGameGroup(&g_games.standalone);
   1.708 +	free(g_games.game_list);
   1.709 +	memset(&g_games, 0, sizeof(g_games));
   1.710 +}