Skip to content

Instantly share code, notes, and snippets.

@thquinn
Last active August 9, 2021 16:58
Show Gist options
  • Save thquinn/da8c0a363efd503fb731e2443266fd7a to your computer and use it in GitHub Desktop.
Save thquinn/da8c0a363efd503fb731e2443266fd7a to your computer and use it in GitHub Desktop.
Scrapes the MTGO trophy leaderboard and keeps a Gist updated
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