├── .gitignore ├── BitStream.js ├── LICENSE ├── README.md ├── build ├── protos.json ├── rapier.js ├── rapier.min.js └── types.json ├── dev └── synchronous.js ├── entities.js ├── examples ├── client.html └── server.js ├── generateTypes.js ├── huffman.js ├── package.json ├── packets.js ├── parser.js ├── proto ├── base_gcmessages.proto ├── c_peer2peer_netmessages.proto ├── connectionless_netmessages.proto ├── demo.proto ├── dota_broadcastmessages.proto ├── dota_clientmessages.proto ├── dota_commonmessages.proto ├── dota_gcmessages_client.proto ├── dota_gcmessages_client_fantasy.proto ├── dota_gcmessages_common.proto ├── dota_gcmessages_server.proto ├── dota_modifiers.proto ├── dota_usermessages.proto ├── econ_gcmessages.proto ├── gameevents.proto ├── gcsdk_gcmessages.proto ├── gcsystemmsgs.proto ├── netmessages.proto ├── network_connection.proto ├── networkbasetypes.proto ├── networksystem_protomessages.proto ├── rendermessages.proto ├── steamdatagram_messages.proto ├── steammessages.proto ├── steammessages_cloud.steamworkssdk.proto ├── steammessages_oauth.steamworkssdk.proto ├── steammessages_unified_base.steamworkssdk.proto ├── te.proto ├── toolevents.proto └── usermessages.proto ├── snappy.js ├── stringTables.js ├── test_js_parser.sh ├── update_proto.sh └── util.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | output.json 30 | -------------------------------------------------------------------------------- /BitStream.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts a given buffer of bytes to a stream of bits and provides methods for reading individual bits (non-aligned reads) 3 | **/ 4 | //var Long = require('long'); 5 | //accepts a native buffer object or a bytebuffer 6 | module.exports = function(buf) { 7 | var ret = { 8 | offset: buf.offset ? buf.offset * 8 : 0, 9 | limit: buf.limit ? buf.limit * 8 : buf.length * 8, 10 | bytes: buf.buffer || buf, 11 | readBits: readBits, 12 | readBuffer: readBuffer, 13 | readBoolean: readBoolean, 14 | readNullTerminatedString: readNullTerminatedString, 15 | readUInt8: readUInt8, 16 | readUBitVar: readUBitVar, 17 | readVarUInt: readVarUInt, 18 | readVarUInt64: readVarUInt64, 19 | readVarInt: readVarInt 20 | }; 21 | /** 22 | * Reads the specified number of bits (possibly non-aligned) and returns as 32bit int 23 | **/ 24 | function readBits(n) { 25 | /* 26 | if (n > (ret.limit - ret.offset)) { 27 | throw "not enough bits left in stream to read!"; 28 | } 29 | */ 30 | var bitOffset = ret.offset % 8; 31 | var bitsToRead = bitOffset + n; 32 | var bytesToRead = ~~(bitsToRead / 8); 33 | //if reading a multiple of 8 bits, read an additional byte 34 | if (bitsToRead % 8) { 35 | bytesToRead += 1; 36 | } 37 | var value = null; 38 | if (!bitOffset && n === 8) { 39 | //if we are byte-aligned and only want one byte, we can read quickly without shifting operations 40 | value = ret.bytes.readUInt8(ret.offset / 8); 41 | } 42 | //32 bit shifting 43 | else if (bitsToRead <= 31) { 44 | value = 0; 45 | //console.error(bits, ret.offset, bitOffset, bitsToRead,bytesToRead); 46 | for (var i = 0; i < bytesToRead; i++) { 47 | //extract the byte from the backing buffer 48 | var m = ret.bytes[~~(ret.offset / 8) + i]; 49 | //move these 8 bits to the correct location 50 | //looks like most significant 8 bits come last, so this flips endianness 51 | value += (m << (i * 8)); 52 | } 53 | //drop the extra bits, since we started from the beginning of the byte regardless of offset 54 | value >>= bitOffset; 55 | //shift a single 1 over, subtract 1 to form a bit mask that removes the first bit 56 | value &= ((1 << n) - 1); 57 | } 58 | else { 59 | //trying to read 32+ bits with native JS probably won't work due to 32 bit limit on shift operations 60 | //this means in practice we may have difficulty with n >= 25 bits (since offset can be up to 7) 61 | //can't fit that into a 32 bit int unless we use JS Long, which is slow 62 | console.error(bitsToRead); 63 | throw "requires long to read >32 bits from bitstream!"; 64 | /* 65 | //64 bit shifting, we only need this if our operations cant fit into 32 bits 66 | value = new Long(); 67 | //console.error(bits, ret.offset, bitOffset, bitsToRead,bytesToRead); 68 | for (var i = 0; i < bytesToRead; i++) { 69 | //extract the byte from the backing buffer 70 | var m64 = ret.bytes[~~(ret.offset / 8) + i]; 71 | //console.error(m, ret.bytes); 72 | //copy m into a 64bit holder so we can shift bits around more 73 | m64 = new Long.fromNumber(m64); 74 | //shift to get the bits we want 75 | value = value.add(m64.shiftLeft(i * 8)); 76 | } 77 | value = value.shiftRight(bitOffset); 78 | //shift a single 1 over, subtract 1 to form a bit mask 79 | value = value.and((1 << n) - 1); 80 | value = value.toInt(); 81 | */ 82 | } 83 | ret.offset += n; 84 | return value; 85 | } 86 | /** 87 | * Reads the specified number of bits into a Buffer and returns 88 | **/ 89 | function readBuffer(bits) { 90 | var bytes = Math.ceil(bits / 8); 91 | var result = new Buffer(bytes); 92 | var offset = 0; 93 | result.length = bytes; 94 | while (bits > 0) { 95 | //read up to 8 bits at a time (we may read less at the end if not aligned) 96 | var bitsToRead = Math.min(bits, 8); 97 | result.writeUInt8(ret.readBits(bitsToRead), offset); 98 | offset += 1; 99 | bits -= bitsToRead; 100 | } 101 | return result; 102 | } 103 | 104 | function readBoolean() { 105 | return ret.readBits(1); 106 | } 107 | /** 108 | * Reads until we reach a null terminator character and returns the result as a string 109 | **/ 110 | function readNullTerminatedString() { 111 | var str = ""; 112 | while (true) { 113 | var byteInt = ret.readBits(8); 114 | if (!byteInt) { 115 | break; 116 | } 117 | var byteBuf = new Buffer(1); 118 | byteBuf.writeUInt8(byteInt); 119 | str += byteBuf.toString(); 120 | } 121 | //console.log(str); 122 | return str; 123 | } 124 | 125 | function readUInt8() { 126 | return ret.readBits(8); 127 | } 128 | /** 129 | * Reads an unsigned varint up to 2^32 from the stream 130 | **/ 131 | function readVarUInt() { 132 | var max = 32; 133 | var m = ((max + 6) / 7) * 7; 134 | var value = 0; 135 | var shift = 0; 136 | while (true) { 137 | var byte = ret.readBits(8); 138 | value |= (byte & 0x7F) << shift; 139 | shift += 7; 140 | if ((byte & 0x80) === 0 || shift == m) { 141 | return value; 142 | } 143 | } 144 | } 145 | /** 146 | * Reads an unsigned varint up to 2^64 from the stream 147 | **/ 148 | function readVarUInt64() { 149 | //TODO need to use Long to handle the return result 150 | var x; 151 | var s; 152 | for (var i = 0;; i++) { 153 | var b = ret.readUInt8(); 154 | if (b < 0x80) { 155 | if (i > 9 || (i == 9 && b > 1)) { 156 | throw "read overflow: varint overflows uint64"; 157 | } 158 | return x | b << s; 159 | } 160 | x |= b & 0x7f << s; 161 | s += 7; 162 | } 163 | } 164 | /** 165 | * Reads a signed varint up to 2^31 from the stream 166 | **/ 167 | function readVarInt() { 168 | var ux = ret.readVarUInt(); 169 | var x = ux >> 1; 170 | if (ux & 1 !== 0) { 171 | //invert x 172 | x = ~x; 173 | } 174 | return x; 175 | } 176 | /** 177 | * Reads a special bit var from the stream, used for packet id 178 | **/ 179 | function readUBitVar() { 180 | // Thanks to Robin Dietrich for providing a clean version of this code :-) 181 | // The header looks like this: [XY00001111222233333333333333333333] where everything > 0 is optional. 182 | // The first 2 bits (X and Y) tell us how much (if any) to read other than the 6 initial bits: 183 | // Y set -> read 4 184 | // X set -> read 8 185 | // X + Y set -> read 28 186 | var v = ret.readBits(6); 187 | //bitwise & 0x30 (0b110000) (determines whether the first two bits are set) 188 | switch (v & 0x30) { 189 | case 0x10: 190 | v = (v & 15) | (ret.readBits(4) << 4); 191 | break; 192 | case 0x20: 193 | v = (v & 15) | (ret.readBits(8) << 4); 194 | break; 195 | case 0x30: 196 | v = (v & 15) | (ret.readBits(28) << 4); 197 | break; 198 | } 199 | return v; 200 | } 201 | return ret; 202 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 The OpenDota Project 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rapier 2 | A JavaScript Dota 2 (Source 2) replay parsing library. 3 | 4 | It throws (exceptions) if incorrectly used. :) 5 | 6 | [![npm version](https://badge.fury.io/js/rapier.svg)](http://badge.fury.io/js/rapier) 7 | 8 | Why JavaScript? 9 | ---- 10 | * Can be used for both server-side and in-browser parsing (isomorphic design) 11 | * No JS replay parsing library yet 12 | 13 | Notes 14 | ---- 15 | * Rapier does not handle entities yet. Everything else (of interest) should be supported. 16 | * Performance of the library is relatively poor compared to other implementations. Part of this is likely due to lack of optimization and partly due to JS lacking types and slow bitwise operations. In exchange, you can develop and run your application fully in JavaScript. 17 | * This library is not currently in production use and is not actively maintained. 18 | 19 | API 20 | ---- 21 | * Rapier is designed to offer a very simple API. 22 | * Users simply attach event listeners with the names of the protobuf messages they're interested in. 23 | * Properties such as string tables, game event descriptors, and id->string mappings are exposed to allow the user to interpret the message. 24 | * Event names are listed under "dems" and "packets" in `build/types.json`, or refer to the original .proto files in `proto`. 25 | 26 | Event Overview 27 | ---- 28 | * DEM messages. The basic building block of the replay. 29 | * CDemoPacket, CDemoFullPacket, CDemoSignonPacket. These messages contain one or more packets. 30 | * Packets. Contain most of the interesting data in the replay. 31 | * User Messages. These include all chat. 32 | * Dota User Messages. These include objectives, map pings, and actions. 33 | * Game Events. These come in several flavors and their content/structure are interpreted by using the game event descriptors (available to the user) 34 | * Combat Log. Combat log entries are a type of game event. Some fields require the use of string tables (available to the user) to translate a number to a useful string ("npc_dota_hero_furion"). 35 | * Packet Entities. 36 | * CDemoFileInfo. This includes an end-of-game summary. 37 | * CDemoSpawnGroup. 38 | * CDemoSaveGame. 39 | 40 | Usage 41 | ---- 42 | * Node.js: `npm install rapier` 43 | * Browser: `` (you can grab the file and host it anywhere) 44 | 45 | Examples 46 | ---- 47 | Examples of server and client side parsing can be found in `examples` 48 | -------------------------------------------------------------------------------- /dev/synchronous.js: -------------------------------------------------------------------------------- 1 | //synchronous implementation, requires entire replay to be read into bytebuffer 2 | var bb = new ByteBuffer(); 3 | inStream.on('data', function(data) { 4 | //tack on the data 5 | bb.append(data); 6 | }); 7 | inStream.on('end', function() { 8 | console.log(bb); 9 | //prepare to read buffer 10 | bb.flip(); 11 | //first 8 bytes=header 12 | var header = readStringSync(8); 13 | console.log("header: %s", header); 14 | if (header.toString() !== "PBDEMS2\0") { 15 | throw "invalid header"; 16 | } 17 | //next 8 bytes: appear to be two int32s related to the size of the demo file 18 | var size1 = readUint32Sync(); 19 | var size2 = readUint32Sync(); 20 | console.log(size1, size2); 21 | var stop = false; 22 | var count = 0; 23 | //next bytes are messages that need to be decoded 24 | //read until stream is drained or stop on OnCDemoStop 25 | while (!stop) { 26 | var msg = readDemoMessageSync(); 27 | count += 1; 28 | stop = count > 1000; 29 | } 30 | }); 31 | 32 | function readDemoMessageSync() { 33 | // Read a command header, which includes both the message type 34 | // well as a flag to determine whether or not whether or not the 35 | // message is compressed with snappy. 36 | //command: = dota.EDemoCommands(p.reader.readVarUint32()) 37 | var command = readVarint32Sync(); 38 | var tick = readVarint32Sync(); 39 | var size = readVarint32Sync(); 40 | var buf = readBytesSync(size); 41 | console.log(command, tick, size); 42 | // Extract the type and compressed flag out of the command 43 | //msgType: = int32(command & ^ dota.EDemoCommands_DEM_IsCompressed) 44 | //msgCompressed: = (command & dota.EDemoCommands_DEM_IsCompressed) == dota.EDemoCommands_DEM_IsCompressed 45 | var msgType = command & ~dota.EDemoCommands.DEM_IsCompressed; 46 | var msgCompressed = (command & dota.EDemoCommands.DEM_IsCompressed) === dota.EDemoCommands.DEM_IsCompressed; 47 | // Read the tick that the message corresponds with. 48 | // tick: = p.reader.readVarUint32() 49 | // This appears to actually be an int32, where a -1 means pre-game. 50 | if (tick === 4294967295) { 51 | tick = 0; 52 | } 53 | // Read the size and following buffer. 54 | // If the buffer is compressed, decompress it with snappy. 55 | if (msgCompressed) { 56 | buf = snappy.uncompressSync(buf); 57 | } 58 | var msg = { 59 | tick: tick, 60 | typeId: msgType, 61 | size: size, 62 | isCompressed: msgCompressed, 63 | data: buf 64 | }; 65 | console.log(msg); 66 | return msg; 67 | } 68 | 69 | function readVarint32Sync() { 70 | return bb.readVarint32(); 71 | } 72 | 73 | function readStringSync(size) { 74 | return bb.readString(size); 75 | } 76 | 77 | function readUint32Sync() { 78 | return bb.readUint32(); 79 | } 80 | 81 | function readByteSync() { 82 | return bb.readByte(); 83 | } 84 | 85 | function readBytesSync(size) { 86 | var buf = bb.slice(bb.offset, bb.offset + size).toBuffer(); 87 | bb.offset += size; 88 | return buf; 89 | } -------------------------------------------------------------------------------- /examples/client.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Browser Parsing Demo 7 | 18 | 19 | 20 | 21 |
22 |

23 |

Drag a replay from your desktop on to the drop zone above to parse.

24 |

