From d6a454c5c39334fedd2d85c82bb7925cec8d515c Mon Sep 17 00:00:00 2001 From: Jaycie Ewald <jaycie.ewald@outlook.com> Date: Wed, 13 Dec 2023 16:20:51 -0600 Subject: [PATCH] rt_ted.c: parse with cJSON to get map author --- source/rt_ted.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ source/rt_ted.h | 5 ++ 2 files changed, 138 insertions(+) diff --git a/source/rt_ted.c b/source/rt_ted.c index 6dbf6df..8f25409 100644 --- a/source/rt_ted.c +++ b/source/rt_ted.c @@ -59,6 +59,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "rt_net.h" #include "_rt_ted.h" +#include "thirdp/cJSON.h" + //======================================== // GLOBAL VARIABLES //======================================== @@ -76,6 +78,8 @@ str_clock Clocks[MAXCLOCKS]; int numclocks; int LightsInArea[NUMAREAS + 1]; +char *mapinfo_json = NULL; + int maxheight; int nominalheight; int elevatorstart; @@ -93,6 +97,8 @@ int lastlevelloaded = -1; boolean insetupgame; boolean ISRTL = false; +boolean mapset_is_rxl = false; + unsigned MapSpecials = 0; char LevelName[80]; @@ -1297,10 +1303,13 @@ void CheckRTLVersion(char *filename) RXL_VERSION >> 8, RXL_VERSION & 0xff); } + mapset_is_rxl = true; close(filehandle); return; } + mapset_is_rxl = false; + if ((strcmp(RTLSignature, COMMBAT_SIGNATURE) != 0) && (strcmp(RTLSignature, NORMAL_SIGNATURE) != 0) && (strcmp(RTLSignature, RANDROTT_SIGNATURE) != 0)) @@ -1391,6 +1400,125 @@ size_t GetMapArrayOffset(int filehandle) } } +/* +====================== += += GetMapInfoJSON += +====================== +*/ +char *GetMapInfoJSON(int filehandle) +{ + char RTLSignature[4]; + uint64_t ofs_info_headers; + uint64_t num_info_headers; + int i; + char info_header_magic[16]; + uint64_t info_header_ofs; + uint64_t info_header_len; + int RTLVersion; + + // load signature + lseek(filehandle, 0, SEEK_SET); + SafeRead(filehandle, RTLSignature, sizeof(RTLSignature)); + + // check if it's from RottEX + if (strcmp(RTLSignature, EXTENDED_SIGNATURE) == 0 || + strcmp(RTLSignature, EXTENDED_COMMBAT_SIGNATURE) == 0) + { + // check version (it matters) + SafeRead(filehandle, &RTLVersion, sizeof(RTLVersion)); + + // seek to header location + lseek(filehandle, 8, SEEK_SET); + + // read offset and num + SafeRead(filehandle, &ofs_info_headers, sizeof(ofs_info_headers)); + SafeRead(filehandle, &num_info_headers, sizeof(num_info_headers)); + + // seek to headers + lseek(filehandle, ofs_info_headers, SEEK_SET); + + // read info headers + for (i = 0; i < num_info_headers; i++) + { + // read header + SafeRead(filehandle, info_header_magic, sizeof(info_header_magic)); + SafeRead(filehandle, &info_header_ofs, sizeof(info_header_ofs)); + SafeRead(filehandle, &info_header_len, sizeof(info_header_len)); + + // MAPINFO info header contains offset to json data + if (strcmp(info_header_magic, "MAPINFO") == 0) + { + char *jsondata = SafeMalloc(info_header_len + 1); + lseek(filehandle, info_header_ofs, SEEK_SET); + SafeRead(filehandle, jsondata, info_header_len); + jsondata[info_header_ofs] = '\0'; + return jsondata; + } + } + + // fail + close(filehandle); + Error("GetMapArrayOffset: Couldn't find MAPSET or MAPS offset!"); + return 0; + } + else + { + return NULL; + } +} + +/* +====================== += += GetMapAuthor += +====================== +*/ +char *GetMapAuthor(int mapnum) +{ + cJSON *root, *maps, *map; + char *ret = NULL; + + if (mapinfo_json == NULL) + return ret; + + /* parse mapinfo */ + root = cJSON_Parse(mapinfo_json); + if (root == NULL) + return ret; + + /* get maps array */ + maps = cJSON_GetObjectItemCaseSensitive(root, "maps"); + if (maps == NULL) + return ret; + + /* iterate over maps */ + map = maps->child; + while (map) + { + char *author; + int mapindex; + + author = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(map, "author")); + mapindex = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(map, "mapindex")); + + if (mapnum == mapindex) + { + ret = M_StringDuplicate(author); + break; + } + + map = map->next; + } + + /* clean up */ + cJSON_Delete(root); + + return ret; +} + /* ====================== = @@ -1414,6 +1542,11 @@ void ReadROTTMap(char *filename, int mapnum) CheckRTLVersion(filename); filehandle = SafeOpenRead(filename); mapsoffset = GetMapArrayOffset(filehandle); + if (mapinfo_json != NULL) + SafeFree(mapinfo_json); + mapinfo_json = GetMapInfoJSON(filehandle); + + GetMapAuthor(0); // // Load map header diff --git a/source/rt_ted.h b/source/rt_ted.h index 535bb14..83e6495 100644 --- a/source/rt_ted.h +++ b/source/rt_ted.h @@ -142,6 +142,9 @@ extern boolean insetupgame; extern char LevelName[80]; extern boolean ISRTL; +extern boolean mapset_is_rxl; +extern char *mapinfo_json; + extern char *ROTTMAPS; extern char *BATTMAPS; @@ -178,6 +181,8 @@ void GetMapInfo(mapfileinfo_t *mapinfo); void GetMapFileName(char *filename); void SetBattleMapFileName(char *filename); word GetMapCRC(int num); +char *GetMapInfoJSON(int filehandle); +char *GetMapAuthor(int map); int GetNextMap(int tilex, int tiley); void Illuminate();