package games.strategy.engine.pbem;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import games.strategy.debug.ClientLogger;
import games.strategy.engine.data.GameData;
import games.strategy.engine.data.PlayerID;
import games.strategy.engine.history.IDelegateHistoryWriter;
import games.strategy.triplea.delegate.remote.IAbstractForumPosterDelegate;
import games.strategy.triplea.ui.MainGameFrame;
import games.strategy.triplea.ui.history.HistoryLog;
import games.strategy.ui.ProgressWindow;
/**
* This class is responsible for posting turn summary and email at the end of each round in a PBEM game.
* A new instance is created at end of turn, based on the Email and a forum poster stored in the game data.
* The needs to be serialized since it is invoked through the IAbstractEndTurnDelegate which require all objects to be
* serializable
* although the PBEM games will always be local
*/
public class PBEMMessagePoster implements Serializable {
public static final String FORUM_POSTER_PROP_NAME = "games.strategy.engine.pbem.IForumPoster";
public static final String EMAIL_SENDER_PROP_NAME = "games.strategy.engine.pbem.IEmailSender";
public static final String WEB_POSTER_PROP_NAME = "games.strategy.engine.pbem.IWebPoster";
public static final String PBEM_GAME_PROP_NAME = "games.strategy.engine.pbem.PBEMMessagePoster";
private static final long serialVersionUID = 2256265436928530566L;
private final IForumPoster m_forumPoster;
private final IEmailSender m_emailSender;
private final IWebPoster m_webSitePoster;
private transient File m_saveGameFile = null;
private transient String m_turnSummary = null;
private transient String m_saveGameRef = null;
private transient String m_turnSummaryRef = null;
private transient String m_emailSendStatus;
private transient String m_webPostStatus;
private transient PlayerID m_currentPlayer;
private final transient GameData m_gameData;
private transient int m_roundNumber;
private transient String m_gameNameAndInfo;
public PBEMMessagePoster(final GameData gameData, final PlayerID currentPlayer, final int roundNumber,
final String title) {
m_gameData = gameData;
m_currentPlayer = currentPlayer;
m_roundNumber = roundNumber;
m_forumPoster = (IForumPoster) gameData.getProperties().get(FORUM_POSTER_PROP_NAME);
m_emailSender = (IEmailSender) gameData.getProperties().get(EMAIL_SENDER_PROP_NAME);
m_webSitePoster = (IWebPoster) gameData.getProperties().get(WEB_POSTER_PROP_NAME);
m_gameNameAndInfo =
"TripleA " + title + " for game: " + gameData.getGameName() + ", version: " + gameData.getGameVersion();
}
public boolean hasMessengers() {
return (m_forumPoster != null || m_emailSender != null || m_webSitePoster != null);
}
public static boolean GameDataHasPlayByEmailOrForumMessengers(final GameData gameData) {
if (gameData == null) {
return false;
}
final IForumPoster forumPoster = (IForumPoster) gameData.getProperties().get(FORUM_POSTER_PROP_NAME);
final IEmailSender emailSender = (IEmailSender) gameData.getProperties().get(EMAIL_SENDER_PROP_NAME);
final IWebPoster webPoster = (IWebPoster) gameData.getProperties().get(WEB_POSTER_PROP_NAME);
final boolean isPBEM = gameData.getProperties().get(PBEM_GAME_PROP_NAME, false);
return (isPBEM && (forumPoster != null || emailSender != null || webPoster != null));
}
public IForumPoster getForumPoster() {
return m_forumPoster;
}
public IWebPoster getWebPoster() {
return m_webSitePoster;
}
public void setTurnSummary(final String turnSummary) {
m_turnSummary = turnSummary;
}
public void setSaveGame(final File saveGameFile) {
m_saveGameFile = saveGameFile;
}
public String getTurnSummaryRef() {
return m_turnSummaryRef;
}
public String getSaveGameRef() {
return m_saveGameRef;
}
/**
* Post summary to form and/or email, and writes the action performed to the history writer
*
* @param historyWriter
* the history writer (which has no effect since save game has already be generated...) // todo (kg)
* @return true if all posts were successful
*/
public boolean post(final IDelegateHistoryWriter historyWriter, final String title, final boolean includeSaveGame) {
boolean forumSuccess = true;
final StringBuilder saveGameSb = new StringBuilder().append("triplea_");
if (m_forumPoster != null) {
saveGameSb.append(m_forumPoster.getTopicId()).append("_");
}
saveGameSb.append(m_currentPlayer.getName().substring(0, Math.min(3, m_currentPlayer.getName().length() - 1)))
.append(m_roundNumber).append(".tsvg");
final String saveGameName = saveGameSb.toString();
if (m_forumPoster != null) {
if (includeSaveGame) {
m_forumPoster.addSaveGame(m_saveGameFile, saveGameName);
}
try {
forumSuccess = m_forumPoster.postTurnSummary((m_gameNameAndInfo + "\n\n" + m_turnSummary),
"TripleA " + title + ": " + m_currentPlayer.getName() + " round " + m_roundNumber);
m_turnSummaryRef = m_forumPoster.getTurnSummaryRef();
if (m_turnSummaryRef != null && historyWriter != null) {
historyWriter.startEvent("Turn Summary: " + m_turnSummaryRef);
}
} catch (final Exception e) {
ClientLogger.logQuietly(e);
}
}
boolean emailSuccess = true;
if (m_emailSender != null) {
final StringBuilder subjectPostFix = new StringBuilder(m_currentPlayer.getName());
subjectPostFix.append(" - ").append("round ").append(m_roundNumber);
try {
m_emailSender.sendEmail(subjectPostFix.toString(), convertToHtml((m_gameNameAndInfo + "\n\n" + m_turnSummary)),
m_saveGameFile, saveGameName);
m_emailSendStatus = "Success, sent to " + m_emailSender.getToAddress();
} catch (final IOException e) {
emailSuccess = false;
m_emailSendStatus = "Failed! Error " + e.getMessage();
ClientLogger.logQuietly(e);
}
}
boolean webSiteSuccess = true;
if (m_webSitePoster != null) {
m_webSitePoster.addSaveGame(m_saveGameFile, saveGameName);
try {
webSiteSuccess =
m_webSitePoster.postTurnSummary(m_gameData, m_turnSummary, m_currentPlayer.getName(), m_roundNumber);
if (webSiteSuccess) {
m_webPostStatus = "Success! Sent State of Game " + m_webSitePoster.getGameName() + " to "
+ m_webSitePoster.getHost() + "\n" + m_webSitePoster.getServerMessage();
} else {
m_webPostStatus = "Failed! " + m_webSitePoster.getServerMessage();
}
} catch (final Exception e) {
webSiteSuccess = false;
m_webPostStatus = "Failed! Error: " + e.getMessage();
ClientLogger.logQuietly(e);
}
}
if (historyWriter != null) {
final StringBuilder sb = new StringBuilder("Post Turn Summary");
if (m_forumPoster != null) {
sb.append(" to ").append(m_forumPoster.getDisplayName()).append(" success = ")
.append(String.valueOf(forumSuccess));
}
if (m_emailSender != null) {
if (m_forumPoster != null) {
sb.append(" and to ");
} else {
sb.append(" to ");
}
sb.append(m_emailSender.getToAddress()).append(" success = ").append(String.valueOf(emailSuccess));
}
historyWriter.startEvent(sb.toString());
}
return forumSuccess && emailSuccess && webSiteSuccess;
}
/**
* Converts text to html, by transforming \n to <br/>.
*
* @param string
* the string to transform
* @return the transformed string
*/
private String convertToHtml(final String string) {
return "<pre><br/>" + string.replaceAll("\n", "<br/>") + "<br/></pre>";
}
/**
* Get the configured email sender.
*
* @return return an email sender or null
*/
public IEmailSender getEmailSender() {
return m_emailSender;
}
/**
* Return the status string from sending the email.
*
* @return a success of failure string, or null if no email sender was configured
*/
public String getEmailSendStatus() {
return m_emailSendStatus;
}
public String getWebPostStatus() {
return m_webPostStatus;
}
public boolean alsoPostMoveSummary() {
if (m_forumPoster != null) {
return m_forumPoster.getAlsoPostAfterCombatMove();
}
if (m_emailSender != null) {
return m_emailSender.getAlsoPostAfterCombatMove();
}
return false;
}
public static void postTurn(final String title, final HistoryLog historyLog, final boolean includeSaveGame,
final PBEMMessagePoster posterPBEM, final IAbstractForumPosterDelegate postingDelegate,
final MainGameFrame mainGameFrame, final JComponent postButton) {
String message = "";
final IForumPoster turnSummaryMsgr = posterPBEM.getForumPoster();
final StringBuilder sb = new StringBuilder();
if (turnSummaryMsgr != null) {
sb.append(message).append("Post ").append(title).append(" ");
if (includeSaveGame) {
sb.append("and save game ");
}
sb.append("to ").append(turnSummaryMsgr.getDisplayName()).append("?\n");
}
final IEmailSender emailSender = posterPBEM.getEmailSender();
if (emailSender != null) {
sb.append("Send email to ").append(emailSender.getToAddress()).append("?\n");
}
final IWebPoster webPoster = posterPBEM.getWebPoster();
if (webPoster != null) {
sb.append("Send game state of '").append(webPoster.getGameName()).append("' to ").append(webPoster.getHost())
.append("?\n");
}
message = sb.toString();
final int choice = JOptionPane.showConfirmDialog(mainGameFrame, message, "Post " + title + "?", 2, -1, null);
if (choice == 0) {
if (postButton != null) {
postButton.setEnabled(false);
}
final ProgressWindow progressWindow = new ProgressWindow(mainGameFrame, "Posting " + title + "...");
progressWindow.setVisible(true);
final Runnable t = () -> {
boolean postOk = true;
File saveGameFile = null;
if (postingDelegate != null) {
postingDelegate.setHasPostedTurnSummary(true);
}
try {
saveGameFile = File.createTempFile("triplea", ".tsvg");
if (saveGameFile != null) {
mainGameFrame.getGame().saveGame(saveGameFile);
posterPBEM.setSaveGame(saveGameFile);
}
} catch (final Exception e) {
postOk = false;
ClientLogger.logQuietly(e);
}
posterPBEM.setTurnSummary(historyLog.toString());
try {
// forward the poster to the delegate which invokes post() on the poster
if (postingDelegate != null) {
if (!postingDelegate.postTurnSummary(posterPBEM, title, includeSaveGame)) {
postOk = false;
}
} else {
if (!posterPBEM.post(null, title, includeSaveGame)) {
postOk = false;
}
}
} catch (final Exception e) {
postOk = false;
ClientLogger.logQuietly(e);
}
if (postingDelegate != null) {
postingDelegate.setHasPostedTurnSummary(postOk);
}
final StringBuilder sb1 = new StringBuilder();
if (posterPBEM.getForumPoster() != null) {
final String saveGameRef = posterPBEM.getSaveGameRef();
final String turnSummaryRef = posterPBEM.getTurnSummaryRef();
if (saveGameRef != null) {
sb1.append("\nSave Game : ").append(saveGameRef);
}
if (turnSummaryRef != null) {
sb1.append("\nSummary Text: ").append(turnSummaryRef);
}
}
if (posterPBEM.getEmailSender() != null) {
sb1.append("\nEmails: ").append(posterPBEM.getEmailSendStatus());
}
if (posterPBEM.getWebPoster() != null) {
sb1.append("\nWeb Site Post: ").append(posterPBEM.getWebPostStatus());
}
historyLog.getWriter().println(sb1.toString());
if (historyLog.isVisible()) {
historyLog.setVisible(true);
}
try {
if (saveGameFile != null && !saveGameFile.delete()) {
System.out.println(
(new StringBuilder()).append("INFO TripleA PBEM/PBF poster couldn't delete temporary savegame: ")
.append(saveGameFile.getCanonicalPath()).toString());
}
} catch (final IOException e) {
ClientLogger.logQuietly("save game file = " + saveGameFile, e);
}
progressWindow.setVisible(false);
progressWindow.removeAll();
progressWindow.dispose();
final boolean finalPostOk = postOk;
final String finalMessage = sb1.toString();
final Runnable runnable = () -> {
if (postButton != null) {
postButton.setEnabled(!finalPostOk);
}
if (finalPostOk) {
JOptionPane.showMessageDialog(mainGameFrame, finalMessage, title + " Posted",
JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(mainGameFrame, finalMessage, title + " Posted",
JOptionPane.ERROR_MESSAGE);
}
};
SwingUtilities.invokeLater(runnable);
};
// start a new thread for posting the summary.
new Thread(t).start();
}
}
}