diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua index 8fa3bc88..2dc6530c 100644 --- a/data/ui_scripts/stats/__init__.lua +++ b/data/ui_scripts/stats/__init__.lua @@ -16,9 +16,9 @@ DataSources.MPStatsSettings = DataSourceHelpers.ListSetup( "MPStatsSettings", fu if dvarName == "cg_unlockall_loot" then Engine.SetDvar( "ui_enableAllHeroes", f1_arg1.value ) end - end + end - table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock All Loot", "Whether loot should be locked based on the player's stats or always unlocked.", "MPStatsSettings_unlock_loot", "cg_unlockall_loot", { + table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock All Loot", "Whether loot should be locked based on the player's stats or always unlocked.", "MPStatsSettings_unlock_loot", "cg_unlockall_loot", { { option = "MENU_DISABLED", value = 0, @@ -42,7 +42,7 @@ 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 Attachments", "All attachments on weapons are unlocked.", "MPStatsSettings_unlockall_attachments", "cg_unlockall_attachments", { { option = "MENU_DISABLED", value = 0, @@ -53,8 +53,7 @@ DataSources.MPStatsSettings = DataSourceHelpers.ListSetup( "MPStatsSettings", fu value = 1 }, }, nil, updateDvar )) - -- Placeholder for later - --[[table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock all camos", "All camos on weapons are unlocked.", "MPStatsSettings_unlockall_camos", "cg_unlockall_camos", { + table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock all Camos and Reticles", "All camos and reticles on weapons are unlocked.", "MPStatsSettings_unlockall_camos_and_reticles", "cg_unlockall_camos_and_reticles", { { option = "MENU_DISABLED", value = 0, @@ -64,7 +63,18 @@ DataSources.MPStatsSettings = DataSourceHelpers.ListSetup( "MPStatsSettings", fu option = "MENU_ENABLED", value = 1 }, - }, nil, updateDvar ))]] + }, nil, updateDvar )) + table.insert( optionsTable, CoD.OptionsUtility.CreateDvarSettings( controller, "Unlock all Emblems and Backings", "All emblems and backings are unlocked.", "MPStatsSettings_unlockall_emblems_and_backings", "cg_unlockall_emblems_and_backings", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar )) local rankLevels = {} if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then @@ -188,7 +198,7 @@ DataSources.MPStatsSettings = DataSourceHelpers.ListSetup( "MPStatsSettings", fu } }) - return optionsTable + return optionsTable end) if Dvar.cg_unlockall_loot:get() == true then @@ -208,7 +218,7 @@ LUI.createMenu.BoiiiStatsMenu = function ( controller ) self.buttonModel = Engine.CreateModel( Engine.GetModelForController( controller ), "BoiiiStatsMenu.buttonPrompts" ) self.anyChildUsesUpdateState = true - local GameSettingsBackground = CoD.GameSettings_Background.new( self, controller ) + local GameSettingsBackground = CoD.GameSettings_Background.new( self, controller ) GameSettingsBackground:setLeftRight( true, true, 0, 0 ) GameSettingsBackground:setTopBottom( true, true, 0, 0 ) GameSettingsBackground.MenuFrame.titleLabel:setText( Engine.Localize( "STATS SETTINGS" ) ) @@ -218,7 +228,7 @@ LUI.createMenu.BoiiiStatsMenu = function ( controller ) self:addElement( GameSettingsBackground ) self.GameSettingsBackground = GameSettingsBackground - local Options = CoD.Competitive_SettingsList.new( self, controller ) + local Options = CoD.Competitive_SettingsList.new( self, controller ) Options:setLeftRight( true, false, 26, 741 ) Options:setTopBottom( true, false, 135, 720 ) Options.Title.DescTitle:setText( Engine.Localize( "Stats" ) ) @@ -227,7 +237,7 @@ LUI.createMenu.BoiiiStatsMenu = function ( controller ) self:addElement( Options ) self.Options = Options - self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil, function ( element, menu, controller, model ) + self:AddButtonCallbackFunction( self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil, function ( element, menu, controller, model ) GoBack( self, controller ) SetPerControllerTableProperty( controller, "disableGameSettingsOptions", nil ) return true @@ -236,10 +246,10 @@ LUI.createMenu.BoiiiStatsMenu = function ( controller ) return true end, false ) - GameSettingsBackground.MenuFrame:setModel( self.buttonModel, controller ) - Options.id = "Options" + GameSettingsBackground.MenuFrame:setModel( self.buttonModel, controller ) + Options.id = "Options" - self:processEvent( { + self:processEvent( { name = "menu_loaded", controller = controller } ) @@ -247,24 +257,24 @@ LUI.createMenu.BoiiiStatsMenu = function ( controller ) name = "update_state", menu = self } ) - if not self:restoreState() then + if not self:restoreState() then self.Options:processEvent( { name = "gain_focus", controller = controller } ) end - LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) + LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) element.GameSettingsBackground:close() element.Options:close() Engine.UnsubscribeAndFreeModel( Engine.GetModel( Engine.GetModelForController( controller ), "BoiiiStatsMenu.buttonPrompts" ) ) end ) - if PostLoadFunc then + if PostLoadFunc then PostLoadFunc( self, controller ) end - return self + return self end CoD.LobbyButtons.MP_STATS = { @@ -272,10 +282,34 @@ CoD.LobbyButtons.MP_STATS = { action = function ( self, element, controller, param, menu ) SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) OpenPopup( menu, "BoiiiStatsMenu", controller ) - end, + end, customId = "btnMPStats" } +CoD.LobbyButtons.MP_START_GAME = { + stringRef = "MENU_START_GAME_CAPS", + action = function ( self, element, controller, param, menu ) + --Engine.SetDvar( "bot_difficulty", 3 ) + Engine.SetDvar( "party_minplayers", 1 ) + Engine.Exec( nil, "launchgame" ) + end, + customId = "btnStartGame" +} + +CoD.LobbyButtons.SETTING_UP_BOTS = { + stringRef = "MENU_SETUP_BOTS_CAPS", + action = function ( self, element, controller, param, menu ) + SetPerControllerTableProperty( controller, "disableGameSettingsOptions", true ) + OpenPopup( menu, "GameSettings_Bots", controller ) + end, + customId = "btnSettingUpBots" +} + +CoD.LobbyButtons.MP_CUSTOM_SETUP_GAME = { + stringRef = "MPUI_SETUP_GAME_CAPS", + action = OpenSetupGameMP, + customId = "btnSetupGame", +} local IsGamescomDemo = function () return Dvar.ui_execdemo_gamescom:get() @@ -302,7 +336,7 @@ local AddButton = function ( controller, options, button, isLargeButton ) button.warning = false if button.defaultState ~= nil then if button.defaultState == CoD.LobbyButtons.DISABLED then - button.disabled = true + button.disabled = true elseif button.defaultState == CoD.LobbyButtons.HIDDEN then button.hidden = true end @@ -376,6 +410,8 @@ local AddSpacer = function ( options ) end end +local MapVote = 0 + CoD.LobbyMenus.MPButtonsOnline = function ( f26_arg0, f26_arg1, f26_arg2 ) if f26_arg2 == 1 then AddLargeButton( f26_arg0, f26_arg1, CoD.LobbyButtons.MP_FIND_MATCH ) @@ -398,8 +434,52 @@ CoD.LobbyMenus.MPButtonsOnline = function ( f26_arg0, f26_arg1, f26_arg2 ) if not DisableBlackMarket() then AddSmallButton( f26_arg0, f26_arg1, CoD.LobbyButtons.BLACK_MARKET ) end - AddSpacer( f26_arg1 ) - AddSmallButton( f26_arg0, f26_arg1, CoD.LobbyButtons.MP_STATS ) + AddSpacer( f26_arg1 ) + AddSmallButton( f26_arg0, f26_arg1, CoD.LobbyButtons.MP_STATS ) + MapVote = 1 +end + +CoD.LobbyMenus.MPButtonsOnlinePublic = function ( f27_arg0, f27_arg1, f27_arg2 ) + if MapVote == 1 then + Engine.Exec(nil, "LobbyStopDemo") -- Enable map vote at start lobby + MapVote = 0 + end + AddLargeButton( f27_arg0, f27_arg1, CoD.LobbyButtons.MP_START_GAME ) --Launch match button + AddSpacer( f27_arg1 ) + AddLargeButton( f27_arg0, f27_arg1, CoD.LobbyButtons.MP_CAC ) + AddLargeButton( f27_arg0, f27_arg1, CoD.LobbyButtons.MP_SPECIALISTS ) + AddLargeButton( f27_arg0, f27_arg1, CoD.LobbyButtons.MP_SCORESTREAKS ) + if Engine.DvarBool( nil, "inventory_test_button_visible" ) then + AddLargeButton( f27_arg0, f27_arg1, CoD.LobbyButtons.MP_INVENTORY_TEST ) + end +--[[local f27_local0 = Engine.GetPlaylistInfoByID( Engine.GetPlaylistID() ) + if f27_local0 then + local f27_local1 = f27_local0.playlist.category + if f27_local1 == Engine.GetPlaylistCategoryIdByName( "core" ) or f27_local1 == Engine.GetPlaylistCategoryIdByName( "hardcore" ) then + AddSpacer( f27_arg1 ) + AddSmallButton( f27_arg0, f27_arg1, CoD.LobbyButtons.MP_PUBLIC_LOBBY_LEADERBOARD ) + end + end +]] if not DisableBlackMarket() then + AddSpacer( f27_arg1 ) + AddLargeButton( f27_arg0, f27_arg1, CoD.LobbyButtons.BLACK_MARKET ) + end + AddSpacer( f27_arg1 ) + AddSmallButton( f27_arg0, f27_arg1, CoD.LobbyButtons.MP_CUSTOM_SETUP_GAME ) --Setup game in public lobby +end + +CoD.LobbyMenus.MPButtonsArenaGame = function ( f31_arg0, f31_arg1, f31_arg2 ) + AddLargeButton( f31_arg0, f31_arg1, CoD.LobbyButtons.MP_START_GAME ) --Launch match button + AddSpacer( f31_arg1 ) + AddLargeButton( f31_arg0, f31_arg1, CoD.LobbyButtons.MP_CAC ) + AddLargeButton( f31_arg0, f31_arg1, CoD.LobbyButtons.MP_SPECIALISTS ) + AddLargeButton( f31_arg0, f31_arg1, CoD.LobbyButtons.MP_SCORESTREAKS ) + if not DisableBlackMarket() then + AddSpacer( f31_arg1 ) + AddLargeButton( f31_arg0, f31_arg1, CoD.LobbyButtons.BLACK_MARKET ) + end + AddSpacer( f31_arg1 ) + AddSmallButton( f31_arg0, f31_arg1, CoD.LobbyButtons.SETTING_UP_BOTS ) --Bot setting button in public lobby end CoD.LobbyMenus.ZMButtonsOnline = function ( f33_arg0, f33_arg1, f33_arg2 ) @@ -414,12 +494,11 @@ CoD.LobbyMenus.ZMButtonsOnline = function ( f33_arg0, f33_arg1, f33_arg2 ) AddSpacer( f33_arg1 ) end AddLargeButton( f33_arg0, f33_arg1, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS ) - -- Disable these for now, demonware emulation still needs to be implemented - --AddLargeButton( f33_arg0, f33_arg1, CoD.LobbyButtons.ZM_MEGACHEW_FACTORY ) - --AddLargeButton( f33_arg0, f33_arg1, CoD.LobbyButtons.ZM_GOBBLEGUM_RECIPES ) + AddLargeButton( f33_arg0, f33_arg1, CoD.LobbyButtons.ZM_MEGACHEW_FACTORY ) + AddLargeButton( f33_arg0, f33_arg1, CoD.LobbyButtons.ZM_GOBBLEGUM_RECIPES ) AddLargeButton( f33_arg0, f33_arg1, CoD.LobbyButtons.ZM_BUILD_KITS ) - AddSpacer( f33_arg1 ) - AddSmallButton( f33_arg0, f33_arg1, CoD.LobbyButtons.MP_STATS ) + AddSpacer( f33_arg1 ) + AddSmallButton( f33_arg0, f33_arg1, CoD.LobbyButtons.MP_STATS ) end local targetButtons = { @@ -455,6 +534,7 @@ local targetButtons = { [LobbyData.UITargets.UI_MPLOBBYONLINETHEATER.id] = CoD.LobbyMenus.ButtonsTheaterGame, [LobbyData.UITargets.UI_ZMLOBBYONLINETHEATER.id] = CoD.LobbyMenus.ButtonsTheaterGame } + CoD.LobbyMenus.AddButtonsForTarget = function ( controller, id ) local buttonFunc = targetButtons[id] local model = nil diff --git a/deps/curl b/deps/curl index 495d0981..f6d6f3ce 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 495d09810aa9ad6ed70ad0cf122e12007f2b8ae1 +Subproject commit f6d6f3ce01e377932f1ce7c24ee34d45a36950b8 diff --git a/src/client/component/loot.cpp b/src/client/component/loot.cpp index 25df9f64..fc12e7b6 100644 --- a/src/client/component/loot.cpp +++ b/src/client/component/loot.cpp @@ -14,7 +14,8 @@ namespace loot game::dvar_t* dvar_cg_unlockall_loot; game::dvar_t* dvar_cg_unlockall_purchases; game::dvar_t* dvar_cg_unlockall_attachments; - game::dvar_t* dvar_cg_cg_unlockall_camos; + game::dvar_t* dvar_cg_unlockall_camos_and_reticles; + game::dvar_t* dvar_cg_unlockall_emblems_and_backings; utils::hook::detour loot_getitemquantity_hook; utils::hook::detour liveinventory_getitemquantity_hook; @@ -22,9 +23,10 @@ namespace loot utils::hook::detour bg_unlockablesisitempurchased_hook; utils::hook::detour bg_unlockablesisitemattachmentlocked_hook; utils::hook::detour bg_unlockablesisattachmentslotlocked_hook; - - int loot_getitemquantity_stub(const game::ControllerIndex_t controller_index, const game::eModes mode, - const int item_id) + utils::hook::detour bg_unlockablesemblemorbackinglockedbychallenge_hook; + utils::hook::detour bg_unlockablesitemoptionlocked_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) { @@ -42,7 +44,7 @@ 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 - if (dvar_cg_unlockall_loot->current.value.enabled && (item_id == 99003 || item_id >= 99018 && item_id <= 99021 || item_id == 99025|| + 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; @@ -90,6 +92,27 @@ namespace loot return bg_unlockablesisattachmentslotlocked_hook.invoke(mode, controller_index, item_index, attachment_slot_index); } + + bool bg_unlockablesitemoptionlocked_stub(game::eModes mode, const game::ControllerIndex_t controllerIndex, int itemIndex, int optionIndex) + { + // This does not unlock Dark Matter. Probably need to do something with group items + if (dvar_cg_unlockall_camos_and_reticles->current.value.enabled) + { + return false; + } + + return bg_unlockablesitemoptionlocked_hook.invoke(mode, controllerIndex, itemIndex, optionIndex); + } + + bool bg_unlockablesemblemorbackinglockedbychallenge_stub(game::eModes mode, const game::ControllerIndex_t controllerIndex, game::emblemChallengeLookup_t* challengeLookup, bool otherPlayer) + { + if (dvar_cg_unlockall_emblems_and_backings->current.value.enabled) + { + return false; + } + + return bg_unlockablesemblemorbackinglockedbychallenge_hook.invoke(mode, controllerIndex, challengeLookup, otherPlayer); + } }; struct component final : client_component @@ -99,7 +122,8 @@ namespace loot dvar_cg_unlockall_loot = game::register_dvar_bool("cg_unlockall_loot", false, game::DVAR_ARCHIVE, "Unlocks blackmarket loot"); dvar_cg_unlockall_purchases = game::register_dvar_bool("cg_unlockall_purchases", false, game::DVAR_ARCHIVE, "Unlock all purchases with tokens"); dvar_cg_unlockall_attachments = game::register_dvar_bool("cg_unlockall_attachments", false, game::DVAR_ARCHIVE, "Unlocks all attachments"); - dvar_cg_cg_unlockall_camos = game::register_dvar_bool("cg_unlockall_camos", false, game::DVAR_ARCHIVE, "Unlocks all camos"); + 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_emblems_and_backings = game::register_dvar_bool("cg_unlockall_emblems_and_backings", false, game::DVAR_ARCHIVE, "Unlocks all emblems and backings"); loot_getitemquantity_hook.create(0x141E82C00_g, loot_getitemquantity_stub); liveinventory_getitemquantity_hook.create(0x141E09030_g, liveinventory_getitemquantity_stub); @@ -107,6 +131,8 @@ namespace loot bg_unlockablesisitempurchased_hook.create(0x1426A9620_g, bg_unlockablesisitempurchased_stub); bg_unlockablesisitemattachmentlocked_hook.create(0x1426A88D0_g, bg_unlockablesisitemattachmentlocked_stub); bg_unlockablesisattachmentslotlocked_hook.create(0x1426A86D0_g, bg_unlockablesisattachmentslotlocked_stub); + bg_unlockablesitemoptionlocked_hook.create(0x1426AA6C0_g, bg_unlockablesitemoptionlocked_stub); + bg_unlockablesemblemorbackinglockedbychallenge_hook.create(0x1426A3AE0_g, bg_unlockablesemblemorbackinglockedbychallenge_stub); scheduler::once([]() { if (dvar_cg_unlockall_loot->current.value.enabled) diff --git a/src/client/component/rcon.cpp b/src/client/component/rcon.cpp index 82af9ecc..bc8fe080 100644 --- a/src/client/component/rcon.cpp +++ b/src/client/component/rcon.cpp @@ -17,7 +17,7 @@ namespace rcon { std::optional get_and_validate_rcon_command(const std::string& data) { - const command::params params{reinterpret_cast(data.data())}; + const command::params params{data.data()}; if (params.size() <= 1) { @@ -55,10 +55,11 @@ namespace rcon void rcon_handler(const game::netadr_t& target, const network::data_view& data) { auto str_data = std::string(reinterpret_cast(data.data()), data.size()); - scheduler::once([target, s = std::move(str_data)] + /*scheduler::once([target, s = std::move(str_data)] { rcon_executer(target, s); - }, scheduler::main); + }, scheduler::main);*/ + rcon_executer(target, str_data); } } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index ff759ff0..d0967dd6 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1594,6 +1594,93 @@ namespace game static_assert(sizeof(workshop_data) == 0x4C8); + struct DDLMember + { + const char* name; + int index; + void* parent; + int bitSize; + int limitSize; + int offset; + int type; + int externalIndex; + unsigned int rangeLimit; + unsigned int serverDelta; + unsigned int clientDelta; + int arraySize; + int enumIndex; + int permission; + }; + + struct DDLHash + { + int hash; + int index; + }; + + struct DDLHashTable + { + DDLHash* list; + int count; + int max; + }; + + struct DDLStruct + { + const char* name; + int bitSize; + int memberCount; + DDLMember* members; + DDLHashTable hashTableUpper; + DDLHashTable hashTableLower; + }; + + struct DDLEnum + { + const char* name; + int memberCount; + const char** members; + DDLHashTable hashTable; + }; + + struct DDLDef + { + char* name; + uint16_t version; + unsigned int checksum; + byte flags; + int bitSize; + int byteSize; + DDLStruct* structList; + int structCount; + DDLEnum* enumList; + int enumCount; + DDLDef* next; + int headerBitSize; + int headerByteSize; + int reserveSize; + int userFlagsSize; + bool paddingUsed; + }; + + struct DDLContext; + typedef void(__stdcall* DDLWriteCB)(DDLContext*, void*); + + struct DDLContext + { + void* buff; + int len; + const DDLDef* def; + DDLWriteCB writeCB; + void* userData; + }; + + struct emblemChallengeLookup_t + { + __int16 challengeIndex; + unsigned char itemIndex; + }; + union XAssetHeader { /*PhysPreset* physPreset;