package games.strategy.engine.pbem;
import java.io.File;
import java.util.Collection;
import java.util.TreeSet;
import java.util.Vector;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import games.strategy.debug.ClientLogger;
import games.strategy.engine.data.GameData;
import games.strategy.engine.data.PlayerID;
import games.strategy.engine.data.Territory;
import games.strategy.engine.framework.startup.ui.editors.EditorPanel;
import games.strategy.engine.framework.startup.ui.editors.IBean;
import games.strategy.engine.framework.startup.ui.editors.MicroWebPosterEditor;
import games.strategy.engine.framework.system.HttpProxy;
import games.strategy.engine.stats.AbstractStat;
import games.strategy.net.OpenFileUtility;
import games.strategy.triplea.Properties;
import games.strategy.triplea.attachments.TerritoryAttachment;
import games.strategy.triplea.delegate.Matches;
import games.strategy.triplea.help.HelpSupport;
import games.strategy.util.Util;
public class TripleAWebPoster implements IWebPoster {
private static final long serialVersionUID = -3013355800798928625L;
private String m_host = MicroWebPosterEditor.HTTP_BLANK;
private Vector<String> m_allHosts = new Vector<>();
private String m_siteId = "";
private boolean m_mailSaveGame = true;
private String m_gameName = "";
private transient String m_serverMessage = "";
private transient File m_saveGameFile = null;
private transient String m_saveGameFileName = "";
private String[] parties;
private static Collection<String> getAlliances(final GameData gameData) {
final Collection<String> rVal = new TreeSet<>();
for (final String alliance : gameData.getAllianceTracker().getAlliances()) {
if (gameData.getAllianceTracker().getPlayersInAlliance(alliance).size() > 1) {
rVal.add(alliance);
}
}
return rVal;
}
private static String getProductionData(final GameData gameData) {
gameData.acquireReadLock();
try {
final Collection<String> alliances = getAlliances(gameData);
final ProductionStat prodStat = new ProductionStat();
String result = "";
for (final String alliance : alliances) {
final int value = (int) prodStat.getValue(alliance, gameData);
if (!result.equals("")) {
result += ";";
}
result += alliance + "=" + value;
}
return result;
} finally {
gameData.releaseReadLock();
}
}
@Override
public boolean postTurnSummary(final GameData gameData, final String turnSummary, final String player,
final int round) {
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
.addTextBody("siteid", m_siteId);
if (gameData != null) {
builder.addTextBody("production", getProductionData(gameData));
}
builder
.addTextBody("gamename", m_gameName)
.addTextBody("player", player)
.addTextBody("summary", turnSummary)
.addTextBody("round", "" + round)
.addTextBody("sendmail", m_mailSaveGame ? "true" : "false");
if (m_saveGameFile != null) {
builder.addBinaryBody("userfile", m_saveGameFile, ContentType.APPLICATION_OCTET_STREAM, m_saveGameFileName);
}
m_serverMessage = executePost(m_host, "upload.php", builder.build());
if (!m_serverMessage.toLowerCase().contains("success")) {
System.out.println("Unknown error, site response: " + m_serverMessage);
return false;
}
} catch (final Exception e) {
m_serverMessage = e.getMessage();
ClientLogger.logQuietly(e);
return false;
}
return true;
}
public static String executePost(final String host, final String path, final HttpEntity entity) throws Exception {
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(getHostUrlPrefix(host) + path);
HttpHost hostConfig = new HttpHost(host);
HttpProxy.addProxy(httpPost);
httpPost.setEntity(entity);
try (CloseableHttpResponse response = client.execute(hostConfig, httpPost)) {
final int status = response.getStatusLine().getStatusCode();
if (status != 200) {
throw new Exception("Post command to " + host + " failed, the server returned status: " + status);
}
return Util.getStringFromInputStream(response.getEntity().getContent());
}
}
}
@Override
public boolean getMailSaveGame() {
return m_mailSaveGame;
}
@Override
public void setMailSaveGame(final boolean mail) {
m_mailSaveGame = mail;
}
@Override
public void addSaveGame(final File saveGame, final String fileName) {
m_saveGameFile = saveGame;
m_saveGameFileName = fileName;
}
@Override
public EditorPanel getEditor() {
return new MicroWebPosterEditor(this, parties);
}
@Override
public boolean sameType(final IBean other) {
return getClass() == other.getClass();
}
@Override
public String getTestMessage() {
return "Testing, this will take a couple of seconds...";
}
@Override
public String getServerMessage() {
return m_serverMessage;
}
@Override
public String getHelpText() {
return HelpSupport.loadHelp("tripleAMicroWebsite.html");
}
@Override
public IWebPoster doClone() {
final TripleAWebPoster clone = new TripleAWebPoster();
clone.setMailSaveGame(getMailSaveGame());
clone.setHost(getHost());
clone.setAllHosts(new Vector<>(getAllHosts()));
clone.setSiteId(getSiteId());
clone.setGameName(getGameName());
return clone;
}
@Override
public String getDisplayName() {
return "TripleA Micro Web Site";
}
@Override
public String getSiteId() {
return m_siteId;
}
@Override
public String getHost() {
return m_host;
}
@Override
public Vector<String> getAllHosts() {
return m_allHosts;
}
private static String getHostUrlPrefix(final String host) {
if (host.endsWith("/")) {
return host;
} else {
return host + "/";
}
}
@Override
public String getGameName() {
return m_gameName;
}
@Override
public void setSiteId(final String siteId) {
m_siteId = siteId;
}
@Override
public void setGameName(final String gameName) {
m_gameName = gameName;
}
@Override
public void setHost(final String host) {
m_host = getHostUrlPrefix(host);
}
@Override
public void setAllHosts(final Vector<String> hosts) {
m_allHosts = hosts;
}
@Override
public void addToAllHosts(final String host) {
final String hostToAdd = getHostUrlPrefix(host);
m_allHosts.remove(hostToAdd);
if (m_allHosts.size() > 10) {
m_allHosts.subList(10, m_allHosts.size()).clear();
}
m_allHosts.add(0, hostToAdd);
}
@Override
public void viewSite() {
OpenFileUtility.openURL(getHost());
}
public void setParties(final String[] parties) {
this.parties = parties;
}
@Override
public void clearSensitiveInfo() {
m_allHosts.clear();
}
}
class ProductionStat extends AbstractStat {
@Override
public String getName() {
return "Production";
}
@Override
public double getValue(final PlayerID player, final GameData data) {
int rVal = 0;
for (final Territory place : data.getMap().getTerritories()) {
final TerritoryAttachment ta = TerritoryAttachment.get(place);
/*
* Match will Check if terr is a Land Convoy Route and check ownership of neighboring Sea Zone, and also check if
* territory is
* contested
*/
if (ta != null && player != null && player.equals(place.getOwner())
&& Matches.territoryCanCollectIncomeFrom(player, data).match(place)) {
rVal += ta.getProduction();
}
}
rVal *= Properties.getPU_Multiplier(data);
return rVal;
}
}