2981 lines
99 KiB
C++
2981 lines
99 KiB
C++
![]() |
// netScriptMgrBase.cpp
|
||
|
//
|
||
|
// Copyright (C) 1999-2009 Rockstar Games. All Rights Reserved.
|
||
|
//
|
||
|
|
||
|
#include "script/handlers/GameScriptMgr.h"
|
||
|
|
||
|
// rage includes
|
||
|
#include "bank/bank.h"
|
||
|
#include "grcore/debugdraw.h"
|
||
|
#include "fwsys/timer.h"
|
||
|
#include "fwscript/scriptguid.h"
|
||
|
|
||
|
// game includes
|
||
|
#include "modelinfo/PedModelInfo.h"
|
||
|
#include "modelinfo/VehicleModelInfo.h"
|
||
|
#include "network/Arrays/NetworkArrayMgr.h"
|
||
|
#include "network/Bandwidth/NetworkBandwidthManager.h"
|
||
|
#include "network/Events/NetworkEventTypes.h"
|
||
|
#include "network/NetworkInterface.h"
|
||
|
#include "network/Network.h"
|
||
|
#include "network/Objects/NetworkObjectMgr.h"
|
||
|
#include "network/Players/NetGamePlayer.h"
|
||
|
#include "network/Sessions/NetworkSession.h"
|
||
|
#include "peds/ped.h"
|
||
|
#include "peds/PlayerInfo.h"
|
||
|
#include "scene/streamer/StreamVolume.h"
|
||
|
#include "scene/world/GameWorld.h"
|
||
|
#include "script/handlers/GameScriptEntity.h"
|
||
|
#include "script/handlers/GameScriptHandler.h"
|
||
|
#include "script/handlers/GameScriptHandlerNetwork.h"
|
||
|
#include "script/handlers/GameScriptResources.h"
|
||
|
#include "script/gta_thread.h"
|
||
|
#include "script/script.h"
|
||
|
#include "script/script_channel.h"
|
||
|
#include "script/streamedscripts.h"
|
||
|
#include "streaming/populationstreaming.h"
|
||
|
#include "streaming/streamingdebug.h"
|
||
|
#include "streaming/streamingengine.h"
|
||
|
#include "streaming/streaminginfo.h"
|
||
|
#include "vfx/misc/MovieManager.h"
|
||
|
#include "Event/EventGroup.h"
|
||
|
|
||
|
#if __DEV
|
||
|
#include "network/NetworkInterface.h"
|
||
|
#include "network/objects/NetworkObjectMgr.h"
|
||
|
#include "network/Players/NetworkPlayerMgr.h"
|
||
|
#include "rline/rlgamerinfo.h"
|
||
|
#endif
|
||
|
|
||
|
SCRIPT_OPTIMISATIONS()
|
||
|
NETWORK_OPTIMISATIONS()
|
||
|
|
||
|
XPARAM(override_script);
|
||
|
XPARAM(dontCrashOnScriptValidation);
|
||
|
|
||
|
PARAM(scriptLogMemoryPeaks, "[MEMORY] Log the memory peaks for the scripts physical and virtual usage.");
|
||
|
|
||
|
#if __BANK
|
||
|
bkCombo* CGameScriptHandlerMgr::ms_pHandlerCombo = NULL;
|
||
|
const char* CGameScriptHandlerMgr::ms_Handlers[CGameScriptHandler::MAX_NUM_SCRIPT_HANDLERS];
|
||
|
unsigned int CGameScriptHandlerMgr::ms_NumHandlers = 0;
|
||
|
int CGameScriptHandlerMgr::ms_HandlerComboIndex = 0;
|
||
|
bool CGameScriptHandlerMgr::ms_DisplayHandlerInfo = false;
|
||
|
bool CGameScriptHandlerMgr::ms_DisplayAllMPHandlers = false;
|
||
|
#endif // __BANK
|
||
|
|
||
|
u32 CGameScriptHandlerMgr::ms_validNetworkScriptHashes[] =
|
||
|
{
|
||
|
ATSTRINGHASH("act_cinema", 0x8961d933),
|
||
|
ATSTRINGHASH("activity_creator_prototype_launcher", 0x4fb9c566),
|
||
|
ATSTRINGHASH("am_agency_suv", 0x12117cf0),
|
||
|
ATSTRINGHASH("am_airstrike", 0x060cd733),
|
||
|
ATSTRINGHASH("am_ammo_drop", 0xa7c6571d),
|
||
|
ATSTRINGHASH("am_armwrestling", 0x3c77f4aa),
|
||
|
ATSTRINGHASH("am_armwrestling_apartment", 0x69bdb2d8),
|
||
|
ATSTRINGHASH("am_armybase", 0x4efb7452),
|
||
|
ATSTRINGHASH("am_backup_heli", 0xddb3aada),
|
||
|
ATSTRINGHASH("am_beach_washup_cinematic", 0xE720B4A4),
|
||
|
ATSTRINGHASH("am_boat_taxi", 0xd8133249),
|
||
|
ATSTRINGHASH("am_bru_box", 0x48600c01),
|
||
|
ATSTRINGHASH("am_car_mod_tut", 0x83a66932),
|
||
|
ATSTRINGHASH("am_casino_limo", 0x3A5BBA05),
|
||
|
ATSTRINGHASH("am_casino_luxury_car", 0xb93135a6),
|
||
|
ATSTRINGHASH("am_casino_peds", 0x1C0F96E7),
|
||
|
ATSTRINGHASH("am_challenges", 0x59de0357),
|
||
|
ATSTRINGHASH("am_cp_collection", 0x0544b90b),
|
||
|
ATSTRINGHASH("am_crate_drop", 0x240f2e7b),
|
||
|
ATSTRINGHASH("am_criminal_damage", 0xc62526f5),
|
||
|
ATSTRINGHASH("am_darts", 0x2a10cf0c),
|
||
|
ATSTRINGHASH("am_darts_apartment", 0xab14f1f2),
|
||
|
ATSTRINGHASH("am_dead_drop", 0x9497de5d),
|
||
|
ATSTRINGHASH("am_destroy_veh", 0xeab28126),
|
||
|
ATSTRINGHASH("am_distract_cops", 0x81dc676e),
|
||
|
ATSTRINGHASH("am_doors", 0xc80b3112),
|
||
|
ATSTRINGHASH("am_ferriswheel", 0xe4e0cbce),
|
||
|
ATSTRINGHASH("am_ga_pickups", 0xa77e5305),
|
||
|
ATSTRINGHASH("am_gang_call", 0x0266ce78),
|
||
|
ATSTRINGHASH("am_heist_int", 0xc74cc971),
|
||
|
ATSTRINGHASH("am_heist_island_plane_land_cinematic", 0x560E198),
|
||
|
ATSTRINGHASH("am_heist_island_plane_take_off_cinematic", 0x1984610C),
|
||
|
ATSTRINGHASH("am_heli_taxi", 0x4840fef0),
|
||
|
ATSTRINGHASH("am_hi_plane_take_off_cinematic", 0x418795CC),
|
||
|
ATSTRINGHASH("am_hi_plane_land_cinematic", 0x9782808A),
|
||
|
ATSTRINGHASH("am_hold_up", 0x0c6dac46),
|
||
|
ATSTRINGHASH("am_hot_property", 0x95335193),
|
||
|
ATSTRINGHASH("am_hot_target", 0x3c04751e),
|
||
|
ATSTRINGHASH("am_hs4_isd_take_vel", 0x9B9330A1),
|
||
|
ATSTRINGHASH("am_hs4_lsa_land_nimb_arrive",0x2941F161),
|
||
|
ATSTRINGHASH("am_hs4_lsa_land_vel", 0xC288DE3E),
|
||
|
ATSTRINGHASH("am_hs4_lsa_take_vel", 0x7BD40072),
|
||
|
ATSTRINGHASH("am_hs4_nimb_isd_lsa_leave", 0x85398B65),
|
||
|
ATSTRINGHASH("am_hs4_nimb_lsa_isd_leave", 0xC2F73739),
|
||
|
ATSTRINGHASH("am_hs4_nimb_lsa_isd_arrive", 0x39DB7A9C),
|
||
|
ATSTRINGHASH("am_hs4_vel_lsa_isd", 0x1FF4E6A9),
|
||
|
ATSTRINGHASH("am_hunt_the_beast", 0x7e76f859),
|
||
|
ATSTRINGHASH("am_lsia_land_cinematic", 0xAEA5F533),
|
||
|
ATSTRINGHASH("am_imp_exp", 0x1961b859),
|
||
|
ATSTRINGHASH("am_island_backup_heli", 0x68867AF7),
|
||
|
ATSTRINGHASH("am_joyrider", 0xe1bc7b99),
|
||
|
ATSTRINGHASH("am_kill_list", 0xa8d5e84c),
|
||
|
ATSTRINGHASH("am_king_of_the_castle", 0x7a9a3349),
|
||
|
ATSTRINGHASH("am_launcher", 0x57c919e1),
|
||
|
ATSTRINGHASH("am_lester_cut", 0x1edd4ad1),
|
||
|
ATSTRINGHASH("am_lowrider_int", 0x4250943e),
|
||
|
ATSTRINGHASH("am_lsia_take_off_cinematic", 0x849DBDF1),
|
||
|
ATSTRINGHASH("am_luxury_showroom", 0xf4ab6fb5),
|
||
|
ATSTRINGHASH("am_mission_launch", 0x8fa27332),
|
||
|
ATSTRINGHASH("am_mp_acid_lab", 0x480e7a1a),
|
||
|
ATSTRINGHASH("am_mp_arc_cab_manager", 0x4ee41f75),
|
||
|
ATSTRINGHASH("am_mp_arcade", 0x500b732f),
|
||
|
ATSTRINGHASH("am_mp_arcade_love_meter", 0x39245013),
|
||
|
ATSTRINGHASH("am_mp_arcade_strength_test", 0x7488fe33),
|
||
|
ATSTRINGHASH("am_mp_arcade_fortune_teller", 0xf4c6d398),
|
||
|
ATSTRINGHASH("am_mp_arcade_claw_crane", 0xa54f9693),
|
||
|
ATSTRINGHASH("am_mp_arena_box", 0x8C9C5FB8),
|
||
|
ATSTRINGHASH("am_mp_arena_garage", 0x26EBCE20),
|
||
|
ATSTRINGHASH("am_mp_armory_aircraft", 0x9c6f5716),
|
||
|
ATSTRINGHASH("am_mp_armory_truck", 0x5b9b0272),
|
||
|
ATSTRINGHASH("am_mp_auto_shop", 0xba18b4c),
|
||
|
ATSTRINGHASH("am_mp_biker_warehouse", 0x504ebb57),
|
||
|
ATSTRINGHASH("am_mp_boardroom_seating", 0x70fc43a2),
|
||
|
ATSTRINGHASH("am_mp_bunker", 0x89d486f8),
|
||
|
ATSTRINGHASH("am_mp_business_hub", 0xC85B5BEF),
|
||
|
ATSTRINGHASH("am_mp_car_meet_property", 0x2385bdc4),
|
||
|
ATSTRINGHASH("am_mp_car_meet_sandbox", 0x5158A9E4),
|
||
|
ATSTRINGHASH("am_mp_casino", 0x7166BD4A),
|
||
|
ATSTRINGHASH("am_mp_casino_apartment", 0xD76D873D),
|
||
|
ATSTRINGHASH("am_mp_casino_dj_room", 0x12daa5f1),
|
||
|
ATSTRINGHASH("am_mp_casino_nightclub", 0x700869D),
|
||
|
ATSTRINGHASH("am_mp_casino_valet_garage", 0x6cc29c20),
|
||
|
ATSTRINGHASH("am_mp_creator_aircraft", 0xd4dddde0),
|
||
|
ATSTRINGHASH("am_mp_creator_trailer", 0xcbd05bfb),
|
||
|
ATSTRINGHASH("am_mp_defunct_base", 0xcab8a943),
|
||
|
ATSTRINGHASH("am_mp_dj", 0xb369e47f),
|
||
|
ATSTRINGHASH("am_mp_drone", 0x230D1E0D),
|
||
|
ATSTRINGHASH("am_mp_fixer_hq", 0x995f4ea5),
|
||
|
ATSTRINGHASH("am_mp_garage_control", 0xfd4b7439),
|
||
|
ATSTRINGHASH("am_mp_hacker_truck", 0x349B7463),
|
||
|
ATSTRINGHASH("am_mp_hangar", 0xefc0d4ec),
|
||
|
ATSTRINGHASH("am_mp_ie_warehouse", 0xb7a8f8db),
|
||
|
ATSTRINGHASH("am_mp_island", 0x1C2A2AF8),
|
||
|
ATSTRINGHASH("am_mp_juggalo_hideout", 0xedfd243e),
|
||
|
ATSTRINGHASH("am_mp_multistorey_garage", 0x679a06a1),
|
||
|
ATSTRINGHASH("am_mp_music_studio", 0xfd3397ae),
|
||
|
ATSTRINGHASH("am_mp_mission", 0x626b9c51),
|
||
|
ATSTRINGHASH("am_mp_nightclub", 0x8C56B7FE),
|
||
|
ATSTRINGHASH("am_mp_orbital_cannon", 0x6c25dccb),
|
||
|
ATSTRINGHASH("am_mp_peds", 0xBC350B6D),
|
||
|
ATSTRINGHASH("am_mp_property_ext", 0x72ee09f2),
|
||
|
ATSTRINGHASH("am_mp_property_int", 0x95b61b3c),
|
||
|
ATSTRINGHASH("am_mp_rc_vehicle", 0xd1894172),
|
||
|
ATSTRINGHASH("am_mp_shooting_range", 0xaa3368fc),
|
||
|
ATSTRINGHASH("am_mp_simeon_showroom", 0x1ed5a03d),
|
||
|
ATSTRINGHASH("am_mp_smoking_activity", 0x121a26b9),
|
||
|
ATSTRINGHASH("am_mp_smpl_interior_ext", 0xe0a7b7ad),
|
||
|
ATSTRINGHASH("am_mp_smpl_interior_int", 0x05973129),
|
||
|
ATSTRINGHASH("am_mp_solomon_office", 0x220A2BF3),
|
||
|
ATSTRINGHASH("am_mp_submarine", 0xE16957F2),
|
||
|
ATSTRINGHASH("am_mp_vehicle_reward", 0x692F8E30),
|
||
|
ATSTRINGHASH("am_mp_vehicle_weapon", 0x322bad51),
|
||
|
ATSTRINGHASH("am_mp_warehouse", 0x2262ddf0),
|
||
|
ATSTRINGHASH("am_mp_yacht", 0xc930c939),
|
||
|
ATSTRINGHASH("am_npc_invites", 0x529d545f),
|
||
|
ATSTRINGHASH("am_pass_the_parcel", 0x8dd957aa),
|
||
|
ATSTRINGHASH("am_patrick", 0xb70b6f22),
|
||
|
ATSTRINGHASH("am_penned_in", 0x9fd87720),
|
||
|
ATSTRINGHASH("am_penthouse_peds", 0x5c0238a9),
|
||
|
ATSTRINGHASH("am_plane_takedown", 0x990a9196),
|
||
|
ATSTRINGHASH("am_prison", 0x70da15b8),
|
||
|
ATSTRINGHASH("am_prostitute", 0x62773681),
|
||
|
ATSTRINGHASH("am_rollercoaster", 0xa8f75ae1),
|
||
|
ATSTRINGHASH("am_rontrevor_cut", 0xe895e13e),
|
||
|
ATSTRINGHASH("am_taxi", 0x455fe4de),
|
||
|
ATSTRINGHASH("am_vehicle_spawn", 0xb726fc82),
|
||
|
ATSTRINGHASH("apartment_minigame_launcher", 0xc4382362),
|
||
|
ATSTRINGHASH("arcade_seating", 0xA0B1239B),
|
||
|
ATSTRINGHASH("arena_box_bench_seats", 0x63905267),
|
||
|
ATSTRINGHASH("arena_carmod", 0xdafc0911),
|
||
|
ATSTRINGHASH("arena_workshop_seats", 0x7030f53f),
|
||
|
ATSTRINGHASH("armory_aircraft_carmod", 0x78ddb08f),
|
||
|
ATSTRINGHASH("atm_trigger", 0x1ab4168d),
|
||
|
ATSTRINGHASH("auto_shop_seating", 0x7A4A46AE),
|
||
|
ATSTRINGHASH("base_carmod", 0x00e813dd),
|
||
|
ATSTRINGHASH("base_corridor_seats", 0x16833adb),
|
||
|
ATSTRINGHASH("base_entrance_seats", 0x8d055fe8),
|
||
|
ATSTRINGHASH("base_heist_seats", 0xc5c0aa16),
|
||
|
ATSTRINGHASH("base_lounge_seats", 0xddf302ec),
|
||
|
ATSTRINGHASH("base_quaters_seats", 0x01aa9982),
|
||
|
ATSTRINGHASH("base_reception_seats", 0x6b938b1b),
|
||
|
ATSTRINGHASH("beach_exterior_seating", 0x3DE90B7C),
|
||
|
ATSTRINGHASH("blackjack", 0xD378365E),
|
||
|
ATSTRINGHASH("business_battles", 0xA6526FA9),
|
||
|
ATSTRINGHASH("business_battles_defend", 0x6FA239A5),
|
||
|
ATSTRINGHASH("business_battles_sell", 0xF3F871DA),
|
||
|
ATSTRINGHASH("business_hub_carmod", 0x6E6F052),
|
||
|
ATSTRINGHASH("business_hub_garage_seats", 0x7d5dee96),
|
||
|
ATSTRINGHASH("camhedz_arcade", 0xE81212C6),
|
||
|
ATSTRINGHASH("car_meet_carmod", 0xBB3D7E9D),
|
||
|
ATSTRINGHASH("car_meet_exterior_seating", 0x581858D7),
|
||
|
ATSTRINGHASH("car_meet_interior_seating", 0xAEC3C263),
|
||
|
ATSTRINGHASH("carmod_shop", 0x1dc6b680),
|
||
|
ATSTRINGHASH("cashisking", 0xaa69fdd3),
|
||
|
ATSTRINGHASH("casino_bar_seating", 0x6e6fc95f),
|
||
|
ATSTRINGHASH("casino_exterior_seating", 0x38C0DADF),
|
||
|
ATSTRINGHASH("casino_interior_seating", 0xc2c12122),
|
||
|
ATSTRINGHASH("casino_lucky_wheel", 0xbdf0ccff),
|
||
|
ATSTRINGHASH("casino_main_lounge_seating", 0x3339c03a),
|
||
|
ATSTRINGHASH("casino_nightclub_seating", 0xF8881E62),
|
||
|
ATSTRINGHASH("casino_penthouse_seating", 0x5a1b8571),
|
||
|
ATSTRINGHASH("casino_slots", 0x5f1459d7),
|
||
|
ATSTRINGHASH("casinoroulette", 0x05e86d0d),
|
||
|
ATSTRINGHASH("clothes_shop_mp", 0xc0f0bbc3),
|
||
|
ATSTRINGHASH("copscrooks_holdup_instance", 0x70871f89),
|
||
|
ATSTRINGHASH("copscrooks_job_instance", 0xF28DD9D9),
|
||
|
ATSTRINGHASH("dont_cross_the_line", 0x85db1b5a),
|
||
|
ATSTRINGHASH("endlesswinter", 0xe237f748),
|
||
|
ATSTRINGHASH("fixer_hq_carmod", 0x41f74a04),
|
||
|
ATSTRINGHASH("fixer_hq_seating", 0x1a207399),
|
||
|
ATSTRINGHASH("fixer_hq_seating_op_floor", 0xc6bd80fc),
|
||
|
ATSTRINGHASH("fixer_hq_seating_pq", 0x15dac453),
|
||
|
ATSTRINGHASH("fm_bj_race_controler", 0xbe3e7d03),
|
||
|
ATSTRINGHASH("fm_content_acid_lab_sell", 0x92772b1f),
|
||
|
ATSTRINGHASH("fm_content_acid_lab_setup", 0x61ff0c31),
|
||
|
ATSTRINGHASH("fm_content_acid_lab_source", 0x701beffb),
|
||
|
ATSTRINGHASH("fm_content_auto_shop_delivery", 0xfc4970dc),
|
||
|
ATSTRINGHASH("fm_content_ammunation", 0x4537E4CA),
|
||
|
ATSTRINGHASH("fm_content_bank_shootout", 0x3f21df40),
|
||
|
ATSTRINGHASH("fm_content_bar_resupply", 0x2363D09D),
|
||
|
ATSTRINGHASH("fm_content_business_battles", 0x62EA78D0),
|
||
|
ATSTRINGHASH("fm_content_bike_shop_delivery", 0x3ff69732),
|
||
|
ATSTRINGHASH("fm_content_cargo", 0x035d0edc),
|
||
|
ATSTRINGHASH("fm_content_cerberus", 0xe05f49f1),
|
||
|
ATSTRINGHASH("fm_content_club_management", 0xa14222b3),
|
||
|
ATSTRINGHASH("fm_content_club_odd_jobs", 0xdf2e4655),
|
||
|
ATSTRINGHASH("fm_content_club_source", 0x2b88e6a1),
|
||
|
ATSTRINGHASH("fm_content_clubhouse_contracts", 0x5a98b2be),
|
||
|
ATSTRINGHASH("fm_content_convoy", 0x4b293c1f),
|
||
|
ATSTRINGHASH("fm_content_crime_scene", 0x5CA3449B),
|
||
|
ATSTRINGHASH("fm_content_dispatch", 0xBC0EB82E),
|
||
|
ATSTRINGHASH("fm_content_drug_lab_work", 0x0bf710af),
|
||
|
ATSTRINGHASH("fm_content_drug_vehicle", 0x5B3F117),
|
||
|
ATSTRINGHASH("fm_content_export_cargo", 0xee7c5974),
|
||
|
ATSTRINGHASH("fm_content_golden_gun", 0xA7CBD213),
|
||
|
ATSTRINGHASH("fm_content_gunrunning", 0x1a160b48),
|
||
|
ATSTRINGHASH("fm_content_island_dj", 0xBE590E09),
|
||
|
ATSTRINGHASH("fm_content_island_heist", 0xF2A65E92),
|
||
|
ATSTRINGHASH("fm_content_metal_detector", 0xEEDDF72E),
|
||
|
ATSTRINGHASH("fm_content_movie_props", 0x9BF88E0E),
|
||
|
ATSTRINGHASH("fm_content_payphone_hit", 0xF7F8D71A),
|
||
|
ATSTRINGHASH("fm_content_payphone_intro", 0x2F916684),
|
||
|
ATSTRINGHASH("fm_content_phantom_car", 0xF699F9CD),
|
||
|
ATSTRINGHASH("fm_content_security_contract", 0x26EA9F66),
|
||
|
ATSTRINGHASH("fm_content_serve_and_protect", 0xFF78189D),
|
||
|
ATSTRINGHASH("fm_content_sightseeing", 0x975e5d41),
|
||
|
ATSTRINGHASH("fm_content_skydive", 0x3d946731),
|
||
|
ATSTRINGHASH("fm_content_slasher", 0xD45729DB),
|
||
|
ATSTRINGHASH("fm_content_smuggler_plane", 0xb8140067),
|
||
|
ATSTRINGHASH("fm_content_smuggler_trail", 0x277b17b6),
|
||
|
ATSTRINGHASH("fm_content_source_research", 0xe3e84b48),
|
||
|
ATSTRINGHASH("fm_content_sprint", 0x51C051E7),
|
||
|
ATSTRINGHASH("fm_content_stash_house", 0x29513dec),
|
||
|
ATSTRINGHASH("fm_content_taxi_driver", 0xb7782ad4),
|
||
|
ATSTRINGHASH("fm_content_tuner_robbery", 0xB5278C95),
|
||
|
ATSTRINGHASH("fm_content_vehicle_list", 0x9E4931D3),
|
||
|
ATSTRINGHASH("fm_content_vip_contract_1", 0x75C7E0D3),
|
||
|
ATSTRINGHASH("fm_content_xmas_mugger", 0x6cfc0084),
|
||
|
ATSTRINGHASH("fm_deathmatch_controler", 0xe62128cb),
|
||
|
ATSTRINGHASH("fm_hideout_controler", 0x055ede8c),
|
||
|
ATSTRINGHASH("fm_hold_up_tut", 0x75804856),
|
||
|
ATSTRINGHASH("fm_horde_controler", 0x514a6d17),
|
||
|
ATSTRINGHASH("fm_impromptu_dm_controler", 0xad453307),
|
||
|
ATSTRINGHASH("fm_intro", 0xefe7c380),
|
||
|
ATSTRINGHASH("fm_mission_controller", 0x6c2ce225),
|
||
|
ATSTRINGHASH("fm_mission_controller_2020", 0xBF461AD0),
|
||
|
ATSTRINGHASH("fm_race_controler", 0xeb004e0e),
|
||
|
ATSTRINGHASH("fm_street_dealer", 0xbc8a3c3e),
|
||
|
ATSTRINGHASH("fm_survival_controller", 0x1D477306),
|
||
|
ATSTRINGHASH("fmmc_launcher", 0xa3fb8a5e),
|
||
|
ATSTRINGHASH("fmmc_playlist_controller", 0x56e10d97),
|
||
|
ATSTRINGHASH("freemode", 0xc875557d),
|
||
|
ATSTRINGHASH("freemodearcade", 0xff3cad99),
|
||
|
ATSTRINGHASH("freemodeLite", 0x1CA0CF36),
|
||
|
ATSTRINGHASH("gb_airfreight", 0x59e32892),
|
||
|
ATSTRINGHASH("gb_amphibious_assault", 0x31dc55bb),
|
||
|
ATSTRINGHASH("gb_assault", 0xc3961a05),
|
||
|
ATSTRINGHASH("gb_bank_job", 0x929CEFED),
|
||
|
ATSTRINGHASH("gb_bellybeast", 0xd4d41110),
|
||
|
ATSTRINGHASH("gb_biker_bad_deal", 0x2334f600),
|
||
|
ATSTRINGHASH("gb_biker_burn_assets", 0xd9ee6178),
|
||
|
ATSTRINGHASH("gb_biker_contraband_defend", 0x56a1412c),
|
||
|
ATSTRINGHASH("gb_biker_contraband_sell", 0xdffc4863),
|
||
|
ATSTRINGHASH("gb_biker_contract_killing", 0x1c8463b3),
|
||
|
ATSTRINGHASH("gb_biker_criminal_mischief", 0x3e927a10),
|
||
|
ATSTRINGHASH("gb_biker_destroy_vans", 0x6a5fc4cc),
|
||
|
ATSTRINGHASH("gb_biker_driveby_assassin", 0x2898b9e6),
|
||
|
ATSTRINGHASH("gb_biker_free_prisoner", 0x966afe8f),
|
||
|
ATSTRINGHASH("gb_biker_joust", 0xa9165795),
|
||
|
ATSTRINGHASH("gb_biker_last_respects", 0x63389db5),
|
||
|
ATSTRINGHASH("gb_biker_race_p2p", 0xd4caa546),
|
||
|
ATSTRINGHASH("gb_biker_rescue_contact", 0x8403149b),
|
||
|
ATSTRINGHASH("gb_biker_rippin_it_up", 0x64ad4306),
|
||
|
ATSTRINGHASH("gb_biker_safecracker", 0xfc5f9481),
|
||
|
ATSTRINGHASH("gb_biker_search_and_destroy", 0x6d5e1016),
|
||
|
ATSTRINGHASH("gb_biker_shuttle", 0xd41e6264),
|
||
|
ATSTRINGHASH("gb_biker_stand_your_ground", 0x9e4e7734),
|
||
|
ATSTRINGHASH("gb_biker_steal_bikes", 0xdd56dc62),
|
||
|
ATSTRINGHASH("gb_biker_unload_weapons", 0xb31a0796),
|
||
|
ATSTRINGHASH("gb_biker_wheelie_rider", 0xb3e837ff),
|
||
|
ATSTRINGHASH("gb_carjacking", 0xa29e8148),
|
||
|
ATSTRINGHASH("gb_cashing_out", 0xaa79b0eb),
|
||
|
ATSTRINGHASH("gb_casino", 0x13645DC3),
|
||
|
ATSTRINGHASH("gb_casino_heist", 0x8ef7e740),
|
||
|
ATSTRINGHASH("gb_collect_money", 0x206c6c4b),
|
||
|
ATSTRINGHASH("gb_contraband_buy", 0xeb04de05),
|
||
|
ATSTRINGHASH("gb_contraband_defend", 0x2055a1a4),
|
||
|
ATSTRINGHASH("gb_contraband_sell", 0x7b3e31d2),
|
||
|
ATSTRINGHASH("gb_data_hack", 0x45154B11),
|
||
|
ATSTRINGHASH("gb_deathmatch", 0x9f42b34b),
|
||
|
ATSTRINGHASH("gb_delivery", 0x6e9955cb),
|
||
|
ATSTRINGHASH("gb_finderskeepers", 0xa6320c4d),
|
||
|
ATSTRINGHASH("gb_fivestar", 0x8dc43a99),
|
||
|
ATSTRINGHASH("gb_fortified", 0x51925081),
|
||
|
ATSTRINGHASH("gb_fragile_goods", 0x2382af03),
|
||
|
ATSTRINGHASH("gb_fully_loaded", 0xda508d57),
|
||
|
ATSTRINGHASH("gb_gangops", 0xfb30320a),
|
||
|
ATSTRINGHASH("gb_gang_ops_planning", 0x6d20caab),
|
||
|
ATSTRINGHASH("gb_gunrunning", 0x8cd0bff0),
|
||
|
ATSTRINGHASH("gb_gunrunning_defend", 0x14b421aa),
|
||
|
ATSTRINGHASH("gb_gunrunning_delivery", 0x29a28ed8),
|
||
|
ATSTRINGHASH("gb_headhunter", 0x71c13b55),
|
||
|
ATSTRINGHASH("gb_hunt_the_boss", 0x52d21ba4),
|
||
|
ATSTRINGHASH("gb_ie_delivery_cutscene", 0x9114379b),
|
||
|
ATSTRINGHASH("gb_illicit_goods_resupply", 0x9d9d13ec),
|
||
|
ATSTRINGHASH("gb_infiltration", 0x610BE6A0),
|
||
|
ATSTRINGHASH("gb_jewel_store_grab", 0xB0BCBA60),
|
||
|
ATSTRINGHASH("gb_ploughed", 0x14611265),
|
||
|
ATSTRINGHASH("gb_point_to_point", 0x45bd5447),
|
||
|
ATSTRINGHASH("gb_ramped_up", 0x506cc782),
|
||
|
ATSTRINGHASH("gb_rob_shop", 0xb4901ab2),
|
||
|
ATSTRINGHASH("gb_salvage", 0x4eff43a1),
|
||
|
ATSTRINGHASH("gb_security_van", 0xE8DA8C5F),
|
||
|
ATSTRINGHASH("gb_sightseer", 0x724eba87),
|
||
|
ATSTRINGHASH("gb_smuggler", 0xabd3de17),
|
||
|
ATSTRINGHASH("gb_stockpiling", 0xf60a885b),
|
||
|
ATSTRINGHASH("gb_target_pursuit", 0x5D94ED7B),
|
||
|
ATSTRINGHASH("gb_terminate", 0xf2095bfd),
|
||
|
ATSTRINGHASH("gb_transporter", 0x0b87dc63),
|
||
|
ATSTRINGHASH("gb_vehicle_export", 0xd9751e61),
|
||
|
ATSTRINGHASH("gb_velocity", 0x5f6c2123),
|
||
|
ATSTRINGHASH("gb_yacht_rob", 0x7fa4662e),
|
||
|
ATSTRINGHASH("ggsm_arcade", 0x2AEDCDFB),
|
||
|
ATSTRINGHASH("grid_arcade_cabinet", 0xD5597100),
|
||
|
ATSTRINGHASH("golf_mp", 0xcf654b49),
|
||
|
ATSTRINGHASH("gunclub_shop", 0x1beb0bf6),
|
||
|
ATSTRINGHASH("gunslinger_arcade", 0xDB23F3DC),
|
||
|
ATSTRINGHASH("hacker_truck_carmod", 0xCE27944E),
|
||
|
ATSTRINGHASH("hairdo_shop_mp", 0xb57685c9),
|
||
|
ATSTRINGHASH("hangar_carmod", 0x34141a78),
|
||
|
ATSTRINGHASH("heist_island_planning", 0x55EC87F4),
|
||
|
ATSTRINGHASH("heistislandtempcinematicfadeout", 0x32ABF33D),
|
||
|
ATSTRINGHASH("heistislandtempcinematicfadein", 0xC1508DAB),
|
||
|
ATSTRINGHASH("heli_gun", 0xba023427),
|
||
|
ATSTRINGHASH("juggalo_hideout_carmod", 0x05760f53),
|
||
|
ATSTRINGHASH("lobby", 0x5a8cb6b1),
|
||
|
ATSTRINGHASH("luxe_veh_activity", 0x304094ed),
|
||
|
ATSTRINGHASH("mg_race_to_point", 0x804da739),
|
||
|
ATSTRINGHASH("missioniaaturret", 0x0c5e8432),
|
||
|
ATSTRINGHASH("mp_bed_high", 0x272557eb),
|
||
|
ATSTRINGHASH("mptestbed", 0x62c09cc6),
|
||
|
ATSTRINGHASH("mptutorial", 0xa1cb0fb5),
|
||
|
ATSTRINGHASH("mptutorial old", 0xe79e6d99),
|
||
|
ATSTRINGHASH("music_studio_seating", 0x95f729db),
|
||
|
ATSTRINGHASH("music_studio_seating_external", 0xdbabae79),
|
||
|
ATSTRINGHASH("music_studio_smoking", 0xa5c68a5b),
|
||
|
ATSTRINGHASH("net_activity_creator_ui", 0x184b4e09),
|
||
|
ATSTRINGHASH("net_apartment_activity", 0xdd40b31d),
|
||
|
ATSTRINGHASH("net_apartment_activity_light", 0xf3e2dd79),
|
||
|
ATSTRINGHASH("net_combat_soaktest", 0xf159fe54),
|
||
|
ATSTRINGHASH("net_jacking_soaktest", 0x74fa8e62),
|
||
|
ATSTRINGHASH("net_test_drive", 0x4eb46ff0),
|
||
|
ATSTRINGHASH("net_session_soaktest", 0xe696faf1),
|
||
|
ATSTRINGHASH("nightclub_ground_floor_seats", 0x8e55be9d),
|
||
|
ATSTRINGHASH("nightclub_office_seats", 0xfd519148),
|
||
|
ATSTRINGHASH("nightclub_vip_seats", 0xdf1e929f),
|
||
|
ATSTRINGHASH("nightclubpeds", 0x9a821400),
|
||
|
ATSTRINGHASH("ob_bong", 0x57439d64),
|
||
|
ATSTRINGHASH("ob_cashregister", 0x0e1819bf),
|
||
|
ATSTRINGHASH("ob_drinking_shots", 0x000269eb),
|
||
|
ATSTRINGHASH("ob_franklin_beer", 0xb1b4d0ed),
|
||
|
ATSTRINGHASH("ob_franklin_wine", 0x00eb926e),
|
||
|
ATSTRINGHASH("ob_jukebox", 0xD044BED0),
|
||
|
ATSTRINGHASH("ob_mp_bed_high", 0xe003b72c),
|
||
|
ATSTRINGHASH("ob_mp_bed_low", 0x0d798ec5),
|
||
|
ATSTRINGHASH("ob_mp_bed_med", 0x51c89b45),
|
||
|
ATSTRINGHASH("ob_mp_shower_med", 0x96c72262),
|
||
|
ATSTRINGHASH("ob_mp_stripper", 0x5a6f3a5f),
|
||
|
ATSTRINGHASH("ob_telescope", 0x5202cf8c),
|
||
|
ATSTRINGHASH("ob_vend1", 0xa39c1f72),
|
||
|
ATSTRINGHASH("ob_vend2", 0x11c77bc7),
|
||
|
ATSTRINGHASH("pb_prostitute", 0x6a96798a),
|
||
|
ATSTRINGHASH("personal_carmod_shop", 0xdef103d2),
|
||
|
ATSTRINGHASH("pilot_school_mp", 0xc5a00edd),
|
||
|
ATSTRINGHASH("range_modern_mp", 0x1f538c61),
|
||
|
ATSTRINGHASH("road_arcade", 0x7ae86e42),
|
||
|
ATSTRINGHASH("sclub_front_bouncer", 0xe79ae0ef),
|
||
|
ATSTRINGHASH("simeon_showroom_seating", 0x23802fd8),
|
||
|
ATSTRINGHASH("specialgarage", 0xbc24c116),
|
||
|
ATSTRINGHASH("specialgaragevehicles", 0x583f311f),
|
||
|
ATSTRINGHASH("streaming", 0xd3ac6be7),
|
||
|
ATSTRINGHASH("stripclub_drinking", 0xede89eb0),
|
||
|
ATSTRINGHASH("stripclub_mp", 0x97cd8e78),
|
||
|
ATSTRINGHASH("stripperhome", 0xb8b48b62),
|
||
|
ATSTRINGHASH("tattoo_shop", 0xc0d26565),
|
||
|
ATSTRINGHASH("tempofficegarage", 0x738b3a59),
|
||
|
ATSTRINGHASH("tennis_network_mp", 0xe3940b1c),
|
||
|
ATSTRINGHASH("testtutorialforproperties", 0x311fd06a),
|
||
|
ATSTRINGHASH("testtutorialproperties", 0x011e64ab),
|
||
|
ATSTRINGHASH("testvehiclespawning", 0x2f07d2ae),
|
||
|
ATSTRINGHASH("testvehiclespawning2", 0x0c093898),
|
||
|
ATSTRINGHASH("Three_Card_Poker", 0xc8608f32),
|
||
|
ATSTRINGHASH("tuner_planning", 0x1BE25EB4),
|
||
|
ATSTRINGHASH("tuner_property_carmod", 0x70b10f84),
|
||
|
ATSTRINGHASH("tuner_sandbox_activity", 0x8758ef91),
|
||
|
ATSTRINGHASH("turret_cam_script", 0xe6511181),
|
||
|
ATSTRINGHASH("vehiclespawning", 0x70f5ddd6),
|
||
|
ATSTRINGHASH("xml_menus", 0x164e8dee),
|
||
|
};
|
||
|
unsigned CGameScriptHandlerMgr::NUM_VALID_NETWORK_SCRIPTS = (sizeof(CGameScriptHandlerMgr::ms_validNetworkScriptHashes) / sizeof(u32));
|
||
|
|
||
|
CGameScriptHandlerMgr::CGameScriptHandlerMgr(CNetworkBandwidthManager* bandwidthMgr)
|
||
|
: scriptHandlerMgr(static_cast<netBandwidthMgr*>(bandwidthMgr))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool CGameScriptHandlerMgr::CRemoteScriptInfo::IsTerminated() const
|
||
|
{
|
||
|
unsigned timeout = CNetwork::GetTimeoutTime();
|
||
|
|
||
|
if (m_ActiveParticipants == 0 && timeout > 0)
|
||
|
{
|
||
|
return (gnetVerify(m_TimeInactive != 0) && GetCurrentTime() - m_TimeInactive > (timeout+1000));
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::CRemoteScriptInfo::AddActiveParticipant( PhysicalPlayerIndex player )
|
||
|
{
|
||
|
gnetAssert(player < MAX_NUM_PHYSICAL_PLAYERS);
|
||
|
|
||
|
m_ActiveParticipants |= (1<<player);
|
||
|
m_TimeInactive = 0;
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::CRemoteScriptInfo::RemoveParticipant( PhysicalPlayerIndex player )
|
||
|
{
|
||
|
gnetAssert(player < MAX_NUM_PHYSICAL_PLAYERS);
|
||
|
|
||
|
m_ActiveParticipants &= ~(1<<player);
|
||
|
|
||
|
if (m_ActiveParticipants == 0 && m_TimeInactive == 0)
|
||
|
m_TimeInactive = GetCurrentTime();
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::CRemoteScriptInfo::UpdateInfo( const CRemoteScriptInfo& that )
|
||
|
{
|
||
|
gnetAssert(that.GetScriptId() == m_ScriptId);
|
||
|
|
||
|
SetParticipants(that.m_ActiveParticipants);
|
||
|
|
||
|
m_HostToken = that.m_HostToken;
|
||
|
m_Host = that.m_Host;
|
||
|
m_ReservedPeds = that.m_ReservedPeds;
|
||
|
m_ReservedVehicles = that.m_ReservedVehicles;
|
||
|
m_ReservedObjects = that.m_ReservedObjects;
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::CRemoteScriptInfo::Serialise(CSyncDataBase& serialiser)
|
||
|
{
|
||
|
static const unsigned SIZEOF_RESERVATION = 7;
|
||
|
|
||
|
m_ScriptId.Serialise(serialiser);
|
||
|
|
||
|
SERIALISE_UNSIGNED(serialiser, m_ActiveParticipants, sizeof(PlayerFlags)<<3, "Active Participants");
|
||
|
SERIALISE_UNSIGNED(serialiser, m_HostToken, sizeof(HostToken)<<3, "Host Token");
|
||
|
|
||
|
if (m_ActiveParticipants != 0)
|
||
|
{
|
||
|
bool bHasReservedPeds = m_ReservedPeds != 0;
|
||
|
bool bHasReservedVehicles = m_ReservedVehicles != 0;
|
||
|
bool bHasReservedObjects = m_ReservedObjects != 0;
|
||
|
|
||
|
SERIALISE_BOOL(serialiser, bHasReservedPeds);
|
||
|
SERIALISE_BOOL(serialiser, bHasReservedVehicles);
|
||
|
SERIALISE_BOOL(serialiser, bHasReservedObjects);
|
||
|
|
||
|
if (bHasReservedPeds || serialiser.GetIsMaximumSizeSerialiser())
|
||
|
{
|
||
|
u32 reservedPeds = m_ReservedPeds;
|
||
|
SERIALISE_UNSIGNED(serialiser, reservedPeds, SIZEOF_RESERVATION, "Reserved peds");
|
||
|
m_ReservedPeds = (u8) reservedPeds;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ReservedPeds = 0;
|
||
|
}
|
||
|
|
||
|
if (bHasReservedVehicles || serialiser.GetIsMaximumSizeSerialiser())
|
||
|
{
|
||
|
u32 reservedVehicles = m_ReservedVehicles;
|
||
|
SERIALISE_UNSIGNED(serialiser, reservedVehicles, SIZEOF_RESERVATION, "Reserved vehicles");
|
||
|
m_ReservedVehicles = (u8) reservedVehicles;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ReservedVehicles = 0;
|
||
|
}
|
||
|
|
||
|
if (bHasReservedObjects || serialiser.GetIsMaximumSizeSerialiser())
|
||
|
{
|
||
|
u32 reservedObjects = m_ReservedObjects;
|
||
|
SERIALISE_UNSIGNED(serialiser, reservedObjects, SIZEOF_RESERVATION, "Reserved objects");
|
||
|
m_ReservedObjects = (u8) reservedObjects;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ReservedObjects = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ReservedPeds = 0;
|
||
|
m_ReservedVehicles = 0;
|
||
|
m_ReservedObjects = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 CGameScriptHandlerMgr::CRemoteScriptInfo::GetCurrentTime() const
|
||
|
{
|
||
|
return fwTimer::GetSystemTimeInMilliseconds();
|
||
|
}
|
||
|
|
||
|
scriptIdBase& CGameScriptHandlerMgr::GetScriptId(const scrThread& scriptThread) const
|
||
|
{
|
||
|
static CGameScriptId scrId;
|
||
|
|
||
|
scrId = CGameScriptId(scriptThread);
|
||
|
|
||
|
return scrId;
|
||
|
}
|
||
|
|
||
|
scriptHandler* CGameScriptHandlerMgr::CreateScriptHandler(scrThread& scriptThread)
|
||
|
{
|
||
|
return rage_new CGameScriptHandler(const_cast<scrThread&>(scriptThread));
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::Init()
|
||
|
{
|
||
|
if (scriptVerify(!m_IsInitialised))
|
||
|
{
|
||
|
CGameScriptHandler::InitPool( MEMBUCKET_SYSTEM );
|
||
|
CGameScriptHandlerNetwork::InitPool( MEMBUCKET_SYSTEM );
|
||
|
CGameScriptHandlerNetComponent::InitPool( MEMBUCKET_SYSTEM );
|
||
|
fwScriptGuid::InitPool( MEMBUCKET_SYSTEM );
|
||
|
CScriptEntityExtension::InitPool( MEMBUCKET_SYSTEM );
|
||
|
#if __DEV
|
||
|
CScriptEntityExtension::GetPool()->RegisterPoolCallback(CScriptEntityExtension::PoolFullCallback);
|
||
|
#endif // __DEV
|
||
|
|
||
|
CGameScriptResource::InitPool( MEMBUCKET_SYSTEM );
|
||
|
|
||
|
scriptHandlerMgr::Init();
|
||
|
}
|
||
|
|
||
|
#if __SCRIPT_MEM_CALC
|
||
|
m_ArrayOfModelsUsedByMovieMeshes.Reset();
|
||
|
m_MapOfMoviesUsedByMovieMeshes.Reset();
|
||
|
m_MapOfRenderTargetsUsedByMovieMeshes.Reset();
|
||
|
m_bTrackMemoryForMovieMeshes = false;
|
||
|
|
||
|
m_TotalScriptVirtualMemory = 0;
|
||
|
m_TotalScriptPhysicalMemory = 0;
|
||
|
m_TotalScriptVirtualMemoryPeak = 0;
|
||
|
m_TotalScriptPhysicalMemoryPeak = 0;
|
||
|
#endif // __SCRIPT_MEM_CALC
|
||
|
|
||
|
scriptHandlerNetComponent::ms_useNoHostFix = Tunables::GetInstance().TryAccess(CD_GLOBAL_HASH, ATSTRINGHASH("USE_NO_HOST_FIX", 0x318526f9), scriptHandlerNetComponent::ms_useNoHostFix);
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::NetworkInit()
|
||
|
{
|
||
|
if (gnetVerify(!m_IsNetworkInitialised))
|
||
|
{
|
||
|
m_remoteActiveScripts.Reset();
|
||
|
m_remoteTerminatedScripts.Reset();
|
||
|
|
||
|
scriptHandlerMgr::NetworkInit();
|
||
|
}
|
||
|
|
||
|
#if __SCRIPT_MEM_CALC
|
||
|
m_TotalScriptVirtualMemoryPeak = 0;
|
||
|
m_TotalScriptPhysicalMemoryPeak = 0;
|
||
|
#endif // __SCRIPT_MEM_CALC
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::NetworkShutdown()
|
||
|
{
|
||
|
scriptHandlerMgr::NetworkShutdown();
|
||
|
|
||
|
#if __SCRIPT_MEM_CALC
|
||
|
m_TotalScriptVirtualMemoryPeak = 0;
|
||
|
m_TotalScriptPhysicalMemoryPeak = 0;
|
||
|
#endif // __SCRIPT_MEM_CALC
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::Shutdown()
|
||
|
{
|
||
|
if (m_IsInitialised)
|
||
|
{
|
||
|
scriptHandlerMgr::Shutdown();
|
||
|
|
||
|
CGameScriptResource::ShutdownPool();
|
||
|
fwScriptGuid::ShutdownPool();
|
||
|
CScriptEntityExtension::ShutdownPool();
|
||
|
CGameScriptHandlerNetComponent::ShutdownPool();
|
||
|
CGameScriptHandlerNetwork::ShutdownPool();
|
||
|
CGameScriptHandler::ShutdownPool();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::Update()
|
||
|
{
|
||
|
scriptHandlerMgr::Update();
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::NetworkUpdate()
|
||
|
{
|
||
|
scriptHandlerMgr::NetworkUpdate();
|
||
|
|
||
|
u32 i=0;
|
||
|
|
||
|
while (i < m_remoteActiveScripts.GetCount())
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].IsTerminated())
|
||
|
{
|
||
|
MoveActiveScriptToTerminatedQueue(i);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::PlayerHasLeft(const netPlayer& player)
|
||
|
{
|
||
|
scriptHandlerMgr::PlayerHasLeft(player);
|
||
|
|
||
|
// remove the player from the participant flags in all active scripts
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
CRemoteScriptInfo* pInfo = &m_remoteActiveScripts[i];
|
||
|
|
||
|
if (pInfo->IsPlayerAParticipant(player.GetPhysicalPlayerIndex()))
|
||
|
{
|
||
|
pInfo->RemoveParticipant(player.GetPhysicalPlayerIndex());
|
||
|
}
|
||
|
|
||
|
if (pInfo->GetHost() == &player)
|
||
|
{
|
||
|
pInfo->SetHost(NULL);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if __BANK
|
||
|
void Bank_ForceResend()
|
||
|
{
|
||
|
CGameScriptHandlerMgr* pMgr = &CTheScripts::GetScriptHandlerMgr();
|
||
|
|
||
|
const CGameScriptHandler* handler = pMgr->GetScriptHandlerFromComboName(pMgr->ms_Handlers[pMgr->ms_HandlerComboIndex]);
|
||
|
|
||
|
if (handler && handler->GetNetworkComponent())
|
||
|
{
|
||
|
handler->GetNetworkComponent()->ForceResendOfAllBroadcastData();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Bank_HostRequest()
|
||
|
{
|
||
|
CGameScriptHandlerMgr* pMgr = &CTheScripts::GetScriptHandlerMgr();
|
||
|
|
||
|
const CGameScriptHandler* handler = pMgr->GetScriptHandlerFromComboName(pMgr->ms_Handlers[pMgr->ms_HandlerComboIndex]);
|
||
|
|
||
|
if (handler && handler->GetNetworkComponent())
|
||
|
{
|
||
|
handler->GetNetworkComponent()->RequestToBeHost();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::InitWidgets(bkBank* pBank)
|
||
|
{
|
||
|
|
||
|
if (scriptVerify(pBank))
|
||
|
{
|
||
|
ms_Handlers[0] = "-- none --";
|
||
|
ms_NumHandlers = 1;
|
||
|
|
||
|
pBank->PushGroup("Script Handlers",false);
|
||
|
ms_pHandlerCombo = pBank->AddCombo("Active Handlers", &ms_HandlerComboIndex, ms_NumHandlers, (const char **)ms_Handlers);
|
||
|
pBank->AddToggle("Display handler info", &ms_DisplayHandlerInfo);
|
||
|
pBank->AddButton("Resend all broadcast data", Bank_ForceResend);
|
||
|
pBank->AddButton("Request to be host", Bank_HostRequest);
|
||
|
pBank->AddToggle("Display all MP handlers", &ms_DisplayAllMPHandlers);
|
||
|
pBank->PopGroup();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// CGameScriptHandlerMgr::ShutdownWidgets
|
||
|
// Since ms_pHandlerCombo is created within the script bank, make sure that we remove the combo and set ms_pHandlerCombo to NULL
|
||
|
// before the script bank is deleted so that ms_pHandlerCombo doesn't have an invalid address
|
||
|
void CGameScriptHandlerMgr::ShutdownWidgets(bkBank* pBank)
|
||
|
{
|
||
|
if (scriptVerify(pBank))
|
||
|
{
|
||
|
pBank->Remove(*ms_pHandlerCombo);
|
||
|
ms_pHandlerCombo = NULL;
|
||
|
|
||
|
ms_HandlerComboIndex = 0;
|
||
|
ms_DisplayHandlerInfo = false;
|
||
|
ms_DisplayAllMPHandlers = false;
|
||
|
}
|
||
|
}
|
||
|
#endif // __BANK
|
||
|
|
||
|
void CGameScriptHandlerMgr::RegisterScript(scrThread& scriptThread)
|
||
|
{
|
||
|
scriptHandlerMgr::RegisterScript(scriptThread);
|
||
|
|
||
|
#if __BANK
|
||
|
UpdateScriptHandlerCombo();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::UnregisterScript(scrThread& scriptThread)
|
||
|
{
|
||
|
GtaThread& gtaThread = static_cast<GtaThread&>(scriptThread);
|
||
|
|
||
|
CGameScriptHandler* handler = gtaThread.m_Handler;
|
||
|
|
||
|
if (AssertVerify(handler) && handler->Terminate())
|
||
|
{
|
||
|
DeleteHandlerWithHash(handler->GetScriptId().GetScriptIdHash());
|
||
|
}
|
||
|
|
||
|
gtaThread.m_Handler = NULL;
|
||
|
|
||
|
#if __BANK
|
||
|
UpdateScriptHandlerCombo();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
bool CGameScriptHandlerMgr::IsScriptValidForNetworking(atHashValue scriptName)
|
||
|
{
|
||
|
#if !__FINAL
|
||
|
if (PARAM_dontCrashOnScriptValidation.Get())
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
#endif // !__FINAL
|
||
|
|
||
|
for (u32 scriptHash = 0; scriptHash < NUM_VALID_NETWORK_SCRIPTS; scriptHash++)
|
||
|
{
|
||
|
if (ms_validNetworkScriptHashes[scriptHash] == scriptName)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::SetScriptAsANetworkScript(GtaThread& scriptThread, int instanceId)
|
||
|
{
|
||
|
CGameScriptId& scriptId = static_cast<CGameScriptId&>(GetScriptId(scriptThread));
|
||
|
|
||
|
atHashValue hash = scriptId.GetScriptIdHash();
|
||
|
|
||
|
netLoggingInterface *log = CTheScripts::GetScriptHandlerMgr().GetLog();
|
||
|
|
||
|
if (log)
|
||
|
{
|
||
|
CGameScriptId logId = scriptId;
|
||
|
logId.SetInstanceId(instanceId);
|
||
|
NetworkLogUtils::WriteLogEvent(*log, "SET_SCRIPT_AS_NETWORK_SCRIPT", "%s", logId.GetScriptName());
|
||
|
}
|
||
|
|
||
|
// find network handler for this thread, destroy it and replace with a network handler
|
||
|
scriptHandler** ppHandler = m_scriptHandlers.Access(hash);
|
||
|
|
||
|
if (ppHandler)
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(*ppHandler);
|
||
|
|
||
|
scriptAssertf(handler->GetNumRegisteredNetworkedObjects() == 0, "CGameScriptHandlerMgr::SetScriptAsANetworkScript : Script %s has registered networked objects", handler->GetScriptName());
|
||
|
|
||
|
if (scriptVerifyf(!handler->RequiresANetworkComponent(), "CGameScriptHandlerMgr::SetScriptAsANetworkScript : Script %s has already been set as a network script", handler->GetScriptName()))
|
||
|
{
|
||
|
if (!IsScriptValidForNetworking(scriptId.GetScriptNameHash()))
|
||
|
{
|
||
|
#if !__FINAL
|
||
|
NETWORK_QUITF(0, "CGameScriptHandlerMgr::SetScriptAsANetworkScript : Cannot network script %s - it has no entry in the valid network scripts allowlist", handler->GetScriptName());
|
||
|
#endif
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (CGameScriptHandlerNetwork::GetPool()->GetNoOfFreeSpaces() == 0)
|
||
|
{
|
||
|
Displayf("** TOO MANY NETWORKED SCRIPTS RUNNING!! **\n");
|
||
|
Displayf("Active networked scripts:\n");
|
||
|
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
scriptHandler* handler = entry.GetData();
|
||
|
|
||
|
if (handler && handler->GetNetworkComponent())
|
||
|
{
|
||
|
Displayf("%s\n", handler->GetLogName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CNetwork::FlushAllLogFiles(true);
|
||
|
|
||
|
NETWORK_QUITF(0, "CGameScriptHandlerMgr::SetScriptAsANetworkScript : Cannot network this script - too many networked scripts running (max %d)", MAX_NUM_ACTIVE_NETWORK_SCRIPTS);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
scriptHandlerObject* aUnnetworkedObjects[CGameScriptHandler::MAX_UNNETWORKED_OBJECTS];
|
||
|
u32 numUnnetworkedObjects = 0;
|
||
|
|
||
|
handler->DetachAllUnnetworkedObjects(aUnnetworkedObjects, numUnnetworkedObjects);
|
||
|
|
||
|
DeleteHandlerWithHash(hash);
|
||
|
|
||
|
scriptThread.bSafeForNetworkGame = true;
|
||
|
scriptThread.InstanceId = instanceId;
|
||
|
|
||
|
if (instanceId != -1)
|
||
|
{
|
||
|
#if __ASSERT
|
||
|
scriptHandler* pHandler = GetScriptHandler(GetScriptId(scriptThread));
|
||
|
|
||
|
// we can't have 2 network script handlers with the same id
|
||
|
NETWORK_QUITF(!pHandler, "SetScriptAsANetworkScript - a network script already exists with this instance id (%s)", pHandler->GetLogName());
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
CGameScriptHandlerNetwork* netHandler = rage_new CGameScriptHandlerNetwork(scriptThread);
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
scriptHandler** ppHandler = m_scriptHandlers.Access(netHandler->GetScriptId().GetScriptIdHash());
|
||
|
if (ppHandler)
|
||
|
{
|
||
|
char logNameOfNewHandler[200];
|
||
|
safecpy(logNameOfNewHandler, netHandler->GetLogName(), NELEM(logNameOfNewHandler)); // CGameScriptId::GetLogName() fills in a static string internally so I need to make a copy of one of the LogName's to display in the assert below
|
||
|
|
||
|
#if __ASSERT
|
||
|
CGameScriptHandler *pGameScriptHandler = static_cast<CGameScriptHandler*>(*ppHandler);
|
||
|
|
||
|
Assertf(false, "CGameScriptHandlerMgr::SetScriptAsANetworkScript - about to add %s(%p) script with hash %u. %s(%p) already exists in the map with this hash",
|
||
|
logNameOfNewHandler, netHandler, netHandler->GetScriptId().GetScriptIdHash().GetHash(),
|
||
|
pGameScriptHandler->GetLogName(), pGameScriptHandler);
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
#endif // !__NO_OUTPUT
|
||
|
|
||
|
m_scriptHandlers.Insert(netHandler->GetScriptId().GetScriptIdHash(), netHandler);
|
||
|
|
||
|
if (m_IsNetworkInitialised)
|
||
|
{
|
||
|
netHandler->CreateNetworkComponent();
|
||
|
}
|
||
|
#if __BANK
|
||
|
UpdateScriptHandlerCombo();
|
||
|
#endif
|
||
|
for (u32 i=0; i<numUnnetworkedObjects; i++)
|
||
|
{
|
||
|
if (instanceId != -1)
|
||
|
{
|
||
|
static_cast<CGameScriptId&>(aUnnetworkedObjects[i]->GetScriptInfo()->GetScriptId()).SetInstanceId(instanceId);
|
||
|
}
|
||
|
|
||
|
netHandler->RegisterExistingScriptObject(*aUnnetworkedObjects[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
scriptAssertf(0, "CGameScriptHandlerMgr::SetScriptAsANetworkScript : The script handler for %s was not found", scriptId.GetLogName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript(GtaThread& scriptThread, int instanceId)
|
||
|
{
|
||
|
CGameScriptId& singlePlayerScriptId = static_cast<CGameScriptId&>(GetScriptId(scriptThread));
|
||
|
|
||
|
atHashValue singlePlayerHash = singlePlayerScriptId.GetScriptIdHash();
|
||
|
|
||
|
// find existing handler for this thread and attempt to replace it with a network handler
|
||
|
scriptHandler** ppHandler = m_scriptHandlers.Access(singlePlayerHash);
|
||
|
|
||
|
if (ppHandler)
|
||
|
{
|
||
|
CGameScriptHandler* pSinglePlayerHandler = static_cast<CGameScriptHandler*>(*ppHandler);
|
||
|
|
||
|
scriptAssertf(pSinglePlayerHandler->GetNumRegisteredObjects() == 0, "CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript : Script %s has registered objects", pSinglePlayerHandler->GetScriptName());
|
||
|
|
||
|
if (scriptVerifyf(!pSinglePlayerHandler->RequiresANetworkComponent(), "CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript : Script %s has already been set as a network script", pSinglePlayerHandler->GetScriptName()))
|
||
|
{
|
||
|
if (CGameScriptHandlerNetwork::GetPool()->GetNoOfFreeSpaces() == 0)
|
||
|
{
|
||
|
Displayf("** TOO MANY NETWORKED SCRIPTS RUNNING!! **\n");
|
||
|
Displayf("Active networked scripts:\n");
|
||
|
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
scriptHandler* handler = entry.GetData();
|
||
|
|
||
|
if (handler && handler->GetNetworkComponent())
|
||
|
{
|
||
|
Displayf("%s\n", handler->GetLogName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CNetwork::FlushAllLogFiles(true);
|
||
|
|
||
|
FatalAssertf(0, "CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript : Cannot network this script - too many networked scripts running (max %d)", MAX_NUM_ACTIVE_NETWORK_SCRIPTS);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (!m_scriptHandlers.Delete(singlePlayerHash))
|
||
|
{
|
||
|
FatalAssertf(0, "CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript : failed to delete handler %s at key %u (%p)\n", pSinglePlayerHandler->GetLogName(), singlePlayerHash.GetHash(), pSinglePlayerHandler);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool bFailedToCreateNetworkHandler = false;
|
||
|
CGameScriptHandlerNetwork* pNetHandler = NULL;
|
||
|
|
||
|
bool singlePlayerSafeForNetworkGame = scriptThread.bSafeForNetworkGame;
|
||
|
int singlePlayerInstanceId = scriptThread.InstanceId;
|
||
|
|
||
|
scriptThread.bSafeForNetworkGame = true;
|
||
|
|
||
|
if (instanceId != -1)
|
||
|
{
|
||
|
scriptThread.InstanceId = instanceId;
|
||
|
|
||
|
scriptHandler* pHandler = GetScriptHandler(GetScriptId(scriptThread));
|
||
|
|
||
|
// we can't have 2 network script handlers with the same id
|
||
|
if (pHandler)
|
||
|
{
|
||
|
Displayf("CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript - a network script already exists with this instance id (%s)", pHandler->GetLogName());
|
||
|
bFailedToCreateNetworkHandler = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!bFailedToCreateNetworkHandler)
|
||
|
{
|
||
|
pNetHandler = rage_new CGameScriptHandlerNetwork(scriptThread);
|
||
|
|
||
|
scriptHandler** ppHandler = m_scriptHandlers.Access(pNetHandler->GetScriptId().GetScriptIdHash());
|
||
|
if (ppHandler)
|
||
|
{
|
||
|
#if !__NO_OUTPUT
|
||
|
char logNameOfNewHandler[200];
|
||
|
safecpy(logNameOfNewHandler, pNetHandler->GetLogName(), NELEM(logNameOfNewHandler)); // CGameScriptId::GetLogName() fills in a static string internally so I need to make a copy of one of the LogName's to display in the assert below
|
||
|
|
||
|
CGameScriptHandler *pGameScriptHandler = static_cast<CGameScriptHandler*>(*ppHandler);
|
||
|
|
||
|
Displayf("CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript - about to add %s(%p) script with hash %u. %s(%p) already exists in the map with this hash",
|
||
|
logNameOfNewHandler, pNetHandler, pNetHandler->GetScriptId().GetScriptIdHash().GetHash(),
|
||
|
pGameScriptHandler->GetLogName(), pGameScriptHandler);
|
||
|
#endif // !__NO_OUTPUT
|
||
|
|
||
|
bFailedToCreateNetworkHandler = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bFailedToCreateNetworkHandler)
|
||
|
{
|
||
|
if (pNetHandler)
|
||
|
{ // I don't need to Delete pNetHandler from m_scriptHandlers because it hasn't been Inserted at this stage
|
||
|
m_DeletingHandlers = true;
|
||
|
|
||
|
pNetHandler->Shutdown();
|
||
|
delete pNetHandler;
|
||
|
pNetHandler = NULL;
|
||
|
|
||
|
m_DeletingHandlers = false;
|
||
|
}
|
||
|
|
||
|
// deleting pNetHandler will have cleared scriptThread.m_Handler (in ~CGameScriptHandler()) so make sure it points to pSinglePlayerHandler
|
||
|
scriptThread.m_Handler = pSinglePlayerHandler;
|
||
|
|
||
|
// Put the original single player handler back to the way it was
|
||
|
scriptThread.bSafeForNetworkGame = singlePlayerSafeForNetworkGame;
|
||
|
scriptThread.InstanceId = singlePlayerInstanceId;
|
||
|
|
||
|
m_scriptHandlers.Insert(singlePlayerHash, pSinglePlayerHandler);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pSinglePlayerHandler)
|
||
|
{ // We've already Deleted pSinglePlayerHandler from m_scriptHandlers so now we just need to delete pSinglePlayerHandler itself
|
||
|
m_DeletingHandlers = true;
|
||
|
|
||
|
pSinglePlayerHandler->Shutdown();
|
||
|
delete pSinglePlayerHandler;
|
||
|
pSinglePlayerHandler = NULL;
|
||
|
|
||
|
m_DeletingHandlers = false;
|
||
|
}
|
||
|
|
||
|
// deleting pSinglePlayerHandler will have cleared scriptThread.m_Handler (in ~CGameScriptHandler()) so make sure it points to pNetHandler
|
||
|
scriptThread.m_Handler = pNetHandler;
|
||
|
|
||
|
m_scriptHandlers.Insert(pNetHandler->GetScriptId().GetScriptIdHash(), pNetHandler);
|
||
|
|
||
|
if (m_IsNetworkInitialised)
|
||
|
{
|
||
|
pNetHandler->CreateNetworkComponent();
|
||
|
}
|
||
|
}
|
||
|
#if __BANK
|
||
|
UpdateScriptHandlerCombo();
|
||
|
#endif
|
||
|
|
||
|
return !bFailedToCreateNetworkHandler;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
scriptAssertf(0, "CGameScriptHandlerMgr::TryToSetScriptAsANetworkScript : The script handler for %s was not found", singlePlayerScriptId.GetLogName());
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void CGameScriptHandlerMgr::SetScriptAsSafeToRunInMP(GtaThread& scriptThread)
|
||
|
{
|
||
|
CGameScriptId& scriptId = static_cast<CGameScriptId&>(GetScriptId(scriptThread));
|
||
|
|
||
|
atHashValue hash = scriptId.GetScriptIdHash();
|
||
|
|
||
|
// find network handler for this thread and change its script id
|
||
|
scriptHandler** ppHandler = m_scriptHandlers.Access(hash);
|
||
|
|
||
|
if (ppHandler)
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(*ppHandler);
|
||
|
|
||
|
if (!m_scriptHandlers.Delete(hash))
|
||
|
{
|
||
|
FatalAssertf(0, "CGameScriptHandlerMgr::SetScriptAsSafeToRunInMP - failed to remove handler %s from map", handler->GetLogName());
|
||
|
}
|
||
|
|
||
|
scriptThread.bSafeForNetworkGame = true;
|
||
|
|
||
|
// recalculate the script id as the hash will now be altered
|
||
|
static_cast<CGameScriptId&>(handler->GetScriptId()).InitGameScriptId(scriptThread);
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
scriptHandler** ppHandler = m_scriptHandlers.Access(handler->GetScriptId().GetScriptIdHash());
|
||
|
if (ppHandler)
|
||
|
{
|
||
|
char logNameOfNewHandler[200];
|
||
|
safecpy(logNameOfNewHandler, handler->GetLogName(), NELEM(logNameOfNewHandler)); // CGameScriptId::GetLogName() fills in a static string internally so I need to make a copy of one of the LogName's to display in the assert below
|
||
|
|
||
|
CGameScriptHandler *pGameScriptHandler = static_cast<CGameScriptHandler*>(*ppHandler);
|
||
|
|
||
|
Quitf("CGameScriptHandlerMgr::SetScriptAsSafeToRunInMP - about to add %s(%p) script with hash %u. %s(%p) already exists in the map with this hash",
|
||
|
logNameOfNewHandler, handler, handler->GetScriptId().GetScriptIdHash().GetHash(),
|
||
|
pGameScriptHandler->GetLogName(), pGameScriptHandler);
|
||
|
}
|
||
|
#endif // !__NO_OUTPUT
|
||
|
|
||
|
m_scriptHandlers.Insert(handler->GetScriptId().GetScriptIdHash(), handler);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
scriptAssertf(0, "CGameScriptHandlerMgr::SetScriptAsSafeToRunInMP : The script handler for %s was not found", scriptId.GetLogName());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 CGameScriptHandlerMgr::GetAllScriptHandlerEntities(CEntity* entityArray[], u32 arrayLen)
|
||
|
{
|
||
|
u32 numEntities = 0;
|
||
|
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler)
|
||
|
{
|
||
|
numEntities += handler->GetAllEntities(&entityArray[numEntities], arrayLen-numEntities);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return numEntities;
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::GetNumReservedScriptEntities(u32 &numPeds, u32 &numVehicles, u32 &numObjects) const
|
||
|
{
|
||
|
numPeds = numVehicles = numObjects = 0;
|
||
|
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->RequiresANetworkComponent())
|
||
|
{
|
||
|
const CGameScriptHandlerNetwork* netHandler = static_cast<const CGameScriptHandlerNetwork*>(handler);
|
||
|
|
||
|
numPeds += netHandler->GetTotalNumReservedPeds();
|
||
|
numVehicles += netHandler->GetTotalNumReservedVehicles();
|
||
|
numObjects += netHandler->GetTotalNumReservedObjects();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::GetNumCreatedScriptEntities(u32 &numPeds, u32 &numVehicles, u32 &numObjects) const
|
||
|
{
|
||
|
numPeds = numVehicles = numObjects = 0;
|
||
|
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->RequiresANetworkComponent())
|
||
|
{
|
||
|
const CGameScriptHandlerNetwork* netHandler = static_cast<const CGameScriptHandlerNetwork*>(handler);
|
||
|
|
||
|
numPeds += netHandler->GetNumCreatedPeds();
|
||
|
numVehicles += netHandler->GetNumCreatedVehicles();
|
||
|
numObjects += netHandler->GetNumCreatedObjects();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::GetNumRequiredScriptEntities(u32 &numPeds, u32 &numVehicles, u32 &numObjects, CGameScriptHandler* pHandlerToIgnore) const
|
||
|
{
|
||
|
numPeds = numVehicles = numObjects = 0;
|
||
|
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler != pHandlerToIgnore && handler->GetNetworkComponent() && handler->GetNetworkComponent()->IsPlaying())
|
||
|
{
|
||
|
const CGameScriptHandlerNetwork* netHandler = static_cast<const CGameScriptHandlerNetwork*>(handler);
|
||
|
|
||
|
u32 peds = 0;
|
||
|
u32 vehs = 0;
|
||
|
u32 objs = 0;
|
||
|
|
||
|
netHandler->GetNumRequiredEntities(peds, vehs, objs);
|
||
|
|
||
|
numPeds += peds;
|
||
|
numVehicles += vehs;
|
||
|
numObjects += objs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 remoteReservedPeds = 0;
|
||
|
u32 remoteReservedVehs = 0;
|
||
|
u32 remoteReservedObjs = 0;
|
||
|
u32 remoteCreatedPeds = 0;
|
||
|
u32 remoteCreatedVehs = 0;
|
||
|
u32 remoteCreatedObjs = 0;
|
||
|
|
||
|
GetRemoteScriptEntityReservations(remoteReservedPeds, remoteReservedVehs, remoteReservedObjs, remoteCreatedPeds, remoteCreatedVehs, remoteCreatedObjs);
|
||
|
|
||
|
if (remoteReservedPeds > remoteCreatedPeds)
|
||
|
{
|
||
|
numPeds += remoteReservedPeds-remoteCreatedPeds;
|
||
|
}
|
||
|
|
||
|
if (remoteReservedVehs > remoteCreatedVehs)
|
||
|
{
|
||
|
numVehicles += remoteReservedVehs-remoteCreatedVehs;
|
||
|
}
|
||
|
|
||
|
if (remoteReservedObjs > remoteCreatedObjs)
|
||
|
{
|
||
|
numObjects += remoteReservedObjs-remoteCreatedObjs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//PURPOSE
|
||
|
// Adds info on a new script running remotely but not locally
|
||
|
void CGameScriptHandlerMgr::AddRemoteScriptInfo(CRemoteScriptInfo& scriptInfo, const netPlayer* sendingPlayer)
|
||
|
{
|
||
|
CGameScriptHandler* pHandler = SafeCast(CGameScriptHandler, GetScriptHandler(scriptInfo.GetScriptId()));
|
||
|
|
||
|
if (gnetVerifyf(scriptInfo.GetScriptId().GetTimeStamp() != 0, "CGameScriptHandlerMgr::AddRemoteScriptInfo: can't add a remote script info with a timestamp of 0"))
|
||
|
{
|
||
|
if (sendingPlayer)
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Got a remote script info update from %s. Participants: %u, Host token: %u. Reservations: peds(%d), vehicles(%d), objects(%d)", sendingPlayer->GetLogName(), scriptInfo.GetActiveParticipants(), scriptInfo.GetHostToken(), scriptInfo.GetReservedPeds(), scriptInfo.GetReservedVehicles(), scriptInfo.GetReservedObjects());
|
||
|
|
||
|
// the sending player is the current host
|
||
|
scriptInfo.SetHost(sendingPlayer);
|
||
|
|
||
|
if (pHandler && !pHandler->IsTerminated())
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Ignore: script is running locally");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Locally update remote script info. Participants: %u, Host token: %u. Reservations: peds(%d), vehicles(%d), objects(%d)", scriptInfo.GetActiveParticipants(), scriptInfo.GetHostToken(), scriptInfo.GetReservedPeds(), scriptInfo.GetReservedVehicles(), scriptInfo.GetReservedObjects());
|
||
|
}
|
||
|
|
||
|
if (scriptInfo.GetActiveParticipants() == 0)
|
||
|
{
|
||
|
// this script has terminated, so remove from active queue and add to terminated queue
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptInfo.m_ScriptId)
|
||
|
{
|
||
|
// if the host token is less than the one we currently have, then this info is from a previous host and is ignored.
|
||
|
if (scriptInfo.m_HostToken < m_remoteActiveScripts[i].m_HostToken)
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Host token out of date (most recent: %u). Ignore.", m_remoteActiveScripts[i].m_HostToken);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MoveActiveScriptToTerminatedQueue(i);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bool bAddActiveScript = true;
|
||
|
|
||
|
// make sure all players still exist (they may have left before we received this update)
|
||
|
for (PhysicalPlayerIndex i=0; i<MAX_NUM_PHYSICAL_PLAYERS; i++)
|
||
|
{
|
||
|
if (scriptInfo.IsPlayerAParticipant(i) && !NetworkInterface::GetPhysicalPlayerFromIndex(i))
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Removed a non-existent player %d from the remote script info update.", i);
|
||
|
scriptInfo.RemoveParticipant(i);
|
||
|
|
||
|
if (scriptInfo.GetActiveParticipants() == 0)
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// check to see if this script is on the terminated queue. This can happen when we are the host and terminate the script, and another player temporarily
|
||
|
// becomes the host and sends another remote script info update back to us before shutting down the script not long after. Once a script is on the terminated
|
||
|
// queue it must stay there.
|
||
|
for (u32 i=0; i<m_remoteTerminatedScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteTerminatedScripts[i].m_ScriptId == scriptInfo.m_ScriptId)
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Remote script info is already on terminated queue. Ignore update.");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// see if we already have an info for this script in the active queue
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptInfo.m_ScriptId)
|
||
|
{
|
||
|
// if the host token is less than the one we currently have, then this info is from a previous host and is ignored.
|
||
|
if (scriptInfo.m_HostToken < m_remoteActiveScripts[i].m_HostToken)
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Host token out of date (most recent: %u). Ignore.", m_remoteActiveScripts[i].m_HostToken);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Update existing remote script info");
|
||
|
|
||
|
// update the existing entry with the latest info
|
||
|
m_remoteActiveScripts[i].UpdateInfo(scriptInfo);
|
||
|
}
|
||
|
|
||
|
bAddActiveScript = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bAddActiveScript && sendingPlayer)
|
||
|
{
|
||
|
// possibly handle the case where we have 2 identical scripts running with different timestamps
|
||
|
bAddActiveScript = HandleTimestampConflict(scriptInfo);
|
||
|
}
|
||
|
|
||
|
if (bAddActiveScript)
|
||
|
{
|
||
|
// we don't want to fill up the queue for the active list.
|
||
|
gnetAssertf(m_remoteActiveScripts.GetAvailable() > 0, "Ran out of active remote script infos");
|
||
|
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Add new active remote script info");
|
||
|
|
||
|
// add a new info to the active queue
|
||
|
if (!m_remoteActiveScripts.Push(scriptInfo))
|
||
|
{
|
||
|
Assertf(0, "The remote active script queue is full");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::AddPlayerToRemoteScript(const CGameScriptId& scriptId, const netPlayer& player)
|
||
|
{
|
||
|
if (gnetVerifyf(scriptId.GetTimeStamp() != 0, "CGameScriptHandlerMgr::AddPlayerToRemoteScript: scriptId has a timestamp of 0"))
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptId, "Add remote player %s (%d) to remote script", player.GetLogName(), player.GetPhysicalPlayerIndex());
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].AddActiveParticipant(player.GetPhysicalPlayerIndex());
|
||
|
WriteRemoteScriptHeader(scriptId, "Participants now = %d", m_remoteActiveScripts[i].GetActiveParticipants());
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (u32 i=0; i<m_remoteTerminatedScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteTerminatedScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
gnetAssertf(0, "Trying to add a participant to a terminated remote script");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WriteRemoteScriptHeader(scriptId, "Active remote script not found. Ignore");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::RemovePlayerFromRemoteScript(const CGameScriptId& scriptId, const netPlayer& player, bool bCalledFromHandler)
|
||
|
{
|
||
|
if (gnetVerifyf(scriptId.GetTimeStamp() != 0, "CGameScriptHandlerMgr::RemovePlayerFromRemoteScript: scriptId %s has a timestamp of 0", scriptId.GetLogName()))
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptId, "Remove remote player %s (%d) from remote script", player.GetLogName(), player.GetPhysicalPlayerIndex());
|
||
|
|
||
|
if (!bCalledFromHandler)
|
||
|
{
|
||
|
scriptHandler* pHandler = GetScriptHandler(scriptId);
|
||
|
|
||
|
if (pHandler && !pHandler->IsTerminated())
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptId, "Ignore: script is running locally");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].RemoveParticipant(player.GetPhysicalPlayerIndex());
|
||
|
|
||
|
WriteRemoteScriptHeader(scriptId, "Participants now = %d", m_remoteActiveScripts[i].GetActiveParticipants());
|
||
|
|
||
|
if (m_remoteActiveScripts[i].GetActiveParticipants() == 0)
|
||
|
{
|
||
|
MoveActiveScriptToTerminatedQueue(i);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if ENABLE_NETWORK_LOGGING
|
||
|
for (u32 i=0; i<m_remoteTerminatedScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteTerminatedScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptId, "Remote script has already been terminated. Ignore.");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WriteRemoteScriptHeader(scriptId, "No remote script found. Ignore");
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::TerminateActiveScriptInfo(const CGameScriptId& scriptId)
|
||
|
{
|
||
|
CGameScriptId idNoTimestamp = scriptId;
|
||
|
|
||
|
// reset the timestamp so that comparisons will find matching scripts
|
||
|
idNoTimestamp.ResetTimestamp();
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].GetScriptId() == idNoTimestamp &&
|
||
|
m_remoteActiveScripts[i].m_ScriptId.GetTimeStamp() != scriptId.GetTimeStamp())
|
||
|
{
|
||
|
WriteRemoteScriptHeader(m_remoteActiveScripts[i].GetScriptId(), "Terminate existing active id");
|
||
|
MoveActiveScriptToTerminatedQueue(i);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::SetNewHostOfRemoteScript(const CGameScriptId& scriptId, const netPlayer& newHost, HostToken newHostToken, PlayerFlags participantFlags)
|
||
|
{
|
||
|
if (gnetVerifyf(scriptId.GetTimeStamp() != 0, "CGameScriptHandlerMgr::SetNewHostOfRemoteScript: scriptId has a timestamp of 0"))
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptId, "Setting new host %s (%d) of remote script. Host token: %u", newHost.GetLogName(), newHost.GetPhysicalPlayerIndex(), newHostToken);
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].SetHostToken(newHostToken);
|
||
|
m_remoteActiveScripts[i].SetParticipants(participantFlags);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WriteRemoteScriptHeader(scriptId, "Active remote script not found. Ignore");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//PURPOSE
|
||
|
// Returns the closest participant of the given remote script
|
||
|
CNetGamePlayer* CGameScriptHandlerMgr::GetClosestParticipantOfRemoteScript(const CRemoteScriptInfo& remoteScriptInfo)
|
||
|
{
|
||
|
CNetGamePlayer* pClosestPlayer = NULL;
|
||
|
float closestDist = 0.0f;
|
||
|
Vector3 localPlayerPos = VEC3V_TO_VECTOR3(CGameWorld::FindLocalPlayer()->GetTransform().GetPosition());
|
||
|
|
||
|
PlayerFlags participantFlags = remoteScriptInfo.GetActiveParticipants();
|
||
|
|
||
|
for (u32 i=0; i<MAX_NUM_PHYSICAL_PLAYERS; i++)
|
||
|
{
|
||
|
if (participantFlags & (1<<i))
|
||
|
{
|
||
|
CNetGamePlayer* pPlayer = static_cast<CNetGamePlayer*>(NetworkInterface::GetPlayerMgr().GetPhysicalPlayerFromIndex((PhysicalPlayerIndex)i));
|
||
|
|
||
|
if (pPlayer->GetPlayerPed() && !pPlayer->IsMyPlayer())
|
||
|
{
|
||
|
Vector3 playerPos = VEC3V_TO_VECTOR3(pPlayer->GetPlayerPed()->GetTransform().GetPosition());
|
||
|
Vector3 diff = playerPos - localPlayerPos;
|
||
|
|
||
|
float playerDist = diff.XYMag2();
|
||
|
|
||
|
if (!pClosestPlayer || playerDist < closestDist)
|
||
|
{
|
||
|
pClosestPlayer = pPlayer;
|
||
|
closestDist = playerDist;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return pClosestPlayer;
|
||
|
}
|
||
|
|
||
|
//PURPOSE
|
||
|
// Gets info on a new script running remotely but not locally
|
||
|
CGameScriptHandlerMgr::CRemoteScriptInfo* CGameScriptHandlerMgr::GetRemoteScriptInfo(const CGameScriptId& scriptId, bool bActiveOnly)
|
||
|
{
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
if (!bActiveOnly || m_remoteActiveScripts[i].GetActiveParticipants() > 0)
|
||
|
return &m_remoteActiveScripts[i];
|
||
|
else
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!bActiveOnly)
|
||
|
{
|
||
|
for (u32 i=0; i<m_remoteTerminatedScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteTerminatedScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
return &m_remoteTerminatedScripts[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
const CGameScriptHandlerMgr::CRemoteScriptInfo* CGameScriptHandlerMgr::GetRemoteScriptInfo(const CGameScriptId& scriptId, bool bActiveOnly) const
|
||
|
{
|
||
|
return const_cast<CGameScriptHandlerMgr*>(this)->GetRemoteScriptInfo(scriptId, bActiveOnly);
|
||
|
}
|
||
|
|
||
|
|
||
|
// returns true if the given script is running, either locally or remotely
|
||
|
bool CGameScriptHandlerMgr::IsScriptActive(const CGameScriptId& scriptId, bool bMatchOnNameOnly)
|
||
|
{
|
||
|
bool bScriptActive = false;
|
||
|
|
||
|
if (GetScriptHandler(scriptId))
|
||
|
{
|
||
|
bScriptActive = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].GetActiveParticipants() > 0)
|
||
|
{
|
||
|
if (bMatchOnNameOnly)
|
||
|
{
|
||
|
// only match using the script name
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId.EqualivalentScriptName(scriptId))
|
||
|
{
|
||
|
bScriptActive = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (m_remoteActiveScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
bScriptActive = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bScriptActive;
|
||
|
}
|
||
|
|
||
|
// returns true if the given script has been terminated
|
||
|
bool CGameScriptHandlerMgr::IsScriptTerminated(const CGameScriptId& scriptId)
|
||
|
{
|
||
|
if (GetScriptHandler(scriptId) && !GetScriptHandler(scriptId)->IsTerminated())
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
for (u32 i=0; i<m_remoteTerminatedScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteTerminatedScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// returns true if the given player is a participant in the given script, either local or remote
|
||
|
bool CGameScriptHandlerMgr::IsPlayerAParticipant(const CGameScriptId& scriptId, const netPlayer& player)
|
||
|
{
|
||
|
scriptHandler* pHandler = GetScriptHandler(scriptId);
|
||
|
|
||
|
if (pHandler && pHandler->GetNetworkComponent() && pHandler->GetNetworkComponent()->IsPlayerAParticipant(player))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptId && m_remoteActiveScripts[i].IsPlayerAParticipant(player.GetPhysicalPlayerIndex()))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool CGameScriptHandlerMgr::IsNetworkHost(const CGameScriptId& scriptId)
|
||
|
{
|
||
|
bool isHost = false;
|
||
|
|
||
|
scriptHandler *handler = GetScriptHandler(scriptId);
|
||
|
scriptHandlerNetComponent* netComponent = handler ? handler->GetNetworkComponent() : NULL;
|
||
|
|
||
|
if (netComponent && netComponent->GetState() == scriptHandlerNetComponent::NETSCRIPT_PLAYING)
|
||
|
{
|
||
|
const netPlayer* pHost = netComponent->GetHost();
|
||
|
|
||
|
if (pHost && pHost->IsMyPlayer())
|
||
|
{
|
||
|
isHost = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return isHost;
|
||
|
}
|
||
|
|
||
|
u32 CGameScriptHandlerMgr::GetNumParticipantsOfScript(const CGameScriptId& scriptId)
|
||
|
{
|
||
|
u32 numParticipants = 0;
|
||
|
|
||
|
scriptHandler* pHandler = GetScriptHandler(scriptId);
|
||
|
|
||
|
if (pHandler && pHandler->GetNetworkComponent())
|
||
|
{
|
||
|
numParticipants = pHandler->GetNetworkComponent()->GetNumParticipants();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32 i = 0;
|
||
|
|
||
|
for (i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == scriptId)
|
||
|
{
|
||
|
numParticipants = m_remoteActiveScripts[i].GetNumParticipants();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Assertf(i<m_remoteActiveScripts.GetCount(), "GetNumParticipantsOfScript: Remote script not running");
|
||
|
}
|
||
|
|
||
|
return numParticipants;
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::RecalculateScriptId(CGameScriptHandler& handler)
|
||
|
{
|
||
|
if (!m_scriptHandlers.Delete(handler.GetScriptId().GetScriptIdHash()))
|
||
|
{
|
||
|
FatalAssertf(0, "CGameScriptHandlerMgr::RecalculateScriptId - failed to remove handler %s from map", handler.GetLogName());
|
||
|
}
|
||
|
#if __ASSERT
|
||
|
if (NetworkInterface::IsGameInProgress())
|
||
|
{
|
||
|
CGameScriptId scriptId(*handler.GetThread());
|
||
|
Assert(!GetScriptHandler(scriptId));
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
static_cast<CGameScriptId&>(handler.GetScriptId()).InitGameScriptId(*handler.GetThread());
|
||
|
|
||
|
#if !__NO_OUTPUT
|
||
|
scriptHandler** ppHandler = m_scriptHandlers.Access(handler.GetScriptId().GetScriptIdHash());
|
||
|
if (ppHandler)
|
||
|
{
|
||
|
char logNameOfNewHandler[200];
|
||
|
safecpy(logNameOfNewHandler, handler.GetLogName(), NELEM(logNameOfNewHandler)); // CGameScriptId::GetLogName() fills in a static string internally so I need to make a copy of one of the LogName's to display in the assert below
|
||
|
|
||
|
CGameScriptHandler *pGameScriptHandler = static_cast<CGameScriptHandler*>(*ppHandler);
|
||
|
|
||
|
Quitf("CGameScriptHandlerMgr::RecalculateScriptId - about to add %s(%p) script with hash %u. %s(%p) already exists in the map with this hash",
|
||
|
logNameOfNewHandler, &handler, handler.GetScriptId().GetScriptIdHash().GetHash(),
|
||
|
pGameScriptHandler->GetLogName(), pGameScriptHandler);
|
||
|
}
|
||
|
#endif // !__NO_OUTPUT
|
||
|
|
||
|
m_scriptHandlers.Insert(handler.GetScriptId().GetScriptIdHash(), &handler);
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::SetNotInMPCutscene()
|
||
|
{
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->RequiresANetworkComponent())
|
||
|
{
|
||
|
CGameScriptHandlerNetwork* netHandler = static_cast<CGameScriptHandlerNetwork*>(handler);
|
||
|
|
||
|
netHandler->SetInMPCutscene(false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::AddToReservationCount(CNetObjGame& scriptEntityObj)
|
||
|
{
|
||
|
if (!scriptEntityObj.IsLocalFlagSet(CNetObjGame::LOCALFLAG_COUNTED_BY_RESERVATIONS))
|
||
|
{
|
||
|
CEntity* pEntity = scriptEntityObj.GetEntity();
|
||
|
|
||
|
if (pEntity)
|
||
|
{
|
||
|
bool bPed = pEntity->GetIsTypePed();
|
||
|
bool bVeh = pEntity->GetIsTypeVehicle();
|
||
|
bool bObj = pEntity->GetIsTypeObject() && scriptEntityObj.GetObjectType() == NET_OBJ_TYPE_OBJECT; // ignore doors and pickups
|
||
|
|
||
|
if (bPed || bVeh || bObj)
|
||
|
{
|
||
|
CScriptEntityExtension* pExtension = pEntity->GetExtension<CScriptEntityExtension>();
|
||
|
|
||
|
const CGameScriptId* pScriptId = NULL;
|
||
|
|
||
|
if (pExtension)
|
||
|
{
|
||
|
pScriptId = static_cast<const CGameScriptId*>(&pExtension->GetScriptInfo()->GetScriptId());
|
||
|
}
|
||
|
|
||
|
if (pScriptId)
|
||
|
{
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == *pScriptId)
|
||
|
{
|
||
|
if (bPed)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].AddCreatedPed();
|
||
|
}
|
||
|
else if (bVeh)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].AddCreatedVehicle();
|
||
|
}
|
||
|
else if (bObj)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].AddCreatedObject();
|
||
|
}
|
||
|
|
||
|
scriptEntityObj.SetLocalFlag(CNetObjGame::LOCALFLAG_COUNTED_BY_RESERVATIONS, true);
|
||
|
|
||
|
netLoggingInterface* log = CTheScripts::GetScriptHandlerMgr().GetLog();
|
||
|
|
||
|
if (log)
|
||
|
{
|
||
|
NetworkLogUtils::WriteLogEvent(*log, "RESERVATION_ENTITY_ADDED", "%s %s", pScriptId->GetLogName(), scriptEntityObj.GetLogName());
|
||
|
LogCurrentReservations(*log);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::RemoveFromReservationCount(CNetObjGame& scriptEntityObj)
|
||
|
{
|
||
|
if (scriptEntityObj.IsLocalFlagSet(CNetObjGame::LOCALFLAG_COUNTED_BY_RESERVATIONS))
|
||
|
{
|
||
|
CEntity* pEntity = scriptEntityObj.GetEntity();
|
||
|
|
||
|
if (gnetVerifyf(pEntity, "Failed to remove reservation count for %s. Gameobject is missing", scriptEntityObj.GetLogName()))
|
||
|
{
|
||
|
bool bPed = pEntity->GetIsTypePed();
|
||
|
bool bVeh = pEntity->GetIsTypeVehicle();
|
||
|
bool bObj = pEntity->GetIsTypeObject() && scriptEntityObj.GetObjectType() == NET_OBJ_TYPE_OBJECT; // ignore doors and pickups
|
||
|
|
||
|
CScriptEntityExtension* pExtension = pEntity->GetExtension<CScriptEntityExtension>();
|
||
|
|
||
|
const CGameScriptId* pScriptId = NULL;
|
||
|
|
||
|
if (pExtension && pExtension->GetScriptInfo())
|
||
|
{
|
||
|
pScriptId = static_cast<const CGameScriptId*>(&pExtension->GetScriptInfo()->GetScriptId());
|
||
|
}
|
||
|
|
||
|
if (pScriptId)
|
||
|
{
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == *pScriptId)
|
||
|
{
|
||
|
if (bPed)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].RemoveCreatedPed();
|
||
|
}
|
||
|
else if (bVeh)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].RemoveCreatedVehicle();
|
||
|
}
|
||
|
else if (bObj)
|
||
|
{
|
||
|
m_remoteActiveScripts[i].RemoveCreatedObject();
|
||
|
}
|
||
|
|
||
|
scriptEntityObj.SetLocalFlag(CNetObjGame::LOCALFLAG_COUNTED_BY_RESERVATIONS, false);
|
||
|
|
||
|
netLoggingInterface* log = CTheScripts::GetScriptHandlerMgr().GetLog();
|
||
|
|
||
|
if (log)
|
||
|
{
|
||
|
NetworkLogUtils::WriteLogEvent(*log, "RESERVATION_ENTITY_REMOVED", "%s %s", pScriptId->GetLogName(), scriptEntityObj.GetLogName());
|
||
|
LogCurrentReservations(*log);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::GetRemoteScriptEntityReservations(u32& reservedPeds, u32& reservedVehicles, u32& reservedObjects, u32& createdPeds, u32& createdVehicles, u32& createdObjects, Vector3* pScopePosition) const
|
||
|
{
|
||
|
reservedPeds = 0;
|
||
|
reservedVehicles = 0;
|
||
|
reservedObjects = 0;
|
||
|
createdPeds = 0;
|
||
|
createdVehicles = 0;
|
||
|
createdObjects = 0;
|
||
|
|
||
|
PlayerFlags playersNearby = 0;
|
||
|
PlayerFlags playersNearbyInPedScope = 0;
|
||
|
PlayerFlags playersNearbyInVehScope = 0;
|
||
|
PlayerFlags playersNearbyInObjScope = 0;
|
||
|
|
||
|
bool playersNearbyCalculated = false;
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
const CRemoteScriptInfo* pInfo = &m_remoteActiveScripts[i];
|
||
|
|
||
|
if (!pInfo->GetRunningLocally())
|
||
|
{
|
||
|
u32 peds = 0;
|
||
|
u32 vehs = 0;
|
||
|
u32 objs = 0;
|
||
|
|
||
|
pInfo->GetReservations(peds, vehs, objs);
|
||
|
|
||
|
if (peds != 0 || vehs != 0 || objs != 0)
|
||
|
{
|
||
|
if (!playersNearbyCalculated)
|
||
|
{
|
||
|
NetworkInterface::GetObjectManager().GetPlayersNearbyInScope(playersNearbyInPedScope, playersNearbyInVehScope, playersNearbyInObjScope, pScopePosition);
|
||
|
|
||
|
playersNearby = playersNearbyInPedScope | playersNearbyInVehScope | playersNearbyInObjScope;
|
||
|
|
||
|
playersNearbyCalculated = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearby != 0)
|
||
|
{
|
||
|
bool bParticipantNearbyInPedScope = false;
|
||
|
bool bParticipantNearbyInVehScope = false;
|
||
|
bool bParticipantNearbyInObjScope = false;
|
||
|
|
||
|
for (u32 p=0; p<MAX_NUM_PHYSICAL_PLAYERS; p++)
|
||
|
{
|
||
|
u32 playerIndex = (1<<p);
|
||
|
|
||
|
if ((playersNearby & playerIndex) && (pInfo->GetActiveParticipants() & playerIndex))
|
||
|
{
|
||
|
Assert(playersNearbyCalculated);
|
||
|
|
||
|
if (playersNearbyInPedScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInPedScope = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearbyInVehScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInVehScope = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearbyInObjScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInObjScope = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bParticipantNearbyInPedScope == (peds != 0) &&
|
||
|
bParticipantNearbyInVehScope == (vehs != 0) &&
|
||
|
bParticipantNearbyInObjScope == (objs != 0))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bParticipantNearbyInPedScope)
|
||
|
{
|
||
|
reservedPeds += peds;
|
||
|
createdPeds += pInfo->GetCreatedPeds();
|
||
|
}
|
||
|
|
||
|
if (bParticipantNearbyInVehScope)
|
||
|
{
|
||
|
reservedVehicles += vehs;
|
||
|
createdVehicles += pInfo->GetCreatedVehicles();
|
||
|
}
|
||
|
|
||
|
if (bParticipantNearbyInObjScope)
|
||
|
{
|
||
|
reservedObjects += objs;
|
||
|
createdObjects += pInfo->GetCreatedObjects();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if ENABLE_NETWORK_LOGGING
|
||
|
void CGameScriptHandlerMgr::LogCurrentReservations(netLoggingInterface& log) const
|
||
|
{
|
||
|
u32 reservedPeds = 0;
|
||
|
u32 reservedVehs = 0;
|
||
|
u32 reservedObjs = 0;
|
||
|
|
||
|
bool bLogLocal = false;
|
||
|
bool bLogRemote = false;
|
||
|
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->RequiresANetworkComponent() && !handler->IsTerminated())
|
||
|
{
|
||
|
const CGameScriptHandlerNetwork* netHandler = static_cast<const CGameScriptHandlerNetwork*>(handler);
|
||
|
|
||
|
reservedPeds = netHandler->GetTotalNumReservedPeds();
|
||
|
reservedVehs = netHandler->GetTotalNumReservedVehicles();
|
||
|
reservedObjs = netHandler->GetTotalNumReservedObjects();
|
||
|
|
||
|
if (reservedPeds > 0 || reservedVehs > 0 || reservedObjs > 0)
|
||
|
{
|
||
|
if (!bLogLocal)
|
||
|
{
|
||
|
NetworkLogUtils::WriteLogEvent(log, "LOCAL_SCRIPT_RESERVATIONS", "");
|
||
|
bLogLocal = true;
|
||
|
}
|
||
|
|
||
|
log.WriteDataValue(netHandler->GetScriptId().GetLogName(), "%d/%d peds, %d/%d vehicles, %d/%d objects", netHandler->GetNumCreatedPeds(), reservedPeds, netHandler->GetNumCreatedVehicles(), reservedVehs, netHandler->GetNumCreatedObjects(), reservedObjs);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PlayerFlags playersNearby = 0;
|
||
|
PlayerFlags playersNearbyInPedScope = 0;
|
||
|
PlayerFlags playersNearbyInVehScope = 0;
|
||
|
PlayerFlags playersNearbyInObjScope = 0;
|
||
|
|
||
|
bool playersNearbyCalculated = false;
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
const CRemoteScriptInfo* pInfo = &m_remoteActiveScripts[i];
|
||
|
|
||
|
if (!pInfo->GetRunningLocally())
|
||
|
{
|
||
|
reservedPeds = 0;
|
||
|
reservedVehs = 0;
|
||
|
reservedObjs = 0;
|
||
|
|
||
|
pInfo->GetReservations(reservedPeds, reservedVehs, reservedObjs);
|
||
|
|
||
|
if (reservedPeds != 0 || reservedVehs != 0 || reservedObjs != 0)
|
||
|
{
|
||
|
if (!playersNearbyCalculated)
|
||
|
{
|
||
|
NetworkInterface::GetObjectManager().GetPlayersNearbyInScope(playersNearbyInPedScope, playersNearbyInVehScope, playersNearbyInObjScope);
|
||
|
|
||
|
playersNearby = playersNearbyInPedScope | playersNearbyInVehScope | playersNearbyInObjScope;
|
||
|
|
||
|
playersNearbyCalculated = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearby != 0)
|
||
|
{
|
||
|
bool bParticipantNearbyInPedScope = false;
|
||
|
bool bParticipantNearbyInVehScope = false;
|
||
|
bool bParticipantNearbyInObjScope = false;
|
||
|
|
||
|
for (u32 p=0; p<MAX_NUM_PHYSICAL_PLAYERS; p++)
|
||
|
{
|
||
|
u32 playerIndex = (1<<p);
|
||
|
|
||
|
if ((playersNearby & playerIndex) && (pInfo->GetActiveParticipants() & playerIndex))
|
||
|
{
|
||
|
Assert(playersNearbyCalculated);
|
||
|
|
||
|
if (playersNearbyInPedScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInPedScope = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearbyInVehScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInVehScope = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearbyInObjScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInObjScope = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!bParticipantNearbyInPedScope)
|
||
|
{
|
||
|
reservedPeds = 0;
|
||
|
}
|
||
|
|
||
|
if (!bParticipantNearbyInVehScope)
|
||
|
{
|
||
|
reservedVehs = 0;
|
||
|
}
|
||
|
|
||
|
if (!bParticipantNearbyInObjScope)
|
||
|
{
|
||
|
reservedObjs = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (reservedPeds>0 || reservedVehs>0 || reservedObjs>0)
|
||
|
{
|
||
|
if (!bLogRemote)
|
||
|
{
|
||
|
NetworkLogUtils::WriteLogEvent(log, "REMOTE_SCRIPT_RESERVATIONS", "");
|
||
|
bLogRemote = true;
|
||
|
}
|
||
|
|
||
|
log.WriteDataValue(m_remoteActiveScripts[i].GetScriptId().GetLogName(), "%d/%d peds, %d/%d vehicles, %d/%d objects", pInfo->GetCreatedPeds(), reservedPeds, pInfo->GetCreatedVehicles(), reservedVehs, pInfo->GetCreatedObjects(), reservedObjs);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
void CGameScriptHandlerMgr::LogCurrentReservations(netLoggingInterface&) const
|
||
|
{
|
||
|
}
|
||
|
#endif // ENABLE_NETWORK_LOGGING
|
||
|
|
||
|
#if __BANK
|
||
|
|
||
|
void CGameScriptHandlerMgr::DisplayScriptHandlerInfo() const
|
||
|
{
|
||
|
if (ms_DisplayHandlerInfo)
|
||
|
{
|
||
|
const CGameScriptHandler* handler = GetScriptHandlerFromComboName(ms_Handlers[ms_HandlerComboIndex]);
|
||
|
|
||
|
if (handler)
|
||
|
{
|
||
|
handler->DisplayScriptHandlerInfo();
|
||
|
|
||
|
grcDebugDraw::AddDebugOutput("");
|
||
|
grcDebugDraw::AddDebugOutput("");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ms_DisplayAllMPHandlers && NetworkInterface::GetLocalPlayer())
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("");
|
||
|
grcDebugDraw::AddDebugOutput("Local net array data: %u (Cached value: %u)", NetworkInterface::GetArrayManager().GetSizeOfLocallyArbitratedArrayData(), NetworkInterface::GetLocalPlayer()->GetSizeOfNetArrayData());
|
||
|
grcDebugDraw::AddDebugOutput("");
|
||
|
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
scriptHandler* handler = entry.GetData();
|
||
|
|
||
|
if (handler && handler->GetNetworkComponent())
|
||
|
{
|
||
|
char name[80];
|
||
|
|
||
|
sprintf(name, "%-80s", handler->GetLogName());
|
||
|
|
||
|
u32 size = handler->GetNetworkComponent()->GetSizeOfHostBroadcastData();
|
||
|
|
||
|
if (handler->GetNetworkComponent()->IsHostMigrating())
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s (Size: %u. Host: ** migrating to %s **)", name, size, handler->GetNetworkComponent()->GetPendingHost()->IsLocal() ? "us" : handler->GetNetworkComponent()->GetPendingHost()->GetLogName());
|
||
|
}
|
||
|
else if (!handler->GetNetworkComponent()->GetHost())
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s (Size: %u. Host: --none--)", name, size);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (handler->GetNetworkComponent()->GetHost()->IsLocal())
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s (Size: %u. Host: us)", name, size);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s (Size: %u. Host: %s)", name, size, handler->GetNetworkComponent()->GetHost()->GetLogName());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
grcDebugDraw::AddDebugOutput("");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::DisplayObjectAndResourceInfo() const
|
||
|
{
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler)
|
||
|
{
|
||
|
handler->DisplayObjectAndResourceInfo();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::DisplayReservationInfo() const
|
||
|
{
|
||
|
u32 reservedPeds = 0;
|
||
|
u32 reservedVehs = 0;
|
||
|
u32 reservedObjs = 0;
|
||
|
|
||
|
grcDebugDraw::AddDebugOutput("-- LOCAL SCRIPTS --");
|
||
|
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->RequiresANetworkComponent() && !handler->IsTerminated())
|
||
|
{
|
||
|
const CGameScriptHandlerNetwork* netHandler = static_cast<const CGameScriptHandlerNetwork*>(handler);
|
||
|
|
||
|
reservedPeds = netHandler->GetTotalNumReservedPeds();
|
||
|
reservedVehs = netHandler->GetTotalNumReservedVehicles();
|
||
|
reservedObjs = netHandler->GetTotalNumReservedObjects();
|
||
|
|
||
|
if (reservedPeds > 0 || reservedVehs > 0 || reservedObjs > 0)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s: %d/%d peds, %d/%d vehicles, %d/%d objects", netHandler->GetScriptName(), netHandler->GetNumCreatedPeds(), reservedPeds, netHandler->GetNumCreatedVehicles(), reservedVehs, netHandler->GetNumCreatedObjects(), reservedObjs);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
grcDebugDraw::AddDebugOutput("-- REMOTE SCRIPTS --");
|
||
|
|
||
|
PlayerFlags playersNearby = 0;
|
||
|
PlayerFlags playersNearbyInPedScope = 0;
|
||
|
PlayerFlags playersNearbyInVehScope = 0;
|
||
|
PlayerFlags playersNearbyInObjScope = 0;
|
||
|
|
||
|
bool playersNearbyCalculated = false;
|
||
|
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
const CRemoteScriptInfo* pInfo = &m_remoteActiveScripts[i];
|
||
|
|
||
|
if (!pInfo->GetRunningLocally())
|
||
|
{
|
||
|
reservedPeds = 0;
|
||
|
reservedVehs = 0;
|
||
|
reservedObjs = 0;
|
||
|
|
||
|
pInfo->GetReservations(reservedPeds, reservedVehs, reservedObjs);
|
||
|
|
||
|
if (reservedPeds != 0 || reservedVehs != 0 || reservedObjs != 0)
|
||
|
{
|
||
|
if (!playersNearbyCalculated)
|
||
|
{
|
||
|
NetworkInterface::GetObjectManager().GetPlayersNearbyInScope(playersNearbyInPedScope, playersNearbyInVehScope, playersNearbyInObjScope);
|
||
|
|
||
|
playersNearby = playersNearbyInPedScope | playersNearbyInVehScope | playersNearbyInObjScope;
|
||
|
|
||
|
playersNearbyCalculated = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearby != 0)
|
||
|
{
|
||
|
bool bParticipantNearbyInPedScope = false;
|
||
|
bool bParticipantNearbyInVehScope = false;
|
||
|
bool bParticipantNearbyInObjScope = false;
|
||
|
|
||
|
for (u32 p=0; p<MAX_NUM_PHYSICAL_PLAYERS; p++)
|
||
|
{
|
||
|
u32 playerIndex = (1<<p);
|
||
|
|
||
|
if ((playersNearby & playerIndex) && (pInfo->GetActiveParticipants() & playerIndex))
|
||
|
{
|
||
|
Assert(playersNearbyCalculated);
|
||
|
|
||
|
if (playersNearbyInPedScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInPedScope = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearbyInVehScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInVehScope = true;
|
||
|
}
|
||
|
|
||
|
if (playersNearbyInObjScope & playerIndex)
|
||
|
{
|
||
|
bParticipantNearbyInObjScope = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!bParticipantNearbyInPedScope)
|
||
|
{
|
||
|
reservedPeds = 0;
|
||
|
}
|
||
|
|
||
|
if (!bParticipantNearbyInVehScope)
|
||
|
{
|
||
|
reservedVehs = 0;
|
||
|
}
|
||
|
|
||
|
if (!bParticipantNearbyInObjScope)
|
||
|
{
|
||
|
reservedObjs = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (reservedPeds>0 || reservedVehs>0 || reservedObjs>0)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s: %d/%d peds, %d/%d vehicles, %d/%d objects", pInfo->GetScriptId().GetScriptName(), pInfo->GetCreatedPeds(), reservedPeds, pInfo->GetCreatedVehicles(), reservedVehs, pInfo->GetCreatedObjects(), reservedObjs);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // __BANK
|
||
|
|
||
|
|
||
|
#if __SCRIPT_MEM_CALC
|
||
|
void CGameScriptHandlerMgr::CalculateMemoryUsage()
|
||
|
{
|
||
|
const strIndex* ignoreList = NULL;
|
||
|
s32 numIgnores = 0;
|
||
|
|
||
|
GetResourceIgnoreList(&ignoreList, numIgnores);
|
||
|
|
||
|
m_TotalScriptVirtualMemory = 0;
|
||
|
m_TotalScriptPhysicalMemory = 0;
|
||
|
|
||
|
u32 TotalVirtualForResourcesWithoutStreamingIndex = 0;
|
||
|
u32 TotalPhysicalForResourcesWithoutStreamingIndex = 0;
|
||
|
|
||
|
const int maxLoadedInt = strStreamingEngine::GetInfo().GetLoadedInfoMap()->GetNumSlots() + strStreamingEngine::GetInfo().GetLoadedPersistentInfoMap()->GetNumSlots()
|
||
|
+ strStreamingEngine::GetInfo().GetRequestInfoMap()->GetNumSlots() + strStreamingEngine::GetInfo().GetLoadingInfoMap().GetNumSlots();
|
||
|
|
||
|
// Fixes B* 2175673
|
||
|
const int maxLoadedCount = CStreamVolumeMgr::GetStreamingIndicesCount();
|
||
|
const u16 maxLoaded = (u16) Min(maxLoadedInt + maxLoadedCount, 0xffff);
|
||
|
|
||
|
strIndex *streamingIndicesForAllScriptsBackingStore = Alloca(strIndex, maxLoaded);
|
||
|
atUserArray<strIndex> streamingIndicesForAllScripts(streamingIndicesForAllScriptsBackingStore, maxLoaded);
|
||
|
|
||
|
strIndex *streamingIndicesForThisScriptBackingStore = Alloca(strIndex, maxLoaded);
|
||
|
atUserArray<strIndex> streamingIndicesForThisScript(streamingIndicesForThisScriptBackingStore, maxLoaded);
|
||
|
|
||
|
u32 ScriptThreadId = 0;
|
||
|
|
||
|
|
||
|
bool bDisplayScriptDetails = true;
|
||
|
bool bFilterScriptObjectDisplay = false;
|
||
|
bool bExcludeScripts = false;
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
bDisplayScriptDetails = CScriptDebug::GetDisplayDetailedScriptMemoryUsage();
|
||
|
bFilterScriptObjectDisplay = CScriptDebug::GetDisplayDetailedScriptMemoryUsageFiltered();
|
||
|
bExcludeScripts = CScriptDebug::GetExcludeScriptFromScriptMemoryUsage();
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (!handler) continue;
|
||
|
|
||
|
streamingIndicesForThisScript.Resize(0);
|
||
|
|
||
|
u32 VirtualForResourcesWithoutStreamingIndexInThisScript = 0;
|
||
|
u32 PhysicalForResourcesWithoutStreamingIndexInThisScript = 0;
|
||
|
|
||
|
ClearMemoryDebugInfoForMovieMeshes(true);
|
||
|
|
||
|
handler->CalculateMemoryUsage(streamingIndicesForThisScript, ignoreList, numIgnores,
|
||
|
VirtualForResourcesWithoutStreamingIndexInThisScript, PhysicalForResourcesWithoutStreamingIndexInThisScript,
|
||
|
bDisplayScriptDetails, bFilterScriptObjectDisplay, 0); //STRFLAG_DONTDELETE);
|
||
|
|
||
|
CalculateMemoryUsageForMovieMeshes(handler, VirtualForResourcesWithoutStreamingIndexInThisScript, PhysicalForResourcesWithoutStreamingIndexInThisScript, bDisplayScriptDetails);
|
||
|
|
||
|
ScriptThreadId = 0;
|
||
|
if (handler->GetThread())
|
||
|
{
|
||
|
ScriptThreadId = (u32) handler->GetThread()->GetThreadId();
|
||
|
}
|
||
|
|
||
|
if (ScriptThreadId != 0)
|
||
|
{
|
||
|
if (CStreamVolumeMgr::IsThereAVolumeOwnedBy((scrThreadId) ScriptThreadId))
|
||
|
{
|
||
|
CStreamVolumeMgr::GetStreamingIndices(streamingIndicesForThisScript);
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
atArray<strIndex> streamingIndicesForStreamingVolume;
|
||
|
CStreamVolumeMgr::GetStreamingIndices(streamingIndicesForStreamingVolume);
|
||
|
|
||
|
u32 VirtualMemForVolume = 0;
|
||
|
u32 PhysicalMemForVolume = 0;
|
||
|
strStreamingEngine::GetInfo().GetObjectAndDependenciesSizes(streamingIndicesForStreamingVolume, VirtualMemForVolume, PhysicalMemForVolume, NULL, 0, true);
|
||
|
grcDebugDraw::AddDebugOutput("%s(%u) Stream Volume %dK %dK", handler->GetScriptName(), ScriptThreadId, VirtualMemForVolume>>10, PhysicalMemForVolume>>10);
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Display the memory used by render targets for normal Bink movies (not mesh sets)
|
||
|
CalculateMemoryUsageForNamedRenderTargets(handler,
|
||
|
VirtualForResourcesWithoutStreamingIndexInThisScript, PhysicalForResourcesWithoutStreamingIndexInThisScript,
|
||
|
bDisplayScriptDetails);
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (CScriptDebug::GetDisplayScriptMemoryUsage())
|
||
|
{
|
||
|
u32 VirtualMemForThisScript = 0;
|
||
|
u32 PhysicalMemForThisScript = 0;
|
||
|
strStreamingEngine::GetInfo().GetObjectAndDependenciesSizes(streamingIndicesForThisScript,
|
||
|
VirtualMemForThisScript, PhysicalMemForThisScript, ignoreList, numIgnores, true);
|
||
|
|
||
|
VirtualMemForThisScript += VirtualForResourcesWithoutStreamingIndexInThisScript;
|
||
|
PhysicalMemForThisScript += PhysicalForResourcesWithoutStreamingIndexInThisScript;
|
||
|
|
||
|
if (VirtualMemForThisScript > 0 || PhysicalMemForThisScript > 0)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%u) Virtual %dK Physical %dK (for all resources, including deps)",
|
||
|
handler->GetScriptName(), ScriptThreadId,
|
||
|
VirtualMemForThisScript>>10, PhysicalMemForThisScript>>10);
|
||
|
}
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
|
||
|
// Add all entries from streamingIndicesForThisScript to streamingIndicesForAllScripts
|
||
|
// Should I remove duplicates at this stage?
|
||
|
s32 indexCount = streamingIndicesForThisScript.GetCount();
|
||
|
for (s32 i=0; i<indexCount; i++)
|
||
|
{
|
||
|
streamingIndicesForAllScripts.Append() = streamingIndicesForThisScript[i];
|
||
|
}
|
||
|
|
||
|
TotalVirtualForResourcesWithoutStreamingIndex += VirtualForResourcesWithoutStreamingIndexInThisScript;
|
||
|
TotalPhysicalForResourcesWithoutStreamingIndex += PhysicalForResourcesWithoutStreamingIndexInThisScript;
|
||
|
}
|
||
|
|
||
|
strStreamingEngine::GetInfo().GetObjectAndDependenciesSizes(streamingIndicesForAllScripts,
|
||
|
m_TotalScriptVirtualMemory, m_TotalScriptPhysicalMemory, ignoreList, numIgnores, true);
|
||
|
|
||
|
m_TotalScriptVirtualMemory += TotalVirtualForResourcesWithoutStreamingIndex;
|
||
|
m_TotalScriptPhysicalMemory += TotalPhysicalForResourcesWithoutStreamingIndex;
|
||
|
|
||
|
//looks for all the path nodes loaded for scripts
|
||
|
u32 nTotalPathNodeVirtualMemory = 0;
|
||
|
u32 nTotalPathNodePhysicalMemory = 0;
|
||
|
ThePaths.CountScriptMemoryUsage(nTotalPathNodeVirtualMemory, nTotalPathNodePhysicalMemory);
|
||
|
m_TotalScriptVirtualMemory += nTotalPathNodeVirtualMemory;
|
||
|
m_TotalScriptPhysicalMemory += nTotalPathNodePhysicalMemory;
|
||
|
|
||
|
//looks for all the navmeshes loaded for scripts
|
||
|
u32 nTotalNavmeshVirtualMemory = 0;
|
||
|
u32 nTotalNavmeshPhysicalMemory = 0;
|
||
|
CPathServer::CountScriptMemoryUsage(nTotalNavmeshVirtualMemory, nTotalNavmeshPhysicalMemory);
|
||
|
m_TotalScriptVirtualMemory += nTotalNavmeshVirtualMemory;
|
||
|
m_TotalScriptPhysicalMemory += nTotalNavmeshPhysicalMemory;
|
||
|
|
||
|
//looks for all the loaded scripts
|
||
|
if(!bExcludeScripts)
|
||
|
{
|
||
|
u32 nTotalScriptVirtualMemory = 0;
|
||
|
u32 nTotalScriptPhysicalMemory = 0;
|
||
|
g_StreamedScripts.CalculateMemoryUsage(nTotalScriptVirtualMemory, nTotalScriptPhysicalMemory, bDisplayScriptDetails);
|
||
|
m_TotalScriptVirtualMemory += nTotalScriptVirtualMemory;
|
||
|
m_TotalScriptPhysicalMemory += nTotalScriptPhysicalMemory;
|
||
|
}
|
||
|
|
||
|
if (m_TotalScriptVirtualMemory > m_TotalScriptVirtualMemoryPeak)
|
||
|
{
|
||
|
m_TotalScriptVirtualMemoryPeak = m_TotalScriptVirtualMemory;
|
||
|
if (PARAM_scriptLogMemoryPeaks.Get())
|
||
|
Displayf("CGameScriptHandlerMgr : [SCRIPT][MEM_PEAK] : Virtual : %s : %10dK", NetworkInterface::IsInFreeMode() ? "MP" : "SP", m_TotalScriptVirtualMemoryPeak>>10);
|
||
|
}
|
||
|
if (m_TotalScriptPhysicalMemory > m_TotalScriptPhysicalMemoryPeak)
|
||
|
{
|
||
|
m_TotalScriptPhysicalMemoryPeak = m_TotalScriptPhysicalMemory;
|
||
|
if (PARAM_scriptLogMemoryPeaks.Get())
|
||
|
Displayf("CGameScriptHandlerMgr : [SCRIPT][MEM_PEAK] : Physical : %s : %10dK", NetworkInterface::IsInFreeMode() ? "MP" : "SP", m_TotalScriptPhysicalMemoryPeak>>10);
|
||
|
}
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (CScriptDebug::GetDisplayScriptMemoryUsage())
|
||
|
{
|
||
|
if (nTotalPathNodeVirtualMemory > 0 || nTotalPathNodePhysicalMemory > 0)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%d) Virtual %dK Physical %dK",
|
||
|
"Script Path Nodes", -1,
|
||
|
nTotalPathNodeVirtualMemory>>10, nTotalPathNodePhysicalMemory>>10);
|
||
|
}
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
|
||
|
// periodically do a test to see if the script streaming memory has exceeded its limit
|
||
|
if (m_streamingMemTestTimer.GetMsTime() > static_cast<float>(STREAMING_MEM_CHECK_TIME))
|
||
|
{
|
||
|
#if __FINAL
|
||
|
size_t virtualLimit = VIRTUAL_STREAMING_MEMORY_LIMIT;
|
||
|
size_t physicalLimit = PHYSICAL_STREAMING_MEMORY_LIMIT;
|
||
|
#else
|
||
|
size_t virtualLimit = VIRTUAL_STREAMING_MEMORY_LIMIT_DBG;
|
||
|
size_t physicalLimit = PHYSICAL_STREAMING_MEMORY_LIMIT_DBG;
|
||
|
const char *overrideScriptRpfName = NULL;
|
||
|
PARAM_override_script.Get(overrideScriptRpfName);
|
||
|
if(overrideScriptRpfName && !stricmp(overrideScriptRpfName, "script_rel"))
|
||
|
{
|
||
|
virtualLimit = VIRTUAL_STREAMING_MEMORY_LIMIT;
|
||
|
physicalLimit = PHYSICAL_STREAMING_MEMORY_LIMIT;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (NetworkInterface::IsInFreeMode() && !CPauseMenu::GetCurrenMissionActive() && !NetworkInterface::IsInSpectatorMode())
|
||
|
{
|
||
|
virtualLimit = VIRTUAL_STREAMING_FREEMODE_MEMORY_LIMIT;
|
||
|
physicalLimit = PHYSICAL_STREAMING_FREEMODE_MEMORY_LIMIT;
|
||
|
}
|
||
|
|
||
|
#if !ONE_STREAMING_HEAP
|
||
|
if (((m_TotalScriptVirtualMemory>>10) > virtualLimit) || ((m_TotalScriptPhysicalMemory>>10) > physicalLimit))
|
||
|
#else
|
||
|
if (((m_TotalScriptVirtualMemory>>10) + (m_TotalScriptPhysicalMemory>>10)) > virtualLimit +physicalLimit)
|
||
|
#endif
|
||
|
{
|
||
|
m_lastStreamingEmergencyTimer.Reset();
|
||
|
}
|
||
|
|
||
|
// check if streaming is trying to request too much data at once
|
||
|
CPlayerInfo *pPlayerInfo = CGameWorld::GetMainPlayerInfo();
|
||
|
if (pPlayerInfo && !pPlayerInfo->AreControlsDisabled())
|
||
|
{
|
||
|
bool emergencyHit = false;
|
||
|
s32 indexCount = streamingIndicesForAllScripts.GetCount();
|
||
|
for (s32 i = 0; i < indexCount; ++i)
|
||
|
{
|
||
|
const strStreamingInfo& info = strStreamingEngine::GetInfo().GetStreamingInfoRef(streamingIndicesForAllScripts[i]);
|
||
|
if (info.GetStatus() != STRINFO_LOADING && info.GetStatus() != STRINFO_LOADREQUESTED)
|
||
|
{
|
||
|
streamingIndicesForAllScripts[i] = strIndex(strIndex::INVALID_INDEX);
|
||
|
}
|
||
|
}
|
||
|
u32 virt = 0;
|
||
|
u32 phys = 0;
|
||
|
strStreamingEngine::GetInfo().GetObjectAndDependenciesSizes(streamingIndicesForAllScripts, virt, phys, ignoreList, numIgnores, true);
|
||
|
if ((virt + phys) >> 10 > TOTAL_STREAMING_REQUEST_TOTAL_LIMIT)
|
||
|
{
|
||
|
m_lastStreamingReqEmergencyTimer.Reset();
|
||
|
emergencyHit = true;
|
||
|
}
|
||
|
|
||
|
// check priority requests only
|
||
|
if (!emergencyHit)
|
||
|
{
|
||
|
for (s32 i = 0; i < indexCount; ++i)
|
||
|
{
|
||
|
if (streamingIndicesForAllScripts[i] == strIndex(strIndex::INVALID_INDEX))
|
||
|
continue;
|
||
|
|
||
|
const strStreamingInfo& info = strStreamingEngine::GetInfo().GetStreamingInfoRef(streamingIndicesForAllScripts[i]);
|
||
|
if ((info.GetFlags() & STRFLAG_PRIORITY_LOAD) == 0)
|
||
|
{
|
||
|
streamingIndicesForAllScripts[i] = strIndex(strIndex::INVALID_INDEX);
|
||
|
}
|
||
|
}
|
||
|
u32 virt = 0;
|
||
|
u32 phys = 0;
|
||
|
strStreamingEngine::GetInfo().GetObjectAndDependenciesSizes(streamingIndicesForAllScripts, virt, phys, ignoreList, numIgnores, true);
|
||
|
if ((virt + phys) >> 10 > TOTAL_STREAMING_REQUEST_PRIO_LIMIT)
|
||
|
{
|
||
|
m_lastStreamingReqEmergencyTimer.Reset();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_streamingMemTestTimer.Reset();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::ClearMemoryDebugInfoForMovieMeshes(bool bTrackMemoryForMovieMeshes) const
|
||
|
{
|
||
|
m_bTrackMemoryForMovieMeshes = bTrackMemoryForMovieMeshes;
|
||
|
m_ArrayOfModelsUsedByMovieMeshes.Reset();
|
||
|
m_MapOfMoviesUsedByMovieMeshes.Reset();
|
||
|
m_MapOfRenderTargetsUsedByMovieMeshes.Reset();
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::CalculateMemoryUsageForMovieMeshes(const CGameScriptHandler* SCRIPT_MEM_DISPLAY_ONLY(pScriptHandler), u32 &VirtualTotal, u32 &PhysicalTotal, bool SCRIPT_MEM_DISPLAY_ONLY(bDisplayScriptDetails)) const
|
||
|
{
|
||
|
// Models
|
||
|
u32 NumberOfModels = m_ArrayOfModelsUsedByMovieMeshes.GetCount();
|
||
|
if (NumberOfModels > 0)
|
||
|
{
|
||
|
s32 totalPhysicalMemory = 0;
|
||
|
s32 totalVirtualMemory = 0;
|
||
|
s32 drawablePhysicalMemory = 0;
|
||
|
s32 drawableVirtualMemory = 0;
|
||
|
s32 texturePhysicalMemory = 0;
|
||
|
s32 textureVirtualMemory = 0;
|
||
|
s32 boundsPhysicalMemory = 0;
|
||
|
s32 boundsVirtualMemory = 0;
|
||
|
|
||
|
CStreamingDebug::GetMemoryStatsByAllocation(m_ArrayOfModelsUsedByMovieMeshes, totalPhysicalMemory, totalVirtualMemory, drawablePhysicalMemory, drawableVirtualMemory,
|
||
|
texturePhysicalMemory, textureVirtualMemory, boundsPhysicalMemory, boundsVirtualMemory);
|
||
|
|
||
|
VirtualTotal += totalVirtualMemory;
|
||
|
PhysicalTotal += totalPhysicalMemory;
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%d) Total For %u Models in Mesh Sets : Virtual %dK Physical %dK",
|
||
|
pScriptHandler->GetScriptName(), pScriptHandler->GetThread()->GetThreadId(),
|
||
|
NumberOfModels,
|
||
|
totalVirtualMemory>>10, totalPhysicalMemory>>10);
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
}
|
||
|
|
||
|
// Movies
|
||
|
u32 virtualSize = 0;
|
||
|
u32 physicalSize = 0;
|
||
|
|
||
|
u32 NumberOfMovies = m_MapOfMoviesUsedByMovieMeshes.GetNumUsed();
|
||
|
if (NumberOfMovies > 0)
|
||
|
{
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%d) Movies used in Mesh Sets",
|
||
|
pScriptHandler->GetScriptName(), pScriptHandler->GetThread()->GetThreadId());
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
|
||
|
atMap<u32,u32>::Iterator MovieMapIterator = m_MapOfMoviesUsedByMovieMeshes.CreateIterator();
|
||
|
while (!MovieMapIterator.AtEnd())
|
||
|
{
|
||
|
u32 movieHandle = MovieMapIterator.GetKey();
|
||
|
|
||
|
// Is there a way to get the name of the movie from its handle?
|
||
|
|
||
|
u32 virtSizeForThisMovie = g_movieMgr.GetMemoryUsage(movieHandle);
|
||
|
virtualSize += virtSizeForThisMovie;
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("Movie Handle=%u: used %d times : Virtual %dK",
|
||
|
movieHandle, MovieMapIterator.GetData(),
|
||
|
virtSizeForThisMovie>>10);
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
|
||
|
MovieMapIterator.Next();
|
||
|
}
|
||
|
|
||
|
VirtualTotal += virtualSize;
|
||
|
PhysicalTotal += physicalSize;
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%d) Total For Movies in Mesh Sets : Virtual %dK",
|
||
|
pScriptHandler->GetScriptName(), pScriptHandler->GetThread()->GetThreadId(),
|
||
|
virtualSize>>10);
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
}
|
||
|
|
||
|
// Render Targets
|
||
|
virtualSize = 0;
|
||
|
physicalSize = 0;
|
||
|
|
||
|
u32 NumberOfRenderTargets = m_MapOfRenderTargetsUsedByMovieMeshes.GetNumUsed();
|
||
|
if (NumberOfRenderTargets > 0)
|
||
|
{
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%d) Render Targets used in Mesh Sets",
|
||
|
pScriptHandler->GetScriptName(), pScriptHandler->GetThread()->GetThreadId());
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
|
||
|
atMap<CRenderTargetMgr::namedRendertarget*, u32>::Iterator RenderTargetIterator = m_MapOfRenderTargetsUsedByMovieMeshes.CreateIterator();
|
||
|
while (!RenderTargetIterator.AtEnd())
|
||
|
{
|
||
|
CRenderTargetMgr::namedRendertarget *pRenderTarget = RenderTargetIterator.GetKey();
|
||
|
|
||
|
if (pRenderTarget)
|
||
|
{
|
||
|
u32 SizeForThisMovie = pRenderTarget->GetMemoryUsage();
|
||
|
physicalSize += SizeForThisMovie;
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("Render Target=%x: used %d times : Physical %dK",
|
||
|
pRenderTarget, RenderTargetIterator.GetData(),
|
||
|
SizeForThisMovie>>10);
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
}
|
||
|
|
||
|
RenderTargetIterator.Next();
|
||
|
}
|
||
|
|
||
|
VirtualTotal += virtualSize;
|
||
|
PhysicalTotal += physicalSize;
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails)
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%d) Total For RenderTargets in Mesh Sets : Physical %dK",
|
||
|
pScriptHandler->GetScriptName(), pScriptHandler->GetThread()->GetThreadId(),
|
||
|
physicalSize>>10);
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
}
|
||
|
|
||
|
ClearMemoryDebugInfoForMovieMeshes(false);
|
||
|
}
|
||
|
|
||
|
// Display the memory used by render targets for normal Bink movies (not mesh sets)
|
||
|
void CGameScriptHandlerMgr::CalculateMemoryUsageForNamedRenderTargets(const CGameScriptHandler* pScriptHandler, u32& UNUSED_PARAM(virtualMemory), u32 &physicalMemory, bool SCRIPT_MEM_DISPLAY_ONLY(bDisplayScriptDetails)) const
|
||
|
{
|
||
|
if (pScriptHandler->GetThread())
|
||
|
{
|
||
|
u32 physicalMemoryForThisThread = gRenderTargetMgr.GetMemoryUsageForNamedRenderTargets(pScriptHandler->GetThread()->GetThreadId());
|
||
|
physicalMemory += physicalMemoryForThisThread;
|
||
|
|
||
|
#if __SCRIPT_MEM_DISPLAY
|
||
|
if (bDisplayScriptDetails && (physicalMemoryForThisThread > 0))
|
||
|
{
|
||
|
grcDebugDraw::AddDebugOutput("%s(%d) Total For RenderTargets in Movies (excluding movies used by mesh sets) : Physical %dK",
|
||
|
pScriptHandler->GetScriptName(), pScriptHandler->GetThread()->GetThreadId(),
|
||
|
physicalMemoryForThisThread>>10);
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_DISPLAY
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::AddToModelsUsedByMovieMeshes(u32 ModelIndex)
|
||
|
{
|
||
|
if (m_bTrackMemoryForMovieMeshes)
|
||
|
{
|
||
|
m_ArrayOfModelsUsedByMovieMeshes.PushAndGrow(ModelIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::AddToMoviesUsedByMovieMeshes(u32 MovieHandle)
|
||
|
{
|
||
|
if (m_bTrackMemoryForMovieMeshes)
|
||
|
{
|
||
|
u32 *pNumberOfTimesUsed = m_MapOfMoviesUsedByMovieMeshes.Access(MovieHandle);
|
||
|
if (pNumberOfTimesUsed)
|
||
|
{
|
||
|
m_MapOfMoviesUsedByMovieMeshes[MovieHandle] = 1 + *pNumberOfTimesUsed;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_MapOfMoviesUsedByMovieMeshes.Insert(MovieHandle, 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::AddToRenderTargetsUsedByMovieMeshes(CRenderTargetMgr::namedRendertarget *pNamedRenderTarget)
|
||
|
{
|
||
|
if (m_bTrackMemoryForMovieMeshes)
|
||
|
{
|
||
|
u32 *pNumberOfTimesUsed = m_MapOfRenderTargetsUsedByMovieMeshes.Access(pNamedRenderTarget);
|
||
|
if (pNumberOfTimesUsed)
|
||
|
{
|
||
|
m_MapOfRenderTargetsUsedByMovieMeshes[pNamedRenderTarget] = 1 + *pNumberOfTimesUsed;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_MapOfRenderTargetsUsedByMovieMeshes.Insert(pNamedRenderTarget, 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif // __SCRIPT_MEM_CALC
|
||
|
|
||
|
#if __BANK
|
||
|
|
||
|
void CGameScriptHandlerMgr::GetScriptDependencyList(atArray<strIndex> &theArray)
|
||
|
{
|
||
|
atArray<strIndex> localIndices;
|
||
|
|
||
|
const strIndex* ignoreList = NULL;
|
||
|
s32 numIgnores = 0;
|
||
|
|
||
|
GetResourceIgnoreList(&ignoreList, numIgnores);
|
||
|
|
||
|
// ignore vehicle resident texture dictionaries. Not sure why (copied from old mission cleanup code)
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler)
|
||
|
{
|
||
|
handler->GetStreamingIndices(localIndices, STRFLAG_DONTDELETE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(int i=0;i<localIndices.size();i++)
|
||
|
{
|
||
|
strStreamingEngine::GetInfo().GetObjectAndDependencies(localIndices[i], theArray, ignoreList, numIgnores);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::UpdateScriptHandlerCombo()
|
||
|
{
|
||
|
#if __DEV
|
||
|
if (ms_pHandlerCombo)
|
||
|
{
|
||
|
ms_NumHandlers = 0;
|
||
|
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->GetScriptName() && AssertVerify(ms_NumHandlers<CGameScriptHandler::MAX_NUM_SCRIPT_HANDLERS))
|
||
|
{
|
||
|
ms_Handlers[ms_NumHandlers++] = handler->GetScriptName();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ms_NumHandlers == 0)
|
||
|
{
|
||
|
ms_Handlers[0] = "-- none --";
|
||
|
ms_NumHandlers = 1;
|
||
|
}
|
||
|
|
||
|
ms_pHandlerCombo->UpdateCombo("Script Handlers", &ms_HandlerComboIndex, ms_NumHandlers, (const char **)ms_Handlers);
|
||
|
}
|
||
|
#endif // __DEV
|
||
|
}
|
||
|
|
||
|
const CGameScriptHandler* CGameScriptHandlerMgr::GetScriptHandlerFromComboName(const char* scriptName) const
|
||
|
{
|
||
|
scriptHandlerMap::ConstIterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->GetScriptName() && !strcmp(handler->GetScriptName(), scriptName))
|
||
|
{
|
||
|
return handler;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
CGameScriptHandler* CGameScriptHandlerMgr::GetScriptHandlerFromComboName(const char* scriptName)
|
||
|
{
|
||
|
scriptHandlerMap::Iterator entry = m_scriptHandlers.CreateIterator();
|
||
|
|
||
|
for (entry.Start(); !entry.AtEnd(); entry.Next())
|
||
|
{
|
||
|
CGameScriptHandler* handler = static_cast<CGameScriptHandler*>(entry.GetData());
|
||
|
|
||
|
if (handler && handler->GetScriptName() && !strcmp(handler->GetScriptName(), scriptName))
|
||
|
{
|
||
|
return handler;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
#endif // __BANK
|
||
|
|
||
|
// gets the streaming objects to ignore when calculating or displaying resource memory usage
|
||
|
void CGameScriptHandlerMgr::GetResourceIgnoreList(const strIndex** ignoreList, s32& numIgnores) const
|
||
|
{
|
||
|
const atArray<strIndex>& residentIgnoreList = gPopStreaming.GetResidentObjectList();
|
||
|
*ignoreList = residentIgnoreList.GetElements();
|
||
|
numIgnores = residentIgnoreList.GetCount();
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::WriteRemoteScriptHeader(const CGameScriptId& LOGGING_ONLY(scriptId), const char *LOGGING_ONLY(headerText), ...)
|
||
|
{
|
||
|
#if ENABLE_NETWORK_LOGGING
|
||
|
char buffer[netLog::MAX_LOG_STRING];
|
||
|
va_list args;
|
||
|
va_start(args, headerText);
|
||
|
vsprintf(buffer, headerText, args);
|
||
|
va_end(args);
|
||
|
|
||
|
if(GetLog())
|
||
|
{
|
||
|
GetLog()->Log("\t<remote script update> %s: %s\r\n", scriptId.GetLogName(), buffer);
|
||
|
}
|
||
|
#endif // #if ENABLE_NETWORK_LOGGING
|
||
|
}
|
||
|
|
||
|
bool CGameScriptHandlerMgr::HandleTimestampConflict(const CRemoteScriptInfo& scriptInfo)
|
||
|
{
|
||
|
bool bAddInfo = true;
|
||
|
bool bDeleteExistingInfo = false;
|
||
|
|
||
|
// watches out for 2 identical scripts running at once with the same timestamp.
|
||
|
|
||
|
// this can happen for 2 reasons:
|
||
|
// 1) a joining machine starts up and hosts a script immediately before being aware of other machines in the session (and the real host).
|
||
|
// This really shouldn't happen: the joining machine should wait for the timeout time before starting up any scripts but we still need to handle
|
||
|
// this problem in case it does arise.
|
||
|
// 2) a new player is accepted by a host running the script on his own, who drops out immediately. The new player loses the host during the joining
|
||
|
// process and starts a new session. The host has not broadcast a remote script info with 0 participants as he thinks there is a remaining
|
||
|
// participant (the new player).
|
||
|
|
||
|
CGameScriptId remoteScriptId = scriptInfo.GetScriptId();
|
||
|
unsigned remoteTimeStamp = remoteScriptId.GetTimeStamp();
|
||
|
|
||
|
const CGameScriptId* pExistingScriptId = NULL;
|
||
|
u32 existingInfoSlot = 0;
|
||
|
|
||
|
// set timestamp to 0 so that it matches ids of existing script handlers with differing timestamps
|
||
|
remoteScriptId.ResetTimestamp();
|
||
|
|
||
|
// find an existing remote script info for this script
|
||
|
for (u32 i=0; i<m_remoteActiveScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteActiveScripts[i].m_ScriptId == remoteScriptId && m_remoteActiveScripts[i].GetActiveParticipants() != 0)
|
||
|
{
|
||
|
pExistingScriptId = &m_remoteActiveScripts[i].GetScriptId();
|
||
|
|
||
|
unsigned existingTimestamp = pExistingScriptId->GetTimeStamp();
|
||
|
|
||
|
if (gnetVerify(existingTimestamp != remoteTimeStamp))
|
||
|
{
|
||
|
WriteRemoteScriptHeader(*pExistingScriptId, "** TIMESTAMP CONFLICT (Remote timestamp: %d) **", remoteTimeStamp);
|
||
|
|
||
|
if (remoteTimeStamp > existingTimestamp)
|
||
|
{
|
||
|
#if __ASSERT
|
||
|
// we should not have an active handler when we get a timestamp conflict
|
||
|
scriptHandler* pHandler = GetScriptHandler(*pExistingScriptId);
|
||
|
|
||
|
if (pHandler &&
|
||
|
pHandler->GetNetworkComponent() &&
|
||
|
pHandler->GetNetworkComponent()->GetState() == scriptHandlerNetComponent::NETSCRIPT_PLAYING)
|
||
|
{
|
||
|
gnetAssertf(0, "Two versions of script %s active with different timestamps! (Remote timestamp: %d)", pExistingScriptId->GetLogName(), remoteTimeStamp);
|
||
|
return true;
|
||
|
}
|
||
|
#endif
|
||
|
WriteRemoteScriptHeader(*pExistingScriptId, "Info removed");
|
||
|
|
||
|
bDeleteExistingInfo = true;
|
||
|
existingInfoSlot = i;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Info not added");
|
||
|
|
||
|
// don't add this script info
|
||
|
bAddInfo = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bDeleteExistingInfo)
|
||
|
{
|
||
|
MoveActiveScriptToTerminatedQueue(existingInfoSlot);
|
||
|
}
|
||
|
|
||
|
return bAddInfo;
|
||
|
}
|
||
|
|
||
|
void CGameScriptHandlerMgr::MoveActiveScriptToTerminatedQueue(u32 activeScriptSlot)
|
||
|
{
|
||
|
CRemoteScriptInfo scriptInfo = m_remoteActiveScripts[activeScriptSlot];
|
||
|
|
||
|
scriptInfo.SetParticipants(0);
|
||
|
scriptInfo.SetHost(NULL);
|
||
|
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Remote script has terminated, move to terminated queue");
|
||
|
|
||
|
m_remoteActiveScripts.Delete(activeScriptSlot);
|
||
|
|
||
|
scriptHandler* pScriptHandler = GetScriptHandler(scriptInfo.GetScriptId());
|
||
|
|
||
|
// ignore the handler if it is running with a 0 timestamp. We only care about the previous instance of the script.
|
||
|
bool bIgnoreZeroTimestamp = Tunables::GetInstance().TryAccess(CD_GLOBAL_HASH, ATSTRINGHASH("CLEANUP_SCRIPT_OBJECTS_FIX", 0x03bfbf68), true);
|
||
|
|
||
|
if (!pScriptHandler || (bIgnoreZeroTimestamp && static_cast<const CGameScriptId&>(pScriptHandler->GetScriptId()).GetTimeStamp() == 0))
|
||
|
{
|
||
|
WriteRemoteScriptHeader(scriptInfo.GetScriptId(), "Cleanup objects, script not running locally");
|
||
|
|
||
|
// inform the object mgr that this script has terminated, so it can clean up any script objects that belonged to the script
|
||
|
NetworkInterface::GetObjectManager().CleanupScriptObjects(scriptInfo.GetScriptId());
|
||
|
}
|
||
|
|
||
|
#if __ASSERT
|
||
|
for (u32 i=0; i<m_remoteTerminatedScripts.GetCount(); i++)
|
||
|
{
|
||
|
if (m_remoteTerminatedScripts[i].m_ScriptId == scriptInfo.GetScriptId())
|
||
|
{
|
||
|
Assertf(0, "Remote script info %s already on terminated queue", scriptInfo.GetScriptId().GetLogName());
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
#endif // __ASSERT
|
||
|
|
||
|
if (m_remoteTerminatedScripts.IsFull())
|
||
|
m_remoteTerminatedScripts.Pop();
|
||
|
|
||
|
if (!m_remoteTerminatedScripts.Push(scriptInfo))
|
||
|
{
|
||
|
Assertf(0, "Failed to add a terminated script to the remote terminated script queue");
|
||
|
}
|
||
|
}
|