Jump to content
McKay Development

Dr. McKay

Administrator
  • Posts

    3589
  • Joined

  • Last visited

Posts posted by Dr. McKay

  1. Maybe items with craft_class "tool" are always craftable. I don't remember seeing any uncraftable name tags or decal tools, for example.

    Also, it's probably worth mentioning that I have a recollection of seeing the NotEcon flag on contracts. Contracts are sent to the game client as CSOEconItems (because adding another SO type for contracts would be way too logical, and we can't have that), but they have the NotEcon flag which hides them from the backpack and other econ views. I could be mistaken on this, but I don't think so. I don't recall ever seeing NotEcon anywhere else.

    Based on this minimal research, here is my best (likely incorrect) guess at pseudocode to match Valve's actual code:

    function IsItemCraftable(EconItem item) {
    	if (item.flags & NotEcon) {
    		return false;
    	}
    	
    	if (item.schemaDefinition.craft_class == "tool") {
    		return true;
    	}
    	
    	if (item.hasAttribute("never craftable")) {
    		return false;
    	}
    	
    	if (
    		(item.origin == Purchased || item.origin == StorePromotion)
    		&& !item.schemaDefinition.capabilities.can_craft_if_purchased
    	) {
    		return false;
    	}
    	
    	if (item.flags & CannotCraft) {
    		return false;
    	}
    	
    	return true;
    }
    
    function IsItemTradable(EconItem item) {
    	if (item.flags & NotEcon) {
    		return false;
    	}
    	
    	if (item.flags & CannotTrade) {
    		return false;
    	}
    	
    	if (item.hasAttribute("tradable after date") && item.getAttribute("tradable after date") > time()) 
    		return false;
    	}
    	
    	if (item.hasAttribute("always tradable")) {
    		return true;
    	}
    	
    	if (item.hasAttribute("cannot trade")) {
    		return false;
    	}
    	
    	if (item.origin == Achievement) {
    		return false;
    	}
    	
    	return true;
    }

    (hasAttribute and getAttribute also check the schema definition if the appropriate attribute is not present on the CSOEconItem instance)

  2. You got me curious, so I dumped my backpack and checked out some craftable and uncraftable items.

    • Tour of Duty Ticket
      • Craftable: Origin 8 (Found in Crate)
      • Uncraftable: Origin 2 (Purchased), flags +16 (unknown flag)
    • Killstreak Kits
      • Inherit "never craftable" attribute from their schema definitions
    • Uncraftable weapon
      • Origin 2 (Purchased), same flags as craftable ToD ticket (4)
    • World Traveler's Hat
      • Inherits "cannot trade" attribute from its schema definition
      • Flags 16
      • Origin 5 (Store Promotion)
    • Sir Hootsalot
      • Flags 0
      • Origin 12 (Halloween Drop)
      • Has "never craftable" attribute on the item
    • Mann Co. Cap
      • Flags 0
      • Origin 5 (Store Promotion)
      • Inherits "cannot trade" attribute from its schema definition
    • Gun Mettle Campaign Coin
      • This one is weird. I haven't found a way to determine that it's uncraftable using only the schema from the WebAPI and the GC data
      • Flags 0
      • Origin 0 (Timed Drop)
      • The only attributes listed in GetSchemaItems are kill eater attributes
      • items_game.txt also includes static_attrs for this defindex, which contains "never craftable" and "cannot trade", among other things
      • I also went back to check if the Mann Co. Cap also includes "never craftable" in items_game.txt, but it only has "cannot trade". My suspicion is that origin 5 (Store Promotion) also makes items uncraftable. I only have 3 items with this origin (World Traveler's Hat, Mann Co. Cap, Mann Co. Online Cap) and all are uncraftable.
    • Pyrovision Goggles
      • I don't have a tradable pair to compare with, but the only identifying characteristic in the GC backpack data is origin 1 (Achievement). Flags are 0 and there are no attributes, and it shares the same defindex as a tradable pair of goggles. So as far as I'm concerned, that's proof that origin can determine tradability or craftability.
    • SpaceChem Pin
      • My instance has the "cannot trade" attribute, but the schema definition has the "always tradable" attribute, and my item is tradable. It seems that "always tradable" overrides the "cannot trade" attribute.
      • I suspect that "always tradable" would also override the Achievement origin, but I can't confirm. The Ghastlierest Gibus has the always tradable attribute, and that's an achievement item. I wouldn't be surprised if the always tradable attribute was added specifically for the Ghastly Gibus Grab achievement.

    Notably, some item have a capability can_craft_if_purchased, which backs up my suspicion that items with origin 2 (Purchased) are uncraftable unless their schema definition defines otherwise.

     

    24 minutes ago, KTVS said:

    so I guess whatever magic is happening on the client to determine craftability also happens behind the scenes with the API before the response is sent

    Yeah, I believe this is what's happening. There are flags that determine if items are untradable or uncraftable, but the WebAPI also resolves the various other conditions that make an item untradable and stuffs them into those props as well.

    For the most part, the only attributes that are sent in your actual backpack data from the GC are those that are specific to an item instance. That would be stuff like maker's mark (crafter name), gifter name, craft index, kill eater (strange kills), tradable after date, stuff like that.

  3. My assumption would be that the Preview flag is set on items that are temporary store previews (the "try it out" button in the Mann Co. store) and that NotEcon would be set on items that shouldn't be tradable or craftable. It seems that your experience doesn't match my assumption, which means that either your data is wrong, my assumption is wrong, or the actual values of the named flags in node-tf2 are wrong. Any of those could be possible; I don't think I got those flag names from any authoritative source.

  4. On 2/14/2022 at 12:05 AM, KTVS said:

    It's possible that this is a completely separate mechanism which is responsible solely for updating these player names, in which case my whole theory is bunk.

    I've never personally confirmed it, though I all but guarantee that after the game client receives info from the GC about an item that's crafted or gifted by a user that's not in the local cache, it separately requests the user's persona name using the SteamWorks RequestUserInformation function. This request goes directly to Steam and bypasses the GC. This function uses the same CM message as steam-user's getPersonas method.

    I promise you that all of the information necessary to tell if an item is tradable or craftable is present in the backpack property. The problem is just that Valve is good at spaghetti code and so there are a handful of different things you need to check to tell if an item is untradable or uncraftable. For tradability, there's origin (for achievement items and untradable free contract rewards), a few different item attributes (cannot trade, purchased, tradable after date, non economy, but also there's the always tradable attribute which surely overrides something but lord knows what), and a flag in the flags bitfield, and probably something else I missed too.

    Non-craftability is a bit easier, and you probably just need to check the purchased, never craftable, and non economy attributes in addition to the flag in the flags bitfield.

    But there's also the Preview and NotEcon flags to contend with. Logic dictates that both of those flags should also indicate that an item is untradable and uncraftable, but maybe that's not the case. It's just a complete mess.

×
×
  • Create New...