forked from ReScrap/ScrapHacks
8.4 KiB
8.4 KiB
Infos
- Engine: ScrapEngine
- Ingame Scripting Language: Python 1.5.2
- Interesting memory locations and functions are noted in
config.yml
Launch options:
-console
: open external console window on start-wideWindow
: start game in widescreen mode
Functions identified:
Ingame-Console (Ctrl+^ or right click on titlebar and select "switch console") (Handler@0x402190
):
<Command>
: Try to evaluate Command as Python expression:<Var>
: Get Game Engine Global Variable:<Var> <Val>
: Set Game Engine Global Variable?
: Show all Global Variable?<String>
: Show all Global Variable matching<String>
/<command>
: Run Command defined inQuickConsole.py
:import quickconsole;quickconsole.%s()
/<command> <arg>,<arg>
: Run function inQuickConsole.py
with argument(s)import quickconsole;quickconsole.%s(%s)
External Console (Scenegraph Debugging?) (Handler @ 0x5f9520
):
listar luces
listar
arbol
(Patch Scrap.exe@offset 0x314bc9 replace 0x20 with 0x00 (or just typearbol
with a space at the end))mem
ver uniones
- Easter Eggs:
imbecil
idiota
capullo
Other interesting Memory Addresses
0x852914
: D3D8-Device pointer0x7FCC00
: number of opened.packed
files0x84cb64
: pointer to console command handler0x7fac84
: pointer to C++ callback list structure0x80b2cc
: pointer to ActionClassList (???)0x807a20
: pointer to SScorer (ingame GUI/Menu/Text system) structure (???)0x80a398
: pointer to SoundSystem (???)0x8b18f0
: pointer to Models Data (can be dumped using scenegraph debugging console)0x8b18f4
: pointer to Scenes Data (can be dumped using scenegraph debugging console)0x8b18f8
: pointer to active Models Data (can be dumped using scenegraph debugging console)
Hash-function used in Hash-Tables
unsigned long hash(const unsigned char *s)
{
unsigned long h = 0, high;
while ( *s )
{
h = ( h << 4 ) + *s++;
if ( high = h & 0xF0000000 )
h ^= high >> 24;
h &= ~high;
}
return h;
}
Other Functions:
Check r2_analyze.py
for full list
File Index struct @ 0x7fcbec
struct FileEntry {
uint32_t offset;
uint32_t size;
uint32_t unk; // seems to always be 0xBADFOO1
unsigned char* path;
FileEntry* next; // next entry in hashtable chain
}
struct FileIDX {
uint32_t size;
FileEntry** entries;
};
Packed Index struct (array @ 0x7fc1b0
)
struct PackedIDX {
void** VMT;
unsigned char* filename;
uint32_t locked; // not sure
void* data;
uint32_t seek;
}
C(++)-Callbacks @ 0x7fac84
Structure:
struct CPP_Callback {
const char* name;
void* func;
CPP_Callback* left;
CPP_Callback* right;
}
Game engine Variables Pointer @ 0x7FBE4C
Structure:
struct GameVar {
GameVar* next;
const char* name;
const char* desc;
uint8_t subtype;
uint8_t type;
uint16_t unk;
void* value;
void* def_value;
}
Types
Value | Type |
---|---|
0x10 |
const char* |
0x20 |
int32_t |
0x30 |
User Control Definition |
0x40 |
float |
0x60 |
Callback function |
Game World/State Pointer @ 0x7fe944
Points to World struct
Offset | Type | Description |
---|---|---|
0x0000 | void** |
Virtual Method Table |
0x0004 | uint32_t |
Size of Entity Hashtable |
0x0008 | void** |
Pointer to Entity Hashtable |
0x0288 | pyEntity* |
UsrEntity[0] |
0x028C | pyEntity* |
UsrEntity[1] |
0x0290 | pyEntity* |
UsrEntity[2] |
0x0294 | pyEntity* |
UsrEntity[3] |
0x02B8 | uint32_t |
Number of entity lists |
0x02BC | void** |
Pointer to entity list Hashtable |
0x0330 | float[3] |
Time (why 3 times?) |
0x1C6C | float |
Alarm level |
0x1C68 | float |
Alarm Grow Level |
0x2158 | float |
Used in World_Init |
0x2170 | ??? |
Used in World_Init |
0x2180 | float |
Used in World_Init |
0x2188 | void* |
Used in World_Init |
0x218C | void* |
Used in World_Init |
0x2190 | float |
Used in World_Init |
0x2198 | void* |
Used in World_Init |
0x219C | void* |
Used in World_Init |
0x21A0 | void** |
Used in World_Init (VTable pointer?) |
0x21B4 | void** |
Used in World_Init (VTable pointer?) |
0x21C8 | ??? |
Used in World_Init |
0x2204 | uint32_t or uint16_t |
Used in World_Init |
0x2230 | float |
Used in World_Init |
0x2238 | ??? |
Used in World_Init |
0x2254 | float |
Used in World_Init |
Entity Hash Table
Hash-function used: PJW (Same parameters as the example implementation)
Entry format:
struct HT_Entry {
void* data;
const char* key;
HT_Entry* next;
}
Data format:
Offset | Type | Description |
---|---|---|
0x0 | void** |
Virtual Method Table (?) |
0x4 | const char* |
name as string |
0x14 | void* |
pointer to self (why?) |
0x28 | float[3] |
Position in Game World |
EntityList Hash Table
Attributes:
Near
First
Num
OnDeath
OnDamage
File Formats
.packed File Format:
Header:
"BFPK\0\0\0\0"
Int32ul: number of files
for each file:
Int32ul: path length
String: path
Int32ul: size
Int32ul: offset in file
Virtual Method Tables:
check r2_analyze.py
for full list
Loading Custom Content (not really working)
- Create a folder
mods
- Drop a
*.packed
file into it - Change
Scrap.cfg
as follows- Add
ModPathName = mods
- Add
ModFileName = <filename>
- Add
Interesting file inside Data.packed
m3d.ini
: Rendering Engine Configurationscripts/
: Game Engine Scripts
How to enable External Console:
- Right click on the title bar (in windowed mode) and click "Switch Console"
- or Use a custom Content Pack (untested!)
How to enable Scenegraph debugging console
- extract
Data.packed
- in m3d.ini uncomment (remove
;
)ConsolaWnd
(GUI Console) and/orConsolaTxt
(Text Console) and set the value toSI
- repack
Data.packed
Misc. Interesting things
sys.path
contains "./lib" so you can import your own Python Modules- Games crashes when starting a multiplayer server and feeding it random UDP data
Code Snippets
Kaitai Struct Parser for .packed files
meta:
id: packed
application: Scrapland
file-extension: packed
endian: le
xref: http://wiki.xentax.com/index.php/Scrapland_PACKED
license: MIT
encoding: UTF-8
seq:
- id: magic
contents: BFPK
doc: File Magic
- id: version
contents: [0,0,0,0]
doc: File Version
- id: num_files
type: u4
doc: Number of files
- id: files
type: file_entry
repeat: expr
repeat-expr: num_files
doc: Entry for each file
types:
file_entry:
seq:
- id: path_len
type: u4
doc: Length of file path
- id: path
type: str
size: path_len
doc: File path
- id: size
type: u4
doc: File size
- id: offset
type: u4
doc: Absoulte File offset
instances:
data:
pos: offset
size: size
TODO:
- Figure out how C++ Callbacks work
- Figure out SM3 (Models), CM3 (Animations) file formats
- Figure out rest of World structure
- Figure out rest of Entity structure