Skip to content

Commit

Permalink
move some files, common dp command, some pool to dump, localize/luafi…
Browse files Browse the repository at this point in the history
…le dump mwiii
  • Loading branch information
ate47 committed Aug 2, 2024
1 parent 21d6c4e commit 7bded68
Show file tree
Hide file tree
Showing 23 changed files with 1,677 additions and 1,174 deletions.
89 changes: 58 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,22 @@

My set of tools. The code is more important than the features, so feel free to reuse it. 🙂

**Supported games**
**Table of contents**

- [Atian Tools](#atian-tools)
- [GSC Compiler/Decompiler](#gsc-compilerdecompiler)
- [Dumper](#dumper)
- [ACTS Lib](#acts-lib)
- [Dependencies](#dependencies)
- [Downloads](#downloads)
- [Related repositories](#related-repositories)
- [Lookup](#lookup)
- [Credits](#credits)


## GSC Compiler/Decompiler

**Supported features**

| Name | Revision | Decompiler | Compiler | PS4 support |
| ------------------------ | -------- | ---------- | -------- | ----------- |
Expand All @@ -16,10 +31,49 @@ My set of tools. The code is more important than the features, so feel free to r
| Modern Warfare III (JUP) | 8A | EXT | EXT ||
| Modern Warfare III (JUP) | 8B | DEC & EXT | EXT ||


- **DEC**: with pre-decode
- **DEC**: With pre-decode
- **EXT**: With extensions, ***The extensions aren't provided publicly, at least not by me.***

**Commands**
```pwsh
# Compile gsc file
acts gscc <input.gsc> -g <game>
# Example
acts gscc my_script.gsc -g cw # Compile my_script.gsc into a cold war script
```

```
# Decompile gsc file
acts gscd file.gscc -g
# Example
acts gscd compiled.gscc -g # Decompile the script compiled.gscc
```

## Dumper

**Supported pools**

- Black Ops 3: `scriptbundle`, `stringtable`, `structuredtable`, `rawfile`, `scriptparsetree`.
- Black Ops 4: `weapon`, `customizationtable`, `rawfile`, `stringtable`, `structuredtable`, `ddl`, `scriptparsetree`, `scriptparsetreeforced`, `scriptbundle`, `scriptbundlelist`, `ttf`, `bgcache`, `maptable`, `maptablelist`, `maptableloadingimages`, `maptablepreviewimages`, `playerrolecategory`, `playerrolecategorytable`, `gametypetable`, `unlockableitem`, `unlockableitemtable`, `playlists`, `hierarchicaltasknetwork`, `storagefile`, `storagefilelist`, `storeproduct`, `storecategory`, `storecategorylist`, `rank`, `ranktable`, `prestige`, `prestigetable`, `labelstore`, `labelstorelist`, `rawstring`.
- Black Ops Cold War (Dec): `rawfile`, `rawfilepreproc`, `rawtextfile`, `stringtable`, `scriptparsetree`, `scriptbundle`.
- Modern Warfare III (COR): `gscobj`, `scriptbundle`, `stringtable`, `localize`, `luafile`.

- **DEC**: Requires pre-decode
- **COR**: Using [Cordycep](https://github.com/Scobalula/Cordycep).

**Commands**
```pwsh
# Command
acts dp <pool>
# Example
acts dp stringtable
```

## ACTS Lib

Prototype libary for random stuff, probably not linked to Call of Duty.
Expand Down Expand Up @@ -53,36 +107,9 @@ You can download the latest release here:
- [ate47/bo3-source](https://github.com/ate47/bo3-source) : Black Ops 3 Dump
- [ate47/bo4-source](https://github.com/ate47/bo4-source) : Black Ops 4 Dump
- [ate47/bocw-source](https://github.com/ate47/bocw-source) : Black Ops Cold War Dump
- [ate47/mwiii-source](https://github.com/ate47/mwiii-source) : Modern Warfare III Dump
- [ate47/BOHashTool](https://github.com/ate47/BOHashTool) : Tool to test hashes with error (en/de)coder for Black Ops games

## Tools

### Mods

Mods implemented in my tool, run `acts mod` for the list.

- `acts mod t8cee` - enable EEs in Custom mutations, offline or casual (Black Ops 4).
- `acts mod t9cee` - enable EEs in offline (Black Ops Cold War).

### Decompiler/Disassembler

Tools to decompile or disassemble the GSC scripts, a bo4 script decompilation is available in the [bo4-source](https://github.com/ate47/bo4-source) and [bocw-source](https://github.com/ate47/bocw-source) repositories.

- gsc disassembler, made in 3 days with a lot of alcohol so don't use it. `acts gscinfo -a -o "output" [input=scriptparsetree]`
- gsc decompiler, same as the disassembler, but 10 days after, not any better. `acts gscinfo -g -o "output" [input=scriptparsetree]`

### Compiler

GSC compiler, not for all the games, the scripts can be compiled using the command `acts gscc -g [game] [directory]`.

### GSC Development (Black Ops 4)

Tools to help with the GSC development.

- gsc vm debugger, dump the function stack when the vm has a crash, `acts dbg`
- can dump the var stack `-s` local var `-v`
- can look inside structures with the depth for array `-A [depth]` and structs `-S [depth]` (need the game started)

## Lookup

To have a lookup over the extracted hashes, you can use a file named `strings.txt` when using the process, it will be loaded automatically, one string per line.
Expand Down
53 changes: 53 additions & 0 deletions src/acts/compatibility/scobalula_csi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <includes.hpp>
#include "scobalula_csi.hpp"

namespace compatibility::scobalula::csi {

const char* CordycepGameName(CordycepGame game) {
switch (game) {
case CG_GHOSTS: return "Ghosts";
case CG_AW: return "Advanced Warfare";
case CG_IW: return "Infinite Warfare";
case CG_MWR: return "Modern Warfare Remastered";
case CG_MW2R: return "Modern Warfare 2 Remastered";
case CG_MW4: return "Modern Warfare 2019";
case CG_MW5: return "Modern Warfare II";
case CG_MW6: return "Modern Warfare III";
case CG_VANGUARD: return "Vanguard";
default: return "<unknown>";
}
}

bool CordycepProc::ReadCsi(const std::filesystem::path& path) {
std::string dbBuff{};

if (!utils::ReadFile(path, dbBuff)) {
LOG_ERROR("Can't read Cordycep database: {}", path.string());
return false;
}

LOG_DEBUG("Loading Cordycep CSI...");
CordycepCsiHeader* header{ (CordycepCsiHeader*)dbBuff.data() };

const char* buffer{ dbBuff.data() };
size_t idx{ offsetof(CordycepCsiHeader, gameDir) };

gameDir.resize(header->stringSize);
memcpy(gameDir.data(), buffer + idx, header->stringSize);
idx += header->stringSize;


LOG_DEBUG("Game Id .. {} (0x{:x})", CordycepGameName(header->gameId), (uint64_t)header->gameId);
LOG_DEBUG("Pools .... 0x{:x}", header->poolsAddress);
LOG_DEBUG("Strings .. 0x{:x}", header->stringsAddress);
LOG_DEBUG("Game dir . '{}'", gameDir);

gameId = header->gameId;
poolsAddress = header->poolsAddress;
stringsAddress = header->stringsAddress;

return true;
}


}
35 changes: 35 additions & 0 deletions src/acts/compatibility/scobalula_csi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

namespace compatibility::scobalula::csi {
enum CordycepGame : uint64_t {
CG_GHOSTS = 0xA0A5354534F4847,
CG_AW = 0x5241574E41564441,
CG_IW = 0x4652415749464E49,
CG_MWR = 0x30305453414D4552,
CG_MW2R = 0x32305453414D4552,
CG_MW4 = 0x3931524157444F4D,
CG_MW5 = 0x3232524157444F4D,
CG_MW6 = 0x4B4F4D41594D4159,
CG_VANGUARD = 0x44524155474E4156,
};

const char* CordycepGameName(CordycepGame game);

struct CordycepProc {
CordycepGame gameId;
uintptr_t poolsAddress;
uintptr_t stringsAddress;
std::string gameDir;

bool ReadCsi(const std::filesystem::path& path);
};

struct CordycepCsiHeader {
CordycepGame gameId;
uintptr_t poolsAddress;
uintptr_t stringsAddress;
uint32_t stringSize;
byte gameDir[4];
};

}
2 changes: 0 additions & 2 deletions src/acts/compatibility/scobalula_wni.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#pragma once

#include <includes_shared.hpp>

namespace compatibility::scobalula::wni {
constexpr const char* packageIndexDir = "package_index";
constexpr uint32_t WNI_MAGIC = 0x20494E57;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include <includes.hpp>
#include "tools/gsc_opcodes.hpp"
#include "compatibility/serious.hpp"
#include "compatibility/serious_db2.hpp"


using namespace tool::gsc::opcode;
using namespace compatibility::serious;
using namespace compatibility::serious::db2;

namespace {

Expand Down Expand Up @@ -191,7 +191,7 @@ namespace {
}
}

namespace compatibility::serious {
namespace compatibility::serious::db2 {
OPCode ConvertFrom(SeriousId id) {
return Maps().ConvertFrom(id);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#pragma once

#include <includes_shared.hpp>
#include "tools/gsc_opcodes.hpp"

namespace compatibility::serious {
namespace compatibility::serious::db2 {
constexpr auto VM_CODES_DB = "vm_codes.db2";

enum SeriousId : byte {
Expand Down
4 changes: 3 additions & 1 deletion src/acts/hashutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ int hashutils::LoadMap(const char* file, bool ignoreCol, bool iw) {
AddPrecomputed(Hash64("uint"), "uint");
AddPrecomputed(Hash64("long"), "long");
AddPrecomputed(Hash64("ulong"), "ulong");
AddPrecomputed(Hash64("$$padding"), "$$padding");
AddPrecomputed(Hash64("$$padding"), "$$padding");
// Dump CF
AddPrecomputed(Hash64("localize.json"), "localize.json");

std::ifstream s(file);

Expand Down
11 changes: 6 additions & 5 deletions src/acts/tools/bo3/dumpt7.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ namespace {
return false;
}
auto flagName = args[++i];

if (!_strcmpi("allraw", flagName)) {
flags |= PDOF_DUMP_ALL_RAW;
}
Expand Down Expand Up @@ -360,7 +360,7 @@ namespace {
ScriptBundleKVP& kvp{ kvps[i] };

utils::Padding(out, depth) << "\"" << GetMTString(proc, kvp.key) << "\"" << ": ";

switch (kvp.type) {
case KVP_INT:
case KVP_VEHICLE:
Expand Down Expand Up @@ -397,7 +397,8 @@ namespace {
return true;
}

int t7dp(Process& proc, int argc, const char* argv[]) {
}
int bo3::pool::t7dp(Process& proc, int argc, const char* argv[]) {
PoolOption opt;

if (!opt.Compute(argv, 2, argc) || opt.m_help) {
Expand Down Expand Up @@ -860,7 +861,7 @@ namespace {
return tool::OK;
}


namespace {
int t7poolscripts(Process& proc, int argc, const char* argv[]) {
std::filesystem::path outDir;
if (argc == 2) {
Expand Down Expand Up @@ -997,6 +998,6 @@ namespace {



ADD_TOOL("dpt7", "bo3", " [pool]", "dump pool (bo3)", L"BlackOps3.exe", t7dp);
ADD_TOOL("dpt7", "bo3", " [pool]", "Black Ops 3 dump pool", L"BlackOps3.exe", t7dp);
ADD_TOOL("wpst7", "bo3", " [output=scriptparsetree_t7]", "dump pooled scripts (bo3)", L"BlackOps3.exe", t7poolscripts);
}
2 changes: 1 addition & 1 deletion src/acts/tools/bo3/pools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,5 @@ namespace bo3::pool {
T7_TYPE_THREAD_LIST = 28,
T7_TYPE_ENT_LIST = 29,
};

int t7dp(Process& proc, int argc, const char* argv[]);
}
51 changes: 51 additions & 0 deletions src/acts/tools/common.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <includes.hpp>

namespace {
int commonpooltool(Process& _, int argc, const char* argv[]) {
const char* tools[]{
"dpbo4",
"dpcw",
"dpt7",
"dpcord",
};

for (const char* name : tools) {
const tool::toolfunctiondata& tool = tool::findtool(name);

if (!tool || !tool.m_game) {
LOG_WARNING("Invalid tool config: {}", name);
continue;
}

Process proc{ tool.m_game };

if (!proc) continue;

LOG_INFO("Find process {} {}", utils::WStrToStr(tool.m_game), proc);

if (!proc.Open()) {
LOG_ERROR("Can't open game process: 0x{:x}", GetLastError());
return -1;
}

return tool.m_func(proc, argc, argv);
}

LOG_ERROR("Can't find any supported game");
LOG_ERROR("Available games:");
for (const char* name : tools) {
const tool::toolfunctiondata& tool = tool::findtool(name);

if (!tool || !tool.m_game) {
continue;
}
LOG_ERROR("- {} : {} ({})", utils::WStrToStr(tool.m_game), tool.m_description, tool.m_category);
}

return tool::BASIC_ERROR;
}

}


ADD_TOOL("dp", "common", " [pool]+", "dump pool", nullptr, commonpooltool);
Loading

0 comments on commit 7bded68

Please sign in to comment.