Load media from subfolders (#9065)

This commit is contained in:
DS 2020-08-20 22:25:29 +02:00 committed by GitHub
parent 9c7340104a
commit 98faeac5a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 34 additions and 21 deletions

@ -152,7 +152,11 @@ Mod directory structure
│   ├── models │   ├── models
│   ├── textures │   ├── textures
│   │   ├── modname_stuff.png │   │   ├── modname_stuff.png
│   │   └── modname_something_else.png │   │   ├── modname_something_else.png
│   │   ├── subfolder_foo
│   │   │ ├── modname_more_stuff.png
│   │   │ └── another_subfolder
│   │   └── bar_subfolder
│   ├── sounds │   ├── sounds
│   ├── media │   ├── media
│   ├── locale │   ├── locale
@ -221,18 +225,20 @@ registered callbacks.
`minetest.settings` can be used to read custom or existing settings at load `minetest.settings` can be used to read custom or existing settings at load
time, if necessary. (See [`Settings`]) time, if necessary. (See [`Settings`])
### `models` ### `textures`, `sounds`, `media`, `models`, `locale`
Models for entities or meshnodes.
### `textures`, `sounds`, `media`
Media files (textures, sounds, whatever) that will be transferred to the Media files (textures, sounds, whatever) that will be transferred to the
client and will be available for use by the mod. client and will be available for use by the mod and translation files for
the clients (see [Translations]).
### `locale` It is suggested to use the folders for the purpous they are thought for,
eg. put textures into `textures`, translation files into `locale`,
models for entities or meshnodes into `models` et cetera.
Translation files for the clients. (See [Translations]) These folders and subfolders can contain subfolders.
Subfolders with names starting with `_` or `.` are ignored.
If a subfolder contains a media file with the same name as a media file
in one of its parents, the parent's file is used.
Naming conventions Naming conventions
------------------ ------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

@ -0,0 +1,3 @@
This is for testing loading textures from subfolders.
If it works correctly, the default_grass_side.png file in this folder is used but
default_grass.png is not overwritten by the file in this folder.

@ -2494,19 +2494,25 @@ void Server::fillMediaCache()
// Collect all media file paths // Collect all media file paths
std::vector<std::string> paths; std::vector<std::string> paths;
m_modmgr->getModsMediaPaths(paths); // The paths are ordered in descending priority
fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
fs::GetRecursiveDirs(paths, porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server"); fs::GetRecursiveDirs(paths, porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server");
fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
m_modmgr->getModsMediaPaths(paths);
// Collect media file information from paths into cache // Collect media file information from paths into cache
for (const std::string &mediapath : paths) { for (const std::string &mediapath : paths) {
std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath); std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath);
for (const fs::DirListNode &dln : dirlist) { for (const fs::DirListNode &dln : dirlist) {
if (dln.dir) // Ignore dirs if (dln.dir) // Ignore dirs (already in paths)
continue; continue;
const std::string &filename = dln.name;
if (m_media.find(filename) != m_media.end()) // Do not override
continue;
std::string filepath = mediapath; std::string filepath = mediapath;
filepath.append(DIR_DELIM).append(dln.name); filepath.append(DIR_DELIM).append(filename);
addMediaFile(dln.name, filepath); addMediaFile(filename, filepath);
} }
} }

@ -99,10 +99,10 @@ void ServerModManager::getModNames(std::vector<std::string> &modlist) const
void ServerModManager::getModsMediaPaths(std::vector<std::string> &paths) const void ServerModManager::getModsMediaPaths(std::vector<std::string> &paths) const
{ {
for (const ModSpec &spec : m_sorted_mods) { for (const ModSpec &spec : m_sorted_mods) {
paths.push_back(spec.path + DIR_DELIM + "textures"); fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "textures");
paths.push_back(spec.path + DIR_DELIM + "sounds"); fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "sounds");
paths.push_back(spec.path + DIR_DELIM + "media"); fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "media");
paths.push_back(spec.path + DIR_DELIM + "models"); fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "models");
paths.push_back(spec.path + DIR_DELIM + "locale"); fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "locale");
} }
} }

@ -169,6 +169,4 @@ void TestServerModManager::testGetModMediaPaths()
std::vector<std::string> result; std::vector<std::string> result;
sm.getModsMediaPaths(result); sm.getModsMediaPaths(result);
UASSERTEQ(bool, result.empty(), false); UASSERTEQ(bool, result.empty(), false);
// We should have 5 folders for each mod (textures, media, locale, model, sounds)
UASSERTEQ(unsigned long, result.size() % 5, 0);
} }