first of all, VERY new to programming. im trying to decompile a.vpd file to a .json file and found a .js that does that but it gives me this error: (note the example for the code typing is "node parser.js proto_defs.vpd proto_defs.json path/to/tf_proto_def_messages.proto")
C:\vg\vcpkg>node parser.js proto_defs.vpd proto_defs.json D:\SteamLibrary\steamapps\common\Team Fortress 2\tf\scripts\protodefs\tf_proto_def_messages.proto
node:internal/modules/cjs/loader:1080
throw err;
^
Error: Cannot find module './selectors/root'
Require stack:
- C:\vg\vcpkg\parser.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
at Module._load (node:internal/modules/cjs/loader:922:27)
at Module.require (node:internal/modules/cjs/loader:1143:19)
at require (node:internal/modules/cjs/helpers:121:18)
at Object.<anonymous> (C:\vg\vcpkg\parser.js:5:36)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [ 'C:\\vg\\vcpkg\\parser.js' ]
}
Node.js v18.17.1
the code of the .js file is
'use strict';
if (process.argv.length < 4) {
console.log('Usage: node parser.js <input> <output> [proto]');
console.log('Example: node parser.js proto_defs.vpd proto_defs.json path/to/tf_proto_def_messages.proto');
return;
}
const FS = require('fs');
const Protobuf = require('protobufjs'); // v6.8.3
const INPUT_FILE = process.argv[2]; // 'proto_defs.vpd'
const OUTPUT_FILE = process.argv[3]; // 'proto_defs.json'
const PROTO_FILE = process.argv[4] || 'tf_proto_def_messages.proto';
const TF2Schema = new Protobuf.Root().loadSync(PROTO_FILE, { keepCase: true });
/*
function deleteNulls(proto) {
Object.keys(proto).forEach(field => {
if (proto[field] === null)
delete proto[field];
else if (Array.isArray(proto[field]) && proto[field].length == 0)
delete proto[field];
else if (typeof proto[field] == 'object')
deleteNulls(proto[field]);
});
return proto;
}
*/
const TypeMap = new Map([
// Types, services and enums must start with an uppercase letter to become available as properties of the
// reflected types as well (i.e. to be able to use MyMessage.MyEnum instead of root.lookup("MyMessage.MyEnum")).
// (c) Docs
[TF2Schema.ProtoDefTypes.DEF_TYPE_QUEST_MAP_NODE, TF2Schema.CMsgQuestMapNodeDef],
[TF2Schema.ProtoDefTypes.DEF_TYPE_QUEST_THEME, TF2Schema.CMsgQuestTheme],
[TF2Schema.ProtoDefTypes.DEF_TYPE_QUEST_MAP_REGION, TF2Schema.CMsgQuestMapRegionDef],
[TF2Schema.ProtoDefTypes.DEF_TYPE_QUEST, TF2Schema.CMsgQuestDef],
[TF2Schema.ProtoDefTypes.DEF_TYPE_QUEST_OBJECTIVE, TF2Schema.CMsgQuestObjectiveDef],
[TF2Schema.ProtoDefTypes.DEF_TYPE_PAINTKIT_VARIABLES, TF2Schema.CMsgPaintKit_Variables],
[TF2Schema.ProtoDefTypes.DEF_TYPE_PAINTKIT_OPERATION, TF2Schema.CMsgPaintKit_Operation],
[TF2Schema.ProtoDefTypes.DEF_TYPE_PAINTKIT_ITEM_DEFINITION, TF2Schema.CMsgPaintKit_ItemDefinition],
[TF2Schema.ProtoDefTypes.DEF_TYPE_PAINTKIT_DEFINITION, TF2Schema.CMsgPaintKit_Definition],
[TF2Schema.ProtoDefTypes.DEF_TYPE_HEADER_ONLY, TF2Schema.CMsgHeaderOnly],
[TF2Schema.ProtoDefTypes.DEF_TYPE_QUEST_MAP_STORE_ITEM, TF2Schema.CMsgQuestMapStoreItem],
[TF2Schema.ProtoDefTypes.DEF_TYPE_QUEST_MAP_STAR_TYPE, TF2Schema.CMsgQuestMapStarType]
]);
let proto_defs_file = FS.readFileSync(INPUT_FILE);
let Definitions = Object.create(null), file_position = 0, def_type, num_records, msg_length, proto_msg;
/*
ProtoRecord {
MsgLength: Uint;
ProtoMsg: Byte[MsgLength];
}
ProtoDef {
DefType: Uint;
NumRecords: Uint;
Record: ProtoRecord[NumRecords]
}
FileStruct {
Definitions: ProtoDef[ProtoDefTypes];
}
*/
while (file_position < proto_defs_file.length) {
def_type = proto_defs_file.readUInt32LE(file_position);
Definitions[def_type] = [];
file_position += 4;
num_records = proto_defs_file.readUInt32LE(file_position);
file_position += 4;
let decoder = TypeMap.get(def_type);
while (num_records--) {
msg_length = proto_defs_file.readUInt32LE(file_position);
file_position += 4;
proto_msg = proto_defs_file.slice(file_position, file_position + msg_length);
if (decoder) {
proto_msg = decoder.decode(proto_msg); // enums as strings
//proto_msg = decoder.toObject(proto_msg, { enums: Number }); // enums as numbers
Definitions[def_type].push(proto_msg); // deleteNulls(proto_msg)
} else {
console.error(`Unknown DefType ${def_type}. Decoder not found!`);
Definitions[def_type].push(proto_msg.toString('hex'));
}
file_position += msg_length;
}
}
FS.writeFileSync(OUTPUT_FILE, JSON.stringify(Definitions, null, '\t'), 'utf8');
i have protobuf,fs installed and parser.js in the right directory. have a good day!
i have installed (to my knowledge) all the necessary tools (protobufjs,fs,tf_proto_def_messages.proto,vcpkg and git) checked multiple times that the directories are right and contacted multiple people who have already decompiled older version of the proto_defs.vpd file. im sure the problem is a rookie mistake and hope to fix this.