CH Optimal Raid

by Bateman

HTML

<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"></script>
<script src="https://cdn.rawgit.com/protobi/lambertw/master/lambertw.js"></script>
<div class="container">
  <div class="row">
    <div class="col s12">
      <h1>Optimal Raid</h1>
    </div>
  </div>

  <div class="row">
    <div class="input-field col s9 m10">
      <input type="text" name="" id="savegame">
      <label for="savegame">Savegame goes here</label>
    </div>

    <div class="col s3 m2 input-field">
      <input type="text" id="guildName">
      <label for="guildName" id="guildNameLbl">Guild name</label>
    </div>
  </div>

  <div class="row">
    <div class="col s12">
      <table>
        <colgroup>
          <col style="width: 200px">
          <col>
        </colgroup>
        <thead style="display: none">
          <tr>
            <th>Key</th>
            <th>Value</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Lifetime HS</td>
            <td>
              <span id="lifetimeHs"></span>
            </td>
          </tr>
          <tr>
            <td>Optimal Raid</td>
            <td>
              <span id="optimalLevel"></span>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <div class="row">
    <div class="col s12 input-field">
      <textarea id="raidLink" cols="30" rows="10" class="materialize-textarea"></textarea>
      <label for="raidLink" id="raidLinkLbl">Raid link</label>
    </div>
  </div>
  
  <div class="row">
    <div class="col s12"><a target="_blank" id="raidLinkAnchor">Press to win</a></div>
  </div>


</div>

TypeScript

interface JQuery {
  trigger(name: string);
  (selector: string): JQuery;
}

interface Savegame {
  uniqueId: string;
  passwordHash: string;
  totalHeroSoulsFromAscensions: number;
}

declare var $: JQuery;
declare var gsl_sf_lambert_Wm1: (x: number) => number;

declare var savegame: HTMLInputElement;
declare var guildName: HTMLInputElement;
declare var guildNameLbl: HTMLLabelElement;
declare var lifetimeHs: HTMLSpanElement;
declare var optimalLevel: HTMLSpanElement;
declare var raidLink: HTMLTextAreaElement;
declare var raidLinkLbl: HTMLLabelElement;
declare var raidLinkAnhor: HTMLAnchorElement;


function decode(save: string): Savegame {
  const ANTI_CHEAT_CODE = 'Fe12NAfA3R6z4k0z';

  if (save.indexOf(ANTI_CHEAT_CODE) > -1) {
    const result = save.split(ANTI_CHEAT_CODE);
    save = '';
    for (let i = 0; i < result[0].length; i += 2) {
      save += result[0][i];
    }
    const data = JSON.parse(atob(save));
    return data;
  } else {
    return null;
  }
}

class Immortal {
  constructor(public level: number) {}

  get hp() {
    return 500 * Math.pow(2, this.level);
  }

  static getLevel(hs) {
    const inner = -(11 * Math.log(2)) / (40960 * hs);
    const w = gsl_sf_lambert_Wm1(inner);
    return Math.ceil(-w / Math.log(2) - 10);
  }
}

var data: Savegame, level: number;

function makeRaidLink(data: Savegame, level: number, guildName: string) {
  if (!data || !level || !guildName) {
    return;
  }

  const baseLink = 'http://clickerheroes-savedgames3-747864888.us-east-1.elb.amazonaws.com/clans/sendTitanDamage.php?';

  const immortal = new Immortal(level);

  const params = {
    levelStarted: level,
    levelReached: level,
    day: 'today',
    purchasedFight: 0,
    guildName: guildName,
    timestamp: Date.now() / 1000,
    uid: data.uniqueId,
    passwordHash: data.passwordHash,
    damageDone: immortal.hp.toExponential(1).replace('+', '')
  };

  const paramsString = Object.keys(params).map(key => `${key}=${params[key]}`).join('&');

  const...