new game list code, detects steam accounts and dynamically shows you which games are under each one

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401729
This commit is contained in:
David Anderson 2007-11-25 18:03:59 +00:00
parent 61673e10f6
commit 8d6139ad5c
7 changed files with 493 additions and 328 deletions

View File

@ -5,6 +5,7 @@
#include "GamesList.h" #include "GamesList.h"
#include "SelectGame.h" #include "SelectGame.h"
game_group_t *g_game_group = NULL;
unsigned int method_chosen = 0; unsigned int method_chosen = 0;
TCHAR method_path[MAX_PATH]; TCHAR method_path[MAX_PATH];
@ -160,12 +161,32 @@ INT_PTR CALLBACK ChooseMethodHandler(HWND hDlg, UINT message, WPARAM wParam, LPA
if (game_type != 0) if (game_type != 0)
{ {
int reason; g_game_group = NULL;
if ((reason = FindGames(game_type)) < 1) BuildGameDB();
if (game_type == GAMES_DEDICATED)
{ {
DisplayBadGamesDialog(hDlg, game_type, reason); g_game_group = &g_games.dedicated;
break; }
else if (game_type == GAMES_LISTEN)
{
g_game_group = &g_games.listen;
}
else if (game_type == GAMES_STANDALONE)
{
g_game_group = &g_games.standalone;
}
if (g_game_group == NULL)
{
return (INT_PTR)TRUE;
}
if (g_game_group->list_count == 0)
{
DisplayBadGamesDialog(hDlg, g_game_group->error_code);
return (INT_PTR)TRUE;
} }
/* If we got a valid games list, we can display the next /* If we got a valid games list, we can display the next

View File

@ -2,7 +2,10 @@
#define _INCLUDE_INSTALLER_CHOOSE_METHOD_H_ #define _INCLUDE_INSTALLER_CHOOSE_METHOD_H_
#include "InstallerMain.h" #include "InstallerMain.h"
#include "GamesList.h"
void *DisplayChooseMethod(HWND hWnd); void *DisplayChooseMethod(HWND hWnd);
extern game_group_t *g_game_group;
#endif //_INCLUDE_INSTALLER_CHOOSE_METHOD_H_ #endif //_INCLUDE_INSTALLER_CHOOSE_METHOD_H_

View File

@ -3,8 +3,30 @@
#include "InstallerMain.h" #include "InstallerMain.h"
#include <stdio.h> #include <stdio.h>
mod_info_t *g_mod_list = NULL; game_database_t g_games =
unsigned int g_mod_count = 0; {
NULL, 0,
{NULL, 0, GAME_LIST_NO_GAMES},
{NULL, 0, GAME_LIST_NO_GAMES},
{NULL, 0, GAME_LIST_NO_GAMES}
};
valve_game_t valve_game_list[] =
{
{_T("counter-strike source"), _T("cstrike"), SOURCE_ENGINE_2004},
{_T("day of defeat source"), _T("dod"), SOURCE_ENGINE_2004},
{_T("half-life 2 deathmatch"), _T("hl2mp"), SOURCE_ENGINE_2004},
{_T("half-life deathmatch source"), _T("hl1mp"), SOURCE_ENGINE_2004},
{_T("team fortress 2"), _T("tf"), SOURCE_ENGINE_2007},
{NULL, NULL, 0},
};
valve_game_t valve_server_list[] =
{
{_T("source dedicated server"), NULL, SOURCE_ENGINE_2004},
{_T("source 2007 dedicated server"), NULL, SOURCE_ENGINE_2007},
{NULL, NULL, 0},
};
int IsValidFolder(const TCHAR *path) int IsValidFolder(const TCHAR *path)
{ {
@ -64,30 +86,80 @@ void DisplayBadFolderDialog(HWND hDlg, int reason)
MB_OK|MB_ICONWARNING); MB_OK|MB_ICONWARNING);
} }
void AddModToList(mod_info_t **mod_list, game_list_t *MakeGameList(const TCHAR *name)
unsigned int *total_mods,
const mod_info_t *mod_info)
{ {
mod_info_t *mods = *mod_list; game_list_t *gl = (game_list_t *)malloc(sizeof(game_list_t));
unsigned int total = *total_mods;
if (mods == NULL) UTIL_Format(gl->root_name,
sizeof(gl->root_name) / sizeof(TCHAR),
_T("%s"),
name);
gl->game_count = 0;
gl->games = NULL;
return gl;
}
void AttachGameListToGroup(game_group_t *group, game_list_t *gl)
{
if (group->lists == NULL)
{ {
mods = (mod_info_t *)malloc(sizeof(mod_info_t)); group->lists = (game_list_t **)malloc(sizeof(game_list_t *));
} }
else else
{ {
mods = (mod_info_t *)realloc(mods, sizeof(mod_info_t) * (total + 1)); group->lists = (game_list_t **)realloc(group->lists,
sizeof(game_list_t *) * (group->list_count + 1));
} }
memcpy(&mods[total], mod_info, sizeof(mod_info_t)); group->lists[group->list_count] = gl;
total++; group->list_count++;
*mod_list = mods;
*total_mods = total;
} }
void TryToAddMod(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigned *total_mods) void AttachModToGameList(game_list_t *gl, unsigned int mod_id)
{
if (gl->games == NULL)
{
gl->games = (unsigned int *)malloc(sizeof(unsigned int));
}
else
{
gl->games = (unsigned int *)realloc(gl->games,
sizeof(unsigned int) * (gl->game_count + 1));
}
gl->games[gl->game_count] = mod_id;
gl->game_count++;
}
unsigned int AddModToList(game_database_t *db, const game_info_t *mod_info)
{
/* Check if a matching game already exists */
for (unsigned int i = 0; i < db->game_count; i++)
{
if (tstrcasecmp(mod_info->game_path, db->game_list[i].game_path) == 0)
{
return i;
}
}
if (db->game_list == NULL)
{
db->game_list = (game_info_t *)malloc(sizeof(game_info_t));
}
else
{
db->game_list = (game_info_t *)realloc(db->game_list,
sizeof(game_info_t) * (db->game_count + 1));
}
memcpy(&db->game_list[db->game_count], mod_info, sizeof(game_info_t));
db->game_count++;
return db->game_count - 1;
}
bool TryToAddMod(const TCHAR *path, int eng_type, game_database_t *db, unsigned int *id)
{ {
FILE *fp; FILE *fp;
TCHAR gameinfo_path[MAX_PATH]; TCHAR gameinfo_path[MAX_PATH];
@ -99,7 +171,7 @@ void TryToAddMod(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigne
if ((fp = _tfopen(gameinfo_path, _T("rt"))) == NULL) if ((fp = _tfopen(gameinfo_path, _T("rt"))) == NULL)
{ {
return; return false;
} }
int pos; int pos;
@ -117,23 +189,41 @@ void TryToAddMod(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigne
} }
if (strcmp(key, "game") == 0) if (strcmp(key, "game") == 0)
{ {
mod_info_t mod; game_info_t mod;
unsigned int got_id;
AnsiToUnicode(value, mod.name, sizeof(mod.name)); AnsiToUnicode(value, mod.name, sizeof(mod.name));
UTIL_Format(mod.mod_path, sizeof(mod.mod_path), _T("%s"), path); UTIL_Format(mod.game_path, sizeof(mod.game_path), _T("%s"), path);
mod.source_engine = eng_type; mod.source_engine = eng_type;
AddModToList(mod_list, total_mods, &mod);
got_id = AddModToList(db, &mod);
if (id != NULL)
{
*id = got_id;
}
fclose(fp);
return true;
} }
} }
fclose(fp); fclose(fp);
return false;
} }
void AddModsFromFolder(const TCHAR *path, int eng_type, mod_info_t **mod_list, unsigned int *total_mods) void AddModsFromFolder(const TCHAR *path,
int eng_type,
game_database_t *db,
game_list_t *gl)
{ {
HANDLE hFind; HANDLE hFind;
WIN32_FIND_DATA fd; WIN32_FIND_DATA fd;
TCHAR temp_path[MAX_PATH]; TCHAR temp_path[MAX_PATH];
TCHAR search_path[MAX_PATH]; TCHAR search_path[MAX_PATH];
unsigned int mod_id;
UTIL_Format(search_path, UTIL_Format(search_path,
sizeof(search_path), sizeof(search_path),
@ -163,30 +253,60 @@ void AddModsFromFolder(const TCHAR *path, int eng_type, mod_info_t **mod_list, u
_T("%s\\%s"), _T("%s\\%s"),
path, path,
fd.cFileName); fd.cFileName);
TryToAddMod(temp_path, eng_type, mod_list, total_mods); if (TryToAddMod(temp_path, eng_type, db, &mod_id))
{
AttachModToGameList(gl, mod_id);
}
} while (FindNextFile(hFind, &fd)); } while (FindNextFile(hFind, &fd));
FindClose(hFind); FindClose(hFind);
} }
void AddValveModsFromFolder(const TCHAR *path, void GetSteamGames(game_database_t *db)
unsigned int game_type,
mod_info_t **mod_list,
unsigned int *total_mods)
{ {
HKEY hkPath;
DWORD dwLen, dwType;
HANDLE hFind; HANDLE hFind;
WIN32_FIND_DATA fd; WIN32_FIND_DATA fd;
TCHAR temp_path[MAX_PATH]; TCHAR temp_path[MAX_PATH];
TCHAR search_path[MAX_PATH]; TCHAR steam_path[MAX_PATH];
TCHAR steamapps_path[MAX_PATH];
UTIL_PathFormat(search_path, if (RegOpenKeyEx(HKEY_CURRENT_USER,
sizeof(search_path) / sizeof(TCHAR), _T("Software\\Valve\\Steam"),
_T("%s\\*.*"), 0,
path); KEY_READ,
&hkPath) != ERROR_SUCCESS)
if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
{ {
db->listen.error_code = GAME_LIST_CANT_READ;
db->dedicated.error_code = GAME_LIST_CANT_READ;
return;
}
dwLen = sizeof(steam_path) / sizeof(TCHAR);
if (RegQueryValueEx(hkPath,
_T("SteamPath"),
NULL,
&dwType,
(LPBYTE)steam_path,
&dwLen) != ERROR_SUCCESS)
{
RegCloseKey(hkPath);
db->listen.error_code = GAME_LIST_CANT_READ;
db->dedicated.error_code = GAME_LIST_CANT_READ;
return;
}
UTIL_PathFormat(steamapps_path,
sizeof(steamapps_path) / sizeof(TCHAR),
_T("%s\\steamapps\\*.*"),
steam_path);
if ((hFind = FindFirstFile(steamapps_path, &fd)) == INVALID_HANDLE_VALUE)
{
RegCloseKey(hkPath);
db->listen.error_code = GAME_LIST_CANT_READ;
db->dedicated.error_code = GAME_LIST_CANT_READ;
return; return;
} }
@ -203,263 +323,163 @@ void AddValveModsFromFolder(const TCHAR *path,
continue; continue;
} }
TCHAR *mod_folder = NULL; /* If we get a folder called "SourceMods," look for third party mods */
int eng_type = SOURCE_ENGINE_UNKNOWN; if (tstrcasecmp(fd.cFileName, _T("SourceMods")) == 0)
{
game_list_t *gl = MakeGameList(_T("Third-Party Games"));
if (game_type == GAMES_LISTEN)
{
if (tstrcasecmp(fd.cFileName, _T( "counter-strike source")) == 0)
{
mod_folder = _T("cstrike");
}
else if (tstrcasecmp(fd.cFileName, _T("day of defeat source")) == 0)
{
mod_folder = _T("dod");
}
else if (tstrcasecmp(fd.cFileName, _T("half-life 2 deathmatch")) == 0)
{
mod_folder = _T("hl2mp");
}
else if (tstrcasecmp(fd.cFileName, _T("half-life deathmatch source")) == 0)
{
mod_folder = _T("hl1mp");
}
else if (tstrcasecmp(fd.cFileName, _T("team fortress 2")) == 0)
{
mod_folder = _T("tf");
eng_type = SOURCE_ENGINE_2007;
}
}
else if (game_type == GAMES_DEDICATED)
{
if (tstrcasecmp(fd.cFileName, _T("source dedicated server")) == 0)
{
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\%s"),
path,
fd.cFileName);
AddModsFromFolder(temp_path, SOURCE_ENGINE_2004, mod_list, total_mods);
}
else if (tstrcasecmp(fd.cFileName, _T("source 2007 dedicated server")) == 0)
{
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\%s"),
path,
fd.cFileName);
AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, mod_list, total_mods);
}
}
if (mod_folder != NULL)
{
UTIL_PathFormat(temp_path, UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR), sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\%s\\%s"), _T("%s\\steamapps\\%s"),
path, steam_path,
fd.cFileName, fd.cFileName);
mod_folder);
TryToAddMod(temp_path, eng_type, mod_list, total_mods); AddModsFromFolder(temp_path, SOURCE_ENGINE_UNKNOWN, db, gl);
if (gl->game_count)
{
AttachGameListToGroup(&db->listen, gl);
}
else
{
free(gl);
}
}
else
{
/* Look for listenserver games */
game_list_t *gl = MakeGameList(fd.cFileName);
for (unsigned int i = 0; valve_game_list[i].folder != NULL; i++)
{
unsigned int mod_id;
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\steamapps\\%s\\%s\\%s"),
steam_path,
fd.cFileName,
valve_game_list[i].folder,
valve_game_list[i].subfolder);
if (TryToAddMod(temp_path, valve_game_list[i].eng_type, db, &mod_id))
{
AttachModToGameList(gl, mod_id);
}
}
if (gl->game_count)
{
AttachGameListToGroup(&db->listen, gl);
}
else
{
free(gl);
}
/* Look for dedicated games */
gl = MakeGameList(fd.cFileName);
for (unsigned int i = 0; valve_server_list[i].folder != NULL; i++)
{
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\steamapps\\%s\\%s"),
steam_path,
fd.cFileName,
valve_server_list[i].folder);
AddModsFromFolder(temp_path, valve_server_list[i].eng_type, db, gl);
}
if (gl->game_count)
{
AttachGameListToGroup(&db->dedicated, gl);
}
else
{
free(gl);
}
} }
} while (FindNextFile(hFind, &fd)); } while (FindNextFile(hFind, &fd));
FindClose(hFind); FindClose(hFind);
RegCloseKey(hkPath);
} }
int BuildGameList(unsigned int game_type, mod_info_t **mod_list) void GetStandaloneGames(game_database_t *db)
{ {
unsigned int total_mods = 0; HKEY hkPath;
DWORD dwLen, dwType, dwAttr;
TCHAR temp_path[MAX_PATH];
TCHAR hlds_path[MAX_PATH];
game_list_t *games_standalone;
if (game_type == GAMES_LISTEN if (RegOpenKeyEx(HKEY_CURRENT_USER,
|| game_type == GAMES_DEDICATED) _T("Software\\Valve\\HLServer"),
{ 0,
HKEY hkPath; KEY_READ,
DWORD dwLen, dwType; &hkPath) != ERROR_SUCCESS)
HANDLE hFind;
WIN32_FIND_DATA fd;
TCHAR temp_path[MAX_PATH];
TCHAR steam_path[MAX_PATH];
TCHAR steamapps_path[MAX_PATH];
if (RegOpenKeyEx(HKEY_CURRENT_USER,
_T("Software\\Valve\\Steam"),
0,
KEY_READ,
&hkPath) != ERROR_SUCCESS)
{
DWORD err = GetLastError();
return GAME_LIST_CANT_READ;
}
dwLen = sizeof(steam_path) / sizeof(TCHAR);
if (RegQueryValueEx(hkPath,
_T("SteamPath"),
NULL,
&dwType,
(LPBYTE)steam_path,
&dwLen) != ERROR_SUCCESS)
{
RegCloseKey(hkPath);
return GAME_LIST_CANT_READ;
}
UTIL_PathFormat(steamapps_path,
sizeof(steamapps_path) / sizeof(TCHAR),
_T("%s\\steamapps\\*.*"),
steam_path);
if ((hFind = FindFirstFile(steamapps_path, &fd)) == INVALID_HANDLE_VALUE)
{
RegCloseKey(hkPath);
return GAME_LIST_CANT_READ;
}
do
{
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
{
continue;
}
if (tstrcasecmp(fd.cFileName, _T(".")) == 0
|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
{
continue;
}
/* If we get a folder called "SourceMods," look for third party mods */
if (game_type == GAMES_LISTEN
&& tstrcasecmp(fd.cFileName, _T("SourceMods")) == 0)
{
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\steamapps\\%s"),
steam_path,
fd.cFileName);
AddModsFromFolder(temp_path, SOURCE_ENGINE_UNKNOWN, mod_list, &total_mods);
}
else
{
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\steamapps\\%s"),
steam_path,
fd.cFileName);
AddValveModsFromFolder(temp_path, game_type, mod_list, &total_mods);
}
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
RegCloseKey(hkPath);
}
else if (game_type == GAMES_STANDALONE)
{
HKEY hkPath;
int eng_type = SOURCE_ENGINE_UNKNOWN;
DWORD dwLen, dwType, dwAttr;
TCHAR temp_path[MAX_PATH];
TCHAR hlds_path[MAX_PATH];
if (RegOpenKeyEx(HKEY_CURRENT_USER,
_T("Software\\Valve\\HLServer"),
0,
KEY_READ,
&hkPath) != ERROR_SUCCESS)
{
return GAME_LIST_CANT_READ;
}
dwLen = sizeof(hlds_path) / sizeof(TCHAR);
if (RegQueryValueEx(hkPath,
_T("InstallPath"),
NULL,
&dwType,
(LPBYTE)hlds_path,
&dwLen) != ERROR_SUCCESS)
{
RegCloseKey(hkPath);
return GAME_LIST_CANT_READ;
}
/* Make sure there is a "srcds.exe" file */
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\srcds.exe"),
hlds_path);
dwAttr = GetFileAttributes(temp_path);
if (dwAttr == INVALID_FILE_ATTRIBUTES)
{
return GAME_LIST_HALFLIFE1;
}
/* If there is an "orangebox" sub folder, we can make a better guess
* at the engine state.
*/
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\orangebox"),
hlds_path);
dwAttr = GetFileAttributes(temp_path);
if (dwAttr != INVALID_FILE_ATTRIBUTES
&& ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
{
eng_type = SOURCE_ENGINE_2004;
AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, mod_list, &total_mods);
}
/* Add everything from the server */
AddModsFromFolder(hlds_path, eng_type, mod_list, &total_mods);
RegCloseKey(hkPath);
}
return (g_mod_list == NULL) ? GAME_LIST_NO_GAMES : (int)total_mods;
}
void FreeGameList(mod_info_t *mod_list)
{
free(mod_list);
}
int _SortModList(const void *item1, const void *item2)
{
const mod_info_t *mod1 = (const mod_info_t *)item1;
const mod_info_t *mod2 = (const mod_info_t *)item2;
return tstrcasecmp(mod1->name, mod2->name);
}
int FindGames(unsigned int game_type)
{
int reason;
ReleaseGamesList();
if ((reason = BuildGameList(game_type, &g_mod_list)) > 0)
{
g_mod_count = (unsigned)reason;
qsort(g_mod_list, g_mod_count, sizeof(mod_info_t), _SortModList);
}
return reason;
}
void ReleaseGamesList()
{
if (g_mod_list == NULL)
{ {
db->standalone.error_code = GAME_LIST_CANT_READ;
return; return;
} }
free(g_mod_list); dwLen = sizeof(hlds_path) / sizeof(TCHAR);
g_mod_list = NULL; if (RegQueryValueEx(hkPath,
g_mod_count = 0; _T("InstallPath"),
NULL,
&dwType,
(LPBYTE)hlds_path,
&dwLen) != ERROR_SUCCESS)
{
RegCloseKey(hkPath);
db->standalone.error_code = GAME_LIST_CANT_READ;
return;
}
/* Make sure there is a "srcds.exe" file */
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\srcds.exe"),
hlds_path);
dwAttr = GetFileAttributes(temp_path);
if (dwAttr == INVALID_FILE_ATTRIBUTES)
{
db->standalone.error_code = GAME_LIST_HALFLIFE1;
return;
}
games_standalone = MakeGameList(_T("Standalone"));
/* If there is an "orangebox" sub folder, we can make a better guess
* at the engine state.
*/
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\orangebox"),
hlds_path);
dwAttr = GetFileAttributes(temp_path);
if (dwAttr != INVALID_FILE_ATTRIBUTES
&& ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
{
AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, db, games_standalone);
}
/* Add everything from the server */
AddModsFromFolder(hlds_path, SOURCE_ENGINE_2004, db, games_standalone);
if (games_standalone->game_count)
{
AttachGameListToGroup(&db->standalone, games_standalone);
}
else
{
free(games_standalone);
}
RegCloseKey(hkPath);
} }
void DisplayBadGamesDialog(HWND hWnd, unsigned int game_type, int reason) void DisplayBadGamesDialog(HWND hWnd, int reason)
{ {
TCHAR message[256]; TCHAR message[256];
UINT idc = 0; UINT idc = 0;
@ -494,3 +514,61 @@ void DisplayBadGamesDialog(HWND hWnd, unsigned int game_type, int reason)
_T("SourceMod Installer"), _T("SourceMod Installer"),
MB_OK|MB_ICONWARNING); MB_OK|MB_ICONWARNING);
} }
int _ModIdCompare(const void *item1, const void *item2)
{
unsigned int mod_id1 = *(unsigned int *)item1;
unsigned int mod_id2 = *(unsigned int *)item2;
return tstrcasecmp(g_games.game_list[mod_id1].name, g_games.game_list[mod_id2].name);
}
int _GroupCompare(const void *item1, const void *item2)
{
game_list_t *g1 = *(game_list_t **)item1;
game_list_t *g2 = *(game_list_t **)item2;
return tstrcasecmp(g1->root_name, g2->root_name);
}
void SortGameGroup(game_group_t *group)
{
qsort(group->lists, group->list_count, sizeof(game_list_t *), _GroupCompare);
for (unsigned int i = 0; i < group->list_count; i++)
{
qsort(group->lists[i]->games,
group->lists[i]->game_count,
sizeof(unsigned int),
_ModIdCompare);
}
}
void BuildGameDB()
{
ReleaseGameDB();
GetStandaloneGames(&g_games);
GetSteamGames(&g_games);
SortGameGroup(&g_games.dedicated);
SortGameGroup(&g_games.listen);
SortGameGroup(&g_games.standalone);
}
void ReleaseGameGroup(game_group_t *group)
{
for (unsigned int i = 0; i < group->list_count; i++)
{
free(group->lists[i]->games);
free(group->lists[i]);
}
free(group->lists);
}
void ReleaseGameDB()
{
ReleaseGameGroup(&g_games.dedicated);
ReleaseGameGroup(&g_games.listen);
ReleaseGameGroup(&g_games.standalone);
free(g_games.game_list);
memset(&g_games, 0, sizeof(g_games));
}

View File

@ -19,21 +19,54 @@
#define SOURCE_ENGINE_2004 1 #define SOURCE_ENGINE_2004 1
#define SOURCE_ENGINE_2007 2 #define SOURCE_ENGINE_2007 2
struct mod_info_t struct valve_game_t
{
const TCHAR *folder;
const TCHAR *subfolder;
int eng_type;
};
/* One game */
struct game_info_t
{ {
TCHAR name[128]; TCHAR name[128];
TCHAR mod_path[MAX_PATH]; TCHAR game_path[MAX_PATH];
int source_engine; int source_engine;
}; };
/* A list of games under one "account" */
struct game_list_t
{
TCHAR root_name[128];
unsigned int *games;
unsigned int game_count;
};
/* A list of accounts */
struct game_group_t
{
game_list_t **lists;
unsigned int list_count;
int error_code;
};
/* All games on the system */
struct game_database_t
{
game_info_t *game_list;
unsigned int game_count;
game_group_t dedicated;
game_group_t listen;
game_group_t standalone;
};
int IsValidFolder(const TCHAR *path); int IsValidFolder(const TCHAR *path);
void DisplayBadFolderDialog(HWND hWnd, int reason); void DisplayBadFolderDialog(HWND hWnd, int reason);
int FindGames(unsigned int game_type); void BuildGameDB();
void DisplayBadGamesDialog(HWND hWnd, unsigned int game_type, int reason); void ReleaseGameDB();
void ReleaseGamesList(); void DisplayBadGamesDialog(HWND hWnd, int reason);
extern mod_info_t *g_mod_list; extern game_database_t g_games;
extern unsigned int g_mod_count;
#endif //_INCLUDE_INSTALLER_GAMES_LIST_H_ #endif //_INCLUDE_INSTALLER_GAMES_LIST_H_

View File

@ -44,6 +44,8 @@
#define ID_INSTALL_CANCEL 1019 #define ID_INSTALL_CANCEL 1019
#define IDC_INSTALL_PANEL 1020 #define IDC_INSTALL_PANEL 1020
#define IDC_INSTALL_TEXT 1021 #define IDC_INSTALL_TEXT 1021
#define IDC_COMBO3 1021
#define IDC_SELGROUP_ACCOUNT 1021
#define ID_INSTALL_START 1022 #define ID_INSTALL_START 1022
#define IDC_PROGRESS_CURCOPY 1023 #define IDC_PROGRESS_CURCOPY 1023
#define IDC_STATIC -1 #define IDC_STATIC -1
@ -57,7 +59,7 @@
#define _APS_NO_MFC 1 #define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 133 #define _APS_NEXT_RESOURCE_VALUE 133
#define _APS_NEXT_COMMAND_VALUE 32771 #define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1012 #define _APS_NEXT_CONTROL_VALUE 1022
#define _APS_NEXT_SYMED_VALUE 110 #define _APS_NEXT_SYMED_VALUE 110
#endif #endif
#endif #endif

View File

@ -7,50 +7,56 @@
#include "LocalCopyMethod.h" #include "LocalCopyMethod.h"
int selected_game_index = -1; int selected_game_index = -1;
mod_info_t **game_sel_list = NULL;
unsigned int game_sel_count = 0;
void AppendSelectableGame(mod_info_t *mod) void UpdateGameListBox(HWND hDlg, game_list_t *gl)
{ {
if (game_sel_list == NULL) HWND lbox = GetDlgItem(hDlg, IDC_SELGAME_LIST);
SendMessage(lbox, LB_RESETCONTENT, 0, 0);
for (unsigned int i = 0; i < gl->game_count; i++)
{ {
game_sel_list = LRESULT res = SendMessage(lbox,
(mod_info_t **)malloc(sizeof(mod_info_t *) * (game_sel_count + 1)); LB_ADDSTRING,
} 0,
else (LPARAM)g_games.game_list[gl->games[i]].name);
{
game_sel_list = if (res == LB_ERR || res == LB_ERRSPACE)
(mod_info_t **)realloc(game_sel_list, {
sizeof(mod_info_t *) * (game_sel_count + 1)); continue;
}
SendMessage(lbox, LB_SETITEMDATA, i, gl->games[i]);
} }
game_sel_list[game_sel_count++] = mod; UpdateWindow(lbox);
} }
#include "windowsx.h"
INT_PTR CALLBACK ChooseGameHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) INT_PTR CALLBACK ChooseGameHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
switch (message) switch (message)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
{ {
HWND lbox = GetDlgItem(hDlg, IDC_SELGAME_LIST); HWND cbox = GetDlgItem(hDlg, IDC_SELGROUP_ACCOUNT);
SendMessage(cbox, CB_RESETCONTENT, 0, 0);
for (unsigned int i = 0; i < g_mod_count; i++) for (unsigned int i = 0; i < g_game_group->list_count; i++)
{ {
LRESULT res = SendMessage(lbox, LRESULT res = SendMessage(cbox,
LB_ADDSTRING, CB_ADDSTRING,
0, 0,
(LPARAM)g_mod_list[i].name); (LPARAM)g_game_group->lists[i]->root_name);
if (res == CB_ERR || res == CB_ERRSPACE)
if (res == LB_ERR || res == LB_ERRSPACE)
{ {
continue; continue;
} }
SendMessage(cbox, CB_SETITEMDATA, i, (LPARAM)g_game_group->lists[i]);
AppendSelectableGame(&g_mod_list[i]);
} }
SendMessage(cbox, CB_SETCURSEL, 0, 0);
UpdateWindow(lbox); UpdateWindow(cbox);
UpdateGameListBox(hDlg, g_game_group->lists[0]);
SetToGlobalPosition(hDlg); SetToGlobalPosition(hDlg);
@ -69,6 +75,29 @@ INT_PTR CALLBACK ChooseGameHandler(HWND hDlg, UINT message, WPARAM wParam, LPARA
EndDialog(hDlg, (INT_PTR)DisplayChooseMethod); EndDialog(hDlg, (INT_PTR)DisplayChooseMethod);
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
else if (LOWORD(wParam) == IDC_SELGROUP_ACCOUNT)
{
if (HIWORD(wParam) == CBN_SELCHANGE)
{
HWND cbox = (HWND)lParam;
LRESULT cursel = SendMessage(cbox, CB_GETCURSEL, 0, 0);
if (cursel == LB_ERR)
{
break;
}
LRESULT data = SendMessage(cbox, CB_GETITEMDATA, cursel, 0);
if (data == CB_ERR)
{
break;
}
game_list_t *gl = (game_list_t *)data;
UpdateGameListBox(hDlg, gl);
}
break;
}
else if (LOWORD(wParam) == IDC_SELGAME_LIST) else if (LOWORD(wParam) == IDC_SELGAME_LIST)
{ {
if (HIWORD(wParam) == LBN_SELCHANGE) if (HIWORD(wParam) == LBN_SELCHANGE)
@ -83,12 +112,13 @@ INT_PTR CALLBACK ChooseGameHandler(HWND hDlg, UINT message, WPARAM wParam, LPARA
break; break;
} }
if (cursel >= (LRESULT)g_mod_count) LRESULT item = SendMessage(lbox, LB_GETITEMDATA, cursel, 0);
if (item == LB_ERR)
{ {
break; break;
} }
selected_game_index = (int)cursel; selected_game_index = (int)item;
HWND button = GetDlgItem(hDlg, ID_SELGAME_NEXT); HWND button = GetDlgItem(hDlg, ID_SELGAME_NEXT);
EnableWindow(button, TRUE); EnableWindow(button, TRUE);
@ -101,7 +131,7 @@ INT_PTR CALLBACK ChooseGameHandler(HWND hDlg, UINT message, WPARAM wParam, LPARA
break; break;
} }
g_LocalCopier.SetOutputPath(game_sel_list[selected_game_index]->mod_path); g_LocalCopier.SetOutputPath(g_games.game_list[selected_game_index].game_path);
SetInstallMethod(&g_LocalCopier); SetInstallMethod(&g_LocalCopier);
UpdateGlobalPosition(hDlg); UpdateGlobalPosition(hDlg);
@ -113,10 +143,7 @@ INT_PTR CALLBACK ChooseGameHandler(HWND hDlg, UINT message, WPARAM wParam, LPARA
} }
case WM_DESTROY: case WM_DESTROY:
{ {
ReleaseGamesList(); ReleaseGameDB();
free(game_sel_list);
game_sel_list = NULL;
game_sel_count = 0;
break; break;
} }
} }

