Jump to content
McKay Development

unable to read price_sheet from CMsgStoreGetUserData


Recommended Posts

Posted

hey,

i try to fetch CSGO in-game store prices via CMsgStoreGetUserData.

message CMsgStoreGetUserData {
	optional fixed32 price_sheet_version = 1;
	optional int32 currency = 2;
}

 

message CMsgStoreGetUserDataResponse {
	optional int32 result = 1;
	optional int32 currency_deprecated = 2;
	optional string country_deprecated = 3;
	optional fixed32 price_sheet_version = 4;
	optional bytes price_sheet = 8;
}

 

When i receive the "CMsgStoreGetUserDataResponse" i can read result, price_sheet_version without problems but "price_sheet" itself is provided as bytes. When i try to read it i get some unreadable text. I also tried to parse it with  binarykvparser which gives  an error "KV type 48 encountered at offset 207"

How could i read the data provided by price_sheet?

thank you in advance

  • 4 weeks later...
Posted

I'm trying to do the same thing, I'm using python though. For me the price_sheet starts with b"LZMA\", so I'm guessing it's compressed with LZMA but I wasn't able to decompress it

  • 3 years later...
  • 4 weeks later...
Posted (edited)
const { LZMA } = require('lzma-native');

function decompressValveLZMA(buffer) {
  if (buffer.length < 13) {
    throw new Error("Buffer too short to be Valve LZMA");
  }
  const magic = buffer.readUInt32BE(0); // Big-Endian
  if (magic !== 0x4C5A4D41) { // 'LZMA'
    throw new Error("Not a Valve LZMA container (magic mismatch)");
  }
  const uncompressedLength = buffer.readUInt32LE(4);
  const compressedLength   = buffer.readUInt32LE(8);
  const expectedTotal = 12 + 5 + compressedLength; // header (12) + props(5) + data
  if (buffer.length < expectedTotal) {
    throw new Error(`Buffer too short: expected ${expectedTotal}, have ${buffer.length}`);
  }
  const props = buffer.slice(12, 12 + 5);
  const lzmaData = buffer.slice(12 + 5, 12 + 5 + compressedLength);
  return new Promise((resolve, reject) => {
    const lzma = new LZMA();
    const lzmaHeader = Buffer.alloc(5 + 8);
    props.copy(lzmaHeader, 0); // копируем 5 байт props
    lzmaHeader.writeUInt32LE(uncompressedLength, 5);
    const fullLzmaStream = Buffer.concat([lzmaHeader, lzmaData]);
    lzma.decompress(fullLzmaStream, (result, error) => {
      if (error) {
        reject(error);
      } else {
        resolve(Buffer.from(result));
      }
    });
  });
}

 

Edited by skr1pt
  • 3 months later...
Posted
function decompressValveLZMA(buffer) {
  if (buffer.length < 13) {
    throw new Error("Buffer too short to be Valve LZMA");
  }

  const magic = buffer.readUInt32BE(0); // 'LZMA' magic
  if (magic !== 0x4C5A4D41) {
    throw new Error("Not a Valve LZMA container (magic mismatch)");
  }

  const uncompressedLength = buffer.readUInt32LE(4);
  const compressedLength   = buffer.readUInt32LE(8);
  const expectedTotal = 12 + 5 + compressedLength;

  if (buffer.length < expectedTotal) {
    throw new Error(`Buffer too short: expected ${expectedTotal}, have ${buffer.length}`);
  }

  const props = buffer.slice(12, 17); // 5 байт props
  const lzmaData = buffer.slice(17, 17 + compressedLength);

  return new Promise((resolve, reject) => {
    const lzma = new LZMA();

    // Собираем заголовок LZMA: props (5) + uncompressed size (8 байт LE)
    const lzmaHeader = Buffer.alloc(13);
    props.copy(lzmaHeader, 0);
    lzmaHeader.writeBigUInt64LE(BigInt(uncompressedLength), 5);

    const fullLzmaStream = Buffer.concat([lzmaHeader, lzmaData]);

    lzma.decompress(fullLzmaStream, (result, error) => {
      if (error) {
        reject(error);
      } else {
        resolve(result);
      }
    });
  });
}


var BinaryKVParser = require('binarykvparser');

handlers[Language.StoreGetUserDataResponse] = async (body) => {
	let proto = decodeProto(Protos.CMsgStoreGetUserDataResponse, body);

	const result = await decompressValveLZMA(proto.price_sheet);

	const parsed = BinaryKVParser.parse(result);


}

I hope it will save time for someone

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...