All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.kaisle.util.ReplayRetriever Maven / Gradle / Ivy

There is a newer version: 1.0.4
Show newest version
package com.github.kaisle.util;

import com.github.kaisle.data.ReplayResponse;
import org.apache.commons.io.FileUtils;
import org.eclipse.jetty.util.log.Log;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

/**
 * Created by Anders Borum on 03-06-2015.
 */
public class ReplayRetriever {

    private final org.slf4j.Logger log = LoggerFactory.getLogger(RuntimeUtil.class.getPackage().getClass());

    private int maxAttempts;
    private int timeout;
    private TimeUnit timeUnit;

    /**
     * A retriever that fetches replays by using a Steam bot.
     * @param maxAttempts The max amount of times the retriever should call the Game Coordinator before terminating. 5 should do in most cases.
     * @param timeout The amount of time to wait for a response. 5 seconds should do in most cases.
     * @param timeUnit The time unit for the timeout.
     */
    public ReplayRetriever(int maxAttempts, int timeout, TimeUnit timeUnit) {
        this.maxAttempts = maxAttempts;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
    }
    
    public void getReplay(String matchId) {
    	//ReplayResponse replayResponse = getReplaySalt(matchId);
    }

    /**
     * Retrieve the replay salt for a given match.
     * @param matchId The match id of the match.
     */
    public List getReplaySalt(List matchId) {
        String workingDir = FileUtil.getWorkingDirectory();
        try {
            FileUtils.copyInputStreamToFile(this.getClass().getClassLoader().getResourceAsStream("/" +  NodeDotaDefines.execution_file_name), new File(workingDir + "/" + NodeDotaDefines.execution_file_name));
            FileUtils.copyInputStreamToFile(this.getClass().getClassLoader().getResourceAsStream("/" +  NodeDotaDefines.config_file_name), new File(workingDir + "/" + NodeDotaDefines.config_file_name));
            FileUtils.copyInputStreamToFile(this.getClass().getClassLoader().getResourceAsStream("/" + "sentry"), new File(workingDir + "/" + "sentry"));
            FileUtils.copyInputStreamToFile(this.getClass().getClassLoader().getResourceAsStream("/" + "servers"), new File(workingDir + "/" + "servers"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //NumberUtil.evaluateString(matchId);
        String[] commands = {"node", NodeDotaDefines.execution_file_name};
        File directory = new File(workingDir);
        log.info("Adding requests.");
        addMatchDetailsRequests(matchId); // Add requests to node-dota.js.

        RuntimeUtil runtimeUtil = new RuntimeUtil();
        ProcessBuilder process = runtimeUtil.buildProcess(commands, directory); // Build the process
        for (int i = 0; i < maxAttempts; i++) {
            List input = runtimeUtil.executeWithTimeout(process, timeout, timeUnit);
            if (input.size() < 200) { // The request failed since the console input is not big enough to represent a valid response.
                try {
                    log.info("Request failed, trying again.");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                continue;
            }
            HashMap values = new HashMap();
            List replayResponses = new ArrayList();
            for (String inputLine : input) { // Loop through the console input and store the relevant data in a map
                if (inputLine.contains("cluster")) {
                    values.put("cluster", inputLine.substring(15, inputLine.length() - 1));
                }
                else if (inputLine.contains("matchId")) {
                    values.put("matchId", inputLine.substring(16, inputLine.length() - 2));
                }
                else if (inputLine.contains("replaySalt")) {
                    values.put("replaySalt", inputLine.substring(inputLine.indexOf(":") + 2, inputLine.length() - 1));
                }
                else if (inputLine.contains("replayState")) {

                    values.put("replayState", inputLine.substring(inputLine.indexOf(":") + 3, inputLine.length() - 2));
                    if (values.get("replayState").equals("REPLAY_EXPIRED")) {
                        replayResponses.add(new ReplayResponse(values.get("replaySalt"), false, values.get("cluster"), values.get("matchId"))); // Reached end of response, build new object containing the data
                    }
                    else if (values.get("replayState").equals("REPLAY_AVAILABLE")) {
                        replayResponses.add(new ReplayResponse(values.get("replaySalt"), true, values.get("cluster"), values.get("matchId")));
                    }
                }
            }
            File nodeDota = new File(workingDir + "/" + NodeDotaDefines.execution_file_name);
            FileUtil.removeLines(nodeDota, "Dota2.matchDetailsRequest"); // Clean up file
            return replayResponses;

        }

        return null;
    }

    /**
     * Add a single matchdetails request to the node-dota.js file.
     * @param matchId
     */
    public void addMatchDetailsRequest(String matchId) {
        String workingDir = FileUtil.getWorkingDirectory();
        File nodeDota = new File(workingDir + "/" + NodeDotaDefines.execution_file_name);
        String requestLine = "            " + NodeDotaDefines.match_details_request + "(" + matchId + ");";
        FileUtil.modifyLine(nodeDota, requestLine, NodeDotaDefines.match_details_request_line_number);
    }

    /**
     * Add several matchdetails requests to the node-dota.js file.
     * @param matchIds
     */
    public void addMatchDetailsRequests(List matchIds) {
        String workingDir = FileUtil.getWorkingDirectory();
        File nodeDota = new File(workingDir + "/" + NodeDotaDefines.execution_file_name);
        List inputLines = new ArrayList();
        for (String matchId: matchIds) {
            inputLines.add("            " + NodeDotaDefines.match_details_request + "(" + matchId + ");");
        }
        FileUtil.appendLinesToMiddle(nodeDota, inputLines, NodeDotaDefines.match_details_request_line_number);

    }

    public void getReplay(String path, ReplayResponse replayResponse) {
        String urlString = "http://replay" + replayResponse.getCluster() + ".valve.net/570/" + replayResponse.getReplaySalt() + "_" + replayResponse.getMatch_id() + ".dem.bz2";
        try {
            URL url = new URL(urlString);
            HttpURLConnection con = (HttpURLConnection) (url).openConnection();
            con.connect();
            FileUtils.copyInputStreamToFile(con.getInputStream(), new File(path));
            con.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy