This commit is contained in:
MihailRis 2026-04-19 22:53:34 +03:00
parent dcaf87988b
commit 84a47b9298
3 changed files with 106 additions and 90 deletions

View file

@ -47,10 +47,6 @@ io::path ContentPack::getContentFile() const {
return folder / CONTENT_FILENAME; return folder / CONTENT_FILENAME;
} }
bool ContentPack::is_pack(const io::path& folder) {
return io::is_regular_file(folder / PACKAGE_FILENAME);
}
std::optional<ContentPackStats> ContentPack::loadStats() const { std::optional<ContentPackStats> ContentPack::loadStats() const {
auto contentFile = getContentFile(); auto contentFile = getContentFile();
if (!io::exists(contentFile)) { if (!io::exists(contentFile)) {
@ -85,6 +81,9 @@ static void checkContentPackId(const std::string& id, const io::path& folder) {
); );
} }
} }
if (id == "none") {
throw contentpack_error(id, folder, "content-pack id is not specified");
}
if (std::find( if (std::find(
ContentPack::RESERVED_NAMES.begin(), ContentPack::RESERVED_NAMES.begin(),
ContentPack::RESERVED_NAMES.end(), ContentPack::RESERVED_NAMES.end(),
@ -94,31 +93,7 @@ static void checkContentPackId(const std::string& id, const io::path& folder) {
} }
} }
ContentPack ContentPack::read(const io::path& folder) { static DependencyPack parse_dependency(std::string depName) {
auto root = io::read_json(folder / PACKAGE_FILENAME);
ContentPack pack;
root.at("id").get(pack.id);
root.at("title").get(pack.title);
root.at("version").get(pack.version);
if (root.has("creators")) {
const auto& creators = root["creators"];
for (int i = 0; i < creators.size(); i++) {
if (i > 0) {
pack.creator += ", ";
}
pack.creator += creators[i].asString();
}
} else {
root.at("creator").get(pack.creator);
}
root.at("description").get(pack.description);
root.at("source").get(pack.source);
pack.folder = folder;
if (auto found = root.at("dependencies")) {
const auto& dependencies = *found;
for (const auto& elem : dependencies) {
std::string depName = elem.asString();
auto level = DependencyLevel::REQUIRED; auto level = DependencyLevel::REQUIRED;
switch (depName.at(0)) { switch (depName.at(0)) {
case '!': case '!':
@ -172,24 +147,54 @@ ContentPack ContentPack::read(const io::path& folder) {
VersionOperator versionOperator; VersionOperator versionOperator;
if (VersionOperatorMeta.getItem(depVerOperator, versionOperator)) { if (VersionOperatorMeta.getItem(depVerOperator, versionOperator)) {
pack.dependencies.push_back( return DependencyPack{level, depName, depVer, versionOperator};
{level, depName, depVer, versionOperator}
);
} else { } else {
throw contentpack_error( throw std::runtime_error("invalid version operator");
pack.id, folder, "invalid version operator"
);
}
}
} }
}
if (pack.id == "none") { ContentPack ContentPack::read(const io::path& folder) {
throw contentpack_error( auto root = io::read_json(folder / PACKAGE_FILENAME);
pack.id, folder, "content-pack id is not specified" ContentPack pack;
); root.at("id").get(pack.id);
}
checkContentPackId(pack.id, folder); checkContentPackId(pack.id, folder);
root.at("title").get(pack.title);
root.at("version").get(pack.version);
if (root.has("creators")) {
const auto& creators = root["creators"];
for (int i = 0; i < creators.size(); i++) {
if (i > 0) {
pack.creator += ", ";
}
pack.creator += creators[i].asString();
}
} else {
root.at("creator").get(pack.creator);
}
root.at("description").get(pack.description);
root.at("source").get(pack.source);
pack.folder = folder;
auto dependenciesList = root.at("dependencies");
if (!dependenciesList) {
return pack;
}
if (auto found = root.at("dependencies")) {
const auto& dependencies = *found;
for (const auto& elem : dependencies) {
std::string depName = elem.asString();
try {
pack.dependencies.push_back(parse_dependency(std::move(depName)));
} catch (const std::runtime_error& err) {
throw contentpack_error(
pack.id,
folder,
"dependency parsing error: " + std::string(err.what())
);
}
}
}
return pack; return pack;
} }
@ -200,15 +205,21 @@ void ContentPack::scanFolder(
return; return;
} }
for (const auto& packFolder : io::directory_iterator(folder)) { for (const auto& packFolder : io::directory_iterator(folder)) {
if (!io::is_directory(packFolder)) continue; if (!io::is_directory(packFolder)) {
if (!is_pack(packFolder)) continue; continue;
}
auto packageFile = packFolder / PACKAGE_FILENAME;
if (!io::is_regular_file(packageFile)) {
continue;
}
try { try {
packs.push_back(read(packFolder)); packs.push_back(read(packFolder));
} catch (const contentpack_error& err) { } catch (const contentpack_error& err) {
std::cerr << "package.json error at " << err.getFolder().string(); logger.warning() << "package.json error at "
std::cerr << ": " << err.what() << std::endl; << err.getFolder().string() << ": " << err.what();
} catch (const std::runtime_error& err) { } catch (const std::runtime_error& err) {
std::cerr << err.what() << std::endl; logger.error() << "reading " << packageFile.string()
<< " error: " << err.what();
} }
} }
} }

View file

@ -85,7 +85,6 @@ struct ContentPack {
static inline const io::path GENERATORS_FOLDER = "generators"; static inline const io::path GENERATORS_FOLDER = "generators";
static const std::vector<std::string> RESERVED_NAMES; static const std::vector<std::string> RESERVED_NAMES;
static bool is_pack(const io::path& folder);
static ContentPack read(const io::path& folder); static ContentPack read(const io::path& folder);
static void scanFolder( static void scanFolder(

View file

@ -56,6 +56,24 @@ dv::value scripting::get_component_value(
return nullptr; return nullptr;
} }
static void init_component_events(
lua::State* L, const scriptenv& env, UserComponent& component
) {
lua::pushenv(L, *env);
auto& funcsset = component.funcsset;
funcsset.on_grounded = lua::hasfield(L, "on_grounded");
funcsset.on_fall = lua::hasfield(L, "on_fall");
funcsset.on_despawn = lua::hasfield(L, "on_despawn");
funcsset.on_sensor_enter = lua::hasfield(L, "on_sensor_enter");
funcsset.on_sensor_exit = lua::hasfield(L, "on_sensor_exit");
funcsset.on_save = lua::hasfield(L, "on_save");
funcsset.on_aim_on = lua::hasfield(L, "on_aim_on");
funcsset.on_aim_off = lua::hasfield(L, "on_aim_off");
funcsset.on_attacked = lua::hasfield(L, "on_attacked");
funcsset.on_used = lua::hasfield(L, "on_used");
lua::pop(L);
}
static void create_component( static void create_component(
lua::State* L, lua::State* L,
int entityIdx, int entityIdx,
@ -72,7 +90,6 @@ static void create_component(
logger.warning() << "pack environment is not available for " logger.warning() << "pack environment is not available for "
<< component.name; << component.name;
} }
logger.debug() << "creating instance of component " << component.name;
lua::pushvalue(L, entityIdx); lua::pushvalue(L, entityIdx);
auto compenv = create_component_environment( auto compenv = create_component_environment(
std::move(parentEnv), -1, component.name std::move(parentEnv), -1, component.name
@ -109,19 +126,8 @@ static void create_component(
lua::setfenv(L); lua::setfenv(L);
lua::call_nothrow(L, 0, 0); lua::call_nothrow(L, 0, 0);
lua::pushenv(L, *compenv); init_component_events(L, compenv, component);
auto& funcsset = component.funcsset; lua::pop(L);
funcsset.on_grounded = lua::hasfield(L, "on_grounded");
funcsset.on_fall = lua::hasfield(L, "on_fall");
funcsset.on_despawn = lua::hasfield(L, "on_despawn");
funcsset.on_sensor_enter = lua::hasfield(L, "on_sensor_enter");
funcsset.on_sensor_exit = lua::hasfield(L, "on_sensor_exit");
funcsset.on_save = lua::hasfield(L, "on_save");
funcsset.on_aim_on = lua::hasfield(L, "on_aim_on");
funcsset.on_aim_off = lua::hasfield(L, "on_aim_off");
funcsset.on_attacked = lua::hasfield(L, "on_attacked");
funcsset.on_used = lua::hasfield(L, "on_used");
lua::pop(L, 2);
component.env = compenv; component.env = compenv;
} }