tools/installer/GamesList.cpp
author David Anderson <dvander@alliedmods.net>
Sun Nov 25 18:03:59 2007 +0000 (2007-11-25)
changeset 1723 befc8cfb4f3c
parent 1651 077571ea8942
child 2289 44045ead61cd
permissions -rw-r--r--
new game list code, detects steam accounts and dynamically shows you which games are under each one
dvander@1651
     1
#include "GamesList.h"
dvander@1651
     2
#include "InstallerUtil.h"
dvander@1651
     3
#include "InstallerMain.h"
dvander@1651
     4
#include <stdio.h>
dvander@1651
     5
dvander@1723
     6
game_database_t g_games = 
dvander@1723
     7
{
dvander@1723
     8
	NULL, 0, 
dvander@1723
     9
	{NULL, 0, GAME_LIST_NO_GAMES}, 
dvander@1723
    10
	{NULL, 0, GAME_LIST_NO_GAMES}, 
dvander@1723
    11
	{NULL, 0, GAME_LIST_NO_GAMES}
dvander@1723
    12
};
dvander@1723
    13
dvander@1723
    14
valve_game_t valve_game_list[] = 
dvander@1723
    15
{
dvander@1723
    16
	{_T("counter-strike source"),		_T("cstrike"),	SOURCE_ENGINE_2004},
dvander@1723
    17
	{_T("day of defeat source"),		_T("dod"),		SOURCE_ENGINE_2004},
dvander@1723
    18
	{_T("half-life 2 deathmatch"),		_T("hl2mp"),	SOURCE_ENGINE_2004},
dvander@1723
    19
	{_T("half-life deathmatch source"),	_T("hl1mp"),	SOURCE_ENGINE_2004},
dvander@1723
    20
	{_T("team fortress 2"),				_T("tf"),		SOURCE_ENGINE_2007},
dvander@1723
    21
	{NULL,								NULL,			0},
dvander@1723
    22
};
dvander@1723
    23
dvander@1723
    24
valve_game_t valve_server_list[] = 
dvander@1723
    25
{
dvander@1723
    26
	{_T("source dedicated server"),		NULL,			SOURCE_ENGINE_2004},
dvander@1723
    27
	{_T("source 2007 dedicated server"), NULL,			SOURCE_ENGINE_2007},
dvander@1723
    28
	{NULL,								NULL,			0},
dvander@1723
    29
};
dvander@1651
    30
dvander@1651
    31
int IsValidFolder(const TCHAR *path)
dvander@1651
    32
{
dvander@1651
    33
	DWORD attr;
dvander@1651
    34
	TCHAR gameinfo_file[MAX_PATH];
dvander@1651
    35
dvander@1651
    36
	UTIL_PathFormat(gameinfo_file, sizeof(gameinfo_file), _T("%s\\gameinfo.txt"), path);
dvander@1651
    37
dvander@1651
    38
	if ((attr = GetFileAttributes(gameinfo_file)) == INVALID_FILE_ATTRIBUTES)
dvander@1651
    39
	{
dvander@1651
    40
		return GAMEINFO_DOES_NOT_EXIST;
dvander@1651
    41
	}
dvander@1651
    42
dvander@1651
    43
	if ((attr & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)
dvander@1651
    44
	{
dvander@1651
    45
		return GAMEINFO_IS_READ_ONLY;
dvander@1651
    46
	}
dvander@1651
    47
dvander@1651
    48
	if ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
dvander@1651
    49
	{
dvander@1651
    50
		return GAMEINFO_DOES_NOT_EXIST;
dvander@1651
    51
	}
dvander@1651
    52
dvander@1651
    53
	return GAMEINFO_IS_USABLE;
dvander@1651
    54
}
dvander@1651
    55
dvander@1651
    56
void DisplayBadFolderDialog(HWND hDlg, int reason)
dvander@1651
    57
{
dvander@1651
    58
	TCHAR message_string[255];
dvander@1651
    59
	UINT resource;
dvander@1651
    60
dvander@1651
    61
	if (reason == GAMEINFO_DOES_NOT_EXIST)
dvander@1651
    62
	{
dvander@1651
    63
		resource = IDS_NO_GAMEINFO;
dvander@1651
    64
	}
dvander@1651
    65
	else if (reason == GAMEINFO_IS_READ_ONLY)
dvander@1651
    66
	{
dvander@1651
    67
		resource = IDS_READONLY_GAMEINFO;
dvander@1651
    68
	}
dvander@1651
    69
	else
dvander@1651
    70
	{
dvander@1651
    71
		return;
dvander@1651
    72
	}
dvander@1651
    73
dvander@1651
    74
	if (LoadString(g_hInstance,
dvander@1651
    75
		resource,
dvander@1651
    76
		message_string,
dvander@1651
    77
		sizeof(message_string) / sizeof(TCHAR)
dvander@1651
    78
		) == 0)
dvander@1651
    79
	{
dvander@1651
    80
		return;
dvander@1651
    81
	}
dvander@1651
    82
dvander@1651
    83
	MessageBox(hDlg, 
dvander@1651
    84
		message_string, 
dvander@1651
    85
		_T("SourceMod Installer"),
dvander@1651
    86
		MB_OK|MB_ICONWARNING);
dvander@1651
    87
}
dvander@1651
    88
dvander@1723
    89
game_list_t *MakeGameList(const TCHAR *name)
dvander@1651
    90
{
dvander@1723
    91
	game_list_t *gl = (game_list_t *)malloc(sizeof(game_list_t));
dvander@1723
    92
dvander@1723
    93
	UTIL_Format(gl->root_name, 
dvander@1723
    94
		sizeof(gl->root_name) / sizeof(TCHAR),
dvander@1723
    95
		_T("%s"),
dvander@1723
    96
		name);
dvander@1723
    97
	gl->game_count = 0;
dvander@1723
    98
	gl->games = NULL;
dvander@1651
    99
dvander@1723
   100
	return gl;
dvander@1723
   101
}
dvander@1723
   102
dvander@1723
   103
void AttachGameListToGroup(game_group_t *group, game_list_t *gl)
dvander@1723
   104
{
dvander@1723
   105
	if (group->lists == NULL)
dvander@1651
   106
	{
dvander@1723
   107
		group->lists = (game_list_t **)malloc(sizeof(game_list_t *));
dvander@1651
   108
	}
dvander@1651
   109
	else
dvander@1651
   110
	{
dvander@1723
   111
		group->lists = (game_list_t **)realloc(group->lists,
dvander@1723
   112
			sizeof(game_list_t *) * (group->list_count + 1));
dvander@1723
   113
	}
dvander@1723
   114
dvander@1723
   115
	group->lists[group->list_count] = gl;
dvander@1723
   116
	group->list_count++;
dvander@1723
   117
}
dvander@1723
   118
dvander@1723
   119
void AttachModToGameList(game_list_t *gl, unsigned int mod_id)
dvander@1723
   120
{
dvander@1723
   121
	if (gl->games == NULL)
dvander@1723
   122
	{
dvander@1723
   123
		gl->games = (unsigned int *)malloc(sizeof(unsigned int));
dvander@1723
   124
	}
dvander@1723
   125
	else
dvander@1723
   126
	{
dvander@1723
   127
		gl->games = (unsigned int *)realloc(gl->games, 
dvander@1723
   128
			sizeof(unsigned int) * (gl->game_count + 1));
dvander@1651
   129
	}
dvander@1651
   130
dvander@1723
   131
	gl->games[gl->game_count] = mod_id;
dvander@1723
   132
	gl->game_count++;
dvander@1651
   133
}
dvander@1651
   134
dvander@1723
   135
unsigned int AddModToList(game_database_t *db, const game_info_t *mod_info)
dvander@1723
   136
{
dvander@1723
   137
	/* Check if a matching game already exists */
dvander@1723
   138
	for (unsigned int i = 0; i < db->game_count; i++)
dvander@1723
   139
	{
dvander@1723
   140
		if (tstrcasecmp(mod_info->game_path, db->game_list[i].game_path) == 0)
dvander@1723
   141
		{
dvander@1723
   142
			return i;
dvander@1723
   143
		}
dvander@1723
   144
	}
dvander@1723
   145
dvander@1723
   146
	if (db->game_list == NULL)
dvander@1723
   147
	{
dvander@1723
   148
		db->game_list = (game_info_t *)malloc(sizeof(game_info_t));
dvander@1723
   149
	}
dvander@1723
   150
	else
dvander@1723
   151
	{
dvander@1723
   152
		db->game_list = (game_info_t *)realloc(db->game_list, 
dvander@1723
   153
			sizeof(game_info_t) * (db->game_count + 1));
dvander@1723
   154
	}
dvander@1723
   155
dvander@1723
   156
	memcpy(&db->game_list[db->game_count], mod_info, sizeof(game_info_t));
dvander@1723
   157
	db->game_count++;
dvander@1723
   158
dvander@1723
   159
	return db->game_count - 1;
dvander@1723
   160
}
dvander@1723
   161
dvander@1723
   162
bool TryToAddMod(const TCHAR *path, int eng_type, game_database_t *db, unsigned int *id)
dvander@1651
   163
{
dvander@1651
   164
	FILE *fp;
dvander@1651
   165
	TCHAR gameinfo_path[MAX_PATH];
dvander@1651
   166
dvander@1651
   167
	UTIL_PathFormat(gameinfo_path,
dvander@1651
   168
		sizeof(gameinfo_path),
dvander@1651
   169
		_T("%s\\gameinfo.txt"),
dvander@1651
   170
		path);
dvander@1651
   171
dvander@1651
   172
	if ((fp = _tfopen(gameinfo_path, _T("rt"))) == NULL)
dvander@1651
   173
	{
dvander@1723
   174
		return false;
dvander@1651
   175
	}
dvander@1651
   176
dvander@1651
   177
	int pos;
dvander@1651
   178
	char buffer[512];
dvander@1651
   179
	char key[256], value[256];
dvander@1651
   180
	while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL)
dvander@1651
   181
	{
dvander@1651
   182
		if ((pos = BreakStringA(buffer, key, sizeof(key))) == -1)
dvander@1651
   183
		{
dvander@1651
   184
			continue;
dvander@1651
   185
		}
dvander@1651
   186
		if ((pos = BreakStringA(&buffer[pos], value, sizeof(value))) == -1)
dvander@1651
   187
		{
dvander@1651
   188
			continue;
dvander@1651
   189
		}
dvander@1651
   190
		if (strcmp(key, "game") == 0)
dvander@1651
   191
		{
dvander@1723
   192
			game_info_t mod;
dvander@1723
   193
			unsigned int got_id;
dvander@1723
   194
dvander@1651
   195
			AnsiToUnicode(value, mod.name, sizeof(mod.name));
dvander@1723
   196
			UTIL_Format(mod.game_path, sizeof(mod.game_path), _T("%s"), path);
dvander@1651
   197
			mod.source_engine = eng_type;
dvander@1723
   198
dvander@1723
   199
			got_id = AddModToList(db, &mod);
dvander@1723
   200
dvander@1723
   201
			if (id != NULL)
dvander@1723
   202
			{
dvander@1723
   203
				*id = got_id;
dvander@1723
   204
			}
dvander@1723
   205
dvander@1723
   206
			fclose(fp);
dvander@1723
   207
dvander@1723
   208
			return true;
dvander@1651
   209
		}
dvander@1651
   210
	}
dvander@1651
   211
dvander@1651
   212
	fclose(fp);
dvander@1723
   213
dvander@1723
   214
	return false;
dvander@1651
   215
}
dvander@1651
   216
