1
0
KF2-Dev-Scripts/KFGame/Classes/KFGFxServerBrowser_ServerList.uc
2023-09-21 22:31:11 +03:00

1129 lines
35 KiB
Ucode

//=============================================================================
// KFGFxServerBrowser_ServerList
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// - Zane 8/19/2014
//=============================================================================
class KFGFxServerBrowser_ServerList extends KFGFxObject_Container
native(UI)
config(UI);
/** Reference to the search datastore. */
var transient KFDataStore_OnlineGameSearch SearchDataStore;
/** stores the password entered by the user when attempting to connect to a server with a password */
var private transient string ServerPassword;
/** True if we want to join as a spectator */
var private transient bool bJoinAsSpectator;
var protected transient const name SearchDSName;
/** Cached online subsystem pointer */
var transient OnlineSubsystem OnlineSub;
/** Cached game interface pointer */
var transient OnlineGameInterface GameInterface;
//A cache for the server list gfx object so we do not have to create them everytime we refresh or update the list
var array<GFxObject> GFxServerObjects;
/** Is an informative dialog about the server browser currently displayed. */
var private transient bool bQueryDialogShowing;
var private transient bool bIssuedInitialQuery;
var private GFxObject DataProvider;
var public int FakePlayerIndex;
var public int SelectedServerIndex;
var localized string LeaveServerBrowserString;
var localized string DetailsString;
var localized string SpectateString;
var KFGFxMenu_ServerBrowser ServerMenu;
var transient int FilteredCount;
/** Maximum number of server entries in the browser */
var globalconfig int MaxSearchResults;
var int lastServerCount;
/**
* Different actions to take when a query completes.
*/
var private transient enum EQueryCompletionAction
{
/** no query action set */
QUERYACTION_None,
/** do nothing when the query completes; default behavior */
QUERYACTION_Default,
/**
* This is set when the user wants to close the scene but we still have active queries. When the queries are completed
* (either through being canceled or receiving all results), close the scene.
*/
QUERYACTION_CloseScene,
/**
* This is set when the user has chosen a server from the list. When the queries are completed or cancelled, join the currently selected server.
*/
QUERYACTION_JoinServer,
/**
* This is set when the user switches from LAN to Internet or vice versa. When the queries are completed of cancelled, clear all results and reissue the
* current query.
*/
QUERYACTION_RefreshAll,
} QueryCompletionAction;
var private transient enum ESearch_Tab
{
TAB_ALL,
TAB_FAVORITES,
TAB_FRIENDS,
TAB_HISTORY,
TAB_LAN,
TAB_MAX,
} ECurrentSearchTab;
struct native ExtraServerInfo
{
var bool ServerHeardBackFrom;
var bool GameRunning;
var bool RequestDispatched;
var int StartTimer; // if game has not started, how many seconds until it does
var float Ping; // direct ping to the server from x-tra fetch
var int Survivors; // current player count
var int SurvivorsAvgLevel;
var int ZedPlayers; // current zed-players for vs servers
};
//equivalent to OnViewLoaded from UDK/Unreal Tournement 3
function Initialize( KFGFxObject_Menu NewParentMenu )
{
local DataStoreClient DSClient;
super.Initialize( NewParentMenu );
ServerMenu =KFGFxMenu_ServerBrowser(NewParentMenu);
LocalizeText();
DSClient = class'UIInteraction'.static.GetDataStoreClient();
if ( DSClient != None )
{
SearchDataStore = KFDataStore_OnlineGameSearch(DSClient.FindDataStore(SearchDSName));
}
OnlineSub = class'GameEngine'.static.GetOnlineSubsystem();
GameInterface = OnlineSub.GameInterface;
//OnViewActivated();
}
function OnViewActivated()
{
//ScriptTrace();
//local UIDataStore_Registry Registry;
//Registry = UIDataStore_Registry(class'UIRoot'.static.StaticResolveDataStore('Registry'));
// Default to LAN.
//Registry.SetData("LanClient", "1");
// Decide whether we're playing LAN or Online and set MatchType appropriately.
ValidateServerType();
// Push an initial query when the page is first activated.
if ( !bIssuedInitialQuery )
{
bIssuedInitialQuery = TRUE;
RefreshServerList(FakePlayerIndex);
}
// Update the list's data provider.
UpdateListDataProvider();
}
function SortServerResultsRequest(int ButtonIndex, int SortOrder)
{
local KFOnlineGameSearch LatestGameSearch;
LatestGameSearch = KFOnlineGameSearch(SearchDataStore.GetActiveGameSearch());
if(LatestGameSearch == none)
{
return;
}
LatestGameSearch.SortResults(ESortType(ButtonIndex), ESortOrder(SortOrder));
UpdateListDataProvider();
}
/**
* Enables / disables the "match type" control based on whether we are signed in online.
*/
function ValidateServerType()
{
local int PlayerIndex, PlayerControllerID;
local LocalPlayer LP;
// Don't worry about remote players
LP = LocalPlayer(GetPC().Player);
// don't have a link connection, or not allowed to play online, don't allow them to select one.
PlayerIndex = class'UIInteraction'.static.GetPlayerIndex(LP.ControllerID);
PlayerControllerID = class'UIInteraction'.static.GetPlayerControllerId( PlayerIndex );
if (!class'UIInteraction'.static.IsLoggedIn(PlayerControllerID, true))
{
`log("MUST BE LOGGED IN TO GET SEARCH RESULTS");
//FORCE A LAN SEARCH HERE. Attempting an online search here will crash the game if you are not signed into Steam ** IF WE SUPPORT IT **
}
}
function ChangeSearchType(ESteamMatchmakingType SearchType, optional bool bPreventNewSearch)
{
GameInterface.SetMatchmakingTypeMode(SearchType);
if(!bPreventNewSearch)
{
RefreshServerList(FakePlayerIndex);
}
}
function LocalizeText()
{
local GFxObject LocalizedObject;
LocalizedObject = CreateObject( "Object" );
LocalizedObject.SetString("players", ServerMenu.PlayersString);
LocalizedObject.SetString("name", ServerMenu.NameString);
LocalizedObject.SetString("mode", ServerMenu.GameModeString);
LocalizedObject.SetString("difficulty", ServerMenu.DifficultyString);
LocalizedObject.SetString("map", ServerMenu.MapString);
LocalizedObject.SetString("filters", ServerMenu.FiltersString);
LocalizedObject.SetString("search", ServerMenu.SearchString);
LocalizedObject.SetString("refresh", ServerMenu.RefreshString);
LocalizedObject.SetString("gamesFound", ServerMenu.GamesFoundString);
LocalizedObject.SetString("back", LeaveServerBrowserString );
LocalizedObject.SetString("details", DetailsString);
LocalizedObject.SetString("spectate", SpectateString);
LocalizedObject.SetString("join", ServerMenu.JoinString);
SetObject("localizedText", LocalizedObject);
}
function OnRefeshClick()
{
RefreshServerList(FakePlayerIndex);
}
function ClearGFXServerList()
{
local GFxObject TempArray;
TempArray = CreateArray();
SetObject("dataProvider", TempArray);
}
/** Refreshes the server list. */
function RefreshServerList(int InPlayerIndex)
{
local KFOnlineGameSearch GameSearch;
if(SearchDataStore == none) {
`log("Can't refresh server list without a Search DS!");
return;
}
ClearGFXServerList();
//This submits the server list query
CancelQuery(QUERYACTION_RefreshAll);
// Get current filter from the string list datastore
GameSearch = KFOnlineGameSearch(SearchDataStore.GetCurrentGameSearch());
// Set max results
if(ServerMenu.FiltersContainer.bLimitServerResults)
{
GameSearch.MaxSearchResults = Max(MaxSearchResults, 1);
}
else
{
GameSearch.MaxSearchResults = MaxInt;
}
}
function BuildServerFilters(KFGFxServerBrowser_Filters Filters, OnlineGameSearch Search)
{
local string GametagSearch;
local string MapName;
local int Mode, Difficulty, Length, WeeklySelectorIndex;
local bool DisableSeasonalSkins;
Search.ClearServerFilters();
Search.AddServerFilter("version_match", string(class'KFGameEngine'.static.GetKFGameVersion()));
Search.TestAddServerFilter( Filters.bNotFull, "notfull");
Search.TestAddServerFilter( Filters.bNotEmpty, "hasplayers");
Search.TestAddBoolGametagFilter(GametagSearch, Filters.bNoLocalAdmin, 'bServerExiled', 0);
DisableSeasonalSkins = Filters.bNoSeasonalSkins;
if (class'KFGameEngine'.static.GetSeasonalEventID() == SEI_None
|| class'KFGameEngine'.static.GetSeasonalEventID() == SEI_Spring)
{
DisableSeasonalSkins = false;
}
Search.TestAddBoolGametagFilter(GametagSearch, DisableSeasonalSkins, 'bNoSeasonalSkins', 1);
if( !class'WorldInfo'.static.IsConsoleBuild() )
{
Search.TestAddServerFilter( Filters.bDedicated, "dedicated");
if( !class'WorldInfo'.static.IsEOSBuild() )
{
Search.TestAddServerFilter( Filters.bVAC_Secure, "secure");
}
}
MapName = Filters.GetSelectedMap();
if (MapName != "")
{
Search.AddServerFilter( "map", MapName);
}
if (Filters.bInProgress && !Filters.bInLobby)
{
Search.TestAddBoolGametagFilter(GametagSearch, Filters.bInProgress, 'bInProgress', 1);
}
else if (Filters.bInLobby)
{
Search.TestAddBoolGametagFilter(GametagSearch, Filters.bInLobby, 'bInProgress', 0);
}
if( !class'WorldInfo'.static.IsConsoleBuild() )
{
Search.TestAddBoolGametagFilter(GametagSearch, Filters.bNoPassword, 'bRequiresPassword', 0);
}
Mode = Filters.SavedGameModeIndex;
if( Mode >= 0 && Mode < 255 )
{
Search.AddGametagFilter( GametagSearch, 'Mode', string(Mode) );
}
Difficulty = Filters.GetSelectedDifficulty();
if (Difficulty >= 0)
{
Search.AddGametagFilter(GametagSearch, 'Difficulty', string(Difficulty));
}
Length = Filters.GetSelectedGameLength();
if (Length >= 0)
{
Search.AddGametagFilter(GametagSearch, 'NumWaves', string(Length));
}
//`log("bCustom="$Filters.bCustom);
if(Filters.bCustom && !class'WorldInfo'.static.IsConsoleBuild() )
{
//`log("adding custom filter");
Search.TestAddBoolGametagFilter(GametagSearch, Filters.bCustom, 'bCustom', 0);
}
WeeklySelectorIndex = Filters.GetWeeklySelectorIndex();
if (Mode == 1 && WeeklySelectorIndex != 0) // // Only when mode is Weekly, 0 means "ANY", 1 is "DEFAULT", then the weeklies
{
WeeklySelectorIndex = WeeklySelectorIndex - 1; // move back to index range
Search.AddGametagFilter(GametagSearch, 'WeeklySelectorIndex', string(WeeklySelectorIndex));
}
if (Len(GametagSearch) > 0)
{
Search.AddServerFilter( "gametagsand", GametagSearch);
}
if (Search.MasterServerSearchKeys.length > 1)
{
Search.AddServerFilter( "and", string(Search.MasterServerSearchKeys.length), 0);
}
//@SABER_BEGIN - Saving the value for ping filter in server search parameters
if (class'WorldInfo'.static.IsEOSBuild())
{
Search.MaxPing = Filters.GetMaxPing();
}
//@SABER_END
}
/**
* Submits a query for the list of servers which match the current configuration.
*/
function SubmitServerListQuery( int PlayerIndex )
{
// ToDo delete
`log("SubmitServerListQuery called!");
//ScriptTrace();
BuildServerFilters(ServerMenu.FiltersContainer, SearchDataStore.GetCurrentGameSearch());
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEOSBuild())
{
class'GameEngine'.static.GetPlayfabInterface().AddFindOnlineGamesCompleteDelegate( OnFindOnlineGamesCompleteDelegate );
}
else
{
// Add a delegate for when the search completes. We will use this callback to do any post searching work.
GameInterface.AddFindOnlineGamesCompleteDelegate(OnFindOnlineGamesCompleteDelegate);
}
// Start a search
if ( !SearchDataStore.SubmitGameSearch(class'UIInteraction'.static.GetPlayerControllerId(PlayerIndex), false) )
{
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEOSBuild())
{
class'GameEngine'.static.GetPlayfabInterface().ClearFindOnlineGamesCompleteDelegate( OnFindOnlineGamesCompleteDelegate );
}
else
{
GameInterface.ClearFindOnlineGamesCompleteDelegate(OnFindOnlineGamesCompleteDelegate);
}
//Set Refreshing to false **UI of we want to show it**
SetRefreshingIndicator(false);
}
else
{
//We're starting a new search, create a new DataProvider array
FilteredCount = 0;
DataProvider = CreateArray();
SetRefreshingIndicator(true);
}
}
/**
* @return True if the entry was filtered, false if it wasn't
*/
native function bool FilterEntry(OnlineGameSearch Search, KFGFxServerBrowser_Filters filter, int entry);
/**
* Delegate fired each time a new server is received, or when the action completes (if there was an error)
*
* @param bWasSuccessful true if the async action completed without error, false if there was an error
*/
function OnFindOnlineGamesCompleteDelegate(bool bWasSuccessful)
{
local bool bSearchCompleted;
local OnlineGameSearch Search;
`log("OnFindOnlineGamesCompleteDelegate called!, bWasSuccessful is" @ bWasSuccessful);
Search = SearchDataStore.GetActiveGameSearch();
bSearchCompleted = Search == none || Search.Results.length == lastServerCount;
if ( !bSearchCompleted )
{
if ( Search.Results.length > 0 && (!ServerMenu.ApplyFilters || !FilterEntry(Search, ServerMenu.FiltersContainer, Search.Results.length-1)) )
{
`TimerHelper.SetTimer( 0.01, false, nameof(UpdateListDataProvider), self );
}
lastServerCount = Search.Results.length;
}
else
{
`log("OnFindOnlineGamesCompleteDelegate complete!");
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEOSBuild())
{
class'GameEngine'.static.GetPlayfabInterface().ClearFindOnlineGamesCompleteDelegate( OnFindOnlineGamesCompleteDelegate );
}
else
{
GameInterface.ClearFindOnlineGamesCompleteDelegate(OnFindOnlineGamesCompleteDelegate);
}
OnFindOnlineGamesComplete(bWasSuccessful);
lastServerCount = -1;
}
// update the enabled state of the button bar buttons
//UpdateButtonStates();
}
function OnClose()
{
`log("KFGFxServerBrowser_ServerList::OnClose called.");
//Make sure delegate isn't still set
CancelQuery(QUERYACTION_CloseScene);
ChangeSearchType(SMT_Internet, true);
KFGameEngine(Class'Engine'.static.GetEngine()).OnHandshakeComplete = None;
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEOSBuild())
{
class'GameEngine'.static.GetPlayfabInterface().ClearFindOnlineGamesCompleteDelegate( OnFindOnlineGamesCompleteDelegate );
class'GameEngine'.static.GetPlayfabInterface().ClearQueryServerInfoCompleteDelegate( OnQueryAdditionalServerInfoComplete );
if (class'WorldInfo'.static.IsEOSBuild()) {
class'GameEngine'.static.GetPlayfabInterface().ClearGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
}
}
else
{
GameInterface.ClearFindOnlineGamesCompleteDelegate(OnFindOnlineGamesCompleteDelegate);
GameInterface.ClearJoinOnlineGameCompleteDelegate(OnJoinGameComplete);
GameInterface.ClearCancelFindOnlineGamesCompleteDelegate(OnCancelSearchComplete);
GameInterface.ClearGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
}
}
function OnGetPlayerListComplete(OnlineGameSettings Settings, bool Success)
{
local int i;
if (SearchDataStore.GetCurrentGameSearch().Results[SelectedServerIndex].GameSettings != Settings)
{
`log("KFGFxServerBrowser_ServerList.OnGetPlayerListComplete got player list for unselected server",, 'DevOnline');
return;
}
if (class'WorldInfo'.static.IsEOSBuild()) {
class'GameEngine'.static.GetPlayfabInterface().ClearGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
} else {
GameInterface.ClearGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
}
if (Success)
{
ServerMenu.ServerDetailsContainer.UpdatePlayerList(Settings);
`log("***Server Browser got player list:");
for (i = 0; i < Settings.PlayersInGame.Length; ++i)
{
`log(i+1 $ ":" @ Settings.PlayersInGame[i].PlayerName);
}
`log("***End of player list");
}
else
{
`log("***Server didn't respond with player list!");
}
}
/**
* Delegate fired when the search for an online game has completed
*
* @param bWasSuccessful true if the async action completed without error, false if there was an error
*/
function OnFindOnlineGamesComplete(bool bWasSuccessful)
{
// ToDo delete
`log("OnFindOnlineGamesComplete called!");
SetRefreshingIndicator(false);
if ( QueryCompletionAction != QUERYACTION_None )
{
/*if ( bQueryDialogShowing )
{
MenuManager.PopView();
bQueryDialogShowing = false;
}
else
{*/
OnCancelSearchComplete(true);
//}
}
// refresh the list with the items from the currently selected gametype's cached query
}
/**
* Fires an asynchronous task to cancels all active queries.
*
* @param DesiredCancelAction specifies what should happen when the asynchronous task completes.
*/
function CancelQuery( optional EQueryCompletionAction DesiredCancelAction=QUERYACTION_Default )
{
// ToDo delete
`Log("CancelQuery called!");
if ( QueryCompletionAction == QUERYACTION_None )
{
QueryCompletionAction = DesiredCancelAction;
if ( SearchDataStore.GetActiveGameSearch() != none )
{
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEOSBuild())
{
class'GameEngine'.static.GetPlayfabInterface().CancelGameSearch();
OnCancelSearchComplete(true);
}
else
{
// we don't check for none so that we get warning in the log if GameInterface is none (this would be bad)
GameInterface.AddCancelFindOnlineGamesCompleteDelegate(OnCancelSearchComplete);
GameInterface.CancelFindOnlineGames();
}
}
else if ( SearchDataStore.GetCurrentGameSearch().Results.length > 0 || QueryCompletionAction == QUERYACTION_RefreshAll )
{
OnCancelSearchComplete(true);
}
// If no cancel delegate will get kicked off, reset the QueryCompletionAction value, or it gets stuck in 'cancelling' mode
else
{
QueryCompletionAction = QUERYACTION_None;
}
}
else
{
`log("Could not cancel query because query cancel already in progress:" @ GetEnum(enum'EQueryCompletionAction', QueryCompletionAction));
}
}
/**
* Handler for the 'cancel query' asynchronous task completion. Performs the actions dictated by the current QueryCompletionAction, as
* set when CancelQuery was called.
*/
function OnCancelSearchComplete( bool bWasSuccessful )
{
local EQueryCompletionAction CurrentAction;
GameInterface.ClearCancelFindOnlineGamesCompleteDelegate(OnCancelSearchComplete);
CurrentAction = QueryCompletionAction;
QueryCompletionAction = QUERYACTION_None;
SetRefreshingIndicator(false);
switch ( CurrentAction )
{
case QUERYACTION_CloseScene:
ClearSearchResults();
break;
case QUERYACTION_JoinServer:
JoinServer(SelectedServerIndex);
break;
case QUERYACTION_RefreshAll:
// if we're leaving the server browser area - clear all stored server query searches
ClearSearchResults();
// Refresh the server browser after our cancel query has completely finished
GetPC().SetTimer(0.25f, false, nameof(DelayedRefresh), self);
break;
default:
break;
}
}
/** If we've just cancelled our search, always delay the next search so the queries
* are not confused */
function DelayedRefresh()
{
SubmitServerListQuery(FakePlayerIndex);
}
function JoinServer(optional int SearchResultIndex = -1, optional string WithPassword = "", optional bool JoinAsSpectator = false)
{
local KFOnlineGameSettings ServerSettings;
local OnlineGameSearchResult SearchResult;
//ScriptTrace();
if( SearchResultIndex >= 0 && SearchResultIndex < SearchDataStore.GetCurrentGameSearch().Results.Length )
{
SearchResult = SearchDataStore.GetCurrentGameSearch().Results[SearchResultIndex];
} else
{
return;
// If the index is invalid, then we will assume its the query by ip result //leaving this in here because this is valid. Currently, OnlineGameSearch does not have this variable.
//SearchResult = SearchDataStore.GetCurrentGameSearch().QueryByIpResult;
}
// Store this in case we need it later
SelectedServerIndex = SearchResultIndex;
// Get the settings
ServerSettings = KFOnlineGameSettings(SearchResult.GameSettings);
if(ServerSettings == none)
{
return;
}
// Just try joining, password or other checks will come back before the travel
ServerPassword = WithPassword;
bJoinAsSpectator = JoinAsSpectator;
ProcessJoin(SearchResult);
}
private function ProcessJoin(OnlineGameSearchResult SearchResult)
{
// ToDo delete
`Log("ProcessJoin called!");
if ( GameInterface != None )
{
if (SearchResult.GameSettings != None)
{
if( (class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEOSBuild()) && !class'WorldInfo'.static.IsE3Build() )
{
// Make sure EOS game has GameSettings for crossplay needs.
if ((GameInterface.GetGameSettings('Game') == None) && class'WorldInfo'.static.IsEOSBuild())
{
GameInterface.JoinOnlineGame(0, 'Game', SearchResult);
}
class'GameEngine'.static.GetPlayfabInterface().AddSearchResultToHistory( SearchResult.GameSettings.JoinString );
class'GameEngine'.static.GetPlayfabInterface().AddQueryServerInfoCompleteDelegate( OnQueryAdditionalServerInfoComplete );
class'GameEngine'.static.GetPlayfabInterface().QueryServerInfo( SearchResult.GameSettings.LobbyId );
}
else
{
// Set the delegate for notification
GameInterface.AddJoinOnlineGameCompleteDelegate(OnJoinGameComplete);
if (OnlineGameInterfaceImpl(GameInterface).GetGameSearch() != none)
{
`log("Already have an online game session when trying to join an online game. Destroying it.",,'DevOnline');
//Despite dire warnings to the contrary, DestroyOnlineGame completes synchronously.
GameInterface.DestroyOnlineGame('Game');
}
// Start the async task
GameInterface.JoinOnlineGame(0, 'Game', SearchResult);
}
}
else
{
OnJoinGameComplete('Game', false);
}
}
else
{
ServerPassword = "";
bJoinAsSpectator = false;
}
}
function OnJoinGameComplete(name SessionName, bool bSuccessful)
{
local string URL;
// Figure out if we have an online subsystem registered
if (GameInterface != None)
{
if (bSuccessful)
{
// Get the platform specific information
if (GameInterface.GetResolvedConnectString(SessionName, URL))
{
KFGameViewportClient(LocalPlayer(GetPC().Player).ViewPortClient).LastConnectionAttemptAddress = URL;
`Log("- Join Game Successful, Traveling: " $ URL);
JoinGameURL();
}
}
// Remove the delegate from the list
GameInterface.ClearJoinOnlineGameCompleteDelegate(OnJoinGameComplete);
}
if( !bSuccessful )
{
if(GetServerDetails(SelectedServerIndex).bRequiresPassword)
{
ServerMenu.ShowPasswordPopup();
}
}
ServerPassword = "";
}
function OnQueryAdditionalServerInfoComplete( bool bWasSuccessful, string LobbyId, string ServerIp, int ServerPort, string ServerTicket )
{
local string OpenCommand;
`log("OnQueryAdditionalServerInfoComplete with success"@bWasSuccessful@"and lobbyID"@LobbyId@"and server IP"@ServerIp@"and port"@ServerPort);
class'GameEngine'.static.GetPlayfabInterface().ClearQueryServerInfoCompleteDelegate( OnQueryAdditionalServerInfoComplete );
if( !bWasSuccessful || ServerIp == "" )
{
// TODO: Popup?
`warn("Failed to connect to server for some reason");
}
else
{
OpenCommand = "open"@ServerIp$":"$ServerPort;
OpenCommand $= "?AuthTicket="$ServerTicket;
OpenCommand $= "?PlayfabPlayerId="$class'GameEngine'.static.GetPlayfabInterface().CachedPlayfabId;
if( bJoinAsSpectator )
{
OpenCommand $= "?SpectatorOnly=1";
}
if (class'WorldInfo'.static.IsEOSBuild() && ( ServerPassword != "" ))
{
OpenCommand $= "?Password=" $ ServerPassword;
}
KFGameEngine(Class'Engine'.static.GetEngine()).OnHandshakeComplete = OnHandshakeComplete;
`log("Going to connect with URL:"@OpenCommand);
ConsoleCommand( OpenCommand );
}
}
function bool OnHandshakeComplete(bool bSuccess, string Error, out int SuppressPasswordRetry)
{
KFGameEngine(Class'Engine'.static.GetEngine()).OnHandshakeComplete = None;
if (bSuccess)
{
OnlineSub.GetLobbyInterface().LobbyJoinServer(KFGameViewportClient(LocalPlayer(GetPC().Player).ViewPortClient).LastConnectionAttemptAddress);
}
SuppressPasswordRetry = 1;
`log("*******OnHandshakeComplete"@bSuccess@Error);
ScriptTrace();
return false;
}
private native function ServerConnect(string URL);
function JoinGameURL()
{
local string URL;
// Call the game specific function to appending/changing the URL
URL = BuildJoinURL();
KFGameEngine(Class'Engine'.static.GetEngine()).OnHandshakeComplete = OnHandshakeComplete;
//`log("join url:" @ URL);
// Get the resolved URL and build the part to start it
ServerConnect(URL);
ServerPassword = "";
}
function string BuildJoinURL()
{
local string ConnectURL;
ConnectURL = KFGameViewportClient(LocalPlayer(GetPC().Player).ViewPortClient).LastConnectionAttemptAddress;
if ( ServerPassword != "" )
{
ConnectURL $= "?Password=" $ ServerPassword;
OnlineSub.GetLobbyInterface().SetServerPassword(ServerPassword);
}
else
{
OnlineSub.GetLobbyInterface().SetServerPassword("");
}
if(bJoinAsSpectator)
{
ConnectURL $= "?SpectatorOnly=1";
}
ConnectURL $= OnlineSub.GetLobbyInterface().GetLobbyURLString();
//ConnectURL $= BuildJoinFiltersRequestURL();
return ConnectURL;
}
function string BuildJoinFiltersRequestURL()
{
local string FiltersURL;
local int GameDifficulty, WeeklySelectorIndex, IntendedWeeklyIndex;
GameDifficulty = ServerMenu.FiltersContainer.GetSelectedDifficulty();
if( ServerMenu.FiltersContainer.SavedGameModeIndex >= 0 )
{
FiltersURL $= "?Game="$class'KFGameInfo'.static.GetGameModeClassFromNum(ServerMenu.FiltersContainer.SavedGameModeIndex);
}
if( GameDifficulty >= 0)
{
FiltersURL $= "?Difficulty="$GameDifficulty;
}
if( ServerMenu.FiltersContainer.SavedLengthIndex >= 0 )
{
FiltersURL $= "?GameLength="$ServerMenu.FiltersContainer.SavedLengthIndex;
}
WeeklySelectorIndex = ServerMenu.FiltersContainer.SavedWeeklySelectorIndex;
if (ServerMenu.FiltersContainer.SavedGameModeIndex == 1
&& WeeklySelectorIndex != 0) // 0 means "ANY", 1 is "DEFAULT", then the weeklies
{
WeeklySelectorIndex = WeeklySelectorIndex - 1; // move back to index range
// IF index matches default, set to 0 (default)
if (WeeklySelectorIndex >= 1)
{
IntendedWeeklyIndex = class'KFGameEngine'.static.GetIntendedWeeklyEventIndexMod();
if (IntendedWeeklyIndex == (WeeklySelectorIndex - 1))
{
WeeklySelectorIndex = 0;
}
}
if (WeeklySelectorIndex >= 0)
{
FiltersURL $= "?WeeklySelectorIndex=" $WeeklySelectorIndex;
}
}
return FiltersURL;
}
function OnRefreshServerDetails()
{
local KFOnlineGameSearch GameSearch;
GameSearch = KFOnlineGameSearch(SearchDataStore.GetCurrentGameSearch());
if(GameSearch != none)
{
`log("Refeshing Server: " @GameSearch.Results[SelectedServerIndex].GameSettings.OwningPlayerName);
//send the once the server is refreshed, ServerDetailsContainer::SetDetails(KFOnlineGameSettings ServerResult);
}
}
function ClearSearchResults()
{
if(SearchDataStore != none)
{
SearchDataStore.ClearAllSearchResults();
}
}
function KFOnlineGameSettings GetServerDetails(int ServerIndex)
{
local KFOnlineGameSearch GameSearch;
local KFOnlineGameSettings KFOGS;
GameSearch = KFOnlineGameSearch(SearchDataStore.GetCurrentGameSearch());
if(GameSearch != none)
{
KFOGS = KFOnlineGameSettings(GameSearch.Results[ServerIndex].GameSettings);
}
return KFOGS;
}
function SetRefreshingIndicator(bool bRefreshing)
{
SetBool("refreshing", bRefreshing);
}
function OnServerSelected(int ServerIndex)
{
local bool success;
local PlayfabInterface PlayfabInter;
SelectedServerIndex = ServerIndex;
`log("***Attempting to get player list for server" @ SelectedServerIndex);
PlayfabInter = class'GameEngine'.static.GetPlayfabInterface();
if( class'WorldInfo'.static.IsEOSBuild() && PlayfabInter != none )
{
PlayfabInter.AddGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
success = SearchDataStore.FindServerPlayerList(SelectedServerIndex);
if (!success)
{
`log("***Failed to get player list for server" @ SelectedServerIndex);
PlayfabInter.ClearGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
}
} else {
GameInterface.AddGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
success = SearchDataStore.FindServerPlayerList(SelectedServerIndex);
if (!success)
{
`log("***Failed to get player list for server" @ SelectedServerIndex);
GameInterface.ClearGetPlayerListCompleteDelegate(OnGetPlayerListComplete);
}
}
}
//native function bool FilterEntry(KFOnlineGameSettings Settings);
function UpdateListDataProvider()
{
local int i, NewServerCount;
local GFxObject TempObj;
local KFOnlineGameSearch LatestGameSearch;
local int Ping, PlayerCount;
local KFOnlineGameSettings TempOnlineGamesSettings;
local KFWeeklyOutbreakInformation WeeklyInfo;
LatestGameSearch = KFOnlineGameSearch(SearchDataStore.GetActiveGameSearch());
if (LatestGameSearch != none && DataProvider != none )
{
for (i = 0; i < LatestGameSearch.Results.Length; i++)
{
if ( LatestGameSearch.Results[i].GameSettings.GfxId == INDEX_NONE || LatestGameSearch.Results[i].GameSettings.GfxId >= GFxServerObjects.length )
{
if ( NewServerCount > 10 )
{
// delay
`TimerHelper.SetTimer( 0.01, false, nameof(UpdateListDataProvider), self );
break;
}
TempOnlineGamesSettings = KFOnlineGameSettings(LatestGameSearch.Results[i].GameSettings);
if (class'WorldInfo'.static.IsEOSBuild() && i >= LatestGameSearch.MaxSearchResults)
{
break;
}
//@SABER_EGS_BEGIN - Add to the list only servers with measured ping
if (class'WorldInfo'.static.IsEOSBuild() && TempOnlineGamesSettings.PingInMs == -1) {
`TimerHelper.SetTimer( 0.1, false, nameof(UpdateListDataProvider), self );
break;
}
//@SABER_EGS_END
TempObj = CreateObject("Object");
TempObj.SetString("serverName", TempOnlineGamesSettings.OwningPlayerName);
PlayerCount = TempOnlineGamesSettings.NumPublicConnections-TempOnlineGamesSettings.NumOpenPublicConnections;
if (PlayerCount < 0)
{
PlayerCount = 0;
}
TempObj.SetFloat("playerCount", PlayerCount);
TempObj.SetFloat("maxPlayerCount", TempOnlineGamesSettings.NumPublicConnections);
TempObj.SetFloat("waveCount", TempOnlineGamesSettings.CurrentWave);
TempObj.SetFloat("maxWaveCount", IsEndlessModeIndex(TempOnlineGamesSettings.Mode) ? INDEX_NONE : TempOnlineGamesSettings.NumWaves);
TempObj.SetFloat("zedCount", TempOnlineGamesSettings.ZedCount);
TempObj.SetFloat("maxZedCount", TempOnlineGamesSettings.MaxZedCount);
TempObj.SetBool("vacEnable", TempOnlineGamesSettings.bAntiCheatProtected);
TempObj.SetBool("mutators", TempOnlineGamesSettings.bMutators);
TempObj.SetBool("bRanked", TempOnlineGamesSettings.bUsesStats);
TempObj.SetBool("bCustom", TempOnlineGamesSettings.bCustom);
Ping = TempOnlineGamesSettings.PingInMs;
TempObj.SetString("ping", (Ping < 0) ? ("-") : (String(Ping)) );
TempObj.SetString("difficulty", Class'KFCommon_LocalizedStrings'.static.GetDifficultyString(TempOnlineGamesSettings.difficulty));
TempObj.SetString("mode", class'KFCommon_LocalizedStrings'.static.GetGameModeString(TempOnlineGamesSettings.Mode));
// If weekly we show the icon of the weekly type
if (IsWeeklyModeIndex(TempOnlineGamesSettings.Mode))
{
if (TempOnlineGamesSettings.WeeklySelectorIndex > 0)
{
WeeklyInfo = class'KFMission_LocalizedStrings'.static.GetWeeklyOutbreakInfoByIndex(TempOnlineGamesSettings.WeeklySelectorIndex - 1);
}
else
{
WeeklyInfo = class'KFMission_LocalizedStrings'.static.GetCurrentWeeklyOutbreakInfo();
}
TempObj.SetString("weeklyType", "img://"$WeeklyInfo.IconPath);
}
TempObj.SetString("map", TempOnlineGamesSettings.MapName);
TempObj.SetBool("locked", TempOnlineGamesSettings.bRequiresPassword);
TempObj.SetBool("serverExiled", TempOnlineGamesSettings.bServerExiled);
//Get Game State from var const databinding EOnlineGameState GameState;
TempObj.SetString("gameStatus", String(TempOnlineGamesSettings.GameState));
GFxServerObjects.AddItem(TempObj);
TempOnlineGamesSettings.GfxId = GFxServerObjects.Length - 1;
NewServerCount++;
}
if ( LatestGameSearch.Results[i].GameSettings.ElementIdx != i )
{
DataProvider.SetElementObject(i, GFxServerObjects[LatestGameSearch.Results[i].GameSettings.GfxId]);
LatestGameSearch.Results[i].GameSettings.ElementIdx = i;
}
}
SetObject("dataProvider", DataProvider);
}
}
function bool IsWeeklyModeIndex(int ModeIndex)
{
return ModeIndex == 1;
}
function bool IsEndlessModeIndex(int ModeIndex)
{
return ModeIndex == 3;
}
function bool IsSelectedServerFavorited(int ServerSearchIndex)
{
local PlayfabInterface PlayfabInter;
local OnlineGameSearch LatestGameSearch;
PlayfabInter = class'GameEngine'.static.GetPlayfabInterface();
if( class'WorldInfo'.static.IsEOSBuild() && PlayfabInter != none )
{
LatestGameSearch = SearchDataStore.GetActiveGameSearch();
return PlayfabInter.IsSearchResultInFavoritesList(LatestGameSearch, ServerSearchIndex);
} else {
return GameInterface.IsSearchResultInFavoritesList(ServerSearchIndex);
}
}
function bool SetSelectedServerFavorited(bool bFavorited)
{
local PlayfabInterface PlayfabInter;
local OnlineGameSearch LatestGameSearch;
PlayfabInter = class'GameEngine'.static.GetPlayfabInterface();
if (bFavorited)
{
if( class'WorldInfo'.static.IsEOSBuild() && PlayfabInter != none )
{
LatestGameSearch = SearchDataStore.GetActiveGameSearch();
return PlayfabInter.AddSearchResultToFavorites(LatestGameSearch, SelectedServerIndex);
} else {
return GameInterface.AddSearchResultToFavorites(SelectedServerIndex);
}
}
else
{
if( class'WorldInfo'.static.IsEOSBuild() && PlayfabInter != none )
{
LatestGameSearch = SearchDataStore.GetActiveGameSearch();
return PlayfabInter.RemoveSearchResultFromFavorites(LatestGameSearch, SelectedServerIndex);
} else {
return GameInterface.RemoveSearchResultFromFavorites(SelectedServerIndex);
}
}
}
cpptext
{
inline UBOOL CheckFilters(const UKFOnlineGameSettings& settings, const UKFGFxServerBrowser_Filters& filter);
}
DefaultProperties
{
lastServerCount=-1
FakePlayerIndex=0
ServerPassword=""
SearchDSName=KFGameSearch
bIssuedInitialQuery=FALSE
bQueryDialogShowing=FALSE
SelectedServerIndex=-1
}