mods.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. Minetest
  3. Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "mods.h"
  17. #include "filesys.h"
  18. #include "log.h"
  19. #include "scripting_server.h"
  20. #include "content/subgames.h"
  21. /**
  22. * Manage server mods
  23. *
  24. * All new calls to this class must be tested in test_servermodmanager.cpp
  25. */
  26. /**
  27. * Creates a ServerModManager which targets worldpath
  28. * @param worldpath
  29. */
  30. ServerModManager::ServerModManager(const std::string &worldpath) :
  31. ModConfiguration(worldpath)
  32. {
  33. SubgameSpec gamespec = findWorldSubgame(worldpath);
  34. // Add all game mods and all world mods
  35. addModsInPath(gamespec.gamemods_path);
  36. addModsInPath(worldpath + DIR_DELIM + "worldmods");
  37. // Load normal mods
  38. std::string worldmt = worldpath + DIR_DELIM + "world.mt";
  39. addModsFromConfig(worldmt, gamespec.addon_mods_paths);
  40. }
  41. // clang-format off
  42. // This function cannot be currenctly easily tested but it should be ASAP
  43. void ServerModManager::loadMods(ServerScripting *script)
  44. {
  45. // Print mods
  46. infostream << "Server: Loading mods: ";
  47. for (const ModSpec &mod : m_sorted_mods) {
  48. infostream << mod.name << " ";
  49. }
  50. infostream << std::endl;
  51. // Load and run "mod" scripts
  52. for (const ModSpec &mod : m_sorted_mods) {
  53. if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) {
  54. throw ModError("Error loading mod \"" + mod.name +
  55. "\": Mod name does not follow naming "
  56. "conventions: "
  57. "Only characters [a-z0-9_] are allowed.");
  58. }
  59. std::string script_path = mod.path + DIR_DELIM + "init.lua";
  60. infostream << " [" << padStringRight(mod.name, 12) << "] [\""
  61. << script_path << "\"]" << std::endl;
  62. auto t = std::chrono::steady_clock::now();
  63. script->loadMod(script_path, mod.name);
  64. infostream << "Mod \"" << mod.name << "\" loaded after "
  65. << std::chrono::duration_cast<std::chrono::milliseconds>(
  66. std::chrono::steady_clock::now() - t).count() * 0.001f
  67. << " seconds" << std::endl;
  68. }
  69. // Run a callback when mods are loaded
  70. script->on_mods_loaded();
  71. }
  72. // clang-format on
  73. const ModSpec *ServerModManager::getModSpec(const std::string &modname) const
  74. {
  75. std::vector<ModSpec>::const_iterator it;
  76. for (it = m_sorted_mods.begin(); it != m_sorted_mods.end(); ++it) {
  77. const ModSpec &mod = *it;
  78. if (mod.name == modname)
  79. return &mod;
  80. }
  81. return NULL;
  82. }
  83. void ServerModManager::getModNames(std::vector<std::string> &modlist) const
  84. {
  85. for (const ModSpec &spec : m_sorted_mods)
  86. modlist.push_back(spec.name);
  87. }
  88. void ServerModManager::getModsMediaPaths(std::vector<std::string> &paths) const
  89. {
  90. for (const ModSpec &spec : m_sorted_mods) {
  91. paths.push_back(spec.path + DIR_DELIM + "textures");
  92. paths.push_back(spec.path + DIR_DELIM + "sounds");
  93. paths.push_back(spec.path + DIR_DELIM + "media");
  94. paths.push_back(spec.path + DIR_DELIM + "models");
  95. paths.push_back(spec.path + DIR_DELIM + "locale");
  96. }
  97. }