tools/installer/GamesList.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Aug 24 05:05:04 2008 +0000 (2008-08-24)
changeset 2238 0879e1742145
parent 1952 b7aa2b626807
child 2289 44045ead61cd
permissions -rw-r--r--
Fixed build.

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