using System; using System.IO; using System.Globalization; const string targetDateStr = "03-11-2025"; const int startId = 92571453; const int delayMs = 500; bool exportProfiles = true; const string outPath = "io/date_range.tsv"; DateTime targetDate = DateTime.ParseExact(targetDateStr, "dd-MM-yyyy", CultureInfo.InvariantCulture).Date; Log($"Searching for {targetDateStr}"); int id = startId; int step = 100000; int foundId = -1; int prevDaysDiff = 0; while (foundId == -1 && step >= 100) { try { var profile = GetProfile(id); DateTime created = DateTime.ParseExact(profile.Created, "dd-MM-yyyy", CultureInfo.InvariantCulture).Date; int daysDiff = (targetDate - created).Days; Log($"ID {id}: {created:dd-MM-yyyy} ({daysDiff}d) step={step}"); if (created == targetDate) { foundId = id; break; } if (prevDaysDiff != 0 && ((prevDaysDiff > 0 && daysDiff < 0) || (prevDaysDiff < 0 && daysDiff > 0))) { step = Math.Max(step / 2, 100); Log($"Crossed over! step={step}"); } else { if (Math.Abs(daysDiff) < 7) step = 1000; else if (Math.Abs(daysDiff) < 30) step = 10000; else step = 100000; } prevDaysDiff = daysDiff; id += daysDiff > 0 ? step : -step; } catch { Log($"Error at {id}, skipping"); id += step > 0 ? 1 : -1; step = Math.Max(Math.Abs(step) / 2, 100); } Delay(delayMs); } if (foundId == -1) { Log("Date not found"); return; } Log($"Found {foundId}, finding first..."); int firstId = foundId; step = -50000; while (Math.Abs(step) >= 1) { int checkId = firstId + step; if (checkId < 1) { step = step / 2; continue; } try { var profile = GetProfile(checkId); DateTime created = DateTime.ParseExact(profile.Created, "dd-MM-yyyy", CultureInfo.InvariantCulture).Date; Log($"First check {checkId}: {created:dd-MM-yyyy} step={step}"); if (created == targetDate) { firstId = checkId; Log($">> New first: {firstId}"); } else if (created < targetDate) { step = step / 2; Log($"Too old, step={step}"); } else { firstId += step; } } catch { Log($"Error {checkId}, reducing step"); step = step / 2; } Delay(delayMs); } Log($"Finding last from {firstId}..."); int lastId = firstId; step = 50000; while (Math.Abs(step) >= 1) { int checkId = lastId + step; try { var profile = GetProfile(checkId); DateTime created = DateTime.ParseExact(profile.Created, "dd-MM-yyyy", CultureInfo.InvariantCulture).Date; Log($"Last check {checkId}: {created:dd-MM-yyyy} step={step}"); if (created == targetDate) { lastId = checkId; Log($">> New last: {lastId}"); } else if (created > targetDate) { step = step / 2; Log($"Too new, step={step}"); } else { lastId += step; } } catch { Log($"Error {checkId}, reducing step"); step = step / 2; } Delay(delayMs); } int total = lastId - firstId + 1; Log($"Range: {firstId}-{lastId} ({total} accounts)"); if (!exportProfiles) { Log("Export disabled, done"); return; } using (var outs = new StreamWriter(outPath)) { outs.WriteLine("ID\tName\tCreated\tLastLogin\tActivityPts\tFriends"); int exported = 0; int skipped = 0; for (int exportId = firstId; exportId <= lastId; exportId++) { try { var profile = GetProfile(exportId); DateTime created = DateTime.ParseExact(profile.Created, "dd-MM-yyyy", CultureInfo.InvariantCulture).Date; if (created != targetDate) { Log($"Wrong date at {exportId}, stopping"); break; } string lastLogin = profile.LastLogin < TimeSpan.Zero ? "invisible" : (DateTime.Now - profile.LastLogin).ToString("yyyy/MM/dd HH:mm:ss"); outs.WriteLine($"{profile.Id}\t{profile.Name}\t{profile.Created}\t{lastLogin}\t{profile.ActivityPoints}\t{profile.Friends}"); exported++; if (exported % 100 == 0) Log($"Exported {exported}/{total}"); } catch { skipped++; } Delay(delayMs); } Log($"Done: {exported} exported, {skipped} skipped"); }