Skip to content

Instantly share code, notes, and snippets.

@IceCruelStuff
Forked from jomo/Minecraft Accounts.md
Created June 8, 2021 02:08
Show Gist options
  • Save IceCruelStuff/7df967b62541f3eb8dda295be4e6eab0 to your computer and use it in GitHub Desktop.
Save IceCruelStuff/7df967b62541f3eb8dda295be4e6eab0 to your computer and use it in GitHub Desktop.

Revisions

  1. @jomo jomo renamed this gist Dec 19, 2020. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. @jomo jomo revised this gist Jan 23, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion track.js
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@ function track(name, a, b, lastfail) {

    if(a === b) {
    check(name, a, function(ok) {
    if (ok && lastfail < a) {
    if (ok && lastfail === a-1) {
    console.log("found:", new Date(a*1000).toUTCString());
    } else {
    if (lastfail === 0) {
  3. @jomo jomo created this gist Jan 23, 2016.
    68 changes: 68 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    Tracks down when a Minecraft account was created.

    # How it works

    Mojang has an API endpoint for usernames:
    ```
    https://api.mojang.com/users/profiles/minecraft/<name>?at=<timestamp>
    ```
    It can be used to find the UUID of an account, by username it used at the given time.
    It returns either `200 OK` or `204 No Content` – indicating that the username was not in use at the time.

    That means we can find out whether an account existed at a specific time.
    We always look at a range of time, starting with Jan 2010 - now.
    The range is then split in half, and a request is made for the intermediate time.
    200 means the account already existed, thus created in the first half; 204 means the account did not yet exist, thus created in the second half.
    This step is repeated with the respective time range until the exact second is found.
    *See also: [Babylonian Method](https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)*

    Currently it needs about 27 requests to find the creation date.

    # Caveats

    This works with nodejs, however it's not a proper module and the `track` function doesn't have a callback.

    Due to Mojang being Mojang, the API endpoint is horribly broken:

    - It does not work with legacy accounts
    - It does not work with accounts that have been renamed
    - Except sometimes™
    - The result may be inaccurate though

    # Example usage

    The arrow indicates in which half of the time range the account was created.

    ```
    > track("dinnerbone")
    range: 1263146630 <-| 1453566749
    range: 1263146630 <-| 1358356689
    range: 1263146630 <-| 1310751659
    range: 1263146630 |-> 1286949144
    range: 1275047888 |-> 1286949144
    range: 1280998517 |-> 1286949144
    range: 1283973831 <-| 1286949144
    range: 1283973831 |-> 1285461487
    range: 1284717660 |-> 1285461487
    range: 1285089574 |-> 1285461487
    range: 1285275531 |-> 1285461487
    range: 1285368510 |-> 1285461487
    range: 1285414999 <-| 1285461487
    range: 1285414999 |-> 1285438243
    range: 1285426622 <-| 1285438243
    range: 1285426622 <-| 1285432432
    range: 1285426622 |-> 1285429527
    range: 1285428075 <-| 1285429527
    range: 1285428075 |-> 1285428801
    range: 1285428439 |-> 1285428801
    range: 1285428621 <-| 1285428801
    range: 1285428621 |-> 1285428711
    range: 1285428667 |-> 1285428711
    range: 1285428690 |-> 1285428711
    range: 1285428701 |-> 1285428711
    range: 1285428707 <-| 1285428711
    range: 1285428707 <-| 1285428709
    range: 1285428707 <-| 1285428708
    found: Sat, 25 Sep 2010 15:31:47 GMT
    ```
    36 changes: 36 additions & 0 deletions track.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    function check(name, num, callback) {
    https.get("https://api.mojang.com/users/profiles/minecraft/" + name + "?at=" + num, function(resp) {
    callback(resp.statusCode === 200);
    });
    };

    function track(name, a, b, lastfail) {
    a = a || 1263146630; // notch sign-up
    b = b || Math.floor(Date.now()/1000);
    lastfail = lastfail || 0;

    if(a === b) {
    check(name, a, function(ok) {
    if (ok && lastfail < a) {
    console.log("found:", new Date(a*1000).toUTCString());
    } else {
    if (lastfail === 0) {
    console.log("target is <= " + a);
    } else {
    console.log("target is > " + a);
    }
    }
    });
    } else {
    var mid = a + Math.floor((b-a)/2);
    check(name, mid, function(ok) {
    if (ok) {
    console.log("range: " + a + "\t<-| \t" + b);
    track(name, a, mid, lastfail);
    } else {
    console.log("range: " + a + "\t |->\t" + b);
    track(name, mid+1, b, mid);
    }
    });
    }
    }