Last active
August 9, 2021 16:58
-
-
Save thquinn/da8c0a363efd503fb731e2443266fd7a to your computer and use it in GitHub Desktop.
Scrapes the MTGO trophy leaderboard and keeps a Gist updated
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Runtime.InteropServices; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using ManagedWinapi; // this can be found here: http://mwinapi.sourceforge.net/ | |
using System.Windows.Forms; | |
using System.Drawing; | |
using Octokit; // this is from NuGet | |
using System.Threading; | |
using System.Diagnostics; | |
namespace MTGOTrophyScrape { | |
class Program { | |
static string GIST_ID = "Gist ID goes here"; | |
static GitHubClient gitHubClient; | |
static void Main(string[] args) { | |
Console.WindowWidth = 80; | |
Console.BufferWidth = Console.WindowWidth; | |
gitHubClient = new GitHubClient(new ProductHeaderValue("Github app name goes here, or seemingly just anything really")); | |
gitHubClient.Credentials = new Credentials("Github personal access token goes here"); | |
List<Tuple<string, int>> leaderboard = GetLeaderboard(); | |
bool updated = UpdateGist(leaderboard, gitHubClient.Gist.Get(GIST_ID).GetAwaiter().GetResult().Files.First().Value.Content); | |
if (updated) { | |
Log("Leaderboard has changed since last run. Updated."); | |
} else { | |
Log("Leaderboard has not changed since last run."); | |
} | |
while (true) { | |
Thread.Sleep(1000); | |
List<Tuple<string, int>> newLeaderboard; | |
try { | |
newLeaderboard = GetLeaderboard(); | |
} catch (Exception) { | |
Log("Can't find MTGO window."); | |
continue; | |
} | |
if (newLeaderboard.SequenceEqual(leaderboard)) { | |
continue; | |
} | |
Log("Leaderboard has changed! Updating..."); | |
leaderboard = newLeaderboard; | |
UpdateGist(leaderboard); | |
Log("Update complete."); | |
} | |
} | |
static List<Tuple<string, int>> GetLeaderboard() { | |
List<Tuple<string, int>> leaderboard = new List<Tuple<string, int>>(); | |
// You can find the location of the window programmatically and use offsets, or just do | |
// what I did here and find where the leaderboard rows are manually. | |
var list = ManagedWinapi.Accessibility.SystemAccessibleObject.FromPoint(-1181, 710).Parent; // first leaderboard row | |
if (list.Window.Title != "Magic: The Gathering Online") { | |
throw new Exception("Can't find top half of leaderboard."); | |
} | |
foreach (var child in list.Children) { | |
string username = child.Children[1].Name; | |
int trophies = int.Parse(child.Children[2].Name); | |
leaderboard.Add(new Tuple<string, int>(username, trophies)); | |
} | |
list = ManagedWinapi.Accessibility.SystemAccessibleObject.FromPoint(-1181, 1115); // sixth leaderboard row (first below the line) | |
if (list.Window.Title != "Magic: The Gathering Online") { | |
throw new Exception("Can't find bottom half of leaderboard."); | |
} | |
foreach (var child in list.Children) { | |
string username = child.Children[1].Name; | |
int trophies = int.Parse(child.Children[2].Name); | |
leaderboard.Add(new Tuple<string, int>(username, trophies)); | |
} | |
// The 20th row of the leaderboard is unreliable. | |
leaderboard.RemoveRange(19, leaderboard.Count - 19); | |
return leaderboard; | |
} | |
static bool UpdateGist(List<Tuple<string, int>> entries, String oldGist = "") { | |
StringBuilder sb = new StringBuilder(); | |
foreach (var entry in entries) { | |
sb.Append(entry.Item1 + '|' + entry.Item2 + '\n'); | |
} | |
string newGist = sb.ToString(); | |
if (oldGist == newGist) { | |
return false; | |
} | |
GistUpdate update = new GistUpdate(); | |
GistFileUpdate gfu = new GistFileUpdate(); | |
gfu.Content = sb.ToString(); | |
update.Files.Add("mtgo_modern_trophies.txt", gfu); | |
Gist task = gitHubClient.Gist.Edit(GIST_ID, update).GetAwaiter().GetResult(); | |
return true; | |
} | |
static void Log(string s) { | |
Console.Write(DateTime.Now.ToString("MM/dd/yyyy h:mm tt")); | |
Console.WriteLine(s); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment