public async IAsyncEnumerable <Image> Paint(string map) { var stopwatch = new Stopwatch(); stopwatch.Start(); await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings (){ Map = map }); var server = pairTracker.Pair.Server; var client = pairTracker.Pair.Client; Console.WriteLine($"Loaded client and server in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); stopwatch.Restart(); var cEntityManager = client.ResolveDependency <IClientEntityManager>(); var cPlayerManager = client.ResolveDependency <Robust.Client.Player.IPlayerManager>(); await client.WaitPost(() => { if (cEntityManager.TryGetComponent(cPlayerManager.LocalPlayer !.ControlledEntity !, out Robust.Client.GameObjects.SpriteComponent? sprite)) { sprite.Visible = false; } }); var sEntityManager = server.ResolveDependency <IServerEntityManager>(); var sPlayerManager = server.ResolveDependency <IPlayerManager>(); await server.WaitPost(() => { if (sEntityManager.TryGetComponent(sPlayerManager.ServerSessions.Single().AttachedEntity !, out SpriteComponent? sprite)) { sprite.Visible = false; } }); await PoolManager.RunTicksSync(pairTracker.Pair, 10); await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); var sMapManager = server.ResolveDependency <IMapManager>(); var tilePainter = new TilePainter(client, server); var entityPainter = new GridPainter(client, server); IMapGrid[] grids = null !; await server.WaitPost(() => { var playerEntity = sPlayerManager.ServerSessions.Single().AttachedEntity; if (playerEntity.HasValue) { sEntityManager.DeleteEntity(playerEntity.Value); } grids = sMapManager.GetAllMapGrids(new MapId(1)).ToArray(); foreach (var grid in grids) { grid.WorldRotation = Angle.Zero; } }); await PoolManager.RunTicksSync(pairTracker.Pair, 10); await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); foreach (var grid in grids) { // Skip empty grids if (grid.LocalAABB.IsEmpty()) { Console.WriteLine($"Warning: Grid {grid.Index} was empty. Skipping image rendering."); continue; } var tileXSize = grid.TileSize * TilePainter.TileImageSize; var tileYSize = grid.TileSize * TilePainter.TileImageSize; var bounds = grid.LocalAABB; var left = bounds.Left; var right = bounds.Right; var top = bounds.Top; var bottom = bounds.Bottom; var w = (int)Math.Ceiling(right - left) * tileXSize; var h = (int)Math.Ceiling(top - bottom) * tileYSize; var gridCanvas = new Image <Rgba32>(w, h); await server.WaitPost(() => { tilePainter.Run(gridCanvas, grid); entityPainter.Run(gridCanvas, grid); gridCanvas.Mutate(e => e.Flip(FlipMode.Vertical)); }); yield return(gridCanvas); } // We don't care if it fails as we have already saved the images. try { await pairTracker.CleanReturnAsync(); } catch { // ignored } }
public async IAsyncEnumerable <Image> Paint(string map) { var stopwatch = new Stopwatch(); stopwatch.Start(); var clientOptions = new ClientContentIntegrationOption { CVarOverrides = { [CVars.NetPVS.Name] = "false" }, Pool = false, FailureLogLevel = LogLevel.Fatal }; var serverOptions = new ServerContentIntegrationOption { CVarOverrides = { [CCVars.GameMap.Name] = map, [CVars.NetPVS.Name] = "false" }, Pool = false, FailureLogLevel = LogLevel.Fatal }; var(client, server) = await StartConnectedServerClientPair(clientOptions, serverOptions); await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); await RunTicksSync(client, server, 10); await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); Console.WriteLine($"Loaded client and server in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); stopwatch.Restart(); var cEntityManager = client.ResolveDependency <IClientEntityManager>(); var cPlayerManager = client.ResolveDependency <Robust.Client.Player.IPlayerManager>(); await client.WaitPost(() => { if (cEntityManager.TryGetComponent(cPlayerManager.LocalPlayer !.ControlledEntity !, out Robust.Client.GameObjects.SpriteComponent? sprite)) { sprite.Visible = false; } }); var sEntityManager = server.ResolveDependency <IServerEntityManager>(); var sPlayerManager = server.ResolveDependency <IPlayerManager>(); await server.WaitPost(() => { if (sEntityManager.TryGetComponent(sPlayerManager.ServerSessions.Single().AttachedEntity !, out SpriteComponent? sprite)) { sprite.Visible = false; } }); await RunTicksSync(client, server, 10); await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); var sMapManager = server.ResolveDependency <IMapManager>(); var tilePainter = new TilePainter(client, server); var entityPainter = new GridPainter(client, server); IMapGrid[] grids = null !; await server.WaitPost(() => { var playerEntity = sPlayerManager.ServerSessions.Single().AttachedEntity; if (playerEntity.HasValue) { sEntityManager.DeleteEntity(playerEntity.Value); } grids = sMapManager.GetAllMapGrids(new MapId(1)).ToArray(); foreach (var grid in grids) { grid.WorldRotation = Angle.Zero; } }); await RunTicksSync(client, server, 10); await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); foreach (var grid in grids) { var tileXSize = grid.TileSize * TilePainter.TileImageSize; var tileYSize = grid.TileSize * TilePainter.TileImageSize; var bounds = grid.LocalBounds; var left = bounds.Left; var right = bounds.Right; var top = bounds.Top; var bottom = bounds.Bottom; var w = (int)Math.Ceiling(right - left) * tileXSize; var h = (int)Math.Ceiling(top - bottom) * tileYSize; var gridCanvas = new Image <Rgba32>(w, h); await server.WaitPost(() => { tilePainter.Run(gridCanvas, grid); entityPainter.Run(gridCanvas, grid); gridCanvas.Mutate(e => e.Flip(FlipMode.Vertical)); }); yield return(gridCanvas); } // We don't care if it fails as we have already saved the images. try { await OneTimeTearDown(); } catch { // ignored } }