diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index 3e7cdef79..6151925a0 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -1668,3 +1668,20 @@ FResourceLump* FileSystem::GetFileAt(int no) return FileInfo[no].lump; } +#include "c_dispatch.h" + +CCMD(fs_dir) +{ + int numfiles = fileSystem.GetNumEntries(); + + for (int i = 0; i < numfiles; i++) + { + auto container = fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(i)); + auto fn1 = fileSystem.GetFileFullName(i); + auto fns = fileSystem.GetFileShortName(i); + auto fnid = fileSystem.GetResourceId(i); + auto length = fileSystem.FileLength(i); + bool hidden = fileSystem.FindFile(fn1) != i; + Printf(PRINT_NONOTIFY, "%s%-64s %-15s (%5d) %10d %s %s\n", hidden ? TEXTCOLOR_RED : TEXTCOLOR_UNTRANSLATED, fn1, fns, fnid, length, container, hidden ? "(h)" : ""); + } +} \ No newline at end of file diff --git a/source/core/menu/usermap.cpp b/source/core/menu/usermap.cpp index 7f4e471c2..3c5847ced 100644 --- a/source/core/menu/usermap.cpp +++ b/source/core/menu/usermap.cpp @@ -45,3 +45,94 @@ #include "findfile.h" #include "v_draw.h" #include "usermap.h" +#include "gamecontrol.h" + +static UsermapDirectory root; + +void InsertMap(int lumpnum) +{ + FString filename = fileSystem.GetFileFullName(lumpnum); + auto path = filename.Split("/"); + + auto current = &root; + for (unsigned i = 0; i < path.Size() - 1; i++) + { + unsigned place = current->subdirectories.FindEx([=](const UsermapDirectory& entry) { return entry.name.CompareNoCase(path[i]) == 0; }); + if (place == current->subdirectories.Size()) + { + place = current->subdirectories.Reserve(1); + current->subdirectories.Last().name = path[i]; + } + current = ¤t->subdirectories[place]; + } + current->entries.Reserve(1); + current->entries.Last().displayname = path.Last(); + current->entries.Last().filename = fileSystem.GetFileFullName(lumpnum); + current->entries.Last().container = fileSystem.GetResourceFileName(fileSystem.GetFileContainer(lumpnum)); + current->entries.Last().size = fileSystem.FileLength(lumpnum); +} + +bool ValidateMap(int lumpnum) +{ + FString filename = fileSystem.GetFileFullName(lumpnum); + + if (fileSystem.FindFile(filename) != lumpnum) return false; + auto fr = fileSystem.OpenFileReader(lumpnum); + uint8_t check[4]; + fr.Read(&check, 4); + if (!isBlood()) + { + if (check[0] < 5 || check[0] > 9 || check[1] || check[2] || check[3]) return false; + } + else + { + if (memcmp(check, "BLM\x1a", 4)) return false; + } + return true; +} + +void SortEntries(UsermapDirectory& dir) +{ + qsort(dir.subdirectories.Data(), dir.subdirectories.Size(), sizeof(dir.subdirectories[0]), [](const void* a, const void* b) -> int + { + auto A = (UsermapDirectory*)a; + auto B = (UsermapDirectory*)b; + + return A->name.CompareNoCase(B->name); + }); + + qsort(dir.entries.Data(), dir.entries.Size(), sizeof(dir.entries[0]), [](const void* a, const void* b) -> int + { + auto A = (UsermapEntry*)a; + auto B = (UsermapEntry*)b; + + return A->displayname.CompareNoCase(B->displayname); + }); + + for (auto& subdir : dir.subdirectories) + { + subdir.parent = &dir; + SortEntries(subdir); + } +} + +void ReadUserMaps() +{ + int numfiles = fileSystem.GetNumEntries(); + + for (int i = 0; i < numfiles; i++) + { + auto fn1 = fileSystem.GetFileFullName(i); + if (!fn1 || !*fn1) continue; + auto map = strstr(fn1, ".map"); + if (!map || strcmp(map, ".map")) continue; + if (!ValidateMap(i)) continue; + InsertMap(i); + } + SortEntries(root); +} + +CCMD(readusermaps) +{ + ReadUserMaps(); +} \ No newline at end of file diff --git a/source/core/menu/usermap.h b/source/core/menu/usermap.h index e69de29bb..350666469 100644 --- a/source/core/menu/usermap.h +++ b/source/core/menu/usermap.h @@ -0,0 +1,19 @@ +#pragma once + + +struct UsermapEntry +{ + FString displayname; + const char* filename; + const char* container; + int size; +}; + +struct UsermapDirectory +{ + FString name; + UsermapDirectory* parent = nullptr; + TArray subdirectories; + TArray entries; +}; +