forked from teamnwah/openmw-tes3coop
Catch exception from invalid scripts during save&load (Fixes #1590)
This commit is contained in:
parent
b5650f5d4f
commit
1de406cb6d
1 changed files with 52 additions and 39 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <components/esm/locals.hpp>
|
#include <components/esm/locals.hpp>
|
||||||
|
|
||||||
#include <components/compiler/locals.hpp>
|
#include <components/compiler/locals.hpp>
|
||||||
|
#include <components/compiler/exception.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/scriptmanager.hpp"
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
@ -75,65 +76,77 @@ namespace MWScript
|
||||||
|
|
||||||
void Locals::write (ESM::Locals& locals, const std::string& script) const
|
void Locals::write (ESM::Locals& locals, const std::string& script) const
|
||||||
{
|
{
|
||||||
const Compiler::Locals& declarations =
|
try
|
||||||
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
|
||||||
|
|
||||||
for (int i=0; i<3; ++i)
|
|
||||||
{
|
{
|
||||||
char type = 0;
|
const Compiler::Locals& declarations =
|
||||||
|
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||||
|
|
||||||
switch (i)
|
for (int i=0; i<3; ++i)
|
||||||
{
|
{
|
||||||
case 0: type = 's'; break;
|
char type = 0;
|
||||||
case 1: type = 'l'; break;
|
|
||||||
case 2: type = 'f'; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& names = declarations.get (type);
|
|
||||||
|
|
||||||
for (int i2=0; i2<static_cast<int> (names.size()); ++i2)
|
|
||||||
{
|
|
||||||
ESM::Variant value;
|
|
||||||
|
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case 0: value.setType (ESM::VT_Int); value.setInteger (mShorts.at (i2)); break;
|
case 0: type = 's'; break;
|
||||||
case 1: value.setType (ESM::VT_Int); value.setInteger (mLongs.at (i2)); break;
|
case 1: type = 'l'; break;
|
||||||
case 2: value.setType (ESM::VT_Float); value.setFloat (mFloats.at (i2)); break;
|
case 2: type = 'f'; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
locals.mVariables.push_back (std::make_pair (names[i2], value));
|
const std::vector<std::string>& names = declarations.get (type);
|
||||||
|
|
||||||
|
for (int i2=0; i2<static_cast<int> (names.size()); ++i2)
|
||||||
|
{
|
||||||
|
ESM::Variant value;
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0: value.setType (ESM::VT_Int); value.setInteger (mShorts.at (i2)); break;
|
||||||
|
case 1: value.setType (ESM::VT_Int); value.setInteger (mLongs.at (i2)); break;
|
||||||
|
case 2: value.setType (ESM::VT_Float); value.setFloat (mFloats.at (i2)); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
locals.mVariables.push_back (std::make_pair (names[i2], value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (const Compiler::SourceException&)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Locals::read (const ESM::Locals& locals, const std::string& script)
|
void Locals::read (const ESM::Locals& locals, const std::string& script)
|
||||||
{
|
{
|
||||||
const Compiler::Locals& declarations =
|
try
|
||||||
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
|
||||||
|
|
||||||
for (std::vector<std::pair<std::string, ESM::Variant> >::const_iterator iter
|
|
||||||
= locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
char type = declarations.getType (iter->first);
|
const Compiler::Locals& declarations =
|
||||||
char index = declarations.getIndex (iter->first);
|
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||||
|
|
||||||
try
|
for (std::vector<std::pair<std::string, ESM::Variant> >::const_iterator iter
|
||||||
|
= locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter)
|
||||||
{
|
{
|
||||||
switch (type)
|
char type = declarations.getType (iter->first);
|
||||||
{
|
char index = declarations.getIndex (iter->first);
|
||||||
case 's': mShorts.at (index) = iter->second.getInteger(); break;
|
|
||||||
case 'l': mLongs.at (index) = iter->second.getInteger(); break;
|
|
||||||
case 'f': mFloats.at (index) = iter->second.getFloat(); break;
|
|
||||||
|
|
||||||
// silently ignore locals that don't exist anymore
|
try
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 's': mShorts.at (index) = iter->second.getInteger(); break;
|
||||||
|
case 'l': mLongs.at (index) = iter->second.getInteger(); break;
|
||||||
|
case 'f': mFloats.at (index) = iter->second.getFloat(); break;
|
||||||
|
|
||||||
|
// silently ignore locals that don't exist anymore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
// ignore type changes
|
||||||
|
/// \todo write to log
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
}
|
||||||
{
|
catch (const Compiler::SourceException&)
|
||||||
// ignore type changes
|
{
|
||||||
/// \todo write to log
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue