Created
December 9, 2023 05:26
-
-
Save lincerely/daab69cadaa395b84f14552407446b6b to your computer and use it in GitHub Desktop.
unpack embedded .rmf objects from .ol WorldCraft prefab library to current directory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// unpack embedded .rmf objects from .ol WorldCraft prefab library to current directory. | |
// list of names and descriptions would be dump into info.txt. | |
// reference: https://github.com/LogicAndTrick/sledge-formats/blob/master/Sledge.Formats.Map/Formats/WorldcraftPrefabLibrary.cs | |
#include <stdio.h> | |
#include <string.h> | |
typedef unsigned char uint8_t; | |
typedef unsigned short uint16_t; | |
typedef unsigned int uint32_t; | |
struct object { | |
uint32_t offset, length; | |
char name[31]; | |
char desc[205]; | |
}; | |
int main(int argc, char** argv) | |
{ | |
if (argc < 2) { | |
fprintf(stderr, "usage: unpack FILE\n"); | |
return 1; | |
} | |
FILE *p; | |
p = fopen(argv[1], "rb"); | |
if (!p) { | |
fprintf(stderr, "failed to open file\n"); | |
return 1; | |
} | |
const char *EXPECTED_HEADER = "Worldcraft Prefab Library\r\n\x1A"; | |
char header[28]; | |
fread(header, 28, 1, p); | |
if (strncmp(header, EXPECTED_HEADER, 28) != 0) { | |
fprintf(stderr, "error: header unmatch\n"); | |
fclose(p); | |
return 1; | |
} | |
float version; | |
fread(&version, 4, 1, p); | |
printf("version: %.1f", version); | |
uint32_t offset; | |
fread(&offset, 4, 1, p); | |
uint16_t nobjects; | |
fread(&nobjects, 2, 1, p); | |
struct object objects[nobjects]; | |
FILE *info_p = fopen("info.txt", "w"); | |
if (!p) { | |
fprintf(stderr, "failed to write info.txt\n"); | |
fclose(p); | |
return 1; | |
} | |
fseek(p, offset, SEEK_SET); | |
for (int i = 0; i < nobjects; i++) { | |
fread(&objects[i], sizeof(struct object), 1, p); | |
fprintf(info_p, "%s : %s\n", objects[i].name, objects[i].desc); | |
fseek(p, 300, SEEK_CUR); | |
} | |
for (int i = 0; i < nobjects; i++) { | |
char fname[256]; | |
sprintf(fname, "%s.rmf", objects[i].name); | |
FILE *rmfp = fopen(fname, "wb"); | |
fseek(p, objects[i].offset, SEEK_SET); | |
for (int j = 0; j < objects[i].length; j++) | |
fputc(fgetc(p), rmfp); | |
fclose(rmfp); | |
} | |
fclose(info_p); | |
fclose(p); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment