From 3e5a445f746f66ecb2a4729eec3cc0766523534e Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Mon, 3 Apr 2023 21:50:21 -0230 Subject: [PATCH 01/50] Unlock all create class slots and sets --- data/ui_scripts/cac_options/__init__.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 data/ui_scripts/cac_options/__init__.lua diff --git a/data/ui_scripts/cac_options/__init__.lua b/data/ui_scripts/cac_options/__init__.lua new file mode 100644 index 00000000..8079e04d --- /dev/null +++ b/data/ui_scripts/cac_options/__init__.lua @@ -0,0 +1,21 @@ +Dvar.purchasedClassSetCount:set( 10 ) + +Engine.GetCustomClassCount = function( arg0 ) + return 10 +end + +Engine.GetNumberOfClassSetsOwned = function( arg0 ) + return 10 +end + +Engine.IsClassSetsAvailableForCurrentGameMode = function() + return true +end + +function IsClassSetsAvailableForCurrentGameMode() + return Engine.IsClassSetsAvailableForCurrentGameMode() +end + +function DoesPlayerHaveExtraSlotsItem( arg0 ) + return true +end From 0323addc8760b968b5137bdc1161929d2b478f09 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 15:16:45 -0230 Subject: [PATCH 02/50] Added util methods - Remove button from pre-existing menu - Remove all spaces from menu - Get index of button --- data/ui_scripts/frontend_menus/utils.lua | 27 +++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/data/ui_scripts/frontend_menus/utils.lua b/data/ui_scripts/frontend_menus/utils.lua index d8190895..78b18d65 100644 --- a/data/ui_scripts/frontend_menus/utils.lua +++ b/data/ui_scripts/frontend_menus/utils.lua @@ -16,6 +16,28 @@ local SetButtonState = function(button, state) end end +local RemoveButton = function(buttonTable, button) + for id, v in pairs(buttonTable) do + if buttonTable[id].optionDisplay == button.stringRef then + table.remove(buttonTable,id) + end + end +end + +local RemoveSpaces = function(buttonTable) + for id, v in pairs(buttonTable) do + buttonTable[id].isLastButtonInGroup = false + end +end + +local GetButtonIndex = function(buttonTable, button) + for id, v in pairs(buttonTable) do + if buttonTable[id].optionDisplay == button.stringRef then + return id + end + end +end + local AddButton = function(controller, options, button, isLargeButton, index) if button == nil then return @@ -125,5 +147,8 @@ return { AddButton = AddButton, AddLargeButton = AddLargeButton, AddSmallButton = AddSmallButton, - AddSpacer = AddSpacer + AddSpacer = AddSpacer, + RemoveButton = RemoveButton, + RemoveSpaces = RemoveSpaces, + GetButtonIndex = GetButtonIndex } From 7ccefacd3f49c64939bdfdef6a7ebf46c6115776 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 15:55:30 -0230 Subject: [PATCH 03/50] Rename Buttons Public Match -> Play Find Game -> Combat Training --- data/ui_scripts/frontend_menus/__init__.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 836045e8..6c23d9fc 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -4,6 +4,19 @@ end local utils = require("utils") +CoD.LobbyButtons.MP_PUBLIC_MATCH = { + stringRef = "MENU_PLAY_CAPS", + action = NavigateToLobby_SelectionList, + param = "MPLobbyOnline", + customId = "btnPublicMatch", +} + +CoD.LobbyButtons.MP_FIND_MATCH = { + stringRef = "MPUI_BASICTRAINING_CAPS", + action = OpenFindMatch, + customId = "btnFindMatch", +} + CoD.LobbyButtons.MP_STATS = { stringRef = "STATS", action = function(self, element, controller, param, menu) From 87f19d4937229bdf69e455173b99d116d5c73bbe Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:34:04 -0230 Subject: [PATCH 04/50] Enable Barracks menu with mods loaded --- .../DataSources_StartMenuTabs.lua | 217 ++++++++++++++++++ data/ui_scripts/frontend_menus/__init__.lua | 1 + 2 files changed, 218 insertions(+) create mode 100644 data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua diff --git a/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua b/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua new file mode 100644 index 00000000..2a07cb6a --- /dev/null +++ b/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua @@ -0,0 +1,217 @@ +DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", function ( f44_arg0 ) + local f44_local0 = {} + table.insert( f44_local0, { + models = { + tabIcon = CoD.buttonStrings.shoulderl + }, + properties = { + m_mouseDisabled = true + } + } ) + if Engine.IsDemoPlaying() then + local f44_local1 = "CoD.StartMenu_GameOptions" + if Engine.IsZombiesGame() then + f44_local1 = "CoD.StartMenu_GameOptions_ZM" + end + table.insert( f44_local0, { + models = { + tabName = Engine.Localize( "MENU_THEATER_CAPS" ), + tabWidget = f44_local1, + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + } ) + elseif Engine.IsInGame() then + if IsGameTypeDOA() and not InSafehouse() then + table.insert( f44_local0, { + models = { + tabName = "DOA", + tabWidget = "CoD.StartMenu_GameOptions_DOA", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + } ) + elseif CoD.isCampaign then + table.insert( f44_local0, { + models = { + tabName = SessionModeToUnlocalizedSessionModeCaps( Engine.CurrentSessionMode() ), + tabWidget = "CoD.StartMenu_GameOptions_CP", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + } ) + if not Engine.IsCampaignModeZombies() then + if CoD.isSafehouse and CoD.isOnlineGame() and not IsInTrainingSim( f44_arg0 ) and Dvar.ui_safehousebarracks:get() and not IsPlayerAGuest( f44_arg0 ) then + table.insert( f44_local0, { + models = { + tabName = "CPUI_BARRACKS_CAPS", + tabWidget = "CoD.CombatRecordCP_Contents", + tabIcon = "" + }, + properties = { + tabId = "combatRecord" + } + } ) + end + if HighestMapReachedGreaterThan( f44_arg0, 1 ) or LUI.DEV ~= nil then + table.insert( f44_local0, { + models = { + tabName = "CPUI_TACTICAL_MODE_CAPS", + tabWidget = "CoD.StartMenu_TacticalMode", + tabIcon = "" + }, + properties = { + tabId = "tacticalMode" + } + } ) + end + if not CoD.isSafehouse and not IsPlayerAGuest( f44_arg0 ) then + table.insert( f44_local0, { + models = { + tabName = "CPUI_ACCOLADES", + tabWidget = "CoD.MissionRecordVault_Challenges", + tabIcon = "" + }, + properties = { + tabId = "accolades" + } + } ) + end + end + elseif Engine.IsZombiesGame() then + table.insert( f44_local0, { + models = { + tabName = SessionModeToUnlocalizedSessionModeCaps( Engine.CurrentSessionMode() ), + tabWidget = "CoD.StartMenu_GameOptions_ZM", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + } ) + else + table.insert( f44_local0, { + models = { + tabName = SessionModeToUnlocalizedSessionModeCaps( Engine.CurrentSessionMode() ), + tabWidget = "CoD.StartMenu_GameOptions", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + } ) + end + else + if not IsPlayerAGuest( f44_arg0 ) then + table.insert( f44_local0, { + models = { + tabName = "MENU_TAB_IDENTITY_CAPS", + tabWidget = "CoD.StartMenu_Identity", + tabIcon = "" + }, + properties = { + tabId = "identity", + disabled = Dvar.ui_execdemo_gamescom:get() + } + } ) + end + if not IsLobbyNetworkModeLAN() and not Dvar.ui_execdemo:get() and not Engine.IsCampaignModeZombies() and not IsPlayerAGuest( f44_arg0 ) then + table.insert( f44_local0, { + models = { + tabName = "MENU_TAB_CHALLENGES_CAPS", + tabWidget = "CoD.StartMenu_Challenges", + tabIcon = "" + }, + properties = { + tabId = "challenges" + } + } ) + local f44_local1 = CoD.isPC + if f44_local1 then + f44_local1 = false --Mods_IsUsingMods() + end + table.insert( f44_local0, { + models = { + tabName = "MENU_TAB_BARRACKS_CAPS", + tabWidget = "CoD.StartMenu_Barracks", + tabIcon = "", + disabled = f44_local1 + }, + properties = { + tabId = "barracks" + } + } ) + if CommunityOptionsEnabled() then + local f44_local2 = CoD.perController[f44_arg0].openMediaTabAfterClosingGroups + CoD.perController[f44_arg0].openMediaTabAfterClosingGroups = false + table.insert( f44_local0, { + models = { + tabName = "MENU_TAB_MEDIA_CAPS", + tabWidget = "CoD.StartMenu_Media", + tabIcon = "" + }, + properties = { + tabId = "media", + selectIndex = f44_local2 + } + } ) + end + end + end + if IsGameTypeDOA() and Engine.IsInGame() and not InSafehouse() then + local f44_local1 = table.insert + local f44_local2 = f44_local0 + local f44_local3 = { + models = { + tabName = "MENU_TAB_OPTIONS_CAPS", + tabWidget = "CoD.StartMenu_Options_DOA", + tabIcon = "" + } + } + local f44_local4 = { + tabId = "options" + } + local f44_local5 = Dvar.ui_execdemo:get() + if f44_local5 then + f44_local5 = not Engine.IsInGame() + end + f44_local4.selectIndex = f44_local5 + f44_local3.properties = f44_local4 + f44_local1( f44_local2, f44_local3 ) + else + local f44_local1 = table.insert + local f44_local2 = f44_local0 + local f44_local3 = { + models = { + tabName = "MENU_TAB_OPTIONS_CAPS", + tabWidget = "CoD.StartMenu_Options", + tabIcon = "" + } + } + local f44_local4 = { + tabId = "options" + } + local f44_local5 = Dvar.ui_execdemo_gamescom:get() + if f44_local5 then + f44_local5 = not Engine.IsInGame() + end + f44_local4.selectIndex = f44_local5 + f44_local3.properties = f44_local4 + f44_local1( f44_local2, f44_local3 ) + end + table.insert( f44_local0, { + models = { + tabIcon = CoD.buttonStrings.shoulderr + }, + properties = { + m_mouseDisabled = true + } + } ) + return f44_local0 +end, true ) \ No newline at end of file diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 6c23d9fc..1b2d3abe 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -3,6 +3,7 @@ if Engine.GetCurrentMap() ~= "core_frontend" then end local utils = require("utils") +require("DataSources_StartMenuTabs") CoD.LobbyButtons.MP_PUBLIC_MATCH = { stringRef = "MENU_PLAY_CAPS", From 6668869b7de5bee2c7ad7c6cc6bfa337617b02c4 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:44:59 -0230 Subject: [PATCH 05/50] Fix Mapvote resetting lobby - sets the map then wait for player to start game - correctly sets the voted map --- data/ui_scripts/frontend_menus/__init__.lua | 19 ++++++++++++------- data/ui_scripts/playlist/__init__.lua | 10 ++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 data/ui_scripts/playlist/__init__.lua diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 1b2d3abe..169d50ab 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -2,6 +2,8 @@ if Engine.GetCurrentMap() ~= "core_frontend" then return end +local EnableLobbyMapVote = true -- toggle map vote in public lobby + local utils = require("utils") require("DataSources_StartMenuTabs") @@ -51,7 +53,13 @@ CoD.LobbyButtons.MP_CUSTOM_SETUP_GAME = { customId = "btnSetupGame", } -local shouldShowMapVote = false +local LobbyMapVoteIsEnabled = EnableLobbyMapVote +local LobbyMapVote = function( LobbyMapVoteIsEnabled ) + if LobbyMapVoteIsEnabled == true then + Engine.Exec( nil, "LobbyStopDemo" ) + end +end + local addCustomButtons = function(controller, menuId, buttonTable, isLeader) if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then utils.AddSpacer(buttonTable) @@ -63,13 +71,10 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) end if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id then - shouldShowMapVote = true + LobbyMapVoteIsEnabled = EnableLobbyMapVote elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEPUBLICGAME.id then - if shouldShowMapVote == true then - shouldShowMapVote = false - --Enable map vote at start lobby - Engine.Exec(nil, "LobbyStopDemo") - end + LobbyMapVote( LobbyMapVoteIsEnabled ) + LobbyMapVoteIsEnabled = false utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) --Launch match button utils.AddSpacer(buttonTable, 1) diff --git a/data/ui_scripts/playlist/__init__.lua b/data/ui_scripts/playlist/__init__.lua new file mode 100644 index 00000000..091a726c --- /dev/null +++ b/data/ui_scripts/playlist/__init__.lua @@ -0,0 +1,10 @@ +if Engine.GetCurrentMap() ~= "core_frontend" then + return +end + +Engine.SetDvar( "lobbyMigrate_Enabled", 0 ) +Engine.SetDvar( "lobbyTimerStatusVotingInterval", 11000 ) +Engine.SetDvar( "lobbyTimerStatusBeginInterval", 10 ) +Engine.SetDvar( "lobbyTimerStatusStartInterval", 10 ) +Engine.SetDvar( "lobbyTimerStatusPostGameInterval", 10 ) +Engine.SetDvar( "lobbyTimerStatusVotingInterval_Arena", 11000 ) From 72a52b6755daf740965e860f966caf3a531bf43e Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:49:56 -0230 Subject: [PATCH 06/50] Added custom "Setup Game" menu --- .../DataSources_GameSettingsFlyoutButtons.lua | 194 ++++++++++++++++++ data/ui_scripts/frontend_menus/__init__.lua | 19 ++ 2 files changed, 213 insertions(+) create mode 100644 data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua diff --git a/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua b/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua new file mode 100644 index 00000000..1df436ff --- /dev/null +++ b/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua @@ -0,0 +1,194 @@ +DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup( "GameSettingsFlyoutButtonsCustom", function ( f7_arg0 ) + local f7_local0 = { + { + optionDisplay = "MPUI_CHANGE_MAP_CAPS", + customId = "btnChangeMap", + action = OpenChangeMap + }, + -- { + -- optionDisplay = "MPUI_CHANGE_GAME_MODE_CAPS", + -- customId = "btnChangeGameMode", + -- action = OpenChangeGameMode + -- }, + { + optionDisplay = "MENU_SETUP_BOTS_CAPS", + customId = "btnSetupBots", + action = OpenBotSettings + }, + { + optionDisplay = "MPUI_EDIT_GAME_RULES_CAPS", + customId = "btnEditGameRules", + action = OpenEditGameRules + } + } + -- if CoD.isPC and IsServerBrowserEnabled() then + -- table.insert( f7_local0, { + -- optionDisplay = "PLATFORM_SERVER_SETTINGS_CAPS", + -- customID = "btnServerSettings", + -- action = OpenServerSettings + -- } ) + -- end + local f7_local1 = {} + for f7_local5, f7_local6 in ipairs( f7_local0 ) do + table.insert( f7_local1, { + models = { + displayText = Engine.Localize( f7_local6.optionDisplay ), + customId = f7_local6.customId, + disabled = f7_local6.disabled + }, + properties = { + title = f7_local6.optionDisplay, + desc = f7_local6.desc, + action = f7_local6.action, + actionParam = f7_local6.actionParam + } + } ) + end + return f7_local1 +end, nil, nil, nil ) + +LUI.createMenu.GameSettingsFlyoutMPCustom = function ( controller ) + local self = CoD.Menu.NewForUIEditor( "GameSettingsFlyoutMPCustom" ) + if PreLoadFunc then + PreLoadFunc( self, controller ) + end + self.soundSet = "default" + self:setOwner( controller ) + self:setLeftRight( true, true, 0, 0 ) + self:setTopBottom( true, true, 0, 0 ) + self:playSound( "menu_open", controller ) + self.buttonModel = Engine.CreateModel( Engine.GetModelForController( controller ), "GameSettingsFlyoutMP.buttonPrompts" ) + self.anyChildUsesUpdateState = true + + local Options = LUI.UIList.new( self, controller, -2, 0, nil, false, false, 0, 0, false, false ) + Options:makeFocusable() + Options:setLeftRight( true, false, 243.43, 523.43 ) + Options:setTopBottom( true, false, 177.56, 329.56 ) + Options:setYRot( 25 ) + Options:setWidgetType( CoD.FE_List1ButtonLarge_PH ) + Options:setVerticalCount( 5 ) + Options:setSpacing( -2 ) + Options:setDataSource( "GameSettingsFlyoutButtonsCustom" ) + Options:registerEventHandler( "gain_focus", function ( element, event ) + local f9_local0 = nil + if element.gainFocus then + f9_local0 = element:gainFocus( event ) + elseif element.super.gainFocus then + f9_local0 = element.super:gainFocus( event ) + end + CoD.Menu.UpdateButtonShownState( element, self, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS ) + return f9_local0 + end ) + Options:registerEventHandler( "lose_focus", function ( element, event ) + local f10_local0 = nil + if element.loseFocus then + f10_local0 = element:loseFocus( event ) + elseif element.super.loseFocus then + f10_local0 = element.super:loseFocus( event ) + end + return f10_local0 + end ) + self:AddButtonCallbackFunction( Options, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "ENTER", function ( element, menu, controller, model ) + ProcessListAction( self, element, controller ) + return true + end, function ( element, menu, controller ) + CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "MENU_SELECT" ) + return true + end, false ) + self:addElement( Options ) + self.Options = Options + + self:mergeStateConditions( { + { + stateName = "Local", + condition = function ( menu, element, event ) + return IsLobbyNetworkModeLAN() + end + } + } ) + self:subscribeToModel( Engine.GetModel( Engine.GetGlobalModel(), "lobbyRoot.lobbyNetworkMode" ), function ( model ) + local f14_local0 = self + local f14_local1 = { + controller = controller, + name = "model_validation", + modelValue = Engine.GetModelValue( model ), + modelName = "lobbyRoot.lobbyNetworkMode" + } + CoD.Menu.UpdateButtonShownState( f14_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE ) + end ) + self:subscribeToModel( Engine.GetModel( Engine.GetGlobalModel(), "lobbyRoot.lobbyNav" ), function ( model ) + local f15_local0 = self + local f15_local1 = { + controller = controller, + name = "model_validation", + modelValue = Engine.GetModelValue( model ), + modelName = "lobbyRoot.lobbyNav" + } + CoD.Menu.UpdateButtonShownState( f15_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE ) + end ) + self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil, function ( element, menu, controller, model ) + GoBack( self, controller ) + ClearMenuSavedState( menu ) + return true + end, function ( element, menu, controller ) + CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, "" ) + return false + end, false ) + self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_START, "M", function ( element, menu, controller, model ) + GoBackAndOpenOverlayOnParent( self, "StartMenu_Main", controller ) + return true + end, function ( element, menu, controller ) + CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_START, "MENU_MENU" ) + return true + end, false ) + self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "S", function ( element, menu, controller, model ) + if not IsLAN() and not IsPlayerAGuest( controller ) and IsPlayerAllowedToPlayOnline( controller ) then + GoBackAndOpenOverlayOnParent( self, "Social_Main", controller ) + return true + else + + end + end, function ( element, menu, controller ) + if not IsLAN() and not IsPlayerAGuest( controller ) and IsPlayerAllowedToPlayOnline( controller ) then + CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "" ) + return false + else + return false + end + end, false ) + self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_LB, nil, function ( element, menu, controller, model ) + SendButtonPressToOccludedMenu( menu, controller, model, Enum.LUIButton.LUI_KEY_LB ) + return true + end, function ( element, menu, controller ) + CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_LB, "" ) + return false + end, false ) + self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_RB, nil, function ( element, menu, controller, model ) + SendButtonPressToOccludedMenu( menu, controller, model, Enum.LUIButton.LUI_KEY_RB ) + return true + end, function ( element, menu, controller ) + CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_RB, "" ) + return false + end, false ) + Options.id = "Options" + self:processEvent( { + name = "menu_loaded", + controller = controller + } ) + self:processEvent( { + name = "update_state", + menu = self + } ) + if not self:restoreState() then + self.Options:processEvent( { + name = "gain_focus", + controller = controller + } ) + end + LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) + element.Options:close() + Engine.UnsubscribeAndFreeModel( Engine.GetModel( Engine.GetModelForController( controller ), "GameSettingsFlyoutMP.buttonPrompts" ) ) + end ) + return self +end + diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 169d50ab..cf9e8568 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -6,6 +6,7 @@ local EnableLobbyMapVote = true -- toggle map vote in public lobby local utils = require("utils") require("DataSources_StartMenuTabs") +require("DataSources_GameSettingsFlyoutButtons") CoD.LobbyButtons.MP_PUBLIC_MATCH = { stringRef = "MENU_PLAY_CAPS", @@ -47,6 +48,24 @@ CoD.LobbyButtons.SETTING_UP_BOTS = { customId = "btnSettingUpBots" } +CoD.LobbyButtons.GameSettingsFlyoutArenas = { + stringRef = "MPUI_SETUP_GAME_CAPS", + action = function( self, element, controller, param, menu ) + SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) + OpenPopup( menu, "GameSettingsFlyoutMP", controller ) + end, + customId = "btnGameSettingsFlyoutMP" +} + +CoD.LobbyButtons.GameSettingsFlyoutMP = { + stringRef = "MPUI_SETUP_GAME_CAPS", + action = function( self, element, controller, param, menu ) + SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) + OpenPopup( menu, "GameSettingsFlyoutMPCustom", controller ) + end, + customId = "btnGameSettingsFlyoutMPCustom" +} + CoD.LobbyButtons.MP_CUSTOM_SETUP_GAME = { stringRef = "MPUI_SETUP_GAME_CAPS", action = OpenSetupGameMP, From 157efd9213f446db105deed72e33ff58a4d2c4f7 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:54:24 -0230 Subject: [PATCH 07/50] Fix custom maps bug showing white block in MP - now searches usermaps folder for folders prefixed with "mp_" --- .../DataSources_ChangeMapCategories.lua | 98 +++++++++++++++++++ data/ui_scripts/frontend_menus/__init__.lua | 1 + 2 files changed, 99 insertions(+) create mode 100644 data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua diff --git a/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua b/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua new file mode 100644 index 00000000..9e25f646 --- /dev/null +++ b/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua @@ -0,0 +1,98 @@ +local f0_local0 = function ( f1_arg0, f1_arg1 ) + if not CoD.useMouse then + return + else + LUI.OverrideFunction_CallOriginalFirst( f1_arg0, "setState", function ( element, controller ) + if IsSelfInState( f1_arg0, "SelectingMap" ) then + f1_arg0.mapList:setMouseDisabled( false ) + f1_arg0.mapCategoriesList:setMouseDisabled( true ) + f1_arg0.m_categorySet = false + else + f1_arg0.mapList:setMouseDisabled( true ) + f1_arg0.mapCategoriesList:setMouseDisabled( false ) + end + end ) + f1_arg0.mapList:setMouseDisabled( true ) + f1_arg0.mapList:registerEventHandler( "leftclick_outside", function ( element, event ) + if IsSelfInState( f1_arg0, "SelectingMap" ) and f1_arg0.m_categorySet then + CoD.PCUtil.SimulateButtonPress( f1_arg1, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE ) + end + f1_arg0.m_categorySet = true + return true + end ) + end +end + +local PostLoadFunc = function ( f4_arg0, f4_arg1 ) + f0_local0( f4_arg0, f4_arg1 ) +end + +local f0_local2 = 10000 +local f0_local3 = 10001 +local f0_local4 = function ( f5_arg0 ) + local f5_local0 = CoD.mapsTable[f5_arg0] + if CoD.CONTENT_DLC6_INDEX <= f5_local0.dlc_pack or f5_arg0 == "mp_redwood_ice" or f5_arg0 == "mp_veiled_heyday" then + return f0_local3 + elseif f5_local0.dlc_pack > 0 then + return f0_local2 + else + return f5_local0.dlc_pack + end +end + +DataSources.ChangeMapCategories = DataSourceHelpers.ListSetup( "ChangeMapCategories", function ( f6_arg0 ) + local f6_local0 = {} + local f6_local1 = CoD.GetMapValue( Engine.DvarString( nil, "ui_mapname" ), "dlc_pack", CoD.CONTENT_ORIGINAL_MAP_INDEX ) + local f6_local2 = function ( f7_arg0, f7_arg1 ) + return { + models = { + text = Engine.Localize( "MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS" ), + buttonText = Engine.Localize( "MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS" ), + image = "playlist_map", + description = Engine.Localize( "MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_DESC" ) + }, + properties = { + category = f7_arg1, + selectIndex = f6_local1 == f7_arg1 + } + } + end + + CoD.mapsTable = Engine.GetGDTMapsTable() + local f6_local3 = function ( f8_arg0 ) + for f8_local3, f8_local4 in pairs( CoD.mapsTable ) do + if f8_local4.session_mode == CoD.gameModeEnum and f0_local4( f8_local3 ) == f8_arg0 and (ShowPurchasableMap( f6_arg0, f8_local3 ) or Engine.IsMapValid( f8_local3 )) then + return true + end + end + return false + end + + if CoD.isCampaign == true then + table.insert( f6_local0, f6_local2( "missions", CoD.CONTENT_ORIGINAL_MAP_INDEX ) ) + table.insert( f6_local0, f6_local2( "dev", CoD.CONTENT_DEV_MAP_INDEX ) ) + else + table.insert( f6_local0, f6_local2( "standard", CoD.CONTENT_ORIGINAL_MAP_INDEX ) ) + if not Dvar.ui_execdemo:get() and f6_local3( f0_local2 ) then + table.insert( f6_local0, f6_local2( "dlc", f0_local2 ) ) + end + if not Dvar.ui_execdemo:get() and f6_local3( f0_local3 ) then + table.insert( f6_local0, f6_local2( "dlc_bonus", f0_local3 ) ) + end + if Mods_Enabled() then --and Engine.Mods_Lists_GetInfoEntries( LuaEnums.USERMAP_BASE_PATH, 0, Engine.Mods_Lists_GetInfoEntriesCount( LuaEnums.USERMAP_BASE_PATH ) ) ~= nil then + + local f9_local11 = Engine.Mods_Lists_GetInfoEntries( LuaEnums.USERMAP_BASE_PATH, 0, Engine.Mods_Lists_GetInfoEntriesCount( LuaEnums.USERMAP_BASE_PATH ) ) + if f9_local11 then + for f9_local12 = 0, #f9_local11, 1 do + local f9_local17 = f9_local11[f9_local12] + if LUI.startswith( f9_local17.internalName, "mp_" ) then + + table.insert( f6_local0, f6_local2( "mods", CoD.CONTENT_MODS_INDEX ) ) + end + end + end + end + end + return f6_local0 +end, true ) + diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index cf9e8568..14511b02 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -6,6 +6,7 @@ local EnableLobbyMapVote = true -- toggle map vote in public lobby local utils = require("utils") require("DataSources_StartMenuTabs") +require("DataSources_ChangeMapCategories") require("DataSources_GameSettingsFlyoutButtons") CoD.LobbyButtons.MP_PUBLIC_MATCH = { From b7af6d6e258e712e8cb9a14db6168b8a62c1599a Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 17:00:21 -0230 Subject: [PATCH 08/50] Add server browser button to mp play menu --- data/ui_scripts/frontend_menus/__init__.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 14511b02..616c1ed6 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -3,6 +3,7 @@ if Engine.GetCurrentMap() ~= "core_frontend" then end local EnableLobbyMapVote = true -- toggle map vote in public lobby +local EnableLargeServerBrowserButton = true -- toggle large server browser button local utils = require("utils") require("DataSources_StartMenuTabs") @@ -67,6 +68,14 @@ CoD.LobbyButtons.GameSettingsFlyoutMP = { customId = "btnGameSettingsFlyoutMPCustom" } +CoD.LobbyButtons.SERVER_BROWSER = { + stringRef = "MENU_SERVER_BROWSER_CAPS", + action = function( self, element, controller, param, menu ) + SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) + OpenPopup( menu, "LobbyServerBrowserOnline", controller ) + end, + customId = "btnDedicated" +} CoD.LobbyButtons.MP_CUSTOM_SETUP_GAME = { stringRef = "MPUI_SETUP_GAME_CAPS", action = OpenSetupGameMP, @@ -92,6 +101,10 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id then LobbyMapVoteIsEnabled = EnableLobbyMapVote + if EnableLargeServerBrowserButton then + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.SERVER_BROWSER, 1) + end + elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEPUBLICGAME.id then LobbyMapVote( LobbyMapVoteIsEnabled ) LobbyMapVoteIsEnabled = false From c4ce0ae031c4d1c2122c72aa881767405cee4c23 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 17:02:27 -0230 Subject: [PATCH 09/50] Clean up menus --- data/ui_scripts/frontend_menus/__init__.lua | 43 ++++++++++++++------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 616c1ed6..3268ccbf 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -23,7 +23,7 @@ CoD.LobbyButtons.MP_FIND_MATCH = { customId = "btnFindMatch", } -CoD.LobbyButtons.MP_STATS = { +CoD.LobbyButtons.STATS = { stringRef = "STATS", action = function(self, element, controller, param, menu) SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) @@ -76,11 +76,6 @@ CoD.LobbyButtons.SERVER_BROWSER = { end, customId = "btnDedicated" } -CoD.LobbyButtons.MP_CUSTOM_SETUP_GAME = { - stringRef = "MPUI_SETUP_GAME_CAPS", - action = OpenSetupGameMP, - customId = "btnSetupGame", -} local LobbyMapVoteIsEnabled = EnableLobbyMapVote local LobbyMapVote = function( LobbyMapVoteIsEnabled ) @@ -90,9 +85,14 @@ local LobbyMapVote = function( LobbyMapVoteIsEnabled ) end local addCustomButtons = function(controller, menuId, buttonTable, isLeader) + + if menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id then + utils.RemoveSpaces(buttonTable) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.THEATER_MP)-1) + end + if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then - utils.AddSpacer(buttonTable) - utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.MP_STATS) + utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.STATS) end if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id or menuId == LobbyData.UITargets.UI_MPLOBBYLANGAME.id then @@ -106,16 +106,31 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) end elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEPUBLICGAME.id then + utils.RemoveButton(buttonTable, CoD.LobbyButtons.MP_PUBLIC_LOBBY_LEADERBOARD) + + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) + utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP, 2) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP)) + LobbyMapVote( LobbyMapVoteIsEnabled ) LobbyMapVoteIsEnabled = false - utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) --Launch match button - utils.AddSpacer(buttonTable, 1) - utils.AddSpacer(buttonTable) - utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.MP_CUSTOM_SETUP_GAME) --Setup game in public lobby elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEARENAGAME.id then - utils.AddSpacer(buttonTable) - utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.SETTING_UP_BOTS) --Bot setting button in public lobby + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) + utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas, 2) + + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas)) + end + + if menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then + -- utils.RemoveButton(buttonTable,CoD.LobbyButtons.ZM_FIND_MATCH) + utils.RemoveButton(buttonTable, CoD.LobbyButtons.THEATER_ZM) + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM, #buttonTable+1) + + utils.RemoveSpaces(buttonTable) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.SERVER_BROWSER)) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS)-1) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.STATS)) end end From 2424c51da666415162d0e98c8ec4696d1534d26f Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 17:21:53 -0230 Subject: [PATCH 10/50] Remove misleading lobby text: - Searching for players - Searching for game - Playlist 0% --- ...rces_playlistCategoryMatchSettingsInfo.lua | 66 +++++++++ .../DataSources_playlistMatchSettingsInfo.lua | 140 ++++++++++++++++++ data/ui_scripts/playlist/__init__.lua | 11 ++ 3 files changed, 217 insertions(+) create mode 100644 data/ui_scripts/playlist/DataSources_playlistCategoryMatchSettingsInfo.lua create mode 100644 data/ui_scripts/playlist/DataSources_playlistMatchSettingsInfo.lua diff --git a/data/ui_scripts/playlist/DataSources_playlistCategoryMatchSettingsInfo.lua b/data/ui_scripts/playlist/DataSources_playlistCategoryMatchSettingsInfo.lua new file mode 100644 index 00000000..f630cb64 --- /dev/null +++ b/data/ui_scripts/playlist/DataSources_playlistCategoryMatchSettingsInfo.lua @@ -0,0 +1,66 @@ +CoD.playlistCategoryMatchSettingsInfo = InheritFrom( LUI.UIElement ) +CoD.playlistCategoryMatchSettingsInfo.new = function ( menu, controller ) + local self = LUI.UIElement.new() + + if PreLoadFunc then + PreLoadFunc( self, controller ) + end + + self:setUseStencil( false ) + self:setClass( CoD.playlistCategoryMatchSettingsInfo ) + self.id = "playlistCategoryMatchSettingsInfo" + self.soundSet = "default" + self:setLeftRight( true, false, 0, 450 ) + self:setTopBottom( true, false, 0, 550 ) + self.anyChildUsesUpdateState = true + + local categoryInfo = CoD.matchSettingsInfo.new( menu, controller ) + categoryInfo:setLeftRight( true, false, 0, 450 ) + categoryInfo:setTopBottom( true, false, 0, 550 ) + categoryInfo.FRBestTime.BestTimeValueText:setText( Engine.Localize( "--:--:--" ) ) + categoryInfo:linkToElementModel( self, nil, false, function ( model ) + categoryInfo:setModel( model, controller ) + end ) + categoryInfo:mergeStateConditions( { + { + stateName = "AspectRatio_1x1", + condition = function ( menu, element, event ) + return AlwaysTrue() + end + } + } ) + self:addElement( categoryInfo ) + self.categoryInfo = categoryInfo + + -- local playlistCount = LUI.UITightText.new() + -- playlistCount:setLeftRight( true, false, 1, 446 ) + -- playlistCount:setTopBottom( true, false, -22, -2 ) + -- playlistCount:setTTF( "fonts/RefrigeratorDeluxe-Regular.ttf" ) + -- playlistCount:linkToElementModel( self, "playlistCount", true, function ( model ) + -- local _playlistCount = Engine.GetModelValue( model ) + -- if _playlistCount then + -- playlistCount:setText( Engine.Localize( _playlistCount ) ) + -- end + -- end ) + -- self:addElement( playlistCount ) + -- self.playlistCount = playlistCount + + self.clipsPerState = { + DefaultState = { + DefaultClip = function () + self:setupElementClipCounter( 0 ) + end + } + } + + LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) + element.categoryInfo:close() + -- element.playlistCount:close() + end ) + + if PostLoadFunc then + PostLoadFunc( self, controller, menu ) + end + + return self +end \ No newline at end of file diff --git a/data/ui_scripts/playlist/DataSources_playlistMatchSettingsInfo.lua b/data/ui_scripts/playlist/DataSources_playlistMatchSettingsInfo.lua new file mode 100644 index 00000000..4aba6c7c --- /dev/null +++ b/data/ui_scripts/playlist/DataSources_playlistMatchSettingsInfo.lua @@ -0,0 +1,140 @@ +CoD.playlistMatchSettingsInfo = InheritFrom( LUI.UIElement ) +CoD.playlistMatchSettingsInfo.new = function ( menu, controller ) + local self = LUI.UIElement.new() + + if PreLoadFunc then + PreLoadFunc( self, controller ) + end + + self:setUseStencil( false ) + self:setClass( CoD.playlistMatchSettingsInfo ) + self.id = "playlistMatchSettingsInfo" + self.soundSet = "default" + self:setLeftRight( true, false, 0, 450 ) + self:setTopBottom( true, false, 0, 550 ) + self.anyChildUsesUpdateState = true + + local gameModeInfo = CoD.matchSettingsInfo.new( menu, controller ) + gameModeInfo:setLeftRight( true, false, 0, 446 ) + gameModeInfo:setTopBottom( true, false, 0, 550 ) + gameModeInfo.FRBestTime.BestTimeValueText:setText( Engine.Localize( "--:--:--" ) ) + gameModeInfo:linkToElementModel( self, nil, false, function ( model ) + gameModeInfo:setModel( model, controller ) + end ) + gameModeInfo:mergeStateConditions( { + { + stateName = "AspectRatio_1x1", + condition = function ( menu, element, event ) + return AlwaysTrue() + end + } + } ) + self:addElement( gameModeInfo ) + self.gameModeInfo = gameModeInfo + + -- local playlistCount = LUI.UIText.new() + -- playlistCount:setLeftRight( true, false, 1, 446 ) + -- playlistCount:setTopBottom( true, false, -22, -2 ) + -- playlistCount:setTTF( "fonts/RefrigeratorDeluxe-Regular.ttf" ) + -- playlistCount:setAlignment( Enum.LUIAlignment.LUI_ALIGNMENT_LEFT ) + -- playlistCount:setAlignment( Enum.LUIAlignment.LUI_ALIGNMENT_TOP ) + -- playlistCount:linkToElementModel( self, "playlistCount", true, function ( model ) + -- local _playlistCount = Engine.GetModelValue( model ) + -- if _playlistCount then + -- playlistCount:setText( Engine.Localize( _playlistCount ) ) + -- end + -- end ) + -- self:addElement( playlistCount ) + -- self.playlistCount = playlistCount + + local PlaylistSpecialEventWidget = CoD.Playlist_SpecialEventWidget.new( menu, controller ) + PlaylistSpecialEventWidget:setLeftRight( true, false, 8.55, 408.55 ) + PlaylistSpecialEventWidget:setTopBottom( true, false, 277, 307 ) + PlaylistSpecialEventWidget:linkToElementModel( self, nil, false, function ( model ) + PlaylistSpecialEventWidget:setModel( model, controller ) + end ) + PlaylistSpecialEventWidget:mergeStateConditions( { + { + stateName = "DoubleXPWeaponXP", + condition = function ( menu, element, event ) + return IsSelfModelValueEqualTo( element, controller, "hasDoubleXP", true ) and IsSelfModelValueEqualTo( element, controller, "hasDoubleWeaponXP", true ) + end + }, + { + stateName = "DoubleXPDoubleCryptokeys", + condition = function ( menu, element, event ) + return IsSelfModelValueEqualTo( element, controller, "hasDoubleXP", true ) and IsSelfModelValueEqualTo( element, controller, "hasDoubleCryptokeys", true ) + end + }, + { + stateName = "WeaponXPDoubleCryptokeysCopy", + condition = function ( menu, element, event ) + return IsSelfModelValueEqualTo( element, controller, "hasDoubleWeaponXP", true ) and IsSelfModelValueEqualTo( element, controller, "hasDoubleCryptokeys", true ) + end + }, + { + stateName = "DoubleXP", + condition = function ( menu, element, event ) + return IsSelfModelValueEqualTo( element, controller, "hasDoubleXP", true ) + end + }, + { + stateName = "DoubleWeaponXP", + condition = function ( menu, element, event ) + return IsSelfModelValueEqualTo( element, controller, "hasDoubleWeaponXP", true ) + end + }, + { + stateName = "DoubleCryptokeys", + condition = function ( menu, element, event ) + return IsSelfModelValueEqualTo( element, controller, "hasDoubleCryptokeys", true ) + end + } + } ) + PlaylistSpecialEventWidget:linkToElementModel( PlaylistSpecialEventWidget, "hasDoubleXP", true, function ( model ) + menu:updateElementState( PlaylistSpecialEventWidget, { + name = "model_validation", + menu = menu, + modelValue = Engine.GetModelValue( model ), + modelName = "hasDoubleXP" + } ) + end ) + PlaylistSpecialEventWidget:linkToElementModel( PlaylistSpecialEventWidget, "hasDoubleWeaponXP", true, function ( model ) + menu:updateElementState( PlaylistSpecialEventWidget, { + name = "model_validation", + menu = menu, + modelValue = Engine.GetModelValue( model ), + modelName = "hasDoubleWeaponXP" + } ) + end ) + PlaylistSpecialEventWidget:linkToElementModel( PlaylistSpecialEventWidget, "hasDoubleCryptokeys", true, function ( model ) + menu:updateElementState( PlaylistSpecialEventWidget, { + name = "model_validation", + menu = menu, + modelValue = Engine.GetModelValue( model ), + modelName = "hasDoubleCryptokeys" + } ) + end ) + self:addElement( PlaylistSpecialEventWidget ) + self.PlaylistSpecialEventWidget = PlaylistSpecialEventWidget + + self.clipsPerState = { + DefaultState = { + DefaultClip = function () + self:setupElementClipCounter( 0 ) + end + } + } + + LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) + element.gameModeInfo:close() + element.PlaylistSpecialEventWidget:close() + -- element.playlistCount:close() + end ) + + if PostLoadFunc then + PostLoadFunc( self, controller, menu ) + end + + return self +end \ No newline at end of file diff --git a/data/ui_scripts/playlist/__init__.lua b/data/ui_scripts/playlist/__init__.lua index 091a726c..a0bb56aa 100644 --- a/data/ui_scripts/playlist/__init__.lua +++ b/data/ui_scripts/playlist/__init__.lua @@ -2,9 +2,20 @@ if Engine.GetCurrentMap() ~= "core_frontend" then return end +Engine.GetLobbyMaxClients = function() + return 1 +end + +function IsLobbyStatusVisible() + return false +end + Engine.SetDvar( "lobbyMigrate_Enabled", 0 ) Engine.SetDvar( "lobbyTimerStatusVotingInterval", 11000 ) Engine.SetDvar( "lobbyTimerStatusBeginInterval", 10 ) Engine.SetDvar( "lobbyTimerStatusStartInterval", 10 ) Engine.SetDvar( "lobbyTimerStatusPostGameInterval", 10 ) Engine.SetDvar( "lobbyTimerStatusVotingInterval_Arena", 11000 ) + +require("DataSources_playlistMatchSettingsInfo") +require("DataSources_playlistCategoryMatchSettingsInfo") \ No newline at end of file From 5581f0100f1eaa2d5cfc718e1534d2daa61cb823 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 17:26:50 -0230 Subject: [PATCH 11/50] set com_maxclients ingame to allow direct connect - 4 for zombies - 18 for multiplayer --- data/ui_scripts/party/__init__.lua | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/data/ui_scripts/party/__init__.lua b/data/ui_scripts/party/__init__.lua index 741d9378..7702e6df 100644 --- a/data/ui_scripts/party/__init__.lua +++ b/data/ui_scripts/party/__init__.lua @@ -1,4 +1,3 @@ - -- Removed check for public matches to allow team change in ranked matches CoD.IsTeamChangeAllowed = function() if Engine.GetGametypeSetting( "allowInGameTeamChange" ) == 1 then @@ -8,6 +7,18 @@ CoD.IsTeamChangeAllowed = function() end end +-- Set com_maxclients InGame so players can join via direct connect +local maxclients = function() + if Engine.IsZombiesGame() then + return 4 + else + return 18 + end +end + +Engine.SetDvar( "com_maxclients", maxclients() ) + + DataSources.StartMenuGameOptions = ListHelper_SetupDataSource("StartMenuGameOptions", function (controller) local options = {} if Engine.IsDemoPlaying() then From 56b5d346d4bcf9669d528bbf95a9b0fdda97f38a Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 17:27:59 -0230 Subject: [PATCH 12/50] Move Datasource.StartMenuGameOptions --- .../DataSources_StartMenuGameOptions.lua | 74 ++++++++++++++++++ data/ui_scripts/party/__init__.lua | 76 +------------------ 2 files changed, 75 insertions(+), 75 deletions(-) create mode 100644 data/ui_scripts/party/DataSources_StartMenuGameOptions.lua diff --git a/data/ui_scripts/party/DataSources_StartMenuGameOptions.lua b/data/ui_scripts/party/DataSources_StartMenuGameOptions.lua new file mode 100644 index 00000000..522b21f3 --- /dev/null +++ b/data/ui_scripts/party/DataSources_StartMenuGameOptions.lua @@ -0,0 +1,74 @@ +DataSources.StartMenuGameOptions = ListHelper_SetupDataSource("StartMenuGameOptions", function (controller) + local options = {} + if Engine.IsDemoPlaying() then + if not IsDemoRestrictedBasicMode() then + table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_UPLOAD_CLIP", Engine.GetDemoSegmentCount())), action = StartMenuUploadClip, disabledFunction = IsUploadClipButtonDisabled}, properties = {hideHelpItemLabel = true}}) + end + if Engine.IsDemoHighlightReelMode() then + table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_DEMO_CUSTOMIZE_HIGHLIGHT_REEL")), action = StartMenuOpenCustomizeHighlightReel, disabledFunction = IsCustomizeHighlightReelButtonDisabled}}) + end + table.insert(options, {models = {displayText = Engine.ToUpper(Engine.ToUpper(Engine.Localize("MENU_JUMP_TO_START"))), action = StartMenuJumpToStart, disabledFunction = IsJumpToStartButtonDisabled}, properties = {hideHelpItemLabel = true}}) + local endDemoButtonText = nil + if Engine.IsDemoClipPlaying() then + endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_CLIP")) + else + endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_FILM")) + end + table.insert(options, {models = {displayText = Engine.ToUpper(endDemoButtonText), action = StartMenuEndDemo}}) + elseif CoD.isCampaign then + table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}}) + local inTrainingSim = CoD.SafeGetModelValue(Engine.GetModelForController(controller), "safehouse.inTrainingSim") + if not inTrainingSim then + inTrainingSim = 0 + end + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) then + if not CoD.isSafehouse and controller == Engine.GetPrimaryController() then + table.insert(options, {models = {displayText = "MENU_RESTART_MISSION_CAPS", action = RestartMission}}) + if LUI.DEV ~= nil then + table.insert(options, {models = {displayText = "MENU_RESTART_CHECKPOINT_CAPS", action = RestartFromCheckpoint}}) + end + end + if controller == Engine.GetPrimaryController() then + table.insert(options, {models = {displayText = "MENU_CHANGE_DIFFICULTY_CAPS", action = OpenDifficultySelect}}) + end + if CoD.isSafehouse and inTrainingSim == 1 then + table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}}) + elseif controller == Engine.GetPrimaryController() then + if Engine.DvarBool(0, "ui_blocksaves") then + table.insert(options, {models = {displayText = "MENU_EXIT_CAPS", action = SaveAndQuitGame}}) + else + table.insert(options, {models = {displayText = "MENU_SAVE_AND_QUIT_CAPS", action = SaveAndQuitGame}}) + end + end + elseif CoD.isSafehouse and inTrainingSim == 1 then + table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}}) + else + table.insert(options, {models = {displayText = "MENU_LEAVE_PARTY_AND_EXIT_CAPS", action = QuitGame}}) + end + elseif CoD.isMultiplayer then + if Engine.Team(controller, "name") ~= "TEAM_SPECTATOR" and Engine.GetGametypeSetting("disableClassSelection") ~= 1 then + table.insert(options, {models = {displayText = "MPUI_CHOOSE_CLASS_BUTTON_CAPS", action = ChooseClass}}) + end + if not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_ROUND_END_KILLCAM) and not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_FINAL_KILLCAM) and CoD.IsTeamChangeAllowed() then + table.insert(options, {models = {displayText = "MPUI_CHANGE_TEAM_BUTTON_CAPS", action = ChooseTeam}}) + end + if controller == 0 then + local endGameText = "MENU_QUIT_GAME_CAPS" + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and not CoD.isOnlineGame() then + endGameText = "MENU_END_GAME_CAPS" + end + table.insert(options, {models = {displayText = endGameText, action = QuitGame_MP}}) + end + elseif CoD.isZombie then + table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}}) + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and (not Engine.SessionModeIsMode(CoD.SESSIONMODE_SYSTEMLINK) or Engine.SessionModeIsMode(CoD.SESSIONMODE_OFFLINE)) then + table.insert(options, {models = {displayText = "MENU_RESTART_LEVEL_CAPS", action = RestartGame}}) + end + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) == true then + table.insert(options, {models = {displayText = "MENU_END_GAME_CAPS", action = QuitGame_MP}}) + else + table.insert(options, {models = {displayText = "MENU_QUIT_GAME_CAPS", action = QuitGame_MP}}) + end + end + return options +end, true) diff --git a/data/ui_scripts/party/__init__.lua b/data/ui_scripts/party/__init__.lua index 7702e6df..2030b7bc 100644 --- a/data/ui_scripts/party/__init__.lua +++ b/data/ui_scripts/party/__init__.lua @@ -18,78 +18,4 @@ end Engine.SetDvar( "com_maxclients", maxclients() ) - -DataSources.StartMenuGameOptions = ListHelper_SetupDataSource("StartMenuGameOptions", function (controller) - local options = {} - if Engine.IsDemoPlaying() then - if not IsDemoRestrictedBasicMode() then - table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_UPLOAD_CLIP", Engine.GetDemoSegmentCount())), action = StartMenuUploadClip, disabledFunction = IsUploadClipButtonDisabled}, properties = {hideHelpItemLabel = true}}) - end - if Engine.IsDemoHighlightReelMode() then - table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_DEMO_CUSTOMIZE_HIGHLIGHT_REEL")), action = StartMenuOpenCustomizeHighlightReel, disabledFunction = IsCustomizeHighlightReelButtonDisabled}}) - end - table.insert(options, {models = {displayText = Engine.ToUpper(Engine.ToUpper(Engine.Localize("MENU_JUMP_TO_START"))), action = StartMenuJumpToStart, disabledFunction = IsJumpToStartButtonDisabled}, properties = {hideHelpItemLabel = true}}) - local endDemoButtonText = nil - if Engine.IsDemoClipPlaying() then - endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_CLIP")) - else - endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_FILM")) - end - table.insert(options, {models = {displayText = Engine.ToUpper(endDemoButtonText), action = StartMenuEndDemo}}) - elseif CoD.isCampaign then - table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}}) - local inTrainingSim = CoD.SafeGetModelValue(Engine.GetModelForController(controller), "safehouse.inTrainingSim") - if not inTrainingSim then - inTrainingSim = 0 - end - if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) then - if not CoD.isSafehouse and controller == Engine.GetPrimaryController() then - table.insert(options, {models = {displayText = "MENU_RESTART_MISSION_CAPS", action = RestartMission}}) - if LUI.DEV ~= nil then - table.insert(options, {models = {displayText = "MENU_RESTART_CHECKPOINT_CAPS", action = RestartFromCheckpoint}}) - end - end - if controller == Engine.GetPrimaryController() then - table.insert(options, {models = {displayText = "MENU_CHANGE_DIFFICULTY_CAPS", action = OpenDifficultySelect}}) - end - if CoD.isSafehouse and inTrainingSim == 1 then - table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}}) - elseif controller == Engine.GetPrimaryController() then - if Engine.DvarBool(0, "ui_blocksaves") then - table.insert(options, {models = {displayText = "MENU_EXIT_CAPS", action = SaveAndQuitGame}}) - else - table.insert(options, {models = {displayText = "MENU_SAVE_AND_QUIT_CAPS", action = SaveAndQuitGame}}) - end - end - elseif CoD.isSafehouse and inTrainingSim == 1 then - table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}}) - else - table.insert(options, {models = {displayText = "MENU_LEAVE_PARTY_AND_EXIT_CAPS", action = QuitGame}}) - end - elseif CoD.isMultiplayer then - if Engine.Team(controller, "name") ~= "TEAM_SPECTATOR" and Engine.GetGametypeSetting("disableClassSelection") ~= 1 then - table.insert(options, {models = {displayText = "MPUI_CHOOSE_CLASS_BUTTON_CAPS", action = ChooseClass}}) - end - if not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_ROUND_END_KILLCAM) and not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_FINAL_KILLCAM) and CoD.IsTeamChangeAllowed() then - table.insert(options, {models = {displayText = "MPUI_CHANGE_TEAM_BUTTON_CAPS", action = ChooseTeam}}) - end - if controller == 0 then - local endGameText = "MENU_QUIT_GAME_CAPS" - if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and not CoD.isOnlineGame() then - endGameText = "MENU_END_GAME_CAPS" - end - table.insert(options, {models = {displayText = endGameText, action = QuitGame_MP}}) - end - elseif CoD.isZombie then - table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}}) - if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and (not Engine.SessionModeIsMode(CoD.SESSIONMODE_SYSTEMLINK) or Engine.SessionModeIsMode(CoD.SESSIONMODE_OFFLINE)) then - table.insert(options, {models = {displayText = "MENU_RESTART_LEVEL_CAPS", action = RestartGame}}) - end - if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) == true then - table.insert(options, {models = {displayText = "MENU_END_GAME_CAPS", action = QuitGame_MP}}) - else - table.insert(options, {models = {displayText = "MENU_QUIT_GAME_CAPS", action = QuitGame_MP}}) - end - end - return options -end, true) +require("DataSources_StartMenuGameOptions") From 70297f04c8372dc969eb15c58f16c33e69dce42d Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 11 Apr 2023 21:33:10 -0230 Subject: [PATCH 13/50] Add blur to setup game flyout menu --- .../DataSources_GameSettingsFlyoutButtons.lua | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua b/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua index 1df436ff..d4d4e60b 100644 --- a/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua +++ b/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua @@ -1,3 +1,58 @@ +local f0_local0 = function ( f1_arg0, f1_arg1 ) + if not CoD.useMouse then + return + else + f1_arg0.Options:setHandleMouse( true ) + f1_arg0.Options:registerEventHandler( "leftclick_outside", function ( element, event ) + CoD.PCUtil.SimulateButtonPress( event.controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE ) + return true + end ) + end +end + +local PostLoadFunc = function ( f3_arg0, f3_arg1 ) + f0_local0( f3_arg0, f3_arg1 ) + f3_arg0.disableBlur = true + f3_arg0.disablePopupOpenCloseAnim = true + Engine.SetModelValue( Engine.CreateModel( Engine.GetGlobalModel(), "GameSettingsFlyoutOpen" ), true ) + LUI.OverrideFunction_CallOriginalSecond( f3_arg0, "close", function ( element ) + Engine.SetModelValue( Engine.CreateModel( Engine.GetGlobalModel(), "GameSettingsFlyoutOpen" ), false ) + end ) + f3_arg0:registerEventHandler( "occlusion_change", function ( element, event ) + local f5_local0 = element:getParent() + if f5_local0 then + local f5_local1 = f5_local0:getFirstChild() + while f5_local1 ~= nil do + if f5_local1.menuName == "Lobby" then + break + end + f5_local1 = f5_local1:getNextSibling() + end + if f5_local1 then + if event.occluded == true then + f5_local1:setAlpha( 0 ) + end + f5_local1:setAlpha( 1 ) + end + end + element:OcclusionChange( event ) + end ) + f3_arg0:subscribeToModel( Engine.CreateModel( Engine.GetGlobalModel(), "lobbyRoot.lobbyNav", true ), function ( model ) + local f6_local0 = f3_arg0.occludedBy + while f6_local0 do + if f6_local0.occludedBy ~= nil then + f6_local0 = f6_local0.occludedBy + end + while f6_local0 and f6_local0.menuName ~= "Lobby" do + f6_local0 = GoBack( f6_local0, f3_arg1 ) + end + Engine.SendClientScriptNotify( f3_arg1, "menu_change" .. Engine.GetLocalClientNum( f3_arg1 ), "Main", "closeToMenu" ) + return + end + GoBack( f3_arg0, f3_arg1 ) + end, false ) +end + DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup( "GameSettingsFlyoutButtonsCustom", function ( f7_arg0 ) local f7_local0 = { { @@ -66,7 +121,7 @@ LUI.createMenu.GameSettingsFlyoutMPCustom = function ( controller ) Options:setTopBottom( true, false, 177.56, 329.56 ) Options:setYRot( 25 ) Options:setWidgetType( CoD.FE_List1ButtonLarge_PH ) - Options:setVerticalCount( 5 ) + Options:setVerticalCount( 3 ) Options:setSpacing( -2 ) Options:setDataSource( "GameSettingsFlyoutButtonsCustom" ) Options:registerEventHandler( "gain_focus", function ( element, event ) @@ -189,6 +244,8 @@ LUI.createMenu.GameSettingsFlyoutMPCustom = function ( controller ) element.Options:close() Engine.UnsubscribeAndFreeModel( Engine.GetModel( Engine.GetModelForController( controller ), "GameSettingsFlyoutMP.buttonPrompts" ) ) end ) + if PostLoadFunc then + PostLoadFunc( self, controller ) + end return self end - From 6a25f0e4aba88338ae9794536dd227e2b12dc44b Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Wed, 12 Apr 2023 18:29:00 -0230 Subject: [PATCH 14/50] Robust com_maxclients override - now sets com_maxclients to lobby default - supports all modes --- data/ui_scripts/party/__init__.lua | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/data/ui_scripts/party/__init__.lua b/data/ui_scripts/party/__init__.lua index 2030b7bc..a2a96f46 100644 --- a/data/ui_scripts/party/__init__.lua +++ b/data/ui_scripts/party/__init__.lua @@ -7,15 +7,17 @@ CoD.IsTeamChangeAllowed = function() end end --- Set com_maxclients InGame so players can join via direct connect -local maxclients = function() - if Engine.IsZombiesGame() then - return 4 - else - return 18 - end +local GetModeInfo = function() + local id = Engine.GetLobbyUIScreen() + return LobbyData:UITargetFromId(id) end -Engine.SetDvar( "com_maxclients", maxclients() ) +local GetMaxClients = function() + local ModeInfo = GetModeInfo() + return ModeInfo.maxClients +end + +-- Set com_maxclients InGame so players can join via direct connect (default from lobbydata) +Engine.SetDvar( "com_maxclients", GetMaxClients() ) require("DataSources_StartMenuGameOptions") From 727b4eadebaef5f7862f93b696cd7a9997f186b8 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Wed, 12 Apr 2023 19:09:36 -0230 Subject: [PATCH 15/50] Standard Lua formatting --- .../DataSources_ChangeMapCategories.lua | 82 +++--- .../DataSources_GameSettingsFlyoutButtons.lua | 249 +++++++++--------- .../DataSources_StartMenuTabs.lua | 82 +++--- data/ui_scripts/frontend_menus/__init__.lua | 47 ++-- data/ui_scripts/frontend_menus/utils.lua | 10 +- 5 files changed, 237 insertions(+), 233 deletions(-) diff --git a/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua b/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua index 9e25f646..468c6bfe 100644 --- a/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua +++ b/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua @@ -1,35 +1,35 @@ -local f0_local0 = function ( f1_arg0, f1_arg1 ) +local f0_local0 = function(f1_arg0, f1_arg1) if not CoD.useMouse then - return + return else - LUI.OverrideFunction_CallOriginalFirst( f1_arg0, "setState", function ( element, controller ) - if IsSelfInState( f1_arg0, "SelectingMap" ) then - f1_arg0.mapList:setMouseDisabled( false ) - f1_arg0.mapCategoriesList:setMouseDisabled( true ) + LUI.OverrideFunction_CallOriginalFirst(f1_arg0, "setState", function(element, controller) + if IsSelfInState(f1_arg0, "SelectingMap") then + f1_arg0.mapList:setMouseDisabled(false) + f1_arg0.mapCategoriesList:setMouseDisabled(true) f1_arg0.m_categorySet = false else - f1_arg0.mapList:setMouseDisabled( true ) - f1_arg0.mapCategoriesList:setMouseDisabled( false ) + f1_arg0.mapList:setMouseDisabled(true) + f1_arg0.mapCategoriesList:setMouseDisabled(false) end - end ) - f1_arg0.mapList:setMouseDisabled( true ) - f1_arg0.mapList:registerEventHandler( "leftclick_outside", function ( element, event ) - if IsSelfInState( f1_arg0, "SelectingMap" ) and f1_arg0.m_categorySet then - CoD.PCUtil.SimulateButtonPress( f1_arg1, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE ) + end) + f1_arg0.mapList:setMouseDisabled(true) + f1_arg0.mapList:registerEventHandler("leftclick_outside", function(element, event) + if IsSelfInState(f1_arg0, "SelectingMap") and f1_arg0.m_categorySet then + CoD.PCUtil.SimulateButtonPress(f1_arg1, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE) end f1_arg0.m_categorySet = true return true - end ) + end) end end -local PostLoadFunc = function ( f4_arg0, f4_arg1 ) - f0_local0( f4_arg0, f4_arg1 ) +local PostLoadFunc = function(f4_arg0, f4_arg1) + f0_local0(f4_arg0, f4_arg1) end local f0_local2 = 10000 local f0_local3 = 10001 -local f0_local4 = function ( f5_arg0 ) +local f0_local4 = function(f5_arg0) local f5_local0 = CoD.mapsTable[f5_arg0] if CoD.CONTENT_DLC6_INDEX <= f5_local0.dlc_pack or f5_arg0 == "mp_redwood_ice" or f5_arg0 == "mp_veiled_heyday" then return f0_local3 @@ -40,16 +40,16 @@ local f0_local4 = function ( f5_arg0 ) end end -DataSources.ChangeMapCategories = DataSourceHelpers.ListSetup( "ChangeMapCategories", function ( f6_arg0 ) +DataSources.ChangeMapCategories = DataSourceHelpers.ListSetup("ChangeMapCategories", function(f6_arg0) local f6_local0 = {} - local f6_local1 = CoD.GetMapValue( Engine.DvarString( nil, "ui_mapname" ), "dlc_pack", CoD.CONTENT_ORIGINAL_MAP_INDEX ) - local f6_local2 = function ( f7_arg0, f7_arg1 ) + local f6_local1 = CoD.GetMapValue(Engine.DvarString(nil, "ui_mapname"), "dlc_pack", CoD.CONTENT_ORIGINAL_MAP_INDEX) + local f6_local2 = function(f7_arg0, f7_arg1) return { models = { - text = Engine.Localize( "MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS" ), - buttonText = Engine.Localize( "MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS" ), + text = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS"), + buttonText = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS"), image = "playlist_map", - description = Engine.Localize( "MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_DESC" ) + description = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_DESC") }, properties = { category = f7_arg1, @@ -57,42 +57,40 @@ DataSources.ChangeMapCategories = DataSourceHelpers.ListSetup( "ChangeMapCategor } } end - + CoD.mapsTable = Engine.GetGDTMapsTable() - local f6_local3 = function ( f8_arg0 ) - for f8_local3, f8_local4 in pairs( CoD.mapsTable ) do - if f8_local4.session_mode == CoD.gameModeEnum and f0_local4( f8_local3 ) == f8_arg0 and (ShowPurchasableMap( f6_arg0, f8_local3 ) or Engine.IsMapValid( f8_local3 )) then + local f6_local3 = function(f8_arg0) + for f8_local3, f8_local4 in pairs(CoD.mapsTable) do + if f8_local4.session_mode == CoD.gameModeEnum and f0_local4(f8_local3) == f8_arg0 and (ShowPurchasableMap(f6_arg0, f8_local3) or Engine.IsMapValid(f8_local3)) then return true end end return false end - + if CoD.isCampaign == true then - table.insert( f6_local0, f6_local2( "missions", CoD.CONTENT_ORIGINAL_MAP_INDEX ) ) - table.insert( f6_local0, f6_local2( "dev", CoD.CONTENT_DEV_MAP_INDEX ) ) + table.insert(f6_local0, f6_local2("missions", CoD.CONTENT_ORIGINAL_MAP_INDEX)) + table.insert(f6_local0, f6_local2("dev", CoD.CONTENT_DEV_MAP_INDEX)) else - table.insert( f6_local0, f6_local2( "standard", CoD.CONTENT_ORIGINAL_MAP_INDEX ) ) - if not Dvar.ui_execdemo:get() and f6_local3( f0_local2 ) then - table.insert( f6_local0, f6_local2( "dlc", f0_local2 ) ) + table.insert(f6_local0, f6_local2("standard", CoD.CONTENT_ORIGINAL_MAP_INDEX)) + if not Dvar.ui_execdemo:get() and f6_local3(f0_local2) then + table.insert(f6_local0, f6_local2("dlc", f0_local2)) end - if not Dvar.ui_execdemo:get() and f6_local3( f0_local3 ) then - table.insert( f6_local0, f6_local2( "dlc_bonus", f0_local3 ) ) + if not Dvar.ui_execdemo:get() and f6_local3(f0_local3) then + table.insert(f6_local0, f6_local2("dlc_bonus", f0_local3)) end if Mods_Enabled() then --and Engine.Mods_Lists_GetInfoEntries( LuaEnums.USERMAP_BASE_PATH, 0, Engine.Mods_Lists_GetInfoEntriesCount( LuaEnums.USERMAP_BASE_PATH ) ) ~= nil then - - local f9_local11 = Engine.Mods_Lists_GetInfoEntries( LuaEnums.USERMAP_BASE_PATH, 0, Engine.Mods_Lists_GetInfoEntriesCount( LuaEnums.USERMAP_BASE_PATH ) ) + local f9_local11 = Engine.Mods_Lists_GetInfoEntries(LuaEnums.USERMAP_BASE_PATH, 0, + Engine.Mods_Lists_GetInfoEntriesCount(LuaEnums.USERMAP_BASE_PATH)) if f9_local11 then for f9_local12 = 0, #f9_local11, 1 do local f9_local17 = f9_local11[f9_local12] - if LUI.startswith( f9_local17.internalName, "mp_" ) then - - table.insert( f6_local0, f6_local2( "mods", CoD.CONTENT_MODS_INDEX ) ) + if LUI.startswith(f9_local17.internalName, "mp_") then + table.insert(f6_local0, f6_local2("mods", CoD.CONTENT_MODS_INDEX)) end end end end end return f6_local0 -end, true ) - +end, true) diff --git a/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua b/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua index d4d4e60b..497efefb 100644 --- a/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua +++ b/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua @@ -1,24 +1,24 @@ -local f0_local0 = function ( f1_arg0, f1_arg1 ) +local f0_local0 = function(f1_arg0, f1_arg1) if not CoD.useMouse then - return + return else - f1_arg0.Options:setHandleMouse( true ) - f1_arg0.Options:registerEventHandler( "leftclick_outside", function ( element, event ) - CoD.PCUtil.SimulateButtonPress( event.controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE ) + f1_arg0.Options:setHandleMouse(true) + f1_arg0.Options:registerEventHandler("leftclick_outside", function(element, event) + CoD.PCUtil.SimulateButtonPress(event.controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE) return true - end ) + end) end end -local PostLoadFunc = function ( f3_arg0, f3_arg1 ) - f0_local0( f3_arg0, f3_arg1 ) +local PostLoadFunc = function(f3_arg0, f3_arg1) + f0_local0(f3_arg0, f3_arg1) f3_arg0.disableBlur = true f3_arg0.disablePopupOpenCloseAnim = true - Engine.SetModelValue( Engine.CreateModel( Engine.GetGlobalModel(), "GameSettingsFlyoutOpen" ), true ) - LUI.OverrideFunction_CallOriginalSecond( f3_arg0, "close", function ( element ) - Engine.SetModelValue( Engine.CreateModel( Engine.GetGlobalModel(), "GameSettingsFlyoutOpen" ), false ) - end ) - f3_arg0:registerEventHandler( "occlusion_change", function ( element, event ) + Engine.SetModelValue(Engine.CreateModel(Engine.GetGlobalModel(), "GameSettingsFlyoutOpen"), true) + LUI.OverrideFunction_CallOriginalSecond(f3_arg0, "close", function(element) + Engine.SetModelValue(Engine.CreateModel(Engine.GetGlobalModel(), "GameSettingsFlyoutOpen"), false) + end) + f3_arg0:registerEventHandler("occlusion_change", function(element, event) local f5_local0 = element:getParent() if f5_local0 then local f5_local1 = f5_local0:getFirstChild() @@ -30,30 +30,32 @@ local PostLoadFunc = function ( f3_arg0, f3_arg1 ) end if f5_local1 then if event.occluded == true then - f5_local1:setAlpha( 0 ) + f5_local1:setAlpha(0) end - f5_local1:setAlpha( 1 ) + f5_local1:setAlpha(1) end end - element:OcclusionChange( event ) - end ) - f3_arg0:subscribeToModel( Engine.CreateModel( Engine.GetGlobalModel(), "lobbyRoot.lobbyNav", true ), function ( model ) + element:OcclusionChange(event) + end) + f3_arg0:subscribeToModel(Engine.CreateModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNav", true), function(model) local f6_local0 = f3_arg0.occludedBy while f6_local0 do if f6_local0.occludedBy ~= nil then f6_local0 = f6_local0.occludedBy end while f6_local0 and f6_local0.menuName ~= "Lobby" do - f6_local0 = GoBack( f6_local0, f3_arg1 ) + f6_local0 = GoBack(f6_local0, f3_arg1) end - Engine.SendClientScriptNotify( f3_arg1, "menu_change" .. Engine.GetLocalClientNum( f3_arg1 ), "Main", "closeToMenu" ) - return + Engine.SendClientScriptNotify(f3_arg1, "menu_change" .. Engine.GetLocalClientNum(f3_arg1), "Main", + "closeToMenu") + return end - GoBack( f3_arg0, f3_arg1 ) - end, false ) + GoBack(f3_arg0, f3_arg1) + end, false) end -DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup( "GameSettingsFlyoutButtonsCustom", function ( f7_arg0 ) +DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup("GameSettingsFlyoutButtonsCustom", +function(f7_arg0) local f7_local0 = { { optionDisplay = "MPUI_CHANGE_MAP_CAPS", @@ -61,9 +63,9 @@ DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup( "Game action = OpenChangeMap }, -- { - -- optionDisplay = "MPUI_CHANGE_GAME_MODE_CAPS", - -- customId = "btnChangeGameMode", - -- action = OpenChangeGameMode + -- optionDisplay = "MPUI_CHANGE_GAME_MODE_CAPS", + -- customId = "btnChangeGameMode", + -- action = OpenChangeGameMode -- }, { optionDisplay = "MENU_SETUP_BOTS_CAPS", @@ -77,17 +79,17 @@ DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup( "Game } } -- if CoD.isPC and IsServerBrowserEnabled() then - -- table.insert( f7_local0, { - -- optionDisplay = "PLATFORM_SERVER_SETTINGS_CAPS", - -- customID = "btnServerSettings", - -- action = OpenServerSettings - -- } ) + -- table.insert( f7_local0, { + -- optionDisplay = "PLATFORM_SERVER_SETTINGS_CAPS", + -- customID = "btnServerSettings", + -- action = OpenServerSettings + -- } ) -- end local f7_local1 = {} - for f7_local5, f7_local6 in ipairs( f7_local0 ) do - table.insert( f7_local1, { + for f7_local5, f7_local6 in ipairs(f7_local0) do + table.insert(f7_local1, { models = { - displayText = Engine.Localize( f7_local6.optionDisplay ), + displayText = Engine.Localize(f7_local6.optionDisplay), customId = f7_local6.customId, disabled = f7_local6.disabled }, @@ -97,155 +99,162 @@ DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup( "Game action = f7_local6.action, actionParam = f7_local6.actionParam } - } ) + }) end return f7_local1 -end, nil, nil, nil ) +end, nil, nil, nil) -LUI.createMenu.GameSettingsFlyoutMPCustom = function ( controller ) - local self = CoD.Menu.NewForUIEditor( "GameSettingsFlyoutMPCustom" ) +LUI.createMenu.GameSettingsFlyoutMPCustom = function(controller) + local self = CoD.Menu.NewForUIEditor("GameSettingsFlyoutMPCustom") if PreLoadFunc then - PreLoadFunc( self, controller ) + PreLoadFunc(self, controller) end self.soundSet = "default" - self:setOwner( controller ) - self:setLeftRight( true, true, 0, 0 ) - self:setTopBottom( true, true, 0, 0 ) - self:playSound( "menu_open", controller ) - self.buttonModel = Engine.CreateModel( Engine.GetModelForController( controller ), "GameSettingsFlyoutMP.buttonPrompts" ) + self:setOwner(controller) + self:setLeftRight(true, true, 0, 0) + self:setTopBottom(true, true, 0, 0) + self:playSound("menu_open", controller) + self.buttonModel = Engine.CreateModel(Engine.GetModelForController(controller), "GameSettingsFlyoutMP.buttonPrompts") self.anyChildUsesUpdateState = true - - local Options = LUI.UIList.new( self, controller, -2, 0, nil, false, false, 0, 0, false, false ) + + local Options = LUI.UIList.new(self, controller, -2, 0, nil, false, false, 0, 0, false, false) Options:makeFocusable() - Options:setLeftRight( true, false, 243.43, 523.43 ) - Options:setTopBottom( true, false, 177.56, 329.56 ) - Options:setYRot( 25 ) - Options:setWidgetType( CoD.FE_List1ButtonLarge_PH ) - Options:setVerticalCount( 3 ) - Options:setSpacing( -2 ) - Options:setDataSource( "GameSettingsFlyoutButtonsCustom" ) - Options:registerEventHandler( "gain_focus", function ( element, event ) + Options:setLeftRight(true, false, 243.43, 523.43) + Options:setTopBottom(true, false, 177.56, 329.56) + Options:setYRot(25) + Options:setWidgetType(CoD.FE_List1ButtonLarge_PH) + Options:setVerticalCount(3) + Options:setSpacing(-2) + Options:setDataSource("GameSettingsFlyoutButtonsCustom") + Options:registerEventHandler("gain_focus", function(element, event) local f9_local0 = nil if element.gainFocus then - f9_local0 = element:gainFocus( event ) + f9_local0 = element:gainFocus(event) elseif element.super.gainFocus then - f9_local0 = element.super:gainFocus( event ) + f9_local0 = element.super:gainFocus(event) end - CoD.Menu.UpdateButtonShownState( element, self, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS ) + CoD.Menu.UpdateButtonShownState(element, self, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS) return f9_local0 - end ) - Options:registerEventHandler( "lose_focus", function ( element, event ) + end) + Options:registerEventHandler("lose_focus", function(element, event) local f10_local0 = nil if element.loseFocus then - f10_local0 = element:loseFocus( event ) + f10_local0 = element:loseFocus(event) elseif element.super.loseFocus then - f10_local0 = element.super:loseFocus( event ) + f10_local0 = element.super:loseFocus(event) end return f10_local0 - end ) - self:AddButtonCallbackFunction( Options, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "ENTER", function ( element, menu, controller, model ) - ProcessListAction( self, element, controller ) + end) + self:AddButtonCallbackFunction(Options, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "ENTER", + function(element, menu, controller, model) + ProcessListAction(self, element, controller) return true - end, function ( element, menu, controller ) - CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "MENU_SELECT" ) + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "MENU_SELECT") return true - end, false ) - self:addElement( Options ) + end, false) + self:addElement(Options) self.Options = Options - - self:mergeStateConditions( { + + self:mergeStateConditions({ { stateName = "Local", - condition = function ( menu, element, event ) + condition = function(menu, element, event) return IsLobbyNetworkModeLAN() end } - } ) - self:subscribeToModel( Engine.GetModel( Engine.GetGlobalModel(), "lobbyRoot.lobbyNetworkMode" ), function ( model ) + }) + self:subscribeToModel(Engine.GetModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNetworkMode"), function(model) local f14_local0 = self local f14_local1 = { controller = controller, name = "model_validation", - modelValue = Engine.GetModelValue( model ), + modelValue = Engine.GetModelValue(model), modelName = "lobbyRoot.lobbyNetworkMode" } - CoD.Menu.UpdateButtonShownState( f14_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE ) - end ) - self:subscribeToModel( Engine.GetModel( Engine.GetGlobalModel(), "lobbyRoot.lobbyNav" ), function ( model ) + CoD.Menu.UpdateButtonShownState(f14_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE) + end) + self:subscribeToModel(Engine.GetModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNav"), function(model) local f15_local0 = self local f15_local1 = { controller = controller, name = "model_validation", - modelValue = Engine.GetModelValue( model ), + modelValue = Engine.GetModelValue(model), modelName = "lobbyRoot.lobbyNav" } - CoD.Menu.UpdateButtonShownState( f15_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE ) - end ) - self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil, function ( element, menu, controller, model ) - GoBack( self, controller ) - ClearMenuSavedState( menu ) + CoD.Menu.UpdateButtonShownState(f15_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE) + end) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil, + function(element, menu, controller, model) + GoBack(self, controller) + ClearMenuSavedState(menu) return true - end, function ( element, menu, controller ) - CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, "" ) + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, "") return false - end, false ) - self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_START, "M", function ( element, menu, controller, model ) - GoBackAndOpenOverlayOnParent( self, "StartMenu_Main", controller ) + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_START, "M", + function(element, menu, controller, model) + GoBackAndOpenOverlayOnParent(self, "StartMenu_Main", controller) return true - end, function ( element, menu, controller ) - CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_START, "MENU_MENU" ) + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_START, "MENU_MENU") return true - end, false ) - self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "S", function ( element, menu, controller, model ) - if not IsLAN() and not IsPlayerAGuest( controller ) and IsPlayerAllowedToPlayOnline( controller ) then - GoBackAndOpenOverlayOnParent( self, "Social_Main", controller ) + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "S", + function(element, menu, controller, model) + if not IsLAN() and not IsPlayerAGuest(controller) and IsPlayerAllowedToPlayOnline(controller) then + GoBackAndOpenOverlayOnParent(self, "Social_Main", controller) return true else - + end - end, function ( element, menu, controller ) - if not IsLAN() and not IsPlayerAGuest( controller ) and IsPlayerAllowedToPlayOnline( controller ) then - CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "" ) + end, function(element, menu, controller) + if not IsLAN() and not IsPlayerAGuest(controller) and IsPlayerAllowedToPlayOnline(controller) then + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "") return false else return false end - end, false ) - self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_LB, nil, function ( element, menu, controller, model ) - SendButtonPressToOccludedMenu( menu, controller, model, Enum.LUIButton.LUI_KEY_LB ) + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_LB, nil, + function(element, menu, controller, model) + SendButtonPressToOccludedMenu(menu, controller, model, Enum.LUIButton.LUI_KEY_LB) return true - end, function ( element, menu, controller ) - CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_LB, "" ) + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_LB, "") return false - end, false ) - self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_RB, nil, function ( element, menu, controller, model ) - SendButtonPressToOccludedMenu( menu, controller, model, Enum.LUIButton.LUI_KEY_RB ) + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_RB, nil, + function(element, menu, controller, model) + SendButtonPressToOccludedMenu(menu, controller, model, Enum.LUIButton.LUI_KEY_RB) return true - end, function ( element, menu, controller ) - CoD.Menu.SetButtonLabel( menu, Enum.LUIButton.LUI_KEY_RB, "" ) + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_RB, "") return false - end, false ) + end, false) Options.id = "Options" - self:processEvent( { + self:processEvent({ name = "menu_loaded", controller = controller - } ) - self:processEvent( { + }) + self:processEvent({ name = "update_state", menu = self - } ) + }) if not self:restoreState() then - self.Options:processEvent( { + self.Options:processEvent({ name = "gain_focus", controller = controller - } ) + }) end - LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) + LUI.OverrideFunction_CallOriginalSecond(self, "close", function(element) element.Options:close() - Engine.UnsubscribeAndFreeModel( Engine.GetModel( Engine.GetModelForController( controller ), "GameSettingsFlyoutMP.buttonPrompts" ) ) - end ) + Engine.UnsubscribeAndFreeModel(Engine.GetModel(Engine.GetModelForController(controller), + "GameSettingsFlyoutMP.buttonPrompts")) + end) if PostLoadFunc then - PostLoadFunc( self, controller ) + PostLoadFunc(self, controller) end return self end diff --git a/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua b/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua index 2a07cb6a..77767260 100644 --- a/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua +++ b/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua @@ -1,31 +1,31 @@ -DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", function ( f44_arg0 ) +DataSources.StartMenuTabs = ListHelper_SetupDataSource("StartMenuTabs", function(f44_arg0) local f44_local0 = {} - table.insert( f44_local0, { + table.insert(f44_local0, { models = { tabIcon = CoD.buttonStrings.shoulderl }, properties = { m_mouseDisabled = true } - } ) + }) if Engine.IsDemoPlaying() then local f44_local1 = "CoD.StartMenu_GameOptions" if Engine.IsZombiesGame() then f44_local1 = "CoD.StartMenu_GameOptions_ZM" end - table.insert( f44_local0, { + table.insert(f44_local0, { models = { - tabName = Engine.Localize( "MENU_THEATER_CAPS" ), + tabName = Engine.Localize("MENU_THEATER_CAPS"), tabWidget = f44_local1, tabIcon = "" }, properties = { tabId = "gameOptions" } - } ) + }) elseif Engine.IsInGame() then if IsGameTypeDOA() and not InSafehouse() then - table.insert( f44_local0, { + table.insert(f44_local0, { models = { tabName = "DOA", tabWidget = "CoD.StartMenu_GameOptions_DOA", @@ -34,21 +34,21 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio properties = { tabId = "gameOptions" } - } ) + }) elseif CoD.isCampaign then - table.insert( f44_local0, { + table.insert(f44_local0, { models = { - tabName = SessionModeToUnlocalizedSessionModeCaps( Engine.CurrentSessionMode() ), + tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()), tabWidget = "CoD.StartMenu_GameOptions_CP", tabIcon = "" }, properties = { tabId = "gameOptions" } - } ) + }) if not Engine.IsCampaignModeZombies() then - if CoD.isSafehouse and CoD.isOnlineGame() and not IsInTrainingSim( f44_arg0 ) and Dvar.ui_safehousebarracks:get() and not IsPlayerAGuest( f44_arg0 ) then - table.insert( f44_local0, { + if CoD.isSafehouse and CoD.isOnlineGame() and not IsInTrainingSim(f44_arg0) and Dvar.ui_safehousebarracks:get() and not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { models = { tabName = "CPUI_BARRACKS_CAPS", tabWidget = "CoD.CombatRecordCP_Contents", @@ -57,10 +57,10 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio properties = { tabId = "combatRecord" } - } ) + }) end - if HighestMapReachedGreaterThan( f44_arg0, 1 ) or LUI.DEV ~= nil then - table.insert( f44_local0, { + if HighestMapReachedGreaterThan(f44_arg0, 1) or LUI.DEV ~= nil then + table.insert(f44_local0, { models = { tabName = "CPUI_TACTICAL_MODE_CAPS", tabWidget = "CoD.StartMenu_TacticalMode", @@ -69,10 +69,10 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio properties = { tabId = "tacticalMode" } - } ) + }) end - if not CoD.isSafehouse and not IsPlayerAGuest( f44_arg0 ) then - table.insert( f44_local0, { + if not CoD.isSafehouse and not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { models = { tabName = "CPUI_ACCOLADES", tabWidget = "CoD.MissionRecordVault_Challenges", @@ -81,35 +81,35 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio properties = { tabId = "accolades" } - } ) + }) end end elseif Engine.IsZombiesGame() then - table.insert( f44_local0, { + table.insert(f44_local0, { models = { - tabName = SessionModeToUnlocalizedSessionModeCaps( Engine.CurrentSessionMode() ), + tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()), tabWidget = "CoD.StartMenu_GameOptions_ZM", tabIcon = "" }, properties = { tabId = "gameOptions" } - } ) + }) else - table.insert( f44_local0, { + table.insert(f44_local0, { models = { - tabName = SessionModeToUnlocalizedSessionModeCaps( Engine.CurrentSessionMode() ), + tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()), tabWidget = "CoD.StartMenu_GameOptions", tabIcon = "" }, properties = { tabId = "gameOptions" } - } ) + }) end else - if not IsPlayerAGuest( f44_arg0 ) then - table.insert( f44_local0, { + if not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { models = { tabName = "MENU_TAB_IDENTITY_CAPS", tabWidget = "CoD.StartMenu_Identity", @@ -119,10 +119,10 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio tabId = "identity", disabled = Dvar.ui_execdemo_gamescom:get() } - } ) + }) end - if not IsLobbyNetworkModeLAN() and not Dvar.ui_execdemo:get() and not Engine.IsCampaignModeZombies() and not IsPlayerAGuest( f44_arg0 ) then - table.insert( f44_local0, { + if not IsLobbyNetworkModeLAN() and not Dvar.ui_execdemo:get() and not Engine.IsCampaignModeZombies() and not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { models = { tabName = "MENU_TAB_CHALLENGES_CAPS", tabWidget = "CoD.StartMenu_Challenges", @@ -131,12 +131,12 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio properties = { tabId = "challenges" } - } ) + }) local f44_local1 = CoD.isPC if f44_local1 then f44_local1 = false --Mods_IsUsingMods() end - table.insert( f44_local0, { + table.insert(f44_local0, { models = { tabName = "MENU_TAB_BARRACKS_CAPS", tabWidget = "CoD.StartMenu_Barracks", @@ -146,11 +146,11 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio properties = { tabId = "barracks" } - } ) + }) if CommunityOptionsEnabled() then local f44_local2 = CoD.perController[f44_arg0].openMediaTabAfterClosingGroups CoD.perController[f44_arg0].openMediaTabAfterClosingGroups = false - table.insert( f44_local0, { + table.insert(f44_local0, { models = { tabName = "MENU_TAB_MEDIA_CAPS", tabWidget = "CoD.StartMenu_Media", @@ -160,7 +160,7 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio tabId = "media", selectIndex = f44_local2 } - } ) + }) end end end @@ -183,7 +183,7 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio end f44_local4.selectIndex = f44_local5 f44_local3.properties = f44_local4 - f44_local1( f44_local2, f44_local3 ) + f44_local1(f44_local2, f44_local3) else local f44_local1 = table.insert local f44_local2 = f44_local0 @@ -203,15 +203,15 @@ DataSources.StartMenuTabs = ListHelper_SetupDataSource( "StartMenuTabs", functio end f44_local4.selectIndex = f44_local5 f44_local3.properties = f44_local4 - f44_local1( f44_local2, f44_local3 ) + f44_local1(f44_local2, f44_local3) end - table.insert( f44_local0, { + table.insert(f44_local0, { models = { tabIcon = CoD.buttonStrings.shoulderr }, properties = { m_mouseDisabled = true } - } ) + }) return f44_local0 -end, true ) \ No newline at end of file +end, true) diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 3268ccbf..55aa2f90 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -2,8 +2,8 @@ if Engine.GetCurrentMap() ~= "core_frontend" then return end -local EnableLobbyMapVote = true -- toggle map vote in public lobby -local EnableLargeServerBrowserButton = true -- toggle large server browser button +local enableLobbyMapVote = true -- toggle map vote in public lobby +local enableLargeServerBrowserButton = true -- toggle large server browser button local utils = require("utils") require("DataSources_StartMenuTabs") @@ -52,43 +52,42 @@ CoD.LobbyButtons.SETTING_UP_BOTS = { CoD.LobbyButtons.GameSettingsFlyoutArenas = { stringRef = "MPUI_SETUP_GAME_CAPS", - action = function( self, element, controller, param, menu ) - SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) - OpenPopup( menu, "GameSettingsFlyoutMP", controller ) + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "GameSettingsFlyoutMP", controller) end, customId = "btnGameSettingsFlyoutMP" } CoD.LobbyButtons.GameSettingsFlyoutMP = { stringRef = "MPUI_SETUP_GAME_CAPS", - action = function( self, element, controller, param, menu ) - SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) - OpenPopup( menu, "GameSettingsFlyoutMPCustom", controller ) + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "GameSettingsFlyoutMPCustom", controller) end, customId = "btnGameSettingsFlyoutMPCustom" } CoD.LobbyButtons.SERVER_BROWSER = { stringRef = "MENU_SERVER_BROWSER_CAPS", - action = function( self, element, controller, param, menu ) - SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) - OpenPopup( menu, "LobbyServerBrowserOnline", controller ) + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "LobbyServerBrowserOnline", controller) end, customId = "btnDedicated" } -local LobbyMapVoteIsEnabled = EnableLobbyMapVote -local LobbyMapVote = function( LobbyMapVoteIsEnabled ) - if LobbyMapVoteIsEnabled == true then - Engine.Exec( nil, "LobbyStopDemo" ) +local lobbyMapVoteIsEnabled = enableLobbyMapVote +local lobbyMapVote = function(lobbyMapVoteIsEnabled) + if lobbyMapVoteIsEnabled == true then + Engine.Exec(nil, "LobbyStopDemo") end end local addCustomButtons = function(controller, menuId, buttonTable, isLeader) - if menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id then utils.RemoveSpaces(buttonTable) - utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.THEATER_MP)-1) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.THEATER_MP) - 1) end if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then @@ -100,11 +99,10 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) end if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id then - LobbyMapVoteIsEnabled = EnableLobbyMapVote - if EnableLargeServerBrowserButton then + lobbyMapVoteIsEnabled = enableLobbyMapVote + if enableLargeServerBrowserButton then utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.SERVER_BROWSER, 1) end - elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEPUBLICGAME.id then utils.RemoveButton(buttonTable, CoD.LobbyButtons.MP_PUBLIC_LOBBY_LEADERBOARD) @@ -112,9 +110,8 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP, 2) utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP)) - LobbyMapVote( LobbyMapVoteIsEnabled ) - LobbyMapVoteIsEnabled = false - + lobbyMapVote(lobbyMapVoteIsEnabled) + lobbyMapVoteIsEnabled = false elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEARENAGAME.id then utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas, 2) @@ -125,11 +122,11 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) if menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then -- utils.RemoveButton(buttonTable,CoD.LobbyButtons.ZM_FIND_MATCH) utils.RemoveButton(buttonTable, CoD.LobbyButtons.THEATER_ZM) - utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM, #buttonTable+1) + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM, #buttonTable + 1) utils.RemoveSpaces(buttonTable) utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.SERVER_BROWSER)) - utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS)-1) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS) - 1) utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.STATS)) end end diff --git a/data/ui_scripts/frontend_menus/utils.lua b/data/ui_scripts/frontend_menus/utils.lua index 78b18d65..7abe1926 100644 --- a/data/ui_scripts/frontend_menus/utils.lua +++ b/data/ui_scripts/frontend_menus/utils.lua @@ -18,9 +18,9 @@ end local RemoveButton = function(buttonTable, button) for id, v in pairs(buttonTable) do - if buttonTable[id].optionDisplay == button.stringRef then - table.remove(buttonTable,id) - end + if buttonTable[id].optionDisplay == button.stringRef then + table.remove(buttonTable, id) + end end end @@ -33,8 +33,8 @@ end local GetButtonIndex = function(buttonTable, button) for id, v in pairs(buttonTable) do if buttonTable[id].optionDisplay == button.stringRef then - return id - end + return id + end end end From 954f612534b36aaa1fb8c654af016af6234e1677 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Wed, 12 Apr 2023 19:42:11 -0230 Subject: [PATCH 16/50] snake_case --- data/ui_scripts/frontend_menus/__init__.lua | 6 +++--- ...Categories.lua => datasources_change_map_categories.lua} | 0 ...uttons.lua => datasources_gamesettingslyout_buttons.lua} | 0 ...es_StartMenuTabs.lua => datasources_start_menu_tabs.lua} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename data/ui_scripts/frontend_menus/{DataSources_ChangeMapCategories.lua => datasources_change_map_categories.lua} (100%) rename data/ui_scripts/frontend_menus/{DataSources_GameSettingsFlyoutButtons.lua => datasources_gamesettingslyout_buttons.lua} (100%) rename data/ui_scripts/frontend_menus/{DataSources_StartMenuTabs.lua => datasources_start_menu_tabs.lua} (100%) diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 55aa2f90..47a0289b 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -6,9 +6,9 @@ local enableLobbyMapVote = true -- toggle map vote in public lobby local enableLargeServerBrowserButton = true -- toggle large server browser button local utils = require("utils") -require("DataSources_StartMenuTabs") -require("DataSources_ChangeMapCategories") -require("DataSources_GameSettingsFlyoutButtons") +require("datasources_start_menu_tabs") +require("datasources_change_map_categories") +require("datasources_gamesettingslyout_buttons") CoD.LobbyButtons.MP_PUBLIC_MATCH = { stringRef = "MENU_PLAY_CAPS", diff --git a/data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua b/data/ui_scripts/frontend_menus/datasources_change_map_categories.lua similarity index 100% rename from data/ui_scripts/frontend_menus/DataSources_ChangeMapCategories.lua rename to data/ui_scripts/frontend_menus/datasources_change_map_categories.lua diff --git a/data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua b/data/ui_scripts/frontend_menus/datasources_gamesettingslyout_buttons.lua similarity index 100% rename from data/ui_scripts/frontend_menus/DataSources_GameSettingsFlyoutButtons.lua rename to data/ui_scripts/frontend_menus/datasources_gamesettingslyout_buttons.lua diff --git a/data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua b/data/ui_scripts/frontend_menus/datasources_start_menu_tabs.lua similarity index 100% rename from data/ui_scripts/frontend_menus/DataSources_StartMenuTabs.lua rename to data/ui_scripts/frontend_menus/datasources_start_menu_tabs.lua From b32168dce6642853d3712ee6d7f0a8e67e65f25c Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Wed, 12 Apr 2023 19:50:41 -0230 Subject: [PATCH 17/50] Make these changes InGame only --- data/ui_scripts/party/__init__.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/ui_scripts/party/__init__.lua b/data/ui_scripts/party/__init__.lua index a2a96f46..5821c1fd 100644 --- a/data/ui_scripts/party/__init__.lua +++ b/data/ui_scripts/party/__init__.lua @@ -1,3 +1,7 @@ +if not Engine.IsInGame() then + return +end + -- Removed check for public matches to allow team change in ranked matches CoD.IsTeamChangeAllowed = function() if Engine.GetGametypeSetting( "allowInGameTeamChange" ) == 1 then From 07586dfeee41e79babffde3e739a59aeea5f949f Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Wed, 12 Apr 2023 19:51:35 -0230 Subject: [PATCH 18/50] Standard Lua formating --- data/ui_scripts/party/__init__.lua | 16 ++++++++-------- ...a => datasources_start_menu_game_options.lua} | 0 2 files changed, 8 insertions(+), 8 deletions(-) rename data/ui_scripts/party/{DataSources_StartMenuGameOptions.lua => datasources_start_menu_game_options.lua} (100%) diff --git a/data/ui_scripts/party/__init__.lua b/data/ui_scripts/party/__init__.lua index 5821c1fd..cd6c5e3e 100644 --- a/data/ui_scripts/party/__init__.lua +++ b/data/ui_scripts/party/__init__.lua @@ -4,24 +4,24 @@ end -- Removed check for public matches to allow team change in ranked matches CoD.IsTeamChangeAllowed = function() - if Engine.GetGametypeSetting( "allowInGameTeamChange" ) == 1 then + if Engine.GetGametypeSetting("allowInGameTeamChange") == 1 then return true else return false end end -local GetModeInfo = function() +local getModeInfo = function() local id = Engine.GetLobbyUIScreen() - return LobbyData:UITargetFromId(id) + return LobbyData:UITargetFromId(id) end -local GetMaxClients = function() - local ModeInfo = GetModeInfo() - return ModeInfo.maxClients +local getMaxClients = function() + local modeInfo = getModeInfo() + return modeInfo.maxClients end -- Set com_maxclients InGame so players can join via direct connect (default from lobbydata) -Engine.SetDvar( "com_maxclients", GetMaxClients() ) +Engine.SetDvar("com_maxclients", getMaxClients()) -require("DataSources_StartMenuGameOptions") +require("datasources_start_menu_game_options") diff --git a/data/ui_scripts/party/DataSources_StartMenuGameOptions.lua b/data/ui_scripts/party/datasources_start_menu_game_options.lua similarity index 100% rename from data/ui_scripts/party/DataSources_StartMenuGameOptions.lua rename to data/ui_scripts/party/datasources_start_menu_game_options.lua From c5091bef79c7f5dc4fe2f5f0215cf12110f0356e Mon Sep 17 00:00:00 2001 From: efinst0rm Date: Sat, 15 Apr 2023 12:39:41 -0500 Subject: [PATCH 19/50] Use current production _serversettings.gsc --- data/scripts/mp/gametypes/_serversettings.gsc | Bin 4518 -> 4612 bytes .../mp/gametypes/_serversettings.gsc_raw | 25 +++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/data/scripts/mp/gametypes/_serversettings.gsc b/data/scripts/mp/gametypes/_serversettings.gsc index 0105b093db16db0bee7ce860fc6f1d226bf54fea..bf3985aab646d5b010b7fea76bcc9567366f1d51 100644 GIT binary patch literal 4612 zcmZ8k3viUx6+ZuNs4>dAg0x#@HlLZowu%)W9ivha5laEJj!GG&&~p-hvScSW|M|{2_dDm_ z|DJpA-&e9~;mjPE``|6z`vw_+fE3`#pPpH>04i?=xP*;lYA@vgG@<>MkPS|l{E0yX z$zXd^B9*iRwKgP@P2FK|JHcTGn;UW=S{KEf zCVGTgA%!iNia=~FBty^~PsOf{vNd55Jd>8XDUg4o~X++x^Y4~P2>AgxRTd}C#MKb-Uf6!|v z+k5XlhY7!;g;h$=n#D&{cN`@=?3JCCnQ(OFyo~xD{mlhZX!VVuypiMFWP8UiVb#2;m*m}fwLaofyTKXC(y3Jjqh9BMl|ml9-p&oTp8Ke+D)#{w zJ%m6V4|n`4whKtVEZPE?Ss6~{7W=~+SYX;X=VxE48~E7Gmug*bB@681j6G@pFV z$z6sIC*vgqdz&5e(8p}2NN)tYkVmVz%dz>t6*(9DGC4hGYg#lEdz;}oRtjnNmnbjy zYwO6ySt&-yL$cfw^b?m_2`yy{RvUykx%m=yT&1lipP0j^_!@mQ9Bi1f@6IF68edU7 zbmsNbzxGPl5xq`FvfN@%Tt=Hj4FSRb9Rt0`Du)zn7RMZY>XBy#(FNa8Wa;wXoZQxv zCt)A9Cc-2$uIgqv`Wd}o68cj<8bfcf4fU97nK14neqAGt^BjAW)q;fGl**w5mqS5(_I2jK%3!FDskkkv8qojtK|H6@el*8Ui@ZGil>)C{5$cOXh zz5T7RPYAc!gSj)7^g5PUzPKu7^X8L|emlHbsaer)zkrn%!(%1RAy`_OULcp;0j=we z^ZvA03wKlfS&ON5PirA2+l58b^ClyTm}X*sh)$@Ad*wL!Yr(MRmAGE>gdyf6{4$t3FZb3JHb-wRLx&MZzW=%bKW;a1W~z>gWd!Qkz_lYN>vPmC$*o ziFk+IP_V;HxlN}%vr={?Zs{0q;xiaL@y$0l$dvttDNp*XJbOHO}FD;vHupG|LBh0&klA z%u>UAB^PTx%&$UTt!}$60B zTA(82$aeOuARV0>#JgVou9bM-&WEnKYKREDKX+}mkI?$>E_5~^Z;#%u2tX$fnrit~ zJ73z-^3aSurV+OcJSNDmcaG${45a&%OT>tGi>pdWy!b|JH7wW#Ua#^oS2^)^9ngi4 z_a&d%UIcgh!SQd)t+_24drQ~8C$vqx4Bj(>c1#^N*M&$ortt(P^BvU_?-&dIXK_6X zy!TliGc#r1x;@r6{wHM@ti}{3e!q8Q8E9_-ZM|<|{V6sSO{~ATPB*ds@EpXwEg`Hw zwN(^&S$l@hkuz1Cb)TDY^z)+V?RlNbIhq%lVK)<*qZBRu#Bm@W5>#UzlQ=x!gX*2> z=9?(s{p#%IbF5!c3J+Mp^rodCzqfexHy@7`+pjoe@DLAWC)D#)x<=9k6#TU@$#6`) zHVEyqL68m_VO+N>-m^Lx3HyLm+=Y9(Mu>CXB(-caJn1Zjejd6Lz6GwX_~4^o9f}$L z<(1(+0F8dfMx&>gbit})+~ejmB3ZYOPoO)>GmsKb(3+v#P=s*_qoA{ zzggDy#SM4FRb#mgS?N(?O;&jR9^U;Z#z$2=|q+&SZs(=10q84j!$dy462e{Q- zwEN7Y^ZR?&QJg*MZUx1`-6{Gy2Y5OyGYE0=?3eva!2$hy*1RiHwx)JsG2p+MY_-pZ zC(v-=+HTU#P~?|=ZC`!M3sxx`(VKizejm$kQG1u1t{z&u#v)}u7`iy{46fIP-@a

