-
Notifications
You must be signed in to change notification settings - Fork 2
/
SFS-decompressed.bt
231 lines (178 loc) · 5.73 KB
/
SFS-decompressed.bt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
//------------------------------------------------
//--- 010 Editor v14.0.1 Binary Template
//
// File: SFS-decompressed.bt
// Authors: Simon Davies (insomnious) & Nexus Mods
// Version: 1.0.0
// Purpose:
// Category:
// File Mask:
// ID Bytes:
// History:
//------------------------------------------------
LittleEndian();
int isGamePlugin( char name[] )
{
if( Strcmp(name, "Starfield.esm") == 0 ) return true;
if( Strcmp(name, "Constellation.esm") == 0 ) return true;
if( Strcmp(name, "OldMars.esm") == 0 ) return true;
if( Strcmp(name, "BlueprintShips-Starfield.esm") == 0 ) return true;
if( Strcmp(name, "SFBGS007.esm") == 0 ) return true;
if( Strcmp(name, "SFBGS008.esm") == 0 ) return true;
if( Strcmp(name, "SFBGS006.esm") == 0 ) return true;
if( Strcmp(name, "SFBGS003.esm") == 0 ) return true;
return false;
}
int isCreationPlugin( char name[] )
{
//if( Strcmp(name, "sfbgs00a_a.esm") == 0 ) return true;
//if( Strcmp(name, "sfbgs023.esm") == 0 ) return true;
local int offset = FTell();
local ushort nextShort = ReadShort();
if ( nextShort != 0 ) return true;
return false;
}
int isCreation( char name[] )
{
if( Strstr(name, ".esm") > -1 )
return false;
return true;
}
typedef struct {
ushort size;
uchar text[size];
} QSTRING;
typedef struct {
uint engineVersion;
ubyte saveVersion;
uint saveNumber;
ushort playerNameSize;
char playerName[playerNameSize];
uint playerLevel;
ushort playerLocationSize;
char playerLocation[playerLocationSize];
ushort playtimeSize;
char playtime[playtimeSize];
ushort raceNameSize;
char raceName[raceNameSize];
ushort gender;
float experience;
float experienceRequired;
uint64 time;
byte padding[8];
uint unknown;
} HEADER;
typedef struct {
ubyte saveVersion;
ushort currentGameVersionSize;
char currentGameVersion[currentGameVersionSize];
ushort createdGameVersionSize;
char createdGameVersion[createdGameVersionSize];
ushort pluginInfoSize;
} INFO;
typedef struct {
ushort pluginNameSize;
char pluginName[pluginNameSize];
// if saveVersion is 140 or more, it has a byte to say if we have extra info
// if less than 140, then we need to use game plugin names to check
if( header.saveVersion >= 140 ) {
ubyte extraInfo;
if ( extraInfo == 1 ) {
ushort creationNameSize;
char creationName[creationNameSize];
ushort creationIdSize;
char creationId[creationIdSize];
ushort flagsSize;
byte flags[flagsSize];
byte achivementFriendly;
Printf("%s is a plugin\n", pluginName);
} else {
Printf("%s is a game plugin\n", pluginName);
}
} else {
if( !isGamePlugin(pluginName) ) {
// isn't game plugin so we are expecting some extra info
if(header.saveVersion >= 122) { // newer save format support creations and have extra data
ushort creationNameSize;
char creationName[creationNameSize];
ushort creationIdSize;
char creationId[creationIdSize];
ushort flagsSize;
byte flags[flagsSize];
byte achivementFriendly;
}
Printf("%s is a plugin\n", pluginName);
} else {
Printf("%s is a game plugin\n", pluginName);
}
}
} PLUGIN <name=pluginName>;
typedef struct {
ubyte unknown0;
ubyte count0;
ubyte pluginCount;
Printf("===== plugins (%d)\n", pluginCount);
PLUGIN plugins[pluginCount] <optimize=false>;
ushort lightPluginCount;
Printf("===== light plugins (%d)\n", lightPluginCount);
PLUGIN lightPlugins[lightPluginCount] <optimize=false>;
if(header.saveVersion >= 122) { // newer save format support medium plugins
uint mediumPluginCount;
Printf("===== medium plugins (%d)\n", mediumPluginCount);
PLUGIN mediumPlugins[mediumPluginCount] <optimize=false>;
}
} PLUGIN_INFO;
typedef struct {
ushort unknown0;
uint pointer0;
uint pointer1;
uint pointer2;
uint pointer3;
uint pointer4;
uint pointer5;
uint pointer6;
uint pointer7;
uint pointer8;
uint pointer9;
uint pointer10;
uint pointer11;
byte padding[52];
} NEW_BLOCK;
typedef struct {
uint pointer0;
uint stringsArrayOffset; // strings array offset?
uint unknown0;
} NEW_BLOCK2;
typedef struct {
uint unknown0;
} NEW_BLOCK3;
typedef struct {
byte unknown0[18];
byte unknown;
byte unknown1[37];
} NEW_BLOCK4 <size=56>;
typedef struct {
ushort arrayCount;
QSTRING strings[arrayCount] <optimize=false>;
} STRINGS_ARRAY;
// actual file
char magic[12]; //0x04034b50
uint headerSize; // starting after this int
HEADER header;
INFO info;
if(header.saveVersion < 122) { // newer save format support creations and have extra data
Printf("Old save version (%d)\n", header.saveVersion);
Warning("Old save version (%d)", header.saveVersion);
}
PLUGIN_INFO pluginInfo;
NEW_BLOCK newBlock;
NEW_BLOCK2 newBlock2;
// unknown block
FSeek(newBlock.pointer0);
NEW_BLOCK3 newBlock3;
// unknown block
FSeek(newBlock.pointer1);
NEW_BLOCK4 newBlock4;
// start of strings array?
FSeek(newBlock2.stringsArrayOffset);
STRINGS_ARRAY stringsArray;