diff --git a/src/menu-vgui/ui_customgame.qc b/src/menu-vgui/ui_customgame.qc index 76a52f00..0e546da1 100644 --- a/src/menu-vgui/ui_customgame.qc +++ b/src/menu-vgui/ui_customgame.qc @@ -22,10 +22,14 @@ void UI_CustomGame_Show ( void ) static vguiList lsbGames; static vguiScrollBar scrlGames; static vguiButton btnLoad; + static vguiButton btnDisable; static void CustomGame_Play ( void ) { GameLibrary_Activate(lsbGames.GetSelected() + 1); } + static void CustomGame_Disable ( void ) { + GameLibrary_Activate( 0 ); + } static void CustomGame_ScrollUpdate ( void ) { scrlGames.SetValue( lsbGames.GetOffset() ); @@ -69,10 +73,23 @@ void UI_CustomGame_Show ( void ) btnLoad.SetSize([64,24]); btnLoad.SetFunc( CustomGame_Play ); + btnDisable = spawn( vguiButton ); + btnDisable.SetTitle( "Disable" ); + btnDisable.SetIcon( "gfx/icon16/control_stop" ); + btnDisable.SetPos( [8 + 80,132] ); + btnDisable.SetSize([64,24]); + btnDisable.SetFunc( CustomGame_Disable ); + + /* no reason to go back to the already running game */ + if (cvar_string("fs_game") == GAME_DIR) { + btnDisable.Hide(); + } + g_uiDesktop.Add( winCustomGame ); winCustomGame.Add( lsbGames ); winCustomGame.Add( scrlGames ); winCustomGame.Add( btnLoad ); + winCustomGame.Add( btnDisable ); } winCustomGame.Show(); diff --git a/src/menu-vgui/ui_findservers.qc b/src/menu-vgui/ui_findservers.qc index d0ad000e..bf0e8867 100644 --- a/src/menu-vgui/ui_findservers.qc +++ b/src/menu-vgui/ui_findservers.qc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,24 +14,301 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#warning Server-browser: Complete me. - -int g_iFindServersInitialized; +int g_iServerBrowserInitialized; void UI_FindServers_Show ( void ) { - static vguiWindow winFind; + static vguiWindow winServers; + static vguiList listTVGames; + static vguiList listLANGames; + static vguiList listInternetGames; + static vguiList listPastGames; + static vguiList listTVGamesID; + static vguiList listLANGamesID; + static vguiList listInternetGamesID; + static vguiList listPastGamesID; + static vguiButton btnUpdateList; + static vguiButton btnRefreshList; + static vguiButton btnConnect; - if ( !g_iFindServersInitialized ) { - g_iFindServersInitialized = TRUE; - winFind = spawn( vguiWindow ); - winFind.SetTitle( "Find Servers (NOT IMPLEMENTED)" ); - winFind.SetSize( '600 400' ); - winFind.SetIcon( "gfx/icon16/world" ); + static vguiButton tabInternetServers; + static vguiButton tabLANServers; + static vguiButton tabHistoricServers; + static vguiButton tabSpectateServers; - g_uiDesktop.Add( winFind ); + static vguiPic picMapShot; + static vguiLabel lblTitle; + static vguiLabel lblMap; + static vguiLabel lblPlayers; + static vguiLabel lblTimeLimit; + static vguiLabel lblPing; + static vguiList targetCategory; + static vguiList targetCategoryID; + + static void Servers_UpdateSpectateGames ( void ) { + int selectedEntry = listTVGames.GetSelected(); + int value = (int)stof(listTVGamesID.GetItem(selectedEntry)); + picMapShot.SetImage(Servers_GetInfo(value, SERVERGAME_MAP)); + picMapShot.SetSize( [232, 174] ); + lblTitle.SetTitle(strcat("Title: ", Servers_GetInfo(value, SERVERGAME_TITLE))); + lblMap.SetTitle(strcat("Map: ", Servers_GetInfo(value, SERVERGAME_MAP))); + lblPlayers.SetTitle(sprintf("Players: %i", Servers_GetInfo(value, SERVERGAME_PLAYERS))); + lblTimeLimit.SetTitle(sprintf("Player limit: %i", Servers_GetInfo(value, SERVERGAME_MAXPLAYERS))); + lblPing.SetTitle(sprintf("Ping: %i", Servers_GetInfo(value, SERVERGAME_PING))); + } + static void Servers_UpdateLANGames ( void ) { + int selectedEntry = listLANGames.GetSelected(); + int value = (int)stof(listLANGamesID.GetItem(selectedEntry)); + picMapShot.SetImage(Servers_GetInfo(value, SERVERGAME_MAP)); + picMapShot.SetSize( [232, 174] ); + lblTitle.SetTitle(strcat("Title: ", Servers_GetInfo(value, SERVERGAME_TITLE))); + lblMap.SetTitle(strcat("Map: ", Servers_GetInfo(value, SERVERGAME_MAP))); + lblPlayers.SetTitle(sprintf("Players: %i", Servers_GetInfo(value, SERVERGAME_PLAYERS))); + lblTimeLimit.SetTitle(sprintf("Player limit: %i", Servers_GetInfo(value, SERVERGAME_MAXPLAYERS))); + lblPing.SetTitle(sprintf("Ping: %i", Servers_GetInfo(value, SERVERGAME_PING))); + } + static void Servers_UpdateInternetGames ( void ) { + int selectedEntry = listInternetGames.GetSelected(); + int value = (int)stof(listInternetGamesID.GetItem(selectedEntry)); + picMapShot.SetImage(Servers_GetInfo(value, SERVERGAME_MAP)); + picMapShot.SetSize( [232, 174] ); + lblTitle.SetTitle(strcat("Title: ", Servers_GetInfo(value, SERVERGAME_TITLE))); + lblMap.SetTitle(strcat("Map: ", Servers_GetInfo(value, SERVERGAME_MAP))); + lblPlayers.SetTitle(sprintf("Players: %i", Servers_GetInfo(value, SERVERGAME_PLAYERS))); + lblTimeLimit.SetTitle(sprintf("Player limit: %i", Servers_GetInfo(value, SERVERGAME_MAXPLAYERS))); + lblPing.SetTitle(sprintf("Ping: %i", Servers_GetInfo(value, SERVERGAME_PING))); + } + static void Servers_UpdatePastGames ( void ) { + int selectedEntry = listPastGames.GetSelected(); + int value = (int)stof(listPastGamesID.GetItem(selectedEntry)); + picMapShot.SetImage(Servers_GetInfo(value, SERVERGAME_MAP)); + picMapShot.SetSize( [232, 174] ); + lblTitle.SetTitle(strcat("Title: ", Servers_GetInfo(value, SERVERGAME_TITLE))); + lblMap.SetTitle(strcat("Map: ", Servers_GetInfo(value, SERVERGAME_MAP))); + lblPlayers.SetTitle(sprintf("Players: %i", Servers_GetInfo(value, SERVERGAME_PLAYERS))); + lblTimeLimit.SetTitle(sprintf("Player limit: %i", Servers_GetInfo(value, SERVERGAME_MAXPLAYERS))); + lblPing.SetTitle(sprintf("Ping: %i", Servers_GetInfo(value, SERVERGAME_PING))); } - winFind.Show(); - winFind.SetPos( ( g_vidsize / 2 ) - ( winFind.GetSize() / 2 ) ); + static void Servers_Update ( void ) { + Master_UpdateCache(); + } + static void Servers_Connect ( void ) { + int selectedEntry = listInternetGames.GetSelected(); + localcmd(sprintf("connect %s\n", Servers_GetInfo(selectedEntry, SERVERGAME_ADDRESS))); + } + + static void Servers_ShowMaps(void) { + listTVGames.Hide(); + listLANGames.Hide(); + listPastGames.Hide(); + listInternetGames.Show(); + listInternetGames.SetSelected(0); + targetCategory = listInternetGames; + targetCategoryID = listInternetGamesID; + Servers_UpdateInternetGames(); + } + + static void Servers_ShowAddons(void) { + listTVGames.Hide(); + listLANGames.Hide(); + listInternetGames.Hide(); + listPastGames.Show(); + listPastGames.SetSelected(0); + targetCategory = listPastGames; + targetCategoryID = listPastGamesID; + Servers_UpdatePastGames(); + } + + static void Servers_ShowMods(void) { + listTVGames.Hide(); + listInternetGames.Hide(); + listPastGames.Hide(); + listLANGames.Show(); + listLANGames.SetSelected(0); + targetCategory = listLANGames; + targetCategoryID = listLANGamesID; + Servers_UpdateLANGames(); + } + + static void Servers_ShowPatches(void) { + listLANGames.Hide(); + listInternetGames.Hide(); + listPastGames.Hide(); + listTVGames.Show(); + listTVGames.SetSelected(0); + targetCategory = listTVGames; + Servers_UpdateSpectateGames(); + } + + static void Servers_FillList(void) { + int modCount = 0i; + int mapCount = 0i; + int addonCount = 0i; + int patchCount = 0i; + + for ( int i = 0; i < Master_GetTotalServers(); i++ ) { + patchCount++; + modCount++; + mapCount++; + addonCount++; + } + + listTVGames.SetItemCount( patchCount ); + listTVGamesID.SetItemCount( patchCount ); + listLANGames.SetItemCount( modCount ); + listLANGamesID.SetItemCount( modCount ); + listPastGames.SetItemCount( addonCount ); + listPastGamesID.SetItemCount( addonCount ); + listInternetGames.SetItemCount( mapCount ); + listInternetGamesID.SetItemCount( mapCount ); + + if (modCount) { + // tabLANServers.SetFunc( Servers_ShowMods ); + } + if (addonCount) { + //tabHistoricServers.SetFunc( Servers_ShowAddons ); + } + if (mapCount) { + tabInternetServers.SetFunc( Servers_ShowMaps ); + } + if (patchCount) { + //tabSpectateServers.SetFunc( Servers_ShowPatches ); + } + + for ( int i = 0; i < Master_GetTotalServers(); i++ ) { + listTVGames.AddItem( Servers_GetInfo(i, SERVERGAME_ADDRESS) ); + listTVGamesID.AddItem(sprintf("%i", i)); + listLANGames.AddItem( Servers_GetInfo(i, SERVERGAME_ADDRESS) ); + listLANGamesID.AddItem(sprintf("%i", i)); + listInternetGames.AddItem( Servers_GetInfo(i, SERVERGAME_ADDRESS) ); + listInternetGamesID.AddItem(sprintf("%i", i)); + listPastGames.AddItem( Servers_GetInfo(i, SERVERGAME_ADDRESS) ); + listPastGamesID.AddItem(sprintf("%i", i)); + + } + } + static void Servers_Refresh ( void ) { + Master_RefreshCache(); + Servers_FillList(); + } + + if ( !g_iServerBrowserInitialized ) { + g_iServerBrowserInitialized = TRUE; + winServers = spawn( vguiWindow ); + winServers.SetTitle( "Find Game" ); + winServers.SetSize( [480,360] ); + winServers.SetIcon( "gfx/icon16/world" ); + + tabInternetServers = spawn( vguiButton ); + tabInternetServers.SetTitle( "Internet" ); + tabInternetServers.SetIcon( "gfx/icon16/page_world" ); + tabInternetServers.SetPos( [8,32] ); + tabHistoricServers = spawn( vguiButton ); + tabHistoricServers.SetTitle( "History" ); + tabHistoricServers.SetIcon( "gfx/icon16/page_edit" ); + tabHistoricServers.SetPos( tabInternetServers.GetPos() + [tabInternetServers.GetWidth() + 8, 0] ); + tabLANServers = spawn( vguiButton ); + tabLANServers.SetTitle( "LAN" ); + tabLANServers.SetIcon( "gfx/icon16/page_lightning" ); + tabLANServers.SetPos( tabHistoricServers.GetPos() + [tabHistoricServers.GetWidth() + 8, 0] ); + tabSpectateServers = spawn( vguiButton ); + tabSpectateServers.SetTitle( "Spectate" ); + tabSpectateServers.SetIcon( "gfx/icon16/page_find" ); + tabSpectateServers.SetPos( tabLANServers.GetPos() + [tabLANServers.GetWidth() + 8, 0] ); + + listTVGames = spawn( vguiList ); + listTVGamesID = spawn( vguiList ); + listTVGames.SetSize( [192, 360-16-24-64] ); + listTVGames.SetPos( [8, 32+32] ); + listTVGames.CallOnSelectionChanged(Servers_UpdateSpectateGames); + + listInternetGames = spawn( vguiList ); + listInternetGamesID = spawn( vguiList ); + listInternetGames.SetSize( [192, 360-16-24-64] ); + listInternetGames.SetPos( [8, 32+32] ); + listInternetGames.CallOnSelectionChanged(Servers_UpdateInternetGames); + + listLANGames = spawn( vguiList ); + listLANGamesID = spawn( vguiList ); + listLANGames.SetSize( [192, 360-16-24-64] ); + listLANGames.SetPos( [8, 32+32] ); + listLANGames.CallOnSelectionChanged(Servers_UpdateLANGames); + + listPastGames = spawn( vguiList ); + listPastGamesID = spawn( vguiList ); + listPastGames.SetSize( [192, 360-16-24-64] ); + listPastGames.SetPos( [8, 32+32] ); + listPastGames.CallOnSelectionChanged(Servers_UpdatePastGames); + + btnConnect = spawn( vguiButton ); + btnConnect.SetTitle( "Connect" ); + btnConnect.SetIcon( "gfx/icon16/world_go" ); + btnConnect.SetPos( [480-80-8,360-24-8] ); + btnConnect.SetSize([80,24]); + btnConnect.SetFunc( Servers_Connect ); + + btnUpdateList = spawn( vguiButton ); + btnUpdateList.SetTitle( "Update" ); + btnUpdateList.SetIcon( "gfx/icon16/page_go" ); + btnUpdateList.SetPos( [8,360-24-8] ); + btnUpdateList.SetSize([80,24]); + btnUpdateList.SetFunc( Servers_Update ); + + btnRefreshList = spawn( vguiButton ); + btnRefreshList.SetTitle( "Refresh" ); + btnRefreshList.SetIcon( "gfx/icon16/page_refresh" ); + btnRefreshList.SetPos( btnUpdateList.GetPos() + [btnUpdateList.GetWidth() + 8, 0] ); + btnRefreshList.SetSize([80,24]); + btnRefreshList.SetFunc( Servers_Refresh ); + + picMapShot = spawn(vguiPic); + picMapShot.SetPos( [232, 64] ); + picMapShot.SetSize( [232, 174] ); + picMapShot.SetBorder(4); + + lblTitle = spawn(vguiLabel); + lblTitle.SetPos( picMapShot.GetPos() + [0, picMapShot.GetHeight() + 8] ); + lblTitle.SetSize( [232, 16] ); + + lblMap = spawn(vguiLabel); + lblMap.SetPos( lblTitle.GetPos() + [0, 16] ); + lblMap.SetSize( [232, 16] ); + + lblPlayers = spawn(vguiLabel); + lblPlayers.SetPos( lblMap.GetPos() + [0, 16] ); + lblPlayers.SetSize( [232, 16] ); + + lblTimeLimit = spawn(vguiLabel); + lblTimeLimit.SetPos( lblPlayers.GetPos() + [0, 16] ); + lblTimeLimit.SetSize( [232, 16] ); + + lblPing = spawn(vguiLabel); + lblPing.SetPos( lblTimeLimit.GetPos() + [0, 16] ); + lblPing.SetSize( [232, 16] ); + + g_uiDesktop.Add( winServers ); + winServers.Add( listTVGames ); + winServers.Add( listInternetGames ); + winServers.Add( listLANGames ); + winServers.Add( listPastGames ); + winServers.Add( btnConnect ); + winServers.Add( btnUpdateList ); + winServers.Add( btnRefreshList ); + winServers.Add( tabInternetServers ); + winServers.Add( tabHistoricServers ); + winServers.Add( tabLANServers ); + winServers.Add( tabSpectateServers ); + + winServers.Add( picMapShot ); + winServers.Add( lblTitle ); + winServers.Add( lblMap ); + winServers.Add( lblPlayers ); + winServers.Add( lblTimeLimit ); + winServers.Add( lblPing ); + Servers_ShowMaps(); + } + + winServers.Show(); + winServers.SetPos( ( g_vidsize / 2 ) - ( winServers.GetSize() / 2 ) ); } diff --git a/src/platform/defs.h b/src/platform/defs.h index 98aaf4e0..2075fa45 100644 --- a/src/platform/defs.h +++ b/src/platform/defs.h @@ -32,6 +32,7 @@ #include "saves.h" #include "fragnet.h" #include "map.h" +#include "servers.h" /** Definitions for FTE's internal package manager. We don't want you to talk to this one directly within Nuclide. */ typedef enum diff --git a/src/platform/gamelibrary.qc b/src/platform/gamelibrary.qc index ff3b7905..b383f4b0 100644 --- a/src/platform/gamelibrary.qc +++ b/src/platform/gamelibrary.qc @@ -461,12 +461,15 @@ GameLibrary_InitCustom(void) int c = 0i; string modPrefix = strcat(GAME_DIR, "-mod"); - gameinfo_count = 0i; + gameinfo_count = 1i; /* do not count the base game (0) */ /* first count let's all manually installed mods */ for (targetID = 0; (gamedirname = getgamedirinfo(targetID, 0)); targetID++) { + if (gamedirname == GAME_DIR) + continue; + gameinfo_count++; - //printf("MANUAL: %S\n", gamedirname); + printf("MANUAL: %S\n", gamedirname); } /* count the package installed mods after */ @@ -479,6 +482,8 @@ GameLibrary_InitCustom(void) if (prefix == modPrefix && installStatus == "enabled") { tokenizebyseparator(packageName, "-"); string gameDir = argv(2); + tokenizebyseparator(gameDir, "="); + gameDir = argv(0); /* check if this mod was installed manually already */ if (GameLibrary_CheckLocalPresence(gameDir) == true) { @@ -501,9 +506,15 @@ GameLibrary_InitCustom(void) return; } + c = 1i; /* set in case there's 0 local mods. */ + /* now loop through all the mods we found and load in the metadata */ - for (targetID = 1; targetID < gameinfo_count; targetID++) { + for (targetID = 0; targetID < gameinfo_count; targetID++) { gamedirname = getgamedirinfo(targetID, 0); + + if (gamedirname == GAME_DIR) + continue; + GameLibrary_SetDefaults(targetID, gamedirname); if (GameLibrary_CheckManifest(targetID, gamedirname) == true) { diff --git a/src/platform/includes.src b/src/platform/includes.src index 05560b71..4bad0af5 100644 --- a/src/platform/includes.src +++ b/src/platform/includes.src @@ -14,5 +14,6 @@ activitypub.qc saves.qc cmd.qc fragnet.qc +servers.qc init.qc #endlist diff --git a/src/platform/master.qc b/src/platform/master.qc index 907a06bf..3499fb3b 100644 --- a/src/platform/master.qc +++ b/src/platform/master.qc @@ -116,23 +116,6 @@ Master_RefreshCache(void) } } -void -Master_UpdateCache(void) -{ - NSLog("Updating host cache..."); - resethostcachemasks(); - sethostcachemaskstring(0, gethostcacheindexforkey("gamedir"), cvar_string("game"), SLIST_TEST_EQUAL); - sethostcachesort(gethostcacheindexforkey("ping"), FALSE); - refreshhostcache(TRUE); - resorthostcache(); - Master_RecountServers(); - int a = Master_GetLANServers() + Master_GetInternetServers(); - - if (a) { - NSLog("Master reports a total of %i servers.", a); - } -} - void Master_ResortCache(void) { @@ -148,6 +131,24 @@ Master_ResortCache(void) srv_fldPlayer0 = gethostcacheindexforkey("player"); } +void +Master_UpdateCache(void) +{ + NSLog("Updating host cache..."); + resethostcachemasks(); + sethostcachemaskstring(0, gethostcacheindexforkey("gamedir"), cvar_string("fs_game"), SLIST_TEST_EQUAL); + sethostcachesort(gethostcacheindexforkey("ping"), FALSE); + refreshhostcache(TRUE); + Master_ResortCache(); + Master_RecountServers(); + int a = Master_GetLANServers() + Master_GetInternetServers(); + + if (a) { + NSLog("Master reports a total of %i servers.", a); + } +} + + void Master_GetInternetList(void) { diff --git a/src/platform/servers.h b/src/platform/servers.h index a76437cc..7f897c41 100644 --- a/src/platform/servers.h +++ b/src/platform/servers.h @@ -1,15 +1,15 @@ -/** Options for querying Game Library entry information using `GameLibrary_GetInfo()` */ +/** Options for querying Game Library entry information using `Servers_GetInfo()` */ typedef enum { - SERVERGAME_TITLE, /**< (string) The title of the game. E.g. "Action Game" */ - SERVERGAME_ADDRESS, /**< (string) The game directory name. E.g. "data" */ - SERVERGAME_PING, /**< (int) The directory to be loaded before the game directory. */ - SERVERGAME_PLAYERS, /**< (int) The first game directory to be loaded. */ - SERVERGAME_MAXPLAYERS, /**< (int) The game its official website. */ - SERVERGAME_MAP, /**< (string) Version number string. */ - SERVERGAME_GAME, /**< (string) The size of the game, in bytes. */ + SERVERGAME_TITLE, /**< (string) The title of the server. E.g. "Action Game" */ + SERVERGAME_ADDRESS, /**< (string) The address. E.g. "128.0.0.1" */ + SERVERGAME_PING, /**< (int) Last ping value to the server. */ + SERVERGAME_PLAYERS, /**< (int) Player count. */ + SERVERGAME_MAXPLAYERS, /**< (int) Player slots. */ + SERVERGAME_MAP, /**< (string) Current map/level file. */ + SERVERGAME_GAME, /**< (string) Game directory. */ } serverGame_t; -/** Retrieves fields for a given game. See gameInfo_t for a list of fields you can query. */ +/** Retrieves fields for a given server. See serverGame_t for a list of fields you can query. */ __variant Servers_GetInfo(int, serverGame_t); diff --git a/src/platform/servers.qc b/src/platform/servers.qc index 2c717825..ffa05295 100644 --- a/src/platform/servers.qc +++ b/src/platform/servers.qc @@ -9,25 +9,25 @@ Servers_GetInfo(int serverID, serverGame_t infoType) switch (infoType) { case SERVERGAME_TITLE: - return (string)gethostcachestring(srv_fldName, i) + return (string)gethostcachestring(srv_fldName, serverID); break; case SERVERGAME_ADDRESS: - return (string)gethostcachestring(srv_fldAdress, i) + return (string)gethostcachestring(srv_fldAdress, serverID); break; case SERVERGAME_PING: - return (string)gethostcachestring(srv_fldPing, i) + return (int)gethostcachenumber(srv_fldPing, serverID); break; case SERVERGAME_PLAYERS: - return (string)gethostcachestring(srv_fldPlayers, i) + return (int)gethostcachenumber(srv_fldPlayers, serverID); break; case SERVERGAME_MAXPLAYERS: - return (string)gethostcachestring(srv_fldMaxplayers, i) + return (int)gethostcachenumber(srv_fldMaxplayers, serverID); break; case SERVERGAME_MAP: - return (string)gethostcachestring(srv_fldMap, i) + return (string)gethostcachestring(srv_fldMap, serverID); break; case SERVERGAME_GAME: - return (string)gethostcachestring(srv_fldGame, i) + return (string)gethostcachestring(srv_fldGame, serverID); break; default: return __NULL__;