View File

@ -99,18 +99,19 @@ BEGIN
CONTROL "Upload via FTP",IDC_METHOD_UPLOAD_FTP,"Button",BS_AUTORADIOBUTTON,21,82,94,16 CONTROL "Upload via FTP",IDC_METHOD_UPLOAD_FTP,"Button",BS_AUTORADIOBUTTON,21,82,94,16
END END
IDD_SELECT_GAME DIALOGEX 0, 0, 244, 130 IDD_SELECT_GAME DIALOGEX 0, 0, 244, 148
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW EXSTYLE WS_EX_APPWINDOW
CAPTION "SourceMod Installer" CAPTION "SourceMod Installer"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
PUSHBUTTON "&Next",ID_SELGAME_NEXT,191,113,50,14,WS_DISABLED PUSHBUTTON "&Next",ID_SELGAME_NEXT,191,131,50,14,WS_DISABLED
PUSHBUTTON "E&xit",ID_SELGAME_EXIT,2,113,50,14 PUSHBUTTON "E&xit",ID_SELGAME_EXIT,2,131,50,14
GROUPBOX "",IDC_SELGAME_PANEL,2,3,239,108 GROUPBOX "",IDC_SELGAME_PANEL,2,3,239,126
DEFPUSHBUTTON "&Back",ID_SELGAME_BACK,136,113,50,14 DEFPUSHBUTTON "&Back",ID_SELGAME_BACK,136,131,50,14
LTEXT "Please select a game:",IDC_SELGAME_TEXT,9,15,122,12 LTEXT "Please select a game from the list below. If there are multiple accounts, you may select one from the combo-box.",IDC_SELGAME_TEXT,7,14,221,16
LISTBOX IDC_SELGAME_LIST,17,30,199,69,LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP LISTBOX IDC_SELGAME_LIST,17,46,199,76,LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SELGROUP_ACCOUNT,17,32,133,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END END
IDD_PERFORM_INSTALL DIALOGEX 0, 0, 243, 116 IDD_PERFORM_INSTALL DIALOGEX 0, 0, 243, 116