}
/* Complex accessors */
public String toJSON() {
JSONObject theJSON = new JSONObject();
try {
theJSON.put("matchId", matchId);
theJSON.put("randomToken", randomToken);
theJSON.put("startTime", startTime.getTime());
theJSON.put("gameMetaURL", getGameRepositoryURL());
theJSON.put("isCompleted", isCompleted);
theJSON.put("isAborted", isAborted);
theJSON.put("states", new JSONArray(renderArrayAsJSON(renderStateHistory(stateHistory), true)));
theJSON.put("moves", new JSONArray(renderArrayAsJSON(renderMoveHistory(moveHistory), false)));
theJSON.put("stateTimes", new JSONArray(renderArrayAsJSON(stateTimeHistory, false)));
if (errorHistory.size() > 0) {
theJSON.put("errors", new JSONArray(renderArrayAsJSON(renderErrorHistory(errorHistory), false)));
}
if (goalValues.size() > 0) {
theJSON.put("goalValues", goalValues);
}
theJSON.put("previewClock", previewClock);
theJSON.put("startClock", startClock);
theJSON.put("playClock", playClock);
if (thePlayerNamesFromHost != null) {
theJSON.put("playerNamesFromHost", thePlayerNamesFromHost);
}
if (isPlayerHuman != null) {
theJSON.put("isPlayerHuman", isPlayerHuman);
}
theJSON.put("scrambled", theGdlScrambler != null ? theGdlScrambler.scrambles() : false);
} catch (JSONException e) {
return null;
}
if (theCryptographicKeys != null) {
try {
SignableJSON.signJSON(theJSON, theCryptographicKeys.thePublicKey, theCryptographicKeys.thePrivateKey);
if (!SignableJSON.isSignedJSON(theJSON)) {
throw new Exception("Could not recognize signed match: " + theJSON);
}
if (!SignableJSON.verifySignedJSON(theJSON)) {
throw new Exception("Could not verify signed match: " + theJSON);
}
} catch (Exception e) {
System.err.println(e);
theJSON.remove("matchHostPK");
theJSON.remove("matchHostSignature");
}
}
return theJSON.toString();
}