├── generated_proto └── .gitignore ├── .gitignore ├── demo.proto ├── netmessages.proto ├── Makefile ├── demoinfo2.cpp ├── demofiledump.h ├── dota_commonmessages.proto ├── dota_modifiers.proto ├── README.txt ├── demofile.h ├── demofile.cpp ├── usermessages.proto ├── dota_usermessages.proto ├── demofiledump.cpp └── ai_activity.proto /generated_proto/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dem 2 | *.o 3 | demoinfo2 4 | output.txt 5 | -------------------------------------------------------------------------------- /demo.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitsuhiko/dota2-demoinfo2/HEAD/demo.proto -------------------------------------------------------------------------------- /netmessages.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitsuhiko/dota2-demoinfo2/HEAD/netmessages.proto -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EXECUTABLE=demoinfo2 2 | 3 | CPP_FILES=$(wildcard *.cpp) 4 | OBJ_FILES=$(CPP_FILES:.cpp=.o) 5 | PROTO_SRC_FILES=$(wildcard *.proto) 6 | PROTO_CPP_FILES=$(addprefix generated_proto/,$(PROTO_SRC_FILES:.proto=.pb.cc)) 7 | PROTO_OBJ_FILES=$(PROTO_CPP_FILES:.cc=.o) 8 | 9 | LD_FLAGS=-lsnappy -lprotobuf -L/usr/local/lib 10 | CC_FLAGS=-I/usr/local/include 11 | PROTOBUF_FLAGS=-I/usr/local/include 12 | 13 | all: ${EXECUTABLE} 14 | 15 | clean: 16 | rm -f ${EXECUTABLE} 17 | rm -f *.o 18 | rm -f generated_proto/* 19 | 20 | generated_proto/%.pb.cc: %.proto 21 | protoc ${PROTO_SRC_FILES} ${PROTOBUF_FLAGS} -I. --cpp_out=generated_proto 22 | 23 | ${EXECUTABLE}: ${PROTO_OBJ_FILES} ${OBJ_FILES} 24 | g++ ${LD_FLAGS} -o $@ ${OBJ_FILES} ${PROTO_OBJ_FILES} 25 | 26 | .cpp.o: ${CPP_FILES} 27 | g++ ${CC_FLAGS} -c -o $@ $< 28 | 29 | .cc.o: ${PROTO_CPP_FILES} 30 | g++ ${CC_FLAGS} -c -o $@ $< 31 | 32 | .PHONY: all clean 33 | -------------------------------------------------------------------------------- /demoinfo2.cpp: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | 25 | #include "demofiledump.h" 26 | 27 | int main( int argc, char *argv[] ) 28 | { 29 | CDemoFileDump DemoFileDump; 30 | 31 | if( argc <= 1 ) 32 | { 33 | printf( "demoinfo2_public.exe filename.dem\n" ); 34 | exit( 0 ); 35 | } 36 | 37 | if( DemoFileDump.Open( argv[ 1 ] ) ) 38 | { 39 | DemoFileDump.DoDump(); 40 | } 41 | 42 | return 1; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /demofiledump.h: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | 25 | #ifndef DEMOFILEDUMP_H 26 | #define DEMOFILEDUMP_H 27 | 28 | #include "demofile.h" 29 | 30 | #include "generated_proto/netmessages.pb.h" 31 | 32 | class CDemoFileDump 33 | { 34 | public: 35 | CDemoFileDump() : m_nFrameNumber( 0 ) {} 36 | ~CDemoFileDump() {} 37 | 38 | bool Open( const char *filename ); 39 | void DoDump(); 40 | 41 | public: 42 | void DumpDemoPacket( const std::string& buf ); 43 | void DumpUserMessage( const void *parseBuffer, int BufferSize ); 44 | void PrintDemoHeader( EDemoCommands DemoCommand, int tick, int size, int uncompressed_size ); 45 | void MsgPrintf( const ::google::protobuf::Message& msg, int size, const char *fmt, ... ); 46 | 47 | public: 48 | CDemoFile m_demofile; 49 | CSVCMsg_GameEventList m_GameEventList; 50 | 51 | int m_nFrameNumber; 52 | }; 53 | 54 | #endif // DEMOFILEDUMP_H 55 | 56 | -------------------------------------------------------------------------------- /dota_commonmessages.proto: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | // 25 | // Purpose: The file defines our Google Protocol Buffers which are used in over 26 | // the wire messages for the Source engine. 27 | // 28 | //============================================================================= 29 | 30 | // We care more about speed than code size 31 | option optimize_for = SPEED; 32 | 33 | // We don't use the service generation functionality 34 | option cc_generic_services = false; 35 | 36 | 37 | // 38 | // STYLE NOTES: 39 | // 40 | // Use CamelCase CMsgMyMessageName style names for messages. 41 | // 42 | // Use lowercase _ delimited names like my_steam_id for field names, this is non-standard for Steam, 43 | // but plays nice with the Google formatted code generation. 44 | // 45 | // Try not to use required fields ever. Only do so if you are really really sure you'll never want them removed. 46 | // Optional should be preffered as it will make versioning easier and cleaner in the future if someone refactors 47 | // your message and wants to remove or rename fields. 48 | // 49 | // Use fixed64 for JobId_t, GID_t, or SteamID. This is appropriate for any field that is normally 50 | // going to be larger than 2^56. Otherwise use int64 for 64 bit values that are frequently smaller 51 | // than 2^56 as it will safe space on the wire in those cases. 52 | // 53 | // Similar to fixed64, use fixed32 for RTime32 or other 32 bit values that are frequently larger than 54 | // 2^28. It will safe space in those cases, otherwise use int32 which will safe space for smaller values. 55 | // An exception to this rule for RTime32 is if the value will frequently be zero rather than set to an actual 56 | // time. 57 | // 58 | 59 | import "google/protobuf/descriptor.proto"; 60 | 61 | // for CMsgVector, etc. 62 | import "netmessages.proto"; 63 | 64 | //============================================================================= 65 | // Dota Common Messages 66 | //============================================================================= 67 | 68 | message CDOTAMsg_LocationPing 69 | { 70 | optional int32 x = 1; 71 | optional int32 y = 2; 72 | optional int32 target = 3; 73 | optional bool direct_ping = 4; 74 | } 75 | 76 | message CDOTAMsg_MapLine 77 | { 78 | optional int32 x = 1; 79 | optional int32 y = 2; 80 | optional bool initial = 3; 81 | } 82 | 83 | 84 | //============================================================================= 85 | 86 | 87 | -------------------------------------------------------------------------------- /dota_modifiers.proto: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | // 25 | // Purpose: The file defines our Google Protocol Buffers which are used in over 26 | // the wire messages for the Source engine. 27 | // 28 | //============================================================================= 29 | 30 | // We care more about speed than code size 31 | option optimize_for = SPEED; 32 | 33 | // We don't use the service generation functionality 34 | option cc_generic_services = false; 35 | 36 | 37 | // 38 | // STYLE NOTES: 39 | // 40 | // Use CamelCase CMsgMyMessageName style names for messages. 41 | // 42 | // Use lowercase _ delimited names like my_steam_id for field names, this is non-standard for Steam, 43 | // but plays nice with the Google formatted code generation. 44 | // 45 | // Try not to use required fields ever. Only do so if you are really really sure you'll never want them removed. 46 | // Optional should be preffered as it will make versioning easier and cleaner in the future if someone refactors 47 | // your message and wants to remove or rename fields. 48 | // 49 | // Use fixed64 for JobId_t, GID_t, or SteamID. This is appropriate for any field that is normally 50 | // going to be larger than 2^56. Otherwise use int64 for 64 bit values that are frequently smaller 51 | // than 2^56 as it will safe space on the wire in those cases. 52 | // 53 | // Similar to fixed64, use fixed32 for RTime32 or other 32 bit values that are frequently larger than 54 | // 2^28. It will safe space in those cases, otherwise use int32 which will safe space for smaller values. 55 | // An exception to this rule for RTime32 is if the value will frequently be zero rather than set to an actual 56 | // time. 57 | // 58 | 59 | import "google/protobuf/descriptor.proto"; 60 | 61 | // for CMsgVector, etc. 62 | import "netmessages.proto"; 63 | 64 | enum DOTA_MODIFIER_ENTRY_TYPE 65 | { 66 | DOTA_MODIFIER_ENTRY_TYPE_ACTIVE = 1; 67 | DOTA_MODIFIER_ENTRY_TYPE_REMOVED = 2; 68 | }; 69 | 70 | message CDOTAModifierBuffTableEntry 71 | { 72 | required DOTA_MODIFIER_ENTRY_TYPE entry_type = 1; 73 | required int32 parent = 2; // ehandle to parent owner 74 | required int32 index = 3; // index into the modifier list on the entity (local to each entity) 75 | required int32 serial_num = 4; // global serial number 76 | 77 | optional int32 name = 5; // index into the modifier name string table 78 | optional int32 ability_level = 6; 79 | optional int32 stack_count = 7; 80 | optional float creation_time = 8; 81 | optional float duration = 9 [ default = -1.0 ]; 82 | optional int32 caster = 10; 83 | optional int32 ability = 11; 84 | 85 | // optional custom data 86 | optional int32 armor = 12; // used by invoker 87 | optional float fade_time = 13; // used by invisiblity 88 | optional bool subtle = 14; // used by invisiblity 89 | optional float channel_time = 15; // used by teleport 90 | optional CMsgVector v_start = 16; // used by teleport 91 | optional CMsgVector v_end = 17; // used by teleport 92 | optional string portal_loop_appear = 18; // used by teleport 93 | optional string portal_loop_disappear = 19; // used by teleport 94 | optional string hero_loop_appear = 20; // used by teleport 95 | optional string hero_loop_disappear = 21; // used by teleport 96 | optional int32 movement_speed = 22; // used by smoke of deceit 97 | optional bool aura = 23; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Note Armin: This is the same thing as was released by Valve just that 2 | windows specific stuff was changed so that it compiles on OS X (and 3 | hopefully Linux). 4 | 5 | 6 | ------------------------------------------------------------------------- 7 | 8 | Original Readme: 9 | 10 | Demoinfo2.exe is a tool that will parse Dota 2 demo files (ending in .dem) 11 | and dump out every message in the demo. Using this tool, third parties 12 | can parse the demo for various game events to generate information and 13 | statistics. 14 | 15 | You can use demoinfo2.exe by itself and parse the demo. We have also 16 | included the source code to the program itself to show how to parse and 17 | retrieve information directly. 18 | 19 | Dota 2's demo format is built around using Google's Protocol Buffers 20 | (protobuf). Protobuf is a message/object serialization language that 21 | generates code to serialize the objects efficiently. If you wish to 22 | understand more about protobuf, check out 23 | http://code.google.com/p/protobuf/ 24 | 25 | In order to build demoinfo2 yourself, you will need Visual Studio 2010. 26 | You will also need to download Google's protobuf and snappy libraries. 27 | 28 | - Extract demoinfo2.zip and it will make a new folder named "demoinfo2". 29 | 30 | - Download protobuf from 31 | http://code.google.com/p/protobuf/downloads/detail?name=protobuf-2.4.1.zip 32 | Install this directly in the protobuf-2.4.1 directory that was created 33 | when you extracted demoinfo2. 34 | 35 | - Open protobuf-2.4.1\vsprojects\protobuf.sln into Visual Studio 2010. 36 | You will be asked to convert it, please do so. Once loaded, select 37 | Release version from the build target in the toolbar. Build the 38 | libprotobuf project by right clicking it in the solution list and hitting 39 | "build." You do not need to build the other protobuf projects. 40 | 41 | - Download protoc (the protobuf compiler) from 42 | http://code.google.com/p/protobuf/downloads/detail?name=protoc-2.4.1-win32.zip 43 | and extract this into the protoc-2.4.1-win32 folder that was created when 44 | you extracted demoinfo2. This is the protobuf compiler that parses .proto 45 | files and generates C++ code to parse the messages in the demo file. 46 | 47 | - The last library needed is Google's snappy compression library. 48 | Download it from 49 | http://code.google.com/p/snappy/downloads/detail?name=snappy-1.0.5.tar.gz 50 | and extract it into the snappy-1.0.5 folder. 51 | 52 | Once those libraries are installed, you can now open demoinfo2.sln and 53 | build your own demoinfo2.exe binary. Select the Release build target from 54 | the toolbar and hit build! You will have a new binary in 55 | demoinfo2\Release\demoinfo2.exe. 56 | 57 | To parse a demo, just download one in Dota 2. They will be in C:\Program 58 | Files (x86)\Steam\steamapps\common\dota 2 beta\dota\replays\*.dem. To 59 | dump a demo, just run "demoinfo2 xxx.dem" and it will print out all the 60 | messages in the demo. 61 | 62 | Google's protobuf can generate parses in Java and Python using the same 63 | .proto files. People proficient in those languages can use protoc.exe to 64 | generate code that parses the protobuf messages and parse the demo file in 65 | those languages. 66 | 67 | We are curious to see what people come up with using this tool and please 68 | do post questions and comments about it on the Replay section of the Dota 69 | 2 Development Forums at http://dev.dota2.com/forumdisplay.php?f=19 70 | 71 | ====== Copyright (c) 2012, Valve Corporation, All rights reserved. ======== 72 | 73 | Redistribution and use in source and binary forms, with or without 74 | modification, are permitted provided that the following conditions are met: 75 | 76 | Redistributions of source code must retain the above copyright notice, this 77 | list of conditions and the following disclaimer. 78 | Redistributions in binary form must reproduce the above copyright notice, 79 | this list of conditions and the following disclaimer in the documentation 80 | and/or other materials provided with the distribution. 81 | 82 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 83 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 84 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 85 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 86 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 87 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 88 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 89 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 90 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 91 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 92 | THE POSSIBILITY OF SUCH DAMAGE. 93 | =========================================================================== 94 | 95 | -------------------------------------------------------------------------------- /demofile.h: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | 25 | #ifndef DEMOFILE_H 26 | #define DEMOFILE_H 27 | 28 | #include "generated_proto/demo.pb.h" 29 | 30 | typedef int32_t int32; 31 | typedef uint32_t uint32; 32 | typedef uint64_t uint64; 33 | typedef uint32_t CRC32_t; 34 | 35 | #define PROTODEMO_HEADER_ID "PBUFDEM" 36 | #define DEMOFILE_FULLPACKETS_VERSION 2 37 | 38 | struct protodemoheader_t 39 | { 40 | char demofilestamp[ 8 ]; // PROTODEMO_HEADER_ID 41 | int32 fileinfo_offset; 42 | }; 43 | 44 | #define MAX_PLAYER_NAME_LENGTH 32 45 | #define MAX_CUSTOM_FILES 4 // max 4 files 46 | #define SIGNED_GUID_LEN 32 // Hashed CD Key (32 hex alphabetic chars + 0 terminator ) 47 | 48 | typedef struct player_info_s 49 | { 50 | // network xuid 51 | uint64 xuid; 52 | // scoreboard information 53 | char name[MAX_PLAYER_NAME_LENGTH]; 54 | // local server user ID, unique while server is running 55 | int userID; 56 | // global unique player identifer 57 | char guid[SIGNED_GUID_LEN + 1]; 58 | // friends identification number 59 | uint32 friendsID; 60 | // friends name 61 | char friendsName[MAX_PLAYER_NAME_LENGTH]; 62 | // true, if player is a bot controlled by game.dll 63 | bool fakeplayer; 64 | // true if player is the HLTV proxy 65 | bool ishltv; 66 | #if defined( REPLAY_ENABLED ) 67 | // true if player is the Replay proxy 68 | bool isreplay; 69 | #endif 70 | // custom files CRC for this player 71 | CRC32_t customFiles[MAX_CUSTOM_FILES]; 72 | // this counter increases each time the server downloaded a new file 73 | unsigned char filesDownloaded; 74 | } player_info_t; 75 | 76 | class IDemoMessage 77 | { 78 | public: 79 | virtual ~IDemoMessage() {}; 80 | 81 | virtual EDemoCommands GetType( void ) const = 0; // returns module specific header tag 82 | virtual size_t GetSize() const = 0; 83 | virtual ::google::protobuf::Message& GetProtoMsg() = 0; 84 | }; 85 | 86 | template< EDemoCommands msgType, typename PB_OBJECT_TYPE > 87 | class CDemoMessagePB : public IDemoMessage, public PB_OBJECT_TYPE 88 | { 89 | public: 90 | CDemoMessagePB() {} 91 | virtual ~CDemoMessagePB() {} 92 | 93 | virtual EDemoCommands GetType() const { return msgType; } 94 | virtual size_t GetSize() const { return sizeof( *this ); } 95 | virtual ::google::protobuf::Message& GetProtoMsg() { return *this; } 96 | }; 97 | 98 | typedef CDemoMessagePB< DEM_FileHeader, CDemoFileHeader > CDemoFileHeader_t; 99 | typedef CDemoMessagePB< DEM_FileInfo, CDemoFileInfo > CDemoFileInfo_t; 100 | typedef CDemoMessagePB< DEM_Stop, CDemoStop > CDemoStop_t; 101 | typedef CDemoMessagePB< DEM_SyncTick, CDemoSyncTick > CDemoSyncTick_t; 102 | typedef CDemoMessagePB< DEM_SendTables, CDemoSendTables > CDemoSendTables_t; 103 | typedef CDemoMessagePB< DEM_ClassInfo, CDemoClassInfo > CDemoClassInfo_t; 104 | typedef CDemoMessagePB< DEM_StringTables, CDemoStringTables > CDemoStringTables_t; 105 | typedef CDemoMessagePB< DEM_ConsoleCmd, CDemoConsoleCmd > CDemoConsoleCmd_t; 106 | typedef CDemoMessagePB< DEM_CustomData, CDemoCustomData > CDemoCustomData_t; 107 | typedef CDemoMessagePB< DEM_CustomDataCallbacks, CDemoCustomDataCallbacks > CDemoCustomDataCallbacks_t; 108 | typedef CDemoMessagePB< DEM_UserCmd, CDemoUserCmd > CDemoUserCmd_t; 109 | typedef CDemoMessagePB< DEM_FullPacket, CDemoFullPacket > CDemoFullPacket_t; 110 | typedef CDemoMessagePB< DEM_Packet, CDemoPacket > CDemoPacket_t; 111 | 112 | //----------------------------------------------------------------------------- 113 | // Demo file 114 | //----------------------------------------------------------------------------- 115 | class CDemoFile 116 | { 117 | public: 118 | CDemoFile(); 119 | ~CDemoFile(); 120 | 121 | bool Open(const char *name); 122 | void Close(); 123 | bool IsDone(); 124 | 125 | EDemoCommands ReadMessageType( int *pTick, bool *pbCompressed ); 126 | bool ReadMessage( IDemoMessage *pMsg, bool bCompressed, int *pSize = NULL, int *pUncompressedSize = NULL ); 127 | 128 | private: 129 | std::string m_szFileName; 130 | 131 | size_t m_fileBufferPos; 132 | std::string m_fileBuffer; 133 | 134 | std::string m_parseBufferSnappy; 135 | }; 136 | 137 | uint32 ReadVarInt32( const std::string& buf, size_t& index ); 138 | 139 | #endif // DEMOFILE_H 140 | 141 | -------------------------------------------------------------------------------- /demofile.cpp: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | 25 | #include 26 | #include "demofile.h" 27 | #include "snappy.h" 28 | 29 | uint32 ReadVarInt32( const std::string& buf, size_t& index ) 30 | { 31 | uint32 b; 32 | int count = 0; 33 | uint32 result = 0; 34 | 35 | do 36 | { 37 | if ( count == 5 ) 38 | { 39 | // If we get here it means that the fifth bit had its 40 | // high bit set, which implies corrupt data. 41 | assert( 0 ); 42 | return result; 43 | } 44 | else if ( index >= buf.size() ) 45 | { 46 | assert( 0 ); 47 | return result; 48 | } 49 | 50 | b = buf[ index++ ]; 51 | result |= ( b & 0x7F ) << ( 7 * count ); 52 | ++count; 53 | } while ( b & 0x80 ); 54 | 55 | return result; 56 | } 57 | 58 | CDemoFile::CDemoFile() : 59 | m_fileBufferPos( 0 ) 60 | { 61 | } 62 | 63 | CDemoFile::~CDemoFile() 64 | { 65 | Close(); 66 | } 67 | 68 | bool CDemoFile::IsDone() 69 | { 70 | return m_fileBufferPos >= m_fileBuffer.size(); 71 | } 72 | 73 | EDemoCommands CDemoFile::ReadMessageType( int *pTick, bool *pbCompressed ) 74 | { 75 | uint32 Cmd = ReadVarInt32( m_fileBuffer, m_fileBufferPos ); 76 | 77 | if( pbCompressed ) 78 | *pbCompressed = !!( Cmd & DEM_IsCompressed ); 79 | 80 | Cmd = ( Cmd & ~DEM_IsCompressed ); 81 | 82 | int Tick = ReadVarInt32( m_fileBuffer, m_fileBufferPos ); 83 | if( pTick ) 84 | *pTick = Tick; 85 | 86 | if( m_fileBufferPos >= m_fileBuffer.size() ) 87 | return DEM_Error; 88 | 89 | return ( EDemoCommands )Cmd; 90 | } 91 | 92 | bool CDemoFile::ReadMessage( IDemoMessage *pMsg, bool bCompressed, int *pSize, int *pUncompressedSize ) 93 | { 94 | int Size = ReadVarInt32( m_fileBuffer, m_fileBufferPos ); 95 | 96 | if( pSize ) 97 | { 98 | *pSize = Size; 99 | } 100 | if( pUncompressedSize ) 101 | { 102 | *pUncompressedSize = 0; 103 | } 104 | 105 | if( m_fileBufferPos + Size > m_fileBuffer.size() ) 106 | { 107 | assert( 0 ); 108 | return false; 109 | } 110 | 111 | if( pMsg ) 112 | { 113 | const char *parseBuffer = &m_fileBuffer[ m_fileBufferPos ]; 114 | m_fileBufferPos += Size; 115 | 116 | if( bCompressed ) 117 | { 118 | if ( snappy::IsValidCompressedBuffer( parseBuffer, Size ) ) 119 | { 120 | size_t uDecompressedLen; 121 | 122 | if ( snappy::GetUncompressedLength( parseBuffer, Size, &uDecompressedLen ) ) 123 | { 124 | if( pUncompressedSize ) 125 | { 126 | *pUncompressedSize = uDecompressedLen; 127 | } 128 | 129 | m_parseBufferSnappy.resize( uDecompressedLen ); 130 | char *parseBufferUncompressed = &m_parseBufferSnappy[ 0 ]; 131 | 132 | if ( snappy::RawUncompress( parseBuffer, Size, parseBufferUncompressed ) ) 133 | { 134 | if ( pMsg->GetProtoMsg().ParseFromArray( parseBufferUncompressed, uDecompressedLen ) ) 135 | { 136 | return true; 137 | } 138 | } 139 | } 140 | } 141 | 142 | assert( 0 ); 143 | fprintf( stderr, "CDemoFile::ReadMessage() snappy::RawUncompress failed.\n" ); 144 | return false; 145 | } 146 | 147 | return pMsg->GetProtoMsg().ParseFromArray( parseBuffer, Size ); 148 | } 149 | else 150 | { 151 | m_fileBufferPos += Size; 152 | return true; 153 | } 154 | } 155 | 156 | bool CDemoFile::Open( const char *name ) 157 | { 158 | Close(); 159 | 160 | FILE *fp = fopen( name, "rb" ); 161 | if( fp ) 162 | { 163 | size_t Length; 164 | protodemoheader_t DotaDemoHeader; 165 | 166 | fseek( fp, 0, SEEK_END ); 167 | Length = ftell( fp ); 168 | fseek( fp, 0, SEEK_SET ); 169 | 170 | if( Length < sizeof( DotaDemoHeader ) ) 171 | { 172 | fprintf( stderr, "CDemoFile::Open: file too small. %s.\n", name ); 173 | return false; 174 | } 175 | 176 | fread( &DotaDemoHeader, 1, sizeof( DotaDemoHeader ), fp ); 177 | Length -= sizeof( DotaDemoHeader ); 178 | 179 | if( strcmp( DotaDemoHeader.demofilestamp, PROTODEMO_HEADER_ID ) ) 180 | { 181 | fprintf( stderr, "CDemoFile::Open: demofilestamp doesn't match. %s.\n", name ); 182 | return false; 183 | } 184 | 185 | m_fileBuffer.resize( Length ); 186 | fread( &m_fileBuffer[ 0 ], 1, Length, fp ); 187 | 188 | fclose( fp ); 189 | fp = NULL; 190 | } 191 | 192 | if ( !m_fileBuffer.size() ) 193 | { 194 | fprintf( stderr, "CDemoFile::Open: couldn't open file %s.\n", name ); 195 | Close(); 196 | return false; 197 | } 198 | 199 | m_fileBufferPos = 0; 200 | m_szFileName = name; 201 | return true; 202 | } 203 | 204 | void CDemoFile::Close() 205 | { 206 | m_szFileName.clear(); 207 | 208 | m_fileBufferPos = 0; 209 | m_fileBuffer.clear(); 210 | 211 | m_parseBufferSnappy.clear(); 212 | } 213 | 214 | -------------------------------------------------------------------------------- /usermessages.proto: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | // 25 | // Purpose: The file defines our Google Protocol Buffers which are used in over 26 | // the wire messages for the Source engine. 27 | // 28 | //============================================================================= 29 | 30 | // We care more about speed than code size 31 | option optimize_for = SPEED; 32 | 33 | // We don't use the service generation functionality 34 | option cc_generic_services = false; 35 | 36 | 37 | // 38 | // STYLE NOTES: 39 | // 40 | // Use CamelCase CMsgMyMessageName style names for messages. 41 | // 42 | // Use lowercase _ delimited names like my_steam_id for field names, this is non-standard for Steam, 43 | // but plays nice with the Google formatted code generation. 44 | // 45 | // Try not to use required fields ever. Only do so if you are really really sure you'll never want them removed. 46 | // Optional should be preffered as it will make versioning easier and cleaner in the future if someone refactors 47 | // your message and wants to remove or rename fields. 48 | // 49 | // Use fixed64 for JobId_t, GID_t, or SteamID. This is appropriate for any field that is normally 50 | // going to be larger than 2^56. Otherwise use int64 for 64 bit values that are frequently smaller 51 | // than 2^56 as it will safe space on the wire in those cases. 52 | // 53 | // Similar to fixed64, use fixed32 for RTime32 or other 32 bit values that are frequently larger than 54 | // 2^28. It will safe space in those cases, otherwise use int32 which will safe space for smaller values. 55 | // An exception to this rule for RTime32 is if the value will frequently be zero rather than set to an actual 56 | // time. 57 | // 58 | 59 | import "google/protobuf/descriptor.proto"; 60 | 61 | // for CMsgVector, etc. 62 | import "netmessages.proto"; 63 | 64 | //============================================================================= 65 | // Base User Messages 66 | //============================================================================= 67 | 68 | enum EBaseUserMessages 69 | { 70 | UM_AchievementEvent = 1; 71 | UM_CloseCaption = 2; 72 | UM_CloseCaptionDirect = 3; // Shares message def CUserMsg_CloseCaption 73 | UM_CurrentTimescale = 4; 74 | UM_DesiredTimescale = 5; 75 | UM_Fade = 6; 76 | UM_GameTitle = 7; 77 | UM_Geiger = 8; 78 | UM_HintText = 9; 79 | UM_HudMsg = 10; 80 | UM_HudText = 11; 81 | UM_KeyHintText = 12; 82 | UM_MessageText = 13; 83 | UM_RequestState = 14; 84 | UM_ResetHUD = 15; 85 | UM_Rumble = 16; 86 | UM_SayText = 17; 87 | UM_SayText2 = 18; 88 | UM_SayTextChannel = 19; 89 | UM_Shake = 20; 90 | UM_ShakeDir = 21; 91 | UM_StatsCrawlMsg = 22; 92 | UM_StatsSkipState = 23; 93 | UM_TextMsg = 24; 94 | UM_Tilt = 25; 95 | UM_Train = 26; 96 | UM_VGUIMenu = 27; 97 | UM_VoiceMask = 28; 98 | UM_VoiceSubtitle = 29; 99 | UM_SendAudio = 30; 100 | 101 | // Game specific user messages should start after this 102 | UM_MAX_BASE = 63; 103 | } 104 | 105 | //============================================================================= 106 | 107 | message CUserMsg_AchievementEvent 108 | { 109 | optional uint32 achievement = 1; 110 | } 111 | 112 | message CUserMsg_CloseCaption 113 | { 114 | optional fixed32 hash = 1; 115 | optional float duration = 2; 116 | optional bool from_player = 3; 117 | } 118 | 119 | message CUserMsg_CurrentTimescale 120 | { 121 | optional float current = 1; 122 | } 123 | 124 | message CUserMsg_DesiredTimescale 125 | { 126 | optional float desired = 1; 127 | optional float duration = 2; 128 | optional uint32 interpolator = 3; 129 | optional float start_blend_time = 4; 130 | } 131 | 132 | message CUserMsg_Fade 133 | { 134 | optional uint32 duration = 1; 135 | optional uint32 hold_time = 2; 136 | optional uint32 flags = 3; 137 | optional fixed32 color = 4; 138 | } 139 | 140 | message CUserMsg_Shake 141 | { 142 | optional uint32 command = 1; 143 | optional float amplitude = 2; 144 | optional float frequency = 3; 145 | optional float duration = 4; 146 | } 147 | 148 | message CUserMsg_ShakeDir 149 | { 150 | optional CUserMsg_Shake shake = 1; 151 | optional CMsgVector direction = 2; 152 | } 153 | 154 | message CUserMsg_Tilt 155 | { 156 | optional uint32 command = 1; 157 | optional bool ease_in_out = 2; 158 | optional CMsgVector angle = 3; 159 | optional float duration = 4; 160 | optional float time = 5; 161 | } 162 | 163 | message CUserMsg_SayText 164 | { 165 | optional uint32 client = 1; 166 | optional string text = 2; 167 | optional bool chat = 3; 168 | } 169 | 170 | message CUserMsg_SayText2 171 | { 172 | optional uint32 client = 1; 173 | optional bool chat = 2; 174 | optional string format = 3; 175 | optional string prefix = 4; 176 | optional string text = 5; 177 | optional string location = 6; 178 | } 179 | 180 | message CUserMsg_HudMsg 181 | { 182 | optional uint32 channel = 1; 183 | optional float x = 2; 184 | optional float y = 3; 185 | optional uint32 color1 = 4; 186 | optional uint32 color2 = 5; 187 | optional uint32 effect = 6; 188 | optional float fade_in_time = 7; 189 | optional float fade_out_time = 8; 190 | optional float hold_time = 9; 191 | optional float fx_time = 10; 192 | optional string message = 11; 193 | } 194 | 195 | message CUserMsg_HudText 196 | { 197 | optional string message = 1; 198 | } 199 | 200 | message CUserMsg_TextMsg 201 | { 202 | optional uint32 dest = 1; 203 | repeated string param = 2; 204 | } 205 | 206 | message CUserMsg_GameTitle 207 | { 208 | } 209 | 210 | message CUserMsg_ResetHUD 211 | { 212 | } 213 | 214 | message CUserMsg_SendAudio 215 | { 216 | ///optional fixed32 hash = 1; // sound hash 217 | optional bool stop = 2; 218 | optional string name = 3; // sound name 219 | } 220 | 221 | message CUserMsg_VoiceMask 222 | { 223 | repeated int32 audible_players_mask = 1; 224 | optional bool player_mod_enabled = 2; 225 | } 226 | 227 | message CUserMsg_RequestState 228 | { 229 | } 230 | 231 | message CUserMsg_HintText 232 | { 233 | optional string message = 1; 234 | } 235 | 236 | message CUserMsg_KeyHintText 237 | { 238 | repeated string messages = 1; 239 | } 240 | 241 | message CUserMsg_StatsCrawlMsg 242 | { 243 | } 244 | 245 | message CUserMsg_StatsSkipState 246 | { 247 | optional int32 num_skips = 1; 248 | optional int32 num_players = 2; 249 | } 250 | 251 | message CUserMsg_VoiceSubtitle 252 | { 253 | optional int32 ent_index = 1; 254 | optional int32 menu = 2; 255 | optional int32 item = 3; 256 | } 257 | 258 | message CUserMsg_VGUIMenu 259 | { 260 | optional string name = 1; 261 | optional bool show = 2; 262 | 263 | message Keys 264 | { 265 | optional string name = 1; 266 | optional string value = 2; 267 | } 268 | 269 | repeated Keys keys = 3; 270 | } 271 | 272 | message CUserMsg_Geiger 273 | { 274 | optional int32 range = 1; 275 | } 276 | 277 | message CUserMsg_Rumble 278 | { 279 | optional int32 index = 1; 280 | optional int32 data = 2; 281 | optional int32 flags = 3; 282 | } 283 | 284 | message CUserMsg_Train 285 | { 286 | optional int32 train = 1; 287 | } 288 | 289 | message CUserMsg_SayTextChannel 290 | { 291 | optional int32 player = 1; 292 | optional int32 channel = 2; 293 | optional string text = 3; 294 | } 295 | 296 | message CUserMsg_MessageText 297 | { 298 | optional uint32 color = 1; 299 | optional string text = 2; 300 | } 301 | 302 | 303 | 304 | -------------------------------------------------------------------------------- /dota_usermessages.proto: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | // 25 | // Purpose: The file defines our Google Protocol Buffers which are used in over 26 | // the wire messages for the Source engine. 27 | // 28 | //============================================================================= 29 | 30 | // We care more about speed than code size 31 | option optimize_for = SPEED; 32 | 33 | // We don't use the service generation functionality 34 | option cc_generic_services = false; 35 | 36 | 37 | // 38 | // STYLE NOTES: 39 | // 40 | // Use CamelCase CMsgMyMessageName style names for messages. 41 | // 42 | // Use lowercase _ delimited names like my_steam_id for field names, this is non-standard for Steam, 43 | // but plays nice with the Google formatted code generation. 44 | // 45 | // Try not to use required fields ever. Only do so if you are really really sure you'll never want them removed. 46 | // Optional should be preffered as it will make versioning easier and cleaner in the future if someone refactors 47 | // your message and wants to remove or rename fields. 48 | // 49 | // Use fixed64 for JobId_t, GID_t, or SteamID. This is appropriate for any field that is normally 50 | // going to be larger than 2^56. Otherwise use int64 for 64 bit values that are frequently smaller 51 | // than 2^56 as it will safe space on the wire in those cases. 52 | // 53 | // Similar to fixed64, use fixed32 for RTime32 or other 32 bit values that are frequently larger than 54 | // 2^28. It will safe space in those cases, otherwise use int32 which will safe space for smaller values. 55 | // An exception to this rule for RTime32 is if the value will frequently be zero rather than set to an actual 56 | // time. 57 | // 58 | 59 | import "google/protobuf/descriptor.proto"; 60 | 61 | // for CMsgVector, etc. 62 | import "netmessages.proto"; 63 | 64 | // for Activity 65 | import "ai_activity.proto"; 66 | 67 | // for structures shared between user and client messages 68 | import "dota_commonmessages.proto"; 69 | 70 | //============================================================================= 71 | // Dota User Messages 72 | //============================================================================= 73 | 74 | enum EDotaUserMessages 75 | { 76 | DOTA_UM_AddUnitToSelection = 64; 77 | DOTA_UM_AIDebugLine = 65; 78 | DOTA_UM_ChatEvent = 66; 79 | DOTA_UM_CombatHeroPositions = 67; 80 | DOTA_UM_CombatLogData = 68; 81 | DOTA_UM_CombatLogShowDeath = 70; 82 | DOTA_UM_CreateLinearProjectile = 71; 83 | DOTA_UM_DestroyLinearProjectile = 72; 84 | DOTA_UM_DodgeTrackingProjectiles = 73; 85 | DOTA_UM_GlobalLightColor = 74; 86 | DOTA_UM_GlobalLightDirection = 75; 87 | DOTA_UM_InvalidCommand = 76; 88 | DOTA_UM_LocationPing = 77; 89 | DOTA_UM_MapLine = 78; 90 | DOTA_UM_MiniKillCamInfo = 79; 91 | DOTA_UM_MinimapDebugPoint = 80; 92 | DOTA_UM_MinimapEvent = 81; 93 | DOTA_UM_NevermoreRequiem = 82; 94 | DOTA_UM_OverheadEvent = 83; 95 | DOTA_UM_SetNextAutobuyItem = 84; 96 | DOTA_UM_SharedCooldown = 85; 97 | DOTA_UM_SpectatorPlayerClick = 86; 98 | DOTA_UM_TutorialTipInfo = 87; 99 | DOTA_UM_UnitEvent = 88; 100 | DOTA_UM_ParticleManager = 89; 101 | DOTA_UM_BotChat = 90; 102 | DOTA_UM_HudError = 91; 103 | DOTA_UM_ItemPurchased = 92; 104 | DOTA_UM_Ping = 93; 105 | DOTA_UM_ItemFound = 94; 106 | } 107 | 108 | //============================================================================= 109 | 110 | message CDOTAUserMsg_AIDebugLine 111 | { 112 | optional string message = 1; 113 | } 114 | 115 | message CDOTAUserMsg_Ping 116 | { 117 | optional string message = 1; 118 | } 119 | 120 | enum DOTA_CHAT_MESSAGE 121 | { 122 | CHAT_MESSAGE_INVALID = -1; 123 | 124 | CHAT_MESSAGE_HERO_KILL = 0; 125 | CHAT_MESSAGE_HERO_DENY = 1; 126 | CHAT_MESSAGE_BARRACKS_KILL = 2; 127 | CHAT_MESSAGE_TOWER_KILL = 3; 128 | CHAT_MESSAGE_TOWER_DENY = 4; 129 | CHAT_MESSAGE_FIRSTBLOOD = 5; 130 | CHAT_MESSAGE_STREAK_KILL = 6; 131 | CHAT_MESSAGE_BUYBACK = 7; 132 | CHAT_MESSAGE_AEGIS = 8; 133 | CHAT_MESSAGE_ROSHAN_KILL = 9; 134 | CHAT_MESSAGE_COURIER_LOST = 10; 135 | CHAT_MESSAGE_COURIER_RESPAWNED = 11; 136 | CHAT_MESSAGE_GLYPH_USED = 12; 137 | CHAT_MESSAGE_ITEM_PURCHASE = 13; 138 | CHAT_MESSAGE_CONNECT = 14; 139 | CHAT_MESSAGE_DISCONNECT = 15; 140 | CHAT_MESSAGE_DISCONNECT_WAIT_FOR_RECONNECT = 16; 141 | CHAT_MESSAGE_DISCONNECT_TIME_REMAINING = 17; 142 | CHAT_MESSAGE_DISCONNECT_TIME_REMAINING_PLURAL = 18; 143 | CHAT_MESSAGE_RECONNECT = 19; 144 | CHAT_MESSAGE_ABANDON = 20; 145 | CHAT_MESSAGE_SAFE_TO_LEAVE = 21; 146 | CHAT_MESSAGE_RUNE_PICKUP = 22; 147 | CHAT_MESSAGE_RUNE_BOTTLE = 23; 148 | CHAT_MESSAGE_INTHEBAG = 24; 149 | CHAT_MESSAGE_SECRETSHOP = 25; 150 | CHAT_MESSAGE_ITEM_AUTOPURCHASED = 26; 151 | CHAT_MESSAGE_ITEMS_COMBINED = 27; 152 | CHAT_MESSAGE_SUPER_CREEPS = 28; 153 | CHAT_MESSAGE_CANT_USE_ACTION_ITEM = 29; 154 | CHAT_MESSAGE_CHARGES_EXHAUSTED = 30; 155 | CHAT_MESSAGE_CANTPAUSE = 31; 156 | CHAT_MESSAGE_NOPAUSESLEFT = 32; 157 | CHAT_MESSAGE_CANTPAUSEYET = 33; 158 | CHAT_MESSAGE_PAUSED = 34; 159 | CHAT_MESSAGE_UNPAUSE_COUNTDOWN = 35; 160 | CHAT_MESSAGE_UNPAUSED = 36; 161 | CHAT_MESSAGE_AUTO_UNPAUSED = 37; 162 | CHAT_MESSAGE_YOUPAUSED = 38; 163 | CHAT_MESSAGE_CANTUNPAUSETEAM = 39; 164 | CHAT_MESSAGE_SAFE_TO_LEAVE_ABANDONER = 40; 165 | CHAT_MESSAGE_VOICE_TEXT_BANNED = 41; 166 | CHAT_MESSAGE_SPECTATORS_WATCHING_THIS_GAME = 42; 167 | CHAT_MESSAGE_REPORT_REMINDER = 43; 168 | CHAT_MESSAGE_ECON_ITEM = 44; 169 | CHAT_MESSAGE_TAUNT = 45; 170 | CHAT_MESSAGE_RANDOM = 46; 171 | CHAT_MESSAGE_RD_TURN = 47; 172 | } 173 | 174 | message CDOTAUserMsg_ChatEvent 175 | { 176 | required DOTA_CHAT_MESSAGE type = 1; 177 | 178 | optional uint32 value = 2; 179 | 180 | // ugh 181 | optional sint32 playerid_1 = 3 [ default = -1 ]; 182 | optional sint32 playerid_2 = 4 [ default = -1 ]; 183 | optional sint32 playerid_3 = 5 [ default = -1 ]; 184 | optional sint32 playerid_4 = 6 [ default = -1 ]; 185 | optional sint32 playerid_5 = 7 [ default = -1 ]; 186 | optional sint32 playerid_6 = 8 [ default = -1 ]; 187 | } 188 | 189 | message CDOTAUserMsg_CombatLogData 190 | { 191 | optional uint32 type = 1; 192 | optional uint32 target_name = 2; 193 | optional uint32 attacker_name = 3; 194 | optional bool attacker_illusion = 4; 195 | optional bool target_illusion = 5; 196 | optional uint32 inflictor_name = 6; 197 | optional int32 value = 7; 198 | optional int32 health = 8; 199 | optional float time = 9; 200 | } 201 | 202 | message CDOTAUserMsg_CombatLogShowDeath 203 | { 204 | } 205 | 206 | message CDOTAUserMsg_BotChat 207 | { 208 | optional uint32 player_id = 1; 209 | optional string format = 2; 210 | optional string message = 3; 211 | optional string target = 4; 212 | } 213 | 214 | message CDOTAUserMsg_CombatHeroPositions 215 | { 216 | optional uint32 index = 1; 217 | optional int32 time = 2; 218 | optional CMsgVector2D world_pos = 3; 219 | optional int32 health = 4; 220 | } 221 | 222 | message CDOTAUserMsg_MiniKillCamInfo 223 | { 224 | message Attacker 225 | { 226 | optional uint32 attacker = 1; 227 | optional int32 total_damage = 2; 228 | 229 | message Ability 230 | { 231 | optional uint32 ability = 1; 232 | optional int32 damage = 2; 233 | } 234 | repeated Ability abilities = 3; 235 | } 236 | repeated Attacker attackers = 1; 237 | } 238 | 239 | message CDOTAUserMsg_GlobalLightColor 240 | { 241 | optional uint32 color = 1; 242 | optional float duration = 2; 243 | } 244 | 245 | message CDOTAUserMsg_GlobalLightDirection 246 | { 247 | optional CMsgVector direction = 1; 248 | optional float duration = 2; 249 | } 250 | 251 | message CDOTAUserMsg_LocationPing 252 | { 253 | optional uint32 player_id = 1; 254 | optional CDOTAMsg_LocationPing location_ping = 2; 255 | } 256 | 257 | message CDOTAUserMsg_MinimapEvent 258 | { 259 | optional int32 event_type = 1; 260 | optional int32 entity_handle = 2; 261 | optional int32 x = 3; 262 | optional int32 y = 4; 263 | optional int32 duration = 5; 264 | } 265 | 266 | message CDOTAUserMsg_MapLine 267 | { 268 | optional int32 player_id = 1; 269 | optional CDOTAMsg_MapLine mapline = 2; 270 | } 271 | 272 | message CDOTAUserMsg_MinimapDebugPoint 273 | { 274 | optional CMsgVector location = 1; 275 | optional uint32 color = 2; 276 | optional int32 size = 3; 277 | optional float duration = 4; 278 | } 279 | 280 | message CDOTAUserMsg_CreateLinearProjectile 281 | { 282 | optional CMsgVector origin = 1; 283 | optional CMsgVector2D velocity = 2; 284 | optional int32 latency = 3; 285 | optional int32 entindex = 4; 286 | optional int32 particle_index = 5; 287 | optional int32 handle = 6; 288 | } 289 | 290 | message CDOTAUserMsg_DestroyLinearProjectile 291 | { 292 | optional int32 handle = 1; 293 | } 294 | 295 | message CDOTAUserMsg_DodgeTrackingProjectiles 296 | { 297 | required int32 entindex = 1; 298 | } 299 | 300 | message CDOTAUserMsg_SpectatorPlayerClick 301 | { 302 | required int32 entindex = 1; 303 | optional int32 order_type = 2; 304 | optional int32 target_index = 3; 305 | } 306 | 307 | message CDOTAUserMsg_NevermoreRequiem 308 | { 309 | optional int32 entity_handle = 1; 310 | optional int32 lines = 2; 311 | optional CMsgVector origin = 3; 312 | } 313 | 314 | message CDOTAUserMsg_InvalidCommand 315 | { 316 | optional string message = 1; 317 | } 318 | 319 | message CDOTAUserMsg_HudError 320 | { 321 | optional int32 order_id = 1; 322 | } 323 | 324 | message CDOTAUserMsg_SharedCooldown 325 | { 326 | optional int32 entindex = 1; 327 | optional string name = 2; 328 | optional float cooldown = 3; 329 | optional int32 name_index = 4; 330 | } 331 | 332 | message CDOTAUserMsg_SetNextAutobuyItem 333 | { 334 | optional string name = 1; 335 | } 336 | 337 | enum EDotaEntityMessages 338 | { 339 | DOTA_UNIT_SPEECH = 0; 340 | DOTA_UNIT_SPEECH_MUTE = 1; 341 | DOTA_UNIT_ADD_GESTURE = 2; 342 | DOTA_UNIT_REMOVE_GESTURE = 3; 343 | DOTA_UNIT_REMOVE_ALL_GESTURES = 4; 344 | DOTA_UNIT_FADE_GESTURE = 6; 345 | } 346 | 347 | message CDOTAUserMsg_UnitEvent 348 | { 349 | required EDotaEntityMessages msg_type = 1; 350 | required int32 entity_index = 2; 351 | 352 | message Speech 353 | { 354 | optional int32 concept = 1; 355 | optional string response = 2; 356 | optional int32 recipient_type = 3; 357 | optional int32 level = 4; 358 | } 359 | 360 | optional Speech speech = 3; 361 | 362 | message SpeechMute 363 | { 364 | optional float delay = 1 [default = 0.5]; 365 | } 366 | 367 | optional SpeechMute speech_mute = 4; 368 | 369 | message AddGesture 370 | { 371 | optional Activity activity = 1; 372 | optional int32 slot = 2; 373 | optional float fade_in = 3 [default = 0]; 374 | optional float fade_out = 4 [default = 0.1]; 375 | } 376 | 377 | optional AddGesture add_gesture = 5; 378 | 379 | message RemoveGesture 380 | { 381 | optional Activity activity = 1; 382 | } 383 | 384 | optional RemoveGesture remove_gesture = 6; 385 | 386 | message BloodImpact 387 | { 388 | optional int32 scale = 1; 389 | optional int32 x_normal = 2; 390 | optional int32 y_normal = 3; 391 | } 392 | 393 | optional BloodImpact blood_impact = 7; 394 | 395 | message FadeGesture 396 | { 397 | optional Activity activity = 1; 398 | } 399 | 400 | optional FadeGesture fade_gesture = 8; 401 | } 402 | 403 | message CDOTAUserMsg_ItemPurchased 404 | { 405 | optional int32 item_index = 1; 406 | } 407 | 408 | message CDOTAUserMsg_ItemFound 409 | { 410 | optional int32 player = 1; 411 | optional int32 quality = 2; 412 | optional int32 rarity = 3; 413 | optional int32 method = 4; 414 | optional int32 itemdef = 5; 415 | } 416 | 417 | enum DOTA_PARTICLE_MESSAGE 418 | { 419 | DOTA_PARTICLE_MANAGER_EVENT_CREATE = 0; 420 | DOTA_PARTICLE_MANAGER_EVENT_UPDATE = 1; 421 | DOTA_PARTICLE_MANAGER_EVENT_UPDATE_FORWARD = 2; 422 | DOTA_PARTICLE_MANAGER_EVENT_UPDATE_ORIENTATION = 3; 423 | DOTA_PARTICLE_MANAGER_EVENT_UPDATE_FALLBACK = 4; 424 | DOTA_PARTICLE_MANAGER_EVENT_UPDATE_ENT = 5; 425 | DOTA_PARTICLE_MANAGER_EVENT_UPDATE_OFFSET = 6; 426 | DOTA_PARTICLE_MANAGER_EVENT_DESTROY = 7; 427 | DOTA_PARTICLE_MANAGER_EVENT_DESTROY_INVOLVING = 8; 428 | DOTA_PARTICLE_MANAGER_EVENT_RELEASE = 9; 429 | DOTA_PARTICLE_MANAGER_EVENT_LATENCY = 10; 430 | }; 431 | 432 | message CDOTAUserMsg_ParticleManager 433 | { 434 | message ReleaseParticleIndex 435 | { 436 | } 437 | message CreateParticle 438 | { 439 | optional int32 particle_name_index = 1; 440 | optional int32 attach_type = 2; 441 | optional int32 entity_handle = 3; 442 | } 443 | message DestroyParticle 444 | { 445 | optional bool destroy_immediately = 1; 446 | } 447 | message DestroyParticleInvolving 448 | { 449 | optional bool destroy_immediately = 1; 450 | optional int32 entity_handle = 3; 451 | } 452 | message UpdateParticle 453 | { 454 | optional int32 control_point = 1; 455 | optional CMsgVector position = 2; 456 | } 457 | message UpdateParticleFwd 458 | { 459 | optional int32 control_point = 1; 460 | optional CMsgVector forward = 2; 461 | } 462 | message UpdateParticleOrient 463 | { 464 | optional int32 control_point = 1; 465 | optional CMsgVector forward = 2; 466 | optional CMsgVector right = 3; 467 | optional CMsgVector up = 4; 468 | } 469 | message UpdateParticleFallback 470 | { 471 | optional int32 control_point = 1; 472 | optional CMsgVector position = 2; 473 | } 474 | message UpdateParticleOffset 475 | { 476 | optional int32 control_point = 1; 477 | optional CMsgVector origin_offset = 2; 478 | } 479 | message UpdateParticleEnt 480 | { 481 | optional int32 control_point = 1; 482 | optional int32 entity_handle = 2; 483 | optional int32 attach_type = 3; 484 | optional int32 attachment = 4; 485 | optional CMsgVector fallback_position = 5; 486 | } 487 | message UpdateParticleLatency 488 | { 489 | optional int32 player_latency = 1; 490 | optional int32 tick = 2; 491 | } 492 | 493 | required DOTA_PARTICLE_MESSAGE type = 1; 494 | required uint32 index = 2; 495 | 496 | optional ReleaseParticleIndex release_particle_index = 3; // DOTA_PARTICLE_MANAGER_EVENT_RELEASE 497 | optional CreateParticle create_particle = 4; // DOTA_PARTICLE_MANAGER_EVENT_CREATE 498 | optional DestroyParticle destroy_particle = 5; // DOTA_PARTICLE_MANAGER_EVENT_DESTROY 499 | optional DestroyParticleInvolving destroy_particle_involving = 6; // DOTA_PARTICLE_MANAGER_EVENT_DESTROY_INVOLVING 500 | optional UpdateParticle update_particle = 7; // DOTA_PARTICLE_MANAGER_EVENT_UPDATE 501 | optional UpdateParticleFwd update_particle_fwd = 8; // DOTA_PARTICLE_MANAGER_EVENT_UPDATE_FORWARD 502 | optional UpdateParticleOrient update_particle_orient = 9; // DOTA_PARTICLE_MANAGER_EVENT_UPDATE_ORIENTATION 503 | optional UpdateParticleFallback update_particle_fallback = 10; // DOTA_PARTICLE_MANAGER_EVENT_UPDATE_FALLBACK 504 | optional UpdateParticleOffset update_particle_offset = 11; // DOTA_PARTICLE_MANAGER_EVENT_UPDATE_OFFSET 505 | optional UpdateParticleEnt update_particle_ent = 12; // DOTA_PARTICLE_MANAGER_EVENT_UPDATE_ENT 506 | optional UpdateParticleLatency update_particle_latency = 13; // DOTA_PARTICLE_MANAGER_EVENT_LATENCY 507 | } 508 | 509 | // If you modify this, make sure you update g_OverheadMessageType! 510 | enum DOTA_OVERHEAD_ALERT 511 | { 512 | OVERHEAD_ALERT_GOLD = 0; 513 | OVERHEAD_ALERT_DENY = 1; 514 | OVERHEAD_ALERT_CRITICAL = 2; 515 | OVERHEAD_ALERT_XP = 3; 516 | OVERHEAD_ALERT_BONUS_SPELL_DAMAGE = 4; 517 | OVERHEAD_ALERT_MISS = 5; 518 | OVERHEAD_ALERT_DAMAGE = 6; 519 | OVERHEAD_ALERT_EVADE = 7; 520 | OVERHEAD_ALERT_BLOCK = 8; 521 | OVERHEAD_ALERT_BONUS_POISON_DAMAGE = 9; 522 | }; 523 | 524 | message CDOTAUserMsg_OverheadEvent 525 | { 526 | required DOTA_OVERHEAD_ALERT message_type = 1; 527 | optional int32 value = 2; 528 | optional int32 target_player_entindex = 3; 529 | optional int32 target_entindex = 4; 530 | optional int32 source_player_entindex = 5; 531 | } 532 | 533 | message CDOTAUserMsg_TutorialTipInfo 534 | { 535 | optional string name = 1; 536 | optional int32 progress = 2; 537 | } 538 | 539 | -------------------------------------------------------------------------------- /demofiledump.cpp: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | 25 | #include 26 | #include "demofile.h" 27 | #include "demofiledump.h" 28 | 29 | #include "google/protobuf/descriptor.h" 30 | #include "google/protobuf/reflection_ops.h" 31 | #include "google/protobuf/descriptor.pb.h" 32 | 33 | #include "generated_proto/usermessages.pb.h" 34 | #include "generated_proto/ai_activity.pb.h" 35 | #include "generated_proto/dota_modifiers.pb.h" 36 | #include "generated_proto/dota_commonmessages.pb.h" 37 | #include "generated_proto/dota_usermessages.pb.h" 38 | 39 | void fatal_errorf( const char* fmt, ... ) 40 | { 41 | va_list vlist; 42 | char buf[ 1024 ]; 43 | 44 | va_start( vlist, fmt); 45 | vsnprintf( buf, sizeof( buf ), fmt, vlist ); 46 | buf[ sizeof( buf ) - 1 ] = 0; 47 | va_end( vlist ); 48 | 49 | fprintf( stderr, "\nERROR: %s\n", buf ); 50 | exit( -1 ); 51 | } 52 | 53 | bool CDemoFileDump::Open( const char *filename ) 54 | { 55 | if ( !m_demofile.Open( filename ) ) 56 | { 57 | fprintf( stderr, "Couldn't open '%s'\n", filename ); 58 | return false; 59 | } 60 | 61 | return true; 62 | } 63 | 64 | void CDemoFileDump::MsgPrintf( const ::google::protobuf::Message& msg, int size, const char *fmt, ... ) 65 | { 66 | va_list vlist; 67 | const std::string& TypeName = msg.GetTypeName(); 68 | 69 | // Print the message type and size 70 | printf( "---- %s (%d bytes) -----------------\n", TypeName.c_str(), size ); 71 | 72 | va_start( vlist, fmt); 73 | vprintf( fmt, vlist ); 74 | va_end( vlist ); 75 | } 76 | 77 | template < class T, int msgType > 78 | void PrintUserMessage( CDemoFileDump& Demo, const void *parseBuffer, int BufferSize ) 79 | { 80 | T msg; 81 | 82 | if( msg.ParseFromArray( parseBuffer, BufferSize ) ) 83 | { 84 | Demo.MsgPrintf( msg, BufferSize, "%s", msg.DebugString().c_str() ); 85 | } 86 | } 87 | 88 | void CDemoFileDump::DumpUserMessage( const void *parseBuffer, int BufferSize ) 89 | { 90 | CSVCMsg_UserMessage userMessage; 91 | 92 | if( userMessage.ParseFromArray( parseBuffer, BufferSize ) ) 93 | { 94 | int Cmd = userMessage.msg_type(); 95 | int SizeUM = userMessage.msg_data().size(); 96 | const void *parseBufferUM = &userMessage.msg_data()[ 0 ]; 97 | 98 | switch( Cmd ) 99 | { 100 | #define HANDLE_UserMsg( _x ) case UM_ ## _x: PrintUserMessage< CUserMsg_ ## _x, UM_ ## _x >( *this, parseBufferUM, SizeUM ); break 101 | #define HANDLE_DOTA_UserMsg( _x ) case DOTA_UM_ ## _x: PrintUserMessage< CDOTAUserMsg_ ## _x, DOTA_UM_ ## _x >( *this, parseBufferUM, SizeUM ); break 102 | 103 | default: 104 | printf( "WARNING. DumpUserMessage(): Unknown user message %d.\n", Cmd ); 105 | break; 106 | 107 | HANDLE_UserMsg( AchievementEvent ); // 1, 108 | HANDLE_UserMsg( CloseCaption ); // 2, 109 | //$ HANDLE_UserMsg( CloseCaptionDirect ); // 3, 110 | HANDLE_UserMsg( CurrentTimescale ); // 4, 111 | HANDLE_UserMsg( DesiredTimescale ); // 5, 112 | HANDLE_UserMsg( Fade ); // 6, 113 | HANDLE_UserMsg( GameTitle ); // 7, 114 | HANDLE_UserMsg( Geiger ); // 8, 115 | HANDLE_UserMsg( HintText ); // 9, 116 | HANDLE_UserMsg( HudMsg ); // 10, 117 | HANDLE_UserMsg( HudText ); // 11, 118 | HANDLE_UserMsg( KeyHintText ); // 12, 119 | HANDLE_UserMsg( MessageText ); // 13, 120 | HANDLE_UserMsg( RequestState ); // 14, 121 | HANDLE_UserMsg( ResetHUD ); // 15, 122 | HANDLE_UserMsg( Rumble ); // 16, 123 | HANDLE_UserMsg( SayText ); // 17, 124 | HANDLE_UserMsg( SayText2 ); // 18, 125 | HANDLE_UserMsg( SayTextChannel ); // 19, 126 | HANDLE_UserMsg( Shake ); // 20, 127 | HANDLE_UserMsg( ShakeDir ); // 21, 128 | HANDLE_UserMsg( StatsCrawlMsg ); // 22, 129 | HANDLE_UserMsg( StatsSkipState ); // 23, 130 | HANDLE_UserMsg( TextMsg ); // 24, 131 | HANDLE_UserMsg( Tilt ); // 25, 132 | HANDLE_UserMsg( Train ); // 26, 133 | HANDLE_UserMsg( VGUIMenu ); // 27, 134 | HANDLE_UserMsg( VoiceMask ); // 28, 135 | HANDLE_UserMsg( VoiceSubtitle ); // 29, 136 | HANDLE_UserMsg( SendAudio ); // 30, 137 | 138 | //$ HANDLE_DOTA_UserMsg( AddUnitToSelection ); // 64, 139 | HANDLE_DOTA_UserMsg( AIDebugLine ); // 65, 140 | HANDLE_DOTA_UserMsg( ChatEvent ); // 66, 141 | HANDLE_DOTA_UserMsg( CombatHeroPositions ); // 67, 142 | HANDLE_DOTA_UserMsg( CombatLogData ); // 68, 143 | //$ HANDLE_DOTA_UserMsg( CombatLogName ); // 69, 144 | HANDLE_DOTA_UserMsg( CombatLogShowDeath ); // 70, 145 | HANDLE_DOTA_UserMsg( CreateLinearProjectile ); // 71, 146 | HANDLE_DOTA_UserMsg( DestroyLinearProjectile ); // 72, 147 | HANDLE_DOTA_UserMsg( DodgeTrackingProjectiles );// 73, 148 | HANDLE_DOTA_UserMsg( GlobalLightColor ); // 74, 149 | HANDLE_DOTA_UserMsg( GlobalLightDirection ); // 75, 150 | HANDLE_DOTA_UserMsg( InvalidCommand ); // 76, 151 | HANDLE_DOTA_UserMsg( LocationPing ); // 77, 152 | HANDLE_DOTA_UserMsg( MapLine ); // 78, 153 | HANDLE_DOTA_UserMsg( MiniKillCamInfo ); // 79, 154 | HANDLE_DOTA_UserMsg( MinimapDebugPoint ); // 80, 155 | HANDLE_DOTA_UserMsg( MinimapEvent ); // 81, 156 | HANDLE_DOTA_UserMsg( NevermoreRequiem ); // 82, 157 | HANDLE_DOTA_UserMsg( OverheadEvent ); // 83, 158 | HANDLE_DOTA_UserMsg( SetNextAutobuyItem ); // 84, 159 | HANDLE_DOTA_UserMsg( SharedCooldown ); // 85, 160 | HANDLE_DOTA_UserMsg( SpectatorPlayerClick ); // 86, 161 | HANDLE_DOTA_UserMsg( TutorialTipInfo ); // 87, 162 | HANDLE_DOTA_UserMsg( UnitEvent ); // 88, 163 | HANDLE_DOTA_UserMsg( ParticleManager ); // 89, 164 | HANDLE_DOTA_UserMsg( BotChat ); // 90, 165 | HANDLE_DOTA_UserMsg( HudError ); // 91, 166 | HANDLE_DOTA_UserMsg( ItemPurchased ); // 92, 167 | HANDLE_DOTA_UserMsg( Ping ); // 93 168 | 169 | #undef HANDLE_UserMsg 170 | #undef HANDLE_DOTA_UserMsg 171 | } 172 | } 173 | } 174 | 175 | template < class T, int msgType > 176 | void PrintNetMessage( CDemoFileDump& Demo, const void *parseBuffer, int BufferSize ) 177 | { 178 | T msg; 179 | 180 | if( msg.ParseFromArray( parseBuffer, BufferSize ) ) 181 | { 182 | if( msgType == svc_GameEventList ) 183 | { 184 | Demo.m_GameEventList.CopyFrom( msg ); 185 | } 186 | 187 | Demo.MsgPrintf( msg, BufferSize, "%s", msg.DebugString().c_str() ); 188 | } 189 | } 190 | 191 | template <> 192 | void PrintNetMessage< CSVCMsg_UserMessage, svc_UserMessage >( CDemoFileDump& Demo, const void *parseBuffer, int BufferSize ) 193 | { 194 | Demo.DumpUserMessage( parseBuffer, BufferSize ); 195 | } 196 | 197 | template <> 198 | void PrintNetMessage< CSVCMsg_GameEvent, svc_GameEvent >( CDemoFileDump& Demo, const void *parseBuffer, int BufferSize ) 199 | { 200 | CSVCMsg_GameEvent msg; 201 | 202 | if( msg.ParseFromArray( parseBuffer, BufferSize ) ) 203 | { 204 | int iDescriptor; 205 | 206 | for( iDescriptor = 0; iDescriptor < Demo.m_GameEventList.descriptors().size(); iDescriptor++ ) 207 | { 208 | const CSVCMsg_GameEventList::descriptor_t& Descriptor = Demo.m_GameEventList.descriptors( iDescriptor ); 209 | 210 | if( Descriptor.eventid() == msg.eventid() ) 211 | break; 212 | } 213 | 214 | if( iDescriptor == Demo.m_GameEventList.descriptors().size() ) 215 | { 216 | printf( "%s", msg.DebugString().c_str() ); 217 | } 218 | else 219 | { 220 | int numKeys = msg.keys().size(); 221 | const CSVCMsg_GameEventList::descriptor_t& Descriptor = Demo.m_GameEventList.descriptors( iDescriptor ); 222 | 223 | printf( "%s eventid:%d %s\n", Descriptor.name().c_str(), msg.eventid(), 224 | msg.has_event_name() ? msg.event_name().c_str() : "" ); 225 | 226 | for( int i = 0; i < numKeys; i++ ) 227 | { 228 | const CSVCMsg_GameEventList::key_t& Key = Descriptor.keys( i ); 229 | const CSVCMsg_GameEvent::key_t& KeyValue = msg.keys( i ); 230 | 231 | printf(" %s: ", Key.name().c_str() ); 232 | 233 | if( KeyValue.has_val_string() ) 234 | printf( "%s ", KeyValue.val_string().c_str() ); 235 | if( KeyValue.has_val_float() ) 236 | printf( "%f ", KeyValue.val_float() ); 237 | if( KeyValue.has_val_long() ) 238 | printf( "%d ", KeyValue.val_long() ); 239 | if( KeyValue.has_val_short() ) 240 | printf( "%d ", KeyValue.val_short() ); 241 | if( KeyValue.has_val_byte() ) 242 | printf( "%d ", KeyValue.val_byte() ); 243 | if( KeyValue.has_val_bool() ) 244 | printf( "%d ", KeyValue.val_bool() ); 245 | if( KeyValue.has_val_uint64() ) 246 | printf( "%lld ", KeyValue.val_uint64() ); 247 | 248 | printf( "\n" ); 249 | } 250 | } 251 | } 252 | } 253 | 254 | static std::string GetNetMsgName( int Cmd ) 255 | { 256 | if( NET_Messages_IsValid( Cmd ) ) 257 | { 258 | return NET_Messages_Name( ( NET_Messages )Cmd ); 259 | } 260 | else if( SVC_Messages_IsValid( Cmd ) ) 261 | { 262 | return SVC_Messages_Name( ( SVC_Messages )Cmd ); 263 | } 264 | 265 | assert( 0 ); 266 | return "NETMSG_???"; 267 | } 268 | 269 | void CDemoFileDump::DumpDemoPacket( const std::string& buf ) 270 | { 271 | size_t index = 0; 272 | 273 | while( index < buf.size() ) 274 | { 275 | int Cmd = ReadVarInt32( buf, index ); 276 | uint32 Size = ReadVarInt32( buf, index ); 277 | 278 | if( index + Size > buf.size() ) 279 | { 280 | const std::string& strName = GetNetMsgName( Cmd ); 281 | 282 | fatal_errorf( "buf.ReadBytes() failed. Cmd:%d '%s' \n", Cmd, strName.c_str() ); 283 | } 284 | 285 | switch( Cmd ) 286 | { 287 | #define HANDLE_NetMsg( _x ) case net_ ## _x: PrintNetMessage< CNETMsg_ ## _x, net_ ## _x >( *this, &buf[ index ], Size ); break 288 | #define HANDLE_SvcMsg( _x ) case svc_ ## _x: PrintNetMessage< CSVCMsg_ ## _x, svc_ ## _x >( *this, &buf[ index ], Size ); break 289 | 290 | default: 291 | printf( "WARNING. DumpUserMessage(): Unknown netmessage %d.\n", Cmd ); 292 | break; 293 | 294 | HANDLE_NetMsg( NOP ); // 0 295 | HANDLE_NetMsg( Disconnect ); // 1 296 | HANDLE_NetMsg( File ); // 2 297 | HANDLE_NetMsg( SplitScreenUser ); // 3 298 | HANDLE_NetMsg( Tick ); // 4 299 | HANDLE_NetMsg( StringCmd ); // 5 300 | HANDLE_NetMsg( SetConVar ); // 6 301 | HANDLE_NetMsg( SignonState ); // 7 302 | HANDLE_SvcMsg( ServerInfo ); // 8 303 | HANDLE_SvcMsg( SendTable ); // 9 304 | HANDLE_SvcMsg( ClassInfo ); // 10 305 | HANDLE_SvcMsg( SetPause ); // 11 306 | HANDLE_SvcMsg( CreateStringTable ); // 12 307 | HANDLE_SvcMsg( UpdateStringTable ); // 13 308 | HANDLE_SvcMsg( VoiceInit ); // 14 309 | HANDLE_SvcMsg( VoiceData ); // 15 310 | HANDLE_SvcMsg( Print ); // 16 311 | HANDLE_SvcMsg( Sounds ); // 17 312 | HANDLE_SvcMsg( SetView ); // 18 313 | HANDLE_SvcMsg( FixAngle ); // 19 314 | HANDLE_SvcMsg( CrosshairAngle ); // 20 315 | HANDLE_SvcMsg( BSPDecal ); // 21 316 | HANDLE_SvcMsg( SplitScreen ); // 22 317 | HANDLE_SvcMsg( UserMessage ); // 23 318 | //$ HANDLE_SvcMsg( EntityMessage ); // 24 319 | HANDLE_SvcMsg( GameEvent ); // 25 320 | HANDLE_SvcMsg( PacketEntities ); // 26 321 | HANDLE_SvcMsg( TempEntities ); // 27 322 | HANDLE_SvcMsg( Prefetch ); // 28 323 | HANDLE_SvcMsg( Menu ); // 29 324 | HANDLE_SvcMsg( GameEventList ); // 30 325 | HANDLE_SvcMsg( GetCvarValue ); // 31 326 | 327 | #undef HANDLE_SvcMsg 328 | #undef HANDLE_NetMsg 329 | } 330 | 331 | index += Size; 332 | } 333 | } 334 | 335 | static bool DumpDemoStringTable( CDemoFileDump& Demo, const CDemoStringTables& StringTables ) 336 | { 337 | for( int i = 0; i < StringTables.tables().size(); i++ ) 338 | { 339 | const CDemoStringTables::table_t& Table = StringTables.tables( i ); 340 | 341 | printf( "#%d %s flags:0x%x (%d Items) %d bytes\n", 342 | i, Table.table_name().c_str(), Table.table_flags(), 343 | Table.items().size() + Table.items_clientside().size(), Table.ByteSize() ); 344 | 345 | bool bIsActiveModifiersTable = !strcmp( Table.table_name().c_str(), "ActiveModifiers" ); 346 | bool bIsUserInfo = !strcmp( Table.table_name().c_str(), "userinfo" ); 347 | 348 | // Only spew out the stringtables (really big) if verbose is on. 349 | for( int itemid = 0; itemid < Table.items().size(); itemid++ ) 350 | { 351 | const CDemoStringTables::items_t& Item = Table.items( itemid ); 352 | 353 | if( bIsActiveModifiersTable ) 354 | { 355 | CDOTAModifierBuffTableEntry Entry; 356 | 357 | if( Entry.ParseFromString( Item.data() ) ) 358 | { 359 | std::string EntryStr = Entry.DebugString(); 360 | printf( " #%d %s", itemid, EntryStr.c_str() ); 361 | continue; 362 | } 363 | } 364 | else if( bIsUserInfo && Item.data().size() == sizeof( player_info_s ) ) 365 | { 366 | const player_info_s *pPlayerInfo = ( const player_info_s * )&Item.data()[ 0 ]; 367 | 368 | printf(" xuid:%lld name:%s userID:%d guid:%s friendsID:%d friendsName:%s fakeplayer:%d ishltv:%d filesDownloaded:%d\n", 369 | pPlayerInfo->xuid, pPlayerInfo->name, pPlayerInfo->userID, pPlayerInfo->guid, pPlayerInfo->friendsID, 370 | pPlayerInfo->friendsName, pPlayerInfo->fakeplayer, pPlayerInfo->ishltv, pPlayerInfo->filesDownloaded ); 371 | } 372 | 373 | printf( " #%d '%s' (%d bytes)\n", itemid, Item.str().c_str(), (int)Item.data().size() ); 374 | } 375 | 376 | for( int itemid = 0; itemid < Table.items_clientside().size(); itemid++ ) 377 | { 378 | const CDemoStringTables::items_t& Item = Table.items_clientside( itemid ); 379 | 380 | printf( " %d. '%s' (%d bytes)\n", itemid, Item.str().c_str(), (int)Item.data().size() ); 381 | } 382 | } 383 | 384 | return true; 385 | } 386 | 387 | void CDemoFileDump::PrintDemoHeader( EDemoCommands DemoCommand, int tick, int size, int uncompressed_size ) 388 | { 389 | const std::string& DemoCommandName = EDemoCommands_Name( DemoCommand ); 390 | 391 | printf( "==== #%d: Tick:%d '%s' Size:%d UncompressedSize:%d ====\n", 392 | m_nFrameNumber, tick, DemoCommandName.c_str(), size, uncompressed_size ); 393 | } 394 | 395 | template < class DEMCLASS > 396 | void PrintDemoMessage( CDemoFileDump& Demo, bool bCompressed, int tick, int& size, int& uncompressed_size ) 397 | { 398 | DEMCLASS Msg; 399 | 400 | if( Demo.m_demofile.ReadMessage( &Msg, bCompressed, &size, &uncompressed_size ) ) 401 | { 402 | Demo.PrintDemoHeader( Msg.GetType(), tick, size, uncompressed_size ); 403 | 404 | Demo.MsgPrintf( Msg, size, "%s", Msg.DebugString().c_str() ); 405 | } 406 | } 407 | 408 | template <> 409 | void PrintDemoMessage( CDemoFileDump& Demo, bool bCompressed, int tick, int& size, int& uncompressed_size ) 410 | { 411 | CDemoStringTables_t Msg; 412 | 413 | if( Demo.m_demofile.ReadMessage( &Msg, bCompressed, &size, &uncompressed_size ) ) 414 | { 415 | Demo.PrintDemoHeader( Msg.GetType(), tick, size, uncompressed_size ); 416 | 417 | DumpDemoStringTable( Demo, Msg ); 418 | } 419 | } 420 | 421 | void CDemoFileDump::DoDump() 422 | { 423 | bool bStopReading = false; 424 | 425 | for( m_nFrameNumber = 0; !bStopReading; m_nFrameNumber++ ) 426 | { 427 | int tick = 0; 428 | int size = 0; 429 | bool bCompressed; 430 | int uncompressed_size = 0; 431 | 432 | if( m_demofile.IsDone() ) 433 | break; 434 | 435 | EDemoCommands DemoCommand = m_demofile.ReadMessageType( &tick, &bCompressed ); 436 | 437 | switch( DemoCommand ) 438 | { 439 | #define HANDLE_DemoMsg( _x ) case DEM_ ## _x: PrintDemoMessage< CDemo ## _x ## _t >( *this, bCompressed, tick, size, uncompressed_size ); break 440 | 441 | HANDLE_DemoMsg( FileHeader ); 442 | HANDLE_DemoMsg( FileInfo ); 443 | HANDLE_DemoMsg( Stop ); 444 | HANDLE_DemoMsg( SyncTick ); 445 | HANDLE_DemoMsg( ConsoleCmd ); 446 | HANDLE_DemoMsg( SendTables ); 447 | HANDLE_DemoMsg( ClassInfo ); 448 | HANDLE_DemoMsg( StringTables ); 449 | HANDLE_DemoMsg( UserCmd ); 450 | HANDLE_DemoMsg( CustomDataCallbacks ); 451 | HANDLE_DemoMsg( CustomData ); 452 | 453 | #undef HANDLE_DemoMsg 454 | 455 | case DEM_FullPacket: 456 | { 457 | CDemoFullPacket_t FullPacket; 458 | 459 | if( m_demofile.ReadMessage( &FullPacket, bCompressed, &size, &uncompressed_size ) ) 460 | { 461 | PrintDemoHeader( DemoCommand, tick, size, uncompressed_size ); 462 | 463 | // Spew the stringtable 464 | DumpDemoStringTable( *this, FullPacket.string_table() ); 465 | 466 | // Ok, now the packet. 467 | DumpDemoPacket( FullPacket.packet().data() ); 468 | } 469 | } 470 | break; 471 | 472 | case DEM_Packet: 473 | case DEM_SignonPacket: 474 | { 475 | CDemoPacket_t Packet; 476 | 477 | if( m_demofile.ReadMessage( &Packet, bCompressed, &size, &uncompressed_size ) ) 478 | { 479 | PrintDemoHeader( DemoCommand, tick, size, uncompressed_size ); 480 | 481 | DumpDemoPacket( Packet.data() ); 482 | } 483 | } 484 | break; 485 | 486 | default: 487 | case DEM_Error: 488 | bStopReading = true; 489 | fatal_errorf( "Shouldn't ever get this demo command?!? %d\n", DemoCommand ); 490 | break; 491 | } 492 | } 493 | } 494 | 495 | -------------------------------------------------------------------------------- /ai_activity.proto: -------------------------------------------------------------------------------- 1 | //====== Copyright (c) 2012, Valve Corporation, All rights reserved. ========// 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // Redistributions of source code must retain the above copyright notice, this 7 | // list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, 9 | // this list of conditions and the following disclaimer in the documentation 10 | // and/or other materials provided with the distribution. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 16 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 | // THE POSSIBILITY OF SUCH DAMAGE. 23 | //===========================================================================// 24 | 25 | // We care more about speed than code size 26 | option optimize_for = SPEED; 27 | 28 | // We don't use the service generation functionality 29 | option cc_generic_services = false; 30 | 31 | enum Activity 32 | { 33 | ACT_INVALID = -1; // So we have something more succint to check for than '-1' 34 | ACT_RESET = 0; // Set m_Activity to this invalid value to force a reset to m_IdealActivity 35 | ACT_IDLE = 1; 36 | ACT_TRANSITION = 2; 37 | ACT_COVER = 3; // FIXME: obsolete? redundant with ACT_COVER_LOW? 38 | ACT_COVER_MED = 4; // FIXME: unsupported? 39 | ACT_COVER_LOW = 5; // FIXME: rename ACT_IDLE_CROUCH? 40 | ACT_WALK = 6; 41 | ACT_WALK_AIM = 7; 42 | ACT_WALK_CROUCH = 8; 43 | ACT_WALK_CROUCH_AIM = 9; 44 | ACT_RUN = 10; 45 | ACT_RUN_AIM = 11; 46 | ACT_RUN_CROUCH = 12; 47 | ACT_RUN_CROUCH_AIM = 13; 48 | ACT_RUN_PROTECTED = 14; 49 | ACT_SCRIPT_CUSTOM_MOVE = 15; 50 | ACT_RANGE_ATTACK1 = 16; 51 | ACT_RANGE_ATTACK2 = 17; 52 | ACT_RANGE_ATTACK1_LOW = 18; // FIXME: not used yet crouched versions of the range attack 53 | ACT_RANGE_ATTACK2_LOW = 19; // FIXME: not used yet crouched versions of the range attack 54 | ACT_DIESIMPLE = 20; 55 | ACT_DIEBACKWARD = 21; 56 | ACT_DIEFORWARD = 22; 57 | ACT_DIEVIOLENT = 23; 58 | ACT_DIERAGDOLL = 24; 59 | ACT_FLY = 25; // Fly (and flap if appropriate) 60 | ACT_HOVER = 26; 61 | ACT_GLIDE = 27; 62 | ACT_SWIM = 28; 63 | ACT_JUMP = 29; 64 | ACT_HOP = 30; // vertical jump 65 | ACT_LEAP = 31; // long forward jump 66 | ACT_LAND = 32; 67 | ACT_CLIMB_UP = 33; 68 | ACT_CLIMB_DOWN = 34; 69 | ACT_CLIMB_DISMOUNT = 35; 70 | ACT_SHIPLADDER_UP = 36; 71 | ACT_SHIPLADDER_DOWN = 37; 72 | ACT_STRAFE_LEFT = 38; 73 | ACT_STRAFE_RIGHT = 39; 74 | ACT_ROLL_LEFT = 40; // tuck and roll left 75 | ACT_ROLL_RIGHT = 41; // tuck and roll right 76 | ACT_TURN_LEFT = 42; // turn quickly left (stationary) 77 | ACT_TURN_RIGHT = 43; // turn quickly right (stationary) 78 | ACT_CROUCH = 44; // FIXME: obsolete? only used be soldier (the act of crouching down from a standing position) 79 | ACT_CROUCHIDLE = 45; // FIXME: obsolete? only used be soldier (holding body in crouched position (loops)) 80 | ACT_STAND = 46; // FIXME: obsolete? should be transition (the act of standing from a crouched position) 81 | ACT_USE = 47; 82 | ACT_ALIEN_BURROW_IDLE = 48; 83 | ACT_ALIEN_BURROW_OUT = 49; 84 | 85 | ACT_SIGNAL1 = 50; 86 | ACT_SIGNAL2 = 51; 87 | ACT_SIGNAL3 = 52; 88 | 89 | ACT_SIGNAL_ADVANCE = 53; // Squad handsignals specific. 90 | ACT_SIGNAL_FORWARD = 54; 91 | ACT_SIGNAL_GROUP = 55; 92 | ACT_SIGNAL_HALT = 56; 93 | ACT_SIGNAL_LEFT = 57; 94 | ACT_SIGNAL_RIGHT = 58; 95 | ACT_SIGNAL_TAKECOVER = 59; 96 | 97 | ACT_LOOKBACK_RIGHT = 60; // look back over shoulder without turning around. 98 | ACT_LOOKBACK_LEFT = 61; 99 | ACT_COWER = 62; // FIXME: unused should be more extreme version of crouching 100 | ACT_SMALL_FLINCH = 63; // FIXME: needed? shouldn't flinching be down with overlays? 101 | ACT_BIG_FLINCH = 64; 102 | ACT_MELEE_ATTACK1 = 65; 103 | ACT_MELEE_ATTACK2 = 66; 104 | ACT_RELOAD = 67; 105 | ACT_RELOAD_START = 68; 106 | ACT_RELOAD_FINISH = 69; 107 | ACT_RELOAD_LOW = 70; 108 | ACT_ARM = 71; // pull out gun for instance 109 | ACT_DISARM = 72; // reholster gun 110 | ACT_DROP_WEAPON = 73; 111 | ACT_DROP_WEAPON_SHOTGUN = 74; 112 | ACT_PICKUP_GROUND = 75; // pick up something in front of you on the ground 113 | ACT_PICKUP_RACK = 76; // pick up something from a rack or shelf in front of you. 114 | ACT_IDLE_ANGRY = 77; // FIXME: being used as an combat ready idle? alternate idle animation in which the monster is clearly agitated. (loop) 115 | 116 | ACT_IDLE_RELAXED = 78; 117 | ACT_IDLE_STIMULATED = 79; 118 | ACT_IDLE_AGITATED = 80; 119 | ACT_IDLE_STEALTH = 81; 120 | ACT_IDLE_HURT = 82; 121 | 122 | ACT_WALK_RELAXED = 83; 123 | ACT_WALK_STIMULATED = 84; 124 | ACT_WALK_AGITATED = 85; 125 | ACT_WALK_STEALTH = 86; 126 | 127 | ACT_RUN_RELAXED = 87; 128 | ACT_RUN_STIMULATED = 88; 129 | ACT_RUN_AGITATED = 89; 130 | ACT_RUN_STEALTH = 90; 131 | 132 | ACT_IDLE_AIM_RELAXED = 91; 133 | ACT_IDLE_AIM_STIMULATED = 92; 134 | ACT_IDLE_AIM_AGITATED = 93; 135 | ACT_IDLE_AIM_STEALTH = 94; 136 | 137 | ACT_WALK_AIM_RELAXED = 95; 138 | ACT_WALK_AIM_STIMULATED = 96; 139 | ACT_WALK_AIM_AGITATED = 97; 140 | ACT_WALK_AIM_STEALTH = 98; 141 | 142 | ACT_RUN_AIM_RELAXED = 99; 143 | ACT_RUN_AIM_STIMULATED = 100; 144 | ACT_RUN_AIM_AGITATED = 101; 145 | ACT_RUN_AIM_STEALTH = 102; 146 | 147 | ACT_CROUCHIDLE_STIMULATED = 103; 148 | ACT_CROUCHIDLE_AIM_STIMULATED = 104; 149 | ACT_CROUCHIDLE_AGITATED = 105; 150 | 151 | ACT_WALK_HURT = 106; // limp (loop) 152 | ACT_RUN_HURT = 107; // limp (loop) 153 | ACT_SPECIAL_ATTACK1 = 108; // very monster specific special attacks. 154 | ACT_SPECIAL_ATTACK2 = 109; 155 | ACT_COMBAT_IDLE = 110; // FIXME: unused? agitated idle. 156 | ACT_WALK_SCARED = 111; 157 | ACT_RUN_SCARED = 112; 158 | ACT_VICTORY_DANCE = 113; // killed a player do a victory dance. 159 | ACT_DIE_HEADSHOT = 114; // die hit in head. 160 | ACT_DIE_CHESTSHOT = 115; // die hit in chest 161 | ACT_DIE_GUTSHOT = 116; // die hit in gut 162 | ACT_DIE_BACKSHOT = 117; // die hit in back 163 | ACT_FLINCH_HEAD = 118; 164 | ACT_FLINCH_CHEST = 119; 165 | ACT_FLINCH_STOMACH = 120; 166 | ACT_FLINCH_LEFTARM = 121; 167 | ACT_FLINCH_RIGHTARM = 122; 168 | ACT_FLINCH_LEFTLEG = 123; 169 | ACT_FLINCH_RIGHTLEG = 124; 170 | ACT_FLINCH_PHYSICS = 125; 171 | ACT_FLINCH_HEAD_BACK = 126; 172 | ACT_FLINCH_CHEST_BACK = 127; 173 | ACT_FLINCH_STOMACH_BACK = 128; 174 | ACT_FLINCH_CROUCH_FRONT = 129; 175 | ACT_FLINCH_CROUCH_BACK = 130; 176 | ACT_FLINCH_CROUCH_LEFT = 131; 177 | ACT_FLINCH_CROUCH_RIGHT = 132; 178 | 179 | ACT_IDLE_ON_FIRE = 133; // ON FIRE animations 180 | ACT_WALK_ON_FIRE = 134; 181 | ACT_RUN_ON_FIRE = 135; 182 | 183 | ACT_RAPPEL_LOOP = 136; // Rappel down a rope! 184 | 185 | ACT_180_LEFT = 137; // 180 degree left turn 186 | ACT_180_RIGHT = 138; 187 | 188 | ACT_90_LEFT = 139; // 90 degree turns 189 | ACT_90_RIGHT = 140; 190 | 191 | ACT_STEP_LEFT = 141; // Single steps 192 | ACT_STEP_RIGHT = 142; 193 | ACT_STEP_BACK = 143; 194 | ACT_STEP_FORE = 144; 195 | 196 | ACT_GESTURE_RANGE_ATTACK1 = 145; 197 | ACT_GESTURE_RANGE_ATTACK2 = 146; 198 | ACT_GESTURE_MELEE_ATTACK1 = 147; 199 | ACT_GESTURE_MELEE_ATTACK2 = 148; 200 | ACT_GESTURE_RANGE_ATTACK1_LOW = 149; // FIXME: not used yet crouched versions of the range attack 201 | ACT_GESTURE_RANGE_ATTACK2_LOW = 150; // FIXME: not used yet crouched versions of the range attack 202 | 203 | ACT_MELEE_ATTACK_SWING_GESTURE = 151; 204 | 205 | ACT_GESTURE_SMALL_FLINCH = 152; 206 | ACT_GESTURE_BIG_FLINCH = 153; 207 | ACT_GESTURE_FLINCH_BLAST = 154; // Startled by an explosion 208 | ACT_GESTURE_FLINCH_BLAST_SHOTGUN = 155; 209 | ACT_GESTURE_FLINCH_BLAST_DAMAGED = 156; // Damaged by an explosion 210 | ACT_GESTURE_FLINCH_BLAST_DAMAGED_SHOTGUN = 157; 211 | ACT_GESTURE_FLINCH_HEAD = 158; 212 | ACT_GESTURE_FLINCH_CHEST = 159; 213 | ACT_GESTURE_FLINCH_STOMACH = 160; 214 | ACT_GESTURE_FLINCH_LEFTARM = 161; 215 | ACT_GESTURE_FLINCH_RIGHTARM = 162; 216 | ACT_GESTURE_FLINCH_LEFTLEG = 163; 217 | ACT_GESTURE_FLINCH_RIGHTLEG = 164; 218 | 219 | ACT_GESTURE_TURN_LEFT = 165; 220 | ACT_GESTURE_TURN_RIGHT = 166; 221 | ACT_GESTURE_TURN_LEFT45 = 167; 222 | ACT_GESTURE_TURN_RIGHT45 = 168; 223 | ACT_GESTURE_TURN_LEFT90 = 169; 224 | ACT_GESTURE_TURN_RIGHT90 = 170; 225 | ACT_GESTURE_TURN_LEFT45_FLAT = 171; 226 | ACT_GESTURE_TURN_RIGHT45_FLAT = 172; 227 | ACT_GESTURE_TURN_LEFT90_FLAT = 173; 228 | ACT_GESTURE_TURN_RIGHT90_FLAT = 174; 229 | 230 | // HALF-LIFE 1 compatability stuff goes here. Temporary! 231 | ACT_BARNACLE_HIT = 175; // barnacle tongue hits a monster 232 | ACT_BARNACLE_PULL = 176; // barnacle is lifting the monster ( loop ) 233 | ACT_BARNACLE_CHOMP = 177; // barnacle latches on to the monster 234 | ACT_BARNACLE_CHEW = 178; // barnacle is holding the monster in its mouth ( loop ) 235 | 236 | // Sometimes you just want to set an NPC's sequence to a sequence that doesn't actually 237 | // have an activity. The AI will reset the NPC's sequence to whatever its IDEAL activity 238 | // is though. So if you set ideal activity to DO_NOT_DISTURB the AI will not interfere 239 | // with the NPC's current sequence. (SJB) 240 | ACT_DO_NOT_DISTURB = 179; 241 | 242 | ACT_SPECIFIC_SEQUENCE = 180; 243 | 244 | // viewmodel (weapon) activities 245 | // FIXME: move these to the specific viewmodels no need to make global 246 | ACT_VM_DRAW = 181; 247 | ACT_VM_HOLSTER = 182; 248 | ACT_VM_IDLE = 183; 249 | ACT_VM_FIDGET = 184; 250 | ACT_VM_PULLBACK = 185; 251 | ACT_VM_PULLBACK_HIGH = 186; 252 | ACT_VM_PULLBACK_LOW = 187; 253 | ACT_VM_THROW = 188; 254 | ACT_VM_PULLPIN = 189; 255 | ACT_VM_PRIMARYATTACK = 190; // fire 256 | ACT_VM_SECONDARYATTACK = 191; // alt. fire 257 | ACT_VM_RELOAD = 192; 258 | ACT_VM_DRYFIRE = 193; // fire with no ammo loaded. 259 | ACT_VM_HITLEFT = 194; // bludgeon swing to left - hit (primary attk) 260 | ACT_VM_HITLEFT2 = 195; // bludgeon swing to left - hit (secondary attk) 261 | ACT_VM_HITRIGHT = 196; // bludgeon swing to right - hit (primary attk) 262 | ACT_VM_HITRIGHT2 = 197; // bludgeon swing to right - hit (secondary attk) 263 | ACT_VM_HITCENTER = 198; // bludgeon swing center - hit (primary attk) 264 | ACT_VM_HITCENTER2 = 199; // bludgeon swing center - hit (secondary attk) 265 | ACT_VM_MISSLEFT = 200; // bludgeon swing to left - miss (primary attk) 266 | ACT_VM_MISSLEFT2 = 201; // bludgeon swing to left - miss (secondary attk) 267 | ACT_VM_MISSRIGHT = 202; // bludgeon swing to right - miss (primary attk) 268 | ACT_VM_MISSRIGHT2 = 203; // bludgeon swing to right - miss (secondary attk) 269 | ACT_VM_MISSCENTER = 204; // bludgeon swing center - miss (primary attk) 270 | ACT_VM_MISSCENTER2 = 205; // bludgeon swing center - miss (secondary attk) 271 | ACT_VM_HAULBACK = 206; // bludgeon haul the weapon back for a hard strike (secondary attk) 272 | ACT_VM_SWINGHARD = 207; // bludgeon release the hard strike (secondary attk) 273 | ACT_VM_SWINGMISS = 208; 274 | ACT_VM_SWINGHIT = 209; 275 | ACT_VM_IDLE_TO_LOWERED = 210; 276 | ACT_VM_IDLE_LOWERED = 211; 277 | ACT_VM_LOWERED_TO_IDLE = 212; 278 | ACT_VM_RECOIL1 = 213; 279 | ACT_VM_RECOIL2 = 214; 280 | ACT_VM_RECOIL3 = 215; 281 | ACT_VM_PICKUP = 216; 282 | ACT_VM_RELEASE = 217; 283 | 284 | ACT_VM_ATTACH_SILENCER = 218; 285 | ACT_VM_DETACH_SILENCER = 219; 286 | 287 | //=========================== 288 | // HL2 Specific Activities 289 | //=========================== 290 | // SLAM Specialty Activities 291 | ACT_SLAM_STICKWALL_IDLE = 220; 292 | ACT_SLAM_STICKWALL_ND_IDLE = 221; 293 | ACT_SLAM_STICKWALL_ATTACH = 222; 294 | ACT_SLAM_STICKWALL_ATTACH2 = 223; 295 | ACT_SLAM_STICKWALL_ND_ATTACH = 224; 296 | ACT_SLAM_STICKWALL_ND_ATTACH2 = 225; 297 | ACT_SLAM_STICKWALL_DETONATE = 226; 298 | ACT_SLAM_STICKWALL_DETONATOR_HOLSTER = 227; 299 | ACT_SLAM_STICKWALL_DRAW = 228; 300 | ACT_SLAM_STICKWALL_ND_DRAW = 229; 301 | ACT_SLAM_STICKWALL_TO_THROW = 230; 302 | ACT_SLAM_STICKWALL_TO_THROW_ND = 231; 303 | ACT_SLAM_STICKWALL_TO_TRIPMINE_ND = 232; 304 | ACT_SLAM_THROW_IDLE = 233; 305 | ACT_SLAM_THROW_ND_IDLE = 234; 306 | ACT_SLAM_THROW_THROW = 235; 307 | ACT_SLAM_THROW_THROW2 = 236; 308 | ACT_SLAM_THROW_THROW_ND = 237; 309 | ACT_SLAM_THROW_THROW_ND2 = 238; 310 | ACT_SLAM_THROW_DRAW = 239; 311 | ACT_SLAM_THROW_ND_DRAW = 240; 312 | ACT_SLAM_THROW_TO_STICKWALL = 241; 313 | ACT_SLAM_THROW_TO_STICKWALL_ND = 242; 314 | ACT_SLAM_THROW_DETONATE = 243; 315 | ACT_SLAM_THROW_DETONATOR_HOLSTER = 244; 316 | ACT_SLAM_THROW_TO_TRIPMINE_ND = 245; 317 | ACT_SLAM_TRIPMINE_IDLE = 246; 318 | ACT_SLAM_TRIPMINE_DRAW = 247; 319 | ACT_SLAM_TRIPMINE_ATTACH = 248; 320 | ACT_SLAM_TRIPMINE_ATTACH2 = 249; 321 | ACT_SLAM_TRIPMINE_TO_STICKWALL_ND = 250; 322 | ACT_SLAM_TRIPMINE_TO_THROW_ND = 251; 323 | ACT_SLAM_DETONATOR_IDLE = 252; 324 | ACT_SLAM_DETONATOR_DRAW = 253; 325 | ACT_SLAM_DETONATOR_DETONATE = 254; 326 | ACT_SLAM_DETONATOR_HOLSTER = 255; 327 | ACT_SLAM_DETONATOR_STICKWALL_DRAW = 256; 328 | ACT_SLAM_DETONATOR_THROW_DRAW = 257; 329 | 330 | // Shotgun Specialty Activities 331 | ACT_SHOTGUN_RELOAD_START = 258; 332 | ACT_SHOTGUN_RELOAD_FINISH = 259; 333 | ACT_SHOTGUN_PUMP = 260; 334 | 335 | // SMG2 special activities 336 | ACT_SMG2_IDLE2 = 261; 337 | ACT_SMG2_FIRE2 = 262; 338 | ACT_SMG2_DRAW2 = 263; 339 | ACT_SMG2_RELOAD2 = 264; 340 | ACT_SMG2_DRYFIRE2 = 265; 341 | ACT_SMG2_TOAUTO = 266; 342 | ACT_SMG2_TOBURST = 267; 343 | 344 | // Physcannon special activities 345 | ACT_PHYSCANNON_UPGRADE = 268; 346 | 347 | // weapon override activities 348 | ACT_RANGE_ATTACK_AR1 = 269; 349 | ACT_RANGE_ATTACK_AR2 = 270; 350 | ACT_RANGE_ATTACK_AR2_LOW = 271; 351 | ACT_RANGE_ATTACK_AR2_GRENADE = 272; 352 | ACT_RANGE_ATTACK_HMG1 = 273; 353 | ACT_RANGE_ATTACK_ML = 274; 354 | ACT_RANGE_ATTACK_SMG1 = 275; 355 | ACT_RANGE_ATTACK_SMG1_LOW = 276; 356 | ACT_RANGE_ATTACK_SMG2 = 277; 357 | ACT_RANGE_ATTACK_SHOTGUN = 278; 358 | ACT_RANGE_ATTACK_SHOTGUN_LOW = 279; 359 | ACT_RANGE_ATTACK_PISTOL = 280; 360 | ACT_RANGE_ATTACK_PISTOL_LOW = 281; 361 | ACT_RANGE_ATTACK_SLAM = 282; 362 | ACT_RANGE_ATTACK_TRIPWIRE = 283; 363 | ACT_RANGE_ATTACK_THROW = 284; 364 | ACT_RANGE_ATTACK_SNIPER_RIFLE = 285; 365 | ACT_RANGE_ATTACK_RPG = 286; 366 | ACT_MELEE_ATTACK_SWING = 287; 367 | 368 | ACT_RANGE_AIM_LOW = 288; 369 | ACT_RANGE_AIM_SMG1_LOW = 289; 370 | ACT_RANGE_AIM_PISTOL_LOW = 290; 371 | ACT_RANGE_AIM_AR2_LOW = 291; 372 | 373 | ACT_COVER_PISTOL_LOW = 292; 374 | ACT_COVER_SMG1_LOW = 293; 375 | 376 | // weapon override activities 377 | ACT_GESTURE_RANGE_ATTACK_AR1 = 294; 378 | ACT_GESTURE_RANGE_ATTACK_AR2 = 295; 379 | ACT_GESTURE_RANGE_ATTACK_AR2_GRENADE = 296; 380 | ACT_GESTURE_RANGE_ATTACK_HMG1 = 297; 381 | ACT_GESTURE_RANGE_ATTACK_ML = 298; 382 | ACT_GESTURE_RANGE_ATTACK_SMG1 = 299; 383 | ACT_GESTURE_RANGE_ATTACK_SMG1_LOW = 300; 384 | ACT_GESTURE_RANGE_ATTACK_SMG2 = 301; 385 | ACT_GESTURE_RANGE_ATTACK_SHOTGUN = 302; 386 | ACT_GESTURE_RANGE_ATTACK_PISTOL = 303; 387 | ACT_GESTURE_RANGE_ATTACK_PISTOL_LOW = 304; 388 | ACT_GESTURE_RANGE_ATTACK_SLAM = 305; 389 | ACT_GESTURE_RANGE_ATTACK_TRIPWIRE = 306; 390 | ACT_GESTURE_RANGE_ATTACK_THROW = 307; 391 | ACT_GESTURE_RANGE_ATTACK_SNIPER_RIFLE = 308; 392 | ACT_GESTURE_MELEE_ATTACK_SWING = 309; 393 | 394 | ACT_IDLE_RIFLE = 310; 395 | ACT_IDLE_SMG1 = 311; 396 | ACT_IDLE_ANGRY_SMG1 = 312; 397 | ACT_IDLE_PISTOL = 313; 398 | ACT_IDLE_ANGRY_PISTOL = 314; 399 | ACT_IDLE_ANGRY_SHOTGUN = 315; 400 | ACT_IDLE_STEALTH_PISTOL = 316; 401 | 402 | ACT_IDLE_PACKAGE = 317; 403 | ACT_WALK_PACKAGE = 318; 404 | ACT_IDLE_SUITCASE = 319; 405 | ACT_WALK_SUITCASE = 320; 406 | 407 | ACT_IDLE_SMG1_RELAXED = 321; 408 | ACT_IDLE_SMG1_STIMULATED = 322; 409 | ACT_WALK_RIFLE_RELAXED = 323; 410 | ACT_RUN_RIFLE_RELAXED = 324; 411 | ACT_WALK_RIFLE_STIMULATED = 325; 412 | ACT_RUN_RIFLE_STIMULATED = 326; 413 | 414 | ACT_IDLE_AIM_RIFLE_STIMULATED = 327; 415 | ACT_WALK_AIM_RIFLE_STIMULATED = 328; 416 | ACT_RUN_AIM_RIFLE_STIMULATED = 329; 417 | 418 | ACT_IDLE_SHOTGUN_RELAXED = 330; 419 | ACT_IDLE_SHOTGUN_STIMULATED = 331; 420 | ACT_IDLE_SHOTGUN_AGITATED = 332; 421 | 422 | // Policing activities 423 | ACT_WALK_ANGRY = 333; 424 | ACT_POLICE_HARASS1 = 334; 425 | ACT_POLICE_HARASS2 = 335; 426 | 427 | // Manned guns 428 | ACT_IDLE_MANNEDGUN = 336; 429 | 430 | // Melee weapon 431 | ACT_IDLE_MELEE = 337; 432 | ACT_IDLE_ANGRY_MELEE = 338; 433 | 434 | // RPG activities 435 | ACT_IDLE_RPG_RELAXED = 339; 436 | ACT_IDLE_RPG = 340; 437 | ACT_IDLE_ANGRY_RPG = 341; 438 | ACT_COVER_LOW_RPG = 342; 439 | ACT_WALK_RPG = 343; 440 | ACT_RUN_RPG = 344; 441 | ACT_WALK_CROUCH_RPG = 345; 442 | ACT_RUN_CROUCH_RPG = 346; 443 | ACT_WALK_RPG_RELAXED = 347; 444 | ACT_RUN_RPG_RELAXED = 348; 445 | 446 | ACT_WALK_RIFLE = 349; 447 | ACT_WALK_AIM_RIFLE = 350; 448 | ACT_WALK_CROUCH_RIFLE = 351; 449 | ACT_WALK_CROUCH_AIM_RIFLE = 352; 450 | ACT_RUN_RIFLE = 353; 451 | ACT_RUN_AIM_RIFLE = 354; 452 | ACT_RUN_CROUCH_RIFLE = 355; 453 | ACT_RUN_CROUCH_AIM_RIFLE = 356; 454 | ACT_RUN_STEALTH_PISTOL = 357; 455 | 456 | ACT_WALK_AIM_SHOTGUN = 358; 457 | ACT_RUN_AIM_SHOTGUN = 359; 458 | 459 | ACT_WALK_PISTOL = 360; 460 | ACT_RUN_PISTOL = 361; 461 | ACT_WALK_AIM_PISTOL = 362; 462 | ACT_RUN_AIM_PISTOL = 363; 463 | ACT_WALK_STEALTH_PISTOL = 364; 464 | ACT_WALK_AIM_STEALTH_PISTOL = 365; 465 | ACT_RUN_AIM_STEALTH_PISTOL = 366; 466 | 467 | // Reloads 468 | ACT_RELOAD_PISTOL = 367; 469 | ACT_RELOAD_PISTOL_LOW = 368; 470 | ACT_RELOAD_SMG1 = 369; 471 | ACT_RELOAD_SMG1_LOW = 370; 472 | ACT_RELOAD_SHOTGUN = 371; 473 | ACT_RELOAD_SHOTGUN_LOW = 372; 474 | 475 | ACT_GESTURE_RELOAD = 373; 476 | ACT_GESTURE_RELOAD_PISTOL = 374; 477 | ACT_GESTURE_RELOAD_SMG1 = 375; 478 | ACT_GESTURE_RELOAD_SHOTGUN = 376; 479 | 480 | // Busy animations 481 | ACT_BUSY_LEAN_LEFT = 377; 482 | ACT_BUSY_LEAN_LEFT_ENTRY = 378; 483 | ACT_BUSY_LEAN_LEFT_EXIT = 379; 484 | ACT_BUSY_LEAN_BACK = 380; 485 | ACT_BUSY_LEAN_BACK_ENTRY = 381; 486 | ACT_BUSY_LEAN_BACK_EXIT = 382; 487 | ACT_BUSY_SIT_GROUND = 383; 488 | ACT_BUSY_SIT_GROUND_ENTRY = 384; 489 | ACT_BUSY_SIT_GROUND_EXIT = 385; 490 | ACT_BUSY_SIT_CHAIR = 386; 491 | ACT_BUSY_SIT_CHAIR_ENTRY = 387; 492 | ACT_BUSY_SIT_CHAIR_EXIT = 388; 493 | ACT_BUSY_STAND = 389; 494 | ACT_BUSY_QUEUE = 390; 495 | 496 | // Dodge animations 497 | ACT_DUCK_DODGE = 391; 498 | 499 | // For NPCs being lifted/eaten by barnacles: 500 | // being swallowed by a barnacle 501 | ACT_DIE_BARNACLE_SWALLOW = 392; 502 | // being lifted by a barnacle 503 | ACT_GESTURE_BARNACLE_STRANGLE = 393; 504 | 505 | ACT_PHYSCANNON_DETACH = 394; // An activity to be played if we're picking this up with the physcannon 506 | ACT_PHYSCANNON_ANIMATE = 395; // An activity to be played by an object being picked up with the physcannon but has different behavior to DETACH 507 | ACT_PHYSCANNON_ANIMATE_PRE = 396; // An activity to be played by an object being picked up with the physcannon before playing the ACT_PHYSCANNON_ANIMATE 508 | ACT_PHYSCANNON_ANIMATE_POST = 397; // An activity to be played by an object being picked up with the physcannon after playing the ACT_PHYSCANNON_ANIMATE 509 | 510 | ACT_DIE_FRONTSIDE = 398; 511 | ACT_DIE_RIGHTSIDE = 399; 512 | ACT_DIE_BACKSIDE = 400; 513 | ACT_DIE_LEFTSIDE = 401; 514 | 515 | ACT_OPEN_DOOR = 402; 516 | 517 | // Dynamic interactions 518 | ACT_DI_ALYX_ZOMBIE_MELEE = 403; 519 | ACT_DI_ALYX_ZOMBIE_TORSO_MELEE = 404; 520 | ACT_DI_ALYX_HEADCRAB_MELEE = 405; 521 | ACT_DI_ALYX_ANTLION = 406; 522 | 523 | ACT_DI_ALYX_ZOMBIE_SHOTGUN64 = 407; 524 | ACT_DI_ALYX_ZOMBIE_SHOTGUN26 = 408; 525 | 526 | ACT_READINESS_RELAXED_TO_STIMULATED = 409; 527 | ACT_READINESS_RELAXED_TO_STIMULATED_WALK = 410; 528 | ACT_READINESS_AGITATED_TO_STIMULATED = 411; 529 | ACT_READINESS_STIMULATED_TO_RELAXED = 412; 530 | 531 | ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED = 413; 532 | ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED_WALK = 414; 533 | ACT_READINESS_PISTOL_AGITATED_TO_STIMULATED = 415; 534 | ACT_READINESS_PISTOL_STIMULATED_TO_RELAXED = 416; 535 | 536 | ACT_IDLE_CARRY = 417; 537 | ACT_WALK_CARRY = 418; 538 | 539 | ///****************** 540 | ///DOTA ANIMATIONS 541 | ///****************** 542 | 543 | ACT_DOTA_IDLE = 419; 544 | //REMOVED ACT_DOTA_IDLE_ALT = 420; 545 | ACT_DOTA_IDLE_RARE = 421; 546 | ACT_DOTA_RUN = 422; 547 | //REMOVED ACT_DOTA_RUN_ALT = 423; 548 | ACT_DOTA_ATTACK = 424; 549 | ACT_DOTA_ATTACK2 = 425; 550 | ACT_DOTA_ATTACK_EVENT = 426; 551 | ACT_DOTA_DIE = 427; 552 | ACT_DOTA_FLINCH = 428; 553 | ACT_DOTA_FLAIL = 429; 554 | ACT_DOTA_DISABLED = 430; 555 | ACT_DOTA_CAST_ABILITY_1 = 431; 556 | ACT_DOTA_CAST_ABILITY_2 = 432; 557 | ACT_DOTA_CAST_ABILITY_3 = 433; 558 | ACT_DOTA_CAST_ABILITY_4 = 434; 559 | ACT_DOTA_CAST_ABILITY_5 = 435; 560 | ACT_DOTA_CAST_ABILITY_6 = 436; 561 | ACT_DOTA_OVERRIDE_ABILITY_1 = 437; 562 | ACT_DOTA_OVERRIDE_ABILITY_2 = 438; 563 | ACT_DOTA_OVERRIDE_ABILITY_3 = 439; 564 | ACT_DOTA_OVERRIDE_ABILITY_4 = 440; 565 | ACT_DOTA_CHANNEL_ABILITY_1 = 441; 566 | ACT_DOTA_CHANNEL_ABILITY_2 = 442; 567 | ACT_DOTA_CHANNEL_ABILITY_3 = 443; 568 | ACT_DOTA_CHANNEL_ABILITY_4 = 444; 569 | ACT_DOTA_CHANNEL_ABILITY_5 = 445; 570 | ACT_DOTA_CHANNEL_ABILITY_6 = 446; 571 | ACT_DOTA_CHANNEL_END_ABILITY_1 = 447; 572 | ACT_DOTA_CHANNEL_END_ABILITY_2 = 448; 573 | ACT_DOTA_CHANNEL_END_ABILITY_3 = 449; 574 | ACT_DOTA_CHANNEL_END_ABILITY_4 = 450; 575 | ACT_DOTA_CHANNEL_END_ABILITY_5 = 451; 576 | ACT_DOTA_CHANNEL_END_ABILITY_6 = 452; 577 | ACT_DOTA_CONSTANT_LAYER = 453; 578 | ACT_DOTA_CAPTURE = 454; 579 | ACT_DOTA_SPAWN = 455; 580 | ACT_DOTA_KILLTAUNT = 456; 581 | ACT_DOTA_TAUNT = 457; 582 | 583 | //Hero specific (I hate my life) 584 | ACT_DOTA_THIRST = 458; 585 | ACT_DOTA_CAST_DRAGONBREATH = 459; 586 | ACT_DOTA_ECHO_SLAM = 460; 587 | ACT_DOTA_CAST_ABILITY_1_END = 461; 588 | ACT_DOTA_CAST_ABILITY_2_END = 462; 589 | ACT_DOTA_CAST_ABILITY_3_END = 463; 590 | ACT_DOTA_CAST_ABILITY_4_END = 464; 591 | ACT_MIRANA_LEAP_END = 465; 592 | ACT_WAVEFORM_START = 466; 593 | ACT_WAVEFORM_END = 467; 594 | ACT_DOTA_CAST_ABILITY_ROT = 468; 595 | ACT_DOTA_DIE_SPECIAL = 469; 596 | ACT_DOTA_RATTLETRAP_BATTERYASSAULT = 470; 597 | ACT_DOTA_RATTLETRAP_POWERCOGS = 471; 598 | ACT_DOTA_RATTLETRAP_HOOKSHOT_START = 472; 599 | ACT_DOTA_RATTLETRAP_HOOKSHOT_LOOP = 473; 600 | ACT_DOTA_RATTLETRAP_HOOKSHOT_END = 474; 601 | ACT_STORM_SPIRIT_OVERLOAD_RUN_OVERRIDE = 475; 602 | ACT_DOTA_TINKER_REARM1 = 476; 603 | ACT_DOTA_TINKER_REARM2 = 477; 604 | ACT_DOTA_TINKER_REARM3 = 478; 605 | ACT_TINY_AVALANCHE = 479; 606 | ACT_TINY_TOSS = 480; 607 | ACT_TINY_GROWL = 481; 608 | ACT_DOTA_WEAVERBUG_ATTACH = 482; 609 | ACT_DOTA_CAST_WILD_AXES_END = 483; 610 | ACT_DOTA_CAST_LIFE_BREAK_START = 484; 611 | ACT_DOTA_CAST_LIFE_BREAK_END = 485; 612 | ACT_DOTA_NIGHTSTALKER_TRANSITION = 486; 613 | ACT_DOTA_LIFESTEALER_RAGE = 487; 614 | ACT_DOTA_LIFESTEALER_OPEN_WOUNDS = 488; 615 | ACT_DOTA_SAND_KING_BURROW_IN = 489; 616 | ACT_DOTA_SAND_KING_BURROW_OUT = 490; 617 | ACT_DOTA_EARTHSHAKER_TOTEM_ATTACK = 491; 618 | ACT_DOTA_WHEEL_LAYER = 492; 619 | ACT_DOTA_ALCHEMIST_CHEMICAL_RAGE_START = 493; 620 | ACT_DOTA_ALCHEMIST_CONCOCTION = 494; 621 | ACT_DOTA_JAKIRO_LIQUIDFIRE_START = 495; 622 | ACT_DOTA_JAKIRO_LIQUIDFIRE_LOOP = 496; 623 | ACT_DOTA_LIFESTEALER_INFEST = 497; 624 | ACT_DOTA_LIFESTEALER_INFEST_END = 498; 625 | ACT_DOTA_LASSO_LOOP = 499; 626 | ACT_DOTA_ALCHEMIST_CONCOCTION_THROW = 500; 627 | ACT_DOTA_ALCHEMIST_CHEMICAL_RAGE_END = 501; 628 | ACT_DOTA_CAST_COLD_SNAP = 502; 629 | ACT_DOTA_CAST_GHOST_WALK = 503; 630 | ACT_DOTA_CAST_TORNADO = 504; 631 | ACT_DOTA_CAST_EMP = 505; 632 | ACT_DOTA_CAST_ALACRITY = 506; 633 | ACT_DOTA_CAST_CHAOS_METEOR = 507; 634 | ACT_DOTA_CAST_SUN_STRIKE = 508; 635 | ACT_DOTA_CAST_FORGE_SPIRIT = 509; 636 | ACT_DOTA_CAST_ICE_WALL = 510; 637 | ACT_DOTA_CAST_DEAFENING_BLAST = 511; 638 | ACT_DOTA_VICTORY = 512; 639 | ACT_DOTA_DEFEAT = 513; 640 | ACT_DOTA_SPIRIT_BREAKER_CHARGE_POSE = 514; 641 | ACT_DOTA_SPIRIT_BREAKER_CHARGE_END = 515; 642 | ACT_DOTA_TELEPORT = 516; 643 | ACT_DOTA_TELEPORT_END = 517; 644 | }; 645 | 646 | 647 | --------------------------------------------------------------------------------