Merge pull request #9749 from RoosterDragon/delay-toctou-fixes

Fix TOCTOU issues when calling Game.RunAfterDelay
This commit is contained in:
Oliver Brakmann
2015-10-25 21:16:15 +01:00
7 changed files with 36 additions and 22 deletions

View File

@@ -767,7 +767,7 @@ namespace OpenRA
public static bool IsCurrentWorld(World world)
{
return OrderManager != null && OrderManager.World == world;
return OrderManager != null && OrderManager.World == world && !world.Disposing;
}
}
}

View File

@@ -62,22 +62,22 @@ namespace OpenRA.Mods.Common.Traits
foreach (var a in player.World.Actors.Where(a => a.Owner == player))
a.Kill(a);
if (player == player.World.LocalPlayer)
Game.RunAfterDelay(info.NotificationDelay, () =>
{
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World))
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Lose", player.Faction.InternalName);
});
}
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Lose", player.Faction.InternalName);
});
}
public void OnPlayerWon(Player player)
{
Game.Debug("{0} is victorious.", player.PlayerName);
if (player == player.World.LocalPlayer)
Game.RunAfterDelay(info.NotificationDelay, () => Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Win", player.Faction.InternalName));
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Win", player.Faction.InternalName);
});
}
public void OnObjectiveAdded(Player player, int id) { }

View File

@@ -150,6 +150,9 @@ namespace OpenRA.Mods.Common.Traits
if (gameOver)
Game.RunAfterDelay(Info.GameOverDelay, () =>
{
if (!Game.IsCurrentWorld(player.World))
return;
player.World.EndGame();
player.World.SetPauseState(true);
player.World.PauseStateLocked = true;

View File

@@ -107,22 +107,22 @@ namespace OpenRA.Mods.Common.Traits
foreach (var a in player.World.Actors.Where(a => a.Owner == player))
a.Kill(a);
if (player == player.World.LocalPlayer)
Game.RunAfterDelay(info.NotificationDelay, () =>
{
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World))
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Lose", player.Faction.InternalName);
});
}
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Lose", player.Faction.InternalName);
});
}
public void OnPlayerWon(Player player)
{
Game.Debug("{0} is victorious.", player.PlayerName);
if (player == player.World.LocalPlayer)
Game.RunAfterDelay(info.NotificationDelay, () => Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Win", player.Faction.InternalName));
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Win", player.Faction.InternalName);
});
}
public void OnObjectiveAdded(Player player, int id) { }

View File

@@ -51,12 +51,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var exitDelay = iop != null ? iop.ExitDelay : 0;
if (mpe != null)
{
Game.RunAfterDelay(exitDelay, () => mpe.Fade(MenuPaletteEffect.EffectType.Black));
Game.RunAfterDelay(exitDelay, () =>
{
if (Game.IsCurrentWorld(world))
mpe.Fade(MenuPaletteEffect.EffectType.Black);
});
exitDelay += 40 * mpe.Info.FadeLength;
}
Game.RunAfterDelay(exitDelay, () =>
{
if (!Game.IsCurrentWorld(world))
return;
Game.Disconnect();
Ui.ResetAll();
Game.LoadShellMap();

View File

@@ -42,6 +42,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
loadingObserverWidgets = true;
Game.RunAfterDelay(objectives != null ? objectives.GameOverDelay : 0, () =>
{
if (!Game.IsCurrentWorld(world))
return;
playerRoot.RemoveChildren();
Game.LoadWidget(world, "OBSERVER_WIDGETS", playerRoot, new WidgetArgs());
});

View File

@@ -109,8 +109,9 @@ namespace OpenRA.Mods.D2k.Activities
Game.RunAfterDelay(1000, () =>
{
foreach (var affectedPlayer in affectedPlayers)
NotifyPlayer(affectedPlayer, attackPosition);
if (Game.IsCurrentWorld(self.World))
foreach (var affectedPlayer in affectedPlayers)
NotifyPlayer(affectedPlayer, attackPosition);
});
}