GK^<{6v7qA5j?2qK@va6FTgC_}%_;8QSPxD(LKcH}%8M0O;%zbdT>J-n8`w06GUr zhcxh?`i&sP?-4o!1>J+Ke_X`k_X?eZLSHABcshVO8iSw{azGyWe*8!G=6>JP2N}o` z{S~p057{r^Ke{JtPrdvR1B~brVmenQV=@XA=1=?iBo-+W)9?`DO#hK-_Dj?7T=Dh( zPQ;n~eHj?Py%f6;AHn%b;rwL!y^nf2r-VE&Wb|XO-)&jf$1x(#>|cqP?kPh5u4(pN z)9i;b>>}j9fOszEl*y4j~KpVkhFM_s=NC5DV`fUz73} zVqqO2R-8bb$!ElQ%N%nH;!OMIY4`-<%sF-9_-HSjoFh<-BBq-939Fph*W)eI@aNMo zf8+K3L(}jD#F_D&xc+HR5Z+M=u@E1ZmFf`Ut+>->`kct{!8uWBr`e09;St0FC;4AO zEYuQWxdLlzC)Oj%a0LI+T@jZWv|s{SoG%ui^sRtX564g*$5xIGJg$!-lV$1-c&+*LNuQq3#)c(w&cd4k4DI@zhT~y(o{P&Wcak?=USGMOlS&+>7mf zY(|{F&Dc(0+mG`g!?E;XJBzIzed*pu+%kNRI}y|O6y~xnPc?9ME1C<-B A;Q#;t literal 4518 zcmZ8k33yc16+Uk!P>6AiOLaa)eY0ldxY~fwk=EJmGe!ceM5CibxbpTr~J)gWDU{(RZUK~W{Mm|6@>TiX~V1u!r6eN&| zv^S-*8Ed318WZVEw!I^gy{yV48`@)0YosBSYHWx!XF_9wiTX@;CL3$Htc_O;?2IJJiyajgm0;OoY&1+w#t~Yz*uqy~5fq zv!QIPp(T=RXidZ*-rf{zji$QeP3^I4cREH!<7E_YsHGvDY3hlAn+K-@>~1K6L@0q# z2OVDJl^ote3E-rg{;1%dN$GYqxlhU*tKKX zk6tH!pB_vV3ss&G^=$`;f5KbHE}au-Bbt6>zsnMBcpmAK2B=!H_l}(Izh-w?=UsRF z?m6L@nVxB9dHQ9v=`|Jv3Zccf2kDiXu6)wH=a;csLE|R+sbX^y6zc-&eAkFND)P#iQe$37UIL zv5Y*2vfaYlYzkJo8=yG(P^bZ5s(s#|x494;|Y? zdn{K(bM%YeDy0hTaE}*>^X)zvTdnHua-y8`f=DO!Q=Nr^*;Ei99ECO1e>cwGshVdZ9ETeMBF>xK zs3zyjP*)#B-7&pAN;Y^t6Sk6yxM)Xt{9Iu)lkQss_(VUI2JhVV??$C++y~0e9Mog( zip4zRS(=_*U^Trn7+p(wqW$c5SJu!R+>dTU=PMeLQ++>TgO*$0+4CXskMa9_lloub zUNoJ$SjcjVNk+f*T%PTQ#Mh@_R`T9omhnTdcwT&_LUtQeR_pHk{Tw|s$XK0eu8Ge2 zpaJY+9KQ`n8wRx+FP-yVt5kc3`2fp7qgGm8>?BzS*8N(WyN2l17NLXg0j#6D#r40* z$=DHpZy%jqnHJn4?z3J={7{j}OXoIWlPo$K=uvX;r9z^tG?458JaZ@fP7TqM>`4cm zYuxjch?_$Fap%0I<0!|x)rz=A2a{dxVw7|ad#y|-ujUc=2^AAKmy=Q5|Iw<>kbaWg za}S-RI}g3b-%_KW9cqZ5`rU|Zv&v-2(o+M`7U0S>ns8apf`dq^Q; zCAJl5qEGYT8ahuW1gI2oAL9$zI9}}NF83Sp=FMJy>Od!iU8ZRL;9S5<{e|zAya}GA zb3Q#^_%sA$Y`YfPG}RS5G!pl2^X}qWl~%IY#FXt1 zNXna>2Q84^t=g`TcCF$TV+?x3MIi_#1LQkQ)oP8~u(bbCsX?ce!`BKhFAr?c^wpD$ zartt0%uV)F4V# z@02iqDN^2RkwaJu#Wl9Qj_MgCJ6w|R(A~A)_=tgU4=Q27S_^cFxT~xWYU>!RrxgR% zI>dcScLw7v zgHI<3SK$3h!tE5mj(Kp1xN`MI(=*Uvly)69M-ca-*=!5~dUvLM5+SAQNZmhahhe{3 z4h9YAtIWIAp(x3A89WifUE#Jk2zRj`{O7QqMcmo8*Bpyrl$BN_opHoH;_WUjg^NCz z8RloYmY5u=uIGxBw>#xX!CBiR|Xa>ZC4*0YyzOY_~(CgN5o^A(KY=Our& z9sItKH8?PY+^^4(m!`V}g0;?E{Uzd+x%x}T?#b0(GoC*cn8o^=#7X*gST_65`mVlDhw5WT@S0C(Ipwigo@P`uUa+n?#bXJm8t9rUq~EIaF%Fzg@FT zt)D|Og|(-Z{8U?7v2JDTQX|Z0HiIT&cZEbhDcdymZPe{yr5v7TUi6dJvP>Amvul@jl-dZF>7`SlV z+#}QR>x14{qD;g_y<#W+qwaUm_vBs%@+5ykUi3ryFYq6AyZYlVA7OxzoI{>&d%}_e zqf}#D?@t0KK)-a`j>#p;G|Cs{0X&K^igE@d$|01C^AS(^4D#dk=O*yeq*vRc)2r+U zCh%L4r>^eOT9qTnQ#U8_f1hAqh%wSzW=zj0IpoL3mqLDge4CJ`E<&__X@dU51U+DG z#?R-FA3r}hL7$z#Z<=5~jQo}TWt1Nwe`RkO<$2`An!v467GVCzucvMTKRjW7zL~(6 zSsI zug5QFQATs7A;x%LQRL}HAYT%!rLD*x#rsZ_QGFF4KOUoIf<8Mz|0?P6+@L=g!GF|| z;W{9NLDgVxSbS0kj%kLsksigd2o3sh-%F9EFFBe!AL$W%;sZ9}ybVZD7e-j$AiWc1 z+we)971^9cUXIG+mu&iwo`Siw;gfC^Oa+`pdJ*RB8Oj~zrw+$3jsjfwM>v8Q`%WBk zG!COJbytKPM4T#!0J8>jYPG1o;e-!C;IOuBt|A0k3b@W6hk*3a_=yga_2Tt@Mq^WZv lT8-xPn`hC??am2-b5co`v1o6m&5=7 diff --git a/data/scripts/mp/gametypes/_serversettings.gsc_raw b/data/scripts/mp/gametypes/_serversettings.gsc_raw index 580e2966..e420ca3c 100644 --- a/data/scripts/mp/gametypes/_serversettings.gsc_raw +++ b/data/scripts/mp/gametypes/_serversettings.gsc_raw @@ -3,11 +3,9 @@ #using scripts\shared\callbacks_shared; #using scripts\shared\system_shared; -#insert scripts\shared\shared.gsh; - #namespace serversettings; -REGISTER_SYSTEM( "serversettings", &__init__, undefined ) +function autoexec __init__sytem__() { system::register("serversettings",&__init__,undefined,undefined); } function __init__() { @@ -17,36 +15,33 @@ function __init__() function init() { level.hostname = GetDvarString( "sv_hostname"); - if (level.hostname == "") - { + if(level.hostname == "") level.hostname = "CoDHost"; - } - SetDvar("sv_hostname", level.hostname); SetDvar("ui_hostname", level.hostname); + //makeDvarServerInfo("ui_hostname", "CoDHost"); level.motd = GetDvarString( "scr_motd" ); if(level.motd == "") - { level.motd = ""; - } SetDvar("scr_motd", level.motd); SetDvar("ui_motd", level.motd); + //makeDvarServerInfo("ui_motd", ""); level.allowvote = GetDvarString( "g_allowvote" ); if(level.allowvote == "") - { level.allowvote = "1"; - } SetDvar("g_allowvote", level.allowvote); SetDvar("ui_allowvote", level.allowvote); - + //makeDvarServerInfo("ui_allowvote", "1"); + level.allow_teamchange = "1"; SetDvar("ui_allow_teamchange", level.allow_teamchange); level.friendlyfire = GetGametypeSetting( "friendlyfiretype" ); SetDvar("ui_friendlyfire", level.friendlyfire); + //makeDvarServerInfo("ui_friendlyfire", "0"); if(GetDvarString( "scr_mapsize") == "") SetDvar("scr_mapsize", "64"); @@ -62,7 +57,7 @@ function init() constrain_gametype(GetDvarString( "g_gametype")); constrain_map_size(level.mapsize); - + thread setup_callbacks(); for(;;) @@ -88,7 +83,7 @@ function update() SetDvar("ui_motd", level.motd); } - g_allowvote = GetDvarString( "g_allowvote"); + g_allowvote = GetDvarString( "g_allowvote" ); if(level.allowvote != g_allowvote) { level.allowvote = g_allowvote; @@ -211,4 +206,4 @@ function setup_callbacks() function default_onForfeit() { level.gameForfeited = false; -} +} \ No newline at end of file From af76836254af81d0e0167fe46d80b7f009799759 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Sun, 16 Apr 2023 18:33:31 -0230 Subject: [PATCH 20/50] cg_unlockall_cac_slots dvar --- src/client/component/loot.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/client/component/loot.cpp b/src/client/component/loot.cpp index 291bcdd6..b95301dc 100644 --- a/src/client/component/loot.cpp +++ b/src/client/component/loot.cpp @@ -17,6 +17,7 @@ namespace loot const game::dvar_t* dvar_cg_unlockall_camos_and_reticles; const game::dvar_t* dvar_cg_unlockall_calling_cards; const game::dvar_t* dvar_cg_unlockall_specialists_outfits; + const game::dvar_t* dvar_cg_unlockall_cac_slots; utils::hook::detour loot_getitemquantity_hook; utils::hook::detour liveinventory_getitemquantity_hook; @@ -30,7 +31,8 @@ namespace loot utils::hook::detour bg_unlockablescharactercustomizationitemlocked_hook; utils::hook::detour bg_emblemisentitlementbackgroundgranted_hook; utils::hook::detour liveentitlements_isentitlementactiveforcontroller_hook; - + utils::hook::detour bg_unlockablesgetcustomclasscount_hook; + int loot_getitemquantity_stub(const game::ControllerIndex_t controller_index, const game::eModes mode, const int item_id) { if (!dvar_cg_unlockall_loot->current.value.enabled) @@ -60,7 +62,7 @@ namespace loot bool liveinventory_areextraslotspurchased_stub(const game::ControllerIndex_t controller_index) { - if (dvar_cg_unlockall_loot->current.value.enabled) + if (dvar_cg_unlockall_cac_slots->current.value.enabled) { return true; } @@ -160,9 +162,19 @@ namespace loot return liveentitlements_isentitlementactiveforcontroller_hook.invoke(controllerIndex, incentiveId); } + + int bg_unlockablesgetcustomclasscount_stub(game::eModes mode, const game::ControllerIndex_t controllerIndex) + { + if (dvar_cg_unlockall_cac_slots->current.value.enabled) + { + return 10; + } + + return bg_unlockablesgetcustomclasscount_hook.invoke(mode, controllerIndex); + } }; - struct component final : client_component + struct component final: client_component { void post_unpack() override { @@ -172,6 +184,7 @@ namespace loot dvar_cg_unlockall_camos_and_reticles = game::register_dvar_bool("cg_unlockall_camos_and_reticles", false, game::DVAR_ARCHIVE, "Unlocks all camos and reticles"); dvar_cg_unlockall_calling_cards = game::register_dvar_bool("cg_unlockall_calling_cards", false, game::DVAR_ARCHIVE, "Unlocks all calling cards"); dvar_cg_unlockall_specialists_outfits = game::register_dvar_bool("cg_unlockall_specialists_outfits", false, game::DVAR_ARCHIVE, "Unlocks all specialists outfits"); + dvar_cg_unlockall_cac_slots = game::register_dvar_bool("cg_unlockall_cac_slots", false, game::DVAR_ARCHIVE, "Unlocks all Create a Class Slots"); loot_getitemquantity_hook.create(0x141E82C00_g, loot_getitemquantity_stub); liveinventory_getitemquantity_hook.create(0x141E09030_g, liveinventory_getitemquantity_stub); @@ -185,6 +198,7 @@ namespace loot bg_unlockablescharactercustomizationitemlocked_hook.create(0x1426A2030_g, bg_unlockablescharactercustomizationitemlocked_stub); bg_emblemisentitlementbackgroundgranted_hook.create(0x142667520_g, bg_emblemisentitlementbackgroundgranted_stub); liveentitlements_isentitlementactiveforcontroller_hook.create(0x141E124E0_g, liveentitlements_isentitlementactiveforcontroller_stub); + bg_unlockablesgetcustomclasscount_hook.create(0x1426A5900_g, bg_unlockablesgetcustomclasscount_stub); scheduler::once([]() { if (dvar_cg_unlockall_loot->current.value.enabled) From b6bc9e6fa4563231cddaa8357e3f5216cef1ae09 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Sun, 16 Apr 2023 21:02:59 -0230 Subject: [PATCH 21/50] Add unlock class slots togle to stats menu --- data/ui_scripts/cac_options/__init__.lua | 21 --------------------- data/ui_scripts/stats/__init__.lua | 13 ++++++++++++- 2 files changed, 12 insertions(+), 22 deletions(-) delete mode 100644 data/ui_scripts/cac_options/__init__.lua diff --git a/data/ui_scripts/cac_options/__init__.lua b/data/ui_scripts/cac_options/__init__.lua deleted file mode 100644 index 8079e04d..00000000 --- a/data/ui_scripts/cac_options/__init__.lua +++ /dev/null @@ -1,21 +0,0 @@ -Dvar.purchasedClassSetCount:set( 10 ) - -Engine.GetCustomClassCount = function( arg0 ) - return 10 -end - -Engine.GetNumberOfClassSetsOwned = function( arg0 ) - return 10 -end - -Engine.IsClassSetsAvailableForCurrentGameMode = function() - return true -end - -function IsClassSetsAvailableForCurrentGameMode() - return Engine.IsClassSetsAvailableForCurrentGameMode() -end - -function DoesPlayerHaveExtraSlotsItem( arg0 ) - return true -end diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua index a20f2ea3..b9b5a34b 100644 --- a/data/ui_scripts/stats/__init__.lua +++ b/data/ui_scripts/stats/__init__.lua @@ -42,7 +42,18 @@ DataSources.MPStatsSettings = DataSourceHelpers.ListSetup( "MPStatsSettings", fu }, }, nil, updateDvar )) end - table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock All Attachments", "All attachments on weapons are unlocked.", "MPStatsSettings_unlockall_attachments", "cg_unlockall_attachments", { + table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock All Class Slots", "Unlock all create-a-class slots and sets.", "MPStatsSettings_unlockall_cac_slots", "cg_unlockall_cac_slots", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar )) + table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock All Attachments", "All attachments on weapons are unlocked.", "MPStatsSettings_unlockall_attachments", "cg_unlockall_attachments", { { option = "MENU_DISABLED", value = 0, From d069df0c869758a8e40258af4c86c65eb154851c Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Sun, 16 Apr 2023 21:04:30 -0230 Subject: [PATCH 22/50] associate cac item_id with cg_unlockall_cac_slots --- src/client/component/loot.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/client/component/loot.cpp b/src/client/component/loot.cpp index b95301dc..329439d4 100644 --- a/src/client/component/loot.cpp +++ b/src/client/component/loot.cpp @@ -50,13 +50,19 @@ namespace loot int liveinventory_getitemquantity_stub(const game::ControllerIndex_t controller_index, const int item_id) { - // Item id's for extra CaC slots, CWL camo's and paid specialist outfits + // Item id's for CWL camo's and paid specialist outfits if (dvar_cg_unlockall_loot->current.value.enabled && (item_id == 99003 || item_id >= 99018 && item_id <= 99021 || item_id == 99025 || item_id >= 90047 && item_id <= 90064)) { return 1; } + // Item id for extra CaC slots + if (dvar_cg_unlockall_cac_slots->current.value.enabled && (item_id == 99003)) + { + return 1; + } + return liveinventory_getitemquantity_hook.invoke(controller_index, item_id); } @@ -205,7 +211,7 @@ namespace loot { game::Dvar_SetFromStringByName("ui_enableAllHeroes", "1", true); } - }, scheduler::pipeline::dvars_loaded); + }, scheduler::pipeline::dvars_loaded); } }; }; From 336cea2047b39669f7dca234f859ce40f6d9d04d Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Sat, 15 Apr 2023 05:19:26 -0230 Subject: [PATCH 23/50] Rename playlist widgets --- data/ui_scripts/playlist/__init__.lua | 4 ++-- ...o.lua => widget_playlist_category_match_settings_info.lua} | 0 ...ttingsInfo.lua => widget_playlist_match_settings_info.lua} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename data/ui_scripts/playlist/{DataSources_playlistCategoryMatchSettingsInfo.lua => widget_playlist_category_match_settings_info.lua} (100%) rename data/ui_scripts/playlist/{DataSources_playlistMatchSettingsInfo.lua => widget_playlist_match_settings_info.lua} (100%) diff --git a/data/ui_scripts/playlist/__init__.lua b/data/ui_scripts/playlist/__init__.lua index a0bb56aa..545529f8 100644 --- a/data/ui_scripts/playlist/__init__.lua +++ b/data/ui_scripts/playlist/__init__.lua @@ -17,5 +17,5 @@ Engine.SetDvar( "lobbyTimerStatusStartInterval", 10 ) Engine.SetDvar( "lobbyTimerStatusPostGameInterval", 10 ) Engine.SetDvar( "lobbyTimerStatusVotingInterval_Arena", 11000 ) -require("DataSources_playlistMatchSettingsInfo") -require("DataSources_playlistCategoryMatchSettingsInfo") \ No newline at end of file +require("widget_playlist_match_settings_info") +require("widget_playlist_category_match_settings_info") \ No newline at end of file diff --git a/data/ui_scripts/playlist/DataSources_playlistCategoryMatchSettingsInfo.lua b/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua similarity index 100% rename from data/ui_scripts/playlist/DataSources_playlistCategoryMatchSettingsInfo.lua rename to data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua diff --git a/data/ui_scripts/playlist/DataSources_playlistMatchSettingsInfo.lua b/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua similarity index 100% rename from data/ui_scripts/playlist/DataSources_playlistMatchSettingsInfo.lua rename to data/ui_scripts/playlist/widget_playlist_match_settings_info.lua From 783e2c2a9ff3034949b5207f897f64faf67b3d3d Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Sat, 15 Apr 2023 05:26:27 -0230 Subject: [PATCH 24/50] Better override strategy --- ..._playlist_category_match_settings_info.lua | 73 ++------- .../widget_playlist_match_settings_info.lua | 147 ++---------------- 2 files changed, 22 insertions(+), 198 deletions(-) diff --git a/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua b/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua index f630cb64..28c34d25 100644 --- a/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua +++ b/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua @@ -1,66 +1,15 @@ -CoD.playlistCategoryMatchSettingsInfo = InheritFrom( LUI.UIElement ) -CoD.playlistCategoryMatchSettingsInfo.new = function ( menu, controller ) - local self = LUI.UIElement.new() +if not CoD.playlistCategoryMatchSettingsInfo then + return +end - if PreLoadFunc then - PreLoadFunc( self, controller ) +local oldPlaylistCategoryMatchSettingsInfo = CoD.playlistCategoryMatchSettingsInfo.new +function CoD.playlistCategoryMatchSettingsInfo.new(menu, controller) + local self = oldPlaylistCategoryMatchSettingsInfo(menu, controller) + + -- Hide the playlist count text + if self.playlistCount then + self.playlistCount:setAlpha(0) end - self:setUseStencil( false ) - self:setClass( CoD.playlistCategoryMatchSettingsInfo ) - self.id = "playlistCategoryMatchSettingsInfo" - self.soundSet = "default" - self:setLeftRight( true, false, 0, 450 ) - self:setTopBottom( true, false, 0, 550 ) - self.anyChildUsesUpdateState = true - - local categoryInfo = CoD.matchSettingsInfo.new( menu, controller ) - categoryInfo:setLeftRight( true, false, 0, 450 ) - categoryInfo:setTopBottom( true, false, 0, 550 ) - categoryInfo.FRBestTime.BestTimeValueText:setText( Engine.Localize( "--:--:--" ) ) - categoryInfo:linkToElementModel( self, nil, false, function ( model ) - categoryInfo:setModel( model, controller ) - end ) - categoryInfo:mergeStateConditions( { - { - stateName = "AspectRatio_1x1", - condition = function ( menu, element, event ) - return AlwaysTrue() - end - } - } ) - self:addElement( categoryInfo ) - self.categoryInfo = categoryInfo - - -- local playlistCount = LUI.UITightText.new() - -- playlistCount:setLeftRight( true, false, 1, 446 ) - -- playlistCount:setTopBottom( true, false, -22, -2 ) - -- playlistCount:setTTF( "fonts/RefrigeratorDeluxe-Regular.ttf" ) - -- playlistCount:linkToElementModel( self, "playlistCount", true, function ( model ) - -- local _playlistCount = Engine.GetModelValue( model ) - -- if _playlistCount then - -- playlistCount:setText( Engine.Localize( _playlistCount ) ) - -- end - -- end ) - -- self:addElement( playlistCount ) - -- self.playlistCount = playlistCount - - self.clipsPerState = { - DefaultState = { - DefaultClip = function () - self:setupElementClipCounter( 0 ) - end - } - } - - LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) - element.categoryInfo:close() - -- element.playlistCount:close() - end ) - - if PostLoadFunc then - PostLoadFunc( self, controller, menu ) - end - return self -end \ No newline at end of file +end diff --git a/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua b/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua index 4aba6c7c..9b31390e 100644 --- a/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua +++ b/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua @@ -1,140 +1,15 @@ -CoD.playlistMatchSettingsInfo = InheritFrom( LUI.UIElement ) -CoD.playlistMatchSettingsInfo.new = function ( menu, controller ) - local self = LUI.UIElement.new() +if not CoD.playlistMatchSettingsInfo then + return +end - if PreLoadFunc then - PreLoadFunc( self, controller ) +local oldPlaylistMatchSettingsInfo = CoD.playlistMatchSettingsInfo.new +function CoD.playlistMatchSettingsInfo.new(menu, controller) + local self = oldPlaylistMatchSettingsInfo(menu, controller) + + -- Hide the playlist count text + if self.playlistCount then + self.playlistCount:setAlpha(0) end - self:setUseStencil( false ) - self:setClass( CoD.playlistMatchSettingsInfo ) - self.id = "playlistMatchSettingsInfo" - self.soundSet = "default" - self:setLeftRight( true, false, 0, 450 ) - self:setTopBottom( true, false, 0, 550 ) - self.anyChildUsesUpdateState = true - - local gameModeInfo = CoD.matchSettingsInfo.new( menu, controller ) - gameModeInfo:setLeftRight( true, false, 0, 446 ) - gameModeInfo:setTopBottom( true, false, 0, 550 ) - gameModeInfo.FRBestTime.BestTimeValueText:setText( Engine.Localize( "--:--:--" ) ) - gameModeInfo:linkToElementModel( self, nil, false, function ( model ) - gameModeInfo:setModel( model, controller ) - end ) - gameModeInfo:mergeStateConditions( { - { - stateName = "AspectRatio_1x1", - condition = function ( menu, element, event ) - return AlwaysTrue() - end - } - } ) - self:addElement( gameModeInfo ) - self.gameModeInfo = gameModeInfo - - -- local playlistCount = LUI.UIText.new() - -- playlistCount:setLeftRight( true, false, 1, 446 ) - -- playlistCount:setTopBottom( true, false, -22, -2 ) - -- playlistCount:setTTF( "fonts/RefrigeratorDeluxe-Regular.ttf" ) - -- playlistCount:setAlignment( Enum.LUIAlignment.LUI_ALIGNMENT_LEFT ) - -- playlistCount:setAlignment( Enum.LUIAlignment.LUI_ALIGNMENT_TOP ) - -- playlistCount:linkToElementModel( self, "playlistCount", true, function ( model ) - -- local _playlistCount = Engine.GetModelValue( model ) - -- if _playlistCount then - -- playlistCount:setText( Engine.Localize( _playlistCount ) ) - -- end - -- end ) - -- self:addElement( playlistCount ) - -- self.playlistCount = playlistCount - - local PlaylistSpecialEventWidget = CoD.Playlist_SpecialEventWidget.new( menu, controller ) - PlaylistSpecialEventWidget:setLeftRight( true, false, 8.55, 408.55 ) - PlaylistSpecialEventWidget:setTopBottom( true, false, 277, 307 ) - PlaylistSpecialEventWidget:linkToElementModel( self, nil, false, function ( model ) - PlaylistSpecialEventWidget:setModel( model, controller ) - end ) - PlaylistSpecialEventWidget:mergeStateConditions( { - { - stateName = "DoubleXPWeaponXP", - condition = function ( menu, element, event ) - return IsSelfModelValueEqualTo( element, controller, "hasDoubleXP", true ) and IsSelfModelValueEqualTo( element, controller, "hasDoubleWeaponXP", true ) - end - }, - { - stateName = "DoubleXPDoubleCryptokeys", - condition = function ( menu, element, event ) - return IsSelfModelValueEqualTo( element, controller, "hasDoubleXP", true ) and IsSelfModelValueEqualTo( element, controller, "hasDoubleCryptokeys", true ) - end - }, - { - stateName = "WeaponXPDoubleCryptokeysCopy", - condition = function ( menu, element, event ) - return IsSelfModelValueEqualTo( element, controller, "hasDoubleWeaponXP", true ) and IsSelfModelValueEqualTo( element, controller, "hasDoubleCryptokeys", true ) - end - }, - { - stateName = "DoubleXP", - condition = function ( menu, element, event ) - return IsSelfModelValueEqualTo( element, controller, "hasDoubleXP", true ) - end - }, - { - stateName = "DoubleWeaponXP", - condition = function ( menu, element, event ) - return IsSelfModelValueEqualTo( element, controller, "hasDoubleWeaponXP", true ) - end - }, - { - stateName = "DoubleCryptokeys", - condition = function ( menu, element, event ) - return IsSelfModelValueEqualTo( element, controller, "hasDoubleCryptokeys", true ) - end - } - } ) - PlaylistSpecialEventWidget:linkToElementModel( PlaylistSpecialEventWidget, "hasDoubleXP", true, function ( model ) - menu:updateElementState( PlaylistSpecialEventWidget, { - name = "model_validation", - menu = menu, - modelValue = Engine.GetModelValue( model ), - modelName = "hasDoubleXP" - } ) - end ) - PlaylistSpecialEventWidget:linkToElementModel( PlaylistSpecialEventWidget, "hasDoubleWeaponXP", true, function ( model ) - menu:updateElementState( PlaylistSpecialEventWidget, { - name = "model_validation", - menu = menu, - modelValue = Engine.GetModelValue( model ), - modelName = "hasDoubleWeaponXP" - } ) - end ) - PlaylistSpecialEventWidget:linkToElementModel( PlaylistSpecialEventWidget, "hasDoubleCryptokeys", true, function ( model ) - menu:updateElementState( PlaylistSpecialEventWidget, { - name = "model_validation", - menu = menu, - modelValue = Engine.GetModelValue( model ), - modelName = "hasDoubleCryptokeys" - } ) - end ) - self:addElement( PlaylistSpecialEventWidget ) - self.PlaylistSpecialEventWidget = PlaylistSpecialEventWidget - - self.clipsPerState = { - DefaultState = { - DefaultClip = function () - self:setupElementClipCounter( 0 ) - end - } - } - - LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) - element.gameModeInfo:close() - element.PlaylistSpecialEventWidget:close() - -- element.playlistCount:close() - end ) - - if PostLoadFunc then - PostLoadFunc( self, controller, menu ) - end - return self -end \ No newline at end of file +end From 1abb08f773a54acb215ec1853a0b51145e4a1bf8 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Sat, 15 Apr 2023 05:27:37 -0230 Subject: [PATCH 25/50] Remove commented code --- data/ui_scripts/frontend_menus/__init__.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 47a0289b..8fbc5d21 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -120,7 +120,6 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) end if menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then - -- utils.RemoveButton(buttonTable,CoD.LobbyButtons.ZM_FIND_MATCH) utils.RemoveButton(buttonTable, CoD.LobbyButtons.THEATER_ZM) utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM, #buttonTable + 1) From 7966d81ab99e3db188a221b542afabc506470c24 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Sat, 15 Apr 2023 05:29:01 -0230 Subject: [PATCH 26/50] whitespace formatting --- data/ui_scripts/playlist/__init__.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/ui_scripts/playlist/__init__.lua b/data/ui_scripts/playlist/__init__.lua index 545529f8..f5eb933f 100644 --- a/data/ui_scripts/playlist/__init__.lua +++ b/data/ui_scripts/playlist/__init__.lua @@ -10,12 +10,12 @@ function IsLobbyStatusVisible() return false end -Engine.SetDvar( "lobbyMigrate_Enabled", 0 ) -Engine.SetDvar( "lobbyTimerStatusVotingInterval", 11000 ) -Engine.SetDvar( "lobbyTimerStatusBeginInterval", 10 ) -Engine.SetDvar( "lobbyTimerStatusStartInterval", 10 ) -Engine.SetDvar( "lobbyTimerStatusPostGameInterval", 10 ) -Engine.SetDvar( "lobbyTimerStatusVotingInterval_Arena", 11000 ) +Engine.SetDvar("lobbyMigrate_Enabled", 0) +Engine.SetDvar("lobbyTimerStatusVotingInterval", 11000) +Engine.SetDvar("lobbyTimerStatusBeginInterval", 10) +Engine.SetDvar("lobbyTimerStatusStartInterval", 10) +Engine.SetDvar("lobbyTimerStatusPostGameInterval", 10) +Engine.SetDvar("lobbyTimerStatusVotingInterval_Arena", 11000) require("widget_playlist_match_settings_info") -require("widget_playlist_category_match_settings_info") \ No newline at end of file +require("widget_playlist_category_match_settings_info") From 564cf28df43ade8742b5f0ec12a6082c0805d883 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Mon, 17 Apr 2023 00:45:46 -0230 Subject: [PATCH 27/50] Remove searching for player text in lobby - No longer sets LobbyMaxClients to 1 as that disallowed splitscreen --- data/ui_scripts/playlist/__init__.lua | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/data/ui_scripts/playlist/__init__.lua b/data/ui_scripts/playlist/__init__.lua index f5eb933f..80bdee19 100644 --- a/data/ui_scripts/playlist/__init__.lua +++ b/data/ui_scripts/playlist/__init__.lua @@ -2,8 +2,23 @@ if Engine.GetCurrentMap() ~= "core_frontend" then return end -Engine.GetLobbyMaxClients = function() - return 1 +if not CoD.LobbyMember then + return +end + +local oldLobbyMember = CoD.LobbyMember.new +function CoD.LobbyMember.new(menu, controller) + local self = oldLobbyMember(menu, controller) + + -- Hide the playlist count text + if self.SearchingForPlayer then + self.SearchingForPlayer:setAlpha(0) + end + if self.FEMemberBlurPanelContainer0 then + self.FEMemberBlurPanelContainer0:setAlpha(0) + end + + return self end function IsLobbyStatusVisible() From 6c07d84e23cfc097ba3acd70320d542027786c54 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 17 Apr 2023 18:42:52 +0200 Subject: [PATCH 28/50] Prepare colored name support --- src/client/component/auth.cpp | 80 ++++++++++++++++++++++++++++++++- src/client/component/auth.hpp | 1 + src/client/component/colors.cpp | 65 +++++++++++++++++++++------ src/client/component/party.hpp | 2 + src/client/game/utils.cpp | 34 ++++++++++++++ src/client/game/utils.hpp | 2 + src/client/std_include.hpp | 1 + 7 files changed, 170 insertions(+), 15 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 78a6b460..7c679aa8 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -2,6 +2,7 @@ #include "loader/component_loader.hpp" #include "auth.hpp" +#include "party.hpp" #include "command.hpp" #include "network.hpp" #include "scheduler.hpp" @@ -24,6 +25,8 @@ namespace auth { namespace { + std::array client_xuids{}; + std::string get_hdd_serial() { DWORD serial{}; @@ -151,6 +154,32 @@ namespace auth return 0; } + void distribute_player_xuid(const game::netadr_t& target, const size_t player_index, const uint64_t xuid) + { + if (player_index >= 18) + { + return; + } + + utils::byte_buffer buffer{}; + buffer.write(static_cast(player_index)); + buffer.write(xuid); + + game::foreach_connected_client([&](const game::client_s& client, size_t index) + { + network::send(client.address, "playerXuid", buffer.get_buffer()); + + if (index != player_index) + { + utils::byte_buffer current_buffer{}; + current_buffer.write(static_cast(index)); + current_buffer.write(client.xuid); + + network::send(target, "playerXuid", current_buffer.get_buffer()); + } + }); + } + void dispatch_connect_packet(const game::netadr_t& target, const std::string& data) { utils::byte_buffer buffer(data); @@ -173,13 +202,17 @@ namespace auth game::SV_DirectConnect(target); - game::foreach_connected_client([&](game::client_s& client) + size_t player_index = 18; + game::foreach_connected_client([&](game::client_s& client, size_t index) { if (client.address == target) { client.xuid = xuid; + player_index = index; } }); + + distribute_player_xuid(target, player_index, xuid); } void handle_connect_packet_fragment(const game::netadr_t& target, const network::data_view& data) @@ -200,6 +233,24 @@ namespace auth }, scheduler::server); } } + + void handle_player_xuid_packet(const game::netadr_t& target, const network::data_view& data) + { + if (game::is_server_running() || !party::is_host(target)) + { + return; + } + + utils::byte_buffer buffer(data); + + const auto player_id = buffer.read(); + const auto xuid = buffer.read(); + + if (player_id < client_xuids.size()) + { + client_xuids[player_id] = xuid; + } + } } uint64_t get_guid() @@ -217,6 +268,32 @@ namespace auth return guid; } + uint64_t get_guid(const size_t client_num) + { + if (client_num >= 18) + { + return 0; + } + + if (!game::is_server_running()) + { + return client_xuids[client_num]; + } + + uint64_t xuid = 0; + const auto callback = [&xuid](const game::client_s& client) + { + xuid = client.xuid; + }; + + if (!game::access_connected_client(client_num, callback)) + { + return 0; + } + + return xuid; + } + struct component final : generic_component { void post_unpack() override @@ -224,6 +301,7 @@ namespace auth // Skip connect handler utils::hook::set(game::select(0x142253EFA, 0x14053714A), 0xEB); network::on("connect", handle_connect_packet_fragment); + network::on("playerXuid", handle_player_xuid_packet); // Patch steam id bit check std::vector> patches{}; diff --git a/src/client/component/auth.hpp b/src/client/component/auth.hpp index 3ee0c53a..87c07f5e 100644 --- a/src/client/component/auth.hpp +++ b/src/client/component/auth.hpp @@ -3,4 +3,5 @@ namespace auth { uint64_t get_guid(); + uint64_t get_guid(size_t client_num); } diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index 306c44b6..5c7f7b4e 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -3,6 +3,10 @@ #include "game/game.hpp" +#include "auth.hpp" + +#include "steam/steam.hpp" + #include #include @@ -10,8 +14,25 @@ namespace colors { namespace { - utils::hook::detour get_player_name_hook; - utils::hook::detour get_gamer_tag_hook; + utils::hook::detour cl_get_client_name_hook; + + std::optional get_color_for_xuid(const uint64_t xuid) + { + if (xuid == 0xCD02AF6448291209 + || xuid == 0x10F0C433E08E1357 + || xuid == 0x60E0FEFE42341715) + { + return 2; + } + + return {}; + } + + std::optional get_color_for_client(const int client_num) + { + const auto xuid = auth::get_guid(static_cast(client_num)); + return get_color_for_xuid(xuid); + } template void patch_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a = 255) @@ -36,23 +57,39 @@ namespace colors utils::hook::copy(g_color_table + index * 4, color_float, sizeof(color_float)); } - /*uint64_t get_player_name_stub(const uint64_t client, int client_num, char* buffer, const int size, - const bool has_clan_tag) + bool cl_get_client_name_stub(const int local_client_num, const int index, char* buf, const int size, + const bool add_clan_name) { - const auto res = get_player_name_hook.invoke(client, client_num, buffer, size, has_clan_tag); + const auto res = cl_get_client_name_hook.invoke(local_client_num, index, buf, size, add_clan_name); - if (_ReturnAddress() != reinterpret_cast(0x1406A7B56_g)) + if (_ReturnAddress() == reinterpret_cast(0x1406A7B56_g)) { - const auto val = utils::string::va("^%d%s", rand() % 7, buffer); - strncpy_s(buffer, size, val, size); + return res; } - return res; - }*/ + const auto color = get_color_for_client(index); + if (!color) + { + return res; + } - /*const char* get_gamer_tag_stub(const uint64_t num) + const auto val = utils::string::va("^%d%s", *color, buf); + utils::string::copy(buf, size, val); + + return res; + } + + /*const char* get_gamer_tag_stub(const uint32_t num) { - return utils::string::va("^3%s", get_gamer_tag_hook.invoke(num)); + const auto color = get_color_for_xuid(steam::SteamUser()->GetSteamID().bits); + const auto name = reinterpret_cast(0x141EC6E80)(num) + 8; + + if (!color || num) + { + return name; + } + + return utils::string::va("^1%s", *color, name); }*/ } @@ -68,8 +105,8 @@ namespace colors patch_color<6>(151, 80, 221); // 6 - Pink // Old addresses - //get_player_name_hook.create(0x1413E3140_g, get_player_name_stub); - //get_gamer_tag_hook.create(0x141EC7370_g, get_gamer_tag_stub); + cl_get_client_name_hook.create(game::CL_GetClientName, cl_get_client_name_stub); + //utils::hook::jump(0x141EC72E0_g, get_gamer_tag_stub); } }; } diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index f682a14e..b10ee95c 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include "game/game.hpp" + namespace party { using query_callback_func = void(bool success, const game::netadr_t& host, const ::utils::info_string& info, uint32_t ping); diff --git a/src/client/game/utils.cpp b/src/client/game/utils.cpp index e374a73a..c61a4350 100644 --- a/src/client/game/utils.cpp +++ b/src/client/game/utils.cpp @@ -176,6 +176,30 @@ namespace game } } + + template + static bool access_client(T* client_states, const size_t index, const std::function& callback) + { + if (!client_states || !callback) + { + return false; + } + + if (index >= get_max_client_count()) + { + return false; + } + + auto& client = client_states[index]; + if (client.client_state <= 0) + { + return false; + } + + callback(client); + return true; + } + void foreach_client(const std::function& callback) { if (is_server()) @@ -214,4 +238,14 @@ namespace game callback(client); }); } + + bool access_connected_client(const size_t index, const std::function& callback) + { + if (is_server()) + { + return access_client(*svs_clients, index, callback); + } + + return access_client(*svs_clients_cl, index, callback); + } } diff --git a/src/client/game/utils.hpp b/src/client/game/utils.hpp index 09abd8e7..5bbc78c0 100644 --- a/src/client/game/utils.hpp +++ b/src/client/game/utils.hpp @@ -24,4 +24,6 @@ namespace game void foreach_connected_client(const std::function& callback); void foreach_connected_client(const std::function& callback); + + bool access_connected_client(size_t index, const std::function& callback); } diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 59b83a41..422c5ed9 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -65,6 +65,7 @@ #endif #include +#include #include #include #include From 4be9292c3b01eef66f08e5ebaa9925b8968d2d64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 18:03:50 +0000 Subject: [PATCH 29/50] Bump deps/curl from `7ed010c` to `1c5ed24` Bumps [deps/curl](https://github.com/curl/curl) from `7ed010c` to `1c5ed24`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/7ed010ce2192ae3e4d9663eaaa3a460f316b708b...1c5ed24ee0e929a6f410fcc3729becfd2ee71211) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 7ed010ce..1c5ed24e 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 7ed010ce2192ae3e4d9663eaaa3a460f316b708b +Subproject commit 1c5ed24ee0e929a6f410fcc3729becfd2ee71211 From d7b835d0ebc5e853714d4e5c990ca78c35def41a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 18:03:53 +0000 Subject: [PATCH 30/50] Bump deps/zlib from `5799c14` to `6658868` Bumps [deps/zlib](https://github.com/madler/zlib) from `5799c14` to `6658868`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/5799c14c8526bf1aaa130c021982f831d155b46d...66588683b36042154ad35140bf9fcbb60c5d573c) --- updated-dependencies: - dependency-name: deps/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/zlib b/deps/zlib index 5799c14c..66588683 160000 --- a/deps/zlib +++ b/deps/zlib @@ -1 +1 @@ -Subproject commit 5799c14c8526bf1aaa130c021982f831d155b46d +Subproject commit 66588683b36042154ad35140bf9fcbb60c5d573c From fa144b7dd65cffb030a2192d13efaeb422046ec7 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 17 Apr 2023 20:08:49 +0200 Subject: [PATCH 31/50] Clear xuids before connecting --- src/client/component/auth.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 7c679aa8..3b56585e 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -135,6 +135,11 @@ namespace auth int send_connect_data_stub(const game::netsrc_t sock, game::netadr_t* adr, const char* data, const int len) { + for (auto& xuid : client_xuids) + { + xuid = 0; + } + try { const auto is_connect_sequence = len >= 7 && strncmp("connect", data, 7) == 0; From e6e2805466d1d85b460b5675e8612eff7f8239f2 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 17 Apr 2023 20:33:41 +0200 Subject: [PATCH 32/50] Fix guid distribution for bots --- src/client/component/auth.cpp | 53 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 3b56585e..8a750cde 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -172,9 +172,12 @@ namespace auth game::foreach_connected_client([&](const game::client_s& client, size_t index) { - network::send(client.address, "playerXuid", buffer.get_buffer()); + if (client.address.type != game::NA_BOT) + { + network::send(client.address, "playerXuid", buffer.get_buffer()); + } - if (index != player_index) + if (index != player_index && target.type != game::NA_BOT) { utils::byte_buffer current_buffer{}; current_buffer.write(static_cast(index)); @@ -185,6 +188,30 @@ namespace auth }); } + void handle_new_player(const game::netadr_t& target) + { + const command::params_sv params{}; + if (params.size() < 2) + { + return; + } + + const utils::info_string info_string(params[1]); + const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 16); + + size_t player_index = 18; + game::foreach_connected_client([&](game::client_s& client, size_t index) + { + if (client.address == target) + { + client.xuid = xuid; + player_index = index; + } + }); + + distribute_player_xuid(target, player_index, xuid); + } + void dispatch_connect_packet(const game::netadr_t& target, const std::string& data) { utils::byte_buffer buffer(data); @@ -206,18 +233,7 @@ namespace auth profile_infos::add_and_distribute_profile_info(target, xuid, info); game::SV_DirectConnect(target); - - size_t player_index = 18; - game::foreach_connected_client([&](game::client_s& client, size_t index) - { - if (client.address == target) - { - client.xuid = xuid; - player_index = index; - } - }); - - distribute_player_xuid(target, player_index, xuid); + handle_new_player(target); } void handle_connect_packet_fragment(const game::netadr_t& target, const network::data_view& data) @@ -256,6 +272,12 @@ namespace auth client_xuids[player_id] = xuid; } } + + void direct_connect_bots_stub(const game::netadr_t address) + { + game::SV_DirectConnect(address); + handle_new_player(address); + } } uint64_t get_guid() @@ -308,6 +330,9 @@ namespace auth network::on("connect", handle_connect_packet_fragment); network::on("playerXuid", handle_player_xuid_packet); + // Intercept SV_DirectConnect in SV_AddTestClient + utils::hook::call(game::select(0x1422490DC, 0x14052E582), direct_connect_bots_stub); + // Patch steam id bit check std::vector> patches{}; const auto p = [&patches](const size_t a, const size_t b) From 4cab2a73bde904a9079f45ca24c0a0e7d9e41920 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 17 Apr 2023 21:13:18 +0200 Subject: [PATCH 33/50] Better fix for clearing stored guids --- src/client/component/auth.cpp | 13 ++++++++----- src/client/component/auth.hpp | 1 + src/client/component/party.cpp | 8 ++++++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 8a750cde..59228b5d 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -135,11 +135,6 @@ namespace auth int send_connect_data_stub(const game::netsrc_t sock, game::netadr_t* adr, const char* data, const int len) { - for (auto& xuid : client_xuids) - { - xuid = 0; - } - try { const auto is_connect_sequence = len >= 7 && strncmp("connect", data, 7) == 0; @@ -321,6 +316,14 @@ namespace auth return xuid; } + void clear_stored_guids() + { + for (auto& xuid : client_xuids) + { + xuid = 0; + } + } + struct component final : generic_component { void post_unpack() override diff --git a/src/client/component/auth.hpp b/src/client/component/auth.hpp index 87c07f5e..30341c98 100644 --- a/src/client/component/auth.hpp +++ b/src/client/component/auth.hpp @@ -4,4 +4,5 @@ namespace auth { uint64_t get_guid(); uint64_t get_guid(size_t client_num); + void clear_stored_guids(); } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 837a97f9..403c0c3a 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -3,6 +3,7 @@ #include "game/game.hpp" #include "party.hpp" +#include "auth.hpp" #include "network.hpp" #include "scheduler.hpp" #include "workshop.hpp" @@ -39,6 +40,8 @@ namespace party void connect_to_lobby(const game::netadr_t& addr, const std::string& mapname, const std::string& gamemode, const std::string& usermap_id, const std::string& mod_id) { + auth::clear_stored_guids(); + workshop::load_mod_if_needed(usermap_id, mod_id); game::XSESSION_INFO info{}; @@ -56,7 +59,8 @@ namespace party } void connect_to_lobby_with_mode(const game::netadr_t& addr, const game::eModes mode, const std::string& mapname, - const std::string& gametype, const std::string& usermap_id, const std::string& mod_id, + const std::string& gametype, const std::string& usermap_id, + const std::string& mod_id, const bool was_retried = false) { if (game::Com_SessionMode_IsMode(mode)) @@ -189,7 +193,7 @@ namespace party const auto usermap_id = workshop::get_usermap_publisher_id(mapname); if (workshop::check_valid_usermap_id(mapname, usermap_id) && - workshop::check_valid_mod_id(mod_id)) + workshop::check_valid_mod_id(mod_id)) { if (is_connecting_to_dedi) { From 7f908163cadc1ef9ab2547c2cdcbff0ef1b7aff3 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 17 Apr 2023 21:17:58 +0200 Subject: [PATCH 34/50] Small cleanup --- src/client/component/auth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 59228b5d..1457ee8e 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -165,7 +165,7 @@ namespace auth buffer.write(static_cast(player_index)); buffer.write(xuid); - game::foreach_connected_client([&](const game::client_s& client, size_t index) + game::foreach_connected_client([&](const game::client_s& client, const size_t index) { if (client.address.type != game::NA_BOT) { @@ -195,7 +195,7 @@ namespace auth const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 16); size_t player_index = 18; - game::foreach_connected_client([&](game::client_s& client, size_t index) + game::foreach_connected_client([&](game::client_s& client, const size_t index) { if (client.address == target) { From ddb63bc5d29d97bebb96edf5226a4a66b528c42f Mon Sep 17 00:00:00 2001 From: ineed bots Date: Mon, 17 Apr 2023 19:56:32 -0600 Subject: [PATCH 35/50] Fix negativeAck exploit (crash DOS) --- src/client/component/patches.cpp | 20 ++++++++++++++++++-- src/client/game/structs.hpp | 12 ++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 0900b5a8..6a2b59e5 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -11,7 +11,20 @@ namespace patches { namespace - { + { + utils::hook::detour sv_executeclientmessages_hook; + + void sv_executeclientmessages_stub(game::client_s* cl, game::msg_t* msg) + { + if (cl->reliableAcknowledge < 0) + { + cl->reliableAcknowledge = cl->reliableSequence; + return; + } + + sv_executeclientmessages_hook.invoke(cl, msg); + } + void script_errors_stub(const char* file, int line, unsigned int code, const char* fmt, ...) { char buffer[0x1000]; @@ -37,7 +50,10 @@ namespace patches // Change 4 character name limit to 3 characters utils::hook::set(game::select(0x14224DA53, 0x140531143), 3); utils::hook::set(game::select(0x14224DBB4, 0x1405312A8), 3); - utils::hook::set(game::select(0x14224DF8C, 0x1405316DC), 3); + utils::hook::set(game::select(0x14224DF8C, 0x1405316DC), 3); + + // make sure client's reliableAck are not negative + sv_executeclientmessages_hook.create(game::select(0x14224A460, 0x14052F840), sv_executeclientmessages_stub); scheduler::once([] { diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 424c59ac..696a33c5 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1583,15 +1583,23 @@ namespace game int client_state; char __pad0[0x28]; netadr_t address; - char __pad1[0x5588]; + char gap_3C[20468]; + int reliableSequence; + int reliableAcknowledge; + char gap_5038[4]; + int messageAcknowledge; + char gap_5040[1416]; uint64_t xuid; char __pad2[0xB5D84]; int guid; char __pad3[0x8]; bool bIsTestClient; - char __pad4[0x29DAC]; + char gap_BB361[3]; + int serverId; + char gap_BB368[171432]; }; + #ifdef __cplusplus static_assert(sizeof(client_s) == 0xE5110); From b891d25b8729967b9072df5c06a1de6a10259cf5 Mon Sep 17 00:00:00 2001 From: ineed bots Date: Mon, 17 Apr 2023 22:04:57 -0600 Subject: [PATCH 36/50] Fix `cl` warning --- src/client/component/patches.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 6a2b59e5..ea4812a9 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -14,15 +14,15 @@ namespace patches { utils::hook::detour sv_executeclientmessages_hook; - void sv_executeclientmessages_stub(game::client_s* cl, game::msg_t* msg) + void sv_executeclientmessages_stub(game::client_s* client, game::msg_t* msg) { - if (cl->reliableAcknowledge < 0) + if (client->reliableAcknowledge < 0) { - cl->reliableAcknowledge = cl->reliableSequence; + client->reliableAcknowledge = client->reliableSequence; return; } - sv_executeclientmessages_hook.invoke(cl, msg); + sv_executeclientmessages_hook.invoke(client, msg); } void script_errors_stub(const char* file, int line, unsigned int code, const char* fmt, ...) From f27a1b97e70356cd7001ea47b97675a285fd08f3 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Tue, 18 Apr 2023 10:49:02 +0200 Subject: [PATCH 37/50] network: improve a patch --- src/client/component/network.cpp | 22 +++++- src/client/component/patches.cpp | 112 ++++++++++++++++--------------- src/client/game/structs.hpp | 12 ++-- src/client/game/symbols.hpp | 2 + 4 files changed, 85 insertions(+), 63 deletions(-) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 546d5a1f..04b5c1a6 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -163,7 +163,6 @@ namespace network : 0; } - uint64_t ret2() { return 2; @@ -173,6 +172,15 @@ namespace network { return 0; } + + void com_error_oob_stub(const char* file, int line, int code, [[maybe_unused]] const char* fmt, const char* error) + { + char buffer[1024]{}; + + strncpy_s(buffer, error, _TRUNCATE); + + game::Com_Error_(file, line, code, "%s", buffer); + } } void on(const std::string& command, const callback& callback) @@ -321,10 +329,20 @@ namespace network // NA_IP -> NA_RAWIP in NetAdr_ToString utils::hook::set(game::select(0x142172ED4, 0x140515864), game::NA_RAWIP); + // Kill 'echo' OOB handler + utils::hook::set(game::select(0x14134D0FB, 0x14018EE82), 0xEB); + if (game::is_server()) { // Remove restrictions for rcon commands - utils::hook::call(0x140538D5C_g, &con_restricted_execute_buf_stub); // SVC_RemoteCommand + utils::hook::call(0x140538D5C_g, con_restricted_execute_buf_stub); // SVC_RemoteCommand + + // Kill 'error' OOB handler on the dedi + utils::hook::nop(0x14018EF8B_g, 5); + } + else + { + utils::hook::call(0x14134D206_g, com_error_oob_stub); } // TODO: Fix that diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index ea4812a9..b7a2824f 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -1,66 +1,68 @@ -#include -#include "loader/component_loader.hpp" - -#include -#include - -#include "scheduler.hpp" - -#include - -namespace patches -{ - namespace - { - utils::hook::detour sv_executeclientmessages_hook; +#include +#include "loader/component_loader.hpp" - void sv_executeclientmessages_stub(game::client_s* client, game::msg_t* msg) - { +#include +#include + +#include "network.hpp" +#include "scheduler.hpp" + +#include + +namespace patches +{ + namespace + { + utils::hook::detour sv_execute_client_messages_hook; + + void sv_execute_client_messages_stub(game::client_s* client, game::msg_t* msg) + { if (client->reliableAcknowledge < 0) { client->reliableAcknowledge = client->reliableSequence; + network::send(client->address, "error", "EXE_LOSTRELIABLECOMMANDS"); return; } - sv_executeclientmessages_hook.invoke(client, msg); + sv_execute_client_messages_hook.invoke(client, msg); } - - void script_errors_stub(const char* file, int line, unsigned int code, const char* fmt, ...) - { - char buffer[0x1000]; - - { - va_list ap; - va_start(ap, fmt); - vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap); - va_end(ap); - } - - game::Com_Error(game::ERROR_SCRIPT_DROP, "%s", buffer); - } - } - - struct component final : generic_component - { - void post_unpack() override - { - // don't make script errors fatal error - utils::hook::call(game::select(0x1412CAC4D, 0x140158EB2), script_errors_stub); - - // Change 4 character name limit to 3 characters - utils::hook::set(game::select(0x14224DA53, 0x140531143), 3); - utils::hook::set(game::select(0x14224DBB4, 0x1405312A8), 3); + + void script_errors_stub(const char* file, int line, unsigned int code, const char* fmt, ...) + { + char buffer[0x1000]; + + { + va_list ap; + va_start(ap, fmt); + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap); + va_end(ap); + } + + game::Com_Error(game::ERROR_SCRIPT_DROP, "%s", buffer); + } + } + + struct component final : generic_component + { + void post_unpack() override + { + // don't make script errors fatal error + utils::hook::call(game::select(0x1412CAC4D, 0x140158EB2), script_errors_stub); + + // Change 4 character name limit to 3 characters + utils::hook::set(game::select(0x14224DA53, 0x140531143), 3); + utils::hook::set(game::select(0x14224DBB4, 0x1405312A8), 3); utils::hook::set(game::select(0x14224DF8C, 0x1405316DC), 3); // make sure client's reliableAck are not negative - sv_executeclientmessages_hook.create(game::select(0x14224A460, 0x14052F840), sv_executeclientmessages_stub); - - scheduler::once([] - { - game::register_dvar_string("password", "", game::DVAR_USERINFO, "password"); - }, scheduler::pipeline::main); - } - }; -} - -REGISTER_COMPONENT(patches::component) + sv_execute_client_messages_hook.create(game::select(0x14224A460, 0x14052F840), sv_execute_client_messages_stub); + + scheduler::once([] + { + game::register_dvar_string("password", "", game::DVAR_USERINFO, "password"); + }, scheduler::pipeline::main); + } + }; +} + +REGISTER_COMPONENT(patches::component) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 696a33c5..9876f2c4 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1583,20 +1583,20 @@ namespace game int client_state; char __pad0[0x28]; netadr_t address; - char gap_3C[20468]; + char __pad1[20468]; int reliableSequence; int reliableAcknowledge; - char gap_5038[4]; + char __pad2[4]; int messageAcknowledge; char gap_5040[1416]; uint64_t xuid; - char __pad2[0xB5D84]; + char __pad3[0xB5D84]; int guid; - char __pad3[0x8]; + char __pad4[0x8]; bool bIsTestClient; - char gap_BB361[3]; + char __pad5[3]; int serverId; - char gap_BB368[171432]; + char __pad6[171432]; }; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 36a82681..fbb93ad9 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -78,6 +78,8 @@ namespace game // G WEAK symbol G_ClearVehicleInputs{0x1423812E0, 0x1405C1200}; + WEAK symbol StuckInClient{0x1415A8360, 0x14023BFE0}; + // Live WEAK symbol Live_GetConnectivityInformation{0x141E0C380}; From 93bb54c6a40a0e93c9e52e66dd35d84b131bfdc6 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Tue, 18 Apr 2023 12:17:41 +0200 Subject: [PATCH 38/50] network: add comment --- src/client/component/network.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 04b5c1a6..4371a17a 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -342,6 +342,7 @@ namespace network } else { + // Truncate error string to make sure there are no buffer overruns later utils::hook::call(0x14134D206_g, com_error_oob_stub); } From 420b89451293369e3c15394ad118062224a6bbcf Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:12:59 -0230 Subject: [PATCH 39/50] You had one job auto-formatter --- src/client/component/loot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/component/loot.cpp b/src/client/component/loot.cpp index 329439d4..39a54490 100644 --- a/src/client/component/loot.cpp +++ b/src/client/component/loot.cpp @@ -58,7 +58,7 @@ namespace loot } // Item id for extra CaC slots - if (dvar_cg_unlockall_cac_slots->current.value.enabled && (item_id == 99003)) + if (dvar_cg_unlockall_cac_slots->current.value.enabled && item_id == 99003) { return 1; } @@ -211,7 +211,7 @@ namespace loot { game::Dvar_SetFromStringByName("ui_enableAllHeroes", "1", true); } - }, scheduler::pipeline::dvars_loaded); + }, scheduler::pipeline::dvars_loaded); } }; }; From bf30653fc2c0786d16d3424150ba968b3d6943a1 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Tue, 18 Apr 2023 09:30:52 -0230 Subject: [PATCH 40/50] Don't break if not CoD.LobbyMember --- data/ui_scripts/playlist/__init__.lua | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/data/ui_scripts/playlist/__init__.lua b/data/ui_scripts/playlist/__init__.lua index 80bdee19..f8080665 100644 --- a/data/ui_scripts/playlist/__init__.lua +++ b/data/ui_scripts/playlist/__init__.lua @@ -2,23 +2,21 @@ if Engine.GetCurrentMap() ~= "core_frontend" then return end -if not CoD.LobbyMember then - return -end - -local oldLobbyMember = CoD.LobbyMember.new -function CoD.LobbyMember.new(menu, controller) - local self = oldLobbyMember(menu, controller) - - -- Hide the playlist count text - if self.SearchingForPlayer then - self.SearchingForPlayer:setAlpha(0) +if CoD.LobbyMember then + local oldLobbyMember = CoD.LobbyMember.new + function CoD.LobbyMember.new(menu, controller) + local self = oldLobbyMember(menu, controller) + + -- Hide the playlist count text + if self.SearchingForPlayer then + self.SearchingForPlayer:setAlpha(0) + end + if self.FEMemberBlurPanelContainer0 then + self.FEMemberBlurPanelContainer0:setAlpha(0) + end + + return self end - if self.FEMemberBlurPanelContainer0 then - self.FEMemberBlurPanelContainer0:setAlpha(0) - end - - return self end function IsLobbyStatusVisible() From ecf5d601c73f2d70987ba4b34fbda3070bdff1a6 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 18 Apr 2023 18:43:57 +0200 Subject: [PATCH 41/50] Add -norelaunch flag --- src/client/updater/file_updater.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/client/updater/file_updater.cpp b/src/client/updater/file_updater.cpp index bee3cf86..f68b6d2d 100644 --- a/src/client/updater/file_updater.cpp +++ b/src/client/updater/file_updater.cpp @@ -200,7 +200,11 @@ namespace updater throw; } - utils::nt::relaunch_self(); + if (!utils::flags::has_flag("norelaunch")) + { + utils::nt::relaunch_self(); + } + throw update_cancelled(); } From 2f5980bcc80416c06caea2eebb20dbf1f462c4ca Mon Sep 17 00:00:00 2001 From: ineed bots Date: Tue, 18 Apr 2023 21:29:18 -0600 Subject: [PATCH 42/50] Fix workaround for bad client reliableAcknowledge DOS We should be checking the difference > 0; not just the reliableAcknowledge. --- src/client/component/patches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index b7a2824f..c442fa83 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -17,7 +17,7 @@ namespace patches void sv_execute_client_messages_stub(game::client_s* client, game::msg_t* msg) { - if (client->reliableAcknowledge < 0) + if ((client->reliableSequence - client->reliableAcknowledge) < 0) { client->reliableAcknowledge = client->reliableSequence; network::send(client->address, "error", "EXE_LOSTRELIABLECOMMANDS"); From 6ce1dff30f1271730aa126d930be29ac0fcd1bd1 Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Wed, 19 Apr 2023 06:02:07 +0200 Subject: [PATCH 43/50] Update structs.hpp --- src/client/game/structs.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 9876f2c4..a9c73f5b 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1,6 +1,6 @@ #pragma once -#define PROTOCOL 3 +#define PROTOCOL 4 #ifdef __cplusplus namespace game From 743326c9c3f37629047eafb172887caf8a6e9d06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 18:01:04 +0000 Subject: [PATCH 44/50] Bump deps/curl from `1c5ed24` to `6b1e4dc` Bumps [deps/curl](https://github.com/curl/curl) from `1c5ed24` to `6b1e4dc`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/1c5ed24ee0e929a6f410fcc3729becfd2ee71211...6b1e4dc6cdd2c1fc1730dc64aa5e2d82615e5993) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 1c5ed24e..6b1e4dc6 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 1c5ed24ee0e929a6f410fcc3729becfd2ee71211 +Subproject commit 6b1e4dc6cdd2c1fc1730dc64aa5e2d82615e5993 From 0316b8210a2c5225d95150439e3c8cabdcc5f94d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 18:01:09 +0000 Subject: [PATCH 45/50] Bump deps/zlib from `6658868` to `b8a8373` Bumps [deps/zlib](https://github.com/madler/zlib) from `6658868` to `b8a8373`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/66588683b36042154ad35140bf9fcbb60c5d573c...b8a8373ec195c8d286fe7e81e78b4a6d31bd859f) --- updated-dependencies: - dependency-name: deps/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/zlib b/deps/zlib index 66588683..b8a8373e 160000 --- a/deps/zlib +++ b/deps/zlib @@ -1 +1 @@ -Subproject commit 66588683b36042154ad35140bf9fcbb60c5d573c +Subproject commit b8a8373ec195c8d286fe7e81e78b4a6d31bd859f From d209a9931ec4f7e3f76ae024a96abe4bd348c5b0 Mon Sep 17 00:00:00 2001 From: Vlad Loktionov Date: Thu, 20 Apr 2023 04:14:55 +0300 Subject: [PATCH 46/50] Add 'Quit to desktop' button in pause menu --- data/ui_scripts/party/__init__.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/data/ui_scripts/party/__init__.lua b/data/ui_scripts/party/__init__.lua index 741d9378..58e4170e 100644 --- a/data/ui_scripts/party/__init__.lua +++ b/data/ui_scripts/party/__init__.lua @@ -80,5 +80,6 @@ DataSources.StartMenuGameOptions = ListHelper_SetupDataSource("StartMenuGameOpti table.insert(options, {models = {displayText = "MENU_QUIT_GAME_CAPS", action = QuitGame_MP}}) end end + table.insert(options, {models = {displayText = "QUIT TO DESKTOP", action = OpenPCQuit}}) return options end, true) From 40fe62cf9f7dea332a8d41a692b3b20cf6b82321 Mon Sep 17 00:00:00 2001 From: WantedDV <122710241+WantedDV@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:35:53 -0230 Subject: [PATCH 47/50] Readability + filename typo --- data/ui_scripts/frontend_menus/__init__.lua | 10 +++++----- ....lua => datasources_gamesettingsflyout_buttons.lua} | 0 2 files changed, 5 insertions(+), 5 deletions(-) rename data/ui_scripts/frontend_menus/{datasources_gamesettingslyout_buttons.lua => datasources_gamesettingsflyout_buttons.lua} (100%) diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua index 8fbc5d21..7ee38ff2 100644 --- a/data/ui_scripts/frontend_menus/__init__.lua +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -8,7 +8,7 @@ local enableLargeServerBrowserButton = true -- toggle large server browser butto local utils = require("utils") require("datasources_start_menu_tabs") require("datasources_change_map_categories") -require("datasources_gamesettingslyout_buttons") +require("datasources_gamesettingsflyout_buttons") CoD.LobbyButtons.MP_PUBLIC_MATCH = { stringRef = "MENU_PLAY_CAPS", @@ -77,7 +77,7 @@ CoD.LobbyButtons.SERVER_BROWSER = { customId = "btnDedicated" } -local lobbyMapVoteIsEnabled = enableLobbyMapVote +local shouldShowMapVote = enableLobbyMapVote local lobbyMapVote = function(lobbyMapVoteIsEnabled) if lobbyMapVoteIsEnabled == true then Engine.Exec(nil, "LobbyStopDemo") @@ -99,7 +99,7 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) end if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id then - lobbyMapVoteIsEnabled = enableLobbyMapVote + shouldShowMapVote = enableLobbyMapVote if enableLargeServerBrowserButton then utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.SERVER_BROWSER, 1) end @@ -110,8 +110,8 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader) utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP, 2) utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP)) - lobbyMapVote(lobbyMapVoteIsEnabled) - lobbyMapVoteIsEnabled = false + lobbyMapVote(shouldShowMapVote) + shouldShowMapVote = false elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEARENAGAME.id then utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas, 2) diff --git a/data/ui_scripts/frontend_menus/datasources_gamesettingslyout_buttons.lua b/data/ui_scripts/frontend_menus/datasources_gamesettingsflyout_buttons.lua similarity index 100% rename from data/ui_scripts/frontend_menus/datasources_gamesettingslyout_buttons.lua rename to data/ui_scripts/frontend_menus/datasources_gamesettingsflyout_buttons.lua From eb3fe7ae6f3beb9733d992ef5f313f2d5d515ba4 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 21 Apr 2023 16:47:50 +0200 Subject: [PATCH 48/50] Prepare openssl key export --- src/client/component/discord.cpp | 6 ++++-- src/common/utils/cryptography.cpp | 15 ++++++++++++++- src/common/utils/cryptography.hpp | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 421fe889..e8cabdf1 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -9,9 +9,11 @@ namespace discord { namespace { - void ready(const DiscordUser* /*request*/) + void ready(const DiscordUser* request) { - printf("Discord: Ready\n"); + SetEnvironmentVariableA("discord_user", request->userId); + + printf("Discord: Ready: %s - %s\n", request->userId, request->username); DiscordRichPresence discord_presence{}; ZeroMemory(&discord_presence, sizeof(discord_presence)); diff --git a/src/common/utils/cryptography.cpp b/src/common/utils/cryptography.cpp index 98f61550..824cb9a7 100644 --- a/src/common/utils/cryptography.cpp +++ b/src/common/utils/cryptography.cpp @@ -229,7 +229,20 @@ namespace utils::cryptography if (ecc_export(buffer, &length, type, &this->key_storage_) == CRYPT_OK) { - return std::string(cs(buffer), length); + return {cs(buffer), length}; + } + + return ""; + } + + std::string ecc::key::get_openssl() const + { + uint8_t buffer[4096] = {0}; + unsigned long length = sizeof(buffer); + + if (ecc_export_openssl(buffer, &length, PK_PUBLIC, &this->key_storage_) == CRYPT_OK) + { + return {cs(buffer), length}; } return ""; diff --git a/src/common/utils/cryptography.hpp b/src/common/utils/cryptography.hpp index 9538c5eb..456a950b 100644 --- a/src/common/utils/cryptography.hpp +++ b/src/common/utils/cryptography.hpp @@ -31,6 +31,8 @@ namespace utils::cryptography std::string serialize(int type = PK_PRIVATE) const; + std::string get_openssl() const; + void free(); bool operator==(key& key) const; From ff70b3e1c59e7ff8db8b611f824624b019e4ae3c Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 21 Apr 2023 21:29:44 +0200 Subject: [PATCH 49/50] Fix crash in connect handler --- src/client/component/auth.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 1457ee8e..9d8108f8 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -382,6 +382,9 @@ namespace auth p(0x141EB74D2_g, 0x141EB7515_g); // ? utils::hook::call(0x14134BF7D_g, send_connect_data_stub); + + // Fix crash + utils::hook::nop(0x142249097_g, 5); } for (const auto& patch : patches) From 6fecdeb68deed7d79c77923ad817f52c6f9ba3c9 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 22 Apr 2023 09:13:03 +0200 Subject: [PATCH 50/50] Introduce sub-protocols --- src/client/component/getinfo.cpp | 1 + src/client/component/party.cpp | 8 + src/client/component/server_list.cpp | 304 ++++---- src/client/game/structs.hpp | 1 + .../steam/interfaces/matchmaking_servers.cpp | 659 +++++++++--------- 5 files changed, 492 insertions(+), 481 deletions(-) diff --git a/src/client/component/getinfo.cpp b/src/client/component/getinfo.cpp index 505c0dd6..7514d8cf 100644 --- a/src/client/component/getinfo.cpp +++ b/src/client/component/getinfo.cpp @@ -110,6 +110,7 @@ namespace getinfo info.set("bots", std::to_string(get_bot_count())); info.set("sv_maxclients", std::to_string(get_max_client_count())); info.set("protocol", std::to_string(PROTOCOL)); + info.set("sub_protocol", std::to_string(SUB_PROTOCOL)); info.set("playmode", std::to_string(game::Com_SessionMode_GetMode())); info.set("gamemode", std::to_string(Com_SessionMode_GetGameMode())); info.set("sv_running", std::to_string(game::is_server_running())); diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 403c0c3a..f5d0487a 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -157,6 +157,14 @@ namespace party return; } + const auto sub_protocol = atoi(info.get("sub_protocol").data()); + if (sub_protocol != SUB_PROTOCOL && sub_protocol != (SUB_PROTOCOL - 1)) + { + const auto str = "Invalid sub-protocol."; + printf("%s\n", str); + return; + } + const auto gamename = info.get("gamename"); if (gamename != "T7"s) { diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index 7c0ca6ad..9e3fcbfc 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -1,164 +1,164 @@ -#include -#include "loader/component_loader.hpp" -#include "server_list.hpp" - -#include "game/game.hpp" - -#include -#include -#include - -#include "network.hpp" -#include "scheduler.hpp" - -namespace server_list -{ - namespace - { +#include +#include "loader/component_loader.hpp" +#include "server_list.hpp" + +#include "game/game.hpp" + +#include +#include +#include + +#include "network.hpp" +#include "scheduler.hpp" + +namespace server_list +{ + namespace + { utils::hook::detour lua_serverinfo_to_table_hook; - - struct state - { - game::netadr_t address{}; - bool requesting{false}; - std::chrono::high_resolution_clock::time_point query_start{}; - callback callback{}; - }; - - utils::concurrency::container master_state; - - void handle_server_list_response(const game::netadr_t& target, - const network::data_view& data, state& s) - { - if (!s.requesting || s.address != target) - { - return; - } - - s.requesting = false; - const auto callback = std::move(s.callback); - - std::optional start{}; - - for (size_t i = 0; i + 6 < data.size(); ++i) - { - if (data[i + 6] == '\\') - { - start.emplace(i); - break; - } - } - - if (!start.has_value()) - { - callback(true, {}); - return; - } - - std::unordered_set result{}; - - for (auto i = start.value(); i + 6 < data.size(); i += 7) - { - if (data[i + 6] != '\\') - { - break; - } - - game::netadr_t address{}; - address.type = game::NA_RAWIP; - address.localNetID = game::NS_CLIENT1; - memcpy(&address.ipv4.a, data.data() + i + 0, 4); - memcpy(&address.port, data.data() + i + 4, 2); - address.port = ntohs(address.port); - - result.emplace(address); - } - - callback(true, result); + + struct state + { + game::netadr_t address{}; + bool requesting{false}; + std::chrono::high_resolution_clock::time_point query_start{}; + callback callback{}; + }; + + utils::concurrency::container master_state; + + void handle_server_list_response(const game::netadr_t& target, + const network::data_view& data, state& s) + { + if (!s.requesting || s.address != target) + { + return; + } + + s.requesting = false; + const auto callback = std::move(s.callback); + + std::optional start{}; + + for (size_t i = 0; i + 6 < data.size(); ++i) + { + if (data[i + 6] == '\\') + { + start.emplace(i); + break; + } + } + + if (!start.has_value()) + { + callback(true, {}); + return; + } + + std::unordered_set result{}; + + for (auto i = start.value(); i + 6 < data.size(); i += 7) + { + if (data[i + 6] != '\\') + { + break; + } + + game::netadr_t address{}; + address.type = game::NA_RAWIP; + address.localNetID = game::NS_CLIENT1; + memcpy(&address.ipv4.a, data.data() + i + 0, 4); + memcpy(&address.port, data.data() + i + 4, 2); + address.port = ntohs(address.port); + + result.emplace(address); + } + + callback(true, result); } void lua_serverinfo_to_table_stub(game::hks::lua_State* state, game::ServerInfo serverInfo, int index) - { + { lua_serverinfo_to_table_hook.invoke(state, serverInfo, index); if (state) { auto botCount = atoi(game::Info_ValueForKey(serverInfo.tags, "bots")); game::Lua_SetTableInt("botCount", botCount, state); - } - } - } - - bool get_master_server(game::netadr_t& address) - { - address = network::address_from_string("server.boiii.re:20810"); - return address.type != game::NA_BAD; - } - - void request_servers(callback callback) - { - master_state.access([&callback](state& s) - { - game::netadr_t addr{}; - if (!get_master_server(addr)) - { - return; - } - - s.requesting = true; - s.address = addr; - s.callback = std::move(callback); - s.query_start = std::chrono::high_resolution_clock::now(); - - network::send(s.address, "getservers", utils::string::va("T7 %i full empty", PROTOCOL)); - }); - } - - struct component final : client_component - { - void post_unpack() override - { - network::on("getServersResponse", [](const game::netadr_t& target, const network::data_view& data) - { - master_state.access([&](state& s) - { - handle_server_list_response(target, data, s); - }); - }); - - scheduler::loop([] - { - master_state.access([](state& s) - { - if (!s.requesting) - { - return; - } - - const auto now = std::chrono::high_resolution_clock::now(); - if ((now - s.query_start) < 2s) - { - return; - } - - s.requesting = false; - s.callback(false, {}); - s.callback = {}; - }); + } + } + } + + bool get_master_server(game::netadr_t& address) + { + address = network::address_from_string("server.boiii.re:20810"); + return address.type != game::NA_BAD; + } + + void request_servers(callback callback) + { + master_state.access([&callback](state& s) + { + game::netadr_t addr{}; + if (!get_master_server(addr)) + { + return; + } + + s.requesting = true; + s.address = addr; + s.callback = std::move(callback); + s.query_start = std::chrono::high_resolution_clock::now(); + + network::send(s.address, "getservers", utils::string::va("T7 %i full empty", PROTOCOL)); + }); + } + + struct component final : client_component + { + void post_unpack() override + { + network::on("getServersResponse", [](const game::netadr_t& target, const network::data_view& data) + { + master_state.access([&](state& s) + { + handle_server_list_response(target, data, s); + }); + }); + + scheduler::loop([] + { + master_state.access([](state& s) + { + if (!s.requesting) + { + return; + } + + const auto now = std::chrono::high_resolution_clock::now(); + if ((now - s.query_start) < 2s) + { + return; + } + + s.requesting = false; + s.callback(false, {}); + s.callback = {}; + }); }, scheduler::async, 200ms); - lua_serverinfo_to_table_hook.create(0x141F1FD10_g, lua_serverinfo_to_table_stub); - } - - void pre_destroy() override - { - master_state.access([](state& s) - { - s.requesting = false; - s.callback = {}; - }); - } - }; -} - -REGISTER_COMPONENT(server_list::component) + lua_serverinfo_to_table_hook.create(0x141F1FD10_g, lua_serverinfo_to_table_stub); + } + + void pre_destroy() override + { + master_state.access([](state& s) + { + s.requesting = false; + s.callback = {}; + }); + } + }; +} + +REGISTER_COMPONENT(server_list::component) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index a9c73f5b..5c13d86e 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1,6 +1,7 @@ #pragma once #define PROTOCOL 4 +#define SUB_PROTOCOL 1 #ifdef __cplusplus namespace game diff --git a/src/client/steam/interfaces/matchmaking_servers.cpp b/src/client/steam/interfaces/matchmaking_servers.cpp index b2996171..594689ce 100644 --- a/src/client/steam/interfaces/matchmaking_servers.cpp +++ b/src/client/steam/interfaces/matchmaking_servers.cpp @@ -1,333 +1,334 @@ -#include -#include "../steam.hpp" - -#include "game/game.hpp" - -#include "component/party.hpp" -#include "component/network.hpp" -#include "component/server_list.hpp" - -#include -#include - -namespace steam -{ - namespace - { - struct server - { - bool handled{false}; - game::netadr_t address{}; - gameserveritem_t server_item{}; - }; - - auto* const internet_request = reinterpret_cast(1); - - using servers = std::vector; - - ::utils::concurrency::container queried_servers{}; - std::atomic current_response{}; - - gameserveritem_t create_server_item(const game::netadr_t& address, const ::utils::info_string& info, - const uint32_t ping, const bool success) - { - gameserveritem_t server{}; - server.m_NetAdr.m_usConnectionPort = address.port; - server.m_NetAdr.m_usQueryPort = address.port; - server.m_NetAdr.m_unIP = ntohl(address.addr); - server.m_nPing = static_cast(ping); - server.m_bHadSuccessfulResponse = success; - server.m_bDoNotRefresh = false; - ::utils::string::copy(server.m_szGameDir, ""); - ::utils::string::copy(server.m_szMap, info.get("mapname").data()); - ::utils::string::copy(server.m_szGameDescription, info.get("description").data()); - server.m_nAppID = 311210; - server.m_nPlayers = atoi(info.get("clients").data()); - server.m_nMaxPlayers = atoi(info.get("sv_maxclients").data()); - server.m_nBotPlayers = atoi(info.get("bots").data()); - server.m_bPassword = info.get("isPrivate") == "1"; - server.m_bSecure = true; - server.m_ulTimeLastPlayed = 0; - server.m_nServerVersion = 1000; - ::utils::string::copy(server.m_szServerName, info.get("hostname").data()); - - const auto playmode = info.get("playmode"); - const auto mode = game::eModes(std::atoi(playmode.data())); - - const auto* tags = ::utils::string::va( - R"(\gametype\%s\dedicated\%s\ranked\false\hardcore\%s\zombies\%s\playerCount\%d\bots\%d\modName\%s\)", - info.get("gametype").data(), +#include +#include "../steam.hpp" + +#include "game/game.hpp" + +#include "component/party.hpp" +#include "component/network.hpp" +#include "component/server_list.hpp" + +#include +#include + +namespace steam +{ + namespace + { + struct server + { + bool handled{false}; + game::netadr_t address{}; + gameserveritem_t server_item{}; + }; + + auto* const internet_request = reinterpret_cast(1); + + using servers = std::vector; + + ::utils::concurrency::container queried_servers{}; + std::atomic current_response{}; + + gameserveritem_t create_server_item(const game::netadr_t& address, const ::utils::info_string& info, + const uint32_t ping, const bool success) + { + const auto sub_protocol = atoi(info.get("sub_protocol").data()); + + gameserveritem_t server{}; + server.m_NetAdr.m_usConnectionPort = address.port; + server.m_NetAdr.m_usQueryPort = address.port; + server.m_NetAdr.m_unIP = ntohl(address.addr); + server.m_nPing = static_cast(ping); + server.m_bHadSuccessfulResponse = success; + server.m_bDoNotRefresh = false; + ::utils::string::copy(server.m_szGameDir, ""); + ::utils::string::copy(server.m_szMap, info.get("mapname").data()); + ::utils::string::copy(server.m_szGameDescription, info.get("description").data()); + server.m_nAppID = (sub_protocol == SUB_PROTOCOL || sub_protocol == (SUB_PROTOCOL - 1)) ? 311210 : 0; + server.m_nPlayers = atoi(info.get("clients").data()); + server.m_nMaxPlayers = atoi(info.get("sv_maxclients").data()); + server.m_nBotPlayers = atoi(info.get("bots").data()); + server.m_bPassword = info.get("isPrivate") == "1"; + server.m_bSecure = true; + server.m_ulTimeLastPlayed = 0; + server.m_nServerVersion = 1000; + ::utils::string::copy(server.m_szServerName, info.get("hostname").data()); + + const auto playmode = info.get("playmode"); + const auto mode = game::eModes(std::atoi(playmode.data())); + + const auto* tags = ::utils::string::va( + R"(\gametype\%s\dedicated\%s\ranked\false\hardcore\%s\zombies\%s\playerCount\%d\bots\%d\modName\%s\)", + info.get("gametype").data(), info.get("dedicated") == "1" ? "true" : "false", - info.get("hc") == "1" ? "true" : "false", + info.get("hc") == "1" ? "true" : "false", mode == game::MODE_ZOMBIES ? "true" : "false", server.m_nPlayers, atoi(info.get("bots").data()), - info.get("modname").data()); - - ::utils::string::copy(server.m_szGameTags, tags); - server.m_steamID.bits = strtoull(info.get("xuid").data(), nullptr, 16); - - return server; - } - - void handle_server_respone(const bool success, const game::netadr_t& host, const ::utils::info_string& info, - const uint32_t ping) - { - bool all_handled = false; - std::optional index{}; - queried_servers.access([&](servers& srvs) - { - size_t i = 0; - for (; i < srvs.size(); ++i) - { - if (srvs[i].address == host) - { - break; - } - } - - if (i >= srvs.size()) - { - return; - } - - index = static_cast(i); - - auto& srv = srvs[i]; - srv.handled = true; - srv.server_item = create_server_item(host, info, ping, success); - - - for (const auto& entry : srvs) - { - if (!entry.handled) - { - return; - } - } - - all_handled = true; - }); - - const auto res = current_response.load(); - if (!index || !res) - { - return; - } - - if (success) - { - res->ServerResponded(internet_request, *index); - } - else - { - res->ServerFailedToRespond(internet_request, *index); - } - - if (all_handled) - { - res->RefreshComplete(internet_request, eServerResponded); - } - } - - void ping_server(const game::netadr_t& server) - { - party::query_server(server, handle_server_respone); - } - } - - void* matchmaking_servers::RequestInternetServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, - matchmaking_server_list_response* pRequestServersResponse) - { - current_response = pRequestServersResponse; - - server_list::request_servers([](const bool success, const std::unordered_set& s) - { - const auto res = current_response.load(); - if (!res) - { - return; - } - - if (!success) - { - res->RefreshComplete(internet_request, eServerFailedToRespond); - return; - } - - if (s.empty()) - { - res->RefreshComplete(internet_request, eNoServersListedOnMasterServer); - return; - } - - queried_servers.access([&s](servers& srvs) - { - srvs = {}; - srvs.reserve(s.size()); - - for (auto& address : s) - { - server new_server{}; - new_server.address = address; - new_server.server_item = create_server_item(address, {}, 0, false); - - srvs.push_back(new_server); - } - }); - - for (auto& srv : s) - { - ping_server(srv); - } - }); - - return internet_request; - } - - void* matchmaking_servers::RequestLANServerList(unsigned int iApp, - matchmaking_server_list_response* pRequestServersResponse) - { - return reinterpret_cast(2); - } - - void* matchmaking_servers::RequestFriendsServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, - matchmaking_server_list_response* pRequestServersResponse) - { - return reinterpret_cast(3); - } - - void* matchmaking_servers::RequestFavoritesServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, - matchmaking_server_list_response* pRequestServersResponse) - { - return reinterpret_cast(4); - } - - void* matchmaking_servers::RequestHistoryServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, - matchmaking_server_list_response* pRequestServersResponse) - { - return reinterpret_cast(5); - } - - void* matchmaking_servers::RequestSpectatorServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, - matchmaking_server_list_response* pRequestServersResponse) - { - return reinterpret_cast(6); - } - - void matchmaking_servers::ReleaseRequest(void* hServerListRequest) - { - if (internet_request == hServerListRequest) - { - current_response = nullptr; - } - } - - gameserveritem_t* matchmaking_servers::GetServerDetails(void* hRequest, int iServer) - { - if (internet_request != hRequest) - { - return nullptr; - } - - static thread_local gameserveritem_t server_item{}; - return queried_servers.access([iServer](const servers& s) -> gameserveritem_t* - { - if (iServer < 0 || static_cast(iServer) >= s.size()) - { - return nullptr; - } - - server_item = s[iServer].server_item; - return &server_item; - }); - } - - void matchmaking_servers::CancelQuery(void* hRequest) - { - } - - void matchmaking_servers::RefreshQuery(void* hRequest) - { - } - - bool matchmaking_servers::IsRefreshing(void* hRequest) - { - return false; - } - - int matchmaking_servers::GetServerCount(void* hRequest) - { - if (internet_request != hRequest) - { - return 0; - } - - return queried_servers.access([](const servers& s) - { - return static_cast(s.size()); - }); - } - - void matchmaking_servers::RefreshServer(void* hRequest, const int iServer) - { - if (internet_request != hRequest) - { - return; - } - - std::optional address{}; - queried_servers.access([&](const servers& s) - { - if (iServer < 0 || static_cast(iServer) >= s.size()) - { - return; - } - - address = s[iServer].address; - }); - - if (address) - { - ping_server(*address); - } - } - - void* matchmaking_servers::PingServer(const unsigned int unIP, const unsigned short usPort, - matchmaking_ping_response* pRequestServersResponse) - { - auto response = pRequestServersResponse; - const auto addr = network::address_from_ip(htonl(unIP), usPort); - - party::query_server( - addr, [response](const bool success, const game::netadr_t& host, const ::utils::info_string& info, - const uint32_t ping) - { - if (success) - { - auto server_item = create_server_item(host, info, ping, success); - response->ServerResponded(server_item); - } - else - { - response->ServerFailedToRespond(); - } - }); - - return reinterpret_cast(static_cast(7 + rand())); - } - - int matchmaking_servers::PlayerDetails(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse) - { - return 0; - } - - int matchmaking_servers::ServerRules(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse) - { - return 0; - } - - void matchmaking_servers::CancelServerQuery(int hServerQuery) - { - } -} + info.get("modname").data()); + + ::utils::string::copy(server.m_szGameTags, tags); + server.m_steamID.bits = strtoull(info.get("xuid").data(), nullptr, 16); + + return server; + } + + void handle_server_respone(const bool success, const game::netadr_t& host, const ::utils::info_string& info, + const uint32_t ping) + { + bool all_handled = false; + std::optional index{}; + queried_servers.access([&](servers& srvs) + { + size_t i = 0; + for (; i < srvs.size(); ++i) + { + if (srvs[i].address == host) + { + break; + } + } + + if (i >= srvs.size()) + { + return; + } + + index = static_cast(i); + + auto& srv = srvs[i]; + srv.handled = true; + srv.server_item = create_server_item(host, info, ping, success); + + + for (const auto& entry : srvs) + { + if (!entry.handled) + { + return; + } + } + + all_handled = true; + }); + + const auto res = current_response.load(); + if (!index || !res) + { + return; + } + + if (success) + { + res->ServerResponded(internet_request, *index); + } + else + { + res->ServerFailedToRespond(internet_request, *index); + } + + if (all_handled) + { + res->RefreshComplete(internet_request, eServerResponded); + } + } + + void ping_server(const game::netadr_t& server) + { + party::query_server(server, handle_server_respone); + } + } + + void* matchmaking_servers::RequestInternetServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, + matchmaking_server_list_response* pRequestServersResponse) + { + current_response = pRequestServersResponse; + + server_list::request_servers([](const bool success, const std::unordered_set& s) + { + const auto res = current_response.load(); + if (!res) + { + return; + } + + if (!success) + { + res->RefreshComplete(internet_request, eServerFailedToRespond); + return; + } + + if (s.empty()) + { + res->RefreshComplete(internet_request, eNoServersListedOnMasterServer); + return; + } + + queried_servers.access([&s](servers& srvs) + { + srvs = {}; + srvs.reserve(s.size()); + + for (auto& address : s) + { + server new_server{}; + new_server.address = address; + new_server.server_item = create_server_item(address, {}, 0, false); + + srvs.push_back(new_server); + } + }); + + for (auto& srv : s) + { + ping_server(srv); + } + }); + + return internet_request; + } + + void* matchmaking_servers::RequestLANServerList(unsigned int iApp, + matchmaking_server_list_response* pRequestServersResponse) + { + return reinterpret_cast(2); + } + + void* matchmaking_servers::RequestFriendsServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, + matchmaking_server_list_response* pRequestServersResponse) + { + return reinterpret_cast(3); + } + + void* matchmaking_servers::RequestFavoritesServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, + matchmaking_server_list_response* pRequestServersResponse) + { + return reinterpret_cast(4); + } + + void* matchmaking_servers::RequestHistoryServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, + matchmaking_server_list_response* pRequestServersResponse) + { + return reinterpret_cast(5); + } + + void* matchmaking_servers::RequestSpectatorServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, + matchmaking_server_list_response* pRequestServersResponse) + { + return reinterpret_cast(6); + } + + void matchmaking_servers::ReleaseRequest(void* hServerListRequest) + { + if (internet_request == hServerListRequest) + { + current_response = nullptr; + } + } + + gameserveritem_t* matchmaking_servers::GetServerDetails(void* hRequest, int iServer) + { + if (internet_request != hRequest) + { + return nullptr; + } + + static thread_local gameserveritem_t server_item{}; + return queried_servers.access([iServer](const servers& s) -> gameserveritem_t* { + if (iServer < 0 || static_cast(iServer) >= s.size()) + { + return nullptr; + } + + server_item = s[iServer].server_item; + return &server_item; + }); + } + + void matchmaking_servers::CancelQuery(void* hRequest) + { + } + + void matchmaking_servers::RefreshQuery(void* hRequest) + { + } + + bool matchmaking_servers::IsRefreshing(void* hRequest) + { + return false; + } + + int matchmaking_servers::GetServerCount(void* hRequest) + { + if (internet_request != hRequest) + { + return 0; + } + + return queried_servers.access([](const servers& s) + { + return static_cast(s.size()); + }); + } + + void matchmaking_servers::RefreshServer(void* hRequest, const int iServer) + { + if (internet_request != hRequest) + { + return; + } + + std::optional address{}; + queried_servers.access([&](const servers& s) + { + if (iServer < 0 || static_cast(iServer) >= s.size()) + { + return; + } + + address = s[iServer].address; + }); + + if (address) + { + ping_server(*address); + } + } + + void* matchmaking_servers::PingServer(const unsigned int unIP, const unsigned short usPort, + matchmaking_ping_response* pRequestServersResponse) + { + auto response = pRequestServersResponse; + const auto addr = network::address_from_ip(htonl(unIP), usPort); + + party::query_server( + addr, [response](const bool success, const game::netadr_t& host, const ::utils::info_string& info, + const uint32_t ping) + { + if (success) + { + auto server_item = create_server_item(host, info, ping, success); + response->ServerResponded(server_item); + } + else + { + response->ServerFailedToRespond(); + } + }); + + return reinterpret_cast(static_cast(7 + rand())); + } + + int matchmaking_servers::PlayerDetails(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse) + { + return 0; + } + + int matchmaking_servers::ServerRules(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse) + { + return 0; + } + + void matchmaking_servers::CancelServerQuery(int hServerQuery) + { + } +}