mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-14 15:40:18 +00:00
Return nil when we try to use an invalid store index from Lua
This commit is contained in:
parent
690a237896
commit
5d211d3c93
@ -231,7 +231,11 @@ namespace MWLua
|
||||
sol::usertype<CellsStore> cells = context.mLua->sol().new_usertype<CellsStore>("Cells");
|
||||
cells[sol::meta_function::length]
|
||||
= [cells3Store, cells4Store](const CellsStore&) { return cells3Store->getSize() + cells4Store->getSize(); };
|
||||
cells[sol::meta_function::index] = [cells3Store, cells4Store](const CellsStore&, size_t index) -> GCell {
|
||||
cells[sol::meta_function::index]
|
||||
= [cells3Store, cells4Store](const CellsStore&, size_t index) -> sol::optional<GCell> {
|
||||
if (index > cells3Store->getSize() + cells3Store->getSize() || index == 0)
|
||||
return sol::nullopt;
|
||||
|
||||
index--; // Translate from Lua's 1-based indexing.
|
||||
if (index < cells3Store->getSize())
|
||||
{
|
||||
|
@ -243,9 +243,13 @@ namespace MWLua
|
||||
= [](const SpellStore& store) { return "ESM3_SpellStore{" + std::to_string(store.getSize()) + " spells}"; };
|
||||
spellStoreT[sol::meta_function::length] = [](const SpellStore& store) { return store.getSize(); };
|
||||
spellStoreT[sol::meta_function::index] = sol::overload(
|
||||
[](const SpellStore& store, size_t index) -> const ESM::Spell* { return store.at(index - 1); },
|
||||
[](const SpellStore& store, size_t index) -> const ESM::Spell* {
|
||||
if (index == 0 || index > store.getSize())
|
||||
return nullptr;
|
||||
return store.at(index - 1);
|
||||
},
|
||||
[](const SpellStore& store, std::string_view spellId) -> const ESM::Spell* {
|
||||
return store.find(ESM::RefId::deserializeText(spellId));
|
||||
return store.search(ESM::RefId::deserializeText(spellId));
|
||||
});
|
||||
spellStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
spellStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
@ -262,9 +266,13 @@ namespace MWLua
|
||||
};
|
||||
enchantmentStoreT[sol::meta_function::length] = [](const EnchantmentStore& store) { return store.getSize(); };
|
||||
enchantmentStoreT[sol::meta_function::index] = sol::overload(
|
||||
[](const EnchantmentStore& store, size_t index) -> const ESM::Enchantment* { return store.at(index - 1); },
|
||||
[](const EnchantmentStore& store, size_t index) -> const ESM::Enchantment* {
|
||||
if (index == 0 || index > store.getSize())
|
||||
return nullptr;
|
||||
return store.at(index - 1);
|
||||
},
|
||||
[](const EnchantmentStore& store, std::string_view enchantmentId) -> const ESM::Enchantment* {
|
||||
return store.find(ESM::RefId::deserializeText(enchantmentId));
|
||||
return store.search(ESM::RefId::deserializeText(enchantmentId));
|
||||
});
|
||||
enchantmentStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
enchantmentStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
@ -280,10 +288,10 @@ namespace MWLua
|
||||
return "ESM3_MagicEffectStore{" + std::to_string(store.getSize()) + " effects}";
|
||||
};
|
||||
magicEffectStoreT[sol::meta_function::index] = sol::overload(
|
||||
[](const MagicEffectStore& store, int id) -> const ESM::MagicEffect* { return store.find(id); },
|
||||
[](const MagicEffectStore& store, int id) -> const ESM::MagicEffect* { return store.search(id); },
|
||||
[](const MagicEffectStore& store, std::string_view id) -> const ESM::MagicEffect* {
|
||||
int index = ESM::MagicEffect::indexNameToIndex(id);
|
||||
return store.find(index);
|
||||
return store.search(index);
|
||||
});
|
||||
auto magicEffectsIter = [magicEffectStore](sol::this_state lua, const sol::object& /*store*/,
|
||||
sol::optional<int> id) -> std::tuple<sol::object, sol::object> {
|
||||
@ -665,20 +673,20 @@ namespace MWLua
|
||||
|
||||
// types.Actor.spells(o)[i]
|
||||
spellsT[sol::meta_function::index] = sol::overload(
|
||||
[](const ActorSpells& spells, size_t index) -> sol::optional<const ESM::Spell*> {
|
||||
[](const ActorSpells& spells, size_t index) -> const ESM::Spell* {
|
||||
if (auto* store = spells.getStore())
|
||||
if (index <= store->count())
|
||||
if (index <= store->count() && index > 0)
|
||||
return store->at(index - 1);
|
||||
return sol::nullopt;
|
||||
return nullptr;
|
||||
},
|
||||
[spellStore](const ActorSpells& spells, std::string_view spellId) -> sol::optional<const ESM::Spell*> {
|
||||
[spellStore](const ActorSpells& spells, std::string_view spellId) -> const ESM::Spell* {
|
||||
if (auto* store = spells.getStore())
|
||||
{
|
||||
const ESM::Spell* spell = spellStore->find(ESM::RefId::deserializeText(spellId));
|
||||
if (store->hasSpell(spell))
|
||||
const ESM::Spell* spell = spellStore->search(ESM::RefId::deserializeText(spellId));
|
||||
if (spell && store->hasSpell(spell))
|
||||
return spell;
|
||||
}
|
||||
return sol::nullopt;
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
// pairs(types.Actor.spells(o))
|
||||
|
@ -136,11 +136,11 @@ namespace MWLua
|
||||
listT[sol::meta_function::to_string]
|
||||
= [](const ListT& list) { return "{" + std::to_string(list.mIds->size()) + " objects}"; };
|
||||
listT[sol::meta_function::length] = [](const ListT& list) { return list.mIds->size(); };
|
||||
listT[sol::meta_function::index] = [](const ListT& list, size_t index) {
|
||||
listT[sol::meta_function::index] = [](const ListT& list, size_t index) -> sol::optional<ObjectT> {
|
||||
if (index > 0 && index <= list.mIds->size())
|
||||
return ObjectT((*list.mIds)[index - 1]);
|
||||
else
|
||||
throw std::runtime_error("Index out of range");
|
||||
return sol::nullopt;
|
||||
};
|
||||
listT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
listT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
|
@ -169,9 +169,13 @@ namespace MWLua
|
||||
= [](const SoundStore& store) { return "ESM3_SoundStore{" + std::to_string(store.getSize()) + " sounds}"; };
|
||||
soundStoreT[sol::meta_function::length] = [](const SoundStore& store) { return store.getSize(); };
|
||||
soundStoreT[sol::meta_function::index] = sol::overload(
|
||||
[](const SoundStore& store, size_t index) -> const ESM::Sound* { return store.at(index - 1); },
|
||||
[](const SoundStore& store, size_t index) -> const ESM::Sound* {
|
||||
if (index == 0 || index > store.getSize())
|
||||
return nullptr;
|
||||
return store.at(index - 1);
|
||||
},
|
||||
[](const SoundStore& store, std::string_view soundId) -> const ESM::Sound* {
|
||||
return store.find(ESM::RefId::deserializeText(soundId));
|
||||
return store.search(ESM::RefId::deserializeText(soundId));
|
||||
});
|
||||
soundStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
soundStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
|
@ -48,13 +48,13 @@ namespace MWLua
|
||||
};
|
||||
sol::usertype<Quests> quests = context.mLua->sol().new_usertype<Quests>("Quests");
|
||||
quests[sol::meta_function::to_string] = [](const Quests& quests) { return "Quests"; };
|
||||
quests[sol::meta_function::index] = sol::overload([](const Quests& quests, std::string_view questId) -> Quest {
|
||||
quests[sol::meta_function::index] = [](const Quests& quests, std::string_view questId) -> sol::optional<Quest> {
|
||||
ESM::RefId quest = ESM::RefId::deserializeText(questId);
|
||||
const ESM::Dialogue* dial = MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().find(quest);
|
||||
if (dial->mType != ESM::Dialogue::Journal)
|
||||
throw std::runtime_error("Not a quest:" + std::string(questId));
|
||||
const ESM::Dialogue* dial = MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().search(quest);
|
||||
if (dial == nullptr || dial->mType != ESM::Dialogue::Journal)
|
||||
return sol::nullopt;
|
||||
return Quest{ .mQuestId = quest, .mMutable = quests.mMutable };
|
||||
});
|
||||
};
|
||||
quests[sol::meta_function::pairs] = [journal](const Quests& quests) {
|
||||
std::vector<ESM::RefId> ids;
|
||||
for (auto it = journal->questBegin(); it != journal->questEnd(); ++it)
|
||||
|
@ -77,7 +77,7 @@ namespace MWLua
|
||||
const MWWorld::Store<T>& store = MWBase::Environment::get().getESMStore()->get<T>();
|
||||
|
||||
table["record"] = sol::overload([](const Object& obj) -> const T* { return obj.ptr().get<T>()->mBase; },
|
||||
[&store](std::string_view id) -> const T* { return store.find(ESM::RefId::deserializeText(id)); });
|
||||
[&store](std::string_view id) -> const T* { return store.search(ESM::RefId::deserializeText(id)); });
|
||||
|
||||
// Define a custom user type for the store.
|
||||
// Provide the interface of a read-only array.
|
||||
@ -89,6 +89,8 @@ namespace MWLua
|
||||
};
|
||||
storeT[sol::meta_function::length] = [](const StoreT& store) { return store.getSize(); };
|
||||
storeT[sol::meta_function::index] = [](const StoreT& store, size_t index) -> const T* {
|
||||
if (index == 0 || index > store.getSize())
|
||||
return nullptr;
|
||||
return store.at(index - 1); // Translate from Lua's 1-based indexing.
|
||||
};
|
||||
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||
|
Loading…
x
Reference in New Issue
Block a user