diff --git a/csgo_gc/gc_client.cpp b/csgo_gc/gc_client.cpp index 033030f..a6dbb26 100644 --- a/csgo_gc/gc_client.cpp +++ b/csgo_gc/gc_client.cpp @@ -723,8 +723,6 @@ std::string ClientGC::RconGiveItem(const RconRequest &request) } Inventory::ParameterizedItemOptions options; - bool hasParameters = parameterStart < request.args.size(); - for (size_t i = parameterStart; i < request.args.size(); i++) { std::string_view parameter{ request.args[i] }; @@ -883,30 +881,13 @@ std::string ClientGC::RconGiveItem(const RconRequest &request) for (uint32_t i = 0; i < count; i++) { - uint64_t itemId = 0; - if (hasParameters) - { - CMsgSOSingleObject &update = updates.emplace_back(); - std::string error; - itemId = m_inventory.CreateParameterizedItem(defIndex, options, update, error); - if (!itemId) - { - updates.pop_back(); - if (error == "unknown defindex") - { - return "ERR unknown defindex"; - } - return std::string{ "ERR " }.append(error); - } - } - else - { - itemId = m_inventory.PurchaseItem(defIndex, updates); - } - + CMsgSOSingleObject &update = updates.emplace_back(); + std::string error; + uint64_t itemId = m_inventory.CreateRconItem(defIndex, options, update, error); if (!itemId) { - return "ERR unknown defindex"; + updates.pop_back(); + return std::string{ "ERR " }.append(error); } itemIds.push_back(itemId); diff --git a/csgo_gc/gc_const_csgo.h b/csgo_gc/gc_const_csgo.h index 468b170..7fc1423 100644 --- a/csgo_gc/gc_const_csgo.h +++ b/csgo_gc/gc_const_csgo.h @@ -82,6 +82,7 @@ enum SOTypeId : uint32_t enum ItemOrigin { ItemOriginPurchased = 2, + ItemOriginTraded = 3, ItemOriginCrate = 8, ItemOriginBaseItem = 22 }; diff --git a/csgo_gc/inventory.cpp b/csgo_gc/inventory.cpp index 4814536..81625ec 100644 --- a/csgo_gc/inventory.cpp +++ b/csgo_gc/inventory.cpp @@ -1969,7 +1969,7 @@ uint64_t Inventory::PurchaseItem(uint32_t defIndex, std::vector &update); - uint64_t CreateParameterizedItem(uint32_t defIndex, + + // Creates an item granted through RCON with the traded acquisition reason. + // Returns the item id on success, or 0 and an error string on failure. + uint64_t CreateRconItem(uint32_t defIndex, const ParameterizedItemOptions &options, CMsgSOSingleObject &update, std::string &error); diff --git a/csgo_gc/souvenir.cpp b/csgo_gc/souvenir.cpp index 27babdf..c964aef 100644 --- a/csgo_gc/souvenir.cpp +++ b/csgo_gc/souvenir.cpp @@ -208,8 +208,15 @@ bool SouvenirOpening::OpenPackage(const CSOEconItem &package, CSOEconItem &item) return false; } - // create the item with souvenir quality - if (!m_itemSchema.CreateItemFromLootListItem(m_random, *selectedItem, false, ItemOriginCrate, UnacknowledgedTournamentDrop, item)) + // Opening a souvenir package is a crate acquisition. TournamentDrop is + // reserved for packages awarded directly for watching tournament matches. + if (!m_itemSchema.CreateItemFromLootListItem( + m_random, + *selectedItem, + false, + ItemOriginCrate, + UnacknowledgedFoundInCrate, + item)) { Platform::Print("SouvenirOpening: failed to create item\n"); return false; diff --git a/docs/rcon.md b/docs/rcon.md deleted file mode 100644 index e62586b..0000000 --- a/docs/rcon.md +++ /dev/null @@ -1,289 +0,0 @@ -# RCON - -csgo_gc exposes an optional Source RCON-compatible control port for the local -ClientGC. It is intended for scripting, debugging, and tools that need to update -the live inventory without restarting CS:GO. - -RCON is disabled by default. - -## Configuration - -Add an `rcon` block to `csgo_gc/config.txt`: - -```text -"rcon" -{ - "enabled" "1" - "bind_address" "127.0.0.1" - "port" "37016" - "password" "" -} -``` - -Options: - -- `enabled`: `1` starts the RCON listener. Missing or `0` leaves it disabled. -- `bind_address`: defaults to `127.0.0.1`. Keep this local unless you have added - your own network protection. -- `port`: defaults to `37016`. -- `password`: Source RCON password. An empty configured password intentionally - accepts any supplied Source RCON password for compatibility with this custom GC. - -The setting is read when the GC is loaded. There is no config hot reload. - -Startup logs include the configured bind address, port, protocol, and whether the -password is empty, without printing the password. - -## Protocol - -The listener speaks the Source RCON binary protocol: - -- Little-endian size-prefixed packets. -- `SERVERDATA_AUTH` for authentication. -- `SERVERDATA_EXECCOMMAND` for commands. -- `SERVERDATA_RESPONSE_VALUE` / `SERVERDATA_AUTH_RESPONSE` for responses. - -Raw newline text mode is not supported. Use a Source RCON client or a script that -implements Source RCON packets. - -Example: - -```powershell -rcon -a 127.0.0.1:37016 -p 1 ping -``` - -Expected response body: - -```text -OK pong -``` - -Basic connectivity check: - -```powershell -Test-NetConnection 127.0.0.1 -Port 37016 -``` - -## Response Format - -Command responses are plain text inside Source RCON response packets: - -```text -OK -ERR -``` - -Responses are kept within one Source RCON response packet. Commands that can -produce many lines, such as inventory listing or item detail inspection, include -`shown` and `truncated` fields. `truncated=1` means output stopped before all -available lines could fit in the single response packet. - -Examples: - -```text -OK pong -OK item_ids=1234567890123 -OK total=500 shown=48 truncated=1 -ERR no client gc -ERR unknown parameter foo -``` - -## Commands - -### `help` - -Lists available commands. - -### `ping` - -Returns: - -```text -OK pong -``` - -This works as long as the RCON server is online, even if no ClientGC is currently -registered. - -### `status` - -Returns RCON and ClientGC state. If the game client GC is online, the response -includes the local SteamID and basic inventory stats. - -### `clients` - -Lists the controllable ClientGC instance. v1 only controls the local ClientGC. - -### `list_items` - -Lists inventory items in stable item-id order. - -Syntax: - -```text -list_items [limit] -``` - -The default limit is `50`; the maximum is `500`. - -The response includes `total`, `shown`, and `truncated` fields. If -`truncated=1`, reduce the limit or use `find_item` to narrow the output. - -### `find_item` - -Finds inventory items by exact item id, exact defindex, display name, or custom -name. - -Syntax: - -```text -find_item -``` - -The response includes `total`, `shown`, and `truncated` fields. At most the -first 50 matches are considered for display, and fewer may be shown if the -single Source RCON packet budget is reached. - -### `item_info` - -Shows detailed information for one inventory item, including attributes and -equipped state. - -Syntax: - -```text -item_info -``` - -The response includes `attributes`, `attr_shown`, and `truncated` fields. If an -item has unusually many or long attributes, `truncated=1` indicates that some -attribute lines were omitted from the response. - -### `give_item` - -Creates one or more inventory items and sends live SO create updates to the game. - -Syntax: - -```text -give_item [count] [key=value...] -``` - -Compatibility forms: - -```text -give_item 7 -give_item 7 5 -``` - -Parameterized examples: - -```text -give_item 7 paint=44 -give_item 7 paint=44 wear=0.12 seed=123 stattrak=5 -give_item 7 paint=44 name="RCON Test" -give_item 1314 music=3 stattrak=10 -give_item 7 paint=44 sticker0=12 sticker0_wear=0 -give_item 4013 tournament_team0=31 tournament_team1=1 -give_item 4132 tournament_team0=46 tournament_team1=1 tournament_mvp=64640068 -``` - -Rules: - -- `count` is optional and must be `1..100`. -- Parameters are `key=value`. -- Keys are case-insensitive. -- Values may be double quoted. Backslash escapes the next character inside - quotes. -- Unknown keys return `ERR unknown parameter `. -- Invalid numeric values return `ERR invalid parameter `. -- Successful creation returns `OK item_ids=...`. - -Supported parameters: - -| Parameter | Type | Notes | -| --- | --- | --- | -| `level` | uint32 | Overrides item level. | -| `quality` | uint32 | Explicit quality override. | -| `rarity` | uint32 | Explicit rarity override. | -| `name` | string | Sets the custom item name. Quote values containing spaces. | -| `paint` | uint32 | Paint kit defindex. Must exist in the item schema. | -| `seed` | uint32 | Paint seed. | -| `wear` | float | Paint wear, `0.0..1.0`. | -| `stattrak` | uint32 | Kill count. `stattrak=1` creates StatTrak with 0 kills. | -| `music` | uint32 | Music definition id. Requires music kit defindex `1314`. | -| `spray_color` | uint32 | Graffiti tint id. | -| `spray_remaining` | uint32 | Remaining spray uses. | -| `tournament_event` | uint32 | Tournament event id. Souvenir package definitions normally provide this automatically. | -| `tournament_stage` | uint32 | Tournament event stage id for a specific match. | -| `tournament_team0` | uint32 | First tournament team id for a souvenir package. | -| `tournament_team1` | uint32 | Second tournament team id for a souvenir package. | -| `tournament_mvp` | uint32 | MVP Steam account id for Cologne 2015 through Berlin 2019 souvenir packages. | -| `sticker0`..`sticker5` | uint32 | Sticker kit defindex. Must exist in the item schema. | -| `stickerN_wear` | float | Sticker wear, `0.0..1.0`. | -| `stickerN_scale` | float | Sticker scale. | -| `stickerN_rotation` | float | Sticker rotation. | - -Derived defaults: - -- `paint` adds paint kit, seed, and wear attributes. If not explicitly set, - `seed=0`, `wear=0.001`, `quality=Unique`, and painted rarity are applied. -- `stattrak` adds kill eater attributes. Non-music items use score type `0`. -- `music` adds music id and music-kit score type `1`. It requires `defindex=1314`. -- `stickerN` adds sticker id and defaults that slot's wear to `0` unless - `stickerN_wear` is supplied. -- Explicit `quality` and `rarity` override derived defaults. -- If no parameters are supplied, the command uses the original basic purchase - path. - -See [Souvenir Packages](souvenirs.md) for complete package examples, tournament -attribute numbers, historical sticker formats, and manual `inventory.txt` -editing. - -### `remove_item` - -Removes an item and sends a live SO destroy update to the game. - -Syntax: - -```text -remove_item -``` - -### `refresh_inventory` - -Resends the full inventory cache subscription to the game. This is a repair and -debug command, not the normal path for adding items. - -### `save_inventory` - -Writes the current in-memory inventory to `csgo_gc/inventory.txt`. - -Syntax: - -```text -save_inventory -``` - -## Common Errors - -```text -ERR no client gc -ERR unknown defindex -ERR unknown paint -ERR unknown music -ERR unknown sticker -ERR item not found -ERR usage: give_item [count] [key=value...] -ERR invalid parameter wear -``` - -`ERR no client gc` means the RCON listener is running, but the local ClientGC has -not registered yet or has already been destroyed. - -## Safety Notes - -The default bind address is `127.0.0.1` because RCON can mutate local GC state and -inventory. Do not bind to a public interface without adding your own access -controls. Source RCON compatibility is provided for tooling convenience; it is -not TLS-protected. diff --git a/docs/souvenirs.md b/docs/souvenirs.md deleted file mode 100644 index 36db52d..0000000 --- a/docs/souvenirs.md +++ /dev/null @@ -1,144 +0,0 @@ -# Souvenir Packages - -csgo_gc can open legacy CS:GO souvenir packages and generate the tournament -metadata and stickers expected for their Major era. The package definition -and its GC loot list select the available collection or collections, while -attributes on that particular package describe the tournament and match. - -The package does not need a `loot list` attribute. Loot lists are GC-side data: -`gc_loot_lists.txt` decides which weapons can be produced, and the package's -tournament attributes decide which souvenir stickers are applied to the result. - -## Creating a Package with RCON - -Use `give_item` with a souvenir package defindex and the teams from the match: - -```powershell -rcon -a 127.0.0.1:37016 -p 1 "give_item 4013 tournament_team0=31 tournament_team1=1" -``` - -Package `4013` is the EMS One Katowice 2014 Souvenir Package. Its item -definition already supplies tournament event `3`, so `tournament_event=3` is -optional. This example produces the dedicated Katowice 2014 event sticker and -the Virtus.Pro and Ninjas in Pyjamas Foil team stickers when the package is -opened. - -The supported tournament parameters are: - -| Parameter | Attribute | Meaning | -| --- | ---: | --- | -| `tournament_event` | 137 | Tournament event id. Usually inherited from the package definition. | -| `tournament_stage` | 138 | Tournament stage id. Optional; retained on the resulting souvenir. | -| `tournament_team0` | 139 | First team id. | -| `tournament_team1` | 140 | Second team id. | -| `tournament_mvp` | 223 | MVP Steam account id for autograph-era souvenirs. | - -These values identify tournament records, not sticker-kit defindexes. csgo_gc -looks up the correct sticker variants in `items_game.txt`. - -### Cologne 2015 through Berlin 2019 - -Souvenirs from the autograph era use a fourth Gold sticker belonging to the -match MVP. Supply the player's 32-bit Steam account id with `tournament_mvp`: - -```powershell -rcon -a 127.0.0.1:37016 -p 1 "give_item 4132 tournament_team0=46 tournament_team1=1 tournament_mvp=64640068" -``` - -In this example: - -- `4132` is the ESL One Cologne 2015 Mirage Souvenir Package. -- Team `46` is Team EnVyUs. -- Team `1` is Ninjas in Pyjamas. -- Account id `64640068` selects the Gold kennyS autograph for event `7`. - -If `tournament_mvp` is omitted, the package still opens, but the resulting item -only has the event and two team stickers and is not a complete match-specific -souvenir for this era. - -### Stockholm 2021 and Later CS:GO Majors - -Beginning with Stockholm 2021, the fourth sticker is the Gold map sticker, not -an MVP autograph. csgo_gc derives the map automatically from the package -definition: - -```powershell -rcon -a 127.0.0.1:37016 -p 1 "give_item 4810 tournament_team0=12 tournament_team1=59" -``` - -Package `4810` is the Stockholm 2021 Mirage package. This produces the event, -Natus Vincere, G2 Esports, and `de_mirage_gold` stickers. Do not supply -`tournament_mvp` for this format. - -## Editing `inventory.txt` - -The same metadata can be added manually to a souvenir package in -`csgo_gc/inventory.txt`. For an autograph-era package, its `attributes` block -can contain: - -```text -"attributes" -{ - "137" "7" - "139" "46" - "140" "1" - "223" "64640068" -} -``` - -Attribute `137` can be omitted when the correct package definition already -contains the tournament event. The values must still describe a sensible -match: csgo_gc resolves sticker kits but does not verify that the specified -teams and MVP actually played one another historically. - -After creating a package through RCON, inspect and persist it with: - -```powershell -rcon -a 127.0.0.1:37016 -p 1 "item_info " -rcon -a 127.0.0.1:37016 -p 1 save_inventory -``` - -## Sticker Formats by Era - -The finish and fourth sticker changed during CS:GO's lifetime. csgo_gc selects -these variants automatically: - -| Tournament era | Generated stickers | -| --- | --- | -| DreamHack Winter 2013 | Tournament-themed sticker; no team metadata was available. | -| EMS Katowice and ESL One Cologne 2014 | Dedicated event sticker and two team Foil stickers. | -| DreamHack Winter 2014 | Event sticker and two team Gold stickers. | -| ESL One Katowice 2015 | Event Gold and two team Gold stickers. | -| ESL One Cologne 2015 through Berlin 2019 | Event Gold, two team Golds, and an MVP Gold autograph. | -| Stockholm 2021 through Paris 2023 | Event Gold, two team Golds, and a Gold map sticker. | - -Early events contain multiple sticker finishes with the same tournament/team -metadata. Selecting the first matching schema entry is incorrect and is also -nondeterministic when entries are stored in an unordered map. The implementation -therefore selects the era-appropriate suffix (`_foil` or `_gold`) and randomly -chooses only where the historical format has multiple valid event designs. - -## Notes for Maintainers - -- Sticker-kit tournament fields are parsed from `items_game.txt`: - `tournament_event_id`, `tournament_team_id`, and `tournament_player_id`. -- Attribute `223`, `tournament mvp account id`, supplies the match-specific - player for the 2015-2019 autograph format. -- The standalone map Gold stickers (`de_mirage_gold`, `de_nuke_gold`, and so - on) do not carry a tournament id. For Stockholm 2021 and later packages, the - map is derived from the package name such as - `crate_stockh2021_promo_de_mirage`. -- Package loot contents and souvenir sticker generation are separate. Missing - server-only package contents belong in `gc_loot_lists.txt`; sticker selection - should remain schema-driven rather than be duplicated in an external rules - file. -- `gc_loot_lists.txt` is supplemental: definitions should use names absent - from the client schema. Duplicate loot-list names are ignored rather than - silently merged with client data. - -Research references: - -- [Valve: The Major is Back (Stockholm 2021)](https://store.steampowered.com/news/app/730/view/4103335143107243030) -- [Valve: The Paris 2023 Major](https://store.steampowered.com/news/app/730/view/5138087875081246097) -- [Final CS:GO `items_game.txt` tracked by SteamTracking](https://github.com/SteamTracking/GameTracking-CS2/blob/e63fc7fdb8dfb4f1873f0db214c0cc16613d5beb/csgo/scripts/items/items_game.txt) -- [Structured sticker-kit export used for cross-checking variants](https://github.com/zwolof/schema-gen/blob/054ce0d1c0b20ab18927d9aa59922abb5d2566c8/exported/sticker_kits.json)