dvander@1723
   217
void AddModsFromFolder(const TCHAR *path,
dvander@1723
   218
					   int eng_type,
dvander@1723
   219
					   game_database_t *db,
dvander@1723
   220
					   game_list_t *gl)
dvander@1651
   221
{
dvander@1651
   222
	HANDLE hFind;
dvander@1651
   223
	WIN32_FIND_DATA fd;
dvander@1651
   224
	TCHAR temp_path[MAX_PATH];
dvander@1651
   225
	TCHAR search_path[MAX_PATH];
dvander@1723
   226
	unsigned int mod_id;
dvander@1651
   227
dvander@1651
   228
	UTIL_Format(search_path,
dvander@1651
   229
		sizeof(search_path),
dvander@1651
   230
		_T("%s\\*.*"),
dvander@1651
   231
		path);
dvander@1651
   232
dvander@1651
   233
	if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
dvander@1651
   234
	{
dvander@1651
   235
		return;
dvander@1651
   236
	}
dvander@1651
   237
dvander@1651
   238
	do 
dvander@1651
   239
	{
dvander@1651
   240
		if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
dvander@1651
   241
		{
dvander@1651
   242
			continue;
dvander@1651
   243
		}
dvander@1651
   244
dvander@1651
   245
		if (tstrcasecmp(fd.cFileName, _T(".")) == 0
dvander@1651
   246
			|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
dvander@1651
   247
		{
dvander@1651
   248
			continue;
dvander@1651
   249
		}
dvander@1651
   250
dvander@1651
   251
		UTIL_PathFormat(temp_path,
dvander@1651
   252
			sizeof(temp_path),
dvander@1651
   253
			_T("%s\\%s"),
dvander@1651
   254
			path,
dvander@1651
   255
			fd.cFileName);
dvander@1723
   256
		if (TryToAddMod(temp_path, eng_type, db, &mod_id))
dvander@1723
   257
		{
dvander@1723
   258
			AttachModToGameList(gl, mod_id);
dvander@1723
   259
		}
dvander@1651
   260
	} while (FindNextFile(hFind, &fd));
dvander@1651
   261
dvander@1651
   262
	FindClose(hFind);
dvander@1651
   263
}
dvander@1651
   264
dvander@1723
   265
void GetSteamGames(game_database_t *db)
dvander@1651
   266
{
dvander@1723
   267
	HKEY hkPath;
dvander@1723
   268
	DWORD dwLen, dwType;
dvander@1651
   269
	HANDLE hFind;
dvander@1651
   270
	WIN32_FIND_DATA fd;
dvander@1651
   271
	TCHAR temp_path[MAX_PATH];
dvander@1723
   272
	TCHAR steam_path[MAX_PATH];
dvander@1723
   273
	TCHAR steamapps_path[MAX_PATH];
dvander@1723
   274
dvander@1723
   275
	if (RegOpenKeyEx(HKEY_CURRENT_USER,
dvander@1723
   276
		_T("Software\\Valve\\Steam"),
dvander@1723
   277
		0,
dvander@1723
   278
		KEY_READ,
dvander@1723
   279
		&hkPath) != ERROR_SUCCESS)
dvander@1723
   280
	{
dvander@1723
   281
		db->listen.error_code = GAME_LIST_CANT_READ;
dvander@1723
   282
		db->dedicated.error_code = GAME_LIST_CANT_READ;
dvander@1723
   283
		return;
dvander@1723
   284
	}
dvander@1651
   285
dvander@1723
   286
	dwLen = sizeof(steam_path) / sizeof(TCHAR);
dvander@1723
   287
	if (RegQueryValueEx(hkPath,
dvander@1723
   288
		_T("SteamPath"),
dvander@1723
   289
		NULL,
dvander@1723
   290
		&dwType,
dvander@1723
   291
		(LPBYTE)steam_path,
dvander@1723
   292
		&dwLen) != ERROR_SUCCESS)
dvander@1723
   293
	{
dvander@1723
   294
		RegCloseKey(hkPath);
dvander@1723
   295
		db->listen.error_code = GAME_LIST_CANT_READ;
dvander@1723
   296
		db->dedicated.error_code = GAME_LIST_CANT_READ;
dvander@1723
   297
		return;
dvander@1723
   298
	}
dvander@1651
   299
dvander@1723
   300
	UTIL_PathFormat(steamapps_path,
dvander@1723
   301
		sizeof(steamapps_path) / sizeof(TCHAR),
dvander@1723
   302
		_T("%s\\steamapps\\*.*"),
dvander@1723
   303
		steam_path);
dvander@1723
   304
dvander@1723
   305
	if ((hFind = FindFirstFile(steamapps_path, &fd)) == INVALID_HANDLE_VALUE)
dvander@1651
   306
	{
dvander@1723
   307
		RegCloseKey(hkPath);
dvander@1723
   308
		db->listen.error_code = GAME_LIST_CANT_READ;
dvander@1723
   309
		db->dedicated.error_code = GAME_LIST_CANT_READ;
dvander@1651
   310
		return;
dvander@1651
   311
	}
dvander@1651
   312
dvander@1651
   313
	do 
dvander@1651
   314
	{
dvander@1651
   315
		if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
dvander@1651
   316
		{
dvander@1651
   317
			continue;
dvander@1651
   318
		}
dvander@1651
   319
dvander@1651
   320
		if (tstrcasecmp(fd.cFileName, _T(".")) == 0
dvander@1651
   321
			|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
dvander@1651
   322
		{
dvander@1651
   323
			continue;
dvander@1651
   324
		}
dvander@1651
   325
dvander@1723
   326
		/* If we get a folder called "SourceMods," look for third party mods */
dvander@1723
   327
		if (tstrcasecmp(fd.cFileName, _T("SourceMods")) == 0)
dvander@1651
   328
		{
dvander@1723
   329
			game_list_t *gl = MakeGameList(_T("Third-Party Games"));
dvander@1723
   330
dvander@1723
   331
			UTIL_PathFormat(temp_path,
dvander@1723
   332
				sizeof(temp_path) / sizeof(TCHAR),
dvander@1723
   333
				_T("%s\\steamapps\\%s"),
dvander@1723
   334
				steam_path,
dvander@1723
   335
				fd.cFileName);
dvander@1723
   336
dvander@1723
   337
			AddModsFromFolder(temp_path, SOURCE_ENGINE_UNKNOWN, db, gl);
dvander@1723
   338
dvander@1723
   339
			if (gl->game_count)
dvander@1651
   340
			{
dvander@1723
   341
				AttachGameListToGroup(&db->listen, gl);
dvander@1651
   342
			}
dvander@1723
   343
			else
dvander@1651
   344
			{
dvander@1723
   345
				free(gl);
dvander@1651
   346
			}
dvander@1651
   347
		}
dvander@1723
   348
		else
dvander@1651
   349
		{
dvander@1723
   350
			/* Look for listenserver games */
dvander@1723
   351
			game_list_t *gl = MakeGameList(fd.cFileName);
dvander@1723
   352
dvander@1723
   353
			for (unsigned int i = 0; valve_game_list[i].folder != NULL; i++)
dvander@1723
   354
			{
dvander@1723
   355
				unsigned int mod_id;
dvander@1723
   356
				UTIL_PathFormat(temp_path,
dvander@1723
   357
					sizeof(temp_path) / sizeof(TCHAR),
dvander@1723
   358
					_T("%s\\steamapps\\%s\\%s\\%s"),
dvander@1723
   359
					steam_path,
dvander@1723
   360
					fd.cFileName,
dvander@1723
   361
					valve_game_list[i].folder,
dvander@1723
   362
					valve_game_list[i].subfolder);
dvander@1723
   363
				if (TryToAddMod(temp_path, valve_game_list[i].eng_type, db, &mod_id))
dvander@1723
   364
				{
dvander@1723
   365
					AttachModToGameList(gl, mod_id);
dvander@1723
   366
				}
dvander@1723
   367
			}
dvander@1723
   368
dvander@1723
   369
			if (gl->game_count)
dvander@1723
   370
			{
dvander@1723
   371
				AttachGameListToGroup(&db->listen, gl);
dvander@1723
   372
			}
dvander@1723
   373
			else
dvander@1723
   374
			{
dvander@1723
   375
				free(gl);
dvander@1723
   376
			}
dvander@1723
   377
dvander@1723
   378
			/* Look for dedicated games */
dvander@1723
   379
			gl = MakeGameList(fd.cFileName);
dvander@1723
   380
dvander@1723
   381
			for (unsigned int i = 0; valve_server_list[i].folder != NULL; i++)
dvander@1651
   382
			{
dvander@1651
   383
				UTIL_PathFormat(temp_path,
dvander@1651
   384
					sizeof(temp_path) / sizeof(TCHAR),
dvander@1723
   385
					_T("%s\\steamapps\\%s\\%s"),
dvander@1723
   386
					steam_path,
dvander@1723
   387
					fd.cFileName,
dvander@1723
   388
					valve_server_list[i].folder);
dvander@1723
   389
				AddModsFromFolder(temp_path, valve_server_list[i].eng_type, db, gl);
dvander@1651
   390
			}
dvander@1723
   391
dvander@1723
   392
			if (gl->game_count)
dvander@1651
   393
			{
dvander@1723
   394
				AttachGameListToGroup(&db->dedicated, gl);
dvander@1651
   395
			}
dvander@1723
   396
			else
dvander@1723
   397
			{
dvander@1723
   398
				free(gl);
dvander@1723
   399
			}
dvander@1651
   400
		}
dvander@1651
   401
dvander@1651
   402
	} while (FindNextFile(hFind, &fd));
dvander@1651
   403
dvander@1651
   404
	FindClose(hFind);
dvander@1723
   405
	RegCloseKey(hkPath);
dvander@1651
   406
}
dvander@1651
   407
dvander@1723
   408
void GetStandaloneGames(game_database_t *db)
dvander@1651
   409
{
dvander@1723
   410
	HKEY hkPath;
dvander@1723
   411
	DWORD dwLen, dwType, dwAttr;
dvander@1723
   412
	TCHAR temp_path[MAX_PATH];
dvander@1723
   413
	TCHAR hlds_path[MAX_PATH];
dvander@1723
   414
	game_list_t *games_standalone;
dvander@1651
   415
dvander@1723
   416
	if (RegOpenKeyEx(HKEY_CURRENT_USER,
dvander@1723
   417
		_T("Software\\Valve\\HLServer"),
dvander@1723
   418
		0,
dvander@1723
   419
		KEY_READ,
dvander@1723
   420
		&hkPath) != ERROR_SUCCESS)
dvander@1651
   421
	{
dvander@1723
   422
		db->standalone.error_code = GAME_LIST_CANT_READ;
dvander@1723
   423
		return;
dvander@1651
   424
	}
dvander@1651
   425
dvander@1723
   426
	dwLen = sizeof(hlds_path) / sizeof(TCHAR);
dvander@1723
   427
	if (RegQueryValueEx(hkPath,
dvander@1723
   428
		_T("InstallPath"),
dvander@1723
   429
		NULL,
dvander@1723
   430
		&dwType,
dvander@1723
   431
		(LPBYTE)hlds_path,
dvander@1723
   432
		&dwLen) != ERROR_SUCCESS)
dvander@1651
   433
	{
dvander@1723
   434
		RegCloseKey(hkPath);
dvander@1723
   435
		db->standalone.error_code = GAME_LIST_CANT_READ;
dvander@1651
   436
		return;
dvander@1651
   437
	}
dvander@1651
   438
dvander@1723
   439
	/* Make sure there is a "srcds.exe" file */
dvander@1723
   440
	UTIL_PathFormat(temp_path,
dvander@1723
   441
		sizeof(temp_path) / sizeof(TCHAR), 
dvander@1723
   442
		_T("%s\\srcds.exe"), 
dvander@1723
   443
		hlds_path);
dvander@1723
   444
	dwAttr = GetFileAttributes(temp_path);
dvander@1723
   445
	if (dwAttr == INVALID_FILE_ATTRIBUTES)
dvander@1723
   446
	{
dvander@1723
   447
		db->standalone.error_code = GAME_LIST_HALFLIFE1;
dvander@1723
   448
		return;
dvander@1723
   449
	}
dvander@1723
   450
dvander@1723
   451
	games_standalone = MakeGameList(_T("Standalone"));
dvander@1723
   452
dvander@1723
   453
	/* If there is an "orangebox" sub folder, we can make a better guess 
dvander@1723
   454
	 * at the engine state.
dvander@1723
   455
	 */
dvander@1723
   456
	UTIL_PathFormat(temp_path,
dvander@1723
   457
		sizeof(temp_path) / sizeof(TCHAR), 
dvander@1723
   458
		_T("%s\\orangebox"), 
dvander@1723
   459
		hlds_path);
dvander@1723
   460
	dwAttr = GetFileAttributes(temp_path);
dvander@1723
   461
	if (dwAttr != INVALID_FILE_ATTRIBUTES
dvander@1723
   462
		&& ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
dvander@1723
   463
	{
dvander@1723
   464
		AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, db, games_standalone);
dvander@1723
   465
	}
dvander@1723
   466
dvander@1723
   467
	/* Add everything from the server */
dvander@1723
   468
	AddModsFromFolder(hlds_path, SOURCE_ENGINE_2004, db, games_standalone);
dvander@1723
   469
dvander@1723
   470
	if (games_standalone->game_count)
dvander@1723
   471
	{
dvander@1723
   472
		AttachGameListToGroup(&db->standalone, games_standalone);
dvander@1723
   473
	}
dvander@1723
   474
	else
dvander@1723
   475
	{
dvander@1723
   476
		free(games_standalone);
dvander@1723
   477
	}
dvander@1723
   478
dvander@1723
   479
	RegCloseKey(hkPath);
dvander@1651
   480
}
dvander@1651
   481
dvander@1723
   482
void DisplayBadGamesDialog(HWND hWnd, int reason)
dvander@1651
   483
{
dvander@1651
   484
	TCHAR message[256];
dvander@1651
   485
	UINT idc = 0;
dvander@1651
   486
dvander@1651
   487
	if (reason == GAME_LIST_CANT_READ)
dvander@1651
   488
	{
dvander@1651
   489
		idc = IDS_GAME_FAIL_READ;
dvander@1651
   490
	}
dvander@1651
   491
	else if (reason == GAME_LIST_HALFLIFE1)
dvander@1651
   492
	{
dvander@1651
   493
		idc = IDS_GAME_FAIL_HL1;
dvander@1651
   494
	}
dvander@1651
   495
	else if (reason == GAME_LIST_NO_GAMES)
dvander@1651
   496
	{
dvander@1651
   497
		idc = IDS_GAME_FAIL_NONE;
dvander@1651
   498
	}
dvander@1651
   499
	else
dvander@1651
   500
	{
dvander@1651
   501
		return;
dvander@1651
   502
	}
dvander@1651
   503
dvander@1651
   504
	if (LoadString(g_hInstance,
dvander@1651
   505
		idc,
dvander@1651
   506
		message,
dvander@1651
   507
		sizeof(message) / sizeof(TCHAR)) == 0)
dvander@1651
   508
	{
dvander@1651
   509
		return;
dvander@1651
   510
	}
dvander@1651
   511
dvander@1651
   512
	MessageBox(hWnd, 
dvander@1651
   513
		message, 
dvander@1651
   514
		_T("SourceMod Installer"),
dvander@1651
   515
		MB_OK|MB_ICONWARNING);
dvander@1651
   516
}
dvander@1723
   517
dvander@1723
   518
int _ModIdCompare(const void *item1, const void *item2)
dvander@1723
   519
{
dvander@1723
   520
	unsigned int mod_id1 = *(unsigned int *)item1;
dvander@1723
   521
	unsigned int mod_id2 = *(unsigned int *)item2;
dvander@1723
   522
dvander@1723
   523
	return tstrcasecmp(g_games.game_list[mod_id1].name, g_games.game_list[mod_id2].name);
dvander@1723
   524
}
dvander@1723
   525
dvander@1723
   526
int _GroupCompare(const void *item1, const void *item2)
dvander@1723
   527
{
dvander@1723
   528
	game_list_t *g1 = *(game_list_t **)item1;
dvander@1723
   529
	game_list_t *g2 = *(game_list_t **)item2;
dvander@1723
   530
dvander@1723
   531
	return tstrcasecmp(g1->root_name, g2->root_name);
dvander@1723
   532
}
dvander@1723
   533
dvander@1723
   534
void SortGameGroup(game_group_t *group)
dvander@1723
   535
{
dvander@1723
   536
	qsort(group->lists, group->list_count, sizeof(game_list_t *), _GroupCompare);
dvander@1723
   537
dvander@1723
   538
	for (unsigned int i = 0; i < group->list_count; i++)
dvander@1723
   539
	{
dvander@1723
   540
		qsort(group->lists[i]->games,
dvander@1723
   541
			  group->lists[i]->game_count,
dvander@1723
   542
			  sizeof(unsigned int),
dvander@1723
   543
			  _ModIdCompare);
dvander@1723
   544
	}
dvander@1723
   545
}
dvander@1723
   546
dvander@1723
   547
void BuildGameDB()
dvander@1723
   548
{
dvander@1723
   549
	ReleaseGameDB();
dvander@1723
   550
	GetStandaloneGames(&g_games);
dvander@1723
   551
	GetSteamGames(&g_games);
dvander@1723
   552
	SortGameGroup(&g_games.dedicated);
dvander@1723
   553
	SortGameGroup(&g_games.listen);
dvander@1723
   554
	SortGameGroup(&g_games.standalone);
dvander@1723
   555
}
dvander@1723
   556
dvander@1723
   557
void ReleaseGameGroup(game_group_t *group)
dvander@1723
   558
{
dvander@1723
   559
	for (unsigned int i = 0; i < group->list_count; i++)
dvander@1723
   560
	{
dvander@1723
   561
		free(group->lists[i]->games);
dvander@1723
   562
		free(group->lists[i]);
dvander@1723
   563
	}
dvander@1723
   564
	free(group->lists);
dvander@1723
   565
}
dvander@1723
   566
dvander@1723
   567
void ReleaseGameDB()
dvander@1723
   568
{
dvander@1723
   569
	ReleaseGameGroup(&g_games.dedicated);
dvander@1723
   570
	ReleaseGameGroup(&g_games.listen);
dvander@1723
   571
	ReleaseGameGroup(&g_games.standalone);
dvander@1723
   572
	free(g_games.game_list);
dvander@1723
   573
	memset(&g_games, 0, sizeof(g_games));
dvander@1723
   574
}