mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-19 12:40:49 +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");
|
sol::usertype<CellsStore> cells = context.mLua->sol().new_usertype<CellsStore>("Cells");
|
||||||
cells[sol::meta_function::length]
|
cells[sol::meta_function::length]
|
||||||
= [cells3Store, cells4Store](const CellsStore&) { return cells3Store->getSize() + cells4Store->getSize(); };
|
= [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.
|
index--; // Translate from Lua's 1-based indexing.
|
||||||
if (index < cells3Store->getSize())
|
if (index < cells3Store->getSize())
|
||||||
{
|
{
|
||||||
|
@ -243,9 +243,13 @@ namespace MWLua
|
|||||||
= [](const SpellStore& store) { return "ESM3_SpellStore{" + std::to_string(store.getSize()) + " spells}"; };
|
= [](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::length] = [](const SpellStore& store) { return store.getSize(); };
|
||||||
spellStoreT[sol::meta_function::index] = sol::overload(
|
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* {
|
[](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::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
spellStoreT[sol::meta_function::ipairs] = 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::length] = [](const EnchantmentStore& store) { return store.getSize(); };
|
||||||
enchantmentStoreT[sol::meta_function::index] = sol::overload(
|
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* {
|
[](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::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
enchantmentStoreT[sol::meta_function::ipairs] = 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}";
|
return "ESM3_MagicEffectStore{" + std::to_string(store.getSize()) + " effects}";
|
||||||
};
|
};
|
||||||
magicEffectStoreT[sol::meta_function::index] = sol::overload(
|
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* {
|
[](const MagicEffectStore& store, std::string_view id) -> const ESM::MagicEffect* {
|
||||||
int index = ESM::MagicEffect::indexNameToIndex(id);
|
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*/,
|
auto magicEffectsIter = [magicEffectStore](sol::this_state lua, const sol::object& /*store*/,
|
||||||
sol::optional<int> id) -> std::tuple<sol::object, sol::object> {
|
sol::optional<int> id) -> std::tuple<sol::object, sol::object> {
|
||||||
@ -665,20 +673,20 @@ namespace MWLua
|
|||||||
|
|
||||||
// types.Actor.spells(o)[i]
|
// types.Actor.spells(o)[i]
|
||||||
spellsT[sol::meta_function::index] = sol::overload(
|
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 (auto* store = spells.getStore())
|
||||||
if (index <= store->count())
|
if (index <= store->count() && index > 0)
|
||||||
return store->at(index - 1);
|
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())
|
if (auto* store = spells.getStore())
|
||||||
{
|
{
|
||||||
const ESM::Spell* spell = spellStore->find(ESM::RefId::deserializeText(spellId));
|
const ESM::Spell* spell = spellStore->search(ESM::RefId::deserializeText(spellId));
|
||||||
if (store->hasSpell(spell))
|
if (spell && store->hasSpell(spell))
|
||||||
return spell;
|
return spell;
|
||||||
}
|
}
|
||||||
return sol::nullopt;
|
return nullptr;
|
||||||
});
|
});
|
||||||
|
|
||||||
// pairs(types.Actor.spells(o))
|
// pairs(types.Actor.spells(o))
|
||||||
|
@ -136,11 +136,11 @@ namespace MWLua
|
|||||||
listT[sol::meta_function::to_string]
|
listT[sol::meta_function::to_string]
|
||||||
= [](const ListT& list) { return "{" + std::to_string(list.mIds->size()) + " objects}"; };
|
= [](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::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())
|
if (index > 0 && index <= list.mIds->size())
|
||||||
return ObjectT((*list.mIds)[index - 1]);
|
return ObjectT((*list.mIds)[index - 1]);
|
||||||
else
|
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::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
listT[sol::meta_function::ipairs] = 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}"; };
|
= [](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::length] = [](const SoundStore& store) { return store.getSize(); };
|
||||||
soundStoreT[sol::meta_function::index] = sol::overload(
|
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* {
|
[](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::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
soundStoreT[sol::meta_function::ipairs] = 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");
|
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::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);
|
ESM::RefId quest = ESM::RefId::deserializeText(questId);
|
||||||
const ESM::Dialogue* dial = MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().find(quest);
|
const ESM::Dialogue* dial = MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().search(quest);
|
||||||
if (dial->mType != ESM::Dialogue::Journal)
|
if (dial == nullptr || dial->mType != ESM::Dialogue::Journal)
|
||||||
throw std::runtime_error("Not a quest:" + std::string(questId));
|
return sol::nullopt;
|
||||||
return Quest{ .mQuestId = quest, .mMutable = quests.mMutable };
|
return Quest{ .mQuestId = quest, .mMutable = quests.mMutable };
|
||||||
});
|
};
|
||||||
quests[sol::meta_function::pairs] = [journal](const Quests& quests) {
|
quests[sol::meta_function::pairs] = [journal](const Quests& quests) {
|
||||||
std::vector<ESM::RefId> ids;
|
std::vector<ESM::RefId> ids;
|
||||||
for (auto it = journal->questBegin(); it != journal->questEnd(); ++it)
|
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>();
|
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; },
|
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.
|
// Define a custom user type for the store.
|
||||||
// Provide the interface of a read-only array.
|
// 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::length] = [](const StoreT& store) { return store.getSize(); };
|
||||||
storeT[sol::meta_function::index] = [](const StoreT& store, size_t index) -> const T* {
|
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.
|
return store.at(index - 1); // Translate from Lua's 1-based indexing.
|
||||||
};
|
};
|
||||||
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user