25 | 26 | 27 | 75 | 76 | -------------------------------------------------------------------------------- /examples/server.js: -------------------------------------------------------------------------------- 1 | var Parser = require('../parser'); 2 | //parser accepts a stream or buffer, returns an eventemitter 3 | var p = new Parser(process.stdin); 4 | //var p = new Parser(require('fs').readFileSync('./testfiles/1698148651_source2.dem')); 5 | //PROPERTIES 6 | //the parser exposes these properties in order to help you interpret the content of the messages 7 | var types = p.types; 8 | var gameEventDescriptors = p.gameEventDescriptors; 9 | var stringTables = p.stringTables; 10 | var entities = p.entities; 11 | //EVENTS 12 | //add an event listener with the name of the protobuf message in order to listen for it 13 | //full dem/packet listing is in build/types.json, or user can refer to original .proto files 14 | //WARNING: not every type listed is actually in the replay--it's automatically generated from enums in .protos! 15 | //- 16 | //game epilogue 17 | p.on("CDemoFileInfo", function(data) { 18 | console.log(data); 19 | }); 20 | //all chat 21 | p.on("CUserMessageSayText2", function(data) { 22 | console.log(data); 23 | }); 24 | //chat wheel 25 | p.on("CDOTAUserMsg_ChatWheel", function(data) { 26 | data.chat_message = types["EDOTAChatWheelMessage"][data.chat_message]; 27 | //console.log(data); 28 | }); 29 | //overhead events 30 | p.on("CDOTAUserMsg_OverheadEvent", function(data) { 31 | //console.log(data); 32 | }); 33 | //map pings 34 | p.on("CDOTAUserMsg_LocationPing", function(data) { 35 | //console.log(data); 36 | }); 37 | //objectives 38 | p.on("CDOTAUserMsg_ChatEvent", function(data) { 39 | //look up the type with DOTA_CHAT_MESSAGE 40 | data.name = types.DOTA_CHAT_MESSAGE[data.type]; 41 | //console.log(data); 42 | }); 43 | p.on("CDOTAUserMsg_CombatLogDataHLTV", function(data) { 44 | data.name = types.DOTA_COMBATLOG_TYPES[data.type] || data.type; 45 | //translate the following fields with the stringtable 46 | data.damage_source_name = getStringFromCombatLogNames(data.damage_source_name); 47 | data.target_name = getStringFromCombatLogNames(data.target_name); 48 | data.attacker_name = getStringFromCombatLogNames(data.attacker_name); 49 | data.inflictor_name = getStringFromCombatLogNames(data.inflictor_name); 50 | data.target_source_name = getStringFromCombatLogNames(data.target_source_name); 51 | data.value_name = getStringFromCombatLogNames(data.value); 52 | for (var key in data) { 53 | if (data[key] === null) { 54 | delete data[key]; 55 | } 56 | } 57 | //console.error(data); 58 | if (data.type > 19) { 59 | console.error(data); 60 | } 61 | console.log(JSON.stringify(data)); 62 | }); 63 | 64 | function getStringFromCombatLogNames(value) { 65 | var combatLogNames = stringTables.tablesByName["CombatLogNames"]; 66 | return combatLogNames.string_data[value] ? combatLogNames.string_data[value].key : value; 67 | } 68 | //gameevents 69 | //NO LONGER PRESENT IN REPLAYS AFTER 2015-10-9 70 | /* 71 | p.on("CMsgSource1LegacyGameEvent", function(data) { 72 | //get the event name from descriptor 73 | data.event_name = gameEventDescriptors[data.eventid].name; 74 | //use the descriptor to read the gameevent data and build a gameevent object 75 | var gameEvent = {}; 76 | data.keys.forEach(function(k, i) { 77 | //each k is an object with an index and some values (one for each primitive, only one is populated) 78 | //we want to get the name of the property and which value to read based on the descriptor for this eventid 79 | var key = gameEventDescriptors[data.eventid].keys[i].name; 80 | var index = gameEventDescriptors[data.eventid].keys[i].type; 81 | //get the value of the key in object for that type 82 | var value = k[Object.keys(k)[index]]; 83 | //populate the gameevent 84 | gameEvent[key] = value; 85 | }); 86 | //combat log is a type of gameevent 87 | //gameevent types are not listed in the .protos, but are defined in the GameEventDescriptors contained within a replay 88 | //therefore we don't know what game event types are available or what data they contain until runtime 89 | if (data.event_name === "dota_combatlog") { 90 | var cle = gameEvent; 91 | //look up the type with DOTA_COMBATLOG_TYPES 92 | cle.name = types.DOTA_COMBATLOG_TYPES[cle.type]; 93 | //translate the entries using stringtable 94 | var combatLogNames = stringTables.tablesByName["CombatLogNames"]; 95 | //translate the following fields with the stringtable 96 | cle.sourcename = combatLogNames.string_data[cle.sourcename].key; 97 | cle.targetname = combatLogNames.string_data[cle.targetname].key; 98 | cle.attackername = combatLogNames.string_data[cle.attackername].key; 99 | cle.inflictorname = combatLogNames.string_data[cle.inflictorname].key; 100 | cle.targetsourcename = combatLogNames.string_data[cle.targetsourcename].key; 101 | //value needs a translation for certain types (for example, purchases), other times it's just an integer 102 | cle.valuename = combatLogNames[cle.value] ? combatLogNames[cle.value].key : null; 103 | if (cle.type === 14) { 104 | //console.log(cle); 105 | } 106 | } 107 | }); 108 | */ 109 | //every tick 110 | /* 111 | p.on("CNETMsg_Tick", function(data) { 112 | //console.log(data); 113 | }); 114 | */ 115 | //console data (includes some stun/slow data and damage breakdown by target/ability) 116 | /* 117 | p.on("CUserMessageTextMsg", function(data) { 118 | //console.log(data); 119 | }); 120 | */ 121 | //user actions 122 | /* 123 | p.on("CDOTAUserMsg_SpectatorPlayerUnitOrders", function(data) { 124 | console.log(data); 125 | }); 126 | */ 127 | //everything 128 | //each event is called with the protobuf message contents and the name of the message 129 | /* 130 | p.on("*", function(data, proto_name) { 131 | //console.log(data); 132 | counts[proto_name] = counts[proto_name] ? counts[proto_name] + 1 : 1; 133 | }); 134 | */ 135 | var counts = {}; 136 | console.time('parse'); 137 | //start takes a callback function that is called when the parse completes 138 | p.start(function(err) { 139 | if (err) { 140 | console.error(err); 141 | } 142 | console.error(counts); 143 | console.timeEnd('parse'); 144 | }); 145 | -------------------------------------------------------------------------------- /generateTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generates a mapping of ids to protobuf message names 3 | **/ 4 | var ProtoBuf = require('protobufjs'); 5 | var builder = ProtoBuf.newBuilder(); 6 | ProtoBuf.loadJsonFile("./build/protos.json", builder); 7 | var dota = builder.build(); 8 | //maintain a mapping for PacketTypes of id to string so we can emit events for different packet types. 9 | //we want to generate them automatically from the protobufs 10 | var packetEnums = { 11 | "NET_Messages": { 12 | abbr: "net_", 13 | full: "CNETMsg_" 14 | }, 15 | "SVC_Messages": { 16 | abbr: "svc_", 17 | full: "CSVCMsg_" 18 | }, 19 | "EBaseUserMessages": { 20 | abbr: "UM_", 21 | full: "CUserMessage" 22 | }, 23 | "EBaseEntityMessages": { 24 | abbr: "EM_", 25 | full: "CEntityMessage" 26 | }, 27 | "EBaseGameEvents": { 28 | abbr: "GE_", 29 | full: "CMsg" 30 | }, 31 | "EDotaUserMessages": { 32 | abbr: "DOTA_UM_", 33 | full: "CDOTAUserMsg_" 34 | } 35 | }; 36 | var demoEnums = { 37 | "EDemoCommands": { 38 | abbr: "DEM_", 39 | full: "CDemo", 40 | } 41 | }; 42 | var types = { 43 | packets: generate(packetEnums), 44 | dems: generate(demoEnums) 45 | }; 46 | for (var key in dota) { 47 | //don't try to build mapping if function 48 | //otherwise reverse the enum to help interpret ids 49 | if (typeof dota[key][Object.keys(dota[key])[0]] !== "function") { 50 | types[key] = reverse(dota[key]); 51 | } 52 | } 53 | process.stdout.write(JSON.stringify(types, null, 2)); 54 | 55 | function generate(enums) { 56 | //using the dota object, each dota[enumName] is an object mapping an internal name to its packet number 57 | //enum EBaseUserMessages { 58 | //UM_AchievementEvent = 101; 59 | //process into -> CUserMessageAchievementEvent 60 | var types = {}; 61 | for (var key in enums) { 62 | var obj = dota[key]; 63 | for (var key2 in obj) { 64 | var protoName = key2.replace(enums[key].abbr, enums[key].full); 65 | types[obj[key2]] = protoName; 66 | } 67 | } 68 | return types; 69 | } 70 | 71 | function reverse(en) { 72 | //accepts an object 73 | //flip the mapping to id->string 74 | var ret = {}; 75 | for (var key in en) { 76 | ret[en[key]] = key; 77 | } 78 | return ret; 79 | } -------------------------------------------------------------------------------- /huffman.js: -------------------------------------------------------------------------------- 1 | var Heap = require('heap'); 2 | /** 3 | * Given an array of counts, builds a huffman tree 4 | **/ 5 | function buildTree(counts) { 6 | //input as an array of weights 7 | //then value=index, weight=array[index] 8 | //construct the tree by using a priority queue (heap) 9 | var heap = new Heap(function(a, b) { 10 | return a.weight - b.weight; 11 | }); 12 | //push all the elements into the heap with custom comparator 13 | //pop them out in sorted order 14 | counts.forEach(function(w, i) { 15 | w = w || 1; 16 | heap.push(HuffmanNode({ 17 | weight: w, 18 | value: i 19 | })); 20 | }); 21 | var n = counts.length; 22 | while (heap.size() > 1) { 23 | //to build the tree: 24 | //pop two elements out 25 | //construct a new node with value=sum of the two, left/right children, then push the new node into the 26 | //repeat until heap only has one element left 27 | var a = heap.pop(); 28 | var b = heap.pop(); 29 | heap.push(HuffmanNode({ 30 | weight: a.weight + b.weight, 31 | value: n, 32 | left: a, 33 | right: b 34 | })); 35 | n += 1; 36 | } 37 | //this element is the root of the tree, return it 38 | return heap.pop(); 39 | } 40 | 41 | function HuffmanNode(options) { 42 | var self = {}; 43 | self.weight = options.w; 44 | self.value = options.v; 45 | self.left = options.left; 46 | self.right = options.right; 47 | self.isLeaf = function(){ 48 | return !self.left && !self.right; 49 | }; 50 | return self; 51 | } 52 | 53 | module.exports = buildTree; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rapier", 3 | "version": "1.0.5", 4 | "description": "A JavaScript Dota 2 (Source 2) replay parsing library.", 5 | "main": "parser.js", 6 | "directories": { 7 | "example": "example" 8 | }, 9 | "dependencies": { 10 | "async": "^1.5.0", 11 | "bytebuffer": "^5.0.0", 12 | "heap": "^0.2.6", 13 | "protobufjs": "4.1.3" 14 | }, 15 | "devDependencies": { 16 | "browserify": "^12.0.1", 17 | "json-loader": "^0.5.4", 18 | "uglify-js": "^2.6.1", 19 | "watchify": "^3.6.1" 20 | }, 21 | "scripts": { 22 | "test": "bash test_js_parser.sh", 23 | "browserify": "browserify ./Parser.js | uglifyjs > ./build/rapier.min.js && browserify ./Parser.js > ./build/rapier.js", 24 | "watchify": "watchify ./Parser.js -o ./build/rapier.js", 25 | "update": "bash update_proto.sh", 26 | "pbjs": "pbjs ./proto/* > ./build/protos.json", 27 | "generateTypes": "node generateTypes.js > ./build/types.json", 28 | "build": "npm run update && npm run pbjs && npm run generateTypes && npm run browserify" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "git+https://github.com/yasp-dota/rapier.git" 33 | }, 34 | "keywords": [ 35 | "dota", 36 | "dota2", 37 | "dota 2", 38 | "replay", 39 | "parser", 40 | "parsing" 41 | ], 42 | "author": "", 43 | "license": "GPL-3.0", 44 | "bugs": { 45 | "url": "https://github.com/yasp-dota/rapier/issues" 46 | }, 47 | "homepage": "https://github.com/yasp-dota/rapier#readme" 48 | } 49 | -------------------------------------------------------------------------------- /packets.js: -------------------------------------------------------------------------------- 1 | var BitStream = require('./BitStream'); 2 | var util = require('./util'); 3 | var extractBuffer = util.extractBuffer; 4 | module.exports = function(p) { 5 | var dota = p.dota; 6 | var packetTypes = p.types.packets; 7 | p.on("CDemoSignonPacket", readCDemoPacket); 8 | p.on("CDemoPacket", readCDemoPacket); 9 | p.on("CDemoFullPacket", function(data) { 10 | //console.error(data); 11 | //readCDemoStringTables(data.string_table); 12 | readCDemoPacket(data.packet); 13 | }); 14 | //this packet sets up our game event descriptors 15 | p.on("CMsgSource1LegacyGameEventList", function(msg) { 16 | //console.error(data); 17 | var gameEventDescriptors = p.gameEventDescriptors; 18 | for (var i = 0; i < msg.descriptors.length; i++) { 19 | gameEventDescriptors[msg.descriptors[i].eventid] = msg.descriptors[i]; 20 | } 21 | }); 22 | /** 23 | * Processes a DEM message containing inner packets. 24 | * This is the main structure that contains all other data types in the demo file. 25 | **/ 26 | function readCDemoPacket(msg) { 27 | /* 28 | message CDemoPacket { 29 | optional int32 sequence_in = 1; 30 | optional int32 sequence_out_ack = 2; 31 | optional bytes data = 3; 32 | } 33 | */ 34 | var priorities = { 35 | "CNETMsg_Tick": -10, 36 | "CSVCMsg_CreateStringTable": -10, 37 | "CSVCMsg_UpdateStringTable": -10, 38 | "CNETMsg_SpawnGroup_Load": -10, 39 | "CSVCMsg_PacketEntities": 5, 40 | "CMsgSource1LegacyGameEvent": 10, 41 | "CMsgDOTACombatLogEntryHLTV": 10 42 | }; 43 | //the inner data of a CDemoPacket is raw bits (no longer byte aligned!) 44 | var packets = []; 45 | //extract the native buffer from the ByteBuffer decoded by protobufjs 46 | var buf = extractBuffer(msg.data); 47 | //convert the buffer object into a bitstream so we can read bits from it 48 | var bs = BitStream(buf); 49 | //read until less than 8 bits left 50 | while (bs.limit - bs.offset >= 8) { 51 | var t = bs.readUBitVar(); 52 | var s = bs.readVarUInt(); 53 | var d = bs.readBuffer(s * 8); 54 | var name = packetTypes[t]; 55 | var pack = { 56 | type: t, 57 | size: s, 58 | data: d, 59 | position: packets.length 60 | }; 61 | packets.push(pack); 62 | } 63 | //sort the inner packets by priority in order to ensure we parse dependent packets last 64 | packets.sort(function(a, b) { 65 | //we must use a stable sort here in order to preserve order of packets when possible (for example, string tables must be parsed in the correct order or their ids are no longer valid) 66 | var p1 = priorities[packetTypes[a.type]] || 0; 67 | var p2 = priorities[packetTypes[b.type]] || 0; 68 | if (p1 === p2) { 69 | return a.position - b.position; 70 | } 71 | return p1 - p2; 72 | }); 73 | for (var i = 0; i < packets.length; i++) { 74 | var packet = packets[i]; 75 | var packType = packet.type; 76 | if (packType in packetTypes) { 77 | //lookup the name of the proto message for this packet type 78 | var name = packetTypes[packType]; 79 | if (dota[name]) { 80 | if (p.isListening(name)) { 81 | packet.data = dota[name].decode(packet.data); 82 | p.emit("*", packet.data, name); 83 | p.emit(name, packet.data, name); 84 | } 85 | } 86 | else { 87 | //console.error("no proto definition for packet name %s", name); 88 | } 89 | } 90 | else { 91 | console.error("no proto name for packet type %s", packType); 92 | } 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /parser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Class creating a Source 2 Dota 2 replay parser 3 | **/ 4 | var ProtoBuf = require('protobufjs'); 5 | var snappy = require('./snappy'); 6 | var EventEmitter = require('events').EventEmitter; 7 | var async = require('async'); 8 | var stream = require('stream'); 9 | var types = require('./build/types.json'); 10 | var protos = require('./build/protos.json'); 11 | var demTypes = types.dems; 12 | //read the protobufs and build a dota object for reference 13 | var builder = ProtoBuf.newBuilder(); 14 | ProtoBuf.loadJson(protos, builder); 15 | var dota = builder.build(); 16 | //CDemoSignonPacket is a special case and should be decoded with CDemoPacket since it doesn't have its own protobuf 17 | //it appears that things like the gameeventlist and createstringtables calls are here? 18 | dota["CDemoSignonPacket"] = dota["CDemoPacket"]; 19 | dota["CDOTAUserMsg_CombatLogDataHLTV"] = dota["CMsgDOTACombatLogEntry"]; 20 | //console.error(Object.keys(dota)); 21 | var Parser = function(input, options) { 22 | //if a JS ArrayBuffer, convert to native node buffer 23 | if (input.byteLength) { 24 | input = new Buffer(input); 25 | } 26 | //wrap a passed buffer in a stream 27 | if (Buffer.isBuffer(input)) { 28 | var bufferStream = new stream.PassThrough(); 29 | bufferStream.end(input); 30 | input = bufferStream; 31 | } 32 | var stop = false; 33 | var p = new EventEmitter(); 34 | //the following properties are exposed to the user to help interpret messages 35 | p.types = types; 36 | p.dota = dota; 37 | p.classIdSize = 0; 38 | p.gameEventDescriptors = {}; 39 | p.classInfo = {}; 40 | p.serializers = {}; 41 | p.entities = {}; 42 | p.baselines = {}; 43 | p.stringTables = { 44 | tables: [], 45 | tablesByName: {} 46 | }; 47 | /** 48 | * Begins parsing the replay. 49 | **/ 50 | p.start = function start(cb) { 51 | input.on('end', function() { 52 | stop = true; 53 | input.removeAllListeners(); 54 | return cb(); 55 | }); 56 | async.series({ 57 | "header": function(cb) { 58 | readString(8, function(err, header) { 59 | //verify the file magic number is correct 60 | cb(err || header.toString() !== "PBDEMS2\0", header); 61 | }); 62 | }, 63 | //two uint32s related to replay size 64 | "size1": readUInt32, 65 | "size2": readUInt32, 66 | "demo": function(cb) { 67 | //keep parsing demo messages until it hits a stop condition 68 | async.until(function() { 69 | return stop; 70 | }, readDemoMessage, cb); 71 | } 72 | }, cb); 73 | }; 74 | /** 75 | * Returns whether there is an attached listener for this message name. 76 | **/ 77 | p.isListening = function isListening(name) { 78 | return p.listeners(name).length || p.listeners("*").length; 79 | }; 80 | /** 81 | * Given the current state of string tables and class info, updates the baseline state. 82 | * This is state that is maintained throughout the parse and is used as fallback when fetching entity properties. 83 | **/ 84 | p.updateInstanceBaseline = function updateInstanceBaseline() { 85 | //TODO 86 | // We can't update the instancebaseline until we have class info. 87 | if (!Object.keys(p.classInfo)) { 88 | return; 89 | } 90 | /* 91 | stringTable, ok := p.StringTables.GetTableByName("instancebaseline") 92 | if !ok { 93 | _debugf("skipping updateInstanceBaseline: no instancebaseline string table") 94 | return 95 | } 96 | 97 | // Iterate through instancebaseline table items 98 | for _, item := range stringTable.Items { 99 | 100 | // Get the class id for the string table item 101 | classId, err := atoi32(item.Key) 102 | if err != nil { 103 | _panicf("invalid instancebaseline key '%s': %s", item.Key, err) 104 | } 105 | 106 | // Get the class name 107 | className, ok := p.ClassInfo[classId] 108 | if !ok { 109 | _panicf("unable to find class info for instancebaseline key %d", classId) 110 | } 111 | 112 | // Create an entry in the map if needed 113 | if _, ok := p.ClassBaselines[classId]; !ok { 114 | p.ClassBaselines[classId] = NewProperties() 115 | } 116 | 117 | // Get the send table associated with the class. 118 | serializer, ok := p.serializers[className] 119 | if !ok { 120 | _panicf("unable to find send table %s for instancebaseline key %d", className, classId) 121 | } 122 | 123 | // Uncomment to dump fixtures 124 | //_dump_fixture("instancebaseline/1731962898_"+className+".rawbuf", item.Value) 125 | 126 | // Parse the properties out of the string table buffer and store 127 | // them as the class baseline in the Parser. 128 | if len(item.Value) > 0 { 129 | _debugfl(1, "Parsing entity baseline %v", serializer[0].Name) 130 | r := NewReader(item.Value) 131 | p.ClassBaselines[classId] = ReadProperties(r, serializer[0]) 132 | // Inline test the baselines 133 | if testLevel >= 1 && r.remBits() > 8 { 134 | _panicf("Too many bits remaining in baseline %v, %v", serializer[0].Name, r.remBits()) 135 | } 136 | } 137 | */ 138 | }; 139 | /** 140 | * Internal listeners to automatically process certain packets. 141 | * We abstract this away from the user so they don't need to worry about it. 142 | * For optimal speed we could allow the user to disable the ones they don't need 143 | **/ 144 | require("./packets")(p); 145 | require("./stringTables")(p); 146 | //require("./entities")(p); 147 | p.on("CDemoStop", function(data) { 148 | //don't stop on CDemoStop since some replays have CDemoGameInfo after it 149 | //stop = true; 150 | }); 151 | return p; 152 | /** 153 | * Reads the next DEM message from the replay (outer message) 154 | * This method is asynchronous since we may not have the entire message yet if streaming 155 | **/ 156 | function readDemoMessage(cb) { 157 | async.series({ 158 | command: readVarUInt, 159 | tick: readVarUInt, 160 | size: readVarUInt 161 | }, function(err, result) { 162 | if (err) { 163 | return cb(err); 164 | } 165 | readBuffer(result.size, function(err, buf) { 166 | // Read a command header, which includes both the message type 167 | // well as a flag to determine whether or not whether or not the 168 | // message is compressed with snappy. 169 | var command = result.command; 170 | var tick = result.tick; 171 | var size = result.size; 172 | // Extract the type and compressed flag out of the command 173 | //msgType: = int32(command & ^ dota.EDemoCommands_DEM_IsCompressed) 174 | //msgCompressed: = (command & dota.EDemoCommands_DEM_IsCompressed) == dota.EDemoCommands_DEM_IsCompressed 175 | var demType = command & ~dota.EDemoCommands.DEM_IsCompressed; 176 | var isCompressed = (command & dota.EDemoCommands.DEM_IsCompressed) === dota.EDemoCommands.DEM_IsCompressed; 177 | // Read the tick that the message corresponds with. 178 | //tick: = p.reader.readVarUint32() 179 | // This appears to actually be an int32, where a -1 means pre-game. 180 | /* 181 | if tick == 4294967295 { 182 | tick = 0 183 | } 184 | */ 185 | if (tick === 4294967295) { 186 | tick = 0; 187 | } 188 | if (isCompressed) { 189 | buf = snappy.uncompressSync(buf); 190 | } 191 | var dem = { 192 | tick: tick, 193 | type: demType, 194 | size: size, 195 | data: buf 196 | }; 197 | //console.error(dem); 198 | if (demType in demTypes) { 199 | //lookup the name of the protobuf message to decode with 200 | var name = demTypes[demType]; 201 | if (dota[name]) { 202 | if (p.isListening(name)) { 203 | dem.data = dota[name].decode(dem.data); 204 | p.emit("*", dem.data, name); 205 | p.emit(name, dem.data, name); 206 | } 207 | } 208 | else { 209 | console.error("no proto definition for dem type %s", demType); 210 | } 211 | } 212 | else { 213 | console.error("no proto name for dem type %s", demType); 214 | } 215 | return cb(err); 216 | }); 217 | }); 218 | } 219 | 220 | function readUInt8(cb) { 221 | readBuffer(1, function(err, buf) { 222 | cb(err, buf.readInt8(0)); 223 | }); 224 | } 225 | 226 | function readString(size, cb) { 227 | readBuffer(size, function(err, buf) { 228 | cb(err, buf.toString()); 229 | }); 230 | } 231 | 232 | function readUInt32(cb) { 233 | readBuffer(4, function(err, buf) { 234 | cb(err, buf.readUInt32LE(0)); 235 | }); 236 | } 237 | 238 | function readVarUInt(cb) { 239 | readUInt8(function(err, tmp) { 240 | if (tmp >= 0) { 241 | return cb(err, tmp); 242 | } 243 | var result = tmp & 0x7f; 244 | readUInt8(function(err, tmp) { 245 | if (tmp >= 0) { 246 | result |= tmp << 7; 247 | return cb(err, result); 248 | } 249 | else { 250 | result |= (tmp & 0x7f) << 7; 251 | readUInt8(function(err, tmp) { 252 | if (tmp >= 0) { 253 | result |= tmp << 14; 254 | return cb(err, result); 255 | } 256 | else { 257 | result |= (tmp & 0x7f) << 14; 258 | readUInt8(function(err, tmp) { 259 | if (tmp >= 0) { 260 | result |= tmp << 21; 261 | return cb(err, result); 262 | } 263 | else { 264 | result |= (tmp & 0x7f) << 21; 265 | readUInt8(function(err, tmp) { 266 | result |= tmp << 28; 267 | if (tmp < 0) { 268 | err = "malformed varint detected"; 269 | } 270 | return cb(err, result); 271 | }); 272 | } 273 | }); 274 | } 275 | }); 276 | } 277 | }); 278 | }); 279 | } 280 | 281 | function readBuffer(size, cb) { 282 | if (!size) { 283 | //return an empty buffer if reading 0 bytes 284 | return cb(null, new Buffer("")); 285 | } 286 | var buf = input.read(size); 287 | if (buf) { 288 | return cb(null, buf); 289 | } 290 | else { 291 | input.once('readable', function() { 292 | return readBuffer(size, cb); 293 | }); 294 | } 295 | } 296 | }; 297 | global.Parser = Parser; 298 | module.exports = Parser; 299 | -------------------------------------------------------------------------------- /proto/base_gcmessages.proto: -------------------------------------------------------------------------------- 1 | import "steammessages.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum EGCBaseMsg { 7 | k_EMsgGCSystemMessage = 4001; 8 | k_EMsgGCReplicateConVars = 4002; 9 | k_EMsgGCConVarUpdated = 4003; 10 | k_EMsgGCInviteToParty = 4501; 11 | k_EMsgGCInvitationCreated = 4502; 12 | k_EMsgGCPartyInviteResponse = 4503; 13 | k_EMsgGCKickFromParty = 4504; 14 | k_EMsgGCLeaveParty = 4505; 15 | k_EMsgGCServerAvailable = 4506; 16 | k_EMsgGCClientConnectToServer = 4507; 17 | k_EMsgGCGameServerInfo = 4508; 18 | k_EMsgGCError = 4509; 19 | k_EMsgGCReplay_UploadedToYouTube = 4510; 20 | k_EMsgGCLANServerAvailable = 4511; 21 | k_EMsgGCInviteToLobby = 4512; 22 | k_EMsgGCLobbyInviteResponse = 4513; 23 | } 24 | 25 | enum EGCBaseProtoObjectTypes { 26 | k_EProtoObjectPartyInvite = 1001; 27 | k_EProtoObjectLobbyInvite = 1002; 28 | } 29 | 30 | enum ECustomGameInstallStatus { 31 | k_ECustomGameInstallStatus_Unknown = 0; 32 | k_ECustomGameInstallStatus_Ready = 1; 33 | k_ECustomGameInstallStatus_Busy = 2; 34 | k_ECustomGameInstallStatus_FailedGeneric = 101; 35 | k_ECustomGameInstallStatus_FailedInternalError = 102; 36 | k_ECustomGameInstallStatus_RequestedTimestampTooOld = 103; 37 | k_ECustomGameInstallStatus_RequestedTimestampTooNew = 104; 38 | k_ECustomGameInstallStatus_CRCMismatch = 105; 39 | k_ECustomGameInstallStatus_FailedSteam = 106; 40 | k_ECustomGameInstallStatus_FailedCanceled = 107; 41 | } 42 | 43 | enum GC_BannedWordType { 44 | GC_BANNED_WORD_DISABLE_WORD = 0; 45 | GC_BANNED_WORD_ENABLE_WORD = 1; 46 | } 47 | 48 | message CGCStorePurchaseInit_LineItem { 49 | optional uint32 item_def_id = 1; 50 | optional uint32 quantity = 2; 51 | optional uint32 cost_in_local_currency = 3; 52 | optional uint32 purchase_type = 4; 53 | optional uint64 source_reference_id = 5; 54 | } 55 | 56 | message CMsgGCStorePurchaseInit { 57 | optional string country = 1; 58 | optional int32 language = 2; 59 | optional int32 currency = 3; 60 | repeated .CGCStorePurchaseInit_LineItem line_items = 4; 61 | } 62 | 63 | message CMsgGCStorePurchaseInitResponse { 64 | optional int32 result = 1; 65 | optional uint64 txn_id = 2; 66 | } 67 | 68 | message CMsgSystemBroadcast { 69 | optional string message = 1; 70 | } 71 | 72 | message CMsgClientPingData { 73 | repeated fixed32 relay_codes = 4 [packed = true]; 74 | repeated uint32 relay_pings = 5 [packed = true]; 75 | repeated uint32 region_codes = 8 [packed = true]; 76 | repeated uint32 region_pings = 9 [packed = true]; 77 | optional uint32 region_ping_failed_bitmask = 10; 78 | } 79 | 80 | message CMsgInviteToParty { 81 | optional fixed64 steam_id = 1; 82 | optional uint32 client_version = 2; 83 | optional uint32 team_id = 3; 84 | optional bool as_coach = 4; 85 | optional .CMsgClientPingData ping_data = 5; 86 | } 87 | 88 | message CMsgInviteToLobby { 89 | optional fixed64 steam_id = 1; 90 | optional uint32 client_version = 2; 91 | } 92 | 93 | message CMsgInvitationCreated { 94 | optional uint64 group_id = 1; 95 | optional fixed64 steam_id = 2; 96 | optional bool user_offline = 3; 97 | } 98 | 99 | message CMsgPartyInviteResponse { 100 | optional uint64 party_id = 1; 101 | optional bool accept = 2; 102 | optional uint32 client_version = 3; 103 | optional .CMsgClientPingData ping_data = 8; 104 | } 105 | 106 | message CMsgLobbyInviteResponse { 107 | optional fixed64 lobby_id = 1; 108 | optional bool accept = 2; 109 | optional uint32 client_version = 3; 110 | optional fixed64 custom_game_crc = 6; 111 | optional fixed32 custom_game_timestamp = 7; 112 | } 113 | 114 | message CMsgKickFromParty { 115 | optional fixed64 steam_id = 1; 116 | } 117 | 118 | message CMsgLeaveParty { 119 | } 120 | 121 | message CMsgCustomGameInstallStatus { 122 | optional .ECustomGameInstallStatus status = 1 [default = k_ECustomGameInstallStatus_Unknown]; 123 | optional string message = 2; 124 | optional fixed32 latest_timestamp_from_steam = 3; 125 | } 126 | 127 | message CMsgServerAvailable { 128 | optional .CMsgCustomGameInstallStatus custom_game_install_status = 1; 129 | } 130 | 131 | message CMsgLANServerAvailable { 132 | optional fixed64 lobby_id = 1; 133 | } 134 | 135 | message CSOEconGameAccountClient { 136 | optional uint32 additional_backpack_slots = 1 [default = 0]; 137 | optional bool trial_account = 2 [default = false]; 138 | optional bool eligible_for_online_play = 3 [default = true]; 139 | optional bool need_to_choose_most_helpful_friend = 4; 140 | optional bool in_coaches_list = 5; 141 | optional fixed32 trade_ban_expiration = 6; 142 | optional fixed32 duel_ban_expiration = 7; 143 | optional uint32 preview_item_def = 8 [default = 0]; 144 | optional bool made_first_purchase = 9 [default = false]; 145 | } 146 | 147 | message CSOItemCriteriaCondition { 148 | optional int32 op = 1; 149 | optional string field = 2; 150 | optional bool required = 3; 151 | optional float float_value = 4; 152 | optional string string_value = 5; 153 | } 154 | 155 | message CSOItemCriteria { 156 | optional uint32 item_level = 1; 157 | optional int32 item_quality = 2; 158 | optional bool item_level_set = 3; 159 | optional bool item_quality_set = 4; 160 | optional uint32 initial_inventory = 5; 161 | optional uint32 initial_quantity = 6; 162 | optional bool ignore_enabled_flag = 8; 163 | repeated .CSOItemCriteriaCondition conditions = 9; 164 | optional bool recent_only = 10; 165 | } 166 | 167 | message CSOItemRecipe { 168 | optional uint32 def_index = 1; 169 | optional string name = 2; 170 | optional string n_a = 3; 171 | optional string desc_inputs = 4; 172 | optional string desc_outputs = 5; 173 | optional string di_a = 6; 174 | optional string di_b = 7; 175 | optional string di_c = 8; 176 | optional string do_a = 9; 177 | optional string do_b = 10; 178 | optional string do_c = 11; 179 | optional bool requires_all_same_class = 12; 180 | optional bool requires_all_same_slot = 13; 181 | optional int32 class_usage_for_output = 14; 182 | optional int32 slot_usage_for_output = 15; 183 | optional int32 set_for_output = 16; 184 | repeated .CSOItemCriteria input_items_criteria = 20; 185 | repeated .CSOItemCriteria output_items_criteria = 21; 186 | repeated uint32 input_item_dupe_counts = 22; 187 | } 188 | 189 | message CMsgApplyStrangePart { 190 | optional uint64 strange_part_item_id = 1; 191 | optional uint64 item_item_id = 2; 192 | } 193 | 194 | message CMsgApplyPennantUpgrade { 195 | optional uint64 upgrade_item_id = 1; 196 | optional uint64 pennant_item_id = 2; 197 | } 198 | 199 | message CMsgApplyEggEssence { 200 | optional uint64 essence_item_id = 1; 201 | optional uint64 egg_item_id = 2; 202 | } 203 | 204 | message CSOEconItemAttribute { 205 | optional uint32 def_index = 1; 206 | optional uint32 value = 2; 207 | optional bytes value_bytes = 3; 208 | } 209 | 210 | message CSOEconItemEquipped { 211 | optional uint32 new_class = 1; 212 | optional uint32 new_slot = 2; 213 | } 214 | 215 | message CSOEconItem { 216 | optional uint64 id = 1; 217 | optional uint32 account_id = 2; 218 | optional uint32 inventory = 3; 219 | optional uint32 def_index = 4; 220 | optional uint32 quantity = 5 [default = 1]; 221 | optional uint32 level = 6 [default = 1]; 222 | optional uint32 quality = 7 [default = 4]; 223 | optional uint32 flags = 8 [default = 0]; 224 | optional uint32 origin = 9 [default = 0]; 225 | repeated .CSOEconItemAttribute attribute = 12; 226 | optional .CSOEconItem interior_item = 13; 227 | optional bool in_use = 14 [default = false]; 228 | optional uint32 style = 15 [default = 0]; 229 | optional uint64 original_id = 16 [default = 0]; 230 | repeated .CSOEconItemEquipped equipped_state = 18; 231 | } 232 | 233 | message CMsgSortItems { 234 | optional uint32 sort_type = 1; 235 | } 236 | 237 | message CSOEconClaimCode { 238 | optional uint32 account_id = 1; 239 | optional uint32 code_type = 2; 240 | optional uint32 time_acquired = 3; 241 | optional string code = 4; 242 | } 243 | 244 | message CMsgStoreGetUserData { 245 | optional fixed32 price_sheet_version = 1; 246 | } 247 | 248 | message CMsgStoreGetUserDataResponse { 249 | optional int32 result = 1; 250 | optional int32 currency = 2; 251 | optional string country = 3; 252 | optional fixed32 price_sheet_version = 4; 253 | optional uint64 experiment_data = 5 [default = 0]; 254 | optional int32 featured_item_idx = 6; 255 | optional bool show_hat_descriptions = 7 [default = true]; 256 | optional bytes price_sheet = 8; 257 | optional int32 default_item_sort = 9 [default = 0]; 258 | repeated uint32 popular_items = 10; 259 | } 260 | 261 | message CMsgUpdateItemSchema { 262 | optional bytes items_game = 1; 263 | optional fixed32 item_schema_version = 2; 264 | optional string items_game_url = 3; 265 | } 266 | 267 | message CMsgGCError { 268 | optional string error_text = 1; 269 | } 270 | 271 | message CMsgRequestInventoryRefresh { 272 | } 273 | 274 | message CMsgConVarValue { 275 | optional string name = 1; 276 | optional string value = 2; 277 | } 278 | 279 | message CMsgReplicateConVars { 280 | repeated .CMsgConVarValue convars = 1; 281 | } 282 | 283 | message CMsgReplayUploadedToYouTube { 284 | optional string youtube_url = 1; 285 | optional string youtube_account_name = 2; 286 | optional uint64 session_id = 3; 287 | } 288 | 289 | message CMsgConsumableExhausted { 290 | optional int32 item_def_id = 1; 291 | } 292 | 293 | message CMsgItemAcknowledged { 294 | optional uint32 account_id = 1; 295 | optional uint32 inventory = 2; 296 | optional uint32 def_index = 3; 297 | optional uint32 quality = 4; 298 | optional uint32 rarity = 5; 299 | optional uint32 origin = 6; 300 | } 301 | 302 | message CMsgSetPresetItemPosition { 303 | optional uint32 class_id = 1; 304 | optional uint32 preset_id = 2; 305 | optional uint32 slot_id = 3; 306 | optional uint64 item_id = 4; 307 | } 308 | 309 | message CMsgSetItemPositions { 310 | message ItemPosition { 311 | optional uint64 item_id = 1; 312 | optional uint32 position = 2; 313 | } 314 | 315 | repeated .CMsgSetItemPositions.ItemPosition item_positions = 1; 316 | } 317 | 318 | message CSOEconItemPresetInstance { 319 | optional uint32 class_id = 2 [(key_field) = true]; 320 | optional uint32 preset_id = 3 [(key_field) = true]; 321 | optional uint32 slot_id = 4 [(key_field) = true]; 322 | optional uint64 item_id = 5; 323 | } 324 | 325 | message CMsgSelectItemPresetForClass { 326 | optional uint32 class_id = 1; 327 | optional uint32 preset_id = 2; 328 | } 329 | 330 | message CMsgSelectItemPresetForClassReply { 331 | optional bool success = 1; 332 | } 333 | 334 | message CSOSelectedItemPreset { 335 | optional uint32 account_id = 1 [(key_field) = true]; 336 | optional uint32 class_id = 2 [(key_field) = true]; 337 | optional uint32 preset_id = 3; 338 | } 339 | 340 | message CMsgGCNameItemNotification { 341 | optional fixed64 player_steamid = 1; 342 | optional uint32 item_def_index = 2; 343 | optional string item_name_custom = 3; 344 | } 345 | 346 | message CMsgGCClientDisplayNotification { 347 | optional string notification_title_localization_key = 1; 348 | optional string notification_body_localization_key = 2; 349 | repeated string body_substring_keys = 3; 350 | repeated string body_substring_values = 4; 351 | } 352 | 353 | message CMsgGCShowItemsPickedUp { 354 | optional fixed64 player_steamid = 1; 355 | } 356 | 357 | message CMsgGCIncrementKillCountResponse { 358 | optional uint32 killer_account_id = 1 [(key_field) = true]; 359 | optional uint32 num_kills = 2; 360 | optional uint32 item_def = 3; 361 | optional uint32 level_type = 4; 362 | } 363 | 364 | message CSOEconItemDropRateBonus { 365 | optional uint32 account_id = 1 [(key_field) = true]; 366 | optional fixed32 expiration_date = 2; 367 | optional float bonus = 3 [(key_field) = true]; 368 | optional uint32 bonus_count = 4; 369 | optional uint64 item_id = 5; 370 | optional uint32 def_index = 6; 371 | optional uint32 seconds_left = 7; 372 | optional uint32 booster_type = 8 [(key_field) = true]; 373 | } 374 | 375 | message CSOEconItemLeagueViewPass { 376 | optional uint32 account_id = 1 [(key_field) = true]; 377 | optional uint32 league_id = 2 [(key_field) = true]; 378 | optional uint32 itemindex = 4; 379 | optional uint32 grant_reason = 5; 380 | } 381 | 382 | message CSOEconItemEventTicket { 383 | optional uint32 account_id = 1; 384 | optional uint32 event_id = 2; 385 | optional uint64 item_id = 3; 386 | } 387 | 388 | message CSOEconItemTournamentPassport { 389 | optional uint32 account_id = 1; 390 | optional uint32 league_id = 2; 391 | optional uint64 item_id = 3; 392 | optional uint32 original_purchaser_id = 4; 393 | optional uint32 passports_bought = 5; 394 | optional uint32 version = 6; 395 | optional uint32 def_index = 7; 396 | optional uint32 reward_flags = 8; 397 | } 398 | 399 | message CMsgGCItemPreviewItemBoughtNotification { 400 | optional uint32 item_def_index = 1; 401 | } 402 | 403 | message CMsgGCStorePurchaseCancel { 404 | optional uint64 txn_id = 1; 405 | } 406 | 407 | message CMsgGCStorePurchaseCancelResponse { 408 | optional uint32 result = 1; 409 | } 410 | 411 | message CMsgGCStorePurchaseFinalize { 412 | optional uint64 txn_id = 1; 413 | } 414 | 415 | message CMsgGCStorePurchaseFinalizeResponse { 416 | optional uint32 result = 1; 417 | repeated uint64 item_ids = 2; 418 | } 419 | 420 | message CMsgGCBannedWordListRequest { 421 | optional uint32 ban_list_group_id = 1; 422 | optional uint32 word_id = 2; 423 | } 424 | 425 | message CMsgGCBannedWord { 426 | optional uint32 word_id = 1; 427 | optional .GC_BannedWordType word_type = 2 [default = GC_BANNED_WORD_DISABLE_WORD]; 428 | optional string word = 3; 429 | } 430 | 431 | message CMsgGCBannedWordListResponse { 432 | optional uint32 ban_list_group_id = 1; 433 | repeated .CMsgGCBannedWord word_list = 2; 434 | } 435 | 436 | message CMsgGCToGCBannedWordListBroadcast { 437 | optional .CMsgGCBannedWordListResponse broadcast = 1; 438 | } 439 | 440 | message CMsgGCToGCBannedWordListUpdated { 441 | optional uint32 group_id = 1; 442 | } 443 | 444 | message CMsgGCToGCDirtySDOCache { 445 | optional uint32 sdo_type = 1; 446 | optional uint64 key_uint64 = 2; 447 | } 448 | 449 | message CMsgGCToGCDirtyMultipleSDOCache { 450 | optional uint32 sdo_type = 1; 451 | repeated uint64 key_uint64 = 2; 452 | } 453 | 454 | message CMsgGCToGCApplyLocalizationDiff { 455 | optional uint32 language = 1; 456 | optional string packed_diff = 2; 457 | } 458 | 459 | message CMsgGCToGCApplyLocalizationDiffResponse { 460 | optional bool success = 1; 461 | } 462 | 463 | message CMsgGCCollectItem { 464 | optional uint64 collection_item_id = 1; 465 | optional uint64 subject_item_id = 2; 466 | } 467 | 468 | message CMsgSDONoMemcached { 469 | } 470 | 471 | message CMsgGCToGCUpdateSQLKeyValue { 472 | optional string key_name = 1; 473 | } 474 | 475 | message CMsgGCToGCBroadcastConsoleCommand { 476 | optional string con_command = 1; 477 | } 478 | 479 | message CMsgGCServerVersionUpdated { 480 | optional uint32 server_version = 1; 481 | } 482 | 483 | message CMsgGCClientVersionUpdated { 484 | optional uint32 client_version = 1; 485 | } 486 | 487 | message CMsgGCToGCWebAPIAccountChanged { 488 | } 489 | 490 | message CMsgRecipeComponent { 491 | optional uint64 subject_item_id = 1; 492 | optional uint64 attribute_index = 2; 493 | } 494 | 495 | message CMsgFulfillDynamicRecipeComponent { 496 | optional uint64 tool_item_id = 1; 497 | repeated .CMsgRecipeComponent consumption_components = 2; 498 | } 499 | 500 | message CMsgGCClientMarketDataRequest { 501 | optional uint32 user_currency = 1; 502 | } 503 | 504 | message CMsgGCClientMarketDataEntry { 505 | optional uint32 item_def_index = 1; 506 | optional uint32 item_quality = 2; 507 | optional uint32 item_sell_listings = 3; 508 | optional uint32 price_in_local_currency = 4; 509 | } 510 | 511 | message CMsgGCClientMarketData { 512 | repeated .CMsgGCClientMarketDataEntry entries = 1; 513 | } 514 | 515 | message CMsgExtractGems { 516 | optional uint64 tool_item_id = 1; 517 | optional uint64 item_item_id = 2; 518 | optional uint32 item_socket_id = 3 [default = 65535]; 519 | } 520 | 521 | message CMsgExtractGemsResponse { 522 | enum EExtractGems { 523 | k_ExtractGems_Succeeded = 0; 524 | k_ExtractGems_Failed_ToolIsInvalid = 1; 525 | k_ExtractGems_Failed_ItemIsInvalid = 2; 526 | k_ExtractGems_Failed_ToolCannotRemoveGem = 3; 527 | k_ExtractGems_Failed_FailedToRemoveGem = 4; 528 | } 529 | 530 | optional uint64 item_id = 1; 531 | optional .CMsgExtractGemsResponse.EExtractGems response = 2 [default = k_ExtractGems_Succeeded]; 532 | } 533 | 534 | message CMsgAddSocket { 535 | optional uint64 tool_item_id = 1; 536 | optional uint64 item_item_id = 2; 537 | optional bool unusual = 3; 538 | } 539 | 540 | message CMsgAddSocketResponse { 541 | enum EAddSocket { 542 | k_AddSocket_Succeeded = 0; 543 | k_AddSocket_Failed_ToolIsInvalid = 1; 544 | k_AddSocket_Failed_ItemCannotBeSocketed = 2; 545 | k_AddSocket_Failed_FailedToAddSocket = 3; 546 | } 547 | 548 | optional uint64 item_id = 1; 549 | repeated uint32 updated_socket_index = 2; 550 | optional .CMsgAddSocketResponse.EAddSocket response = 3 [default = k_AddSocket_Succeeded]; 551 | } 552 | 553 | message CMsgAddItemToSocketData { 554 | optional uint64 gem_item_id = 1; 555 | optional uint32 socket_index = 2; 556 | } 557 | 558 | message CMsgAddItemToSocket { 559 | optional uint64 item_item_id = 1; 560 | repeated .CMsgAddItemToSocketData gems_to_socket = 2; 561 | } 562 | 563 | message CMsgAddItemToSocketResponse { 564 | enum EAddGem { 565 | k_AddGem_Succeeded = 0; 566 | k_AddGem_Failed_GemIsInvalid = 1; 567 | k_AddGem_Failed_ItemIsInvalid = 2; 568 | k_AddGem_Failed_FailedToAddGem = 3; 569 | k_AddGem_Failed_InvalidGemTypeForSocket = 4; 570 | k_AddGem_Failed_InvalidGemTypeForHero = 5; 571 | k_AddGem_Failed_InvalidGemTypeForSlot = 6; 572 | k_AddGem_Failed_SocketContainsUnremovableGem = 7; 573 | } 574 | 575 | optional uint64 item_item_id = 1; 576 | repeated uint32 updated_socket_index = 2; 577 | optional .CMsgAddItemToSocketResponse.EAddGem response = 3 [default = k_AddGem_Succeeded]; 578 | } 579 | 580 | message CMsgResetStrangeGemCount { 581 | optional uint64 item_item_id = 1; 582 | optional uint32 socket_index = 2; 583 | } 584 | 585 | message CMsgResetStrangeGemCountResponse { 586 | enum EResetGem { 587 | k_ResetGem_Succeeded = 0; 588 | k_ResetGem_Failed_FailedToResetGem = 1; 589 | k_ResetGem_Failed_ItemIsInvalid = 2; 590 | k_ResetGem_Failed_InvalidSocketId = 3; 591 | k_ResetGem_Failed_SocketCannotBeReset = 4; 592 | } 593 | 594 | optional .CMsgResetStrangeGemCountResponse.EResetGem response = 1 [default = k_ResetGem_Succeeded]; 595 | } 596 | 597 | -------------------------------------------------------------------------------- /proto/c_peer2peer_netmessages.proto: -------------------------------------------------------------------------------- 1 | import "netmessages.proto"; 2 | 3 | option cc_generic_services = false; 4 | 5 | enum P2P_Messages { 6 | p2p_TextMessage = 256; 7 | p2p_Voice = 257; 8 | p2p_Ping = 258; 9 | } 10 | 11 | message CP2P_TextMessage { 12 | optional bytes text = 1; 13 | } 14 | 15 | message CSteam_Voice_Encoding { 16 | optional bytes voice_data = 1; 17 | } 18 | 19 | message CP2P_Voice { 20 | enum Handler_Flags { 21 | Played_Audio = 1; 22 | } 23 | 24 | optional .CMsgVoiceAudio audio = 1; 25 | optional uint32 broadcast_group = 2; 26 | } 27 | 28 | message CP2P_Ping { 29 | required uint64 send_time = 1; 30 | required bool is_reply = 2; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /proto/connectionless_netmessages.proto: -------------------------------------------------------------------------------- 1 | import "netmessages.proto"; 2 | 3 | option cc_generic_services = false; 4 | 5 | message C2S_CONNECT_Message { 6 | optional uint32 host_version = 1; 7 | optional uint32 auth_protocol = 2; 8 | optional uint32 challenge_number = 3; 9 | optional fixed64 reservation_cookie = 4; 10 | optional bool low_violence = 5; 11 | optional bytes encrypted_password = 6; 12 | repeated .CCLCMsg_SplitPlayerConnect splitplayers = 7; 13 | optional bytes auth_steam = 8; 14 | optional string challenge_context = 9; 15 | } 16 | 17 | message C2S_CONNECTION_Message { 18 | optional string addon_name = 1; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /proto/demo.proto: -------------------------------------------------------------------------------- 1 | option cc_generic_services = false; 2 | 3 | enum EDemoCommands { 4 | DEM_Error = -1; 5 | DEM_Stop = 0; 6 | DEM_FileHeader = 1; 7 | DEM_FileInfo = 2; 8 | DEM_SyncTick = 3; 9 | DEM_SendTables = 4; 10 | DEM_ClassInfo = 5; 11 | DEM_StringTables = 6; 12 | DEM_Packet = 7; 13 | DEM_SignonPacket = 8; 14 | DEM_ConsoleCmd = 9; 15 | DEM_CustomData = 10; 16 | DEM_CustomDataCallbacks = 11; 17 | DEM_UserCmd = 12; 18 | DEM_FullPacket = 13; 19 | DEM_SaveGame = 14; 20 | DEM_SpawnGroups = 15; 21 | DEM_Max = 16; 22 | DEM_IsCompressed = 64; 23 | } 24 | 25 | message CDemoFileHeader { 26 | required string demo_file_stamp = 1; 27 | optional int32 network_protocol = 2; 28 | optional string server_name = 3; 29 | optional string client_name = 4; 30 | optional string map_name = 5; 31 | optional string game_directory = 6; 32 | optional int32 fullpackets_version = 7; 33 | optional bool allow_clientside_entities = 8; 34 | optional bool allow_clientside_particles = 9; 35 | optional string addons = 10; 36 | } 37 | 38 | message CGameInfo { 39 | message CDotaGameInfo { 40 | message CPlayerInfo { 41 | optional string hero_name = 1; 42 | optional string player_name = 2; 43 | optional bool is_fake_client = 3; 44 | optional uint64 steamid = 4; 45 | optional int32 game_team = 5; 46 | } 47 | 48 | message CHeroSelectEvent { 49 | optional bool is_pick = 1; 50 | optional uint32 team = 2; 51 | optional uint32 hero_id = 3; 52 | } 53 | 54 | optional uint32 match_id = 1; 55 | optional int32 game_mode = 2; 56 | optional int32 game_winner = 3; 57 | repeated .CGameInfo.CDotaGameInfo.CPlayerInfo player_info = 4; 58 | optional uint32 leagueid = 5; 59 | repeated .CGameInfo.CDotaGameInfo.CHeroSelectEvent picks_bans = 6; 60 | optional uint32 radiant_team_id = 7; 61 | optional uint32 dire_team_id = 8; 62 | optional string radiant_team_tag = 9; 63 | optional string dire_team_tag = 10; 64 | optional uint32 end_time = 11; 65 | } 66 | 67 | optional .CGameInfo.CDotaGameInfo dota = 4; 68 | } 69 | 70 | message CDemoFileInfo { 71 | optional float playback_time = 1; 72 | optional int32 playback_ticks = 2; 73 | optional int32 playback_frames = 3; 74 | optional .CGameInfo game_info = 4; 75 | } 76 | 77 | message CDemoPacket { 78 | optional int32 sequence_in = 1; 79 | optional int32 sequence_out_ack = 2; 80 | optional bytes data = 3; 81 | } 82 | 83 | message CDemoFullPacket { 84 | optional .CDemoStringTables string_table = 1; 85 | optional .CDemoPacket packet = 2; 86 | } 87 | 88 | message CDemoSaveGame { 89 | optional bytes data = 1; 90 | optional fixed64 steam_id = 2; 91 | optional fixed64 signature = 3; 92 | optional int32 version = 4; 93 | } 94 | 95 | message CDemoSyncTick { 96 | } 97 | 98 | message CDemoConsoleCmd { 99 | optional string cmdstring = 1; 100 | } 101 | 102 | message CDemoSendTables { 103 | optional bytes data = 1; 104 | } 105 | 106 | message CDemoClassInfo { 107 | message class_t { 108 | optional int32 class_id = 1; 109 | optional string network_name = 2; 110 | optional string table_name = 3; 111 | } 112 | 113 | repeated .CDemoClassInfo.class_t classes = 1; 114 | } 115 | 116 | message CDemoCustomData { 117 | optional int32 callback_index = 1; 118 | optional bytes data = 2; 119 | } 120 | 121 | message CDemoCustomDataCallbacks { 122 | repeated string save_id = 1; 123 | } 124 | 125 | message CDemoStringTables { 126 | message items_t { 127 | optional string str = 1; 128 | optional bytes data = 2; 129 | } 130 | 131 | message table_t { 132 | optional string table_name = 1; 133 | repeated .CDemoStringTables.items_t items = 2; 134 | repeated .CDemoStringTables.items_t items_clientside = 3; 135 | optional int32 table_flags = 4; 136 | } 137 | 138 | repeated .CDemoStringTables.table_t tables = 1; 139 | } 140 | 141 | message CDemoStop { 142 | } 143 | 144 | message CDemoUserCmd { 145 | optional int32 cmd_number = 1; 146 | optional bytes data = 2; 147 | } 148 | 149 | message CDemoSpawnGroups { 150 | repeated bytes msgs = 3; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /proto/dota_broadcastmessages.proto: -------------------------------------------------------------------------------- 1 | option optimize_for = SPEED; 2 | option cc_generic_services = false; 3 | 4 | enum EDotaBroadcastMessages { 5 | DOTA_BM_LANLobbyRequest = 1; 6 | DOTA_BM_LANLobbyReply = 2; 7 | } 8 | 9 | message CDOTABroadcastMsg { 10 | required .EDotaBroadcastMessages type = 1 [default = DOTA_BM_LANLobbyRequest]; 11 | optional bytes msg = 2; 12 | } 13 | 14 | message CDOTABroadcastMsg_LANLobbyRequest { 15 | } 16 | 17 | message CDOTABroadcastMsg_LANLobbyReply { 18 | message CLobbyMember { 19 | optional uint32 account_id = 1; 20 | optional string player_name = 2; 21 | } 22 | 23 | optional uint64 id = 1; 24 | optional uint32 tournament_id = 2; 25 | optional uint32 tournament_game_id = 3; 26 | repeated .CDOTABroadcastMsg_LANLobbyReply.CLobbyMember members = 4; 27 | optional bool requires_pass_key = 5; 28 | optional uint32 leader_account_id = 6; 29 | optional uint32 game_mode = 7; 30 | optional string name = 8; 31 | optional uint32 players = 9; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /proto/dota_clientmessages.proto: -------------------------------------------------------------------------------- 1 | import "dota_commonmessages.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum EDotaClientMessages { 7 | DOTA_CM_MapLine = 301; 8 | DOTA_CM_AspectRatio = 302; 9 | DOTA_CM_MapPing = 303; 10 | DOTA_CM_UnitsAutoAttack = 304; 11 | DOTA_CM_AutoPurchaseItems = 305; 12 | DOTA_CM_TestItems = 306; 13 | DOTA_CM_SearchString = 307; 14 | DOTA_CM_Pause = 308; 15 | DOTA_CM_ShopViewMode = 309; 16 | DOTA_CM_SetUnitShareFlag = 310; 17 | DOTA_CM_SwapRequest = 311; 18 | DOTA_CM_SwapAccept = 312; 19 | DOTA_CM_WorldLine = 313; 20 | DOTA_CM_RequestGraphUpdate = 314; 21 | DOTA_CM_ItemAlert = 315; 22 | DOTA_CM_ChatWheel = 316; 23 | DOTA_CM_SendStatPopup = 317; 24 | DOTA_CM_BeginLastHitChallenge = 318; 25 | DOTA_CM_UpdateQuickBuy = 319; 26 | DOTA_CM_UpdateCoachListen = 320; 27 | DOTA_CM_CoachHUDPing = 321; 28 | DOTA_CM_RecordVote = 322; 29 | DOTA_CM_UnitsAutoAttackAfterSpell = 323; 30 | DOTA_CM_WillPurchaseAlert = 324; 31 | DOTA_CM_PlayerShowCase = 325; 32 | DOTA_CM_TeleportRequiresHalt = 326; 33 | DOTA_CM_CameraZoomAmount = 327; 34 | DOTA_CM_BroadcasterUsingCamerman = 328; 35 | DOTA_CM_BroadcasterUsingAssistedCameraOperator = 329; 36 | DOTA_CM_EnemyItemAlert = 330; 37 | DOTA_CM_FreeInventory = 331; 38 | DOTA_CM_BuyBackStateAlert = 332; 39 | DOTA_CM_QuickBuyAlert = 333; 40 | DOTA_CM_HeroStatueLike = 334; 41 | DOTA_CM_ModifierAlert = 335; 42 | DOTA_CM_TeamShowcaseEditor = 336; 43 | DOTA_CM_HPManaAlert = 337; 44 | DOTA_CM_GlyphAlert = 338; 45 | DOTA_CM_TeamShowcaseClientData = 339; 46 | DOTA_CM_PlayTeamShowcase = 340; 47 | DOTA_CM_EventCNY2015Cmd = 341; 48 | DOTA_CM_FillEmptySlotsWithBots = 342; 49 | DOTA_CM_DemoHero = 343; 50 | DOTA_CM_AbilityLearnModeToggled = 344; 51 | DOTA_CM_AbilityStartUse = 345; 52 | DOTA_CM_ChallengeSelect = 346; 53 | DOTA_CM_ChallengeReroll = 347; 54 | DOTA_CM_ClickedBuff = 348; 55 | DOTA_CM_CoinWager = 349; 56 | DOTA_CM_ExecuteOrders = 350; 57 | DOTA_CM_XPAlert = 351; 58 | DOTA_CM_GenericBooleanConvar = 352; 59 | } 60 | 61 | message CDOTAClientMsg_MapPing { 62 | optional .CDOTAMsg_LocationPing location_ping = 1; 63 | } 64 | 65 | message CDOTAClientMsg_ItemAlert { 66 | optional .CDOTAMsg_ItemAlert item_alert = 1; 67 | } 68 | 69 | message CDOTAClientMsg_EnemyItemAlert { 70 | optional uint32 item_entindex = 1; 71 | } 72 | 73 | message CDOTAClientMsg_ModifierAlert { 74 | optional int32 buff_internal_index = 1; 75 | optional uint32 target_entindex = 2; 76 | } 77 | 78 | message CDOTAClientMsg_ClickedBuff { 79 | optional int32 buff_internal_index = 1; 80 | optional uint32 target_entindex = 2; 81 | } 82 | 83 | message CDOTAClientMsg_HPManaAlert { 84 | optional uint32 target_entindex = 1; 85 | } 86 | 87 | message CDOTAClientMsg_GlyphAlert { 88 | optional bool negative = 1; 89 | } 90 | 91 | message CDOTAClientMsg_MapLine { 92 | optional .CDOTAMsg_MapLine mapline = 1; 93 | } 94 | 95 | message CDOTAClientMsg_AspectRatio { 96 | optional float ratio = 1; 97 | } 98 | 99 | message CDOTAClientMsg_UnitsAutoAttack { 100 | optional bool enabled = 1; 101 | } 102 | 103 | message CDOTAClientMsg_UnitsAutoAttackAfterSpell { 104 | optional bool enabled = 1; 105 | } 106 | 107 | message CDOTAClientMsg_TeleportRequiresHalt { 108 | optional bool enabled = 1; 109 | } 110 | 111 | message CDOTAClientMsg_GenericBooleanConvar { 112 | enum EType { 113 | FORCE_DEFAULT_RESPAWN_STINGER = 1; 114 | } 115 | 116 | optional .CDOTAClientMsg_GenericBooleanConvar.EType type = 1 [default = FORCE_DEFAULT_RESPAWN_STINGER]; 117 | optional bool value = 2; 118 | } 119 | 120 | message CDOTAClientMsg_AutoPurchaseItems { 121 | optional bool enabled = 1; 122 | } 123 | 124 | message CDOTAClientMsg_TestItems { 125 | optional string key_values = 1; 126 | } 127 | 128 | message CDOTAClientMsg_SearchString { 129 | optional string search = 1; 130 | } 131 | 132 | message CDOTAClientMsg_Pause { 133 | } 134 | 135 | message CDOTAClientMsg_ShopViewMode { 136 | optional uint32 mode = 1; 137 | } 138 | 139 | message CDOTAClientMsg_SetUnitShareFlag { 140 | optional uint32 playerID = 1; 141 | optional uint32 flag = 2; 142 | optional bool state = 3; 143 | } 144 | 145 | message CDOTAClientMsg_SwapRequest { 146 | optional uint32 player_id = 1; 147 | } 148 | 149 | message CDOTAClientMsg_SwapAccept { 150 | optional uint32 player_id = 1; 151 | } 152 | 153 | message CDOTAClientMsg_WorldLine { 154 | optional .CDOTAMsg_WorldLine worldline = 1; 155 | } 156 | 157 | message CDOTAClientMsg_RequestGraphUpdate { 158 | } 159 | 160 | message CDOTAClientMsg_ChatWheel { 161 | optional .EDOTAChatWheelMessage chat_message = 1 [default = k_EDOTA_CW_Ok]; 162 | optional uint32 param_hero_id = 2; 163 | } 164 | 165 | message CDOTAClientMsg_SendStatPopup { 166 | optional .CDOTAMsg_SendStatPopup statpopup = 1; 167 | } 168 | 169 | message CDOTAClientMsg_BeginLastHitChallenge { 170 | optional uint32 chosen_lane = 1; 171 | optional bool helper_enabled = 2; 172 | } 173 | 174 | message CDOTAClientMsg_UpdateQuickBuyItem { 175 | optional int32 item_type = 1; 176 | optional bool purchasable = 2; 177 | } 178 | 179 | message CDOTAClientMsg_UpdateQuickBuy { 180 | repeated .CDOTAClientMsg_UpdateQuickBuyItem items = 1; 181 | } 182 | 183 | message CDOTAClientMsg_UpdateCoachListen { 184 | optional uint32 player_mask = 1; 185 | } 186 | 187 | message CDOTAClientMsg_CoachHUDPing { 188 | optional .CDOTAMsg_CoachHUDPing hud_ping = 1; 189 | } 190 | 191 | message CDOTAClientMsg_RecordVote { 192 | optional int32 choice_index = 1; 193 | } 194 | 195 | message CDOTAClientMsg_WillPurchaseAlert { 196 | optional int32 itemid = 1; 197 | optional uint32 gold_remaining = 2; 198 | } 199 | 200 | message CDOTAClientMsg_BuyBackStateAlert { 201 | } 202 | 203 | message CDOTAClientMsg_QuickBuyAlert { 204 | optional int32 itemid = 1; 205 | optional int32 gold_required = 2; 206 | } 207 | 208 | message CDOTAClientMsg_PlayerShowCase { 209 | optional bool showcase = 1; 210 | } 211 | 212 | message CDOTAClientMsg_CameraZoomAmount { 213 | optional float zoom_amount = 1; 214 | } 215 | 216 | message CDOTAClientMsg_BroadcasterUsingCameraman { 217 | optional bool cameraman = 1; 218 | } 219 | 220 | message CDOTAClientMsg_BroadcasterUsingAssistedCameraOperator { 221 | optional bool enabled = 1; 222 | } 223 | 224 | message CAdditionalEquipSlotClientMsg { 225 | optional uint32 class_id = 1; 226 | optional uint32 slot_id = 2; 227 | optional uint32 def_index = 3; 228 | } 229 | 230 | message CDOTAClientMsg_FreeInventory { 231 | repeated .CAdditionalEquipSlotClientMsg equips = 1; 232 | } 233 | 234 | message CDOTAClientMsg_FillEmptySlotsWithBots { 235 | optional bool fillwithbots = 1; 236 | } 237 | 238 | message CDOTAClientMsg_HeroStatueLike { 239 | optional uint32 owner_player_id = 1; 240 | } 241 | 242 | message CDOTAClientMsg_TeamShowcaseEditor { 243 | optional bytes data = 1; 244 | } 245 | 246 | message CDOTAClientMsg_TeamShowcaseClientData { 247 | optional bytes data = 1; 248 | } 249 | 250 | message CDOTAClientMsg_PlayTeamShowcase { 251 | } 252 | 253 | message CDOTAClientMsg_EventCNY2015Cmd { 254 | optional bytes data = 1; 255 | } 256 | 257 | message CDOTAClientMsg_DemoHero { 258 | optional int32 hero_id = 1; 259 | optional int32 hero_id_to_spawn = 2; 260 | repeated uint32 item_defs = 3; 261 | repeated uint64 item_ids = 4; 262 | optional uint32 style_index = 5; 263 | optional bool keep_existing_demohero = 6; 264 | } 265 | 266 | message CDOTAClientMsg_ChallengeSelect { 267 | optional uint32 event_id = 1; 268 | optional uint32 slot_id = 2; 269 | optional uint32 sequence_id = 3; 270 | } 271 | 272 | message CDOTAClientMsg_ChallengeReroll { 273 | optional uint32 event_id = 1; 274 | optional uint32 slot_id = 2; 275 | optional uint32 sequence_id = 3; 276 | } 277 | 278 | message CDOTAClientMsg_CoinWager { 279 | optional uint32 wager_amount = 1; 280 | } 281 | 282 | message CDOTAClientMsg_ExecuteOrders { 283 | repeated .CDOTAMsg_UnitOrder orders = 1; 284 | } 285 | 286 | message CDOTAClientMsg_XPAlert { 287 | optional uint32 target_entindex = 1; 288 | } 289 | 290 | -------------------------------------------------------------------------------- /proto/dota_commonmessages.proto: -------------------------------------------------------------------------------- 1 | import "networkbasetypes.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum EDOTAChatWheelMessage { 7 | k_EDOTA_CW_Ok = 0; 8 | k_EDOTA_CW_Care = 1; 9 | k_EDOTA_CW_GetBack = 2; 10 | k_EDOTA_CW_NeedWards = 3; 11 | k_EDOTA_CW_Stun = 4; 12 | k_EDOTA_CW_Help = 5; 13 | k_EDOTA_CW_Push = 6; 14 | k_EDOTA_CW_GoodJob = 7; 15 | k_EDOTA_CW_Missing = 8; 16 | k_EDOTA_CW_Missing_Top = 9; 17 | k_EDOTA_CW_Missing_Mid = 10; 18 | k_EDOTA_CW_Missing_Bottom = 11; 19 | k_EDOTA_CW_Go = 12; 20 | k_EDOTA_CW_Initiate = 13; 21 | k_EDOTA_CW_Follow = 14; 22 | k_EDOTA_CW_Group_Up = 15; 23 | k_EDOTA_CW_Spread_Out = 16; 24 | k_EDOTA_CW_Split_Farm = 17; 25 | k_EDOTA_CW_Attack = 18; 26 | k_EDOTA_CW_BRB = 19; 27 | k_EDOTA_CW_Dive = 20; 28 | k_EDOTA_CW_OMW = 21; 29 | k_EDOTA_CW_Get_Ready = 22; 30 | k_EDOTA_CW_Bait = 23; 31 | k_EDOTA_CW_Heal = 24; 32 | k_EDOTA_CW_Mana = 25; 33 | k_EDOTA_CW_OOM = 26; 34 | k_EDOTA_CW_Skill_Cooldown = 27; 35 | k_EDOTA_CW_Ulti_Ready = 28; 36 | k_EDOTA_CW_Enemy_Returned = 29; 37 | k_EDOTA_CW_All_Missing = 30; 38 | k_EDOTA_CW_Enemy_Incoming = 31; 39 | k_EDOTA_CW_Invis_Enemy = 32; 40 | k_EDOTA_CW_Enemy_Had_Rune = 33; 41 | k_EDOTA_CW_Split_Push = 34; 42 | k_EDOTA_CW_Coming_To_Gank = 35; 43 | k_EDOTA_CW_Request_Gank = 36; 44 | k_EDOTA_CW_Fight_Under_Tower = 37; 45 | k_EDOTA_CW_Deny_Tower = 38; 46 | k_EDOTA_CW_Buy_Courier = 39; 47 | k_EDOTA_CW_Upgrade_Courier = 40; 48 | k_EDOTA_CW_Need_Detection = 41; 49 | k_EDOTA_CW_They_Have_Detection = 42; 50 | k_EDOTA_CW_Buy_TP = 43; 51 | k_EDOTA_CW_Reuse_Courier = 44; 52 | k_EDOTA_CW_Deward = 45; 53 | k_EDOTA_CW_Building_Mek = 46; 54 | k_EDOTA_CW_Building_Pipe = 47; 55 | k_EDOTA_CW_Stack_And_Pull = 48; 56 | k_EDOTA_CW_Pull = 49; 57 | k_EDOTA_CW_Pulling = 50; 58 | k_EDOTA_CW_Stack = 51; 59 | k_EDOTA_CW_Jungling = 52; 60 | k_EDOTA_CW_Roshan = 53; 61 | k_EDOTA_CW_Affirmative = 54; 62 | k_EDOTA_CW_Wait = 55; 63 | k_EDOTA_CW_Pause = 56; 64 | k_EDOTA_CW_Current_Time = 57; 65 | k_EDOTA_CW_Check_Runes = 58; 66 | k_EDOTA_CW_Smoke_Gank = 59; 67 | k_EDOTA_CW_GLHF = 60; 68 | k_EDOTA_CW_Nice = 61; 69 | k_EDOTA_CW_Thanks = 62; 70 | k_EDOTA_CW_Sorry = 63; 71 | k_EDOTA_CW_No_Give_Up = 64; 72 | k_EDOTA_CW_Just_Happened = 65; 73 | k_EDOTA_CW_Game_Is_Hard = 66; 74 | k_EDOTA_CW_New_Meta = 67; 75 | k_EDOTA_CW_My_Bad = 68; 76 | k_EDOTA_CW_Regret = 69; 77 | k_EDOTA_CW_Relax = 70; 78 | k_EDOTA_CW_MissingHero = 71; 79 | k_EDOTA_CW_ReturnedHero = 72; 80 | k_EDOTA_CW_GG = 73; 81 | k_EDOTA_CW_GGWP = 74; 82 | k_EDOTA_CW_All_GG = 75; 83 | k_EDOTA_CW_All_GGWP = 76; 84 | k_EDOTA_CW_What_To_Buy = 77; 85 | k_EDOTA_CW_Im_Retreating = 78; 86 | k_EDOTA_CW_Space_Created = 79; 87 | k_EDOTA_CW_Whoops = 80; 88 | k_EDOTA_CW_Tower_then_Back = 81; 89 | k_EDOTA_CW_Barracks_then_Back = 82; 90 | k_EDOTA_CW_Ward_Bottom_Rune = 83; 91 | k_EDOTA_CW_Ward_Top_Rune = 84; 92 | k_EDOTA_CW_Zeus_Ult = 85; 93 | } 94 | 95 | enum EDOTAStatPopupTypes { 96 | k_EDOTA_SPT_Textline = 0; 97 | k_EDOTA_SPT_Basic = 1; 98 | k_EDOTA_SPT_Poll = 2; 99 | k_EDOTA_SPT_Grid = 3; 100 | } 101 | 102 | enum dotaunitorder_t { 103 | DOTA_UNIT_ORDER_NONE = 0; 104 | DOTA_UNIT_ORDER_MOVE_TO_POSITION = 1; 105 | DOTA_UNIT_ORDER_MOVE_TO_TARGET = 2; 106 | DOTA_UNIT_ORDER_ATTACK_MOVE = 3; 107 | DOTA_UNIT_ORDER_ATTACK_TARGET = 4; 108 | DOTA_UNIT_ORDER_CAST_POSITION = 5; 109 | DOTA_UNIT_ORDER_CAST_TARGET = 6; 110 | DOTA_UNIT_ORDER_CAST_TARGET_TREE = 7; 111 | DOTA_UNIT_ORDER_CAST_NO_TARGET = 8; 112 | DOTA_UNIT_ORDER_CAST_TOGGLE = 9; 113 | DOTA_UNIT_ORDER_HOLD_POSITION = 10; 114 | DOTA_UNIT_ORDER_TRAIN_ABILITY = 11; 115 | DOTA_UNIT_ORDER_DROP_ITEM = 12; 116 | DOTA_UNIT_ORDER_GIVE_ITEM = 13; 117 | DOTA_UNIT_ORDER_PICKUP_ITEM = 14; 118 | DOTA_UNIT_ORDER_PICKUP_RUNE = 15; 119 | DOTA_UNIT_ORDER_PURCHASE_ITEM = 16; 120 | DOTA_UNIT_ORDER_SELL_ITEM = 17; 121 | DOTA_UNIT_ORDER_DISASSEMBLE_ITEM = 18; 122 | DOTA_UNIT_ORDER_MOVE_ITEM = 19; 123 | DOTA_UNIT_ORDER_CAST_TOGGLE_AUTO = 20; 124 | DOTA_UNIT_ORDER_STOP = 21; 125 | DOTA_UNIT_ORDER_TAUNT = 22; 126 | DOTA_UNIT_ORDER_BUYBACK = 23; 127 | DOTA_UNIT_ORDER_GLYPH = 24; 128 | DOTA_UNIT_ORDER_EJECT_ITEM_FROM_STASH = 25; 129 | DOTA_UNIT_ORDER_CAST_RUNE = 26; 130 | DOTA_UNIT_ORDER_PING_ABILITY = 27; 131 | DOTA_UNIT_ORDER_MOVE_TO_DIRECTION = 28; 132 | DOTA_UNIT_ORDER_PATROL = 29; 133 | } 134 | 135 | message CDOTAMsg_LocationPing { 136 | optional int32 x = 1; 137 | optional int32 y = 2; 138 | optional int32 target = 3; 139 | optional bool direct_ping = 4; 140 | optional int32 type = 5; 141 | } 142 | 143 | message CDOTAMsg_ItemAlert { 144 | optional int32 x = 1; 145 | optional int32 y = 2; 146 | optional int32 itemid = 3; 147 | } 148 | 149 | message CDOTAMsg_MapLine { 150 | optional int32 x = 1; 151 | optional int32 y = 2; 152 | optional bool initial = 3; 153 | } 154 | 155 | message CDOTAMsg_WorldLine { 156 | optional int32 x = 1; 157 | optional int32 y = 2; 158 | optional int32 z = 3; 159 | optional bool initial = 4; 160 | optional bool end = 5; 161 | } 162 | 163 | message CDOTAMsg_SendStatPopup { 164 | optional .EDOTAStatPopupTypes style = 1 [default = k_EDOTA_SPT_Textline]; 165 | repeated string stat_strings = 2; 166 | repeated int32 stat_images = 3; 167 | } 168 | 169 | message CDOTAMsg_CoachHUDPing { 170 | optional uint32 x = 1; 171 | optional uint32 y = 2; 172 | optional string tgtpath = 3; 173 | } 174 | 175 | message CDOTAMsg_UnitOrder { 176 | optional sint32 issuer = 1 [default = -1]; 177 | optional .dotaunitorder_t order_type = 2 [default = DOTA_UNIT_ORDER_NONE]; 178 | repeated int32 units = 3; 179 | optional int32 target_index = 4; 180 | optional int32 ability_index = 5; 181 | optional .CMsgVector position = 6; 182 | optional bool queue = 7; 183 | optional int32 sequence_number = 8; 184 | } 185 | 186 | -------------------------------------------------------------------------------- /proto/dota_modifiers.proto: -------------------------------------------------------------------------------- 1 | import "networkbasetypes.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum DOTA_MODIFIER_ENTRY_TYPE { 7 | DOTA_MODIFIER_ENTRY_TYPE_ACTIVE = 1; 8 | DOTA_MODIFIER_ENTRY_TYPE_REMOVED = 2; 9 | } 10 | 11 | message CDOTAModifierBuffTableEntry { 12 | required .DOTA_MODIFIER_ENTRY_TYPE entry_type = 1 [default = DOTA_MODIFIER_ENTRY_TYPE_ACTIVE]; 13 | required int32 parent = 2; 14 | required int32 index = 3; 15 | required int32 serial_num = 4; 16 | optional int32 modifier_class = 5; 17 | optional int32 ability_level = 6; 18 | optional int32 stack_count = 7; 19 | optional float creation_time = 8; 20 | optional float duration = 9 [default = -1]; 21 | optional int32 caster = 10; 22 | optional int32 ability = 11; 23 | optional int32 armor = 12; 24 | optional float fade_time = 13; 25 | optional bool subtle = 14; 26 | optional float channel_time = 15; 27 | optional .CMsgVector v_start = 16; 28 | optional .CMsgVector v_end = 17; 29 | optional string portal_loop_appear = 18; 30 | optional string portal_loop_disappear = 19; 31 | optional string hero_loop_appear = 20; 32 | optional string hero_loop_disappear = 21; 33 | optional int32 movement_speed = 22; 34 | optional bool aura = 23; 35 | optional int32 activity = 24; 36 | optional int32 damage = 25; 37 | optional int32 range = 26; 38 | optional int32 dd_modifier_index = 27; 39 | optional int32 dd_ability_index = 28; 40 | optional string illusion_label = 29; 41 | optional bool active = 30; 42 | optional string player_ids = 31; 43 | optional string lua_name = 32; 44 | } 45 | 46 | message CDOTALuaModifierEntry { 47 | required int32 modifier_type = 1; 48 | required string modifier_filename = 2; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /proto/econ_gcmessages.proto: -------------------------------------------------------------------------------- 1 | import "steammessages.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum EGCItemMsg { 7 | k_EMsgGCBase = 1000; 8 | k_EMsgGCSetItemPosition = 1001; 9 | k_EMsgGCCraft = 1002; 10 | k_EMsgGCCraftResponse = 1003; 11 | k_EMsgGCDelete = 1004; 12 | k_EMsgGCVerifyCacheSubscription = 1005; 13 | k_EMsgClientToGCNameItem = 1006; 14 | k_EMsgGCPaintItem = 1009; 15 | k_EMsgGCPaintItemResponse = 1010; 16 | k_EMsgGCGoldenWrenchBroadcast = 1011; 17 | k_EMsgGCMOTDRequest = 1012; 18 | k_EMsgGCMOTDRequestResponse = 1013; 19 | k_EMsgGCAddItemToSocket_DEPRECATED = 1014; 20 | k_EMsgGCAddItemToSocketResponse_DEPRECATED = 1015; 21 | k_EMsgGCAddSocketToBaseItem_DEPRECATED = 1016; 22 | k_EMsgGCAddSocketToItem_DEPRECATED = 1017; 23 | k_EMsgGCAddSocketToItemResponse_DEPRECATED = 1018; 24 | k_EMsgGCNameBaseItem = 1019; 25 | k_EMsgGCNameBaseItemResponse = 1020; 26 | k_EMsgGCRemoveSocketItem_DEPRECATED = 1021; 27 | k_EMsgGCRemoveSocketItemResponse_DEPRECATED = 1022; 28 | k_EMsgGCCustomizeItemTexture = 1023; 29 | k_EMsgGCCustomizeItemTextureResponse = 1024; 30 | k_EMsgGCUseItemRequest = 1025; 31 | k_EMsgGCUseItemResponse = 1026; 32 | k_EMsgGCGiftedItems = 1027; 33 | k_EMsgGCRemoveItemName = 1030; 34 | k_EMsgGCRemoveItemPaint = 1031; 35 | k_EMsgGCUnwrapGiftRequest = 1037; 36 | k_EMsgGCUnwrapGiftResponse = 1038; 37 | k_EMsgGCSetItemStyle_DEPRECATED = 1039; 38 | k_EMsgGCUsedClaimCodeItem = 1040; 39 | k_EMsgGCSortItems = 1041; 40 | k_EMsgGC_RevolvingLootList_DEPRECATED = 1042; 41 | k_EMsgGCUpdateItemSchema = 1049; 42 | k_EMsgGCRemoveCustomTexture = 1051; 43 | k_EMsgGCRemoveCustomTextureResponse = 1052; 44 | k_EMsgGCRemoveMakersMark = 1053; 45 | k_EMsgGCRemoveMakersMarkResponse = 1054; 46 | k_EMsgGCRemoveUniqueCraftIndex = 1055; 47 | k_EMsgGCRemoveUniqueCraftIndexResponse = 1056; 48 | k_EMsgGCSaxxyBroadcast = 1057; 49 | k_EMsgGCBackpackSortFinished = 1058; 50 | k_EMsgGCAdjustItemEquippedState = 1059; 51 | k_EMsgGCCollectItem = 1061; 52 | k_EMsgGCItemAcknowledged = 1062; 53 | k_EMsgGCPresets_SelectPresetForClass = 1063; 54 | k_EMsgGCPresets_SetItemPosition = 1064; 55 | k_EMsgGCPresets_SelectPresetForClassReply = 1067; 56 | k_EMsgClientToGCNameItemResponse = 1068; 57 | k_EMsgGCApplyConsumableEffects = 1069; 58 | k_EMsgGCConsumableExhausted = 1070; 59 | k_EMsgGCShowItemsPickedUp = 1071; 60 | k_EMsgGCClientDisplayNotification = 1072; 61 | k_EMsgGCApplyStrangePart = 1073; 62 | k_EMsgGC_IncrementKillCountResponse = 1075; 63 | k_EMsgGCApplyPennantUpgrade = 1076; 64 | k_EMsgGCSetItemPositions = 1077; 65 | k_EMsgGCSetItemPositions_RateLimited = 1096; 66 | k_EMsgGCApplyEggEssence = 1078; 67 | k_EMsgGCNameEggEssenceResponse = 1079; 68 | k_EMsgGCFulfillDynamicRecipeComponent = 1082; 69 | k_EMsgGCFulfillDynamicRecipeComponentResponse = 1083; 70 | k_EMsgGCClientRequestMarketData = 1084; 71 | k_EMsgGCClientRequestMarketDataResponse = 1085; 72 | k_EMsgGCExtractGems = 1086; 73 | k_EMsgGCAddSocket = 1087; 74 | k_EMsgGCAddItemToSocket = 1088; 75 | k_EMsgGCAddItemToSocketResponse = 1089; 76 | k_EMsgGCAddSocketResponse = 1090; 77 | k_EMsgGCResetStrangeGemCount = 1091; 78 | k_EMsgGCRequestCrateItems = 1092; 79 | k_EMsgGCRequestCrateItemsResponse = 1093; 80 | k_EMsgGCExtractGemsResponse = 1094; 81 | k_EMsgGCResetStrangeGemCountResponse = 1095; 82 | k_EMsgGCServerUseItemRequest = 1103; 83 | k_EMsgGCAddGiftItem = 1104; 84 | k_EMsgGCRemoveItemGiftMessage = 1105; 85 | k_EMsgGCRemoveItemGiftMessageResponse = 1106; 86 | k_EMsgGCRemoveItemGifterAccountId = 1107; 87 | k_EMsgGCRemoveItemGifterAccountIdResponse = 1108; 88 | k_EMsgClientToGCRemoveItemGifterAttributes = 1109; 89 | k_EMsgClientToGCRemoveItemName = 1110; 90 | k_EMsgClientToGCRemoveItemDescription = 1111; 91 | k_EMsgClientToGCRemoveItemAttributeResponse = 1112; 92 | k_EMsgGCTradingBase = 1500; 93 | k_EMsgGCTrading_InitiateTradeRequest = 1501; 94 | k_EMsgGCTrading_InitiateTradeResponse = 1502; 95 | k_EMsgGCTrading_StartSession = 1503; 96 | k_EMsgGCTrading_SessionClosed = 1509; 97 | k_EMsgGCTrading_InitiateTradeRequestResponse = 1514; 98 | k_EMsgGCServerBrowser_FavoriteServer = 1601; 99 | k_EMsgGCServerBrowser_BlacklistServer = 1602; 100 | k_EMsgGCServerRentalsBase = 1700; 101 | k_EMsgGCItemPreviewCheckStatus = 1701; 102 | k_EMsgGCItemPreviewStatusResponse = 1702; 103 | k_EMsgGCItemPreviewRequest = 1703; 104 | k_EMsgGCItemPreviewRequestResponse = 1704; 105 | k_EMsgGCItemPreviewExpire = 1705; 106 | k_EMsgGCItemPreviewExpireNotification = 1706; 107 | k_EMsgGCItemPreviewItemBoughtNotification = 1707; 108 | k_EMsgGCDev_NewItemRequest = 2001; 109 | k_EMsgGCDev_NewItemRequestResponse = 2002; 110 | k_EMsgGCStoreGetUserData = 2500; 111 | k_EMsgGCStoreGetUserDataResponse = 2501; 112 | k_EMsgGCStorePurchaseFinalize = 2504; 113 | k_EMsgGCStorePurchaseFinalizeResponse = 2505; 114 | k_EMsgGCStorePurchaseCancel = 2506; 115 | k_EMsgGCStorePurchaseCancelResponse = 2507; 116 | k_EMsgGCStorePurchaseInit = 2510; 117 | k_EMsgGCStorePurchaseInitResponse = 2511; 118 | k_EMsgGCBannedWordListRequest = 2512; 119 | k_EMsgGCBannedWordListResponse = 2513; 120 | k_EMsgGCToGCBannedWordListBroadcast = 2514; 121 | k_EMsgGCToGCBannedWordListUpdated = 2515; 122 | k_EMsgGCToGCDirtySDOCache = 2516; 123 | k_EMsgGCToGCDirtyMultipleSDOCache = 2517; 124 | k_EMsgGCToGCUpdateSQLKeyValue = 2518; 125 | k_EMsgGCToGCBroadcastConsoleCommand = 2521; 126 | k_EMsgGCServerVersionUpdated = 2522; 127 | k_EMsgGCApplyAutograph = 2523; 128 | k_EMsgGCToGCWebAPIAccountChanged = 2524; 129 | k_EMsgGCClientVersionUpdated = 2528; 130 | k_EMsgGCItemPurgatory_FinalizePurchase = 2531; 131 | k_EMsgGCItemPurgatory_FinalizePurchaseResponse = 2532; 132 | k_EMsgGCItemPurgatory_RefundPurchase = 2533; 133 | k_EMsgGCItemPurgatory_RefundPurchaseResponse = 2534; 134 | k_EMsgGCToGCPlayerStrangeCountAdjustments = 2535; 135 | k_EMsgGCRequestStoreSalesData = 2536; 136 | k_EMsgGCRequestStoreSalesDataResponse = 2537; 137 | k_EMsgGCRequestStoreSalesDataUpToDateResponse = 2538; 138 | k_EMsgGCToGCPingRequest = 2539; 139 | k_EMsgGCToGCPingResponse = 2540; 140 | k_EMsgGCToGCGetUserSessionServer = 2541; 141 | k_EMsgGCToGCGetUserSessionServerResponse = 2542; 142 | k_EMsgGCToGCGetUserServerMembers = 2543; 143 | k_EMsgGCToGCGetUserServerMembersResponse = 2544; 144 | k_EMsgGCToGCGetUserPCBangNo = 2545; 145 | k_EMsgGCToGCGetUserPCBangNoResponse = 2546; 146 | k_EMsgGCToGCCanUseDropRateBonus = 2547; 147 | k_EMsgSQLAddDropRateBonus = 2548; 148 | k_EMsgGCToGCRefreshSOCache = 2549; 149 | k_EMsgGCToGCApplyLocalizationDiff = 2550; 150 | k_EMsgGCToGCApplyLocalizationDiffResponse = 2551; 151 | k_EMsgGCToGCCheckAccountTradeStatus = 2552; 152 | k_EMsgGCToGCCheckAccountTradeStatusResponse = 2553; 153 | k_EMsgGCToGCGrantAccountRolledItems = 2554; 154 | k_EMsgGCToGCGrantSelfMadeItemToAccount = 2555; 155 | k_EMsgSQLUpgradeBattleBooster = 2556; 156 | k_EMsgGCPartnerBalanceRequest = 2557; 157 | k_EMsgGCPartnerBalanceResponse = 2558; 158 | k_EMsgGCPartnerRechargeRedirectURLRequest = 2559; 159 | k_EMsgGCPartnerRechargeRedirectURLResponse = 2560; 160 | k_EMsgGCStatueCraft = 2561; 161 | k_EMsgGCRedeemCode = 2562; 162 | k_EMsgGCRedeemCodeResponse = 2563; 163 | k_EMsgGCToGCItemConsumptionRollback = 2564; 164 | k_EMsgClientToGCWrapAndDeliverGift = 2565; 165 | k_EMsgClientToGCWrapAndDeliverGiftResponse = 2566; 166 | k_EMsgClientToGCUnpackBundleResponse = 2567; 167 | k_EMsgGCToClientStoreTransactionCompleted = 2568; 168 | k_EMsgClientToGCEquipItems = 2569; 169 | k_EMsgClientToGCEquipItemsResponse = 2570; 170 | k_EMsgClientToGCUnlockItemStyle = 2571; 171 | k_EMsgClientToGCUnlockItemStyleResponse = 2572; 172 | k_EMsgClientToGCSetItemInventoryCategory = 2573; 173 | k_EMsgClientToGCUnlockCrate = 2574; 174 | k_EMsgClientToGCUnlockCrateResponse = 2575; 175 | k_EMsgClientToGCUnpackBundle = 2576; 176 | k_EMsgClientToGCSetItemStyle = 2577; 177 | k_EMsgClientToGCSetItemStyleResponse = 2578; 178 | k_EMsgGCGenericResult = 2579; 179 | k_EMsgSQLGCToGCGrantBackpackSlots = 2580; 180 | k_EMsgClientToGCLookupAccountName = 2581; 181 | k_EMsgClientToGCLookupAccountNameResponse = 2582; 182 | } 183 | 184 | enum EGCMsgResponse { 185 | k_EGCMsgResponseOK = 0; 186 | k_EGCMsgResponseDenied = 1; 187 | k_EGCMsgResponseServerError = 2; 188 | k_EGCMsgResponseTimeout = 3; 189 | k_EGCMsgResponseInvalid = 4; 190 | k_EGCMsgResponseNoMatch = 5; 191 | k_EGCMsgResponseUnknownError = 6; 192 | k_EGCMsgResponseNotLoggedOn = 7; 193 | k_EGCMsgFailedToCreate = 8; 194 | } 195 | 196 | enum EItemPurgatoryResponse_Finalize { 197 | k_ItemPurgatoryResponse_Finalize_Succeeded = 0; 198 | k_ItemPurgatoryResponse_Finalize_Failed_Incomplete = 1; 199 | k_ItemPurgatoryResponse_Finalize_Failed_ItemsNotInPurgatory = 2; 200 | k_ItemPurgatoryResponse_Finalize_Failed_CouldNotFindItems = 3; 201 | k_ItemPurgatoryResponse_Finalize_Failed_NoSOCache = 4; 202 | k_ItemPurgatoryResponse_Finalize_BackpackFull = 5; 203 | } 204 | 205 | enum EItemPurgatoryResponse_Refund { 206 | k_ItemPurgatoryResponse_Refund_Succeeded = 0; 207 | k_ItemPurgatoryResponse_Refund_Failed_ItemNotInPurgatory = 1; 208 | k_ItemPurgatoryResponse_Refund_Failed_CouldNotFindItem = 2; 209 | k_ItemPurgatoryResponse_Refund_Failed_NoSOCache = 3; 210 | k_ItemPurgatoryResponse_Refund_Failed_NoDetail = 4; 211 | k_ItemPurgatoryResponse_Refund_Failed_NexonWebAPI = 5; 212 | } 213 | 214 | enum EGCPartnerRequestResponse { 215 | k_EPartnerRequestOK = 1; 216 | k_EPartnerRequestBadAccount = 2; 217 | k_EPartnerRequestNotLinked = 3; 218 | k_EPartnerRequestUnsupportedPartnerType = 4; 219 | } 220 | 221 | enum EGCMsgInitiateTradeResponse { 222 | k_EGCMsgInitiateTradeResponse_Accepted = 0; 223 | k_EGCMsgInitiateTradeResponse_Declined = 1; 224 | k_EGCMsgInitiateTradeResponse_VAC_Banned_Initiator = 2; 225 | k_EGCMsgInitiateTradeResponse_VAC_Banned_Target = 3; 226 | k_EGCMsgInitiateTradeResponse_Target_Already_Trading = 4; 227 | k_EGCMsgInitiateTradeResponse_Disabled = 5; 228 | k_EGCMsgInitiateTradeResponse_NotLoggedIn = 6; 229 | k_EGCMsgInitiateTradeResponse_Cancel = 7; 230 | k_EGCMsgInitiateTradeResponse_TooSoon = 8; 231 | k_EGCMsgInitiateTradeResponse_TooSoonPenalty = 9; 232 | k_EGCMsgInitiateTradeResponse_Trade_Banned_Initiator = 10; 233 | k_EGCMsgInitiateTradeResponse_Trade_Banned_Target = 11; 234 | k_EGCMsgInitiateTradeResponse_Free_Account_Initiator_DEPRECATED = 12; 235 | k_EGCMsgInitiateTradeResponse_Shared_Account_Initiator = 13; 236 | k_EGCMsgInitiateTradeResponse_Service_Unavailable = 14; 237 | k_EGCMsgInitiateTradeResponse_Target_Blocked = 15; 238 | k_EGCMsgInitiateTradeResponse_NeedVerifiedEmail = 16; 239 | k_EGCMsgInitiateTradeResponse_NeedSteamGuard = 17; 240 | k_EGCMsgInitiateTradeResponse_SteamGuardDuration = 18; 241 | k_EGCMsgInitiateTradeResponse_TheyCannotTrade = 19; 242 | k_EGCMsgInitiateTradeResponse_Recent_Password_Reset = 20; 243 | k_EGCMsgInitiateTradeResponse_Using_New_Device = 21; 244 | k_EGCMsgInitiateTradeResponse_Sent_Invalid_Cookie = 22; 245 | } 246 | 247 | message CMsgApplyAutograph { 248 | optional uint64 autograph_item_id = 1; 249 | optional uint64 item_item_id = 2; 250 | } 251 | 252 | message CMsgAdjustItemEquippedState { 253 | optional uint64 item_id = 1; 254 | optional uint32 new_class = 2; 255 | optional uint32 new_slot = 3; 256 | optional uint32 style_index = 4; 257 | } 258 | 259 | message CMsgEconPlayerStrangeCountAdjustment { 260 | message CStrangeCountAdjustment { 261 | optional uint32 event_type = 1; 262 | optional uint64 item_id = 2; 263 | optional uint32 adjustment = 3; 264 | } 265 | 266 | optional uint32 account_id = 1; 267 | repeated .CMsgEconPlayerStrangeCountAdjustment.CStrangeCountAdjustment strange_count_adjustments = 2; 268 | } 269 | 270 | message CMsgRequestItemPurgatory_FinalizePurchase { 271 | repeated uint64 item_ids = 1; 272 | } 273 | 274 | message CMsgRequestItemPurgatory_FinalizePurchaseResponse { 275 | optional uint32 result = 1; 276 | repeated uint64 item_ids = 2; 277 | } 278 | 279 | message CMsgRequestItemPurgatory_RefundPurchase { 280 | repeated uint64 item_ids = 1; 281 | } 282 | 283 | message CMsgRequestItemPurgatory_RefundPurchaseResponse { 284 | optional uint32 result = 1; 285 | } 286 | 287 | message CMsgCraftingResponse { 288 | repeated uint64 item_ids = 1; 289 | } 290 | 291 | message CMsgGCRequestStoreSalesData { 292 | optional uint32 version = 1; 293 | optional uint32 currency = 2; 294 | } 295 | 296 | message CMsgGCRequestStoreSalesDataResponse { 297 | message Price { 298 | optional uint32 item_def = 1; 299 | optional uint32 price = 2; 300 | } 301 | 302 | repeated .CMsgGCRequestStoreSalesDataResponse.Price sale_price = 1; 303 | optional uint32 version = 2; 304 | optional uint32 expiration_time = 3; 305 | } 306 | 307 | message CMsgGCRequestStoreSalesDataUpToDateResponse { 308 | optional uint32 version = 1; 309 | optional uint32 expiration_time = 2; 310 | } 311 | 312 | message CMsgGCToGCPingRequest { 313 | } 314 | 315 | message CMsgGCToGCPingResponse { 316 | } 317 | 318 | message CMsgGCToGCGetUserSessionServer { 319 | optional uint32 account_id = 1; 320 | } 321 | 322 | message CMsgGCToGCGetUserSessionServerResponse { 323 | optional fixed64 server_steam_id = 1; 324 | } 325 | 326 | message CMsgGCToGCGetUserServerMembers { 327 | optional uint32 account_id = 1; 328 | optional uint32 max_spectators = 2; 329 | } 330 | 331 | message CMsgGCToGCGetUserServerMembersResponse { 332 | repeated uint32 member_account_id = 1; 333 | } 334 | 335 | message CMsgLookupMultipleAccountNames { 336 | repeated uint32 accountids = 1 [packed = true]; 337 | } 338 | 339 | message CMsgLookupMultipleAccountNamesResponse { 340 | message Account { 341 | optional uint32 accountid = 1; 342 | optional string persona = 2; 343 | } 344 | 345 | repeated .CMsgLookupMultipleAccountNamesResponse.Account accounts = 1; 346 | } 347 | 348 | message CMsgGCToGCGetUserPCBangNo { 349 | optional uint32 account_id = 1; 350 | } 351 | 352 | message CMsgGCToGCGetUserPCBangNoResponse { 353 | optional uint32 pc_bang_no = 1; 354 | } 355 | 356 | message CMsgRequestCrateItems { 357 | optional uint32 crate_item_def = 1; 358 | } 359 | 360 | message CMsgRequestCrateItemsResponse { 361 | enum EResult { 362 | k_Succeeded = 0; 363 | k_Failed = 1; 364 | } 365 | 366 | optional uint32 response = 1; 367 | repeated uint32 item_defs = 2; 368 | } 369 | 370 | message CMsgGCToGCCanUseDropRateBonus { 371 | optional uint32 account_id = 1; 372 | optional float drop_rate_bonus = 2; 373 | optional uint32 booster_type = 3; 374 | optional uint32 exclusive_item_def = 4; 375 | optional bool allow_equal_rate = 5; 376 | } 377 | 378 | message CMsgSQLAddDropRateBonus { 379 | optional uint32 account_id = 1; 380 | optional uint64 item_id = 2; 381 | optional uint32 item_def = 3; 382 | optional float drop_rate_bonus = 4; 383 | optional uint32 booster_type = 5; 384 | optional uint32 seconds_duration = 6; 385 | optional uint32 end_time_stamp = 7; 386 | } 387 | 388 | message CMsgSQLUpgradeBattleBooster { 389 | optional uint32 account_id = 1; 390 | optional uint32 item_def = 2; 391 | optional float bonus_to_add = 3; 392 | optional uint32 booster_type = 4; 393 | } 394 | 395 | message CMsgGCToGCRefreshSOCache { 396 | optional uint32 account_id = 1; 397 | optional bool reload = 2; 398 | } 399 | 400 | message CMsgGCToGCCheckAccountTradeStatus { 401 | optional uint32 account_id = 1; 402 | optional bool initiator = 2; 403 | } 404 | 405 | message CMsgGCToGCCheckAccountTradeStatusResponse { 406 | optional bool can_trade = 1; 407 | optional uint32 error_code = 2; 408 | } 409 | 410 | message CMsgGCToGCGrantAccountRolledItems { 411 | message Item { 412 | message DynamicAttribute { 413 | optional string name = 1; 414 | optional uint32 value_uint32 = 2; 415 | optional float value_float = 3; 416 | } 417 | 418 | message AdditionalAuditEntry { 419 | optional uint32 owner_account_id = 1; 420 | optional uint32 audit_action = 2; 421 | optional uint32 audit_data = 3; 422 | } 423 | 424 | optional uint32 item_def = 1; 425 | repeated string loot_lists = 2; 426 | optional bool ignore_limit = 3; 427 | optional uint32 origin = 4; 428 | repeated .CMsgGCToGCGrantAccountRolledItems.Item.DynamicAttribute dynamic_attributes = 5; 429 | repeated .CMsgGCToGCGrantAccountRolledItems.Item.AdditionalAuditEntry additional_audit_entries = 6; 430 | optional uint32 inventory_token = 7; 431 | } 432 | 433 | optional uint32 account_id = 1; 434 | repeated .CMsgGCToGCGrantAccountRolledItems.Item items = 2; 435 | optional uint32 audit_action = 3; 436 | optional uint32 audit_data = 4; 437 | } 438 | 439 | message CMsgGCToGCGrantSelfMadeItemToAccount { 440 | optional uint32 item_def_index = 1; 441 | optional uint32 accountid = 2; 442 | } 443 | 444 | message CMsgUseItem { 445 | optional uint64 item_id = 1; 446 | optional fixed64 target_steam_id = 2; 447 | repeated uint32 gift__potential_targets = 3; 448 | optional uint32 duel__class_lock = 4; 449 | optional uint64 initiator_steam_id = 5; 450 | optional bool itempack__ack_immediately = 6; 451 | } 452 | 453 | message CMsgServerUseItem { 454 | optional uint32 initiator_account_id = 1; 455 | optional .CMsgUseItem use_item_msg = 2; 456 | } 457 | 458 | message CMsgGCPartnerBalanceRequest { 459 | } 460 | 461 | message CMsgGCPartnerBalanceResponse { 462 | optional .EGCPartnerRequestResponse result = 1 [default = k_EPartnerRequestOK]; 463 | optional uint32 balance = 2; 464 | } 465 | 466 | message CGCStoreRechargeRedirect_LineItem { 467 | optional uint32 item_def_id = 1; 468 | optional uint32 quantity = 2; 469 | } 470 | 471 | message CMsgGCPartnerRechargeRedirectURLRequest { 472 | repeated .CGCStoreRechargeRedirect_LineItem line_items = 1; 473 | } 474 | 475 | message CMsgGCPartnerRechargeRedirectURLResponse { 476 | optional .EGCPartnerRequestResponse result = 1 [default = k_EPartnerRequestOK]; 477 | optional string url = 2; 478 | } 479 | 480 | message CMsgGCEconSQLWorkItemEmbeddedRollbackData { 481 | optional uint32 account_id = 1; 482 | optional uint64 deleted_item_id = 2; 483 | } 484 | 485 | message CMsgCraftStatue { 486 | optional uint32 heroid = 1; 487 | optional string sequencename = 2; 488 | optional float cycle = 3; 489 | optional string description = 4; 490 | optional uint32 pedestal_itemdef = 5; 491 | optional uint64 toolid = 6; 492 | } 493 | 494 | message CMsgRedeemCode { 495 | optional string code = 1; 496 | } 497 | 498 | message CMsgRedeemCodeResponse { 499 | enum EResultCode { 500 | k_Succeeded = 0; 501 | k_Failed_CodeNotFound = 1; 502 | k_Failed_CodeAlreadyUsed = 2; 503 | k_Failed_OtherError = 3; 504 | } 505 | 506 | optional uint32 response = 1; 507 | optional uint64 item_id = 2; 508 | } 509 | 510 | message CMsgDevNewItemRequest { 511 | optional string item_def_name = 3; 512 | optional string loot_list_name = 4; 513 | repeated string attr_def_name = 5; 514 | repeated string attr_value = 6; 515 | } 516 | 517 | message CMsgDevNewItemRequestResponse { 518 | optional bool success = 1; 519 | } 520 | 521 | message CMsgGCAddGiftItem { 522 | optional uint32 account_id = 1; 523 | optional uint64 item_id = 2; 524 | } 525 | 526 | message CMsgClientToGCWrapAndDeliverGift { 527 | optional uint64 item_id = 1; 528 | optional uint32 give_to_account_id = 2; 529 | optional string gift_message = 3; 530 | } 531 | 532 | message CMsgClientToGCWrapAndDeliverGiftResponse { 533 | optional .EGCMsgResponse response = 1 [default = k_EGCMsgResponseOK]; 534 | optional uint32 gifting_charge_uses = 2; 535 | optional int32 gifting_charge_max = 3; 536 | optional uint32 gifting_uses = 4; 537 | optional int32 gifting_max = 5; 538 | optional uint32 gifting_window_hours = 6; 539 | optional .EGCMsgInitiateTradeResponse trade_restriction = 7 [default = k_EGCMsgInitiateTradeResponse_Accepted]; 540 | } 541 | 542 | message CMsgClientToGCUnwrapGift { 543 | optional uint64 item_id = 1; 544 | } 545 | 546 | message CMsgClientToGCUnpackBundle { 547 | optional uint64 item_id = 1; 548 | } 549 | 550 | message CMsgClientToGCUnpackBundleResponse { 551 | enum EUnpackBundle { 552 | k_UnpackBundle_Succeeded = 0; 553 | k_UnpackBundle_Failed_ItemIsNotBundle = 1; 554 | k_UnpackBundle_Failed_UnableToCreateContainedItem = 2; 555 | k_UnpackBundle_Failed_SOCacheError = 3; 556 | k_UnpackBundle_Failed_ItemIsInvalid = 4; 557 | k_UnpackBundle_Failed_BadItemQuantity = 5; 558 | k_UnpackBundle_Failed_UnableToDeleteItem = 6; 559 | } 560 | 561 | repeated uint64 unpacked_item_ids = 1; 562 | optional .CMsgClientToGCUnpackBundleResponse.EUnpackBundle response = 2 [default = k_UnpackBundle_Succeeded]; 563 | } 564 | 565 | message CMsgGCToClientStoreTransactionCompleted { 566 | optional uint64 txn_id = 1; 567 | repeated uint64 item_ids = 2; 568 | } 569 | 570 | message CMsgClientToGCEquipItems { 571 | repeated .CMsgAdjustItemEquippedState equips = 1; 572 | } 573 | 574 | message CMsgClientToGCEquipItemsResponse { 575 | optional fixed64 so_cache_version_id = 1; 576 | } 577 | 578 | message CMsgClientToGCSetItemStyle { 579 | optional uint64 item_id = 1; 580 | optional uint32 style_index = 2; 581 | } 582 | 583 | message CMsgClientToGCSetItemStyleResponse { 584 | enum ESetStyle { 585 | k_SetStyle_Succeeded = 0; 586 | k_SetStyle_Failed = 1; 587 | k_SetStyle_Failed_StyleIsLocked = 2; 588 | } 589 | 590 | optional .CMsgClientToGCSetItemStyleResponse.ESetStyle response = 1 [default = k_SetStyle_Succeeded]; 591 | } 592 | 593 | message CMsgClientToGCUnlockItemStyle { 594 | optional uint64 item_to_unlock = 1; 595 | optional uint32 style_index = 2; 596 | repeated uint64 consumable_item_ids = 3; 597 | } 598 | 599 | message CMsgClientToGCUnlockItemStyleResponse { 600 | enum EUnlockStyle { 601 | k_UnlockStyle_Succeeded = 0; 602 | k_UnlockStyle_Failed_PreReq = 1; 603 | k_UnlockStyle_Failed_CantAfford = 2; 604 | k_UnlockStyle_Failed_CantCommit = 3; 605 | k_UnlockStyle_Failed_CantLockCache = 4; 606 | k_UnlockStyle_Failed_CantAffordAttrib = 5; 607 | k_UnlockStyle_Failed_CantAffordGem = 6; 608 | k_UnlockStyle_Failed_NoCompendiumLevel = 7; 609 | k_UnlockStyle_Failed_AlreadyUnlocked = 8; 610 | k_UnlockStyle_Failed_OtherError = 9; 611 | k_UnlockStyle_Failed_ItemIsInvalid = 10; 612 | k_UnlockStyle_Failed_ToolIsInvalid = 11; 613 | } 614 | 615 | optional .CMsgClientToGCUnlockItemStyleResponse.EUnlockStyle response = 1 [default = k_UnlockStyle_Succeeded]; 616 | optional uint64 item_id = 2; 617 | optional uint32 style_index = 3; 618 | optional uint32 style_prereq = 4; 619 | } 620 | 621 | message CMsgClientToGCSetItemInventoryCategory { 622 | repeated uint64 item_ids = 1; 623 | optional uint32 set_to_value = 2; 624 | optional uint32 remove_categories = 3; 625 | optional uint32 add_categories = 4; 626 | } 627 | 628 | message CMsgClientToGCUnlockCrate { 629 | optional uint64 crate_item_id = 1; 630 | optional uint64 key_item_id = 2; 631 | } 632 | 633 | message CMsgClientToGCUnlockCrateResponse { 634 | message Item { 635 | optional uint64 item_id = 1; 636 | optional uint32 def_index = 2; 637 | } 638 | 639 | optional .EGCMsgResponse result = 1 [default = k_EGCMsgResponseOK]; 640 | repeated .CMsgClientToGCUnlockCrateResponse.Item granted_items = 2; 641 | } 642 | 643 | message CMsgClientToGCRemoveItemAttribute { 644 | optional uint64 item_id = 1; 645 | } 646 | 647 | message CMsgClientToGCRemoveItemAttributeResponse { 648 | enum ERemoveItemAttribute { 649 | k_RemoveItemAttribute_Succeeded = 0; 650 | k_RemoveItemAttribute_Failed = 1; 651 | k_RemoveItemAttribute_Failed_ItemIsInvalid = 2; 652 | k_RemoveItemAttribute_Failed_AttributeCannotBeRemoved = 3; 653 | k_RemoveItemAttribute_Failed_AttributeDoesntExist = 4; 654 | } 655 | 656 | optional .CMsgClientToGCRemoveItemAttributeResponse.ERemoveItemAttribute response = 1 [default = k_RemoveItemAttribute_Succeeded]; 657 | optional uint64 item_id = 2; 658 | } 659 | 660 | message CMsgClientToGCNameItem { 661 | optional uint64 subject_item_id = 1; 662 | optional uint64 tool_item_id = 2; 663 | optional string name = 3; 664 | } 665 | 666 | message CMsgClientToGCNameItemResponse { 667 | enum ENameItem { 668 | k_NameItem_Succeeded = 0; 669 | k_NameItem_Failed = 1; 670 | k_NameItem_Failed_ToolIsInvalid = 2; 671 | k_NameItem_Failed_ItemIsInvalid = 3; 672 | k_NameItem_Failed_NameIsInvalid = 4; 673 | } 674 | 675 | optional .CMsgClientToGCNameItemResponse.ENameItem response = 1 [default = k_NameItem_Succeeded]; 676 | optional uint64 item_id = 2; 677 | } 678 | 679 | message CMsgGCSetItemPosition { 680 | optional uint64 item_id = 1; 681 | optional uint32 new_position = 2; 682 | } 683 | 684 | message CAttribute_ItemDynamicRecipeComponent { 685 | optional uint32 item_def = 1; 686 | optional uint32 item_quality = 2; 687 | optional uint32 item_flags = 3; 688 | optional string attributes_string = 4; 689 | optional uint32 item_count = 5; 690 | optional uint32 items_fulfilled = 6; 691 | optional uint32 item_rarity = 7; 692 | optional string lootlist = 8; 693 | optional uint64 fulfilled_item_id = 9; 694 | } 695 | 696 | message CProtoItemSocket { 697 | optional uint64 item_id = 1; 698 | optional uint32 attr_def_index = 2; 699 | optional uint32 required_type = 3; 700 | optional string required_hero = 4; 701 | optional uint32 gem_def_index = 5; 702 | optional bool not_tradable = 6; 703 | optional string required_item_slot = 7; 704 | } 705 | 706 | message CProtoItemSocket_Empty { 707 | optional .CProtoItemSocket socket = 1; 708 | } 709 | 710 | message CProtoItemSocket_Effect { 711 | optional .CProtoItemSocket socket = 1; 712 | optional uint32 effect = 2; 713 | } 714 | 715 | message CProtoItemSocket_Color { 716 | optional .CProtoItemSocket socket = 1; 717 | optional uint32 red = 2; 718 | optional uint32 green = 3; 719 | optional uint32 blue = 4; 720 | } 721 | 722 | message CProtoItemSocket_Strange { 723 | optional .CProtoItemSocket socket = 1; 724 | optional uint32 strange_type = 2; 725 | optional uint32 strange_value = 3; 726 | } 727 | 728 | message CProtoItemSocket_Spectator { 729 | optional .CProtoItemSocket socket = 1; 730 | optional uint32 games_viewed = 2; 731 | optional uint32 corporation_id = 3; 732 | optional uint32 league_id = 4; 733 | optional uint32 team_id = 5; 734 | } 735 | 736 | message CProtoItemSocket_AssetModifier { 737 | optional .CProtoItemSocket socket = 1; 738 | optional uint32 asset_modifier = 2; 739 | } 740 | 741 | message CProtoItemSocket_AssetModifier_DESERIALIZE_FROM_STRING_ONLY { 742 | optional .CProtoItemSocket socket = 1; 743 | optional uint32 asset_modifier = 2; 744 | optional uint32 anim_modifier = 3; 745 | optional uint32 ability_effect = 4; 746 | } 747 | 748 | message CProtoItemSocket_Autograph { 749 | optional .CProtoItemSocket socket = 1; 750 | optional string autograph = 2; 751 | optional uint32 autograph_id = 3; 752 | optional uint32 autograph_score = 4; 753 | } 754 | 755 | message CProtoItemSocket_StaticVisuals { 756 | optional .CProtoItemSocket socket = 1; 757 | } 758 | 759 | message CAttribute_String { 760 | optional string value = 1; 761 | } 762 | 763 | message CWorkshop_GetItemDailyRevenue_Request { 764 | optional uint32 appid = 1; 765 | optional uint32 item_id = 2; 766 | optional uint32 date_start = 3; 767 | optional uint32 date_end = 4; 768 | } 769 | 770 | message CWorkshop_GetItemDailyRevenue_Response { 771 | message CountryDailyRevenue { 772 | optional string country_code = 1; 773 | optional uint32 date = 2; 774 | optional int64 revenue_usd = 3; 775 | optional int32 units = 4; 776 | } 777 | 778 | repeated .CWorkshop_GetItemDailyRevenue_Response.CountryDailyRevenue country_revenue = 1; 779 | } 780 | 781 | message CMsgGenericResult { 782 | optional uint32 eresult = 1 [default = 2]; 783 | } 784 | 785 | message CMsgSQLGCToGCGrantBackpackSlots { 786 | optional uint32 account_id = 1; 787 | optional uint32 add_slots = 2; 788 | } 789 | 790 | message CMsgClientToGCLookupAccountName { 791 | optional uint32 account_id = 1; 792 | } 793 | 794 | message CMsgClientToGCLookupAccountNameResponse { 795 | optional uint32 account_id = 1; 796 | optional string account_name = 2; 797 | } 798 | 799 | -------------------------------------------------------------------------------- /proto/gameevents.proto: -------------------------------------------------------------------------------- 1 | import "networkbasetypes.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum EBaseGameEvents { 7 | GE_VDebugGameSessionIDEvent = 200; 8 | GE_PlaceDecalEvent = 201; 9 | GE_ClearWorldDecalsEvent = 202; 10 | GE_ClearEntityDecalsEvent = 203; 11 | GE_ClearDecalsForSkeletonInstanceEvent = 204; 12 | GE_Source1LegacyGameEventList = 205; 13 | GE_Source1LegacyListenEvents = 206; 14 | GE_Source1LegacyGameEvent = 207; 15 | GE_SosStartSoundEvent = 208; 16 | GE_SosStopSoundEvent = 209; 17 | GE_SosSetSoundEventParams = 210; 18 | GE_SosSetLibraryStackFields = 211; 19 | GE_SosStopSoundEventHash = 212; 20 | } 21 | 22 | message CMsgVDebugGameSessionIDEvent { 23 | optional int32 clientid = 1; 24 | optional string gamesessionid = 2; 25 | } 26 | 27 | message CMsgPlaceDecalEvent { 28 | optional .CMsgVector position = 1; 29 | optional .CMsgVector normal = 2; 30 | optional .CMsgVector saxis = 3; 31 | optional uint32 decalmaterialindex = 4; 32 | optional uint32 flags = 5; 33 | optional fixed32 color = 6; 34 | optional float width = 7; 35 | optional float height = 8; 36 | optional float depth = 9; 37 | optional uint32 entityhandleindex = 10; 38 | optional fixed32 skeletoninstancehash = 11; 39 | optional int32 boneindex = 12; 40 | optional bool translucenthit = 13; 41 | } 42 | 43 | message CMsgClearWorldDecalsEvent { 44 | optional uint32 flagstoclear = 1; 45 | } 46 | 47 | message CMsgClearEntityDecalsEvent { 48 | optional uint32 flagstoclear = 1; 49 | } 50 | 51 | message CMsgClearDecalsForSkeletonInstanceEvent { 52 | optional uint32 flagstoclear = 1; 53 | optional uint32 entityhandleindex = 2; 54 | optional uint32 skeletoninstancehash = 3; 55 | } 56 | 57 | message CMsgSource1LegacyGameEventList { 58 | message key_t { 59 | optional int32 type = 1; 60 | optional string name = 2; 61 | } 62 | 63 | message descriptor_t { 64 | optional int32 eventid = 1; 65 | optional string name = 2; 66 | repeated .CMsgSource1LegacyGameEventList.key_t keys = 3; 67 | } 68 | 69 | repeated .CMsgSource1LegacyGameEventList.descriptor_t descriptors = 1; 70 | } 71 | 72 | message CMsgSource1LegacyListenEvents { 73 | optional int32 playerslot = 1; 74 | repeated uint32 eventarraybits = 2; 75 | } 76 | 77 | message CMsgSource1LegacyGameEvent { 78 | message key_t { 79 | optional int32 type = 1; 80 | optional string val_string = 2; 81 | optional float val_float = 3; 82 | optional int32 val_long = 4; 83 | optional int32 val_short = 5; 84 | optional int32 val_byte = 6; 85 | optional bool val_bool = 7; 86 | optional uint64 val_uint64 = 8; 87 | } 88 | 89 | optional string event_name = 1; 90 | optional int32 eventid = 2; 91 | repeated .CMsgSource1LegacyGameEvent.key_t keys = 3; 92 | } 93 | 94 | message CMsgSosStartSoundEvent { 95 | optional int32 soundevent_guid = 1; 96 | optional fixed32 soundevent_hash = 2; 97 | optional int32 source_entity_index = 3; 98 | optional int32 seed = 4; 99 | optional bytes packed_params = 5; 100 | } 101 | 102 | message CMsgSosStopSoundEvent { 103 | optional int32 soundevent_guid = 1; 104 | } 105 | 106 | message CMsgSosStopSoundEventHash { 107 | optional fixed32 soundevent_hash = 1; 108 | optional int32 source_entity_index = 2; 109 | } 110 | 111 | message CMsgSosSetSoundEventParams { 112 | optional int32 soundevent_guid = 1; 113 | optional bytes packed_params = 5; 114 | } 115 | 116 | message CMsgSosSetLibraryStackFields { 117 | optional fixed32 stack_hash = 1; 118 | optional bytes packed_fields = 5; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /proto/gcsdk_gcmessages.proto: -------------------------------------------------------------------------------- 1 | import "steammessages.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum ESourceEngine { 7 | k_ESE_Source1 = 0; 8 | k_ESE_Source2 = 1; 9 | } 10 | 11 | enum PartnerAccountType { 12 | PARTNER_NONE = 0; 13 | PARTNER_PERFECT_WORLD = 1; 14 | PARTNER_NEXON = 2; 15 | PARTNER_INVALID = 3; 16 | } 17 | 18 | enum GCConnectionStatus { 19 | GCConnectionStatus_HAVE_SESSION = 0; 20 | GCConnectionStatus_GC_GOING_DOWN = 1; 21 | GCConnectionStatus_NO_SESSION = 2; 22 | GCConnectionStatus_NO_SESSION_IN_LOGON_QUEUE = 3; 23 | GCConnectionStatus_NO_STEAM = 4; 24 | GCConnectionStatus_SUSPENDED = 5; 25 | GCConnectionStatus_STEAM_GOING_DOWN = 6; 26 | } 27 | 28 | message CMsgSHA1Digest { 29 | required fixed64 block1 = 1; 30 | required fixed64 block2 = 2; 31 | required fixed32 block3 = 3; 32 | } 33 | 34 | message CMsgSOIDOwner { 35 | optional uint32 type = 1; 36 | optional uint64 id = 2; 37 | } 38 | 39 | message CMsgSOSingleObject { 40 | optional int32 type_id = 2; 41 | optional bytes object_data = 3; 42 | optional fixed64 version = 4; 43 | optional .CMsgSOIDOwner owner_soid = 5; 44 | optional uint32 service_id = 6; 45 | } 46 | 47 | message CMsgSOMultipleObjects { 48 | message SingleObject { 49 | option (msgpool_soft_limit) = 256; 50 | option (msgpool_hard_limit) = 1024; 51 | optional int32 type_id = 1; 52 | optional bytes object_data = 2; 53 | } 54 | 55 | repeated .CMsgSOMultipleObjects.SingleObject objects_modified = 2; 56 | optional fixed64 version = 3; 57 | repeated .CMsgSOMultipleObjects.SingleObject objects_added = 4; 58 | repeated .CMsgSOMultipleObjects.SingleObject objects_removed = 5; 59 | optional .CMsgSOIDOwner owner_soid = 6; 60 | optional uint32 service_id = 7; 61 | } 62 | 63 | message CMsgSOCacheSubscribed { 64 | message SubscribedType { 65 | optional int32 type_id = 1; 66 | repeated bytes object_data = 2; 67 | } 68 | 69 | repeated .CMsgSOCacheSubscribed.SubscribedType objects = 2; 70 | optional fixed64 version = 3; 71 | optional .CMsgSOIDOwner owner_soid = 4; 72 | optional uint32 service_id = 5; 73 | repeated uint32 service_list = 6; 74 | optional fixed64 sync_version = 7; 75 | } 76 | 77 | message CMsgSOCacheSubscribedUpToDate { 78 | optional fixed64 version = 1; 79 | optional .CMsgSOIDOwner owner_soid = 2; 80 | optional uint32 service_id = 3; 81 | repeated uint32 service_list = 4; 82 | optional fixed64 sync_version = 5; 83 | } 84 | 85 | message CMsgSOCacheUnsubscribed { 86 | optional .CMsgSOIDOwner owner_soid = 2; 87 | } 88 | 89 | message CMsgSOCacheSubscriptionCheck { 90 | optional fixed64 version = 2; 91 | optional .CMsgSOIDOwner owner_soid = 3; 92 | optional uint32 service_id = 4; 93 | repeated uint32 service_list = 5; 94 | optional fixed64 sync_version = 6; 95 | } 96 | 97 | message CMsgSOCacheSubscriptionRefresh { 98 | optional .CMsgSOIDOwner owner_soid = 2; 99 | } 100 | 101 | message CMsgSOCacheVersion { 102 | optional fixed64 version = 1; 103 | } 104 | 105 | message CMsgGCMultiplexMessage { 106 | optional uint32 msgtype = 1; 107 | optional bytes payload = 2; 108 | repeated fixed64 steamids = 3; 109 | } 110 | 111 | message CGCToGCMsgMasterAck { 112 | message Process { 113 | optional uint32 dir_index = 1; 114 | repeated uint32 type_instances = 2; 115 | } 116 | 117 | optional uint32 dir_index = 1; 118 | optional string machine_name = 3; 119 | optional string process_name = 4; 120 | repeated .CGCToGCMsgMasterAck.Process directory = 6; 121 | } 122 | 123 | message CGCToGCMsgMasterAck_Response { 124 | optional int32 eresult = 1 [default = 2]; 125 | } 126 | 127 | message CGCToGCMsgMasterStartupComplete { 128 | message GCInfo { 129 | optional uint32 dir_index = 1; 130 | optional string machine_name = 2; 131 | } 132 | 133 | repeated .CGCToGCMsgMasterStartupComplete.GCInfo gc_info = 1; 134 | } 135 | 136 | message CGCToGCMsgRouted { 137 | optional uint32 msg_type = 1; 138 | optional fixed64 sender_id = 2; 139 | optional bytes net_message = 3; 140 | } 141 | 142 | message CGCToGCMsgRoutedReply { 143 | optional uint32 msg_type = 1; 144 | optional bytes net_message = 2; 145 | } 146 | 147 | message CMsgGCUpdateSubGCSessionInfo { 148 | message CMsgUpdate { 149 | optional fixed64 steamid = 1; 150 | optional fixed32 ip = 2; 151 | optional bool trusted = 3; 152 | } 153 | 154 | repeated .CMsgGCUpdateSubGCSessionInfo.CMsgUpdate updates = 1; 155 | } 156 | 157 | message CMsgGCRequestSubGCSessionInfo { 158 | optional fixed64 steamid = 1; 159 | } 160 | 161 | message CMsgGCRequestSubGCSessionInfoResponse { 162 | optional fixed32 ip = 1; 163 | optional bool trusted = 2; 164 | } 165 | 166 | message CMsgSOCacheHaveVersion { 167 | optional .CMsgSOIDOwner soid = 1; 168 | optional fixed64 version = 2; 169 | optional uint32 service_id = 3; 170 | optional uint32 cached_file_version = 4; 171 | } 172 | 173 | message CMsgClientHello { 174 | optional uint32 version = 1; 175 | repeated .CMsgSOCacheHaveVersion socache_have_versions = 2; 176 | optional uint32 client_session_need = 3; 177 | optional .PartnerAccountType client_launcher = 4 [default = PARTNER_NONE]; 178 | optional string secret_key = 5; 179 | optional uint32 client_language = 6; 180 | optional .ESourceEngine engine = 7 [default = k_ESE_Source1]; 181 | } 182 | 183 | message CMsgClientWelcome { 184 | message Location { 185 | optional float latitude = 1; 186 | optional float longitude = 2; 187 | optional string country = 3; 188 | } 189 | 190 | optional uint32 version = 1; 191 | optional bytes game_data = 2; 192 | repeated .CMsgSOCacheSubscribed outofdate_subscribed_caches = 3; 193 | repeated .CMsgSOCacheSubscriptionCheck uptodate_subscribed_caches = 4; 194 | optional .CMsgClientWelcome.Location location = 5; 195 | optional bytes save_game_key = 6; 196 | optional fixed32 item_schema_crc = 7; 197 | optional string items_game_url = 8; 198 | } 199 | 200 | message CMsgConnectionStatus { 201 | optional .GCConnectionStatus status = 1 [default = GCConnectionStatus_HAVE_SESSION]; 202 | optional uint32 client_session_need = 2; 203 | optional int32 queue_position = 3; 204 | optional int32 queue_size = 4; 205 | optional int32 wait_seconds = 5; 206 | optional int32 estimated_wait_seconds_remaining = 6; 207 | } 208 | 209 | message CMsgGCToGCSOCacheSubscribe { 210 | message CMsgHaveVersions { 211 | optional uint32 service_id = 1; 212 | optional uint64 version = 2; 213 | } 214 | 215 | optional fixed64 subscriber = 1; 216 | optional fixed64 subscribe_to = 2; 217 | optional fixed64 sync_version = 3; 218 | repeated .CMsgGCToGCSOCacheSubscribe.CMsgHaveVersions have_versions = 4; 219 | } 220 | 221 | message CMsgGCToGCSOCacheUnsubscribe { 222 | optional fixed64 subscriber = 1; 223 | optional fixed64 unsubscribe_from = 2; 224 | } 225 | 226 | message CMsgGCClientPing { 227 | } 228 | 229 | message CMsgGCToGCLoadSessionSOCache { 230 | optional uint32 account_id = 1; 231 | } 232 | 233 | message CMsgGCToGCLoadSessionSOCacheResponse { 234 | } 235 | 236 | message CMsgGCToGCUpdateSessionStats { 237 | optional uint32 user_sessions = 1; 238 | optional uint32 server_sessions = 2; 239 | optional bool in_logon_surge = 3; 240 | } 241 | 242 | message CWorkshop_PopulateItemDescriptions_Request { 243 | message SingleItemDescription { 244 | optional uint32 gameitemid = 1; 245 | optional string item_description = 2; 246 | } 247 | 248 | message ItemDescriptionsLanguageBlock { 249 | optional string language = 1; 250 | repeated .CWorkshop_PopulateItemDescriptions_Request.SingleItemDescription descriptions = 2; 251 | } 252 | 253 | optional uint32 appid = 1; 254 | repeated .CWorkshop_PopulateItemDescriptions_Request.ItemDescriptionsLanguageBlock languages = 2; 255 | } 256 | 257 | message CWorkshop_GetContributors_Request { 258 | optional uint32 appid = 1; 259 | optional uint32 gameitemid = 2; 260 | } 261 | 262 | message CWorkshop_GetContributors_Response { 263 | repeated fixed64 contributors = 1; 264 | } 265 | 266 | message CWorkshop_SetItemPaymentRules_Request { 267 | message WorkshopItemPaymentRule { 268 | optional uint64 workshop_file_id = 1; 269 | optional float revenue_percentage = 2; 270 | optional string rule_description = 3; 271 | } 272 | 273 | message PartnerItemPaymentRule { 274 | optional uint32 account_id = 1; 275 | optional float revenue_percentage = 2; 276 | optional string rule_description = 3; 277 | } 278 | 279 | optional uint32 appid = 1; 280 | optional uint32 gameitemid = 2; 281 | repeated .CWorkshop_SetItemPaymentRules_Request.WorkshopItemPaymentRule associated_workshop_files = 3; 282 | repeated .CWorkshop_SetItemPaymentRules_Request.PartnerItemPaymentRule partner_accounts = 4; 283 | } 284 | 285 | message CWorkshop_SetItemPaymentRules_Response { 286 | } 287 | 288 | message CBroadcast_PostGameDataFrame_Request { 289 | optional uint32 appid = 1; 290 | optional fixed64 steamid = 2; 291 | optional fixed64 broadcast_id = 3; 292 | optional bytes frame_data = 4; 293 | } 294 | 295 | -------------------------------------------------------------------------------- /proto/gcsystemmsgs.proto: -------------------------------------------------------------------------------- 1 | option optimize_for = SPEED; 2 | option cc_generic_services = false; 3 | 4 | enum EGCSystemMsg { 5 | k_EGCMsgInvalid = 0; 6 | k_EGCMsgMulti = 1; 7 | k_EGCMsgGenericReply = 10; 8 | k_EGCMsgSystemBase = 50; 9 | k_EGCMsgAchievementAwarded = 51; 10 | k_EGCMsgConCommand = 52; 11 | k_EGCMsgStartPlaying = 53; 12 | k_EGCMsgStopPlaying = 54; 13 | k_EGCMsgStartGameserver = 55; 14 | k_EGCMsgStopGameserver = 56; 15 | k_EGCMsgWGRequest = 57; 16 | k_EGCMsgWGResponse = 58; 17 | k_EGCMsgGetUserGameStatsSchema = 59; 18 | k_EGCMsgGetUserGameStatsSchemaResponse = 60; 19 | k_EGCMsgGetUserStatsDEPRECATED = 61; 20 | k_EGCMsgGetUserStatsResponse = 62; 21 | k_EGCMsgAppInfoUpdated = 63; 22 | k_EGCMsgValidateSession = 64; 23 | k_EGCMsgValidateSessionResponse = 65; 24 | k_EGCMsgLookupAccountFromInput = 66; 25 | k_EGCMsgSendHTTPRequest = 67; 26 | k_EGCMsgSendHTTPRequestResponse = 68; 27 | k_EGCMsgPreTestSetup = 69; 28 | k_EGCMsgRecordSupportAction = 70; 29 | k_EGCMsgGetAccountDetails_DEPRECATED = 71; 30 | k_EGCMsgReceiveInterAppMessage = 73; 31 | k_EGCMsgFindAccounts = 74; 32 | k_EGCMsgPostAlert = 75; 33 | k_EGCMsgGetLicenses = 76; 34 | k_EGCMsgGetUserStats = 77; 35 | k_EGCMsgGetCommands = 78; 36 | k_EGCMsgGetCommandsResponse = 79; 37 | k_EGCMsgAddFreeLicense = 80; 38 | k_EGCMsgAddFreeLicenseResponse = 81; 39 | k_EGCMsgGetIPLocation = 82; 40 | k_EGCMsgGetIPLocationResponse = 83; 41 | k_EGCMsgSystemStatsSchema = 84; 42 | k_EGCMsgGetSystemStats = 85; 43 | k_EGCMsgGetSystemStatsResponse = 86; 44 | k_EGCMsgSendEmail = 87; 45 | k_EGCMsgSendEmailResponse = 88; 46 | k_EGCMsgGetEmailTemplate = 89; 47 | k_EGCMsgGetEmailTemplateResponse = 90; 48 | k_EGCMsgGrantGuestPass = 91; 49 | k_EGCMsgGrantGuestPassResponse = 92; 50 | k_EGCMsgGetAccountDetails = 93; 51 | k_EGCMsgGetAccountDetailsResponse = 94; 52 | k_EGCMsgGetPersonaNames = 95; 53 | k_EGCMsgGetPersonaNamesResponse = 96; 54 | k_EGCMsgMultiplexMsg = 97; 55 | k_EGCMsgWebAPIRegisterInterfaces = 101; 56 | k_EGCMsgWebAPIJobRequest = 102; 57 | k_EGCMsgWebAPIJobRequestHttpResponse = 104; 58 | k_EGCMsgWebAPIJobRequestForwardResponse = 105; 59 | k_EGCMsgMemCachedGet = 200; 60 | k_EGCMsgMemCachedGetResponse = 201; 61 | k_EGCMsgMemCachedSet = 202; 62 | k_EGCMsgMemCachedDelete = 203; 63 | k_EGCMsgMemCachedStats = 204; 64 | k_EGCMsgMemCachedStatsResponse = 205; 65 | k_EGCMsgSQLStats = 210; 66 | k_EGCMsgSQLStatsResponse = 211; 67 | k_EGCMsgMasterSetDirectory = 220; 68 | k_EGCMsgMasterSetDirectoryResponse = 221; 69 | k_EGCMsgMasterSetWebAPIRouting = 222; 70 | k_EGCMsgMasterSetWebAPIRoutingResponse = 223; 71 | k_EGCMsgMasterSetClientMsgRouting = 224; 72 | k_EGCMsgMasterSetClientMsgRoutingResponse = 225; 73 | k_EGCMsgSetOptions = 226; 74 | k_EGCMsgSetOptionsResponse = 227; 75 | k_EGCMsgSystemBase2 = 500; 76 | k_EGCMsgGetPurchaseTrustStatus = 501; 77 | k_EGCMsgGetPurchaseTrustStatusResponse = 502; 78 | k_EGCMsgUpdateSession = 503; 79 | k_EGCMsgGCAccountVacStatusChange = 504; 80 | k_EGCMsgCheckFriendship = 505; 81 | k_EGCMsgCheckFriendshipResponse = 506; 82 | k_EGCMsgGetPartnerAccountLink = 507; 83 | k_EGCMsgGetPartnerAccountLinkResponse = 508; 84 | k_EGCMsgVSReportedSuspiciousActivity = 509; 85 | k_EGCMsgDPPartnerMicroTxns = 512; 86 | k_EGCMsgDPPartnerMicroTxnsResponse = 513; 87 | k_EGCMsgGetIPASN = 514; 88 | k_EGCMsgGetIPASNResponse = 515; 89 | k_EGCMsgGetAppFriendsList = 516; 90 | k_EGCMsgGetAppFriendsListResponse = 517; 91 | } 92 | 93 | enum ESOMsg { 94 | k_ESOMsg_Create = 21; 95 | k_ESOMsg_Update = 22; 96 | k_ESOMsg_Destroy = 23; 97 | k_ESOMsg_CacheSubscribed = 24; 98 | k_ESOMsg_CacheUnsubscribed = 25; 99 | k_ESOMsg_UpdateMultiple = 26; 100 | k_ESOMsg_CacheSubscriptionRefresh = 28; 101 | k_ESOMsg_CacheSubscribedUpToDate = 29; 102 | } 103 | 104 | enum EGCBaseClientMsg { 105 | k_EMsgGCPingRequest = 3001; 106 | k_EMsgGCPingResponse = 3002; 107 | k_EMsgGCClientWelcome = 4004; 108 | k_EMsgGCServerWelcome = 4005; 109 | k_EMsgGCClientHello = 4006; 110 | k_EMsgGCServerHello = 4007; 111 | k_EMsgGCClientConnectionStatus = 4009; 112 | k_EMsgGCServerConnectionStatus = 4010; 113 | } 114 | 115 | enum EGCToGCMsg { 116 | k_EGCToGCMsgMasterAck = 150; 117 | k_EGCToGCMsgMasterAckResponse = 151; 118 | k_EGCToGCMsgRouted = 152; 119 | k_EGCToGCMsgRoutedReply = 153; 120 | k_EMsgGCUpdateSubGCSessionInfo = 154; 121 | k_EMsgGCRequestSubGCSessionInfo = 155; 122 | k_EMsgGCRequestSubGCSessionInfoResponse = 156; 123 | k_EGCToGCMsgMasterStartupComplete = 157; 124 | k_EMsgGCToGCSOCacheSubscribe = 158; 125 | k_EMsgGCToGCSOCacheUnsubscribe = 159; 126 | k_EMsgGCToGCLoadSessionSOCache = 160; 127 | k_EMsgGCToGCLoadSessionSOCacheResponse = 161; 128 | k_EMsgGCToGCUpdateSessionStats = 162; 129 | } 130 | 131 | -------------------------------------------------------------------------------- /proto/netmessages.proto: -------------------------------------------------------------------------------- 1 | import "networkbasetypes.proto"; 2 | 3 | option cc_generic_services = false; 4 | 5 | enum CLC_Messages { 6 | clc_ClientInfo = 20; 7 | clc_Move = 21; 8 | clc_VoiceData = 22; 9 | clc_BaselineAck = 23; 10 | clc_ListenEvents = 24; 11 | clc_RespondCvarValue = 25; 12 | clc_FileCRCCheck = 26; 13 | clc_LoadingProgress = 27; 14 | clc_SplitPlayerConnect = 28; 15 | clc_ClientMessage = 29; 16 | clc_SplitPlayerDisconnect = 30; 17 | clc_ServerStatus = 31; 18 | clc_ServerPing = 32; 19 | clc_RequestPause = 33; 20 | clc_CmdKeyValues = 34; 21 | } 22 | 23 | enum SVC_Messages { 24 | svc_ServerInfo = 40; 25 | svc_FlattenedSerializer = 41; 26 | svc_ClassInfo = 42; 27 | svc_SetPause = 43; 28 | svc_CreateStringTable = 44; 29 | svc_UpdateStringTable = 45; 30 | svc_VoiceInit = 46; 31 | svc_VoiceData = 47; 32 | svc_Print = 48; 33 | svc_Sounds = 49; 34 | svc_SetView = 50; 35 | svc_ClearAllStringTables = 51; 36 | svc_CmdKeyValues = 52; 37 | svc_BSPDecal = 53; 38 | svc_SplitScreen = 54; 39 | svc_PacketEntities = 55; 40 | svc_Prefetch = 56; 41 | svc_Menu = 57; 42 | svc_GetCvarValue = 58; 43 | svc_StopSound = 59; 44 | svc_PeerList = 60; 45 | svc_PacketReliable = 61; 46 | svc_HLTVStatus = 62; 47 | svc_FullFrameSplit = 70; 48 | } 49 | 50 | enum VoiceDataFormat_t { 51 | VOICEDATA_FORMAT_STEAM = 0; 52 | VOICEDATA_FORMAT_ENGINE = 1; 53 | } 54 | 55 | enum RequestPause_t { 56 | RP_PAUSE = 0; 57 | RP_UNPAUSE = 1; 58 | RP_TOGGLEPAUSE = 2; 59 | } 60 | 61 | enum PrefetchType { 62 | PFT_SOUND = 0; 63 | } 64 | 65 | enum ESplitScreenMessageType { 66 | MSG_SPLITSCREEN_ADDUSER = 0; 67 | MSG_SPLITSCREEN_REMOVEUSER = 1; 68 | } 69 | 70 | enum EQueryCvarValueStatus { 71 | eQueryCvarValueStatus_ValueIntact = 0; 72 | eQueryCvarValueStatus_CvarNotFound = 1; 73 | eQueryCvarValueStatus_NotACvar = 2; 74 | eQueryCvarValueStatus_CvarProtected = 3; 75 | } 76 | 77 | enum DIALOG_TYPE { 78 | DIALOG_MSG = 0; 79 | DIALOG_MENU = 1; 80 | DIALOG_TEXT = 2; 81 | DIALOG_ENTRY = 3; 82 | DIALOG_ASKCONNECT = 4; 83 | } 84 | 85 | enum SVC_Messages_LowFrequency { 86 | svc_dummy = 600; 87 | } 88 | 89 | enum Bidirectional_Messages { 90 | bi_RebroadcastGameEvent = 16; 91 | bi_RebroadcastSource = 17; 92 | bi_GameEvent = 18; 93 | } 94 | 95 | enum Bidirectional_Messages_LowFrequency { 96 | bi_RelayInfo = 700; 97 | bi_RelayPacket = 701; 98 | } 99 | 100 | message CCLCMsg_ClientInfo { 101 | optional fixed32 send_table_crc = 1; 102 | optional uint32 server_count = 2; 103 | optional bool is_hltv = 3; 104 | optional bool is_replay = 4; 105 | optional uint32 friends_id = 5; 106 | optional string friends_name = 6; 107 | } 108 | 109 | message CCLCMsg_Move { 110 | optional uint32 num_backup_commands = 1; 111 | optional uint32 num_new_commands = 2; 112 | optional bytes data = 3; 113 | } 114 | 115 | message CMsgVoiceAudio { 116 | optional .VoiceDataFormat_t format = 1 [default = VOICEDATA_FORMAT_STEAM]; 117 | optional bytes voice_data = 2; 118 | optional int32 sequence_bytes = 3; 119 | optional uint32 section_number = 4; 120 | optional uint32 sample_rate = 5; 121 | optional uint32 uncompressed_sample_offset = 6; 122 | } 123 | 124 | message CCLCMsg_VoiceData { 125 | optional .CMsgVoiceAudio audio = 1; 126 | optional fixed64 xuid = 2; 127 | optional uint32 tick = 3; 128 | } 129 | 130 | message CCLCMsg_BaselineAck { 131 | optional int32 baseline_tick = 1; 132 | optional int32 baseline_nr = 2; 133 | } 134 | 135 | message CCLCMsg_ListenEvents { 136 | repeated fixed32 event_mask = 1; 137 | } 138 | 139 | message CCLCMsg_RespondCvarValue { 140 | optional int32 cookie = 1; 141 | optional int32 status_code = 2; 142 | optional string name = 3; 143 | optional string value = 4; 144 | } 145 | 146 | message CCLCMsg_FileCRCCheck { 147 | optional int32 code_path = 1; 148 | optional string path = 2; 149 | optional int32 code_filename = 3; 150 | optional string filename = 4; 151 | optional fixed32 crc = 5; 152 | } 153 | 154 | message CCLCMsg_LoadingProgress { 155 | optional int32 progress = 1; 156 | } 157 | 158 | message CCLCMsg_SplitPlayerConnect { 159 | optional string playername = 1; 160 | } 161 | 162 | message CCLCMsg_ClientMessage { 163 | optional int32 msg_type = 1; 164 | optional bytes data = 2; 165 | } 166 | 167 | message CCLCMsg_SplitPlayerDisconnect { 168 | optional int32 slot = 1; 169 | } 170 | 171 | message CCLCMsg_ServerStatus { 172 | optional bool simplified = 1; 173 | } 174 | 175 | message CCLCMsg_ServerPing { 176 | } 177 | 178 | message CCLCMsg_RequestPause { 179 | optional .RequestPause_t pause_type = 1 [default = RP_PAUSE]; 180 | optional int32 pause_group = 2; 181 | } 182 | 183 | message CCLCMsg_CmdKeyValues { 184 | optional bytes data = 1; 185 | } 186 | 187 | message CSVCMsg_ServerInfo { 188 | optional int32 protocol = 1; 189 | optional int32 server_count = 2; 190 | optional bool is_dedicated = 3; 191 | optional bool is_hltv = 4; 192 | optional bool is_replay = 5; 193 | optional int32 c_os = 6; 194 | optional fixed32 map_crc = 7; 195 | optional fixed32 client_crc = 8; 196 | optional fixed32 string_table_crc = 9; 197 | optional int32 max_clients = 10; 198 | optional int32 max_classes = 11; 199 | optional int32 player_slot = 12; 200 | optional float tick_interval = 13; 201 | optional string game_dir = 14; 202 | optional string map_name = 15; 203 | optional string sky_name = 16; 204 | optional string host_name = 17; 205 | optional string addon_name = 18; 206 | optional .CSVCMsg_GameSessionConfiguration game_session_config = 19; 207 | optional bytes game_session_manifest = 20; 208 | } 209 | 210 | message CSVCMsg_ClassInfo { 211 | message class_t { 212 | optional int32 class_id = 1; 213 | optional string data_table_name = 2; 214 | optional string class_name = 3; 215 | } 216 | 217 | optional bool create_on_client = 1; 218 | repeated .CSVCMsg_ClassInfo.class_t classes = 2; 219 | } 220 | 221 | message CSVCMsg_SetPause { 222 | optional bool paused = 1; 223 | } 224 | 225 | message CSVCMsg_VoiceInit { 226 | optional int32 quality = 1; 227 | optional string codec = 2; 228 | optional int32 version = 3 [default = 0]; 229 | } 230 | 231 | message CSVCMsg_Print { 232 | optional string text = 1; 233 | } 234 | 235 | message CSVCMsg_Sounds { 236 | message sounddata_t { 237 | optional sint32 origin_x = 1; 238 | optional sint32 origin_y = 2; 239 | optional sint32 origin_z = 3; 240 | optional uint32 volume = 4; 241 | optional float delay_value = 5; 242 | optional int32 sequence_number = 6; 243 | optional int32 entity_index = 7; 244 | optional int32 channel = 8; 245 | optional int32 pitch = 9; 246 | optional int32 flags = 10; 247 | optional uint32 sound_num = 11; 248 | optional fixed32 sound_num_handle = 12; 249 | optional int32 speaker_entity = 13; 250 | optional int32 random_seed = 14; 251 | optional int32 sound_level = 15; 252 | optional bool is_sentence = 16; 253 | optional bool is_ambient = 17; 254 | optional uint32 guid = 18; 255 | optional fixed64 sound_resource_id = 19; 256 | } 257 | 258 | optional bool reliable_sound = 1; 259 | repeated .CSVCMsg_Sounds.sounddata_t sounds = 2; 260 | } 261 | 262 | message CSVCMsg_Prefetch { 263 | optional int32 sound_index = 1; 264 | optional .PrefetchType resource_type = 2 [default = PFT_SOUND]; 265 | } 266 | 267 | message CSVCMsg_SetView { 268 | optional int32 entity_index = 1; 269 | optional int32 slot = 2; 270 | } 271 | 272 | message CSVCMsg_FixAngle { 273 | optional bool relative = 1; 274 | optional .CMsgQAngle angle = 2; 275 | } 276 | 277 | message CSVCMsg_CrosshairAngle { 278 | optional .CMsgQAngle angle = 1; 279 | } 280 | 281 | message CSVCMsg_BSPDecal { 282 | optional .CMsgVector pos = 1; 283 | optional int32 decal_texture_index = 2; 284 | optional int32 entity_index = 3; 285 | optional int32 model_index = 4; 286 | optional bool low_priority = 5; 287 | } 288 | 289 | message CSVCMsg_SplitScreen { 290 | optional .ESplitScreenMessageType type = 1 [default = MSG_SPLITSCREEN_ADDUSER]; 291 | optional int32 slot = 2; 292 | optional int32 player_index = 3; 293 | } 294 | 295 | message CSVCMsg_GetCvarValue { 296 | optional int32 cookie = 1; 297 | optional string cvar_name = 2; 298 | } 299 | 300 | message CSVCMsg_Menu { 301 | optional int32 dialog_type = 1; 302 | optional bytes menu_key_values = 2; 303 | } 304 | 305 | message CSVCMsg_SendTable { 306 | message sendprop_t { 307 | optional int32 type = 1; 308 | optional string var_name = 2; 309 | optional int32 flags = 3; 310 | optional int32 priority = 4; 311 | optional string dt_name = 5; 312 | optional int32 num_elements = 6; 313 | optional float low_value = 7; 314 | optional float high_value = 8; 315 | optional int32 num_bits = 9; 316 | } 317 | 318 | optional bool is_end = 1; 319 | optional string net_table_name = 2; 320 | optional bool needs_decoder = 3; 321 | repeated .CSVCMsg_SendTable.sendprop_t props = 4; 322 | } 323 | 324 | message CSVCMsg_GameEventList { 325 | message key_t { 326 | optional int32 type = 1; 327 | optional string name = 2; 328 | } 329 | 330 | message descriptor_t { 331 | optional int32 eventid = 1; 332 | optional string name = 2; 333 | repeated .CSVCMsg_GameEventList.key_t keys = 3; 334 | } 335 | 336 | repeated .CSVCMsg_GameEventList.descriptor_t descriptors = 1; 337 | } 338 | 339 | message CSVCMsg_PacketEntities { 340 | optional int32 max_entries = 1; 341 | optional int32 updated_entries = 2; 342 | optional bool is_delta = 3; 343 | optional bool update_baseline = 4; 344 | optional int32 baseline = 5; 345 | optional int32 delta_from = 6; 346 | optional bytes entity_data = 7; 347 | optional bool pending_full_frame = 8; 348 | optional uint32 active_spawngroup_handle = 9; 349 | optional uint32 max_spawngroup_creationsequence = 10; 350 | } 351 | 352 | message CSVCMsg_TempEntities { 353 | optional bool reliable = 1; 354 | optional int32 num_entries = 2; 355 | optional bytes entity_data = 3; 356 | } 357 | 358 | message CSVCMsg_CreateStringTable { 359 | optional string name = 1; 360 | optional int32 num_entries = 2; 361 | optional bool user_data_fixed_size = 3; 362 | optional int32 user_data_size = 4; 363 | optional int32 user_data_size_bits = 5; 364 | optional int32 flags = 6; 365 | optional bytes string_data = 7; 366 | optional int32 uncompressed_size = 8; 367 | optional bool data_compressed = 9; 368 | } 369 | 370 | message CSVCMsg_UpdateStringTable { 371 | optional int32 table_id = 1; 372 | optional int32 num_changed_entries = 2; 373 | optional bytes string_data = 3; 374 | } 375 | 376 | message CSVCMsg_VoiceData { 377 | optional .CMsgVoiceAudio audio = 1; 378 | optional int32 client = 2; 379 | optional bool proximity = 3; 380 | optional fixed64 xuid = 4; 381 | optional int32 audible_mask = 5; 382 | optional uint32 tick = 6; 383 | } 384 | 385 | message CSVCMsg_PacketReliable { 386 | optional int32 tick = 1; 387 | optional int32 messagessize = 2; 388 | optional bool state = 3; 389 | } 390 | 391 | message CSVCMsg_FullFrameSplit { 392 | optional int32 tick = 1; 393 | optional int32 section = 2; 394 | optional int32 total = 3; 395 | optional bytes data = 4; 396 | } 397 | 398 | message CSVCMsg_HLTVStatus { 399 | optional string master = 1; 400 | optional int32 clients = 2; 401 | optional int32 slots = 3; 402 | optional int32 proxies = 4; 403 | } 404 | 405 | message CSVCMsg_CmdKeyValues { 406 | optional bytes data = 1; 407 | } 408 | 409 | message CMsgIPCAddress { 410 | optional fixed64 computer_guid = 1; 411 | optional uint32 process_id = 2; 412 | } 413 | 414 | message CMsgServerPeer { 415 | optional int32 player_slot = 1; 416 | optional fixed64 steamid = 2; 417 | optional .CMsgIPCAddress ipc = 3; 418 | optional bool they_hear_you = 4; 419 | optional bool you_hear_them = 5; 420 | optional bool is_listenserver_host = 6; 421 | } 422 | 423 | message CSVCMsg_PeerList { 424 | repeated .CMsgServerPeer peer = 1; 425 | } 426 | 427 | message CSVCMsg_ClearAllStringTables { 428 | optional string mapname = 1; 429 | optional uint32 map_crc = 2; 430 | } 431 | 432 | message ProtoFlattenedSerializerField_t { 433 | optional int32 var_type_sym = 1; 434 | optional int32 var_name_sym = 2; 435 | optional int32 bit_count = 3; 436 | optional float low_value = 4; 437 | optional float high_value = 5; 438 | optional int32 encode_flags = 6; 439 | optional int32 field_serializer_name_sym = 7; 440 | optional int32 field_serializer_version = 8; 441 | optional int32 send_node_sym = 9; 442 | optional int32 var_encoder_sym = 10; 443 | } 444 | 445 | message ProtoFlattenedSerializer_t { 446 | optional int32 serializer_name_sym = 1; 447 | optional int32 serializer_version = 2; 448 | repeated int32 fields_index = 3; 449 | } 450 | 451 | message CSVCMsg_FlattenedSerializer { 452 | repeated .ProtoFlattenedSerializer_t serializers = 1; 453 | repeated string symbols = 2; 454 | repeated .ProtoFlattenedSerializerField_t fields = 3; 455 | } 456 | 457 | message CSVCMsg_StopSound { 458 | optional fixed32 guid = 1; 459 | } 460 | 461 | message CBidirMsg_RebroadcastGameEvent { 462 | optional bool posttoserver = 1; 463 | optional int32 buftype = 2; 464 | optional uint32 clientbitcount = 3; 465 | optional uint64 receivingclients = 4; 466 | } 467 | 468 | message CBidirMsg_RebroadcastSource { 469 | optional int32 eventsource = 1; 470 | } 471 | 472 | message SerializedNetAddress_t { 473 | required bytes serializedAddress = 1; 474 | } 475 | 476 | message CBidirMsg_RelayInfo { 477 | enum Operation_t { 478 | RIO_REQUEST_RELAY = 0; 479 | RIO_WILL_RELAY = 1; 480 | RIO_NO_ROUTE = 2; 481 | RIO_REJECT_RELAY = 3; 482 | RIO_ESTABLISH_CONNECTION = 4; 483 | } 484 | 485 | required .CBidirMsg_RelayInfo.Operation_t operation = 1 [default = RIO_REQUEST_RELAY]; 486 | optional .SerializedNetAddress_t serializedTargetAddress = 2; 487 | optional uint32 additionalHops = 3; 488 | } 489 | 490 | message SignedPayload_t { 491 | required bytes payloadData = 1; 492 | required uint32 signature = 2; 493 | required bool bPayloadEncrypted = 3; 494 | } 495 | 496 | message CBidirMsg_RelayPacket { 497 | message SignedDestinationAddress_t { 498 | required .SerializedNetAddress_t serializedAddr = 1; 499 | required uint32 signature = 2; 500 | optional bytes encryptedPayloadKey = 3; 501 | } 502 | 503 | required uint32 prevhopcount = 1; 504 | required .SerializedNetAddress_t originalSender = 2; 505 | required .SignedPayload_t signedPayload = 3; 506 | repeated .CBidirMsg_RelayPacket.SignedDestinationAddress_t recipientList = 4; 507 | } 508 | 509 | -------------------------------------------------------------------------------- /proto/network_connection.proto: -------------------------------------------------------------------------------- 1 | import "google/protobuf/descriptor.proto"; 2 | 3 | option cc_generic_services = false; 4 | 5 | extend .google.protobuf.EnumValueOptions { 6 | optional string network_connection_token = 50500; 7 | } 8 | 9 | enum ENetworkDisconnectionReason { 10 | NETWORK_DISCONNECT_INVALID = 0; 11 | NETWORK_DISCONNECT_SHUTDOWN = 1; 12 | NETWORK_DISCONNECT_DISCONNECT_BY_USER = 2 [(network_connection_token) = "#GameUI_Disconnect_User"]; 13 | NETWORK_DISCONNECT_DISCONNECT_BY_SERVER = 3 [(network_connection_token) = "#GameUI_Disconnect_Server"]; 14 | NETWORK_DISCONNECT_LOST = 4 [(network_connection_token) = "#GameUI_Disconnect_ConnectionLost"]; 15 | NETWORK_DISCONNECT_OVERFLOW = 5 [(network_connection_token) = "#GameUI_Disconnect_ConnectionOverflow"]; 16 | NETWORK_DISCONNECT_STEAM_BANNED = 6 [(network_connection_token) = "#GameUI_Disconnect_SteamIDBanned"]; 17 | NETWORK_DISCONNECT_STEAM_INUSE = 7 [(network_connection_token) = "#GameUI_Disconnect_SteamIDInUse"]; 18 | NETWORK_DISCONNECT_STEAM_TICKET = 8 [(network_connection_token) = "#GameUI_Disconnect_SteamTicket"]; 19 | NETWORK_DISCONNECT_STEAM_LOGON = 9 [(network_connection_token) = "#GameUI_Disconnect_SteamLogon"]; 20 | NETWORK_DISCONNECT_STEAM_AUTHCANCELLED = 10 [(network_connection_token) = "#GameUI_Disconnect_SteamLogon"]; 21 | NETWORK_DISCONNECT_STEAM_AUTHALREADYUSED = 11 [(network_connection_token) = "#GameUI_Disconnect_SteamLogon"]; 22 | NETWORK_DISCONNECT_STEAM_AUTHINVALID = 12 [(network_connection_token) = "#GameUI_Disconnect_SteamLogon"]; 23 | NETWORK_DISCONNECT_STEAM_VACBANSTATE = 13 [(network_connection_token) = "#GameUI_Disconnect_SteamVAC"]; 24 | NETWORK_DISCONNECT_STEAM_LOGGED_IN_ELSEWHERE = 14 [(network_connection_token) = "#GameUI_Disconnect_SteamInUse"]; 25 | NETWORK_DISCONNECT_STEAM_VAC_CHECK_TIMEDOUT = 15 [(network_connection_token) = "#GameUI_Disconnect_SteamTimeOut"]; 26 | NETWORK_DISCONNECT_STEAM_DROPPED = 16 [(network_connection_token) = "#GameUI_Disconnect_SteamDropped"]; 27 | NETWORK_DISCONNECT_STEAM_OWNERSHIP = 17 [(network_connection_token) = "#GameUI_Disconnect_SteamOwnership"]; 28 | NETWORK_DISCONNECT_SERVERINFO_OVERFLOW = 18 [(network_connection_token) = "#GameUI_Disconnect_ServerInfoOverflow"]; 29 | NETWORK_DISCONNECT_TICKMSG_OVERFLOW = 19 [(network_connection_token) = "#GameUI_Disconnect_TickMessage"]; 30 | NETWORK_DISCONNECT_STRINGTABLEMSG_OVERFLOW = 20 [(network_connection_token) = "#GameUI_Disconnect_StringTableMessage"]; 31 | NETWORK_DISCONNECT_DELTAENTMSG_OVERFLOW = 21 [(network_connection_token) = "#GameUI_Disconnect_DeltaEntMessage"]; 32 | NETWORK_DISCONNECT_TEMPENTMSG_OVERFLOW = 22 [(network_connection_token) = "#GameUI_Disconnect_TempEntMessage"]; 33 | NETWORK_DISCONNECT_SOUNDSMSG_OVERFLOW = 23 [(network_connection_token) = "#GameUI_Disconnect_SoundsMessage"]; 34 | NETWORK_DISCONNECT_SNAPSHOTOVERFLOW = 24 [(network_connection_token) = "#GameUI_Disconnect_SnapshotOverflow"]; 35 | NETWORK_DISCONNECT_SNAPSHOTERROR = 25 [(network_connection_token) = "#GameUI_Disconnect_SnapshotError"]; 36 | NETWORK_DISCONNECT_RELIABLEOVERFLOW = 26 [(network_connection_token) = "#GameUI_Disconnect_ReliableOverflow"]; 37 | NETWORK_DISCONNECT_BADDELTATICK = 27 [(network_connection_token) = "#GameUI_Disconnect_BadClientDeltaTick"]; 38 | NETWORK_DISCONNECT_NOMORESPLITS = 28 [(network_connection_token) = "#GameUI_Disconnect_NoMoreSplits"]; 39 | NETWORK_DISCONNECT_TIMEDOUT = 29 [(network_connection_token) = "#GameUI_Disconnect_TimedOut"]; 40 | NETWORK_DISCONNECT_DISCONNECTED = 30 [(network_connection_token) = "#GameUI_Disconnect_Disconnected"]; 41 | NETWORK_DISCONNECT_LEAVINGSPLIT = 31 [(network_connection_token) = "#GameUI_Disconnect_LeavingSplit"]; 42 | NETWORK_DISCONNECT_DIFFERENTCLASSTABLES = 32 [(network_connection_token) = "#GameUI_Disconnect_DifferentClassTables"]; 43 | NETWORK_DISCONNECT_BADRELAYPASSWORD = 33 [(network_connection_token) = "#GameUI_Disconnect_BadRelayPassword"]; 44 | NETWORK_DISCONNECT_BADSPECTATORPASSWORD = 34 [(network_connection_token) = "#GameUI_Disconnect_BadSpectatorPassword"]; 45 | NETWORK_DISCONNECT_HLTVRESTRICTED = 35 [(network_connection_token) = "#GameUI_Disconnect_HLTVRestricted"]; 46 | NETWORK_DISCONNECT_NOSPECTATORS = 36 [(network_connection_token) = "#GameUI_Disconnect_NoSpectators"]; 47 | NETWORK_DISCONNECT_HLTVUNAVAILABLE = 37 [(network_connection_token) = "#GameUI_Disconnect_HLTVUnavailable"]; 48 | NETWORK_DISCONNECT_HLTVSTOP = 38 [(network_connection_token) = "#GameUI_Disconnect_HLTVStop"]; 49 | NETWORK_DISCONNECT_KICKED = 39 [(network_connection_token) = "#GameUI_Disconnect_Kicked"]; 50 | NETWORK_DISCONNECT_BANADDED = 40 [(network_connection_token) = "#GameUI_Disconnect_BanAdded"]; 51 | NETWORK_DISCONNECT_KICKBANADDED = 41 [(network_connection_token) = "#GameUI_Disconnect_KickBanAdded"]; 52 | NETWORK_DISCONNECT_HLTVDIRECT = 42 [(network_connection_token) = "#GameUI_Disconnect_HLTVDirect"]; 53 | NETWORK_DISCONNECT_PURESERVER_CLIENTEXTRA = 43 [(network_connection_token) = "#GameUI_Disconnect_PureServer_ClientExtra"]; 54 | NETWORK_DISCONNECT_PURESERVER_MISMATCH = 44 [(network_connection_token) = "#GameUI_Disconnect_PureServer_Mismatch"]; 55 | NETWORK_DISCONNECT_USERCMD = 45 [(network_connection_token) = "#GameUI_Disconnect_UserCmd"]; 56 | NETWORK_DISCONNECT_REJECTED_BY_GAME = 46 [(network_connection_token) = "#GameUI_Disconnect_RejectedByGame"]; 57 | NETWORK_DISCONNECT_MESSAGE_PARSE_ERROR = 47 [(network_connection_token) = "#GameUI_Disconnect_MessageParseError"]; 58 | NETWORK_DISCONNECT_INVALID_MESSAGE_ERROR = 48 [(network_connection_token) = "#GameUI_Disconnect_InvalidMessageError"]; 59 | NETWORK_DISCONNECT_BAD_SERVER_PASSWORD = 49 [(network_connection_token) = "#GameUI_Disconnect_BadServerPassword"]; 60 | NETWORK_DISCONNECT_DIRECT_CONNECT_RESERVATION = 50; 61 | NETWORK_DISCONNECT_CONNECTION_FAILURE = 51 [(network_connection_token) = "#GameUI_Disconnect_ConnectionFailure"]; 62 | NETWORK_DISCONNECT_NO_PEER_GROUP_HANDLERS = 52 [(network_connection_token) = "#GameUI_Disconnect_NoPeerGroupHandlers"]; 63 | NETWORK_DISCONNECT_RECONNECTION = 53; 64 | NETWORK_DISCONNECT_LOOPSHUTDOWN = 54 [(network_connection_token) = "#GameUI_Disconnect_LoopShutdown"]; 65 | NETWORK_DISCONNECT_LOOPDEACTIVATE = 55 [(network_connection_token) = "#GameUI_Disconnect_LoopDeactivate"]; 66 | NETWORK_DISCONNECT_HOST_ENDGAME = 56 [(network_connection_token) = "#GameUI_Disconnect_Host_EndGame"]; 67 | NETWORK_DISCONNECT_LOOP_LEVELLOAD_ACTIVATE = 57 [(network_connection_token) = "#GameUI_Disconnect_LoopLevelLoadActivate"]; 68 | NETWORK_DISCONNECT_CREATE_SERVER_FAILED = 58 [(network_connection_token) = "#GameUI_Disconnect_CreateServerFailed"]; 69 | NETWORK_DISCONNECT_EXITING = 59 [(network_connection_token) = "#GameUI_Disconnect_ExitingEngine"]; 70 | NETWORK_DISCONNECT_REQUEST_HOSTSTATE_IDLE = 60 [(network_connection_token) = "#GameUI_Disconnect_Request_HSIdle"]; 71 | NETWORK_DISCONNECT_REQUEST_HOSTSTATE_HLTVRELAY = 61 [(network_connection_token) = "#GameUI_Disconnect_Request_HLTVRelay"]; 72 | NETWORK_DISCONNECT_CLIENT_CONSISTENCY_FAIL = 62 [(network_connection_token) = "#GameUI_ClientConsistencyFail"]; 73 | NETWORK_DISCONNECT_CLIENT_UNABLE_TO_CRC_MAP = 63 [(network_connection_token) = "#GameUI_ClientUnableToCRCMap"]; 74 | NETWORK_DISCONNECT_CLIENT_NO_MAP = 64 [(network_connection_token) = "#GameUI_ClientNoMap"]; 75 | NETWORK_DISCONNECT_CLIENT_DIFFERENT_MAP = 65 [(network_connection_token) = "#GameUI_ClientDifferentMap"]; 76 | NETWORK_DISCONNECT_SERVER_REQUIRES_STEAM = 66 [(network_connection_token) = "#GameUI_ServerRequireSteams"]; 77 | NETWORK_DISCONNECT_STEAM_DENY_MISC = 67 [(network_connection_token) = "#GameUI_Disconnect_SteamDeny_Misc"]; 78 | NETWORK_DISCONNECT_STEAM_DENY_BAD_ANTI_CHEAT = 68 [(network_connection_token) = "#GameUI_Disconnect_SteamDeny_BadAntiCheat"]; 79 | NETWORK_DISCONNECT_SERVER_SHUTDOWN = 69 [(network_connection_token) = "#GameUI_Disconnect_ServerShutdown"]; 80 | NETWORK_DISCONNECT_SPLITPACKET_SEND_OVERFLOW = 70 [(network_connection_token) = "#GameUI_Disconnect_Splitpacket_Send_Overflow"]; 81 | NETWORK_DISCONNECT_REPLAY_INCOMPATIBLE = 71 [(network_connection_token) = "#GameUI_Disconnect_ReplayIncompatible"]; 82 | NETWORK_DISCONNECT_CONNECT_REQUEST_TIMEDOUT = 72 [(network_connection_token) = "#GameUI_Disconnect_ConnectionTimedout"]; 83 | NETWORK_DISCONNECT_SERVER_INCOMPATIBLE = 73 [(network_connection_token) = "#GameUI_Disconnect_ServerIncompatible"]; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /proto/networkbasetypes.proto: -------------------------------------------------------------------------------- 1 | import "network_connection.proto"; 2 | 3 | option cc_generic_services = false; 4 | 5 | enum NET_Messages { 6 | net_NOP = 0; 7 | net_Disconnect = 1; 8 | net_SplitScreenUser = 3; 9 | net_Tick = 4; 10 | net_StringCmd = 5; 11 | net_SetConVar = 6; 12 | net_SignonState = 7; 13 | net_SpawnGroup_Load = 8; 14 | net_SpawnGroup_ManifestUpdate = 9; 15 | net_SpawnGroup_SetCreationTick = 11; 16 | net_SpawnGroup_Unload = 12; 17 | net_SpawnGroup_LoadCompleted = 13; 18 | } 19 | 20 | enum SpawnGroupFlags_t { 21 | SPAWN_GROUP_LOAD_ENTITIES_FROM_SAVE = 1; 22 | SPAWN_GROUP_DONT_SPAWN_ENTITIES = 2; 23 | SPAWN_GROUP_SYNCHRONOUS_SPAWN = 4; 24 | SPAWN_GROUP_IS_INITIAL_SPAWN_GROUP = 8; 25 | SPAWN_GROUP_CREATE_CLIENT_ONLY_ENTITIES = 16; 26 | SPAWN_GROUP_SAVE_ENTITIES = 32; 27 | SPAWN_GROUP_BLOCK_UNTIL_LOADED = 64; 28 | SPAWN_GROUP_LOAD_STREAMING_DATA = 128; 29 | SPAWN_GROUP_CREATE_NEW_SCENE_WORLD = 256; 30 | } 31 | 32 | message CMsgVector { 33 | optional float x = 1; 34 | optional float y = 2; 35 | optional float z = 3; 36 | } 37 | 38 | message CMsgVector2D { 39 | optional float x = 1; 40 | optional float y = 2; 41 | } 42 | 43 | message CMsgQAngle { 44 | optional float x = 1; 45 | optional float y = 2; 46 | optional float z = 3; 47 | } 48 | 49 | message CMsgPlayerInfo { 50 | optional string name = 1; 51 | optional fixed64 xuid = 2; 52 | optional int32 userid = 3; 53 | optional fixed64 steamid = 4; 54 | optional bool fakeplayer = 5; 55 | optional bool ishltv = 6; 56 | } 57 | 58 | message CMsg_CVars { 59 | message CVar { 60 | optional string name = 1; 61 | optional string value = 2; 62 | } 63 | 64 | repeated .CMsg_CVars.CVar cvars = 1; 65 | } 66 | 67 | message CNETMsg_NOP { 68 | } 69 | 70 | message CNETMsg_SplitScreenUser { 71 | optional int32 slot = 1; 72 | } 73 | 74 | message CNETMsg_Disconnect { 75 | optional .ENetworkDisconnectionReason reason = 2 [default = NETWORK_DISCONNECT_INVALID]; 76 | } 77 | 78 | message CNETMsg_Tick { 79 | optional uint32 tick = 1; 80 | optional uint32 host_frametime = 2; 81 | optional uint32 host_frametime_std_deviation = 3; 82 | optional uint32 host_computationtime = 4; 83 | optional uint32 host_computationtime_std_deviation = 5; 84 | optional uint32 host_framestarttime_std_deviation = 6; 85 | } 86 | 87 | message CNETMsg_StringCmd { 88 | optional string command = 1; 89 | } 90 | 91 | message CNETMsg_SetConVar { 92 | optional .CMsg_CVars convars = 1; 93 | } 94 | 95 | message CNETMsg_SignonState { 96 | optional uint32 signon_state = 1; 97 | optional uint32 spawn_count = 2; 98 | optional uint32 num_server_players = 3; 99 | repeated string players_networkids = 4; 100 | optional string map_name = 5; 101 | } 102 | 103 | message CSVCMsg_GameEvent { 104 | message key_t { 105 | optional int32 type = 1; 106 | optional string val_string = 2; 107 | optional float val_float = 3; 108 | optional int32 val_long = 4; 109 | optional int32 val_short = 5; 110 | optional int32 val_byte = 6; 111 | optional bool val_bool = 7; 112 | optional uint64 val_uint64 = 8; 113 | } 114 | 115 | optional string event_name = 1; 116 | optional int32 eventid = 2; 117 | repeated .CSVCMsg_GameEvent.key_t keys = 3; 118 | } 119 | 120 | message CSVCMsgList_GameEvents { 121 | message event_t { 122 | optional int32 tick = 1; 123 | optional .CSVCMsg_GameEvent event = 2; 124 | } 125 | 126 | repeated .CSVCMsgList_GameEvents.event_t events = 1; 127 | } 128 | 129 | message CSVCMsg_UserMessage { 130 | optional int32 msg_type = 1; 131 | optional bytes msg_data = 2; 132 | } 133 | 134 | message CSVCMsgList_UserMessages { 135 | message usermsg_t { 136 | optional int32 tick = 1; 137 | optional .CSVCMsg_UserMessage msg = 2; 138 | } 139 | 140 | repeated .CSVCMsgList_UserMessages.usermsg_t usermsgs = 1; 141 | } 142 | 143 | message CNETMsg_SpawnGroup_Load { 144 | optional string worldname = 1; 145 | optional string entitylumpname = 2; 146 | optional string entityfiltername = 3; 147 | optional uint32 spawngrouphandle = 4; 148 | optional uint32 spawngroupownerhandle = 5; 149 | optional .CMsgVector world_offset_pos = 6; 150 | optional .CMsgQAngle world_offset_angle = 7; 151 | optional bytes spawngroupmanifest = 8; 152 | optional uint32 flags = 9; 153 | optional int32 tickcount = 10; 154 | optional bool manifestincomplete = 11; 155 | optional string localnamefixup = 12; 156 | optional string parentnamefixup = 13; 157 | optional int32 manifestloadpriority = 14; 158 | optional uint32 worldgroupid = 15; 159 | optional uint32 creationsequence = 16; 160 | } 161 | 162 | message CNETMsg_SpawnGroup_ManifestUpdate { 163 | optional uint32 spawngrouphandle = 1; 164 | optional bytes spawngroupmanifest = 2; 165 | optional bool manifestincomplete = 3; 166 | } 167 | 168 | message CNETMsg_SpawnGroup_SetCreationTick { 169 | optional uint32 spawngrouphandle = 1; 170 | optional int32 tickcount = 2; 171 | optional uint32 creationsequence = 3; 172 | } 173 | 174 | message CNETMsg_SpawnGroup_Unload { 175 | optional uint32 spawngrouphandle = 1; 176 | optional uint32 flags = 2; 177 | optional int32 tickcount = 3; 178 | } 179 | 180 | message CNETMsg_SpawnGroup_LoadCompleted { 181 | optional uint32 spawngrouphandle = 1; 182 | } 183 | 184 | message CSVCMsg_GameSessionConfiguration { 185 | optional bool is_multiplayer = 1; 186 | optional bool is_loadsavegame = 2; 187 | optional bool is_background_map = 3; 188 | optional bool is_headless = 4; 189 | optional uint32 min_client_limit = 5; 190 | optional uint32 max_client_limit = 6; 191 | optional uint32 max_clients = 7; 192 | optional fixed32 tick_interval = 8; 193 | optional string hostname = 9; 194 | optional string savegamename = 10; 195 | optional string s1_mapname = 11; 196 | optional string gamemode = 12; 197 | optional string server_ip_address = 13; 198 | optional bytes data = 14; 199 | optional bool is_localonly = 15; 200 | } 201 | 202 | -------------------------------------------------------------------------------- /proto/networksystem_protomessages.proto: -------------------------------------------------------------------------------- 1 | option cc_generic_services = false; 2 | 3 | message NetMessageSplitscreenUserChanged { 4 | optional uint32 slot = 1; 5 | } 6 | 7 | message NetMessageConnectionClosed { 8 | optional uint32 reason = 1; 9 | } 10 | 11 | message NetMessageConnectionCrashed { 12 | optional uint32 reason = 1; 13 | } 14 | 15 | message NetMessagePacketStart { 16 | optional uint32 incoming_sequence = 1; 17 | optional uint32 outgoing_acknowledged = 2; 18 | } 19 | 20 | message NetMessagePacketEnd { 21 | } 22 | 23 | -------------------------------------------------------------------------------- /proto/steamdatagram_messages.proto: -------------------------------------------------------------------------------- 1 | option cc_generic_services = false; 2 | 3 | enum ESteamDatagramMsgID { 4 | k_ESteamDatagramMsg_RouterPingRequest = 1; 5 | k_ESteamDatagramMsg_RouterPingReply = 2; 6 | k_ESteamDatagramMsg_GameserverPingRequest = 3; 7 | k_ESteamDatagramMsg_GameserverPingReply = 4; 8 | k_ESteamDatagramMsg_GameserverSessionRequest = 5; 9 | k_ESteamDatagramMsg_GameserverSessionEstablished = 6; 10 | k_ESteamDatagramMsg_NoSession = 7; 11 | k_ESteamDatagramMsg_Diagnostic = 8; 12 | k_ESteamDatagramMsg_DataClientToRouter = 9; 13 | k_ESteamDatagramMsg_DataRouterToServer = 10; 14 | k_ESteamDatagramMsg_DataServerToRouter = 11; 15 | k_ESteamDatagramMsg_DataRouterToClient = 12; 16 | k_ESteamDatagramMsg_Stats = 13; 17 | k_ESteamDatagramMsg_ClientPingSampleRequest = 14; 18 | k_ESteamDatagramMsg_ClientPingSampleReply = 15; 19 | k_ESteamDatagramMsg_ClientToRouterSwitchedPrimary = 16; 20 | } 21 | 22 | message CMsgSteamDatagramRouterPingReply { 23 | optional fixed32 client_timestamp = 1; 24 | repeated fixed32 latency_datacenter_ids = 2 [packed = true]; 25 | repeated uint32 latency_ping_ms = 3 [packed = true]; 26 | optional fixed32 your_public_ip = 4; 27 | optional fixed32 server_time = 5; 28 | optional fixed64 challenge = 6; 29 | optional uint32 seconds_until_shutdown = 7; 30 | optional fixed32 client_cookie = 8; 31 | } 32 | 33 | message CMsgSteamDatagramGameserverPing { 34 | optional uint32 client_session = 1; 35 | optional fixed64 client_steam_id = 2; 36 | optional fixed32 client_timestamp = 3; 37 | optional fixed32 router_timestamp = 4; 38 | optional uint32 router_gameserver_latency = 5; 39 | optional uint32 seq_number_router = 6; 40 | optional uint32 seq_number_e2e = 7; 41 | } 42 | 43 | message CMsgSteamDatagramGameServerAuthTicket { 44 | message ExtraField { 45 | optional string name = 1; 46 | optional string string_value = 2; 47 | optional sint32 int32_value = 3; 48 | optional fixed32 fixed32_value = 4; 49 | optional fixed64 fixed64_value = 5; 50 | } 51 | 52 | optional fixed32 time_expiry = 1; 53 | optional fixed64 authorized_steam_id = 2; 54 | optional fixed32 authorized_public_ip = 3; 55 | optional fixed64 gameserver_steam_id = 4; 56 | optional fixed64 gameserver_net_id = 5; 57 | optional bytes signature = 6; 58 | optional uint32 app_id = 7; 59 | repeated .CMsgSteamDatagramGameServerAuthTicket.ExtraField extra_fields = 8; 60 | } 61 | 62 | message CMsgSteamDatagramGameserverSessionRequest { 63 | optional .CMsgSteamDatagramGameServerAuthTicket ticket = 1; 64 | optional fixed32 challenge_time = 3; 65 | optional fixed64 challenge = 4; 66 | optional fixed32 client_cookie = 5; 67 | } 68 | 69 | message CMsgSteamDatagramGameserverSessionEstablished { 70 | optional fixed32 client_cookie = 1; 71 | optional fixed64 gameserver_steam_id = 3; 72 | optional uint32 seconds_until_shutdown = 4; 73 | } 74 | 75 | message CMsgSteamDatagramNoSession { 76 | optional fixed32 client_cookie = 7; 77 | optional fixed32 your_public_ip = 2; 78 | optional fixed32 server_time = 3; 79 | optional fixed64 challenge = 4; 80 | optional uint32 seconds_until_shutdown = 5; 81 | } 82 | 83 | message CMsgSteamDatagramDiagnostic { 84 | optional uint32 severity = 1; 85 | optional string text = 2; 86 | } 87 | 88 | message CMsgSteamDatagramDataCenterState { 89 | message Server { 90 | optional string address = 1; 91 | optional uint32 ping_ms = 2; 92 | } 93 | 94 | message DataCenter { 95 | optional string code = 1; 96 | repeated .CMsgSteamDatagramDataCenterState.Server server_sample = 2; 97 | } 98 | 99 | repeated .CMsgSteamDatagramDataCenterState.DataCenter data_centers = 1; 100 | } 101 | 102 | message CMsgSteamDatagramLinkInstantaneousStats { 103 | optional uint32 out_packets_per_sec_x10 = 1; 104 | optional uint32 out_bytes_per_sec = 2; 105 | optional uint32 in_packets_per_sec_x10 = 3; 106 | optional uint32 in_bytes_per_sec = 4; 107 | optional uint32 ping_ms = 5; 108 | optional uint32 packets_dropped_pct = 6; 109 | optional uint32 packets_weird_sequence_pct = 7; 110 | } 111 | 112 | message CMsgSteamDatagramLinkLifetimeStats { 113 | optional uint64 packets_sent = 3; 114 | optional uint64 kb_sent = 4; 115 | optional uint64 packets_recv = 5; 116 | optional uint64 kb_recv = 6; 117 | optional uint64 packets_recv_sequenced = 7; 118 | optional uint64 packets_recv_dropped = 8; 119 | optional uint64 packets_recv_out_of_order = 9; 120 | optional uint64 packets_recv_duplicate = 10; 121 | optional uint64 packets_recv_lurch = 11; 122 | } 123 | 124 | message CMsgSteamDatagramConnectionQuality { 125 | optional .CMsgSteamDatagramLinkInstantaneousStats instantaneous = 1; 126 | optional .CMsgSteamDatagramLinkLifetimeStats lifetime = 2; 127 | } 128 | 129 | message CMsgSteamDatagramConnectionStatsClientToRouter { 130 | optional .CMsgSteamDatagramConnectionQuality c2r = 1; 131 | optional .CMsgSteamDatagramConnectionQuality c2s = 2; 132 | optional fixed32 client_timestamp = 3; 133 | optional fixed32 client_cookie = 8; 134 | optional uint32 seq_num_c2r = 9; 135 | optional uint32 seq_num_c2s = 10; 136 | } 137 | 138 | message CMsgSteamDatagramConnectionStatsRouterToClient { 139 | optional .CMsgSteamDatagramConnectionQuality r2c = 1; 140 | optional .CMsgSteamDatagramConnectionQuality s2c = 2; 141 | optional fixed32 client_timestamp_from_router = 3; 142 | optional fixed32 client_timestamp_from_server = 4; 143 | optional uint32 router_gameserver_latency = 5; 144 | optional uint32 seconds_until_shutdown = 6; 145 | optional fixed32 client_cookie = 7; 146 | optional uint32 seq_num_r2c = 8; 147 | optional uint32 seq_num_s2c = 9; 148 | } 149 | 150 | message CMsgSteamDatagramConnectionStatsRouterToServer { 151 | optional .CMsgSteamDatagramConnectionQuality r2s = 1; 152 | optional .CMsgSteamDatagramConnectionQuality c2s = 2; 153 | optional fixed32 client_timestamp = 3; 154 | optional fixed32 router_timestamp = 4; 155 | optional uint32 seq_num_r2s = 5; 156 | optional uint32 seq_num_c2s = 6; 157 | optional fixed64 client_steam_id = 7; 158 | optional uint32 client_session_id = 8; 159 | } 160 | 161 | message CMsgSteamDatagramConnectionStatsServerToRouter { 162 | optional .CMsgSteamDatagramConnectionQuality s2r = 1; 163 | optional .CMsgSteamDatagramConnectionQuality s2c = 2; 164 | optional uint32 seq_num_s2r = 3; 165 | optional uint32 seq_num_s2c = 4; 166 | optional fixed64 client_steam_id = 5; 167 | optional uint32 client_session_id = 6; 168 | } 169 | 170 | message CMsgSteamDatagramClientPingSampleRequest { 171 | optional fixed32 client_cookie = 1; 172 | } 173 | 174 | message CMsgSteamDatagramClientPingSampleReply { 175 | message RoutingCluster { 176 | optional fixed32 id = 1; 177 | optional uint32 front_ping_ms = 2; 178 | optional uint32 e2e_ping_ms = 3; 179 | } 180 | 181 | optional fixed32 client_cookie = 1; 182 | repeated .CMsgSteamDatagramClientPingSampleReply.RoutingCluster routing_clusters = 2; 183 | } 184 | 185 | message CMsgSteamDatagramClientSwitchedPrimary { 186 | message RouterQuality { 187 | optional uint32 score = 1; 188 | optional uint32 front_ping = 2; 189 | optional uint32 back_ping = 3; 190 | optional uint32 seconds_until_down = 4; 191 | } 192 | 193 | optional fixed32 client_cookie = 1; 194 | optional fixed32 from_ip = 2; 195 | optional uint32 from_port = 3; 196 | optional fixed32 from_router_cluster = 4; 197 | optional uint32 from_active_time = 5; 198 | optional uint32 from_active_packets_recv = 6; 199 | optional string from_dropped_reason = 7; 200 | optional uint32 gap_ms = 8; 201 | optional .CMsgSteamDatagramClientSwitchedPrimary.RouterQuality from_quality_now = 9; 202 | optional .CMsgSteamDatagramClientSwitchedPrimary.RouterQuality to_quality_now = 10; 203 | optional .CMsgSteamDatagramClientSwitchedPrimary.RouterQuality from_quality_then = 11; 204 | optional .CMsgSteamDatagramClientSwitchedPrimary.RouterQuality to_quality_then = 12; 205 | } 206 | 207 | -------------------------------------------------------------------------------- /proto/steammessages.proto: -------------------------------------------------------------------------------- 1 | import "google/protobuf/descriptor.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | extend .google.protobuf.FieldOptions { 7 | optional bool key_field = 60000 [default = false]; 8 | } 9 | 10 | extend .google.protobuf.MessageOptions { 11 | optional int32 msgpool_soft_limit = 60000 [default = 32]; 12 | optional int32 msgpool_hard_limit = 60001 [default = 384]; 13 | } 14 | 15 | enum GCProtoBufMsgSrc { 16 | GCProtoBufMsgSrc_Unspecified = 0; 17 | GCProtoBufMsgSrc_FromSystem = 1; 18 | GCProtoBufMsgSrc_FromSteamID = 2; 19 | GCProtoBufMsgSrc_FromGC = 3; 20 | GCProtoBufMsgSrc_ReplySystem = 4; 21 | } 22 | 23 | message CMsgProtoBufHeader { 24 | option (msgpool_soft_limit) = 256; 25 | option (msgpool_hard_limit) = 1024; 26 | optional fixed64 client_steam_id = 1; 27 | optional int32 client_session_id = 2; 28 | optional uint32 source_app_id = 3; 29 | optional fixed64 job_id_source = 10 [default = 18446744073709551615]; 30 | optional fixed64 job_id_target = 11 [default = 18446744073709551615]; 31 | optional string target_job_name = 12; 32 | optional int32 eresult = 13 [default = 2]; 33 | optional string error_message = 14; 34 | optional .GCProtoBufMsgSrc gc_msg_src = 200 [default = GCProtoBufMsgSrc_Unspecified]; 35 | optional uint32 gc_dir_index_source = 201; 36 | } 37 | 38 | message CMsgWebAPIKey { 39 | optional uint32 status = 1 [default = 255]; 40 | optional uint32 account_id = 2 [default = 0]; 41 | optional uint32 publisher_group_id = 3 [default = 0]; 42 | optional uint32 key_id = 4; 43 | optional string domain = 5; 44 | } 45 | 46 | message CMsgHttpRequest { 47 | message RequestHeader { 48 | optional string name = 1; 49 | optional string value = 2; 50 | } 51 | 52 | message QueryParam { 53 | optional string name = 1; 54 | optional bytes value = 2; 55 | } 56 | 57 | optional uint32 request_method = 1; 58 | optional string hostname = 2; 59 | optional string url = 3; 60 | repeated .CMsgHttpRequest.RequestHeader headers = 4; 61 | repeated .CMsgHttpRequest.QueryParam get_params = 5; 62 | repeated .CMsgHttpRequest.QueryParam post_params = 6; 63 | optional bytes body = 7; 64 | optional uint32 absolute_timeout = 8; 65 | } 66 | 67 | message CMsgWebAPIRequest { 68 | optional string UNUSED_job_name = 1; 69 | optional string interface_name = 2; 70 | optional string method_name = 3; 71 | optional uint32 version = 4; 72 | optional .CMsgWebAPIKey api_key = 5; 73 | optional .CMsgHttpRequest request = 6; 74 | optional uint32 routing_app_id = 7; 75 | } 76 | 77 | message CMsgHttpResponse { 78 | message ResponseHeader { 79 | optional string name = 1; 80 | optional string value = 2; 81 | } 82 | 83 | optional uint32 status_code = 1; 84 | repeated .CMsgHttpResponse.ResponseHeader headers = 2; 85 | optional bytes body = 3; 86 | } 87 | 88 | message CMsgAMFindAccounts { 89 | optional uint32 search_type = 1; 90 | optional string search_string = 2; 91 | } 92 | 93 | message CMsgAMFindAccountsResponse { 94 | repeated fixed64 steam_id = 1; 95 | } 96 | 97 | message CMsgNotifyWatchdog { 98 | optional uint32 source = 1; 99 | optional uint32 alert_type = 2; 100 | optional uint32 alert_destination = 3; 101 | optional bool critical = 4; 102 | optional uint32 time = 5; 103 | optional uint32 appid = 6; 104 | optional string text = 7; 105 | } 106 | 107 | message CMsgAMGetLicenses { 108 | optional fixed64 steamid = 1; 109 | } 110 | 111 | message CMsgPackageLicense { 112 | optional uint32 package_id = 1; 113 | optional uint32 time_created = 2; 114 | optional uint32 owner_id = 3; 115 | } 116 | 117 | message CMsgAMGetLicensesResponse { 118 | repeated .CMsgPackageLicense license = 1; 119 | optional uint32 result = 2; 120 | } 121 | 122 | message CMsgAMGetUserGameStats { 123 | optional fixed64 steam_id = 1; 124 | optional fixed64 game_id = 2; 125 | repeated uint32 stats = 3; 126 | } 127 | 128 | message CMsgAMGetUserGameStatsResponse { 129 | message Stats { 130 | optional uint32 stat_id = 1; 131 | optional uint32 stat_value = 2; 132 | } 133 | 134 | message Achievement_Blocks { 135 | optional uint32 achievement_id = 1; 136 | optional uint32 achievement_bit_id = 2; 137 | optional fixed32 unlock_time = 3; 138 | } 139 | 140 | optional fixed64 steam_id = 1; 141 | optional fixed64 game_id = 2; 142 | optional int32 eresult = 3 [default = 2]; 143 | repeated .CMsgAMGetUserGameStatsResponse.Stats stats = 4; 144 | repeated .CMsgAMGetUserGameStatsResponse.Achievement_Blocks achievement_blocks = 5; 145 | } 146 | 147 | message CMsgGCGetCommandList { 148 | optional uint32 app_id = 1; 149 | optional string command_prefix = 2; 150 | } 151 | 152 | message CMsgGCGetCommandListResponse { 153 | repeated string command_name = 1; 154 | } 155 | 156 | message CGCMsgMemCachedGet { 157 | repeated string keys = 1; 158 | } 159 | 160 | message CGCMsgMemCachedGetResponse { 161 | message ValueTag { 162 | optional bool found = 1; 163 | optional bytes value = 2; 164 | } 165 | 166 | repeated .CGCMsgMemCachedGetResponse.ValueTag values = 1; 167 | } 168 | 169 | message CGCMsgMemCachedSet { 170 | message KeyPair { 171 | optional string name = 1; 172 | optional bytes value = 2; 173 | } 174 | 175 | repeated .CGCMsgMemCachedSet.KeyPair keys = 1; 176 | } 177 | 178 | message CGCMsgMemCachedDelete { 179 | repeated string keys = 1; 180 | } 181 | 182 | message CGCMsgMemCachedStats { 183 | } 184 | 185 | message CGCMsgMemCachedStatsResponse { 186 | optional uint64 curr_connections = 1; 187 | optional uint64 cmd_get = 2; 188 | optional uint64 cmd_set = 3; 189 | optional uint64 cmd_flush = 4; 190 | optional uint64 get_hits = 5; 191 | optional uint64 get_misses = 6; 192 | optional uint64 delete_hits = 7; 193 | optional uint64 delete_misses = 8; 194 | optional uint64 bytes_read = 9; 195 | optional uint64 bytes_written = 10; 196 | optional uint64 limit_maxbytes = 11; 197 | optional uint64 curr_items = 12; 198 | optional uint64 evictions = 13; 199 | optional uint64 bytes = 14; 200 | } 201 | 202 | message CGCMsgSQLStats { 203 | optional uint32 schema_catalog = 1; 204 | } 205 | 206 | message CGCMsgSQLStatsResponse { 207 | optional uint32 threads = 1; 208 | optional uint32 threads_connected = 2; 209 | optional uint32 threads_active = 3; 210 | optional uint32 operations_submitted = 4; 211 | optional uint32 prepared_statements_executed = 5; 212 | optional uint32 non_prepared_statements_executed = 6; 213 | optional uint32 deadlock_retries = 7; 214 | optional uint32 operations_timed_out_in_queue = 8; 215 | optional uint32 errors = 9; 216 | } 217 | 218 | message CMsgAMAddFreeLicense { 219 | optional fixed64 steamid = 1; 220 | optional uint32 ip_public = 2; 221 | optional uint32 packageid = 3; 222 | optional string store_country_code = 4; 223 | } 224 | 225 | message CMsgAMAddFreeLicenseResponse { 226 | optional int32 eresult = 1 [default = 2]; 227 | optional int32 purchase_result_detail = 2; 228 | optional fixed64 transid = 3; 229 | } 230 | 231 | message CGCMsgGetIPLocation { 232 | repeated fixed32 ips = 1; 233 | } 234 | 235 | message CIPLocationInfo { 236 | optional uint32 ip = 1; 237 | optional float latitude = 2; 238 | optional float longitude = 3; 239 | optional string country = 4; 240 | optional string state = 5; 241 | optional string city = 6; 242 | } 243 | 244 | message CGCMsgGetIPLocationResponse { 245 | repeated .CIPLocationInfo infos = 1; 246 | } 247 | 248 | message CGCMsgGetIPASN { 249 | repeated fixed32 ips = 1; 250 | } 251 | 252 | message CIPASNInfo { 253 | optional fixed32 ip = 1; 254 | optional uint32 asn = 2; 255 | } 256 | 257 | message CGCMsgGetIPASNResponse { 258 | repeated .CIPASNInfo infos = 1; 259 | } 260 | 261 | message CGCMsgSystemStatsSchema { 262 | optional uint32 gc_app_id = 1; 263 | optional bytes schema_kv = 2; 264 | } 265 | 266 | message CGCMsgGetSystemStats { 267 | } 268 | 269 | message CGCMsgGetSystemStatsResponse { 270 | optional uint32 gc_app_id = 1; 271 | optional bytes stats_kv = 2; 272 | optional uint32 active_jobs = 3; 273 | optional uint32 yielding_jobs = 4; 274 | optional uint32 user_sessions = 5; 275 | optional uint32 game_server_sessions = 6; 276 | optional uint32 socaches = 7; 277 | optional uint32 socaches_to_unload = 8; 278 | optional uint32 socaches_loading = 9; 279 | optional uint32 writeback_queue = 10; 280 | optional uint32 steamid_locks = 11; 281 | optional uint32 logon_queue = 12; 282 | optional uint32 logon_jobs = 13; 283 | } 284 | 285 | message CMsgAMSendEmail { 286 | message ReplacementToken { 287 | optional string token_name = 1; 288 | optional string token_value = 2; 289 | } 290 | 291 | message PersonaNameReplacementToken { 292 | optional fixed64 steamid = 1; 293 | optional string token_name = 2; 294 | } 295 | 296 | optional fixed64 steamid = 1; 297 | optional uint32 email_msg_type = 2; 298 | optional uint32 email_format = 3; 299 | repeated .CMsgAMSendEmail.PersonaNameReplacementToken persona_name_tokens = 5; 300 | optional uint32 source_gc = 6; 301 | repeated .CMsgAMSendEmail.ReplacementToken tokens = 7; 302 | } 303 | 304 | message CMsgAMSendEmailResponse { 305 | optional uint32 eresult = 1 [default = 2]; 306 | } 307 | 308 | message CMsgGCGetEmailTemplate { 309 | optional uint32 app_id = 1; 310 | optional uint32 email_msg_type = 2; 311 | optional int32 email_lang = 3; 312 | optional int32 email_format = 4; 313 | } 314 | 315 | message CMsgGCGetEmailTemplateResponse { 316 | optional uint32 eresult = 1 [default = 2]; 317 | optional bool template_exists = 2; 318 | optional string template = 3; 319 | } 320 | 321 | message CMsgAMGrantGuestPasses2 { 322 | optional fixed64 steam_id = 1; 323 | optional uint32 package_id = 2; 324 | optional int32 passes_to_grant = 3; 325 | optional int32 days_to_expiration = 4; 326 | optional int32 action = 5; 327 | } 328 | 329 | message CMsgAMGrantGuestPasses2Response { 330 | optional int32 eresult = 1 [default = 2]; 331 | optional int32 passes_granted = 2 [default = 0]; 332 | } 333 | 334 | message CGCSystemMsg_GetAccountDetails { 335 | option (msgpool_soft_limit) = 128; 336 | option (msgpool_hard_limit) = 512; 337 | optional fixed64 steamid = 1; 338 | optional uint32 appid = 2; 339 | } 340 | 341 | message CGCSystemMsg_GetAccountDetails_Response { 342 | option (msgpool_soft_limit) = 128; 343 | option (msgpool_hard_limit) = 512; 344 | optional uint32 eresult_deprecated = 1 [default = 2]; 345 | optional string account_name = 2; 346 | optional string persona_name = 3; 347 | optional bool is_profile_created = 26; 348 | optional bool is_profile_public = 4; 349 | optional bool is_inventory_public = 5; 350 | optional bool is_vac_banned = 7; 351 | optional bool is_cyber_cafe = 8; 352 | optional bool is_school_account = 9; 353 | optional bool is_limited = 10; 354 | optional bool is_subscribed = 11; 355 | optional uint32 package = 12; 356 | optional bool is_free_trial_account = 13; 357 | optional uint32 free_trial_expiration = 14; 358 | optional bool is_low_violence = 15; 359 | optional bool is_account_locked_down = 16; 360 | optional bool is_community_banned = 17; 361 | optional bool is_trade_banned = 18; 362 | optional uint32 trade_ban_expiration = 19; 363 | optional uint32 accountid = 20; 364 | optional uint32 suspension_end_time = 21; 365 | optional string currency = 22; 366 | optional uint32 steam_level = 23; 367 | optional uint32 friend_count = 24; 368 | optional uint32 account_creation_time = 25; 369 | optional bool is_steamguard_enabled = 27; 370 | optional bool is_phone_verified = 28; 371 | optional bool is_two_factor_auth_enabled = 29; 372 | optional uint32 two_factor_enabled_time = 30; 373 | optional uint32 phone_verification_time = 31; 374 | optional uint64 phone_id = 33; 375 | optional bool is_phone_identifying = 34; 376 | } 377 | 378 | message CMsgGCGetPersonaNames { 379 | repeated fixed64 steamids = 1; 380 | } 381 | 382 | message CMsgGCGetPersonaNames_Response { 383 | message PersonaName { 384 | optional fixed64 steamid = 1; 385 | optional string persona_name = 2; 386 | } 387 | 388 | repeated .CMsgGCGetPersonaNames_Response.PersonaName succeeded_lookups = 1; 389 | repeated fixed64 failed_lookup_steamids = 2; 390 | } 391 | 392 | message CMsgGCCheckFriendship { 393 | optional fixed64 steamid_left = 1; 394 | optional fixed64 steamid_right = 2; 395 | } 396 | 397 | message CMsgGCCheckFriendship_Response { 398 | optional bool success = 1; 399 | optional bool found_friendship = 2; 400 | } 401 | 402 | message CMsgGCGetAppFriendsList { 403 | optional fixed64 steamid = 1; 404 | } 405 | 406 | message CMsgGCGetAppFriendsList_Response { 407 | optional bool success = 1; 408 | repeated fixed64 steamids = 2; 409 | } 410 | 411 | message CMsgGCMsgMasterSetDirectory { 412 | message SubGC { 413 | optional uint32 dir_index = 1; 414 | optional string name = 2; 415 | optional string box = 3; 416 | optional string command_line = 4; 417 | optional string gc_binary = 5; 418 | } 419 | 420 | optional uint32 master_dir_index = 1; 421 | repeated .CMsgGCMsgMasterSetDirectory.SubGC dir = 2; 422 | } 423 | 424 | message CMsgGCMsgMasterSetDirectory_Response { 425 | optional int32 eresult = 1 [default = 2]; 426 | } 427 | 428 | message CMsgGCMsgWebAPIJobRequestForwardResponse { 429 | optional uint32 dir_index = 1; 430 | } 431 | 432 | message CGCSystemMsg_GetPurchaseTrust_Request { 433 | optional fixed64 steamid = 1; 434 | } 435 | 436 | message CGCSystemMsg_GetPurchaseTrust_Response { 437 | optional bool has_prior_purchase_history = 1; 438 | optional bool has_no_recent_password_resets = 2; 439 | optional bool is_wallet_cash_trusted = 3; 440 | optional uint32 time_all_trusted = 4; 441 | } 442 | 443 | message CMsgGCHAccountVacStatusChange { 444 | optional fixed64 steam_id = 1; 445 | optional uint32 app_id = 2; 446 | optional uint32 rtime_vacban_starts = 3; 447 | optional bool is_banned_now = 4; 448 | optional bool is_banned_future = 5; 449 | } 450 | 451 | message CMsgGCGetPartnerAccountLink { 452 | optional fixed64 steamid = 1; 453 | } 454 | 455 | message CMsgGCGetPartnerAccountLink_Response { 456 | optional uint32 pwid = 1; 457 | optional uint32 nexonid = 2; 458 | } 459 | 460 | message CMsgGCRoutingInfo { 461 | enum RoutingMethod { 462 | RANDOM = 0; 463 | DISCARD = 1; 464 | CLIENT_STEAMID = 2; 465 | PROTOBUF_FIELD_UINT64 = 3; 466 | WEBAPI_PARAM_UINT64 = 4; 467 | } 468 | 469 | repeated uint32 dir_index = 1; 470 | optional .CMsgGCRoutingInfo.RoutingMethod method = 2 [default = RANDOM]; 471 | optional .CMsgGCRoutingInfo.RoutingMethod fallback = 3 [default = DISCARD]; 472 | optional uint32 protobuf_field = 4; 473 | optional string webapi_param = 5; 474 | } 475 | 476 | message CMsgGCMsgMasterSetWebAPIRouting { 477 | message Entry { 478 | optional string interface_name = 1; 479 | optional string method_name = 2; 480 | optional .CMsgGCRoutingInfo routing = 3; 481 | } 482 | 483 | repeated .CMsgGCMsgMasterSetWebAPIRouting.Entry entries = 1; 484 | } 485 | 486 | message CMsgGCMsgMasterSetClientMsgRouting { 487 | message Entry { 488 | optional uint32 msg_type = 1; 489 | optional .CMsgGCRoutingInfo routing = 2; 490 | } 491 | 492 | repeated .CMsgGCMsgMasterSetClientMsgRouting.Entry entries = 1; 493 | } 494 | 495 | message CMsgGCMsgMasterSetWebAPIRouting_Response { 496 | optional int32 eresult = 1 [default = 2]; 497 | } 498 | 499 | message CMsgGCMsgMasterSetClientMsgRouting_Response { 500 | optional int32 eresult = 1 [default = 2]; 501 | } 502 | 503 | message CMsgGCMsgSetOptions { 504 | message MessageRange { 505 | required uint32 low = 1; 506 | required uint32 high = 2; 507 | } 508 | 509 | enum Option { 510 | NOTIFY_USER_SESSIONS = 0; 511 | NOTIFY_SERVER_SESSIONS = 1; 512 | NOTIFY_ACHIEVEMENTS = 2; 513 | NOTIFY_VAC_ACTION = 3; 514 | } 515 | 516 | enum GCSQLVersion { 517 | GCSQL_VERSION_BASELINE = 1; 518 | GCSQL_VERSION_BOOLTYPE = 2; 519 | } 520 | 521 | repeated .CMsgGCMsgSetOptions.Option options = 1; 522 | repeated .CMsgGCMsgSetOptions.MessageRange client_msg_ranges = 2; 523 | optional .CMsgGCMsgSetOptions.GCSQLVersion gcsql_version = 3 [default = GCSQL_VERSION_BASELINE]; 524 | } 525 | 526 | message CMsgGCHUpdateSession { 527 | message ExtraField { 528 | optional string name = 1; 529 | optional string value = 2; 530 | } 531 | 532 | optional fixed64 steam_id = 1; 533 | optional uint32 app_id = 2; 534 | optional bool online = 3; 535 | optional fixed64 server_steam_id = 4; 536 | optional uint32 server_addr = 5; 537 | optional uint32 server_port = 6; 538 | optional uint32 os_type = 7; 539 | optional uint32 client_addr = 8; 540 | repeated .CMsgGCHUpdateSession.ExtraField extra_fields = 9; 541 | } 542 | 543 | message CMsgNotificationOfSuspiciousActivity { 544 | message MultipleGameInstances { 545 | optional uint32 app_instance_count = 1; 546 | repeated fixed64 other_steamids = 2; 547 | } 548 | 549 | optional fixed64 steamid = 1; 550 | optional uint32 appid = 2; 551 | optional .CMsgNotificationOfSuspiciousActivity.MultipleGameInstances multiple_instances = 3; 552 | } 553 | 554 | message CMsgDPPartnerMicroTxns { 555 | message PartnerMicroTxn { 556 | optional uint32 init_time = 1; 557 | optional uint32 last_update_time = 2; 558 | optional uint64 txn_id = 3; 559 | optional uint32 account_id = 4; 560 | optional uint32 line_item = 5; 561 | optional uint64 item_id = 6; 562 | optional uint32 def_index = 7; 563 | optional uint32 price = 8; 564 | optional uint32 tax = 9; 565 | optional uint32 price_usd = 10; 566 | optional uint32 tax_usd = 11; 567 | optional uint32 purchase_type = 12; 568 | optional uint32 steam_txn_type = 13; 569 | optional string country_code = 14; 570 | optional string region_code = 15; 571 | optional int32 quantity = 16; 572 | optional uint64 ref_trans_id = 17; 573 | } 574 | 575 | message PartnerInfo { 576 | optional uint32 partner_id = 1; 577 | optional string partner_name = 2; 578 | optional string currency_code = 3; 579 | optional string currency_name = 4; 580 | } 581 | 582 | optional uint32 appid = 1; 583 | optional string gc_name = 2; 584 | optional .CMsgDPPartnerMicroTxns.PartnerInfo partner = 3; 585 | repeated .CMsgDPPartnerMicroTxns.PartnerMicroTxn transactions = 4; 586 | } 587 | 588 | message CMsgDPPartnerMicroTxnsResponse { 589 | enum EErrorCode { 590 | k_MsgValid = 0; 591 | k_MsgInvalidAppID = 1; 592 | k_MsgInvalidPartnerInfo = 2; 593 | k_MsgNoTransactions = 3; 594 | k_MsgSQLFailure = 4; 595 | k_MsgPartnerInfoDiscrepancy = 5; 596 | k_MsgTransactionInsertFailed = 7; 597 | k_MsgAlreadyRunning = 8; 598 | k_MsgInvalidTransactionData = 9; 599 | } 600 | 601 | optional uint32 eresult = 1 [default = 2]; 602 | optional .CMsgDPPartnerMicroTxnsResponse.EErrorCode eerrorcode = 2 [default = k_MsgValid]; 603 | } 604 | 605 | -------------------------------------------------------------------------------- /proto/steammessages_cloud.steamworkssdk.proto: -------------------------------------------------------------------------------- 1 | import "steammessages_unified_base.steamworkssdk.proto"; 2 | 3 | message CCloud_GetUploadServerInfo_Request { 4 | optional uint32 appid = 1 [(description) = "App ID to which a file will be uploaded to."]; 5 | } 6 | 7 | message CCloud_GetUploadServerInfo_Response { 8 | optional string server_url = 1; 9 | } 10 | 11 | message CCloud_GetFileDetails_Request { 12 | optional uint64 ugcid = 1 [(description) = "ID of the Cloud file to get details for."]; 13 | optional uint32 appid = 2 [(description) = "App ID the file belongs to."]; 14 | } 15 | 16 | message CCloud_UserFile { 17 | optional uint32 appid = 1; 18 | optional uint64 ugcid = 2; 19 | optional string filename = 3; 20 | optional uint64 timestamp = 4; 21 | optional uint32 file_size = 5; 22 | optional string url = 6; 23 | optional fixed64 steamid_creator = 7; 24 | } 25 | 26 | message CCloud_GetFileDetails_Response { 27 | optional .CCloud_UserFile details = 1; 28 | } 29 | 30 | message CCloud_EnumerateUserFiles_Request { 31 | optional uint32 appid = 1 [(description) = "App ID to enumerate the files of."]; 32 | optional bool extended_details = 2 [(description) = "(Optional) Get extended details back on the files found. Defaults to only returned the app Id and UGC Id of the files found."]; 33 | optional uint32 count = 3 [(description) = "(Optional) Maximum number of results to return on this call. Defaults to a maximum of 500 files returned."]; 34 | optional uint32 start_index = 4 [(description) = "(Optional) Starting index to begin enumeration at. Defaults to the beginning of the list."]; 35 | } 36 | 37 | message CCloud_EnumerateUserFiles_Response { 38 | repeated .CCloud_UserFile files = 1; 39 | optional uint32 total_files = 2; 40 | } 41 | 42 | message CCloud_Delete_Request { 43 | optional string filename = 1; 44 | optional uint32 appid = 2 [(description) = "App ID the file belongs to."]; 45 | } 46 | 47 | message CCloud_Delete_Response { 48 | } 49 | 50 | service Cloud { 51 | option (service_description) = "A service for Steam Cloud operations."; 52 | rpc GetUploadServerInfo (.CCloud_GetUploadServerInfo_Request) returns (.CCloud_GetUploadServerInfo_Response) { 53 | option (method_description) = "Returns the URL of the proper cloud server for a user."; 54 | } 55 | rpc GetFileDetails (.CCloud_GetFileDetails_Request) returns (.CCloud_GetFileDetails_Response) { 56 | option (method_description) = "Returns details on a Cloud file."; 57 | } 58 | rpc EnumerateUserFiles (.CCloud_EnumerateUserFiles_Request) returns (.CCloud_EnumerateUserFiles_Response) { 59 | option (method_description) = "Enumerates Cloud files for a user of a given app ID. Returns up to 500 files at a time."; 60 | } 61 | rpc Delete (.CCloud_Delete_Request) returns (.CCloud_Delete_Response) { 62 | option (method_description) = "Deletes a file from the user's cloud."; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /proto/steammessages_oauth.steamworkssdk.proto: -------------------------------------------------------------------------------- 1 | import "steammessages_unified_base.steamworkssdk.proto"; 2 | 3 | message COAuthToken_ImplicitGrantNoPrompt_Request { 4 | optional string clientid = 1 [(description) = "Client ID for which to count the number of issued tokens"]; 5 | } 6 | 7 | message COAuthToken_ImplicitGrantNoPrompt_Response { 8 | optional string access_token = 1 [(description) = "OAuth Token, granted on success"]; 9 | optional string redirect_uri = 2 [(description) = "Redirection URI provided during client registration."]; 10 | } 11 | 12 | service OAuthToken { 13 | option (service_description) = "Service containing methods to manage OAuth tokens"; 14 | rpc ImplicitGrantNoPrompt (.COAuthToken_ImplicitGrantNoPrompt_Request) returns (.COAuthToken_ImplicitGrantNoPrompt_Response) { 15 | option (method_description) = "Grants an implicit OAuth token (grant type 'token') for the specified client ID on behalf of a user without prompting"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /proto/steammessages_unified_base.steamworkssdk.proto: -------------------------------------------------------------------------------- 1 | import "google/protobuf/descriptor.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | extend .google.protobuf.FieldOptions { 7 | optional string description = 50000; 8 | } 9 | 10 | extend .google.protobuf.ServiceOptions { 11 | optional string service_description = 50000; 12 | optional .EProtoExecutionSite service_execution_site = 50008 [default = k_EProtoExecutionSiteUnknown]; 13 | } 14 | 15 | extend .google.protobuf.MethodOptions { 16 | optional string method_description = 50000; 17 | } 18 | 19 | extend .google.protobuf.EnumOptions { 20 | optional string enum_description = 50000; 21 | } 22 | 23 | extend .google.protobuf.EnumValueOptions { 24 | optional string enum_value_description = 50000; 25 | } 26 | 27 | enum EProtoExecutionSite { 28 | k_EProtoExecutionSiteUnknown = 0; 29 | k_EProtoExecutionSiteSteamClient = 3; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /proto/te.proto: -------------------------------------------------------------------------------- 1 | import "networkbasetypes.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum ETEProtobufIds { 7 | TE_EffectDispatchId = 400; 8 | TE_ArmorRicochetId = 401; 9 | TE_BeamEntPointId = 402; 10 | TE_BeamEntsId = 403; 11 | TE_BeamPointsId = 404; 12 | TE_BeamRingId = 405; 13 | TE_BreakModelId = 406; 14 | TE_BSPDecalId = 407; 15 | TE_BubblesId = 408; 16 | TE_BubbleTrailId = 409; 17 | TE_DecalId = 410; 18 | TE_WorldDecalId = 411; 19 | TE_EnergySplashId = 412; 20 | TE_FizzId = 413; 21 | TE_ShatterSurfaceId = 414; 22 | TE_GlowSpriteId = 415; 23 | TE_ImpactId = 416; 24 | TE_MuzzleFlashId = 417; 25 | TE_BloodStreamId = 418; 26 | TE_ExplosionId = 419; 27 | TE_DustId = 420; 28 | TE_LargeFunnelId = 421; 29 | TE_SparksId = 422; 30 | TE_PhysicsPropId = 423; 31 | TE_PlayerDecalId = 424; 32 | TE_ProjectedDecalId = 425; 33 | TE_SmokeId = 426; 34 | } 35 | 36 | message CMsgTEArmorRicochet { 37 | optional .CMsgVector pos = 1; 38 | optional .CMsgVector dir = 2; 39 | } 40 | 41 | message CMsgTEBaseBeam { 42 | optional fixed64 modelindex = 1; 43 | optional fixed64 haloindex = 2; 44 | optional uint32 startframe = 3; 45 | optional uint32 framerate = 4; 46 | optional float life = 5; 47 | optional float width = 6; 48 | optional float endwidth = 7; 49 | optional uint32 fadelength = 8; 50 | optional float amplitude = 9; 51 | optional fixed32 color = 10; 52 | optional uint32 speed = 11; 53 | optional uint32 flags = 12; 54 | } 55 | 56 | message CMsgTEBeamEntPoint { 57 | optional .CMsgTEBaseBeam base = 1; 58 | optional uint32 startentity = 2; 59 | optional uint32 endentity = 3; 60 | optional .CMsgVector start = 4; 61 | optional .CMsgVector end = 5; 62 | } 63 | 64 | message CMsgTEBeamEnts { 65 | optional .CMsgTEBaseBeam base = 1; 66 | optional uint32 startentity = 2; 67 | optional uint32 endentity = 3; 68 | } 69 | 70 | message CMsgTEBeamPoints { 71 | optional .CMsgTEBaseBeam base = 1; 72 | optional .CMsgVector start = 2; 73 | optional .CMsgVector end = 3; 74 | } 75 | 76 | message CMsgTEBeamRing { 77 | optional .CMsgTEBaseBeam base = 1; 78 | optional uint32 startentity = 2; 79 | optional uint32 endentity = 3; 80 | } 81 | 82 | message CMsgTEBreakModel { 83 | optional .CMsgVector origin = 1; 84 | optional .CMsgQAngle angles = 2; 85 | optional .CMsgVector size = 3; 86 | optional .CMsgVector velocity = 4; 87 | optional uint32 randomization = 5; 88 | optional fixed64 modelindex = 6; 89 | optional uint32 count = 7; 90 | optional float time = 8; 91 | optional uint32 flags = 9; 92 | } 93 | 94 | message CMsgTEBSPDecal { 95 | optional .CMsgVector origin = 1; 96 | optional .CMsgVector normal = 2; 97 | optional .CMsgVector saxis = 3; 98 | optional uint32 entity = 4; 99 | optional uint32 index = 5; 100 | } 101 | 102 | message CMsgTEBubbles { 103 | optional .CMsgVector mins = 1; 104 | optional .CMsgVector maxs = 2; 105 | optional float height = 3; 106 | optional uint32 count = 4; 107 | optional float speed = 5; 108 | } 109 | 110 | message CMsgTEBubbleTrail { 111 | optional .CMsgVector mins = 1; 112 | optional .CMsgVector maxs = 2; 113 | optional float waterz = 3; 114 | optional uint32 count = 4; 115 | optional float speed = 5; 116 | } 117 | 118 | message CMsgTEDecal { 119 | optional .CMsgVector origin = 1; 120 | optional .CMsgVector start = 2; 121 | optional uint32 entity = 3; 122 | optional uint32 hitbox = 4; 123 | optional uint32 index = 5; 124 | } 125 | 126 | message CMsgEffectData { 127 | optional .CMsgVector origin = 1; 128 | optional .CMsgVector start = 2; 129 | optional .CMsgVector normal = 3; 130 | optional .CMsgQAngle angles = 4; 131 | optional fixed32 entity = 5; 132 | optional fixed32 otherentity = 6; 133 | optional float scale = 7; 134 | optional float magnitude = 8; 135 | optional float radius = 9; 136 | optional fixed32 surfaceprop = 10; 137 | optional fixed64 effectindex = 11; 138 | optional uint32 damagetype = 12; 139 | optional uint32 material = 13; 140 | optional uint32 hitbox = 14; 141 | optional uint32 color = 15; 142 | optional uint32 flags = 16; 143 | optional int32 attachmentindex = 17; 144 | optional uint32 effectname = 18; 145 | optional uint32 attachmentname = 19; 146 | } 147 | 148 | message CMsgTEEffectDispatch { 149 | optional .CMsgEffectData effectdata = 1; 150 | } 151 | 152 | message CMsgTEEnergySplash { 153 | optional .CMsgVector pos = 1; 154 | optional .CMsgVector dir = 2; 155 | optional bool explosive = 3; 156 | } 157 | 158 | message CMsgTEFizz { 159 | optional uint32 entity = 1; 160 | optional uint32 density = 2; 161 | optional int32 current = 3; 162 | } 163 | 164 | message CMsgTEShatterSurface { 165 | optional .CMsgVector origin = 1; 166 | optional .CMsgQAngle angles = 2; 167 | optional .CMsgVector force = 3; 168 | optional .CMsgVector forcepos = 4; 169 | optional float width = 5; 170 | optional float height = 6; 171 | optional float shardsize = 7; 172 | optional uint32 surfacetype = 8; 173 | optional fixed32 frontcolor = 9; 174 | optional fixed32 backcolor = 10; 175 | } 176 | 177 | message CMsgTEGlowSprite { 178 | optional .CMsgVector origin = 1; 179 | optional float scale = 2; 180 | optional float life = 3; 181 | optional uint32 brightness = 4; 182 | } 183 | 184 | message CMsgTEImpact { 185 | optional .CMsgVector origin = 1; 186 | optional .CMsgVector normal = 2; 187 | optional uint32 type = 3; 188 | } 189 | 190 | message CMsgTEMuzzleFlash { 191 | optional .CMsgVector origin = 1; 192 | optional .CMsgQAngle angles = 2; 193 | optional float scale = 3; 194 | optional uint32 type = 4; 195 | } 196 | 197 | message CMsgTEBloodStream { 198 | optional .CMsgVector origin = 1; 199 | optional .CMsgVector direction = 2; 200 | optional fixed32 color = 3; 201 | optional uint32 amount = 4; 202 | } 203 | 204 | message CMsgTEExplosion { 205 | optional .CMsgVector origin = 1; 206 | optional uint32 framerate = 2; 207 | optional uint32 flags = 3; 208 | optional .CMsgVector normal = 4; 209 | optional uint32 materialtype = 5; 210 | optional uint32 radius = 6; 211 | optional uint32 magnitude = 7; 212 | optional float scale = 8; 213 | optional bool affect_ragdolls = 9; 214 | } 215 | 216 | message CMsgTEDust { 217 | optional .CMsgVector origin = 1; 218 | optional float size = 2; 219 | optional float speed = 3; 220 | optional .CMsgVector direction = 4; 221 | } 222 | 223 | message CMsgTELargeFunnel { 224 | optional .CMsgVector origin = 1; 225 | optional uint32 reversed = 2; 226 | } 227 | 228 | message CMsgTESparks { 229 | optional .CMsgVector origin = 1; 230 | optional uint32 magnitude = 2; 231 | optional uint32 length = 3; 232 | optional .CMsgVector direction = 4; 233 | } 234 | 235 | message CMsgTEPhysicsProp { 236 | optional .CMsgVector origin = 1; 237 | optional .CMsgVector velocity = 2; 238 | optional .CMsgQAngle angles = 3; 239 | optional fixed32 skin = 4; 240 | optional uint32 flags = 5; 241 | optional uint32 effects = 6; 242 | optional fixed32 color = 7; 243 | optional fixed64 modelindex = 8; 244 | optional uint32 breakmodelsnottomake = 9; 245 | optional float scale = 10; 246 | } 247 | 248 | message CMsgTEPlayerDecal { 249 | optional .CMsgVector origin = 1; 250 | optional uint32 player = 2; 251 | optional uint32 entity = 3; 252 | } 253 | 254 | message CMsgTEProjectedDecal { 255 | optional .CMsgVector origin = 1; 256 | optional .CMsgQAngle angles = 2; 257 | optional uint32 index = 3; 258 | optional float distance = 4; 259 | } 260 | 261 | message CMsgTESmoke { 262 | optional .CMsgVector origin = 1; 263 | optional float scale = 2; 264 | } 265 | 266 | message CMsgTEWorldDecal { 267 | optional .CMsgVector origin = 1; 268 | optional .CMsgVector normal = 2; 269 | optional uint32 index = 3; 270 | } 271 | 272 | -------------------------------------------------------------------------------- /proto/toolevents.proto: -------------------------------------------------------------------------------- 1 | import "networkbasetypes.proto"; 2 | 3 | option cc_generic_services = false; 4 | 5 | message ChangeMapToolEvent { 6 | optional string mapname = 1; 7 | } 8 | 9 | message TraceRayServerToolEvent { 10 | optional .CMsgVector start = 1; 11 | optional .CMsgVector end = 2; 12 | } 13 | 14 | message ToolTraceRayResult { 15 | optional bool hit = 1; 16 | optional .CMsgVector impact = 2; 17 | optional .CMsgVector normal = 3; 18 | optional float distance = 4; 19 | optional float fraction = 5; 20 | optional int32 ehandle = 6; 21 | } 22 | 23 | message SpawnEntityToolEvent { 24 | optional bytes entity_keyvalues = 1; 25 | optional bool clientsideentity = 2; 26 | } 27 | 28 | message SpawnEntityToolEventResult { 29 | optional int32 ehandle = 1; 30 | } 31 | 32 | message DestroyEntityToolEvent { 33 | optional int32 ehandle = 1; 34 | } 35 | 36 | message DestroyAllEntitiesToolEvent { 37 | } 38 | 39 | message RestartMapToolEvent { 40 | } 41 | 42 | message ToolEvent_GetEntityInfo { 43 | optional int32 ehandle = 1; 44 | optional bool clientsideentity = 2; 45 | } 46 | 47 | message ToolEvent_GetEntityInfoResult { 48 | optional string cppclass = 1 [default = "shithead"]; 49 | optional string classname = 2; 50 | optional string name = 3; 51 | optional .CMsgVector origin = 4; 52 | optional .CMsgVector mins = 5; 53 | optional .CMsgVector maxs = 6; 54 | } 55 | 56 | message ToolEvent_GetEntityInputs { 57 | optional int32 ehandle = 1; 58 | optional bool clientsideentity = 2; 59 | } 60 | 61 | message ToolEvent_GetEntityInputsResult { 62 | repeated string input_list = 1; 63 | } 64 | 65 | message ToolEvent_FireEntityInput { 66 | optional int32 ehandle = 1; 67 | optional bool clientsideentity = 2; 68 | optional string input_name = 3; 69 | optional string input_param = 4; 70 | } 71 | 72 | message ToolEvent_SFMRecordingStateChanged { 73 | optional bool isrecording = 1; 74 | } 75 | 76 | message ToolEvent_SFMToolActiveStateChanged { 77 | optional bool isactive = 1; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /proto/usermessages.proto: -------------------------------------------------------------------------------- 1 | import "networkbasetypes.proto"; 2 | 3 | option optimize_for = SPEED; 4 | option cc_generic_services = false; 5 | 6 | enum EBaseUserMessages { 7 | UM_AchievementEvent = 101; 8 | UM_CloseCaption = 102; 9 | UM_CloseCaptionDirect = 103; 10 | UM_CurrentTimescale = 104; 11 | UM_DesiredTimescale = 105; 12 | UM_Fade = 106; 13 | UM_GameTitle = 107; 14 | UM_HintText = 109; 15 | UM_HudMsg = 110; 16 | UM_HudText = 111; 17 | UM_KeyHintText = 112; 18 | UM_ColoredText = 113; 19 | UM_RequestState = 114; 20 | UM_ResetHUD = 115; 21 | UM_Rumble = 116; 22 | UM_SayText = 117; 23 | UM_SayText2 = 118; 24 | UM_SayTextChannel = 119; 25 | UM_Shake = 120; 26 | UM_ShakeDir = 121; 27 | UM_TextMsg = 124; 28 | UM_ScreenTilt = 125; 29 | UM_Train = 126; 30 | UM_VGUIMenu = 127; 31 | UM_VoiceMask = 128; 32 | UM_VoiceSubtitle = 129; 33 | UM_SendAudio = 130; 34 | UM_ItemPickup = 131; 35 | UM_AmmoDenied = 132; 36 | UM_CrosshairAngle = 133; 37 | UM_ShowMenu = 134; 38 | UM_CreditsMsg = 135; 39 | UM_CloseCaptionPlaceholder = 142; 40 | UM_CameraTransition = 143; 41 | UM_AudioParameter = 144; 42 | UM_ParticleManager = 145; 43 | UM_HudError = 146; 44 | UM_CustomGameEvent = 148; 45 | UM_MAX_BASE = 200; 46 | } 47 | 48 | enum EBaseEntityMessages { 49 | EM_PlayJingle = 136; 50 | EM_ScreenOverlay = 137; 51 | EM_RemoveAllDecals = 138; 52 | EM_PropagateForce = 139; 53 | EM_DoSpark = 140; 54 | EM_FixAngle = 141; 55 | } 56 | 57 | enum eRollType { 58 | ROLL_NONE = -1; 59 | ROLL_STATS = 0; 60 | ROLL_CREDITS = 1; 61 | ROLL_LATE_JOIN_LOGO = 2; 62 | ROLL_OUTTRO = 3; 63 | } 64 | 65 | enum PARTICLE_MESSAGE { 66 | GAME_PARTICLE_MANAGER_EVENT_CREATE = 0; 67 | GAME_PARTICLE_MANAGER_EVENT_UPDATE = 1; 68 | GAME_PARTICLE_MANAGER_EVENT_UPDATE_FORWARD = 2; 69 | GAME_PARTICLE_MANAGER_EVENT_UPDATE_ORIENTATION = 3; 70 | GAME_PARTICLE_MANAGER_EVENT_UPDATE_FALLBACK = 4; 71 | GAME_PARTICLE_MANAGER_EVENT_UPDATE_ENT = 5; 72 | GAME_PARTICLE_MANAGER_EVENT_UPDATE_OFFSET = 6; 73 | GAME_PARTICLE_MANAGER_EVENT_DESTROY = 7; 74 | GAME_PARTICLE_MANAGER_EVENT_DESTROY_INVOLVING = 8; 75 | GAME_PARTICLE_MANAGER_EVENT_RELEASE = 9; 76 | GAME_PARTICLE_MANAGER_EVENT_LATENCY = 10; 77 | GAME_PARTICLE_MANAGER_EVENT_SHOULD_DRAW = 11; 78 | GAME_PARTICLE_MANAGER_EVENT_FROZEN = 12; 79 | GAME_PARTICLE_MANAGER_EVENT_CHANGE_CONTROL_POINT_ATTACHMENT = 13; 80 | } 81 | 82 | message CUserMessageAchievementEvent { 83 | optional uint32 achievement = 1; 84 | } 85 | 86 | message CUserMessageCloseCaption { 87 | optional fixed32 hash = 1; 88 | optional float duration = 2; 89 | optional bool from_player = 3; 90 | optional int32 ent_index = 4; 91 | } 92 | 93 | message CUserMessageCloseCaptionDirect { 94 | optional fixed32 hash = 1; 95 | optional float duration = 2; 96 | optional bool from_player = 3; 97 | optional int32 ent_index = 4; 98 | } 99 | 100 | message CUserMessageCloseCaptionPlaceholder { 101 | optional string string = 1; 102 | optional float duration = 2; 103 | optional bool from_player = 3; 104 | optional int32 ent_index = 4; 105 | } 106 | 107 | message CUserMessageCurrentTimescale { 108 | optional float current = 1; 109 | } 110 | 111 | message CUserMessageDesiredTimescale { 112 | optional float desired = 1; 113 | optional float acceleration = 2; 114 | optional float minblendrate = 3; 115 | optional float blenddeltamultiplier = 4; 116 | } 117 | 118 | message CUserMessageFade { 119 | optional uint32 duration = 1; 120 | optional uint32 hold_time = 2; 121 | optional uint32 flags = 3; 122 | optional fixed32 color = 4; 123 | } 124 | 125 | message CUserMessageShake { 126 | optional uint32 command = 1; 127 | optional float amplitude = 2; 128 | optional float frequency = 3; 129 | optional float duration = 4; 130 | } 131 | 132 | message CUserMessageShakeDir { 133 | optional .CUserMessageShake shake = 1; 134 | optional .CMsgVector direction = 2; 135 | } 136 | 137 | message CUserMessageScreenTilt { 138 | optional uint32 command = 1; 139 | optional bool ease_in_out = 2; 140 | optional .CMsgVector angle = 3; 141 | optional float duration = 4; 142 | optional float time = 5; 143 | } 144 | 145 | message CUserMessageSayText { 146 | optional uint32 playerindex = 1; 147 | optional string text = 2; 148 | optional bool chat = 3; 149 | } 150 | 151 | message CUserMessageSayText2 { 152 | optional uint32 entityindex = 1; 153 | optional bool chat = 2; 154 | optional string messagename = 3; 155 | optional string param1 = 4; 156 | optional string param2 = 5; 157 | optional string param3 = 6; 158 | optional string param4 = 7; 159 | } 160 | 161 | message CUserMessageHudMsg { 162 | optional uint32 channel = 1; 163 | optional float x = 2; 164 | optional float y = 3; 165 | optional fixed32 color1 = 4; 166 | optional fixed32 color2 = 5; 167 | optional uint32 effect = 6; 168 | optional float fade_in_time = 7; 169 | optional float fade_out_time = 8; 170 | optional float hold_time = 9; 171 | optional float fx_time = 10; 172 | optional string message = 11; 173 | } 174 | 175 | message CUserMessageHudText { 176 | optional string message = 1; 177 | } 178 | 179 | message CUserMessageTextMsg { 180 | optional uint32 dest = 1; 181 | repeated string param = 2; 182 | } 183 | 184 | message CUserMessageGameTitle { 185 | } 186 | 187 | message CUserMessageResetHUD { 188 | } 189 | 190 | message CUserMessageSendAudio { 191 | optional string soundname = 1; 192 | optional bool stop = 2; 193 | } 194 | 195 | message CUserMessageAudioParameter { 196 | optional uint32 parameter_type = 1; 197 | optional uint32 name_hash_code = 2; 198 | optional float value = 3; 199 | } 200 | 201 | message CUserMessageVoiceMask { 202 | repeated uint32 gamerules_masks = 1; 203 | repeated uint32 ban_masks = 2; 204 | optional bool mod_enable = 3; 205 | } 206 | 207 | message CUserMessageRequestState { 208 | } 209 | 210 | message CUserMessageHintText { 211 | optional string message = 1; 212 | } 213 | 214 | message CUserMessageKeyHintText { 215 | repeated string messages = 1; 216 | } 217 | 218 | message CUserMessageVoiceSubtitle { 219 | optional int32 player = 1; 220 | optional int32 menu = 2; 221 | optional int32 item = 3; 222 | } 223 | 224 | message CUserMessageVGUIMenu { 225 | message Keys { 226 | optional string name = 1; 227 | optional string value = 2; 228 | } 229 | 230 | optional string name = 1; 231 | optional bool show = 2; 232 | repeated .CUserMessageVGUIMenu.Keys keys = 3; 233 | } 234 | 235 | message CUserMessageRumble { 236 | optional int32 index = 1; 237 | optional int32 data = 2; 238 | optional int32 flags = 3; 239 | } 240 | 241 | message CUserMessageTrain { 242 | optional uint32 position = 1; 243 | } 244 | 245 | message CUserMessageSayTextChannel { 246 | optional int32 player = 1; 247 | optional int32 channel = 2; 248 | optional string text = 3; 249 | } 250 | 251 | message CUserMessageColoredText { 252 | optional uint32 color = 1; 253 | optional string text = 2; 254 | optional bool reset = 3; 255 | optional int32 context_player_id = 4; 256 | optional int32 context_value = 5; 257 | optional int32 context_team_id = 6; 258 | } 259 | 260 | message CUserMessageItemPickup { 261 | optional string itemname = 1; 262 | } 263 | 264 | message CUserMessageAmmoDenied { 265 | optional uint32 ammo_id = 1; 266 | } 267 | 268 | message CUserMessageCrosshairAngle { 269 | optional .CMsgQAngle angcrosshair = 1; 270 | } 271 | 272 | message CUserMessageShowMenu { 273 | optional uint32 validslots = 1; 274 | optional uint32 displaytime = 2; 275 | optional bool needmore = 3; 276 | optional string menustring = 4; 277 | } 278 | 279 | message CUserMessageCreditsMsg { 280 | optional .eRollType rolltype = 1 [default = ROLL_NONE]; 281 | } 282 | 283 | message CEntityMessagePlayJingle { 284 | } 285 | 286 | message CEntityMessageScreenOverlay { 287 | optional bool start_effect = 1; 288 | } 289 | 290 | message CEntityMessageRemoveAllDecals { 291 | optional bool remove_decals = 1; 292 | } 293 | 294 | message CEntityMessagePropagateForce { 295 | optional .CMsgVector impulse = 1; 296 | } 297 | 298 | message CEntityMessageDoSpark { 299 | optional .CMsgVector origin = 1; 300 | optional uint32 entityindex = 2; 301 | optional float radius = 3; 302 | optional fixed32 color = 4; 303 | optional uint32 beams = 5; 304 | optional float thick = 6; 305 | optional float duration = 7; 306 | } 307 | 308 | message CEntityMessageFixAngle { 309 | optional bool relative = 1; 310 | optional .CMsgQAngle angle = 2; 311 | } 312 | 313 | message CUserMessageCameraTransition { 314 | message Transition_DataDriven { 315 | optional string filename = 1; 316 | optional int32 attach_ent_index = 2; 317 | } 318 | 319 | optional uint32 camera_type = 1; 320 | optional float duration = 2; 321 | optional .CUserMessageCameraTransition.Transition_DataDriven params_data_driven = 3; 322 | } 323 | 324 | message CUserMsg_ParticleManager { 325 | message ReleaseParticleIndex { 326 | } 327 | 328 | message CreateParticle { 329 | optional fixed64 particle_name_index = 1; 330 | optional int32 attach_type = 2; 331 | optional int32 entity_handle = 3; 332 | } 333 | 334 | message DestroyParticle { 335 | optional bool destroy_immediately = 1; 336 | } 337 | 338 | message DestroyParticleInvolving { 339 | optional bool destroy_immediately = 1; 340 | optional int32 entity_handle = 3; 341 | } 342 | 343 | message UpdateParticle { 344 | optional int32 control_point = 1; 345 | optional .CMsgVector position = 2; 346 | } 347 | 348 | message UpdateParticleFwd { 349 | optional int32 control_point = 1; 350 | optional .CMsgVector forward = 2; 351 | } 352 | 353 | message UpdateParticleOrient { 354 | optional int32 control_point = 1; 355 | optional .CMsgVector forward = 2; 356 | optional .CMsgVector right = 3; 357 | optional .CMsgVector up = 4; 358 | } 359 | 360 | message UpdateParticleFallback { 361 | optional int32 control_point = 1; 362 | optional .CMsgVector position = 2; 363 | } 364 | 365 | message UpdateParticleOffset { 366 | optional int32 control_point = 1; 367 | optional .CMsgVector origin_offset = 2; 368 | } 369 | 370 | message UpdateParticleEnt { 371 | optional int32 control_point = 1; 372 | optional int32 entity_handle = 2; 373 | optional int32 attach_type = 3; 374 | optional int32 attachment = 4; 375 | optional .CMsgVector fallback_position = 5; 376 | optional bool include_wearables = 6; 377 | } 378 | 379 | message UpdateParticleSetFrozen { 380 | optional bool set_frozen = 1; 381 | } 382 | 383 | message UpdateParticleShouldDraw { 384 | optional bool should_draw = 1; 385 | } 386 | 387 | message ChangeControlPointAttachment { 388 | optional int32 attachment_old = 1; 389 | optional int32 attachment_new = 2; 390 | optional int32 entity_handle = 3; 391 | } 392 | 393 | required .PARTICLE_MESSAGE type = 1 [default = GAME_PARTICLE_MANAGER_EVENT_CREATE]; 394 | required uint32 index = 2; 395 | optional .CUserMsg_ParticleManager.ReleaseParticleIndex release_particle_index = 3; 396 | optional .CUserMsg_ParticleManager.CreateParticle create_particle = 4; 397 | optional .CUserMsg_ParticleManager.DestroyParticle destroy_particle = 5; 398 | optional .CUserMsg_ParticleManager.DestroyParticleInvolving destroy_particle_involving = 6; 399 | optional .CUserMsg_ParticleManager.UpdateParticle update_particle = 7; 400 | optional .CUserMsg_ParticleManager.UpdateParticleFwd update_particle_fwd = 8; 401 | optional .CUserMsg_ParticleManager.UpdateParticleOrient update_particle_orient = 9; 402 | optional .CUserMsg_ParticleManager.UpdateParticleFallback update_particle_fallback = 10; 403 | optional .CUserMsg_ParticleManager.UpdateParticleOffset update_particle_offset = 11; 404 | optional .CUserMsg_ParticleManager.UpdateParticleEnt update_particle_ent = 12; 405 | optional .CUserMsg_ParticleManager.UpdateParticleShouldDraw update_particle_should_draw = 14; 406 | optional .CUserMsg_ParticleManager.UpdateParticleSetFrozen update_particle_set_frozen = 15; 407 | optional .CUserMsg_ParticleManager.ChangeControlPointAttachment change_control_point_attachment = 16; 408 | } 409 | 410 | message CUserMsg_HudError { 411 | optional int32 order_id = 1; 412 | } 413 | 414 | message CUserMsg_CustomGameEvent { 415 | optional string event_name = 1; 416 | optional bytes data = 2; 417 | } 418 | 419 | -------------------------------------------------------------------------------- /snappy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A pure JS implementation of Snappy decompression, for use in the browser 3 | **/ 4 | var ByteBuffer = require('bytebuffer'); 5 | module.exports = { 6 | uncompressSync: function(buf) { 7 | var input = ByteBuffer.wrap(buf); 8 | var size = input.readVarint32(); 9 | var output = new ByteBuffer(size); 10 | output.offset = 0; 11 | output.length = size; 12 | input.littleEndian = true; 13 | var copy = function(output, length, offset) { 14 | var ptr = output.offset - offset; 15 | for (var i = 0; i < length; ++i) { 16 | output.writeByte(output.readByte(ptr + i)); 17 | } 18 | }; 19 | while (input.remaining()) { 20 | var tag = input.readUint8(); 21 | switch (tag & 3) { 22 | case 0: 23 | var length = (tag >> 2) + 1; 24 | if (length >= 61) { 25 | var bytes = length - 60; 26 | length = 0; 27 | for (var i = 0; i < bytes; ++i) { 28 | length |= input.readUint8() << (8 * i); 29 | } 30 | length++; 31 | } 32 | for (var i = 0; i < length; ++i) { 33 | output.writeByte(input.readByte()); 34 | } 35 | break; 36 | case 1: 37 | var length = ((tag >> 2) & 7) + 4; 38 | var offset = ((tag >> 5) << 8) | input.readUint8(); 39 | copy(output, length, offset); 40 | break; 41 | case 2: 42 | var length = (tag >> 2) + 1; 43 | var offset = input.readUint16(); 44 | copy(output, length, offset); 45 | break; 46 | case 3: 47 | var length = (tag >> 2) + 1; 48 | var offset = input.readUint32(); 49 | copy(output, length, offset); 50 | break; 51 | }; 52 | } 53 | output.offset = 0; 54 | return output; 55 | } 56 | }; -------------------------------------------------------------------------------- /stringTables.js: -------------------------------------------------------------------------------- 1 | var BitStream = require('./BitStream'); 2 | var snappy = require('./snappy'); 3 | var util = require('./util'); 4 | var extractBuffer = util.extractBuffer; 5 | module.exports = function(p) { 6 | //string tables may mutate over the lifetime of the replay. 7 | //Therefore we listen for create/update events and modify the table as needed. 8 | //p.on("CDemoStringTables", readCDemoStringTables); 9 | p.on("CSVCMsg_CreateStringTable", readCreateStringTable); 10 | p.on("CSVCMsg_UpdateStringTable", readUpdateStringTable); 11 | 12 | function readCDemoStringTables(data) { 13 | //rather than processing when we read this demo message, we want to create when we read the packet CSVCMsg_CreateStringTable 14 | //this packet is just emitted as a state dump at intervals 15 | return; 16 | } 17 | 18 | function readCreateStringTable(msg) { 19 | //create a stringtable 20 | //console.error(data); 21 | var buf = extractBuffer(msg.string_data); 22 | if (msg.data_compressed) { 23 | //decompress the string data with snappy 24 | //early source 2 replays may use LZSS, we can detect this by reading the first four bytes of buffer 25 | buf = snappy.uncompressSync(buf); 26 | } 27 | //pass the buffer and parse string table data from it 28 | var items = parseStringTableData(buf, msg.num_entries, msg.user_data_fixed_size, msg.user_data_size); 29 | //console.error(items); 30 | //remove the buf and replace with items, which is a decoded version of it 31 | msg.string_data = {}; 32 | // Insert the items into the table as an object 33 | items.forEach(function(it) { 34 | msg.string_data[it.index] = it; 35 | }); 36 | p.stringTables.tablesByName[msg.name] = msg; 37 | p.stringTables.tables.push(msg); 38 | // Apply the updates to baseline state 39 | if (msg.name === "instancebaseline") { 40 | p.updateInstanceBaseline(); 41 | } 42 | } 43 | 44 | function readUpdateStringTable(msg) { 45 | //update a string table 46 | //retrieve table by id 47 | var table = p.stringTables.tables[msg.table_id]; 48 | //extract native buffer 49 | var buf = extractBuffer(msg.string_data); 50 | if (table) { 51 | var items = parseStringTableData(buf, msg.num_changed_entries, table.user_data_fixed_size, table.user_data_size); 52 | var string_data = table.string_data; 53 | items.forEach(function(it) { 54 | //console.error(it); 55 | if (!string_data[it.index]) { 56 | //we don't have this item in the string table yet, add it 57 | string_data[it.index] = it; 58 | } 59 | else { 60 | //we're updating an existing item 61 | //only update key if the new key is not blank 62 | if (it.key) { 63 | //console.error("updating key %s->%s at index %s on %s, id %s", string_data[it.index].key, it.key, it.index, table.name, data.table_id); 64 | string_data[it.index].key = it.key; 65 | //string_data[it.index].key = [].concat(string_data[it.index].key).concat(it.key); 66 | } 67 | //only update value if the new item has a nonempty value buffer 68 | if (it.value.length) { 69 | //console.error("updating value length %s->%s at index %s on %s", string_data[it.index].value.length, it.value.length, it.index, table.name); 70 | string_data[it.index].value = it.value; 71 | } 72 | } 73 | }); 74 | // Apply the updates to baseline state 75 | if (msg.name === "instancebaseline") { 76 | p.updateInstanceBaseline(); 77 | } 78 | } 79 | else { 80 | console.err("string table %s doesn't exist!", msg.table_id); 81 | throw "string table doesn't exist!"; 82 | } 83 | } 84 | /** 85 | * Parses a buffer of string table data and returns an array of decoded items 86 | **/ 87 | function parseStringTableData(buf, num_entries, userDataFixedSize, userDataSize) { 88 | // Some tables have no data 89 | if (!buf.limit) { 90 | return []; 91 | } 92 | var items = []; 93 | var bs = BitStream(buf); 94 | // Start with an index of -1. 95 | // If the first item is at index 0 it will use a incr operation. 96 | var index = -1; 97 | var STRINGTABLE_KEY_HISTORY_SIZE = 32; 98 | // Maintain a list of key history 99 | // each entry is a string 100 | var keyHistory = []; 101 | // Loop through entries in the data structure 102 | // Each entry is a tuple consisting of {index, key, value} 103 | // Index can either be incremented from the previous position or overwritten with a given entry. 104 | // Key may be omitted (will be represented here as "") 105 | // Value may be omitted 106 | for (var i = 0; i < num_entries; i++) { 107 | var key = null; 108 | var value = new Buffer(0); 109 | // Read a boolean to determine whether the operation is an increment or 110 | // has a fixed index position. A fixed index position of zero should be 111 | // the last data in the buffer, and indicates that all data has been read. 112 | var incr = bs.readBoolean(); 113 | if (incr) { 114 | index += 1; 115 | } 116 | else { 117 | index = bs.readVarUInt() + 1; 118 | } 119 | // Some values have keys, some don't. 120 | var hasKey = bs.readBoolean(); 121 | if (hasKey) { 122 | // Some entries use reference a position in the key history for 123 | // part of the key. If referencing the history, read the position 124 | // and size from the buffer, then use those to build the string 125 | // combined with an extra string read (null terminated). 126 | // Alternatively, just read the string. 127 | var useHistory = bs.readBoolean(); 128 | if (useHistory) { 129 | var pos = bs.readBits(5); 130 | var size = bs.readBits(5); 131 | if (pos >= keyHistory.length) { 132 | //history doesn't have this position, just read 133 | key = bs.readNullTerminatedString(); 134 | } 135 | else { 136 | var s = keyHistory[pos]; 137 | if (size > s.length) { 138 | //our target size is longer than the key stored in history 139 | //pad the remaining size with a null terminated string from stream 140 | key = (s + bs.readNullTerminatedString()); 141 | } 142 | else { 143 | //we only want a piece of the historical string, slice it out and read the null terminator 144 | key = s.slice(0, size) + bs.readNullTerminatedString(); 145 | } 146 | } 147 | } 148 | else { 149 | //don't use the history, just read the string 150 | key = bs.readNullTerminatedString(); 151 | } 152 | keyHistory.push(key); 153 | if (keyHistory.length > STRINGTABLE_KEY_HISTORY_SIZE) { 154 | //drop the oldest key if we hit the cap 155 | keyHistory.shift(); 156 | } 157 | } 158 | // Some entries have a value. 159 | var hasValue = bs.readBoolean(); 160 | if (hasValue) { 161 | // Values can be either fixed size (with a size specified in 162 | // bits during table creation, or have a variable size with 163 | // a 14-bit prefixed size. 164 | if (userDataFixedSize) { 165 | value = bs.readBuffer(userDataSize); 166 | } 167 | else { 168 | var valueSize = bs.readBits(14); 169 | //XXX mysterious 3 bits of data? 170 | bs.readBits(3); 171 | value = bs.readBuffer(valueSize * 8); 172 | } 173 | } 174 | items.push({ 175 | index: index, 176 | key: key, 177 | value: value 178 | }); 179 | } 180 | //console.error(keyHistory, items, num_entries); 181 | return items; 182 | } 183 | } -------------------------------------------------------------------------------- /test_js_parser.sh: -------------------------------------------------------------------------------- 1 | node `dirname "$0"`/examples/server.js < ../yasp/1872397571_449987541.dem -------------------------------------------------------------------------------- /update_proto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname "$0"` 3 | pushd proto 4 | rm *.proto 5 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/base_gcmessages.proto 6 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/c_peer2peer_netmessages.proto 7 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/connectionless_netmessages.proto 8 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/demo.proto 9 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_broadcastmessages.proto 10 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_clientmessages.proto 11 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_commonmessages.proto 12 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_gcmessages_client.proto 13 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_gcmessages_client_fantasy.proto 14 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_gcmessages_common.proto 15 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_gcmessages_server.proto 16 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_modifiers.proto 17 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/dota_usermessages.proto 18 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/econ_gcmessages.proto 19 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/gameevents.proto 20 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/gcsdk_gcmessages.proto 21 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/gcsystemmsgs.proto 22 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/netmessages.proto 23 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/network_connection.proto 24 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/networkbasetypes.proto 25 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/networksystem_protomessages.proto 26 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/rendermessages.proto 27 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/steamdatagram_messages.proto 28 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/steammessages.proto 29 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/steammessages_cloud.steamworkssdk.proto 30 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/steammessages_oauth.steamworkssdk.proto 31 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/steammessages_unified_base.steamworkssdk.proto 32 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/te.proto 33 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/toolevents.proto 34 | wget https://raw.githubusercontent.com/SteamDatabase/GameTracking/master/Protobufs/dota/usermessages.proto -------------------------------------------------------------------------------- /util.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extractBuffer: function(bb) { 3 | return bb; 4 | //rewrap it in a new Buffer to force usage of node Buffer wrapper rather than ArrayBuffer when in browser 5 | //return new Buffer(bb.toBuffer()); 6 | } 7 | } --------------------------------------------------------------------------------