Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.net.HttpURLConnection;
- import java.net.SocketTimeoutException;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- /**
- * A program that can be used to collect bird coins for an Angry Birds Friends account.
- *
- * <p>Usage:
- *
- * <ol>
- * <li>Comment out the redeemGifts() method, and run the program to see how many gifts you have.
- * <li>Configure the number of gifts to redeem, number of connections, and authentication params.
- * <li>Run again with redeemGifts() uncommented to perform the collection.
- * </ol>
- */
- public class BirdCoins {
- /**
- * Number of gifts to redeem with this collection. If this is less than the total number of
- * available gifts, the ones closest to expiration will be redeemed first.
- */
- private static final int GIFTS_TO_REDEEM = 1;
- /**
- * The number of simultaneous connections to make when redeeming gifts. A higher number will
- * generally result in a bigger collection. Depending on your computer specs and network
- * connection speed, you might want to set this somewhere between about 100 and 1000.
- */
- private static final int NUM_CONNECTIONS = 150;
- /**
- * Authentication query parameters to append to requests. HTTP 403 is returned if these are not
- * included. To learn how to find the auth params for your account, see
- * https://docs.google.com/document/d/1uBLHVlG-t_fOlQYXjnMkIIEqOWyAvoF-jBXDS1rXCFY/edit
- */
- static final String AUTH_PARAMS = "hash=123-456&st=123abcDEF";
- private static final String USER_AGENT =
- "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
- private static final String URL_BASE = "https://angrybirds-facebook.appspot.com/";
- private static final String ACCEPT_GIFTS_URL = URL_BASE + "acceptrequest/";
- private static final String READ_GIFTS_URL = URL_BASE + "/getrequests";
- /**
- * Timeout in ms for opening a collect connection. Most of the time it takes roughly 40ms to open
- * a connection, but occasionally it takes many seconds. Give each connection CONNECT_TIMEOUT_MS
- * before just giving up waiting and starting a new one instead. This makes the time to open
- * connections 2-3 times faster in practice.
- */
- private static final int CONNECT_TIMEOUT_MS = 100;
- /** Collection read timeout. A value of 0 means to let the collection take as long as it needs. */
- private static final int READ_TIMEOUT_MS = 0;
- public static void main(String[] args) throws Exception {
- System.out.println("Number of available gifts: " + parseGifts(readGifts()).length);
- // redeemGifts();
- }
- private static void redeemGifts() throws Exception {
- String postBody = getPostBody();
- URL acceptUrl = new URL(ACCEPT_GIFTS_URL + "?" + AUTH_PARAMS);
- HashMap<HttpURLConnection, OutputStream> connections = new HashMap<>();
- System.out.println("About to open connections");
- long t0 = System.currentTimeMillis();
- int numTimeout = 0;
- while (connections.size() < NUM_CONNECTIONS) {
- HttpURLConnection con = (HttpURLConnection) acceptUrl.openConnection();
- con.setConnectTimeout(CONNECT_TIMEOUT_MS);
- con.setReadTimeout(READ_TIMEOUT_MS);
- long t = System.currentTimeMillis();
- try {
- OutputStream os = getOutputStream(con); // this blocks for ~40ms
- System.out.println(
- "Took this many ms to open one connection: " + (System.currentTimeMillis() - t));
- connections.put(con, os);
- } catch (SocketTimeoutException ste) {
- numTimeout++;
- }
- }
- System.out.println("This many connections timed out: " + numTimeout);
- long t1 = System.currentTimeMillis();
- System.out.println("Took this many ms: " + (t1 - t0));
- System.out.println();
- System.out.println("About to write");
- for (Map.Entry<HttpURLConnection, OutputStream> connection : connections.entrySet()) {
- OutputStream os = connection.getValue();
- os.write(postBody.getBytes());
- }
- long t2 = System.currentTimeMillis();
- System.out.println("Took this many ms: " + (t2 - t1));
- System.out.println();
- System.out.println("About to flush");
- for (Map.Entry<HttpURLConnection, OutputStream> connection : connections.entrySet()) {
- OutputStream os = connection.getValue();
- os.flush();
- }
- long t3 = System.currentTimeMillis();
- System.out.println("Took this many ms: " + (t3 - t2));
- System.out.println();
- System.out.println("About to close");
- for (Map.Entry<HttpURLConnection, OutputStream> connection : connections.entrySet()) {
- OutputStream os = connection.getValue();
- os.close();
- }
- final long t4 = System.currentTimeMillis();
- System.out.println("Took this many ms: " + (t4 - t3));
- System.out.println();
- System.out.println("About to create threads");
- for (Map.Entry<HttpURLConnection, OutputStream> connection : connections.entrySet()) {
- final HttpURLConnection httpUrlConnection = connection.getKey();
- Thread t = new Thread() {
- HttpURLConnection con = httpUrlConnection;
- public void run() {
- try {
- int responseCode = con.getResponseCode();
- System.out.println(responseCode + " at time " + (System.currentTimeMillis() - t4));
- } catch (Exception e) {
- // e.printStackTrace();
- }
- }
- };
- t.start();
- }
- long t5 = System.currentTimeMillis();
- System.out.println("Took this many ms: " + (t5 - t4));
- System.out.println();
- }
- private static String getPostBody() throws Exception {
- List<String> gifts = getOldestGifts(parseGifts(readGifts()), GIFTS_TO_REDEEM);
- return "[\"" + String.join("\",\"", gifts) + "\"]";
- }
- private static String readGifts() throws Exception {
- String urlString = READ_GIFTS_URL + "?" + AUTH_PARAMS;
- return read(urlString);
- }
- static String read(String urlString) throws Exception {
- URL url = new URL(urlString);
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
- con.setRequestMethod("GET");
- con.setRequestProperty("User-Agent", USER_AGENT);
- int responseCode = con.getResponseCode();
- System.out.println("Sending GET request to URL: " + urlString);
- System.out.println("Response code: " + responseCode);
- BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
- String inputLine;
- StringBuffer response = new StringBuffer();
- while ((inputLine = in.readLine()) != null) {
- response.append(inputLine);
- }
- in.close();
- return response.toString();
- }
- private static String[] parseGifts(String gifts) {
- return parseJson(gifts, "r");
- }
- static String[] parseJson(String gifts, String id) {
- String quotedId = "\"" + id + "\"";
- ArrayList<String> giftsList = new ArrayList<String>();
- String remainingGifts = gifts;
- while (remainingGifts.indexOf(quotedId) != -1) {
- int giftStart = remainingGifts.indexOf(quotedId) + 4 + id.length();
- int giftEnd = giftStart + remainingGifts.substring(giftStart).indexOf("\"");
- giftsList.add(remainingGifts.substring(giftStart, giftEnd));
- remainingGifts = remainingGifts.substring(giftEnd);
- }
- return giftsList.toArray(new String[0]);
- }
- /**
- * Returns the specified number of gifts from the provided list that are the oldest (closest to
- * expiration).
- */
- private static final List<String> getOldestGifts(String[] gifts, int numGiftsToRedeem) {
- List<String> giftsList = Arrays.asList(gifts);
- Collections.sort(giftsList, new Comparator<String>() {
- @Override
- public int compare(String o1, String o2) {
- int year1 = getGiftYear(o1);
- int year2 = getGiftYear(o2);
- int month1 = getGiftMonth(o1);
- int month2 = getGiftMonth(o2);
- int day1 = getGiftDay(o1);
- int day2 = getGiftDay(o2);
- if (year1 < year2) {
- return -1;
- } else if (year1 > year2) {
- return 1;
- } else if (month1 < month2) {
- return -1;
- } else if (month1 > month2) {
- return 1;
- } else if (day1 < day2) {
- return -1;
- } else if (day1 > day2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- if (giftsList.size() > numGiftsToRedeem) {
- return giftsList.subList(0, numGiftsToRedeem);
- }
- return giftsList;
- }
- private static final int getGiftYear(String gift) {
- return Integer.parseInt(gift.substring(gift.length() - 8, gift.length() - 4));
- }
- private static final int getGiftMonth(String gift) {
- return Integer.parseInt(gift.substring(gift.length() - 4, gift.length() - 2));
- }
- private static final int getGiftDay(String gift) {
- return Integer.parseInt(gift.substring(gift.length() - 2, gift.length()));
- }
- private static OutputStream getOutputStream(HttpURLConnection con) throws IOException {
- con.setRequestMethod("POST");
- con.setRequestProperty("user-agent", USER_AGENT);
- con.setRequestProperty("content-type", "application/json; charset=utf-8");
- con.setDoOutput(true);
- return con.getOutputStream();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement