1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-21 14:02:59 +01:00

Merge pull request #21276 from ZehMatt/fix-21188

Fix using iterators that are deleted by the plugin
This commit is contained in:
Matt
2024-01-25 18:46:51 +02:00
committed by GitHub
2 changed files with 34 additions and 11 deletions

View File

@@ -1634,7 +1634,7 @@ void ScriptEngine::RemoveInterval(const std::shared_ptr<Plugin>& plugin, Interva
// Only allow owner or REPL (nullptr) to remove intervals
if (plugin == nullptr || interval.Owner == plugin)
{
_intervals.erase(it);
interval.Deleted = true;
}
}
@@ -1653,21 +1653,43 @@ void ScriptEngine::UpdateIntervals()
}
_lastIntervalTimestamp = timestamp;
for (auto it = _intervals.begin(), itNext = it; it != _intervals.end(); it = itNext)
// Erase all intervals marked as deleted.
for (auto it = _intervals.begin(); it != _intervals.end();)
{
itNext++;
auto& interval = it->second;
if (timestamp >= interval.LastTimestamp + interval.Delay)
if (interval.Deleted)
{
ExecutePluginCall(interval.Owner, interval.Callback, {}, false);
it = _intervals.erase(it);
}
else
{
it++;
}
}
interval.LastTimestamp = timestamp;
if (!interval.Repeat)
{
_intervals.erase(it);
}
// Execute all intervals that are due.
for (auto it = _intervals.begin(); it != _intervals.end(); it++)
{
auto& interval = it->second;
if (timestamp < interval.LastTimestamp + interval.Delay)
{
continue;
}
if (interval.Deleted)
{
// There is a chance that in one of the callbacks it deletes another interval.
continue;
}
ExecutePluginCall(interval.Owner, interval.Callback, {}, false);
interval.LastTimestamp = timestamp;
if (!interval.Repeat)
{
interval.Deleted = true;
}
}
}

View File

@@ -134,6 +134,7 @@ namespace OpenRCT2::Scripting
int64_t LastTimestamp{};
DukValue Callback;
bool Repeat{};
bool Deleted{};
};
class ScriptEngine