private static void MainWorkingBody() { using (WebsocketWrapper wrapper = new WebsocketWrapper(logger, false)) { wrapper.OnConnectionLost += (o, e) => mapUpdatedResetEvent.Reset(); cache.Wrapper = wrapper; logger.LogDebug("MainWorkingBody(): downloading chunks"); cache.DownloadChunks(); wrapper.OnPixelChanged += LogPixelChanged; placed.Clear(); bool wasChanged; do { logger.LogDebug("MainWorkingBody(): main body cycle started"); wasChanged = false; repeatingFails = false; foreach (Pixel pixel in pixelsToBuild) { mapUpdatedResetEvent.WaitOne(); (short x, short y, EarthPixelColor color) = pixel; EarthPixelColor actualColor = cache.GetPixelColor(x, y); if (!IsCorrectPixelColor(actualColor, color)) { logger.LogDebug($"MainWorkingBody(): {pixel} - wrong color ({actualColor})"); wasChanged = true; bool success; placed.Add(pixel); do { wrapper.WaitWebsocketConnected(); success = HttpWrapper.PlacePixel(x, y, color, out double cd, out double totalCd, out string error); if (success) { logger.LogPixel($"{(cd == 4 ? "P" : "Rep")}laced pixel:", DateTime.Now, MessageGroup.Pixel, x, y, color); Thread.Sleep(TimeSpan.FromSeconds(totalCd < 53 ? 1 : cd)); } else { logger.LogDebug($"MainWorkingBody(): pixel placing handled error {error}"); if (error == "captcha") { ProcessCaptcha(); } else { logger.Log($"Failed to place pixel: {error}", MessageGroup.PixelFail); } logger.LogDebug($"MainWorkingBody(): sleep {cd:F2} seconds"); Thread.Sleep(TimeSpan.FromSeconds(cd)); } } while (!success); } } if (options.DefenseMode) { if (!wasChanged) { logger.Log("Image is intact, waiting...", MessageGroup.Info); lock (waitingGriefLock) { logger.LogDebug("MainWorkingBody(): acquiring grief waiting lock"); gotGriefed.Reset(); gotGriefed.WaitOne(); } logger.LogDebug("MainWorkingBody(): got griefed"); Thread.Sleep(new Random().Next(500, 3000)); } } } while (options.DefenseMode || wasChanged); logger.Log("Building is finished", MessageGroup.Info); return; } }