commit
d89f3f2d13
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -40,7 +40,7 @@
|
||||
[submodule "deps/protobuf"]
|
||||
path = deps/protobuf
|
||||
url = https://github.com/protocolbuffers/protobuf.git
|
||||
branch = 3.17.x
|
||||
branch = 3.20.x
|
||||
[submodule "deps/zlib"]
|
||||
path = deps/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
|
146
data/ui_scripts/custom_depot/__init__.lua
Normal file
146
data/ui_scripts/custom_depot/__init__.lua
Normal file
@ -0,0 +1,146 @@
|
||||
if game:issingleplayer() then
|
||||
return
|
||||
end
|
||||
|
||||
-- from mpdepotbase.lua, global definition isn't working
|
||||
InventoryCurrencyType = {
|
||||
LaunchCredits = 1,
|
||||
Credits = 2,
|
||||
Parts = 3,
|
||||
CoDPoints = 4,
|
||||
Bonus = 5,
|
||||
Max = 6
|
||||
}
|
||||
|
||||
ItemRarity = {
|
||||
Common = 0,
|
||||
Rare = 1,
|
||||
Legendary = 2,
|
||||
Epic = 3
|
||||
}
|
||||
|
||||
custom_depot = {
|
||||
collection_details_menu = nil,
|
||||
data = {
|
||||
currencies = {
|
||||
launchCredits = 0, -- LaunchCredits
|
||||
credits = 0, -- Credits
|
||||
parts = 0, -- Parts
|
||||
codPoints = 0, -- CoDPoints
|
||||
bonus = 0 -- Bonus
|
||||
},
|
||||
items = {},
|
||||
reward_splashes = {},
|
||||
has_accepted_mod_eula = false,
|
||||
has_seen_mod_eula = false
|
||||
},
|
||||
directory_path = "players2/user",
|
||||
file_name = "depot.json",
|
||||
file_path = nil,
|
||||
functions = {}
|
||||
}
|
||||
|
||||
custom_depot.file_path = string.format("%s/%s", custom_depot.directory_path, custom_depot.file_name)
|
||||
|
||||
custom_depot.get_function = function(function_name)
|
||||
if not function_name or not custom_depot.functions[function_name] then
|
||||
return nil
|
||||
end
|
||||
|
||||
return custom_depot.functions[function_name]
|
||||
end
|
||||
|
||||
custom_depot.functions["save_depot_data"] = function()
|
||||
io.writefile(custom_depot.file_path, json.encode(custom_depot.data), false)
|
||||
end
|
||||
|
||||
custom_depot.functions["load_depot_data"] = function()
|
||||
if not io.directoryexists(custom_depot.directory_path) then
|
||||
io.createdirectory(custom_depot.directory_path)
|
||||
end
|
||||
|
||||
if not io.fileexists(custom_depot.file_path) then
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
|
||||
custom_depot.data = json.decode(io.readfile(custom_depot.file_path))
|
||||
end
|
||||
|
||||
local function convert_currency_to_string(type)
|
||||
if type == InventoryCurrencyType.LaunchCredits then
|
||||
return "launchCredits"
|
||||
elseif type == InventoryCurrencyType.Credits then
|
||||
return "credits"
|
||||
elseif type == InventoryCurrencyType.Parts then
|
||||
return "parts"
|
||||
elseif type == InventoryCurrencyType.CoDPoints then
|
||||
return "codPoints"
|
||||
elseif type == InventoryCurrencyType.Bonus then
|
||||
return "bonus"
|
||||
end
|
||||
end
|
||||
|
||||
custom_depot.functions["add_currency"] = function(currency_type, amount)
|
||||
local type = convert_currency_to_string(currency_type)
|
||||
custom_depot.data.currencies[type] = custom_depot.data.currencies[type] + amount
|
||||
end
|
||||
|
||||
custom_depot.functions["remove_currency"] = function(currency_type, amount)
|
||||
local type = convert_currency_to_string(currency_type)
|
||||
custom_depot.data.currencies[type] = custom_depot.data.currencies[type] - amount
|
||||
end
|
||||
|
||||
custom_depot.functions["get_currency"] = function(currency_type)
|
||||
local type = convert_currency_to_string(currency_type)
|
||||
|
||||
if not currency_type or not custom_depot.data.currencies[type] then
|
||||
return nil
|
||||
end
|
||||
|
||||
return custom_depot.data.currencies[type]
|
||||
end
|
||||
|
||||
custom_depot.functions["add_item"] = function(item, value)
|
||||
custom_depot.data.items[item] = value
|
||||
end
|
||||
|
||||
custom_depot.functions["has_item"] = function(item)
|
||||
return custom_depot.data.items[item] ~= nil
|
||||
end
|
||||
|
||||
custom_depot.functions["add_reward_splash"] = function(item, value)
|
||||
custom_depot.data.reward_splashes[item] = value
|
||||
end
|
||||
|
||||
custom_depot.functions["has_reward_splash"] = function(item)
|
||||
return custom_depot.data.reward_splashes[item] ~= nil
|
||||
end
|
||||
|
||||
custom_depot.functions["has_accepted_mod_eula"] = function()
|
||||
return custom_depot.data.has_accepted_mod_eula
|
||||
end
|
||||
|
||||
custom_depot.functions["set_has_accepted_mod_eula"] = function(value)
|
||||
custom_depot.data.has_accepted_mod_eula = value
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
|
||||
custom_depot.functions["has_seen_mod_eula"] = function()
|
||||
return custom_depot.data.has_seen_mod_eula
|
||||
end
|
||||
|
||||
custom_depot.functions["set_has_seen_mod_eula"] = function(value)
|
||||
custom_depot.data.has_seen_mod_eula = value
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
|
||||
custom_depot.get_function("load_depot_data")()
|
||||
|
||||
if Engine.InFrontend() then
|
||||
require("mod_eula")
|
||||
require("depot_override")
|
||||
end
|
||||
|
||||
if not Engine.InFrontend() then
|
||||
require("scoreboard_override")
|
||||
end
|
332
data/ui_scripts/custom_depot/depot_override.lua
Normal file
332
data/ui_scripts/custom_depot/depot_override.lua
Normal file
@ -0,0 +1,332 @@
|
||||
GetCurrencyBalance = function(currency_type)
|
||||
return custom_depot.get_function("get_currency")(currency_type)
|
||||
end
|
||||
|
||||
Inventory_PurchaseItem_orig = Engine.Inventory_PurchaseItem
|
||||
Engine.Inventory_PurchaseItem = function(controller, item_guid, unk2)
|
||||
if not custom_depot.get_function("has_item")(item_guid) then
|
||||
custom_depot.get_function("add_item")(item_guid, true)
|
||||
|
||||
local item_value = Engine.TableLookup(LootTable.File, LootTable.Cols.GUID, item_guid, LootTable.Cols.Value)
|
||||
custom_depot.get_function("remove_currency")(InventoryCurrencyType.Parts, item_value)
|
||||
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
|
||||
if custom_depot.collection_details_menu then
|
||||
custom_depot.collection_details_menu:OnCraftedItem()
|
||||
end
|
||||
end
|
||||
|
||||
return Inventory_PurchaseItem_orig(controller, item_guid, unk2)
|
||||
end
|
||||
|
||||
GetItemLockState_orig = Engine.GetItemLockState
|
||||
Engine.GetItemLockState = function(controller, item_guid)
|
||||
if custom_depot.get_function("has_item")(item_guid) then
|
||||
return "Unlocked", 0, ""
|
||||
end
|
||||
|
||||
return GetItemLockState_orig(controller, item_guid)
|
||||
end
|
||||
|
||||
GetItemSet_orig = GetItemSet
|
||||
GetItemSet = function(item_set_id)
|
||||
local item_set = GetItemSet_orig(item_set_id)
|
||||
local items_unlocked = 0
|
||||
|
||||
for k, v in pairs(item_set.setItems) do
|
||||
if custom_depot.get_function("has_item")(v.guid) and (not v.isOwned or v.lockState == "Unlocked") then
|
||||
v.isOwned = true
|
||||
v.lockState = "Unlocked"
|
||||
items_unlocked = items_unlocked + 1
|
||||
end
|
||||
end
|
||||
|
||||
if items_unlocked == #item_set.setItems then
|
||||
if not item_set.completed then
|
||||
item_set.completed = true
|
||||
end
|
||||
|
||||
if not custom_depot.get_function("has_item")(item_set.setReward.guid) then
|
||||
custom_depot.get_function("add_item")(item_set.setReward.guid, true)
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
|
||||
if custom_depot.collection_details_menu then
|
||||
custom_depot.collection_details_menu:OnCompletedSet()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
item_set.numOwned = items_unlocked
|
||||
return item_set
|
||||
end
|
||||
|
||||
GetItemSets_orig = GetItemSets
|
||||
GetItemSets = function()
|
||||
local item_sets = GetItemSets_orig()
|
||||
local completed_sets = 0
|
||||
|
||||
for i = 1, #item_sets.seasons do
|
||||
local seasons_completed_sets = 0
|
||||
local sets = item_sets.seasons[i].sets
|
||||
local rewardData = item_sets.seasons[i].rewardData
|
||||
|
||||
for i = 1, #sets do
|
||||
if sets[i].completed then
|
||||
completed_sets = completed_sets + 1
|
||||
seasons_completed_sets = seasons_completed_sets + 1
|
||||
end
|
||||
end
|
||||
|
||||
if item_sets.seasons[i].completedSets == #sets then
|
||||
rewardData.setReward.isOwned = true
|
||||
rewardData.setReward.lockState = "Unlocked"
|
||||
rewardData.completed = true
|
||||
|
||||
if not custom_depot.get_function("has_item")(rewardData.setReward.guid) then
|
||||
custom_depot.get_function("add_item")(rewardData.setReward.guid, true)
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
end
|
||||
|
||||
item_sets.seasons[i].completedSets = seasons_completed_sets
|
||||
end
|
||||
|
||||
for k, v in pairs(item_sets.itemToSetMap) do
|
||||
local items_unlocked = 0
|
||||
|
||||
for i = 1, #v.setItems do
|
||||
if custom_depot.get_function("has_item")(v.setItems[i].guid) and
|
||||
(not v.setItems[i].isOwned or v.setItems[i].lockState == "Unlocked") then
|
||||
v.setItems[i].isOwned = true
|
||||
v.setItems[i].lockState = "Unlocked"
|
||||
items_unlocked = items_unlocked + 1
|
||||
end
|
||||
end
|
||||
|
||||
if items_unlocked == #v.setItems then
|
||||
if not v.completed then
|
||||
v.completed = true
|
||||
completed_sets = completed_sets + 1
|
||||
end
|
||||
|
||||
if not custom_depot.get_function("has_item")(v.setReward.guid) then
|
||||
custom_depot.get_function("add_item")(v.setReward.guid, true)
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
end
|
||||
|
||||
v.numOwned = items_unlocked
|
||||
end
|
||||
|
||||
item_sets.completedSets = completed_sets
|
||||
return item_sets
|
||||
end
|
||||
|
||||
IsContentPromoUnlocked_orig = IsContentPromoUnlocked
|
||||
IsContentPromoUnlocked = function()
|
||||
return true
|
||||
end
|
||||
|
||||
TryShowCollectionCompleted_orig = TryShowCollectionCompleted
|
||||
TryShowCollectionCompleted = function(controller, reward_data, unk1)
|
||||
if reward_data.completed then
|
||||
if not custom_depot.get_function("has_reward_splash")(reward_data.setReward.guid) then
|
||||
LUI.FlowManager.RequestAddMenu(nil, "MPDepotCollectionRewardSplash", true, controller, false, {
|
||||
collectionData = reward_data
|
||||
})
|
||||
|
||||
if custom_depot.collection_details_menu then
|
||||
custom_depot.collection_details_menu:OnCompletedSet()
|
||||
end
|
||||
|
||||
custom_depot.get_function("add_reward_splash")(reward_data.setReward.guid, true)
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
TryShowSeasonCompleted_orig = TryShowSeasonCompleted
|
||||
TryShowSeasonCompleted = function(controller, reward_data, unk1)
|
||||
if reward_data.completed then
|
||||
if not custom_depot.get_function("has_reward_splash")(reward_data.setReward.guid) then
|
||||
LUI.FlowManager.RequestAddMenu(nil, "MPDepotCollectionRewardSplash", true, controller, false, {
|
||||
collectionData = reward_data
|
||||
})
|
||||
|
||||
if custom_depot.collection_details_menu then
|
||||
custom_depot.collection_details_menu:OnCompletedSet()
|
||||
end
|
||||
|
||||
custom_depot.get_function("add_reward_splash")(reward_data.setReward.guid, true)
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
MPDepotCollectionDetailsMenu_orig = LUI.MenuBuilder.m_types_build["MPDepotCollectionDetailsMenu"]
|
||||
MPDepotCollectionDetailsMenu = function(unk1, unk2)
|
||||
custom_depot.collection_details_menu = MPDepotCollectionDetailsMenu_orig(unk1, unk2)
|
||||
return custom_depot.collection_details_menu
|
||||
end
|
||||
LUI.MenuBuilder.m_types_build["MPDepotCollectionDetailsMenu"] = MPDepotCollectionDetailsMenu
|
||||
|
||||
MPDepotOpenLootMenu_orig = LUI.MenuBuilder.m_types_build["MPDepotOpenLootMenu"]
|
||||
MPDepotOpenLootMenu = function(unk1, unk2)
|
||||
local open_loot_menu = MPDepotOpenLootMenu_orig(unk1, unk2)
|
||||
|
||||
local supply_drop_orig = open_loot_menu.m_eventHandlers["supply_drop"]
|
||||
open_loot_menu:registerEventHandler("supply_drop", function(f48_arg0, f48_arg1)
|
||||
f48_arg1.success = true
|
||||
f48_arg1.transaction = f48_arg0.supplyDropTransaction
|
||||
f48_arg1.duplicateRefund = false
|
||||
f48_arg1.items = {}
|
||||
f48_arg1.currencies = {}
|
||||
f48_arg1.replacements = {}
|
||||
f48_arg1.cards = {}
|
||||
|
||||
local supply_drop_price = LUI.MPDepot.GetSupplyDropPrice(f48_arg0.supplyDropType)
|
||||
custom_depot.get_function("remove_currency")(supply_drop_price.type, supply_drop_price.amount)
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
|
||||
for i = 1, unk2.crateType:find("_basic") and math.random(1, 2) or math.random(2, 3) do
|
||||
local items_list = LUI.MPLootDropsBase.GetGenericItemList(x, LUI.MPDepot.LootDropsData[LUI.MPDepot
|
||||
.SuppyDropLootStream[unk2.crateType]].lootTableColName)
|
||||
local random_item = items_list[math.random(#items_list)]
|
||||
|
||||
while random_item.inventoryItemType ~= Cac.InventoryItemType.Loot do
|
||||
random_item = items_list[math.random(#items_list)]
|
||||
end
|
||||
|
||||
if random_item then
|
||||
f48_arg1.items[i] = random_item.guid
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #f48_arg1.items do
|
||||
if not custom_depot.get_function("has_item")(f48_arg1.items[i]) then
|
||||
custom_depot.get_function("add_item")(f48_arg1.items[i], true)
|
||||
else
|
||||
local item_rarity = tonumber(Engine.TableLookup(LootTable.File, LootTable.Cols.GUID, f48_arg1.items[i],
|
||||
LootTable.Cols.Rarity))
|
||||
local dismantled_amount = 0
|
||||
|
||||
if item_rarity == ItemRarity.Common then
|
||||
dismantled_amount = math.random(1, 75)
|
||||
elseif item_rarity == ItemRarity.Rare then
|
||||
dismantled_amount = math.random(75, 155)
|
||||
elseif item_rarity == ItemRarity.Legendary then
|
||||
dismantled_amount = math.random(155, 260)
|
||||
elseif item_rarity == ItemRarity.Epic then
|
||||
dismantled_amount = math.random(260, 550)
|
||||
end
|
||||
|
||||
table.insert(f48_arg1.replacements, {
|
||||
item_index = i,
|
||||
currency = {
|
||||
amount = dismantled_amount
|
||||
}
|
||||
})
|
||||
|
||||
custom_depot.get_function("add_currency")(InventoryCurrencyType.Parts, dismantled_amount)
|
||||
end
|
||||
end
|
||||
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
supply_drop_orig(f48_arg0, f48_arg1)
|
||||
end)
|
||||
|
||||
local slow_purchase_transfer_orig = open_loot_menu.m_eventHandlers["slow_purchase_transfer"]
|
||||
open_loot_menu:registerEventHandler("slow_purchase_transfer", function(f33_arg0, f33_arg1)
|
||||
local f33_local0 = 0
|
||||
if f33_arg0.slowPurchaseTimer then
|
||||
f33_arg0.slowPurchaseTimer:close()
|
||||
f33_arg0.slowPurchaseTimer = nil
|
||||
end
|
||||
local f33_local1 = CoD.CreateState(-500, 0, 500, 20, CoD.AnchorTypes.Top)
|
||||
f33_local1.font = CoD.TextSettings.BodyFont.Font
|
||||
f33_local1.verticalAlignment = LUI.VerticalAlignment.Top
|
||||
f33_local1.horizontalAlignment = LUI.HorizontalAlignment.Center
|
||||
f33_local1.color = Colors.mw1_green
|
||||
f33_local1.alpha = 1
|
||||
f33_arg0.slowPurchaseText = LUI.UIText.new(f33_local1)
|
||||
f33_arg0:addElement(f33_arg0.slowPurchaseText)
|
||||
f33_arg0.slowPurchaseText:setText(Engine.Localize("@DEPOT_TRANSFER_IN_PROGRESS_DOT"))
|
||||
f33_arg0.slowPurchaseText.textState = 1
|
||||
f33_arg0.slowPurchaseText:registerEventHandler("update_slow_purchase_text", f0_local30)
|
||||
f33_arg0.slowPurchaseText:addElement(LUI.UITimer.new(1000, "update_slow_purchase_text"))
|
||||
local f33_local2 = LUI.MenuBuilder.BuildRegisteredType("progressBar")
|
||||
f33_local2:registerAnimationState("default", {
|
||||
topAnchor = false,
|
||||
bottomAnchor = true,
|
||||
leftAnchor = false,
|
||||
rightAnchor = false,
|
||||
top = 0,
|
||||
height = 40
|
||||
})
|
||||
f33_local2:animateToState("default")
|
||||
f33_arg0.slowPurchaseText:addElement(f33_local2)
|
||||
f33_local2:animateFill(f33_local0)
|
||||
f33_arg0.purchaseTimeoutTimer = LUI.UITimer.new(f33_local0, "abort_purchase_transfer", nil, true)
|
||||
f33_arg0:addElement(f33_arg0.purchaseTimeoutTimer)
|
||||
end)
|
||||
|
||||
return open_loot_menu
|
||||
end
|
||||
LUI.MenuBuilder.m_types_build["MPDepotOpenLootMenu"] = MPDepotOpenLootMenu
|
||||
|
||||
AddLootDropTabSelector_orig = LUI.MPDepotBase.AddLootDropTabSelector
|
||||
LUI.MPDepotBase.AddLootDropTabSelector = function(unk1, unk2)
|
||||
if not custom_depot.get_function("has_accepted_mod_eula")() then
|
||||
local item_sets = GetItemSets()
|
||||
|
||||
unk1:AddButtonWithInfo("depot_collections", "@DEPOT_COLLECTIONS", "MPDepotCollectionsMenu", nil, nil,
|
||||
Engine.Localize("@MPUI_X_SLASH_Y", item_sets.completedSets, item_sets.numSets))
|
||||
|
||||
unk1:AddButtonWithInfo("depot_armory", "@DEPOT_ARMORY", "MPDepotArmoryMenu")
|
||||
return
|
||||
end
|
||||
|
||||
AddLootDropTabSelector_orig(unk1, unk2)
|
||||
end
|
||||
|
||||
MPDepotMenu_orig = LUI.MenuBuilder.m_types_build["MPDepotMenu"]
|
||||
MPDepotMenu = function(unk1, unk2)
|
||||
local depot_menu = MPDepotMenu_orig(unk1, unk2)
|
||||
|
||||
if not custom_depot.get_function("has_seen_mod_eula")() then
|
||||
LUI.FlowManager.RequestAddMenu(nil, "mod_eula", true, 0, false, {
|
||||
acceptCallback = function()
|
||||
custom_depot.get_function("set_has_accepted_mod_eula")(true)
|
||||
custom_depot.get_function("set_has_seen_mod_eula")(true)
|
||||
LUI.FlowManager.RequestLeaveMenu(depot_menu)
|
||||
end,
|
||||
declineCallback = function()
|
||||
custom_depot.get_function("set_has_accepted_mod_eula")(false)
|
||||
custom_depot.get_function("set_has_seen_mod_eula")(true)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
return depot_menu
|
||||
end
|
||||
LUI.MenuBuilder.m_types_build["MPDepotMenu"] = MPDepotMenu
|
||||
|
||||
GetLootDataForRef_orig = LUI.InventoryUtils.GetLootDataForRef
|
||||
LUI.InventoryUtils.GetLootDataForRef = function(f13_arg0, f13_arg1, f13_arg2, f13_arg3, f13_arg4)
|
||||
local loot_data = GetLootDataForRef_orig(f13_arg0, f13_arg1, f13_arg2, f13_arg3, f13_arg4)
|
||||
|
||||
if loot_data and custom_depot.get_function("has_item")(loot_data.guid) then
|
||||
loot_data.lockState = "Unlocked"
|
||||
end
|
||||
|
||||
return loot_data
|
||||
end
|
23
data/ui_scripts/custom_depot/mod_eula.lua
Normal file
23
data/ui_scripts/custom_depot/mod_eula.lua
Normal file
@ -0,0 +1,23 @@
|
||||
game:addlocalizedstring("CUSTOM_DEPOT_EULA_1", "Dear User,")
|
||||
game:addlocalizedstring("CUSTOM_DEPOT_EULA_2",
|
||||
"By using this feature, you acknowledge that you are over 18 years old, and that any sort of chance games / gambling are allowed in your country (even if they do not involve real money).")
|
||||
game:addlocalizedstring("CUSTOM_DEPOT_EULA_3",
|
||||
"The H1-Mod team is not responsible if you break the law within your country, and the sole responsibility will be upon you to respect the same.")
|
||||
game:addlocalizedstring("CUSTOM_DEPOT_EULA_4",
|
||||
"The H1-Mod team will never include real money transactions within the modified systems. The only way to get currency, should you wish to, is by playing the game.")
|
||||
game:addlocalizedstring("CUSTOM_DEPOT_EULA_5", "Best Regards,")
|
||||
game:addlocalizedstring("CUSTOM_DEPOT_EULA_6", "The H1-Mod Team.")
|
||||
|
||||
local mod_eula = function(unk1, unk2)
|
||||
return LUI.EULABase.new(CoD.CreateState(0, 0, 0, 0, CoD.AnchorTypes.All), {
|
||||
textStrings = LUI.EULABase.CreateTextStrings("@CUSTOM_DEPOT_EULA_", 6),
|
||||
declineCallback = function(unk3)
|
||||
unk2.declineCallback(unk3)
|
||||
end,
|
||||
acceptCallback = function(unk4)
|
||||
unk2.acceptCallback(unk4)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
LUI.MenuBuilder.registerPopupType("mod_eula", mod_eula)
|
56
data/ui_scripts/custom_depot/scoreboard_override.lua
Normal file
56
data/ui_scripts/custom_depot/scoreboard_override.lua
Normal file
@ -0,0 +1,56 @@
|
||||
-- from roundend.lua, dev comments says that the game["round_end"] array contains indexes for this table
|
||||
local ending_reasons = {"MP_DRAW", "LUA_MENU_REPORT_DRAW", "MP_ROUND_WIN", "MP_ROUND_LOSS", "LUA_MENU_REPORT_VICTORY",
|
||||
"LUA_MENU_REPORT_DEFEAT", "MP_HALFTIME", "MP_OVERTIME", "MP_ROUNDEND", "MP_INTERMISSION",
|
||||
"MP_SWITCHING_SIDES", "MP_MATCH_BONUS_IS", "MP_MATCH_TIE", "MP_GAME_END", "SPLASHES_BLANK"}
|
||||
|
||||
local function starts_with(str, start)
|
||||
return str:sub(1, #start) == start
|
||||
end
|
||||
|
||||
local player_old_score = 0
|
||||
|
||||
local scoreboard_orig = LUI.MenuBuilder.m_types_build["scoreboard"]
|
||||
local scoreboard = function(unk1, unk2)
|
||||
local scoreboard = scoreboard_orig(unk1, unk2)
|
||||
|
||||
scoreboard:registerOmnvarHandler("ui_round_end", function(f22_arg0, f22_arg1)
|
||||
if GameX.IsRankedMatch() then
|
||||
local player_score = 0
|
||||
|
||||
local gamemode = GameX.GetGameMode()
|
||||
local player_stats = Game.GetPlayerScoreInfoAtRank(Game.GetPlayerTeam(), Game.GetPlayerScoreRanking())
|
||||
|
||||
--[[
|
||||
this will do the job for when its needed, aka when round loss/win occurs
|
||||
this check may be true more than once cuz this callback happens 3 times,
|
||||
but the player_old_score variable will stop us from adding more currency
|
||||
]] --
|
||||
local unlocalized_string = ending_reasons[Game.GetOmnvar("ui_round_end_title")]
|
||||
local is_round_based = starts_with(unlocalized_string, "MP_ROUND") or IsGameTypeRoundBased(gamemode)
|
||||
|
||||
if is_round_based or gamemode == "conf" or gamemode == "war" then
|
||||
player_score = player_stats.score
|
||||
else
|
||||
player_score = player_stats.extrascore0
|
||||
end
|
||||
|
||||
local currency_gain = math.floor((player_score - player_old_score) * 10 / 100)
|
||||
|
||||
if currency_gain <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
custom_depot.get_function("add_currency")(InventoryCurrencyType.Parts, currency_gain)
|
||||
|
||||
if custom_depot.functions["has_accepted_mod_eula"]() then
|
||||
custom_depot.get_function("add_currency")(InventoryCurrencyType.Credits, math.random(2, 3))
|
||||
end
|
||||
|
||||
player_old_score = player_score
|
||||
custom_depot.get_function("save_depot_data")()
|
||||
end
|
||||
end)
|
||||
|
||||
return scoreboard
|
||||
end
|
||||
LUI.MenuBuilder.m_types_build["scoreboard"] = scoreboard
|
1
data/ui_scripts/extra_gamemodes/__init__.lua
Normal file
1
data/ui_scripts/extra_gamemodes/__init__.lua
Normal file
@ -0,0 +1 @@
|
||||
-- this patch has been moved to ui_scripts/patches/gamemodes.lua
|
@ -9,6 +9,8 @@ game:addlocalizedstring("LUA_MENU_LATENCY_DESC", "Show server latency.")
|
||||
game:addlocalizedstring("LUA_MENU_RED_DOT_BRIGHTNESS", "Red dot Brightness")
|
||||
game:addlocalizedstring("LUA_MENU_RED_DOT_BRIGHTNESS_DESC", "Adjust the brightness of red dot reticles.")
|
||||
|
||||
game:replacelocalizedstring("MENU_SYSINFO_CUSTOMER_SUPPORT_URL", "https://h1.gg/")
|
||||
|
||||
function createdivider(menu, text)
|
||||
local element = LUI.UIElement.new({
|
||||
leftAnchor = true,
|
||||
|
1
data/ui_scripts/no_mode_switch/__init__.lua
Normal file
1
data/ui_scripts/no_mode_switch/__init__.lua
Normal file
@ -0,0 +1 @@
|
||||
-- this patch has been moved to ui_scripts/patches/no_mode_switch.lua
|
@ -5,6 +5,8 @@ end
|
||||
if (Engine.InFrontend()) then
|
||||
require("shaderdialog")
|
||||
require("gamemodes")
|
||||
require("no_mode_switch")
|
||||
require("disable_useless_things")
|
||||
end
|
||||
|
||||
-- defined in mp_hud/hudutils.lua
|
||||
|
17
data/ui_scripts/patches/disable_useless_things.lua
Normal file
17
data/ui_scripts/patches/disable_useless_things.lua
Normal file
@ -0,0 +1,17 @@
|
||||
-- Disable CP
|
||||
Engine.SetDvarInt("ui_enable_cp", 0)
|
||||
|
||||
-- Disable CP store
|
||||
Engine.SetDvarInt("ui_show_store", 0)
|
||||
|
||||
-- Remove CoD account button
|
||||
if Engine.IsMultiplayer() and CoD.IsCoDAccountRegistrationAvailableInMyRegion() then
|
||||
LUI.removemenubutton("pc_controls", 4)
|
||||
end
|
||||
|
||||
-- Remove social button
|
||||
LUI.MenuBuilder.m_definitions["online_friends_widget"] = function()
|
||||
return {
|
||||
type = "UIElement"
|
||||
}
|
||||
end
|
13
data/ui_scripts/patches/no_mode_switch.lua
Normal file
13
data/ui_scripts/patches/no_mode_switch.lua
Normal file
@ -0,0 +1,13 @@
|
||||
LUI.MenuBuilder.m_definitions["main_choose_exe_popup_menu"] = function()
|
||||
return {
|
||||
type = "generic_yesno_popup",
|
||||
id = "main_choose_exe_popup_menu_id",
|
||||
properties = {
|
||||
popup_title = Engine.Localize("@MENU_NOTICE"),
|
||||
message_text = Engine.Localize("@MENU_QUIT_WARNING"),
|
||||
yes_action = function()
|
||||
Engine.Quit()
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
2
deps/asmjit
vendored
2
deps/asmjit
vendored
@ -1 +1 @@
|
||||
Subproject commit 35f92e8706db78c6aa7482b5e1cdb59c5972a965
|
||||
Subproject commit c59847629d3a19da4d10f0be4ac33b43fc4a100f
|
2
deps/curl
vendored
2
deps/curl
vendored
@ -1 +1 @@
|
||||
Subproject commit e2e7f54b7bea521fa8373095d0f43261a720cda0
|
||||
Subproject commit 9153ba708be87ed6e7c25e1b4864f86fadeb95ad
|
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
||||
Subproject commit 5500c72c5b616da9f0125bcfab513987a1226e2b
|
||||
Subproject commit 6e9e60367d8744e86856590d8ea0e793c61deeec
|
2
deps/zlib
vendored
2
deps/zlib
vendored
@ -1 +1 @@
|
||||
Subproject commit ec3df00224d4b396e2ac6586ab5d25f673caa4c2
|
||||
Subproject commit 2333419cd76cb9ae5f15c9b240b16a2052b27691
|
@ -2,9 +2,11 @@
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "command.hpp"
|
||||
#include "console.hpp"
|
||||
#include "scheduler.hpp"
|
||||
#include "network.hpp"
|
||||
#include "party.hpp"
|
||||
#include "scripting.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
@ -12,6 +14,7 @@
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/string.hpp>
|
||||
#include <utils/cryptography.hpp>
|
||||
#include <utils/io.hpp>
|
||||
|
||||
namespace bots
|
||||
{
|
||||
@ -53,14 +56,12 @@ namespace bots
|
||||
return;
|
||||
}
|
||||
|
||||
static auto first_bot = true;
|
||||
|
||||
const auto bot_name = game::SV_BotGetRandomName();
|
||||
const auto bot_ent = game::SV_AddBot(bot_name);
|
||||
const auto* const bot_name = game::SV_BotGetRandomName();
|
||||
const auto* bot_ent = game::SV_AddBot(bot_name);
|
||||
|
||||
if (bot_ent)
|
||||
{
|
||||
spawn_bot(bot_ent->s.entityNum);
|
||||
spawn_bot(bot_ent->s.number);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -70,6 +71,50 @@ namespace bots
|
||||
}, scheduler::pipeline::server, 100ms);
|
||||
}
|
||||
}
|
||||
|
||||
utils::hook::detour get_bot_name_hook;
|
||||
std::vector<std::string> bot_names{};
|
||||
|
||||
void load_bot_data()
|
||||
{
|
||||
static const char* bots_txt = "h1-mod/bots.txt";
|
||||
|
||||
std::string bots_content;
|
||||
if (!utils::io::read_file(bots_txt, &bots_content))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto names = utils::string::split(bots_content, '\n');
|
||||
for (auto& name : names)
|
||||
{
|
||||
name = utils::string::replace(name, "\r", "");
|
||||
if (!name.empty())
|
||||
{
|
||||
bot_names.emplace_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t bot_id = 0;
|
||||
|
||||
const char* get_random_bot_name()
|
||||
{
|
||||
if (bot_names.empty())
|
||||
{
|
||||
load_bot_data();
|
||||
}
|
||||
|
||||
// only use bot names once, no dupes in names
|
||||
if (!bot_names.empty() && bot_id < bot_names.size())
|
||||
{
|
||||
bot_id %= bot_names.size();
|
||||
const auto& entry = bot_names.at(bot_id++);
|
||||
return utils::string::va("%.*s", static_cast<int>(entry.size()), entry.data());
|
||||
}
|
||||
|
||||
return get_bot_name_hook.invoke<const char*>();
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
@ -82,6 +127,8 @@ namespace bots
|
||||
return;
|
||||
}
|
||||
|
||||
get_bot_name_hook.create(game::SV_BotGetRandomName, get_random_bot_name);
|
||||
|
||||
command::add("spawnBot", [](const command::params& params)
|
||||
{
|
||||
if (!can_add())
|
||||
@ -102,6 +149,13 @@ namespace bots
|
||||
scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i);
|
||||
}
|
||||
});
|
||||
|
||||
// Clear bot names and reset ID on game shutdown to allow new names to be added without restarting
|
||||
scripting::on_shutdown([]
|
||||
{
|
||||
bot_names.clear();
|
||||
bot_id = 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
|
||||
#include "command.hpp"
|
||||
#include "console.hpp"
|
||||
#include "game_console.hpp"
|
||||
@ -8,11 +12,6 @@
|
||||
#include "scheduler.hpp"
|
||||
#include "logfile.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
|
||||
#include "game/scripting/execution.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/string.hpp>
|
||||
#include <utils/memory.hpp>
|
||||
@ -39,8 +38,14 @@ namespace command
|
||||
}
|
||||
}
|
||||
|
||||
void client_command(const int client_num)
|
||||
void client_command(const char client_num)
|
||||
{
|
||||
if (game::mp::g_entities[client_num].client == nullptr)
|
||||
{
|
||||
// Client is not fully connected
|
||||
return;
|
||||
}
|
||||
|
||||
if (!logfile::client_command_stub(client_num))
|
||||
{
|
||||
return;
|
||||
@ -539,9 +544,9 @@ namespace command
|
||||
static void add_commands_generic()
|
||||
{
|
||||
add("quit", game::Quit);
|
||||
add("crash", []()
|
||||
add("crash", []
|
||||
{
|
||||
*reinterpret_cast<int*>(1) = 0;
|
||||
*reinterpret_cast<int*>(1) = 0x12345678;
|
||||
});
|
||||
|
||||
add("commandDump", [](const params& argument)
|
||||
|
@ -32,7 +32,7 @@ namespace logfile
|
||||
return {};
|
||||
}
|
||||
|
||||
const scripting::entity player{game::Scr_GetEntityId(ent->s.entityNum, 0)};
|
||||
const scripting::entity player{game::Scr_GetEntityId(ent->s.number, 0)};
|
||||
return scripting::lua::convert(state, player);
|
||||
}
|
||||
|
||||
@ -262,7 +262,7 @@ namespace logfile
|
||||
scheduler::once([cmd, message, self, hidden]()
|
||||
{
|
||||
const scripting::entity level{*game::levelEntityId};
|
||||
const scripting::entity player{game::Scr_GetEntityId(self->s.entityNum, 0)};
|
||||
const scripting::entity player{game::Scr_GetEntityId(self->s.number, 0)};
|
||||
|
||||
scripting::notify(level, cmd, {player, message, hidden});
|
||||
scripting::notify(player, cmd, {message, hidden});
|
||||
|
@ -14,6 +14,8 @@ namespace lui
|
||||
namespace
|
||||
{
|
||||
uint64_t event_count{};
|
||||
uint64_t obituary_count{};
|
||||
|
||||
bool begin_game_message_event_stub(int a1, const char* name, void* a3)
|
||||
{
|
||||
if (event_count > 30)
|
||||
@ -27,6 +29,16 @@ namespace lui
|
||||
|
||||
return utils::hook::invoke<bool>(0x2655A0_b, a1, name, a3);
|
||||
}
|
||||
|
||||
void cg_entity_event_stub(void* a1, void* a2, unsigned int event_type, void* a4)
|
||||
{
|
||||
if (event_type == 140 && obituary_count++ >= 20)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
utils::hook::invoke<void>(0xF9400_b, a1, a2, event_type, a4);
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
@ -38,6 +50,7 @@ namespace lui
|
||||
{
|
||||
// Patch game message overflow
|
||||
utils::hook::call(0x266E6B_b, begin_game_message_event_stub);
|
||||
utils::hook::call(0xEAC1C_b, cg_entity_event_stub);
|
||||
|
||||
scheduler::loop([]()
|
||||
{
|
||||
@ -46,6 +59,11 @@ namespace lui
|
||||
event_count--;
|
||||
}
|
||||
}, scheduler::pipeline::lui, 50ms);
|
||||
|
||||
scheduler::loop([]()
|
||||
{
|
||||
obituary_count = 0;
|
||||
}, scheduler::pipeline::lui, 0ms);
|
||||
}
|
||||
|
||||
// Increase max extra LUI memory
|
||||
|
@ -67,7 +67,8 @@ namespace patches
|
||||
|
||||
void set_client_dvar_from_server_stub(void* clientNum, void* cgameGlob, const char* dvar, const char* value)
|
||||
{
|
||||
if (dvar == "cg_fov"s || dvar == "cg_fovMin"s)
|
||||
const auto dvar_lowercase = utils::string::to_lower(dvar);
|
||||
if (dvar_lowercase == "cg_fov"s || dvar_lowercase == "cg_fovMin"s)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -121,7 +122,13 @@ namespace patches
|
||||
|
||||
command::params_sv params{};
|
||||
const auto menu_id = atoi(params.get(1));
|
||||
const auto client = &svs_clients[ent->s.entityNum];
|
||||
const auto client = &svs_clients[ent->s.number];
|
||||
|
||||
// 13 => change class
|
||||
if (menu_id == 13 && ent->client->team == game::mp::TEAM_SPECTATOR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 32 => "end_game"
|
||||
if (menu_id == 32 && client->header.remoteAddress.type != game::NA_LOOPBACK)
|
||||
@ -318,6 +325,13 @@ namespace patches
|
||||
utils::hook::jump(SELECT_VALUE(0x511050_b, 0x620040_b), _aligned_realloc);
|
||||
}
|
||||
|
||||
// Uncheat protect gamepad-related dvars
|
||||
dvars::override::register_float("gpad_button_deadzone", 0.13f, 0, 1, game::DVAR_FLAG_SAVED);
|
||||
dvars::override::register_float("gpad_stick_deadzone_min", 0.2f, 0, 1, game::DVAR_FLAG_SAVED);
|
||||
dvars::override::register_float("gpad_stick_deadzone_max", 0.01f, 0, 1, game::DVAR_FLAG_SAVED);
|
||||
dvars::override::register_float("gpad_stick_pressed", 0.4f, 0, 1, game::DVAR_FLAG_SAVED);
|
||||
dvars::override::register_float("gpad_stick_pressed_hysteresis", 0.1f, 0, 1, game::DVAR_FLAG_SAVED);
|
||||
|
||||
if (!game::environment::is_sp())
|
||||
{
|
||||
patch_mp();
|
||||
@ -326,6 +340,9 @@ namespace patches
|
||||
|
||||
static void patch_mp()
|
||||
{
|
||||
// fix vid_restart crash
|
||||
utils::hook::set<uint8_t>(0x139680_b, 0xC3);
|
||||
|
||||
utils::hook::jump(0x5BB9C0_b, &live_get_local_client_name);
|
||||
|
||||
// Disable data validation error popup
|
||||
@ -409,6 +426,9 @@ namespace patches
|
||||
|
||||
// Fix gamepad related crash
|
||||
cl_gamepad_scrolling_buttons_hook.create(0x133210_b, cl_gamepad_scrolling_buttons_stub);
|
||||
|
||||
// Prevent the game from modifying Windows microphone volume (since voice chat isn't used)
|
||||
utils::hook::set<uint8_t>(0x5BEEA0_b, 0xC3); // Mixer_SetWaveInRecordLevels
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -49,12 +49,8 @@ namespace renderer
|
||||
{
|
||||
switch (dvars::r_fullbright->current.integer)
|
||||
{
|
||||
case 4:
|
||||
return 3;
|
||||
case 3:
|
||||
return 13;
|
||||
case 2:
|
||||
return 25;
|
||||
return 13;
|
||||
default:
|
||||
return game::TECHNIQUE_UNLIT;
|
||||
}
|
||||
@ -148,7 +144,7 @@ namespace renderer
|
||||
return;
|
||||
}
|
||||
|
||||
dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 4, game::DVAR_FLAG_SAVED, "Toggles rendering without lighting");
|
||||
dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 2, game::DVAR_FLAG_SAVED, "Toggles rendering without lighting");
|
||||
|
||||
r_init_draw_method_hook.create(SELECT_VALUE(0x5467E0_b, 0x669580_b), &r_init_draw_method_stub);
|
||||
r_update_front_end_dvar_options_hook.create(SELECT_VALUE(0x583560_b, 0x6A78C0_b), &r_update_front_end_dvar_options_stub);
|
||||
|
@ -44,6 +44,8 @@ namespace scripting
|
||||
|
||||
game::dvar_t* g_dump_scripts;
|
||||
|
||||
std::vector<std::function<void()>> shutdown_callbacks;
|
||||
|
||||
void vm_notify_stub(const unsigned int notify_list_owner_id, const game::scr_string_t string_value,
|
||||
game::VariableValue* top)
|
||||
{
|
||||
@ -94,6 +96,11 @@ namespace scripting
|
||||
script_function_table.clear();
|
||||
}
|
||||
|
||||
for (const auto& callback : shutdown_callbacks)
|
||||
{
|
||||
callback();
|
||||
}
|
||||
|
||||
scripting::notify(*game::levelEntityId, "shutdownGame_called", {1});
|
||||
lua::engine::stop();
|
||||
return g_shutdown_game_hook.invoke<void>(free_scripts);
|
||||
@ -162,6 +169,11 @@ namespace scripting
|
||||
}
|
||||
}
|
||||
|
||||
void on_shutdown(const std::function<void()>& callback)
|
||||
{
|
||||
shutdown_callbacks.push_back(callback);
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
|
@ -8,4 +8,6 @@ namespace scripting
|
||||
extern std::unordered_map<int, std::unordered_map<std::string, int>> fields_table;
|
||||
extern std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
|
||||
extern utils::concurrency::container<shared_table_t> shared_table;
|
||||
|
||||
void on_shutdown(const std::function<void()>& callback);
|
||||
}
|
@ -143,8 +143,9 @@ namespace server_list
|
||||
|
||||
if (column == 2)
|
||||
{
|
||||
return utils::string::va("%d/%d [%d]", servers[i].clients, servers[index].max_clients,
|
||||
servers[i].bots);
|
||||
const auto client_count = servers[i].clients - servers[i].bots;
|
||||
return utils::string::va("%d/%d [%d]", client_count, servers[i].max_clients,
|
||||
servers[i].clients);
|
||||
}
|
||||
|
||||
if (column == 3)
|
||||
@ -169,12 +170,20 @@ namespace server_list
|
||||
{
|
||||
std::stable_sort(servers.begin(), servers.end(), [](const server_info& a, const server_info& b)
|
||||
{
|
||||
if (a.clients == b.clients)
|
||||
const auto a_players = a.clients - a.bots;
|
||||
const auto b_players = b.clients - b.bots;
|
||||
|
||||
if (a_players == b_players)
|
||||
{
|
||||
return a.ping < b.ping;
|
||||
if (a.clients == b.clients)
|
||||
{
|
||||
return a.ping < b.ping;
|
||||
}
|
||||
|
||||
return a.clients > b.clients;
|
||||
}
|
||||
|
||||
return a.clients > b.clients;
|
||||
return a_players > b_players;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -5040,6 +5040,11 @@ namespace dvars
|
||||
"Turn on debug lines for melee traces",
|
||||
generate_hash("melee_debug")
|
||||
},
|
||||
{
|
||||
"mis_cheat",
|
||||
"Set when level unlock cheat is performed",
|
||||
generate_hash("mis_cheat")
|
||||
},
|
||||
{
|
||||
"migration_dvarErrors",
|
||||
"Whether to check for illegal script dvar changes.",
|
||||
|
@ -76,6 +76,8 @@ namespace scripting
|
||||
{
|
||||
return { this->id_, this->get_value_id(key.as<S>()) };
|
||||
}
|
||||
|
||||
throw std::runtime_error("Invalid key type");
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1290,9 +1290,9 @@ namespace scripting
|
||||
{"_meth_8215", 0x8215}, // SP 0x2CB4A0 MP 0x44CB00
|
||||
{"_meth_8216", 0x8216}, // SP 0x2CB5D0 MP 0x44CCA0
|
||||
{"_meth_8217", 0x8217}, // SP 0x2CB720 MP 0x44CCF0
|
||||
{"circle", 0x8218}, // SP 0x2D0720 MP 0x439750
|
||||
{"circle", 0x8218}, // SP 0x2D0720 MP 0x439750 - iw6 name is WorldPointInReticle_Circle
|
||||
{"rect", 0x8219}, // SP 0x2D12D0 MP 0x439F20
|
||||
{"_meth_821a", 0x821A}, // SP 0x2D1850 MP 0x43A680
|
||||
{"getpointinbounds", 0x821A}, // SP 0x2D1850 MP 0x43A680
|
||||
{"transfermarkstonewscriptmodel", 0x821B}, // SP 0x2D1FC0 MP 0x43B020
|
||||
{"setwatersheeting", 0x821C}, // SP 0x2C47C0 MP 0x445400
|
||||
{"_meth_821d", 0x821D}, // SP 0x2C02D0 MP 0x000000
|
||||
@ -1303,8 +1303,8 @@ namespace scripting
|
||||
{"_meth_8222", 0x8222}, // SP 0x2CDCF0 MP 0x437140
|
||||
{"_meth_8223", 0x8223}, // SP 0x2CD9F0 MP 0x436F30
|
||||
{"_meth_8224", 0x8224}, // SP 0x2CE3A0 MP 0x437750
|
||||
{"_meth_8225", 0x8225}, // SP 0x2D1E80 MP 0x438700
|
||||
{"_meth_8226", 0x8226}, // SP 0x2C2210 MP 0x4432D0
|
||||
{"isitemunlocked", 0x8225}, // SP 0x2D1E80 MP 0x438700
|
||||
{"getrankedplayerdata", 0x8226}, // SP 0x2C2210 MP 0x4432D0
|
||||
{"vehicleturretcontroloff", 0x8227}, // SP 0x4E7230 MP 0x60E170
|
||||
{"isturretready", 0x8228}, // SP 0x4E7310 MP 0x609890
|
||||
{"_meth_8229", 0x8229}, // SP 0x4E7560 MP 0x609B20
|
||||
@ -1332,7 +1332,7 @@ namespace scripting
|
||||
{"_meth_8240", 0x8240}, // SP 0x2C4AD0 MP 0x000000
|
||||
{"_meth_8241", 0x8241}, // SP 0x274CF0 MP 0x000000
|
||||
{"_meth_8242", 0x8242}, // SP 0x2750F0 MP 0x000000
|
||||
{"_meth_8243", 0x8243}, // SP 0x2C2550 MP 0x443C20
|
||||
{"setcommonplayerdata", 0x8243}, // SP 0x2C2550 MP 0x443C20 - Could be also setrankedplayerdata
|
||||
{"_meth_8244", 0x8244}, // SP 0x2C2A00 MP 0x4442D0
|
||||
{"_meth_8245", 0x8245}, // SP 0x2C3190 MP 0x444850
|
||||
{"trackerupdate", 0x8246}, // SP 0x2C51C0 MP 0x447650
|
||||
@ -1455,7 +1455,7 @@ namespace scripting
|
||||
{"notsolid", 0x82BB}, // SP 0x2E3230 MP 0x452FA0
|
||||
{"setcandamage", 0x82BC}, // SP 0x2E2300 MP 0x453ED0
|
||||
{"setcanradiusdamage", 0x82BD}, // SP 0x2E2360 MP 0x453F30
|
||||
{"physicslaunchclient", 0x82BE}, // SP 0x2E23E0 MP 0x453FB0
|
||||
{"physicslaunch", 0x82BE}, // SP 0x2E23E0 MP 0x453FB0
|
||||
{"setcardicon", 0x82BF}, // SP 0x000000 MP 0x411100
|
||||
{"setcardnameplate", 0x82C0}, // SP 0x000000 MP 0x411110
|
||||
{"setcarddisplayslot", 0x82C1}, // SP 0x000000 MP 0x411120
|
||||
@ -1492,11 +1492,11 @@ namespace scripting
|
||||
{"player_recoilscaleoff", 0x82E0}, // SP 0x28D920 MP 0x4092D0
|
||||
{"weaponlockstart", 0x82E1}, // SP 0x28DA00 MP 0x409530
|
||||
{"weaponlockfinalize", 0x82E2}, // SP 0x28DCC0 MP 0x4097A0
|
||||
{"disableautoreload", 0x82E3}, // SP 0x28DFC0 MP 0x409C50
|
||||
{"weaponlockfree", 0x82E3}, // SP 0x28DFC0 MP 0x409C50 - was disableautoreload
|
||||
{"setentertime", 0x82E4}, // SP 0x28E060 MP 0x409E60
|
||||
{"usinggamepad", 0x82E5}, // SP 0x000000 MP 0x411680
|
||||
{"_meth_82e6", 0x82E6}, // SP 0x000000 MP 0x411700
|
||||
{"_meth_82e7", 0x82E7}, // SP 0x000000 MP 0x411710
|
||||
{"issighted", 0x82E7}, // SP 0x000000 MP 0x411710
|
||||
{"_meth_82e8", 0x82E8}, // SP 0x000000 MP 0x411730
|
||||
{"_meth_82e9", 0x82E9}, // SP 0x000000 MP 0x411720
|
||||
{"_meth_82ea", 0x82EA}, // SP 0x2905B0 MP 0x40BAD0
|
||||
@ -2012,7 +2012,7 @@ namespace scripting
|
||||
{"_meth_84fa", 0x84FA}, // SP 0x2C63F0 MP 0x44D230
|
||||
{"_meth_84fb", 0x84FB}, // SP 0x2BF9D0 MP 0x447EB0
|
||||
{"_meth_84fc", 0x84FC}, // SP 0x2C5650 MP 0x447220
|
||||
{"_meth_84fd", 0x84FD}, // SP 0x000000 MP 0x4109F0
|
||||
{"_meth_84fd", 0x84FD}, // SP 0x000000 MP 0x4109F0 - Could be setMLGCamVisibility or SetMLGSpectator
|
||||
{"_meth_84fe", 0x84FE}, // SP 0x000000 MP 0x0B90C0
|
||||
{"_meth_84ff", 0x84FF}, // SP 0x000000 MP 0x0B9280
|
||||
{"_meth_8500", 0x8500}, // SP 0x2C17E0 MP 0x443F90
|
||||
@ -2153,6 +2153,7 @@ namespace scripting
|
||||
|
||||
std::unordered_map<std::string, unsigned> token_map =
|
||||
{
|
||||
{"", 0x000},
|
||||
{"pl#", 0x001},
|
||||
{"-", 0x002},
|
||||
{"radius`", 0x003},
|
||||
@ -2187,7 +2188,7 @@ namespace scripting
|
||||
{"ai_sight_line_group", 0x020},
|
||||
{"aim_highest_bone", 0x021},
|
||||
{"aim_vis_bone", 0x022},
|
||||
{"aiSpread", 0x023},
|
||||
{"aispread", 0x023},
|
||||
{"aisquadmembers", 0x024},
|
||||
{"alert", 0x025},
|
||||
{"alertlevel", 0x026},
|
||||
@ -2669,10 +2670,10 @@ namespace scripting
|
||||
{"infinite_energy", 0x202},
|
||||
{"info_notnull", 0x203},
|
||||
{"info_player_start", 0x204},
|
||||
{"init", 0x205},
|
||||
{"not_init", 0x205},
|
||||
{"initstructs", 0x206},
|
||||
{"insolid", 0x207},
|
||||
{"intermission", 0x208},
|
||||
{"init", 0x208},
|
||||
{"interval", 0x209},
|
||||
{"inuse", 0x20A},
|
||||
{"invalid_parent", 0x20B},
|
||||
@ -2764,10 +2765,10 @@ namespace scripting
|
||||
{"luinotifyserver", 0x261},
|
||||
{"mag_eject", 0x262},
|
||||
{"mag_eject_left", 0x263},
|
||||
{"main", 0x264},
|
||||
{"not_main", 0x264},
|
||||
{"manual", 0x265},
|
||||
{"manual_ai", 0x266},
|
||||
{"manual_change", 0x267},
|
||||
{"main", 0x267},
|
||||
{"map", 0x268},
|
||||
{"matchid", 0x269},
|
||||
{"matchmakingsettingsversion", 0x26A},
|
||||
@ -2887,13 +2888,13 @@ namespace scripting
|
||||
{"operationsdeadline", 0x2DC},
|
||||
{"oriented", 0x2DD},
|
||||
{"orientto_complete", 0x2DE},
|
||||
{"origin", 0x2DF},
|
||||
{"_not_origin", 0x2DF},
|
||||
{"other", 0x2E0},
|
||||
{"over", 0x2E1},
|
||||
{"_not_owner", 0x2E2}, // was "owner"
|
||||
{"origin", 0x2E2},
|
||||
{"pacifist", 0x2E3},
|
||||
{"pacifistwait", 0x2E4},
|
||||
{"owner", 0x2E5}, // was "pain"
|
||||
{"owner", 0x2E5},
|
||||
{"pantssize", 0x2E6},
|
||||
{"parentindex", 0x2E7},
|
||||
{"parentname", 0x2E8},
|
||||
@ -2925,10 +2926,10 @@ namespace scripting
|
||||
{"perkrestricted", 0x302},
|
||||
{"perks", 0x303},
|
||||
{"perkslots", 0x304},
|
||||
{"_not_pers", 0x305}, // was "pers"
|
||||
{"_not_pers", 0x305},
|
||||
{"persistentperksunlocked", 0x306},
|
||||
{"persistentweaponsunlocked", 0x307},
|
||||
{"pers", 0x308}, // was "phone_off"
|
||||
{"pers", 0x308},
|
||||
{"phone_on", 0x309},
|
||||
{"physics_finished", 0x30A},
|
||||
{"physics_impact", 0x30B},
|
||||
@ -2952,10 +2953,10 @@ namespace scripting
|
||||
{"playerip", 0x31D},
|
||||
{"playername", 0x31E},
|
||||
{"playerpositions", 0x31F},
|
||||
{"players", 0x320},
|
||||
{"playerSpread", 0x321},
|
||||
{"_not_players", 0x320},
|
||||
{"playerspread", 0x321},
|
||||
{"playerxuidhigh", 0x322},
|
||||
{"playerxuidlow", 0x323},
|
||||
{"players", 0x323},
|
||||
{"playing", 0x324},
|
||||
{"points", 0x325},
|
||||
{"position", 0x326},
|
||||
@ -2981,10 +2982,10 @@ namespace scripting
|
||||
{"primaryfurniturekit", 0x33A},
|
||||
{"primaryoffhand", 0x33B},
|
||||
{"primaryreticle", 0x33C},
|
||||
{"primaryweapon", 0x33D},
|
||||
{"_not_primaryweapon", 0x33D},
|
||||
{"privatematchactivesquadmember", 0x33E},
|
||||
{"privatematchcustomclasses", 0x33F},
|
||||
{"privatematchsquadmembers", 0x340},
|
||||
{"primaryweapon", 0x340},
|
||||
{"projectile_impact", 0x341},
|
||||
{"projectile_impact_player", 0x342},
|
||||
{"prone", 0x343},
|
||||
@ -3058,10 +3059,10 @@ namespace scripting
|
||||
{"scope_cap", 0x387},
|
||||
{"scope_center", 0x388},
|
||||
{"scope_top", 0x389},
|
||||
{"score", 0x38A},
|
||||
{"_not_score", 0x38A},
|
||||
{"script", 0x38B},
|
||||
{"script_brushmodel", 0x38C},
|
||||
{"script_clut", 0x38D},
|
||||
{"score", 0x38D},
|
||||
{"script_context", 0x38E},
|
||||
{"script_delay", 0x38F},
|
||||
{"script_goal_changed", 0x390},
|
||||
@ -3096,10 +3097,10 @@ namespace scripting
|
||||
{"secondaryfurniturekit", 0x3AD},
|
||||
{"secondaryoffhand", 0x3AE},
|
||||
{"secondaryreticle", 0x3AF},
|
||||
{"secondaryweapon", 0x3B0},
|
||||
{"_not_secondaryweapon", 0x3B0},
|
||||
{"sentry", 0x3B1},
|
||||
{"sentry_manual", 0x3B2},
|
||||
{"sentry_offline", 0x3B3},
|
||||
{"secondaryweapon", 0x3B3},
|
||||
{"servertimecount", 0x3B4},
|
||||
{"servertimeexceedcount", 0x3B5},
|
||||
{"servertimemax", 0x3B6},
|
||||
@ -3205,7 +3206,7 @@ namespace scripting
|
||||
{"suppressionduration", 0x41A},
|
||||
{"suppressionmeter", 0x41B},
|
||||
{"suppressionstarttime", 0x41C},
|
||||
{"suppressionTime", 0x41D},
|
||||
{"suppressiontime", 0x41D},
|
||||
{"suppressionwait", 0x41E},
|
||||
{"surfacetype", 0x41F},
|
||||
{"surprisedbymedistsq", 0x420},
|
||||
@ -3312,10 +3313,10 @@ namespace scripting
|
||||
{"tag_sight_off", 0x485},
|
||||
{"tag_sight_on", 0x486},
|
||||
{"tag_stow_back_mid_attach", 0x487},
|
||||
{"_not_tag_stowed_back", 0x488}, // was "tag_stowed_back"
|
||||
{"_not_tag_stowed_back", 0x488},
|
||||
{"tag_stowed_hip_rear", 0x489},
|
||||
{"tag_sync", 0x48A},
|
||||
{"tag_stowed_back", 0x48B}, // was "tag_tip"
|
||||
{"tag_stowed_back", 0x48B},
|
||||
{"tag_turret", 0x48C},
|
||||
{"tag_turret_base", 0x48D},
|
||||
{"tag_turret_pitch", 0x48E},
|
||||
@ -3340,10 +3341,10 @@ namespace scripting
|
||||
{"target", 0x4A1},
|
||||
{"target_script_trigger", 0x4A2},
|
||||
{"targetname", 0x4A3},
|
||||
{"_not_team", 0x4A4}, // was "team"
|
||||
{"_not_team", 0x4A4},
|
||||
{"team3", 0x4A5},
|
||||
{"teambalanced", 0x4A6},
|
||||
{"team", 0x4A7}, // was "teammode_axisallies"
|
||||
{"team", 0x4A7},
|
||||
{"teammode_ffa", 0x4A8},
|
||||
{"teammovewaittime", 0x4A9},
|
||||
{"their_score", 0x4AA},
|
||||
@ -3370,10 +3371,10 @@ namespace scripting
|
||||
{"traversecost", 0x4BF},
|
||||
{"traversesoonnotifydist", 0x4C0},
|
||||
{"trend", 0x4C1},
|
||||
{"_not_trigger", 0x4C2}, // was "trigger"
|
||||
{"_not_trigger", 0x4C2},
|
||||
{"trigger_damage", 0x4C3},
|
||||
{"trigger_use", 0x4C4},
|
||||
{"trigger", 0x4C5}, // was "trigger_use_touch"
|
||||
{"trigger", 0x4C5},
|
||||
{"truck_cam", 0x4C6},
|
||||
{"turnrate", 0x4C7},
|
||||
{"turret_deactivate", 0x4C8},
|
||||
@ -3492,97 +3493,423 @@ namespace scripting
|
||||
{"codescripts/struct", 0x53E},
|
||||
{"codescripts/message", 0x53F},
|
||||
{"maps/mp/gametypes/_callbacksetup", 0x540},
|
||||
{"_createfx", 0x575},
|
||||
{"_effect", 0x58F},
|
||||
{"_hasperk", 0x5CB},
|
||||
{"_objective_delete", 0x603},
|
||||
{"_unsetperk", 0x67B},
|
||||
{"ac130", 0x6CE},
|
||||
{"ac130player", 0x6D1},
|
||||
{"scorepercentagecutoff", 0x782},
|
||||
{"addspawnpoints", 0x82F},
|
||||
{"addstartspawnpoints", 0x831},
|
||||
{"addtocharactersarray", 0x848},
|
||||
{"addtoteam", 0x851},
|
||||
{"agent_funcs", 0x897},
|
||||
{"agent_gameparticipant", 0x898},
|
||||
{"agent_teamparticipant", 0x89F},
|
||||
{"agent_type", 0x8A0},
|
||||
{"agentarray", 0x8A1},
|
||||
{"airstrikeinprogress", 0x99C},
|
||||
{"allowuse", 0xAB2},
|
||||
{"allowvote", 0xAB4},
|
||||
{"anim_prop_models", 0xBEC},
|
||||
{"applyloadout", 0xCAE},
|
||||
{"artillerydangercenter", 0xD33},
|
||||
{"atbrinkofdeath", 0xD82},
|
||||
{"attackers", 0xE34},
|
||||
{"primaryprogressbartexty", 0xF88},
|
||||
{"audio", 0x10F0},
|
||||
{"avoidkillstreakonspawntimer", 0x11FC},
|
||||
{"basefontscale", 0x1309},
|
||||
{"bcsounds", 0x1358},
|
||||
{"beingrevived", 0x13AB},
|
||||
{"blockweapondrops", 0x14B5},
|
||||
{"bombsquadicons", 0x154C},
|
||||
{"bombsquadids", 0x154D},
|
||||
{"bot_funcs", 0x161B},
|
||||
{"breathingstoptime", 0x17E6},
|
||||
{"brinkofdeathkillstreak", 0x1818},
|
||||
{"greatestuniqueplayerkills", 0x18B1},
|
||||
{"c4explodethisframe", 0x1974},
|
||||
{"callback_playerdamage", 0x19F5},
|
||||
{"callbackplayerdamage", 0x19FE},
|
||||
{"candocombat", 0x1AC6},
|
||||
{"canperformclienttraces", 0x1AD6},
|
||||
{"carryflag", 0x1BB4},
|
||||
{"challengeinfo", 0x1C62},
|
||||
{"changingweapon", 0x1C87},
|
||||
{"characters", 0x1C8E},
|
||||
{"checkdynamicspawns", 0x1CFA},
|
||||
{"chopper", 0x1D48},
|
||||
{"class", 0x1E2E},
|
||||
{"classtweaks", 0x1E40},
|
||||
{"claymoredetectiondot", 0x1E44},
|
||||
{"claymoredetectiongraceperiod", 0x1E45},
|
||||
{"claymoredetectionmindist", 0x1E46},
|
||||
{"claymoredetonateradius", 0x1E47},
|
||||
{"clearonvictimdisconnect", 0x1EF9},
|
||||
{"clientid", 0x1F0F},
|
||||
{"clientmatchdataid", 0x1F10},
|
||||
{"clienttweakables", 0x1F12},
|
||||
{"combathigh", 0x20AB},
|
||||
{"concussionendtime", 0x20DF},
|
||||
{"conf_fx", 0x20E9},
|
||||
{"connecttime", 0x214F},
|
||||
{"console", 0x2153},
|
||||
{"createuseobject", 0x244C},
|
||||
{"curorigin", 0x24C8},
|
||||
{"curprogress", 0x24C9},
|
||||
{"currentweaponatspawn", 0x252E},
|
||||
{"damagedplayers", 0x259A},
|
||||
{"defaultvalue", 0x27A1},
|
||||
{"delayminetime", 0x27E9},
|
||||
{"deleteobjpoint", 0x2859},
|
||||
{"detectedexploit", 0x2991},
|
||||
{"detectexplosives", 0x2992},
|
||||
{"detectid", 0x2994},
|
||||
{"disabled", 0x2AFD},
|
||||
{"disabledoffhandweapons", 0x2B05},
|
||||
{"disabledusability", 0x2B0A},
|
||||
{"disabledweapon", 0x2B0B},
|
||||
{"disabledweaponswitch", 0x2B0C},
|
||||
{"disablespawning", 0x2B28},
|
||||
{"dogtags", 0x2CDF},
|
||||
{"doingfinalkillcamfx", 0x2CE6},
|
||||
{"doingsplash", 0x2CE9},
|
||||
{"dont_delete_grenades_on_next_spawn", 0x2D1E},
|
||||
{"drawfriend", 0x2DD7},
|
||||
{"droppeddeathweapon", 0x2F74},
|
||||
{"empendtime", 0x3082},
|
||||
{"entity_number", 0x3314},
|
||||
{"entityheadicons", 0x331A},
|
||||
{"finalkill", 0x373E},
|
||||
{"findboxcenter", 0x3779},
|
||||
{"flashduration", 0x38AE},
|
||||
{"flashendtime", 0x38B1},
|
||||
{"flashrumbleduration", 0x38C4},
|
||||
{"forfeitinprogress", 0x39DF},
|
||||
{"freeplayers", 0x3A2A},
|
||||
{"friendlydamage", 0x3A97},
|
||||
{"fx", 0x3B23},
|
||||
{"gameended", 0x3BDA},
|
||||
{"gameendtime", 0x3BDC},
|
||||
{"gamemodemodifyplayerdamage", 0x3BF6},
|
||||
{"gametweaks", 0x3C02},
|
||||
{"getnextobjid", 0x4041},
|
||||
{"getotherteam", 0x4067},
|
||||
{"getspawnpoint", 0x40D2},
|
||||
{"getspawnpoint_freeforall", 0x40D5},
|
||||
{"getteamspawnpoints", 0x411F},
|
||||
{"getweaponclass", 0x4167},
|
||||
{"giveloadout", 0x41E0},
|
||||
{"gotpullbacknotify", 0x428B},
|
||||
{"guid", 0x4450},
|
||||
{"gunner", 0x4473},
|
||||
{"hardcoremode", 0x46CA},
|
||||
{"hardpointtweaks", 0x46CE},
|
||||
{"hasdied", 0x4726},
|
||||
{"headmodel", 0x477D},
|
||||
{"healthoverlaycutoff", 0x478D},
|
||||
{"healthregendisabled", 0x478E},
|
||||
{"healthregenerationstreak", 0x4791},
|
||||
{"hits", 0x4926},
|
||||
{"hitsthismag", 0x4929},
|
||||
{"hostname", 0x4A3E},
|
||||
{"hud", 0x4AB3},
|
||||
{"hudtweaks", 0x4AFF},
|
||||
{"idflags", 0x4B56},
|
||||
{"idflags_no_knockback", 0x4B58},
|
||||
{"idflags_shield_explosive_impact", 0x4B5E},
|
||||
{"idflags_shield_explosive_impact_huge", 0x4B5F},
|
||||
{"idflags_shield_explosive_splash ", 0x4B60},
|
||||
{"idflags_stun", 0x4B61},
|
||||
{"idflagstime", 0x4B62},
|
||||
{"inc", 0x4C13},
|
||||
{"inframes", 0x4C67},
|
||||
{"ingraceperiod", 0x4C6D},
|
||||
{"init_animatedmodels", 0x4C77},
|
||||
{"initedentityheadicons", 0x4DB6},
|
||||
{"initializematchrules", 0x4DE0},
|
||||
{"initializetagpathvariables", 0x4DE3},
|
||||
{"initspawns", 0x4E26},
|
||||
{"inlaststand", 0x4E3C},
|
||||
{"inplayersmokescreen", 0x4E42},
|
||||
{"isactive", 0x50A6},
|
||||
{"isagent", 0x50AB},
|
||||
{"iscooked", 0x50E8},
|
||||
{"ishorde", 0x511D},
|
||||
{"iskillstreakweapon", 0x513D},
|
||||
{"isrocketcorpse", 0x5193},
|
||||
{"issniper", 0x51AB},
|
||||
{"istactical", 0x51C7},
|
||||
{"isteamspeaking", 0x51D0},
|
||||
{"joining_team", 0x528C},
|
||||
{"kill_streak", 0x533C},
|
||||
{"killcam", 0x534B},
|
||||
{"killcamlength", 0x534F},
|
||||
{"killedplayers", 0x5363},
|
||||
{"killstreakrounddelay", 0x53A2},
|
||||
{"killstreakspawnshield", 0x53A8},
|
||||
{"largeprojectiledamage", 0x54C0},
|
||||
{"lastclass", 0x5589},
|
||||
{"lastconcussedtime", 0x558B},
|
||||
{"lastkilldogtime", 0x558D},
|
||||
{"lastdamagewasfromenemy", 0x5591},
|
||||
{"lastdeathicon", 0x5592},
|
||||
{"lastdroppableweapon", 0x5598},
|
||||
{"lastflashedtime", 0x55A1},
|
||||
{"lastgrenadesuicidetime", 0x55A5},
|
||||
{"lasthittime", 0x55AB},
|
||||
{"lastkilledby", 0x55B1},
|
||||
{"lastkilltime", 0x55B6},
|
||||
{"lastprimaryweaponswaptime", 0x55CD},
|
||||
{"lastshotfiredtime", 0x55D9},
|
||||
{"laststatustime", 0x55FC},
|
||||
{"lastwave", 0x560E},
|
||||
{"leaving_team", 0x566D},
|
||||
{"lowertextfontsize", 0x58A8},
|
||||
{"lowertexty", 0x58A9},
|
||||
{"lowertextyalign", 0x58AA},
|
||||
{"plantedlethalequip", 0x5979},
|
||||
{"mapcenter", 0x5986},
|
||||
{"mapsize", 0x5990},
|
||||
{"matchbonus", 0x59DF},
|
||||
{"matchrules_damagemultiplier", 0x59E6},
|
||||
{"matchrules_vampirism", 0x59EB},
|
||||
{"maxclients", 0x5A29},
|
||||
{"maxevents", 0x5A37},
|
||||
{"maxfontscale", 0x5A39},
|
||||
{"maxkillstreaks", 0x5A3C},
|
||||
{"maxlives", 0x5A40},
|
||||
{"maxnumawardsperplayer", 0x5A41},
|
||||
{"maxlogclients", 0x5A42},
|
||||
{"maxnumchallengesperplayer", 0x5A45},
|
||||
{"maxperplayerexplosives", 0x5A4A},
|
||||
{"minedamagehalfheight", 0x5C51},
|
||||
{"minedamagemax", 0x5C53},
|
||||
{"minedamagemin", 0x5C54},
|
||||
{"minedamageradius", 0x5C56},
|
||||
{"minedetectiongraceperiod", 0x5C58},
|
||||
{"minedetectionheight", 0x5C59},
|
||||
{"minedetectionradius", 0x5C5A},
|
||||
{"mineselfdestructtime", 0x5C5F},
|
||||
{"missioncallbacks", 0x5CDC},
|
||||
{"modifyplayerdamage", 0x5D51},
|
||||
{"movespeedscaler", 0x5F7B},
|
||||
{"mp_createfx", 0x5FAC},
|
||||
{"multiteambased", 0x5FEC},
|
||||
{"objectivepointsmod", 0x6301},
|
||||
{"objectivescaler", 0x6303},
|
||||
{"objid", 0x6304},
|
||||
{"teamobjids", 0x6305},
|
||||
{"oldheadicon", 0x63D4},
|
||||
{"oldheadiconteam", 0x63D5},
|
||||
{"omaclasschanged", 0x6436},
|
||||
{"onforfeit", 0x64AF},
|
||||
{"onlinegame", 0x64B8},
|
||||
{"onnormaldeath", 0x64BF},
|
||||
{"onplayerconnectaudioinit", 0x64C9},
|
||||
{"onplayerscore", 0x64D5},
|
||||
{"onstartgametype", 0x64EC},
|
||||
{"onuse", 0x64F8},
|
||||
{"outframes", 0x65C4},
|
||||
{"participants", 0x669D},
|
||||
{"tookweaponfrom", 0x680B},
|
||||
{"placement", 0x6861},
|
||||
{"planemodel", 0x687C},
|
||||
{"playedstartingmusic", 0x6A41},
|
||||
{"player_speed", 0x6C19},
|
||||
{"playerhealth_regularregendelay", 0x6CC3},
|
||||
{"playertweaks", 0x6D74},
|
||||
{"bonusupdatetotal", 0x6E8A},
|
||||
{"primaryprogressbarfontsize", 0x6F85},
|
||||
{"primaryprogressbarheight", 0x6F86},
|
||||
{"primaryprogressbartextx", 0x6F87},
|
||||
{"primaryprogressbarwidth", 0x6F89},
|
||||
{"primaryprogressbarx", 0x6F8A},
|
||||
{"primaryprogressbary", 0x6F8B},
|
||||
{"qafinished", 0x7073},
|
||||
{"quickmessagetoall", 0x70A2},
|
||||
{"rankedmatch", 0x7137},
|
||||
{"ranktable", 0x713A},
|
||||
{"recentkillcount", 0x7260},
|
||||
{"recoilscale", 0x7268},
|
||||
{"regenspeed", 0x72D4},
|
||||
{"registerhalftimedvar", 0x72EF},
|
||||
{"registernumlivesdvar", 0x72F4},
|
||||
{"registerroundlimitdvar", 0x72F6},
|
||||
{"registerroundswitchdvar", 0x72F7},
|
||||
{"registerscorelimitdvar", 0x72F8},
|
||||
{"registertimelimitdvar", 0x72F9},
|
||||
{"registerwinlimitdvar", 0x72FE},
|
||||
{"reinitializematchrulesonmigration", 0x7307},
|
||||
{"removefromcharactersarray", 0x73A7},
|
||||
{"requiredmapaspectratio", 0x740C},
|
||||
{"reverb_settings", 0x74F1},
|
||||
{"riotshieldxpbullets", 0x7556},
|
||||
{"rules", 0x7674},
|
||||
{"scavenger_altmode", 0x785B},
|
||||
{"scavenger_secondary", 0x785C},
|
||||
{"script_accumulate", 0x792B},
|
||||
{"script_destructable_area", 0x799B},
|
||||
{"script_fxcommand", 0x79F0},
|
||||
{"script_fxid", 0x79F1},
|
||||
{"script_gametype_atdm", 0x79F5},
|
||||
{"script_gametype_ctf", 0x79F6},
|
||||
{"script_gametype_dm", 0x79F7},
|
||||
{"script_gametype_koth", 0x79F8},
|
||||
{"script_gametype_sd", 0x79FA},
|
||||
{"script_gametype_tdm", 0x79FB},
|
||||
{"script_threshold", 0x7AF4},
|
||||
{"setclass", 0x7F3B},
|
||||
{"setcommonrulesfrommatchrulesdata", 0x7F3F},
|
||||
{"setobjectivehinttext", 0x7FC3},
|
||||
{"setobjectivescoretext", 0x7FC4},
|
||||
{"setobjectivetext", 0x7FC5},
|
||||
{"setupcallbacks", 0x8301},
|
||||
{"setupminimap", 0x8324},
|
||||
{"setusetime", 0x834C},
|
||||
{"shieldbullethits", 0x84C5},
|
||||
{"shielddamage", 0x84C6},
|
||||
{"showingfinalkillcam", 0x8516},
|
||||
{"showtoteam", 0x8535},
|
||||
{"softlanding", 0x885F},
|
||||
{"softlandingtriggers", 0x8860},
|
||||
{"spamdelay", 0x88B9},
|
||||
{"spawndogtags", 0x899E},
|
||||
{"spawnmaxs", 0x89F3},
|
||||
{"spawnmins", 0x89F6},
|
||||
{"spawnpoints", 0x8A01},
|
||||
{"speakers", 0x8A19},
|
||||
{"spectateoverride", 0x8A4A},
|
||||
{"splashqueue", 0x8A6B},
|
||||
{"splitscreen", 0x8A7C},
|
||||
{"stingerlockstarttime", 0x8E48},
|
||||
{"stingerlostsightlinetime", 0x8E49},
|
||||
{"stingerstage", 0x8E59},
|
||||
{"stingertarget", 0x8E5A},
|
||||
{"stingeruseentered", 0x8E5C},
|
||||
{"stuckenemyentity", 0x8F6C},
|
||||
{"stunscaler", 0x8F77},
|
||||
{"suicides", 0x8FAF},
|
||||
{"switching_teams", 0x907E},
|
||||
{"tag_stowed_hip", 0x90D3},
|
||||
{"tagteamupdater", 0x910A},
|
||||
{"teambalance", 0x91E9},
|
||||
{"teambased", 0x91EB},
|
||||
{"teamkillsthisround", 0x91F3},
|
||||
{"teamnamelist", 0x91F7},
|
||||
{"teamprogressbarfontsize", 0x91FB},
|
||||
{"teamprogressbarheight", 0x91FC},
|
||||
{"teamprogressbartexty", 0x91FD},
|
||||
{"teamprogressbarwidth", 0x91FE},
|
||||
{"teamprogressbary", 0x91FF},
|
||||
{"teamspawnpoints", 0x9201},
|
||||
{"teamtweaks", 0x9205},
|
||||
{"throwinggrenade", 0x933E},
|
||||
{"timeplayed", 0x9372},
|
||||
{"trackingweaponname", 0x94FB},
|
||||
{"trigunderwater", 0x9822},
|
||||
{"tweakablesinitialized", 0x99E0},
|
||||
{"updateddmscores", 0x9B0F},
|
||||
{"userate", 0x9C10},
|
||||
{"usestartspawns", 0x9C14},
|
||||
{"usingremote", 0x9C34},
|
||||
{"v", 0x9C42},
|
||||
{"voice_count", 0x9D33},
|
||||
{"visuals", 0x9E9C},
|
||||
{"waitingtodeactivate", 0xA04B},
|
||||
{"wasaliveatmatchstart", 0xA1BE},
|
||||
{"waschained", 0xA1C0},
|
||||
{"wasdamaged", 0xA1C3},
|
||||
{"wasdamagedfrombulletpenetration", 0xA1C5},
|
||||
{"wasti", 0xA1D2},
|
||||
{"waswinning", 0xA1D4},
|
||||
{"waterdeletez", 0xA297},
|
||||
{"wavedelay", 0xA2AB},
|
||||
{"weaponattachments", 0xA2D3},
|
||||
{"weaponlist", 0xA2DD},
|
||||
{"weapontweaks", 0xA2F2},
|
||||
{"whizby_settings", 0xA315},
|
||||
{"scoreinfo", 0xA3A5},
|
||||
{"xpupdatetotal", 0xA3AB},
|
||||
|
||||
// additional findings from gametype/map scripts - mikey (6/26/2022)
|
||||
{"common_scripts/_fx", 0xA4FB},
|
||||
{"codescripts/character", 0xA4EF},
|
||||
{"common_scripts/_artcommon", 0xA4F0},
|
||||
{"common_scripts/_bcs_location_trigs", 0xA4F1},
|
||||
{"common_scripts/_createfx", 0xA4F2},
|
||||
{"common_scripts/_createfxmenu", 0xA4F3},
|
||||
{"common_scripts/_destructible", 0xA4F4},
|
||||
{"common_scripts/_dynamic_world", 0xA4F5},
|
||||
{"common_scripts/_elevator", 0xA4F6},
|
||||
{"common_scripts/_exploder", 0xA4F7},
|
||||
{"common_scripts/_fx", 0xA4F8},
|
||||
{"common_scripts/_pipes", 0xA4F9},
|
||||
{"common_scripts/utility", 0xA4FA},
|
||||
|
||||
{"QuickMessageToAll", 0x70a2},
|
||||
{"SetupCallbacks", 0x8301},
|
||||
{"_effect", 0x58f},
|
||||
{"_objective_delete", 0x603},
|
||||
{"addSpawnPoints", 0x82f},
|
||||
{"addStartSpawnPoints", 0x831},
|
||||
{"addToCharactersArray", 0x848},
|
||||
{"allowUse", 0xab2},
|
||||
{"applyLoadout", 0xcae}, // has applyLoadout notify like IW6's giveLoadout does at the end + similar logic
|
||||
{"characters", 0x1c8e},
|
||||
{"checkDynamicSpawns", 0x1cfa},
|
||||
{"clearOnVictimDisconnect", 0x1ef9},
|
||||
{"conf_fx", 0x20e9},
|
||||
{"console", 0x2153},
|
||||
{"createUseObject", 0x244c},
|
||||
{"curOrigin", 0x24c8},
|
||||
{"deleteObjPoint", 0x2859},
|
||||
{"dogtags", 0x2cdf},
|
||||
{"finalKill", 0x373e},
|
||||
{"findBoxCenter", 0x3779},
|
||||
{"forfeitInProgress", 0x39df},
|
||||
{"gamemodeModifyPlayerDamage", 0x3bf6},
|
||||
{"getNextObjID", 0x4041},
|
||||
{"getOtherTeam", 0x4067},
|
||||
{"getSpawnPoint", 0x40d2},
|
||||
{"getSpawnpoint_FreeForAll", 0x40d5},
|
||||
{"getTeamSpawnPoints", 0x411f},
|
||||
{"giveLoadout", 0x41e0}, // this may not even be giveLoadout but it's a wrapper for it and it does the same logic so
|
||||
{"guid", 0x4450},
|
||||
{"inGracePeriod", 0x4c6d},
|
||||
{"initSpawns", 0x4e26},
|
||||
{"initializeMatchRules", 0x4de0},
|
||||
{"initializeTagPathVariables", 0x4de3},
|
||||
{"mapCenter", 0x5986},
|
||||
{"maps/mp/_compass", 0xa731},
|
||||
{"maps/mp/_load", 0xa74c},
|
||||
{"maps/mp/_utility", 0xa764},
|
||||
{"maps/mp/_animatedmodels", 0xA72B},
|
||||
{"maps/mp/_areas", 0xA72C},
|
||||
{"maps/mp/_art", 0xA72D},
|
||||
{"maps/mp/_audio", 0xA72E},
|
||||
{"maps/mp/_awards", 0xA72F},
|
||||
{"maps/mp/_compass", 0xA731},
|
||||
{"maps/mp/_createfx", 0xA732},
|
||||
{"maps/mp/_crib", 0xA733},
|
||||
{"maps/mp/_destructables", 0xA734},
|
||||
{"maps/mp/_entityheadicons", 0xA737},
|
||||
{"maps/mp/_events", 0xA738},
|
||||
{"maps/mp/_flashgranades", 0xA747},
|
||||
{"maps/mp/_fx", 0xA748},
|
||||
{"maps/mp/_global_fx", 0xA749},
|
||||
{"maps/mp/_global_fx_code", 0xA74A},
|
||||
{"maps/mp/_load", 0xA74C},
|
||||
{"maps/mp/_matchdata", 0xA74E},
|
||||
{"maps/mp/_sun", 0xA752},
|
||||
{"maps/mp/_scope", 0xA755},
|
||||
{"maps/mp/_scoreboard", 0xA758},
|
||||
{"maps/mp/_shutter", 0xA759},
|
||||
{"maps/mp/_stinger", 0xA75B},
|
||||
{"maps/mp/_utility", 0xA764},
|
||||
{"maps/mp/_zipline", 0xA76A},
|
||||
{"maps/mp/gametypes/_battlechatter_mp", 0xA78A},
|
||||
{"maps/mp/gametypes/_class", 0xA78B},
|
||||
{"maps/mp/gametypes/_damage", 0xA78D},
|
||||
{"maps/mp/gametypes/_damagefeedback", 0xA78E},
|
||||
{"maps/mp/gametypes/_deathicons", 0xA78F},
|
||||
{"maps/mp/gametypes/_dev", 0xA790},
|
||||
{"maps/mp/gametypes/_equipment", 0xA791},
|
||||
{"maps/mp/gametypes/_friendicons", 0xA792},
|
||||
{"maps/mp/gametypes/_gamelogic", 0xA793},
|
||||
{"maps/mp/gametypes/_gameobjects", 0xA794},
|
||||
{"maps/mp/gametypes/_gamescores", 0xA795},
|
||||
{"maps/mp/gametypes/_globalentities", 0xA796},
|
||||
{"maps/mp/gametypes/_globallogic", 0xA797},
|
||||
{"maps/mp/gametypes/_menus", 0xa7a9},
|
||||
{"maps/mp/gametypes/_objpoints", 0xa7ac},
|
||||
{"maps/mp/gametypes/_spawnlogic", 0xa7b9},
|
||||
{"maps/mp/gametypes/_spawnscoring", 0xa7ba},
|
||||
{"matchRules_damageMultiplier", 0x59e6},
|
||||
{"matchRules_vampirism", 0x59eb},
|
||||
{"modifyPlayerDamage", 0x5d51},
|
||||
{"objId", 0x6304},
|
||||
{"onForfeit", 0x64af},
|
||||
{"onNormalDeath", 0x64bf},
|
||||
{"onPlayerScore", 0x64d5},
|
||||
{"onStartGameType", 0x64ec},
|
||||
{"onUse", 0x64f8},
|
||||
{"participants", 0x669d},
|
||||
{"reInitializeMatchRulesOnMigration", 0x7307},
|
||||
{"registerHalfTimeDvar", 0x72ef},
|
||||
{"registerNumLivesDvar", 0x72f4},
|
||||
{"registerRoundLimitDvar", 0x72f6},
|
||||
{"registerRoundSwitchDvar", 0x72f7},
|
||||
{"registerScoreLimitDvar", 0x72f8},
|
||||
{"registerTimeLimitDvar", 0x72f9},
|
||||
{"registerWinLimitDvar", 0x72fe},
|
||||
{"removeFromCharactersArray", 0x73a7},
|
||||
{"setClass", 0x7f3b},
|
||||
{"setCommonRulesFromMatchRulesData", 0x7f3f},
|
||||
{"setObjectiveHintText", 0x7fc3},
|
||||
{"setObjectiveScoreText", 0x7fc4},
|
||||
{"setObjectiveText", 0x7fc5},
|
||||
{"setUseTime", 0x834c},
|
||||
{"setupMiniMap", 0x8324},
|
||||
{"showToTeam", 0x8535},
|
||||
{"spawnDogTags", 0x899e},
|
||||
{"spawnMaxs", 0x89f3},
|
||||
{"spawnMins", 0x89f6},
|
||||
{"spawnPoints", 0x8a01},
|
||||
{"splitscreen", 0x8a7c},
|
||||
{"tag_stowed_hip", 0x90d3},
|
||||
{"tagTeamUpdater", 0x910a},
|
||||
{"teamBased", 0x91eb},
|
||||
{"teamNameList", 0x91f7},
|
||||
{"teamObjIds", 0x6305},
|
||||
{"teamSpawnPoints", 0x9201},
|
||||
{"v", 0x9c42},
|
||||
{"visuals", 0x9e9c},
|
||||
{"multiTeamBased", 0x5fec},
|
||||
{"maps/mp/gametypes/_hardpoints", 0xA798},
|
||||
{"maps/mp/gametypes/_healthoverlay", 0xA799},
|
||||
{"maps/mp/gametypes/_hostmigration", 0xA7A4},
|
||||
{"maps/mp/gametypes/_hud", 0xA7A5},
|
||||
{"maps/mp/gametypes/_hud_message", 0xA7A6},
|
||||
{"maps/mp/gametypes/_hud_util", 0xA7A7},
|
||||
{"maps/mp/gametypes/_killcam", 0xA7A8},
|
||||
{"maps/mp/gametypes/_menus", 0xA7A9},
|
||||
{"maos/mp/gametypes/_missions", 0xA7AA},
|
||||
{"maps/mp/gametypes/_music_and_dialog", 0xA7AB},
|
||||
{"maps/mp/gametypes/_objpoints", 0xA7AC},
|
||||
{"maps/mp/gametypes/_presistence", 0xA7AE},
|
||||
{"maps/mp/gametypes/_playerlogic", 0xA7B1},
|
||||
{"maps/mp/gametypes/_portable_radar", 0xA7B2},
|
||||
{"maps/mp/gametypes/_quickmessages", 0xA7B3},
|
||||
{"maps/mp/gametypes/_rank", 0xA7B4},
|
||||
{"maps/mp/gametypes/_portableaoegenerator", 0xA7B5},
|
||||
{"maps/mp/gametypes/_serversettings", 0xA7B6},
|
||||
{"maps/mp/gametypes/_shellshock", 0xA7B7},
|
||||
{"maps/mp/gametypes/_spawnlogic", 0xA7B9},
|
||||
{"maps/mp/gametypes/_spawnscoring", 0xA7BA},
|
||||
{"maps/mp/gametypes/_spectating", 0xA7BB},
|
||||
{"maps/mp/gametypes/_teams", 0xA7BC},
|
||||
{"maps/mp/gametypes/_tweakables", 0xA7BD},
|
||||
{"maps/mp/gametypes/_weapons", 0xA7BE},
|
||||
{"maps/mp/gametypes/_perkfunctions", 0xA7E5},
|
||||
{"maps/mp/gametypes/_perks", 0xA7E6},
|
||||
};
|
||||
}
|
||||
|
@ -10,14 +10,31 @@
|
||||
#include "../../../component/logfile.hpp"
|
||||
#include "../../../component/scripting.hpp"
|
||||
#include "../../../component/fastfiles.hpp"
|
||||
#include "../../../component/scheduler.hpp"
|
||||
|
||||
#include <utils/string.hpp>
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/http.hpp>
|
||||
|
||||
namespace scripting::lua
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct http_request
|
||||
{
|
||||
sol::protected_function on_error;
|
||||
sol::protected_function on_progress;
|
||||
sol::protected_function on_load;
|
||||
};
|
||||
|
||||
std::unordered_map<uint64_t, http_request> http_requests;
|
||||
|
||||
std::string get_as_string(const sol::this_state s, sol::object o)
|
||||
{
|
||||
sol::state_view state(s);
|
||||
return state["tostring"](o);
|
||||
}
|
||||
|
||||
vector normalize_vector(const vector& vec)
|
||||
{
|
||||
const auto length = sqrt(
|
||||
@ -567,6 +584,162 @@ namespace scripting::lua
|
||||
return sol::lua_value{s, sol::lua_nil};
|
||||
}
|
||||
};
|
||||
|
||||
static uint64_t task_id = 0;
|
||||
|
||||
state["http"] = sol::table::create(state.lua_state());
|
||||
|
||||
state["http"]["get"] = [](const sol::this_state, const std::string& url,
|
||||
const sol::protected_function& callback, sol::variadic_args va)
|
||||
{
|
||||
bool async = false;
|
||||
|
||||
if (va.size() >= 1 && va[0].get_type() == sol::type::boolean)
|
||||
{
|
||||
async = va[0].as<bool>();
|
||||
}
|
||||
|
||||
const auto cur_task_id = task_id++;
|
||||
auto request_callbacks = &http_requests[cur_task_id];
|
||||
request_callbacks->on_load = callback;
|
||||
|
||||
::scheduler::once([url, cur_task_id]()
|
||||
{
|
||||
if (http_requests.find(cur_task_id) == http_requests.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto data = utils::http::get_data(url);
|
||||
::scheduler::once([data, cur_task_id]()
|
||||
{
|
||||
if (http_requests.find(cur_task_id) == http_requests.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& request_callbacks_ = http_requests[cur_task_id];
|
||||
const auto has_value = data.has_value();
|
||||
handle_error(request_callbacks_.on_load(has_value ? data.value().buffer : "", has_value));
|
||||
http_requests.erase(cur_task_id);
|
||||
}, ::scheduler::pipeline::server);
|
||||
}, ::scheduler::pipeline::async);
|
||||
};
|
||||
|
||||
state["http"]["request"] = [](const sol::this_state s, const std::string& url, sol::variadic_args va)
|
||||
{
|
||||
auto request = sol::table::create(s.lua_state());
|
||||
|
||||
std::string buffer{};
|
||||
std::string fields_string{};
|
||||
std::unordered_map<std::string, std::string> headers_map;
|
||||
|
||||
if (va.size() >= 1 && va[0].get_type() == sol::type::table)
|
||||
{
|
||||
const auto options = va[0].as<sol::table>();
|
||||
|
||||
const auto fields = options["parameters"];
|
||||
const auto body = options["body"];
|
||||
const auto headers = options["headers"];
|
||||
|
||||
if (fields.get_type() == sol::type::table)
|
||||
{
|
||||
const auto _fields = fields.get<sol::table>();
|
||||
|
||||
for (const auto& field : _fields)
|
||||
{
|
||||
const auto key = field.first.as<std::string>();
|
||||
const auto value = get_as_string(s, field.second);
|
||||
|
||||
fields_string += key + "=" + value + "&";
|
||||
}
|
||||
}
|
||||
|
||||
if (body.get_type() == sol::type::string)
|
||||
{
|
||||
fields_string = body.get<std::string>();
|
||||
}
|
||||
|
||||
if (headers.get_type() == sol::type::table)
|
||||
{
|
||||
const auto _headers = headers.get<sol::table>();
|
||||
|
||||
for (const auto& header : _headers)
|
||||
{
|
||||
const auto key = header.first.as<std::string>();
|
||||
const auto value = get_as_string(s, header.second);
|
||||
|
||||
headers_map[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
request["onerror"] = []() {};
|
||||
request["onprogress"] = []() {};
|
||||
request["onload"] = []() {};
|
||||
|
||||
request["send"] = [url, fields_string, request, headers_map]()
|
||||
{
|
||||
const auto cur_task_id = task_id++;
|
||||
auto request_callbacks = &http_requests[cur_task_id];
|
||||
request_callbacks->on_error = request["onerror"];
|
||||
request_callbacks->on_progress = request["onprogress"];
|
||||
request_callbacks->on_load = request["onload"];
|
||||
|
||||
::scheduler::once([url, fields_string, cur_task_id, headers_map]()
|
||||
{
|
||||
if (http_requests.find(cur_task_id) == http_requests.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = utils::http::get_data(url, fields_string, headers_map, [cur_task_id](size_t value)
|
||||
{
|
||||
::scheduler::once([cur_task_id, value]()
|
||||
{
|
||||
if (http_requests.find(cur_task_id) == http_requests.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& request_callbacks_ = http_requests[cur_task_id];
|
||||
handle_error(request_callbacks_.on_progress(value));
|
||||
}, ::scheduler::pipeline::server);
|
||||
});
|
||||
|
||||
::scheduler::once([cur_task_id, result]()
|
||||
{
|
||||
if (http_requests.find(cur_task_id) == http_requests.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& request_callbacks_ = http_requests[cur_task_id];
|
||||
|
||||
if (!result.has_value())
|
||||
{
|
||||
request_callbacks_.on_error("Unknown", -1);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& http_result = result.value();
|
||||
|
||||
if (http_result.code == CURLE_OK)
|
||||
{
|
||||
handle_error(request_callbacks_.on_load(http_result.buffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_error(request_callbacks_.on_error(curl_easy_strerror(http_result.code), http_result.code));
|
||||
}
|
||||
|
||||
http_requests.erase(cur_task_id);
|
||||
}, ::scheduler::pipeline::server);
|
||||
}, ::scheduler::pipeline::async);
|
||||
};
|
||||
|
||||
return request;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "script_value.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "array.hpp"
|
||||
#include "functions.hpp"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
@ -290,4 +291,39 @@ namespace scripting
|
||||
{
|
||||
return this->value_.get();
|
||||
}
|
||||
|
||||
std::string script_value::to_string() const
|
||||
{
|
||||
if (this->is<int>())
|
||||
{
|
||||
return utils::string::va("%i", this->as<int>());
|
||||
}
|
||||
|
||||
if (this->is<float>())
|
||||
{
|
||||
return utils::string::va("%f", this->as<float>());
|
||||
}
|
||||
|
||||
if (this->is<std::string>())
|
||||
{
|
||||
return this->as<std::string>();
|
||||
}
|
||||
|
||||
if (this->is<vector>())
|
||||
{
|
||||
const auto vec = this->as<vector>();
|
||||
return utils::string::va("(%g, %g, %g)",
|
||||
vec.get_x(),
|
||||
vec.get_y(),
|
||||
vec.get_z()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->is<std::function<void()>>())
|
||||
{
|
||||
return utils::string::va("[[ function ]]");
|
||||
}
|
||||
|
||||
return this->type_name();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "variable_value.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
#include <utils/string.hpp>
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
class entity;
|
||||
@ -32,6 +34,14 @@ namespace scripting
|
||||
template <typename T>
|
||||
bool is() const;
|
||||
|
||||
// was gonna do this but no clue if this is the same on H1 so just return string (https://github.com/fedddddd/t6-gsc-utils/blob/main/src/game/scripting/script_value.hpp#L18)
|
||||
std::string type_name() const
|
||||
{
|
||||
return utils::string::va("%s", this->get_raw().type);
|
||||
}
|
||||
|
||||
std::string to_string() const;
|
||||
|
||||
template <typename T>
|
||||
T as() const
|
||||
{
|
||||
|
@ -1519,16 +1519,39 @@ namespace game
|
||||
int usesDelta;
|
||||
};
|
||||
|
||||
enum sessionState_t
|
||||
{
|
||||
SESS_STATE_PLAYING = 0x0,
|
||||
SESS_STATE_DEAD = 0x1,
|
||||
SESS_STATE_SPECTATOR = 0x2,
|
||||
SESS_STATE_INTERMISSION = 0x3,
|
||||
};
|
||||
|
||||
enum team_t
|
||||
{
|
||||
TEAM_FREE = 0x0,
|
||||
TEAM_BAD = 0x0,
|
||||
TEAM_AXIS = 0x1,
|
||||
TEAM_ALLIES = 0x2,
|
||||
TEAM_SPECTATOR = 0x3,
|
||||
TEAM_NUM_TEAMS = 0x4,
|
||||
};
|
||||
|
||||
struct gclient_s
|
||||
{
|
||||
char __pad0[2];
|
||||
char pm_type; // 2
|
||||
char __pad1[18831];
|
||||
char __pad1[18573];
|
||||
sessionState_t sessionState;
|
||||
char __pad2[220]; // 254
|
||||
team_t team;
|
||||
char __pad3[30];
|
||||
char name[32]; // 18834
|
||||
char __pad2[622];
|
||||
char __pad4[622];
|
||||
int flags; // 19488
|
||||
}; // size = ?
|
||||
|
||||
static_assert(offsetof(gclient_s, team) == 18800);
|
||||
static_assert(offsetof(gclient_s, name) == 18834);
|
||||
static_assert(offsetof(gclient_s, flags) == 19488);
|
||||
|
||||
@ -1542,7 +1565,7 @@ namespace game
|
||||
|
||||
struct EntityState
|
||||
{
|
||||
uint16_t entityNum;
|
||||
uint16_t number;
|
||||
}; // size = ?
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -147,6 +147,24 @@ LUI.addmenubutton = function(name, data)
|
||||
end)
|
||||
end
|
||||
|
||||
LUI.removemenubutton = function(name, index)
|
||||
LUI.onmenuopen(name, function(menu)
|
||||
if (not menu.list) then
|
||||
return
|
||||
end
|
||||
|
||||
local buttonlist = menu:getChildById(menu.type .. "_list")
|
||||
local button = buttonlist.childRecord[string.format("%s_button_%s", name, index)]
|
||||
buttonlist:removeElement(button)
|
||||
|
||||
local hintbox = menu.optionTextInfo
|
||||
menu:removeElement(hintbox)
|
||||
|
||||
LUI.Options.InitScrollingList(menu.list, nil)
|
||||
menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu)
|
||||
end)
|
||||
end
|
||||
|
||||
LUI.openmenu = function(menu, args)
|
||||
stack = args
|
||||
LUI.FlowManager.RequestAddMenu(nil, menu)
|
||||
|
@ -21,7 +21,8 @@ namespace utils::flags
|
||||
if (wide_flag[0] == L'-')
|
||||
{
|
||||
wide_flag.erase(wide_flag.begin());
|
||||
flags.emplace_back(string::convert(wide_flag));
|
||||
const auto flag = string::convert(wide_flag);
|
||||
flags.emplace_back(string::to_lower(flag));
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,14 +41,7 @@ namespace utils::flags
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
for (const auto& entry : enabled_flags)
|
||||
{
|
||||
if (string::to_lower(entry) == string::to_lower(flag))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return std::ranges::any_of(enabled_flags.cbegin(), enabled_flags.cend(),
|
||||
[flag](const auto& elem) { return elem == string::to_lower(flag); });
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,32 @@ namespace utils::http
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct progress_helper
|
||||
{
|
||||
const std::function<void(size_t)>* callback{};
|
||||
std::exception_ptr exception{};
|
||||
};
|
||||
|
||||
int progress_callback(void* clientp, const curl_off_t /*dltotal*/, const curl_off_t dlnow, const curl_off_t /*ultotal*/, const curl_off_t /*ulnow*/)
|
||||
{
|
||||
auto* helper = static_cast<progress_helper*>(clientp);
|
||||
|
||||
try
|
||||
{
|
||||
if (*helper->callback)
|
||||
{
|
||||
(*helper->callback)(dlnow);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
helper->exception = std::current_exception();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t write_callback(void* contents, const size_t size, const size_t nmemb, void* userp)
|
||||
{
|
||||
auto* buffer = static_cast<std::string*>(userp);
|
||||
@ -16,7 +42,8 @@ namespace utils::http
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<result> get_data(const std::string& url)
|
||||
std::optional<result> get_data(const std::string& url, const std::string& fields,
|
||||
const headers& headers, const std::function<void(size_t)>& callback)
|
||||
{
|
||||
curl_slist* header_list = nullptr;
|
||||
auto* curl = curl_easy_init();
|
||||
@ -31,13 +58,28 @@ namespace utils::http
|
||||
curl_easy_cleanup(curl);
|
||||
});
|
||||
|
||||
for (const auto& header : headers)
|
||||
{
|
||||
auto data = header.first + ": " + header.second;
|
||||
header_list = curl_slist_append(header_list, data.data());
|
||||
}
|
||||
|
||||
std::string buffer{};
|
||||
progress_helper helper{};
|
||||
helper.callback = &callback;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.data());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &helper);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
|
||||
|
||||
if (!fields.empty())
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields.data());
|
||||
}
|
||||
|
||||
const auto code = curl_easy_perform(curl);
|
||||
|
||||
@ -49,20 +91,24 @@ namespace utils::http
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
result result;
|
||||
result.code = code;
|
||||
|
||||
return result;
|
||||
if (helper.exception)
|
||||
{
|
||||
std::rethrow_exception(helper.exception);
|
||||
}
|
||||
|
||||
result result;
|
||||
result.code = code;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::future<std::optional<result>> get_data_async(const std::string& url)
|
||||
std::future<std::optional<result>> get_data_async(const std::string& url, const std::string& fields,
|
||||
const headers& headers, const std::function<void(size_t)>& callback)
|
||||
{
|
||||
return std::async(std::launch::async, [url]()
|
||||
return std::async(std::launch::async, [url, fields, headers, callback]()
|
||||
{
|
||||
return get_data(url);
|
||||
return get_data(url, fields, headers, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,14 @@ namespace utils::http
|
||||
{
|
||||
struct result
|
||||
{
|
||||
CURLcode code;
|
||||
std::string buffer;
|
||||
CURLcode code{};
|
||||
std::string buffer{};
|
||||
};
|
||||
|
||||
std::optional<result> get_data(const std::string& url);
|
||||
std::future<std::optional<result>> get_data_async(const std::string& url);
|
||||
using headers = std::unordered_map<std::string, std::string>;
|
||||
|
||||
std::optional<result> get_data(const std::string& url, const std::string& fields = {},
|
||||
const headers& headers = {}, const std::function<void(size_t)>& callback = {});
|
||||
std::future<std::optional<result>> get_data_async(const std::string& url, const std::string& fields = {},
|
||||
const headers& headers = {}, const std::function<void(size_t)>& callback = {});
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace utils
|
||||
return value->second;
|
||||
}
|
||||
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
void info_string::parse(std::string buffer)
|
||||
@ -49,15 +49,15 @@ namespace utils
|
||||
{
|
||||
//auto first = true;
|
||||
std::string info_string;
|
||||
for (auto i = this->key_value_pairs_.begin(); i != this->key_value_pairs_.end(); ++i)
|
||||
for (const auto& [key, val] : this->key_value_pairs_)
|
||||
{
|
||||
//if (first) first = false;
|
||||
/*else*/
|
||||
info_string.append("\\");
|
||||
|
||||
info_string.append(i->first); // Key
|
||||
info_string.append(key);
|
||||
info_string.append("\\");
|
||||
info_string.append(i->second); // Value
|
||||
info_string.append(val);
|
||||
}
|
||||
|
||||
return info_string;
|
||||
|
@ -32,7 +32,7 @@ namespace utils::io
|
||||
|
||||
if (stream.is_open())
|
||||
{
|
||||
stream.write(data.data(), data.size());
|
||||
stream.write(data.data(), static_cast<std::streamsize>(data.size()));
|
||||
stream.close();
|
||||
return true;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ namespace utils
|
||||
|
||||
void* memory::allocate(const size_t length)
|
||||
{
|
||||
return calloc(length, 1);
|
||||
return std::calloc(length, 1);
|
||||
}
|
||||
|
||||
char* memory::duplicate_string(const std::string& string)
|
||||
@ -86,7 +86,7 @@ namespace utils
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
::free(data);
|
||||
std::free(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
tools/protoc.exe
BIN
tools/protoc.exe
Binary file not shown.
Loading…
Reference in New Issue
Block a user