### Apply Music Kit to Player Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Applies a music kit to a player, updating StatTrak MVP counters if available. It handles null checks for player inventory services and the music kit item itself. Dependencies include CCSPlayerController and PlayerInventory classes. ```csharp // Apply music kit on connection GivePlayerMusicKit(player, inventory); // Implementation public void GivePlayerMusicKit(CCSPlayerController player, PlayerInventory inventory) { if (!IsPlayerHumanAndValid(player)) return; if (player.InventoryServices == null) return; var item = inventory.MusicKit; if (item != null) { player.InventoryServices.MusicID = (ushort)item.Def; Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInventoryServices"); player.MusicKitID = item.Def; Utilities.SetStateChanged(player, "CCSPlayerController", "m_iMusicKitID"); player.MusicKitMVPs = item.Stattrak; Utilities.SetStateChanged(player, "CCSPlayerController", "m_iMusicKitMVPs"); } } // Increment on MVP public void GivePlayerMusicKitStatTrakIncrement(CCSPlayerController player) { if (PlayerInventoryManager.TryGetValue(player.SteamID, out var inventory)) { var item = inventory.MusicKit; if (item != null) { item.Stattrak += 1; SendStatTrakIncrement(player.SteamID, item.Uid); } } } // Event handler public HookResult OnRoundMvpPre(EventRoundMvp @event, GameEventInfo _) { var player = @event.Userid; if (player != null && IsPlayerHumanAndValid(player) && IsPlayerPawnValid(player)) { GivePlayerMusicKitStatTrakIncrement(player); } return HookResult.Continue; } ``` -------------------------------- ### Authenticate Player to CS2 Inventory Simulator Web Service Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Generates a login token for players to authenticate with the Inventory Simulator web service. It handles the sign-in request, including API key and user ID, and provides feedback to the player in-game. The command requires an API key to be configured and the web service login to be enabled. ```csharp // Send authentication request SendSignIn(player.SteamID); // Example: Command handler [ConsoleCommand("css_wslogin", "Authenticate player to Inventory Simulator.")] public void OnWsloginCommand(CCSPlayerController? player, CommandInfo _) { if (invsim_apikey.Value != "" && invsim_wslogin.Value && player != null) { player.PrintToChat(Localizer["invsim.login_in_progress"]); if (AuthenticatingPlayer.ContainsKey(player.SteamID)) return; SendSignIn(player.SteamID); } } // Internal authentication flow public async void SendSignIn(ulong userId) { if (AuthenticatingPlayer.ContainsKey(userId)) return; AuthenticatingPlayer.TryAdd(userId, true); var response = await Send( "/api/sign-in", new { apiKey = invsim_apikey.Value, userId = userId.ToString() } ); AuthenticatingPlayer.TryRemove(userId, out var _); Server.NextFrame(() => { var player = Utilities.GetPlayerFromSteamId(userId); if (response == null) { player?.PrintToChat(Localizer["invsim.login_failed"]); return; } player?.PrintToChat(Localizer["invsim.login", $"{GetAPIUrl("/api/sign-in/callback")}?token={response.Token}"]); }); } ``` -------------------------------- ### Configure Spray System Settings (Bash) Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt This Bash snippet demonstrates how to configure the spray system within the CS2 Inventory Simulator plugin using server console variables (ConVars). It shows how to enable/disable the spray system, set spray cooldowns, and control spray-on-use behavior. ```bash # Graffiti invsim_spray_enabled "true" # Enable spray system invsim_spraychanger_enabled "false" # Replace vanilla sprays invsim_spray_on_use "false" # Spray with USE key invsim_spray_cooldown "30" # Spray cooldown (seconds) ``` -------------------------------- ### Fetch Player Inventory from API (C#) Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Retrieves equipped cosmetic items for a player from the Inventory Simulator API. Supports caching and force refresh. Handles API communication with retry logic. ```csharp await FetchPlayerInventory(player.SteamID, force: false); await FetchPlayerInventory(player.SteamID, force: true); public void OnPlayerConnect(CCSPlayerController player) { if (PlayerOnTickInventoryManager.TryGetValue(player.SteamID, out var tuple)) PlayerOnTickInventoryManager[player.SteamID] = (player, tuple.Item2); RefreshPlayerInventory(player); } public async Task FetchPlayerInventory(ulong steamId, bool force = false) { var existing = PlayerInventoryManager.TryGetValue(steamId, out var i) ? i : null; if (!force && existing != null) return; if (FetchingPlayerInventory.ContainsKey(steamId)) return; FetchingPlayerInventory.TryAdd(steamId, true); for (var attempt = 0; attempt < 3; attempt++) { try { var playerInventory = await Fetch($"/api/equipped/v3/{steamId}.json", true); if (playerInventory != null) { if (existing != null) playerInventory.CachedWeaponEconItems = existing.CachedWeaponEconItems; PlayerCooldownManager[steamId] = Now(); AddPlayerInventory(steamId, playerInventory); } break; } catch { // Retry up to 3 times } } FetchingPlayerInventory.Remove(steamId, out var _); } ``` -------------------------------- ### Register and Implement Spray Graffiti Command (C#) Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt This C# code registers the 'css_spray' command and implements the logic for players to spray graffiti. It includes checks for command usage, cooldowns, player status, and item availability. The graffiti is applied by creating a 'player_spray_decal' entity with appropriate properties. ```csharp // Register spray command [ConsoleCommand("css_spray", "Spray player's graffiti.")] public void OnSprayCommand(CCSPlayerController? player, CommandInfo _) { if (player != null && invsim_spray_enabled.Value) { if (PlayerSprayCooldownManager.TryGetValue(player.SteamID, out var timestamp)) { var cooldown = invsim_spray_cooldown.Value; var diff = Now() - timestamp; if (diff < cooldown) { player.PrintToChat(Localizer["invsim.spray_cooldown", cooldown - diff]); return; } } SprayPlayerGraffiti(player); } } // Implementation with trace and entity creation public unsafe void SprayPlayerGraffiti(CCSPlayerController player) { if (!IsPlayerHumanAndValid(player)) return; var inventory = GetPlayerInventory(player); var item = inventory.Graffiti; if (item == null) return; var pawn = player.PlayerPawn.Value; if (pawn == null || pawn.LifeState != (int)LifeState_t.LIFE_ALIVE) return; var movementServices = pawn.MovementServices?.As(); if (movementServices == null) return; var trace = stackalloc GameTrace[1]; if (!pawn.IsAbleToApplySpray((IntPtr)trace) || (IntPtr)trace == IntPtr.Zero) return; player.EmitSound("SprayCan.Shake"); PlayerSprayCooldownManager[player.SteamID] = Now(); var endPos = Vector3toVector(trace->EndPos); var normalPos = Vector3toVector(trace->Normal); var sprayDecal = Utilities.CreateEntityByName("player_spray_decal"); if (sprayDecal != null) { sprayDecal.EndPos.Add(endPos); sprayDecal.Start.Add(endPos); sprayDecal.Left.Add(movementServices.Left); sprayDecal.Normal.Add(normalPos); sprayDecal.AccountID = (uint)player.SteamID; sprayDecal.Player = item.Def; sprayDecal.TintID = item.Tint; sprayDecal.DispatchSpawn(); player.EmitSound("SprayCan.Paint"); } } // Use key binding support public void SprayPlayerGraffitiThruPlayerButtons(CCSPlayerController player) { if ((player.Buttons & PlayerButtons.Use) != 0 && player.PlayerPawn.Value?.IsAbleToApplySpray() == true) { if (IsPlayerUseCmdBusy(player)) PlayerUseCmdManager[player.SteamID] = true; if (PlayerUseCmdManager.TryGetValue(player.SteamID, out var timer)) timer.Kill(); PlayerUseCmdManager[player.SteamID] = AddTimer(0.1f, () => { if (PlayerUseCmdBlockManager.ContainsKey(player.SteamID)) PlayerUseCmdBlockManager.Remove(player.SteamID, out var _); else if (player.IsValid && !IsPlayerUseCmdBusy(player)) player.ExecuteClientCommandFromServer("css_spray"); }); } } ``` -------------------------------- ### Register CS2 Inventory Simulator Plugin Hooks and Events (C#) Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt This snippet demonstrates how to initialize the InventorySimulator plugin in C#. It registers various event listeners and function hooks for player events, game events, and ConVar changes to manage inventory customization and synchronize with an external system. Dependencies include the CounterStrikeSharp framework. ```csharp public partial class InventorySimulator : BasePlugin { public override string ModuleAuthor => "Ian Lucas"; public override string ModuleDescription => "Inventory Simulator (inventory.cstrike.app)"; public override string ModuleName => "InventorySimulator"; public override string ModuleVersion => "1.0.0"; public override void Load(bool hotReload) { // Tick and entity listeners RegisterListener(OnTick); RegisterListener(OnEntityCreated); // Player events RegisterEventHandler(OnPlayerConnect); RegisterEventHandler(OnPlayerConnectFull); RegisterEventHandler(OnRoundPrestart); RegisterEventHandler(OnPlayerSpawn); RegisterEventHandler(OnPlayerDeathPre, HookMode.Pre); RegisterEventHandler(OnRoundMvpPre, HookMode.Pre); RegisterEventHandler(OnPlayerDisconnect); // Function hooks VirtualFunctions.GiveNamedItemFunc.Hook(OnGiveNamedItemPost, HookMode.Post); Extensions.UpdateSelectTeamPreview.Hook(OnUpdateSelectTeamPreview, HookMode.Post); // ConVar change handlers invsim_file.ValueChanged += OnInvsimFileChanged; OnInvsimFileChanged(null, invsim_file.Value); invsim_require_inventory.ValueChanged += OnInvSimRequireInventoryChange; OnInvSimRequireInventoryChange(null, invsim_require_inventory.Value); invsim_compatibility_mode.ValueChanged += OnInvSimCompatibilityModeChange; OnInvSimCompatibilityModeChange(null, invsim_compatibility_mode.Value); invsim_spray_on_use.ValueChanged += OnInvSimSprayOnUseChange; OnInvSimSprayOnUseChange(null, invsim_spray_on_use.Value); } } ``` -------------------------------- ### Apply Player Gloves in CS2 Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Applies custom glove models and attributes (paint kit, wear, seed) to a player. This implementation includes a workaround for potential model issues on player spawn. It relies on the PlayerInventory class to retrieve glove data. ```csharp // Apply gloves on player spawn GivePlayerGloves(player, inventory); // Example: Spawn event handler public HookResult OnPlayerSpawn(EventPlayerSpawn @event, GameEventInfo _) { var player = @event.Userid; if (player != null && IsPlayerHumanAndValid(player) && IsPlayerPawnValid(player)) { GiveOnPlayerSpawn(player); } return HookResult.Continue; } public void GiveOnPlayerSpawn(CCSPlayerController player) { var inventory = GetPlayerInventory(player); GivePlayerPin(player, inventory); GivePlayerAgent(player, inventory); GivePlayerGloves(player, inventory); } // Gloves implementation with workaround public void GivePlayerGloves(CCSPlayerController player, PlayerInventory inventory) { var pawn = player.PlayerPawn.Value; if (pawn == null || pawn.Handle == IntPtr.Zero) return; var fallback = invsim_fallback_team.Value; var item = inventory.GetGloves(player.TeamNum, fallback); if (item != null) { if (invsim_ws_gloves_fix.Value) { // Workaround by @daffyyyy var model = pawn.CBodyComponent?.SceneNode?.GetSkeletonInstance() ?.ModelState.ModelName; if (!string.IsNullOrEmpty(model)) { pawn.SetModel("characters/models/tm_jumpsuit/tm_jumpsuit_varianta.vmdl"); pawn.SetModel(model); } } var glove = pawn.EconGloves; Server.NextFrame(() => { if (pawn.IsValid) { ApplyGloveAttributesFromItem(glove, item); // Thanks to xstage and stefanx111 pawn.AcceptInput("SetBodygroup", value: "default_gloves,1"); } }); } } ``` -------------------------------- ### Apply Weapon Skin to CS2 Weapons Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Applies paint kit, wear, seed, nametag, StatTrak, and stickers to weapons in CS2. This function is typically hooked into weapon creation events to ensure skins are applied as weapons are given to players. It retrieves weapon data from the player's inventory and applies the relevant attributes. ```csharp // Apply skin when weapon is given to player GivePlayerWeaponSkin(player, weapon); // Example: Hook into weapon creation public HookResult OnGiveNamedItemPost(DynamicHook hook) { var className = hook.GetParam(1); if (!className.Contains("weapon")) return HookResult.Continue; var itemServices = hook.GetParam(0); var weapon = hook.GetReturn(); var player = GetPlayerFromItemServices(itemServices); if (player != null) { GivePlayerWeaponSkin(player, weapon); } return HookResult.Continue; } // Internal implementation public void GivePlayerWeaponSkin(CCSPlayerController player, CBasePlayerWeapon weapon) { if (IsCustomWeaponItemID(weapon)) return; var isKnife = weapon.DesignerName.IsKnifeClassName(); var entityDef = weapon.AttributeManager.Item.ItemDefinitionIndex; var inventory = GetPlayerInventory(player); var fallback = invsim_fallback_team.Value; var item = isKnife ? inventory.GetKnife(player.TeamNum, fallback) : inventory.GetWeapon(player.Team, entityDef, fallback); if (item != null) { item.WearOverride ??= inventory.GetWeaponEconItemWear(item); ApplyWeaponAttributesFromItem(weapon.AttributeManager.Item, item, weapon, player); } } ``` -------------------------------- ### Apply Agent Models in CS2 Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Sets the player's agent model, including optional patches and voice parameters. This function supports enforcing specific agent models for Terrorist and Counter-Terrorist teams and handling custom agent items retrieved from the PlayerInventory. ```csharp // Apply agent on spawn GivePlayerAgent(player, inventory); // Implementation with minmodels enforcement public void GivePlayerAgent(CCSPlayerController player, PlayerInventory inventory) { if (invsim_minmodels.Value > 0) { // Force SAS & Phoenix models if (player.Team == CsTeam.Terrorist) SetPlayerModel(player, "characters/models/tm_phoenix/tm_phoenix.vmdl"); if (player.Team == CsTeam.CounterTerrorist) SetPlayerModel(player, "characters/models/ctm_sas/ctm_sas.vmdl"); return; } if (inventory.Agents.TryGetValue(player.TeamNum, out var item)) { var patches = item.Patches.Count != 5 ? Enumerable.Repeat((uint)0, 5).ToList() : item.Patches; SetPlayerModel(player, GetAgentModelPath(item.Model), item.VoFallback, item.VoPrefix, item.VoFemale, patches); } } // Team preview application public void GivePlayerTeamPreview(CCSPlayerController player, CCSGO_TeamPreviewCharacterPosition teamPreview, PlayerInventory inventory) { var fallback = invsim_fallback_team.Value; var gloveItem = inventory.GetGloves(player.TeamNum, fallback); if (gloveItem != null) { ApplyGloveAttributesFromItem(teamPreview.GlovesItem, gloveItem); Utilities.SetStateChanged(teamPreview, "CCSGO_TeamPreviewCharacterPosition", "m_glovesItem"); } var weaponItem = teamPreview.WeaponItem.IsKnifeClassName() ? inventory.GetKnife(player.TeamNum, fallback) : inventory.GetWeapon(player.Team, teamPreview.WeaponItem.ItemDefinitionIndex, fallback); if (weaponItem != null) { ApplyWeaponAttributesFromItem(teamPreview.WeaponItem, weaponItem); Utilities.SetStateChanged(teamPreview, "CCSGO_TeamPreviewCharacterPosition", "m_weaponItem"); } if (inventory.Agents.TryGetValue(player.TeamNum, out var agentItem) && agentItem.Def != null) { teamPreview.AgentItem.ItemDefinitionIndex = agentItem.Def.Value; Utilities.SetStateChanged(teamPreview, "CCSGO_TeamPreviewCharacterPosition", "m_agentItem"); } } ``` -------------------------------- ### Refresh Weapons on !ws Command in C# Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt This C# code snippet registers the 'css_ws' console command to refresh a player's inventory. It handles cooldowns, checks if an inventory refresh is already in progress, and then calls the logic to give the player their current weapons with updated ammo and item details. It also manages dropping old weapons and equipping the new ones, including setting them as the active weapon if necessary. ```csharp // Register command [ConsoleCommand("css_ws", "Refreshes player's inventory.")] public void OnWSCommand(CCSPlayerController? player, CommandInfo _) { var url = invsim_ws_print_full_url.Value ? GetAPIUrl() : invsim_hostname.Value; player?.PrintToChat(Localizer["invsim.announce", url]); if (!invsim_ws_enabled.Value || player == null) return; if (PlayerCooldownManager.TryGetValue(player.SteamID, out var timestamp)) { var cooldown = invsim_ws_cooldown.Value; var diff = Now() - timestamp; if (diff < cooldown) { player.PrintToChat(Localizer["invsim.ws_cooldown", cooldown - diff]); return; } } if (FetchingPlayerInventory.ContainsKey(player.SteamID)) { player.PrintToChat(Localizer["invsim.ws_in_progress"]); return; } RefreshPlayerInventory(player, true); player.PrintToChat(Localizer["invsim.ws_new"]); } // Refresh logic with immediate weapon replacement public void GivePlayerCurrentWeapons( CCSPlayerController player, PlayerInventory inventory, PlayerInventory oldInventory) { var pawn = player.PlayerPawn.Value; var weaponServices = pawn?.WeaponServices?.As(); if (pawn == null || weaponServices == null) return; var activeDesignerName = weaponServices.ActiveWeapon.Value?.DesignerName; var targets = new List<(string, string, int, int, bool, gear_slot_t)>(); foreach (var handle in weaponServices.MyWeapons) { var weapon = handle.Value?.As(); if (weapon == null || weapon.DesignerName.Contains("weapon_") != true) continue; if (weapon.OriginalOwnerXuidLow != (uint)player.SteamID) continue; var data = weapon.VData; if (data == null) continue; if (data.GearSlot is gear_slot_t.GEAR_SLOT_RIFLE or gear_slot_t.GEAR_SLOT_PISTOL or gear_slot_t.GEAR_SLOT_KNIFE) { var entityDef = weapon.AttributeManager.Item.ItemDefinitionIndex; var fallback = invsim_fallback_team.Value; var oldItem = data.GearSlot is gear_slot_t.GEAR_SLOT_KNIFE ? oldInventory.GetKnife(player.TeamNum, fallback) : oldInventory.GetWeapon(player.Team, entityDef, fallback); var item = data.GearSlot is gear_slot_t.GEAR_SLOT_KNIFE ? inventory.GetKnife(player.TeamNum, fallback) : inventory.GetWeapon(player.Team, entityDef, fallback); if (oldItem == item) continue; var clip = weapon.Clip1; var reserve = weapon.ReserveAmmo[0]; targets.Add((weapon.DesignerName, weapon.GetDesignerName(), clip, reserve, activeDesignerName == weapon.DesignerName, data.GearSlot)); } } foreach (var target in targets) { var oldWeapon = weaponServices.MyWeapons .FirstOrDefault(h => h.Value?.DesignerName == target.Item1)?.Value; if (oldWeapon != null) { weaponServices.DropWeapon(oldWeapon); oldWeapon.Remove(); } var weapon = new CBasePlayerWeapon(player.GiveNamedItem(target.Item2)); Server.RunOnTick(Server.TickCount + 32, () => { if (weapon.IsValid) { weapon.Clip1 = target.Item3; Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_iClip1"); weapon.ReserveAmmo[0] = target.Item4; Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_pReserveAmmo"); Server.NextFrame(() => { if (target.Item5 && player.IsValid) { var command = target.Item6 switch { gear_slot_t.GEAR_SLOT_RIFLE => "slot1", gear_slot_t.GEAR_SLOT_PISTOL => "slot2", gear_slot_t.GEAR_SLOT_KNIFE => "slot3", _ => null, }; if (command != null) player.ExecuteClientCommand(command); } }); } }); } } ``` -------------------------------- ### Apply Collectible Pin to Player Profile Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Sets the collectible pin displayed on a player's profile. This function iterates through the player's rank array and assigns the pin's value. It ensures that the player's inventory services are valid before proceeding. ```csharp // Apply pin on spawn GivePlayerPin(player, inventory); // Implementation public void GivePlayerPin(CCSPlayerController player, PlayerInventory inventory) { if (player.InventoryServices == null) return; var pin = inventory.Pin; if (pin == null) return; for (var index = 0; index < player.InventoryServices.Rank.Length; index++) { player.InventoryServices.Rank[index] = index == 5 ? (MedalRank_t)pin.Value : MedalRank_t.MEDAL_RANK_NONE; Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInventoryServices"); } } ``` -------------------------------- ### Send StatTrak Increment to API (C#) Source: https://context7.com/ianlucas/cs2-inventory-simulator-plugin/llms.txt Updates the StatTrak counter for a specific weapon item when a player achieves a kill or MVP. This function sends an API request to the Inventory Simulator service. Requires an API key for authentication. ```csharp SendStatTrakIncrement(player.SteamID, item.Uid); public HookResult OnPlayerDeathPre(EventPlayerDeath @event, GameEventInfo _) { var attacker = @event.Attacker; var victim = @event.Userid; if (attacker != null && victim != null) { var isValidAttacker = IsPlayerHumanAndValid(attacker) && IsPlayerPawnValid(attacker); var isValidVictim = (invsim_stattrak_ignore_bots.Value ? IsPlayerHumanAndValid(victim) : IsPlayerValid(victim)) && IsPlayerPawnValid(victim); if (isValidAttacker && isValidVictim) { GivePlayerWeaponStatTrakIncrement(attacker, @event.Weapon, @event.WeaponItemid); } } return HookResult.Continue; } public async void SendStatTrakIncrement(ulong userId, int targetUid) { if (invsim_apikey.Value == "") return; await Send( "/api/increment-item-stattrak", new { apiKey = invsim_apikey.Value, targetUid, userId = userId.ToString(), } ); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.