package polly.rx.httpv2; import java.io.IOException; import java.io.OutputStream; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import polly.rx.MSG; import polly.rx.MyPlugin; import polly.rx.core.AZEntryManager; import polly.rx.core.FleetDBManager; import polly.rx.core.ScoreBoardManager; import polly.rx.core.ScoreBoardManager.EntryResult; import polly.rx.core.orion.http.OrionController; import polly.rx.entities.AZEntry; import polly.rx.entities.BattleReport; import polly.rx.entities.BattleReportShip; import polly.rx.entities.BattleTactic; import polly.rx.entities.FleetScan; import polly.rx.entities.FleetScanShip; import polly.rx.entities.ScoreBoardEntry; import polly.rx.graphs.NamedPoint; import polly.rx.httpv2.StatisticsGatherer.BattleReportStatistics; import polly.rx.parsing.BattleReportParser; import polly.rx.parsing.FleetScanParser; import polly.rx.parsing.ParseException; import polly.rx.parsing.QBattleReportParser; import polly.rx.parsing.QFleetScanParser; import polly.rx.parsing.ScoreBoardParser; import de.skuzzle.polly.http.annotations.Get; import de.skuzzle.polly.http.annotations.OnRegister; import de.skuzzle.polly.http.annotations.Param; import de.skuzzle.polly.http.annotations.Post; import de.skuzzle.polly.http.api.AlternativeAnswerException; import de.skuzzle.polly.http.api.Controller; import de.skuzzle.polly.http.api.answers.HttpAnswer; import de.skuzzle.polly.http.api.answers.HttpAnswers; import de.skuzzle.polly.http.api.answers.HttpInputStreamAnswer; import de.skuzzle.polly.http.api.answers.HttpResourceAnswer; import de.skuzzle.polly.sdk.MyPolly; import de.skuzzle.polly.sdk.Types; import de.skuzzle.polly.sdk.Types.BooleanType; import de.skuzzle.polly.sdk.Types.NumberType; import de.skuzzle.polly.sdk.Types.TimespanType; import de.skuzzle.polly.sdk.User; import de.skuzzle.polly.sdk.exceptions.DatabaseException; import de.skuzzle.polly.sdk.httpv2.GsonHttpAnswer; import de.skuzzle.polly.sdk.httpv2.PollyController; import de.skuzzle.polly.sdk.httpv2.SuccessResult; import de.skuzzle.polly.sdk.httpv2.WebinterfaceManager; import de.skuzzle.polly.sdk.httpv2.html.HTMLTools; import de.skuzzle.polly.sdk.roles.RoleManager; import de.skuzzle.polly.sdk.time.Time; import de.skuzzle.polly.tools.io.FastByteArrayOutputStream; public class RXController extends PollyController { public final static String PAGE_FLEET_SCAN_MANAGER = "/pages/fleetScanPage"; //$NON-NLS-1$ public final static String PAGE_FLEET_SCAN_DETAILS = "/pages/fleetScanDetails"; //$NON-NLS-1$ public final static String PAGE_FLEET_SCAN_SHIPS = "/pages/fleetScanShips"; //$NON-NLS-1$ public final static String PAGE_SCAN_SHIP_DETAILS = "/pages/scanShipDetails"; //$NON-NLS-1$ public final static String PAGE_SCOREBOARD = "/pages/scoreboard"; //$NON-NLS-1$ public final static String PAGE_REPORTS = "/pages/reports"; //$NON-NLS-1$ public final static String PAGE_CONFIGURE_AZ = "/pages/configureAz"; //$NON-NLS-1$ public final static String PAGE_GM_SCRIPTS = "/pages/gmScripts"; //$NON-NLS-1$ public final static String PAGE_COMPARE_SCORES = "/pages/score/compare"; //$NON-NLS-1$ public final static String PAGE_SCORE_DETAILS = "/pages/score/details"; //$NON-NLS-1$ public final static String PAGE_REPORT_DETAILS = "/pages/reportDetails"; //$NON-NLS-1$ public final static String PAGE_TRAININGS = "/pages/trainings"; //$NON-NLS-1$ public final static String PAGE_SECTORS = "/pages/sectors"; //$NON-NLS-1$ public final static String API_ADD_TO_COMPARE = "/api/addToCompare"; //$NON-NLS-1$ public final static String API_REMOVE_FROM_COMPARE = "/api/removeFromCompare"; //$NON-NLS-1$ public final static String API_ADD_AZ_ENTRY = "/api/addAzEntry"; //$NON-NLS-1$ public final static String API_DELETE_AZ_ENTRY = "/api/deleteAzEntry"; //$NON-NLS-1$ public final static String API_POST_FLEET_SCAN = "/api/postFleetScan"; //$NON-NLS-1$ public final static String API_POST_QFLEET_SCAN = "/api/postQFleetScan"; //$NON-NLS-1$ public final static String API_GRAPH_COMPARE = "/api/graphCompare"; //$NON-NLS-1$ public final static String API_GRAPH_FOR_VENAD = "/api/graphForVenad"; //$NON-NLS-1$ public final static String API_IMAGE_FROM_SESSION = "/api/imageFromSession"; //$NON-NLS-1$ public final static String API_POST_SCOREBOARD = "/api/postScoreboard"; //$NON-NLS-1$ public final static String API_POST_REPORT = "/api/postReport"; //$NON-NLS-1$ public final static String API_POST_QREPORT = "/postQReport"; //$NON-NLS-1$ public final static String API_DELETE_REPORT = "/api/deleteReport"; //$NON-NLS-1$ public final static String API_REPORT_STATISTICS = "/api/battlereportStatistics"; //$NON-NLS-1$ public final static String API_TEST_LOGIN = "/api/testLogin"; //$NON-NLS-1$ public final static String GM_SCRAPE_SCOREBOARD = "/GM/scrapescoreboarddata.user.js"; //$NON-NLS-1$ public final static String GM_KB_REPORT = "/GM/kbreport.user.js"; //$NON-NLS-1$ public final static String GM_FLEET_SCANS = "/GM/fleetscan.user.js"; //$NON-NLS-1$ public final static String GM_ORION = "/GM/orion.user.js"; //$NON-NLS-1$ public final static String GM_ORIONV2 = "/GM/orionv2.user.js"; //$NON-NLS-1$ public final static String GM_ORIONV2_META = "/GM/orionv2.meta.js"; //$NON-NLS-1$ public final static String GM_FLEET_PROFILES = "/GM/fleetprofiles.user.js"; //$NON-NLS-1$ public final static String GM_FLEET_PROFILES_META = "/GM/fleetprofiles.meta.js"; //$NON-NLS-1$ public final static String FILES_VIEW = "/polly/rx/httpv2/view"; //$NON-NLS-1$ private final static String CONTENT_FLEET_SCAN_MANAGER = "polly/rx/httpv2/view/fleetscans.overview.html"; //$NON-NLS-1$ private final static String CONTENT_FLEET_SCAN_DETAILS = "polly/rx/httpv2/view/fleetscan.details.html"; //$NON-NLS-1$ private final static String CONTENT_FLEET_SCAN_SHIPS = "polly/rx/httpv2/view/scanships.overview.html"; //$NON-NLS-1$ private final static String CONTENT_SCAN_SHIP_DETAILS = "polly/rx/httpv2/view/scanship.details.html"; //$NON-NLS-1$ private final static String CONTENT_SCOREBOARD = "polly/rx/httpv2/view/scoreboard.overview.html"; //$NON-NLS-1$ private final static String CONTENT_REPORTS = "polly/rx/httpv2/view/battlereports.overview.html"; //$NON-NLS-1$ private final static String CONTENT_CONFIG_AZ = "polly/rx/httpv2/view/configure.az.html"; //$NON-NLS-1$ private final static String CONTENT_COMPARE_SCORES = "polly/rx/httpv2/view/scoreboard.compare.html"; //$NON-NLS-1$ private final static String CONTENT_SCORE_DETAILS = "polly/rx/httpv2/view/scoreboard.details.html"; //$NON-NLS-1$ private final static String CONTENT_GRAPH_COMPARE = "polly/rx/httpv2/view/graph.html"; //$NON-NLS-1$ private final static String CONTENT_GRAPH_FOR_VENAD = "polly/rx/httpv2/view/graph.html"; //$NON-NLS-1$ private final static String CONTENT_REPORT_DETAILS = "polly/rx/httpv2/view/battlereports.details.html"; //$NON-NLS-1$ private final static String CONTENT_REPORT_STATISTICS = "polly/rx/httpv2/view/battlereports.statistics.html"; //$NON-NLS-1$ private final static String CONTENT_SCRAPE_SCOREBOARD = "polly/rx/httpv2/view/scrapescoreboarddata.user.js"; //$NON-NLS-1$ private final static String CONTENT_KB_REPORT = "polly/rx/httpv2/view/kbreport.user.js"; //$NON-NLS-1$ private final static String CONTENT_FLEET_SCANS = "polly/rx/httpv2/view/fleetscan.user.js"; //$NON-NLS-1$ private final static String CONTENT_TRAININGS = "polly/rx/httpv2/view/trainings.html"; //$NON-NLS-1$ private final static String CONTENT_GM_ORION = "polly/rx/httpv2/view/orion.user.js"; //$NON-NLS-1$ private final static String CONTENT_GM_ORIONV2 = "polly/rx/httpv2/view/orionv2.user.js"; //$NON-NLS-1$ private final static String CONTENT_GM_ORIONV2_META = "polly/rx/httpv2/view/orionv2.meta.js"; //$NON-NLS-1$ private final static String CONTENT_GM_FLEET_PROFILES = "polly/rx/httpv2/view/fleetprofiles.user.js"; //$NON-NLS-1$ private final static String CONTENT_GM_FLEET_PROFILES_META = "polly/rx/httpv2/view/fleetprofiles.meta.js"; //$NON-NLS-1$ private final static String REVORIX_CATEGORY_KEY = "httpRxCategory"; //$NON-NLS-1$ private final static String FLEET_SCAN_NAME_KEY = "httpFleetScanMngr"; //$NON-NLS-1$ private final static String FLEET_SCAN_DESC_KEY = "httpFleetScanMngrDesc"; //$NON-NLS-1$ private final static String SCANNED_SHIPS_NAME_KEY = "httpScannedShips"; //$NON-NLS-1$ private final static String SCANNED_SHIPS_DESC_KEY = "httpScannedShipsDesc"; //$NON-NLS-1$ private final static String SCOREBOARD_NAME_KEY = "httpScoreboardMngr"; //$NON-NLS-1$ private final static String SCOREBOARD_DESC_KEY = "httpScoreboardMngrDesc"; //$NON-NLS-1$ private final static String REPORTS_NAME_KEY = "httpReportsMngr"; //$NON-NLS-1$ private final static String REPORTS_DESC_KEY = "httpReportsMngrDesc"; //$NON-NLS-1$ private final static String CONFIG_AZ_NAME_KEY = "httpAzMngr"; //$NON-NLS-1$ private final static String CONFIG_AZ_DESC_KEY = "httpAzMngrDesc"; //$NON-NLS-1$ private final static String TRAININGS_NAME_KEY = "htmlTrainingCaption"; //$NON-NLS-1$ private final static String TRAININGS_DESC_KEY = "htmlTrainingDescription"; //$NON-NLS-1$ private final static String COMPARE_LIST_KEY = "COMPARE_LIST"; //$NON-NLS-1$ private final static String MULTI_GRAPH_PREFIX = "graph_compare_mm_"; //$NON-NLS-1$ private final static String SINGLE_GRAPH_PREFIX = "graph_"; //$NON-NLS-1$ public final static String STATS_PREFIX = "BR_STATS_"; //$NON-NLS-1$ private final FleetDBManager fleetDb; private final ScoreBoardManager sbManager; private final AZEntryManager azManager; public RXController(MyPolly myPolly, FleetDBManager fleetDb, ScoreBoardManager sbManager, AZEntryManager azManager) { super(myPolly); this.azManager = azManager; this.fleetDb = fleetDb; this.sbManager = sbManager; } @Override protected Controller createInstance() { return new RXController(getMyPolly(), this.fleetDb, this.sbManager, this.azManager); } @Override protected Map<String, Object> createContext(String content) { final Map<String, Object> c = super.createContext(content); HTMLTools.gainFieldAccess(c, MSG.class, "MSG"); //$NON-NLS-1$ return c; } @Get(value = PAGE_TRAININGS, name = TRAININGS_NAME_KEY) @OnRegister({ WebinterfaceManager.ADD_MENU_ENTRY, MSG.FAMILY, REVORIX_CATEGORY_KEY, TRAININGS_DESC_KEY, RoleManager.REGISTERED_PERMISSION }) public HttpAnswer trainingsPage() throws AlternativeAnswerException { requirePermissions(RoleManager.REGISTERED_PERMISSION); return this.makeAnswer(createContext(CONTENT_TRAININGS)); } @Get(value = PAGE_FLEET_SCAN_MANAGER, name = FLEET_SCAN_NAME_KEY) @OnRegister({ WebinterfaceManager.ADD_MENU_ENTRY, MSG.FAMILY, REVORIX_CATEGORY_KEY, FLEET_SCAN_DESC_KEY, FleetDBManager.VIEW_FLEET_SCAN_PERMISSION }) public HttpAnswer fleetScanPage() throws AlternativeAnswerException { requirePermissions(FleetDBManager.VIEW_FLEET_SCAN_PERMISSION); return this.makeAnswer(createContext(CONTENT_FLEET_SCAN_MANAGER)); } @Get(PAGE_FLEET_SCAN_DETAILS) public HttpAnswer fleetScanDetailsPage(@Param("scanId") int scanId) throws AlternativeAnswerException { requirePermissions(FleetDBManager.VIEW_FLEET_SCAN_PERMISSION); final FleetScan scan = this.fleetDb.getScanById(scanId); final Map<String, Object> c = createContext( CONTENT_FLEET_SCAN_DETAILS); c.put("scan", scan); //$NON-NLS-1$ return this.makeAnswer(c); } @Get(value = PAGE_FLEET_SCAN_SHIPS, name = SCANNED_SHIPS_NAME_KEY) @OnRegister({ WebinterfaceManager.ADD_MENU_ENTRY, MSG.FAMILY, REVORIX_CATEGORY_KEY, SCANNED_SHIPS_DESC_KEY, FleetDBManager.VIEW_FLEET_SCAN_PERMISSION }) public HttpAnswer fleetScanShipsPage() throws AlternativeAnswerException { requirePermissions(FleetDBManager.VIEW_FLEET_SCAN_PERMISSION); return this.makeAnswer(createContext(CONTENT_FLEET_SCAN_SHIPS)); } @Get(PAGE_SCAN_SHIP_DETAILS) public HttpAnswer scanShipDetails(@Param("shipId") int id) throws AlternativeAnswerException { requirePermissions(FleetDBManager.VIEW_FLEET_SCAN_PERMISSION); final FleetScanShip ship = this.fleetDb.getShipByRevorixId(id); final Map<String, Object> c = createContext(CONTENT_SCAN_SHIP_DETAILS); c.put("ship", ship); //$NON-NLS-1$ return this.makeAnswer(c); } public final class CompareList extends SuccessResult { private final Set<String> entries; public CompareList() { super(true, ""); //$NON-NLS-1$ this.entries = new HashSet<>(); } public Set<String> getEntries() { return this.entries; } @Override public String toString() { return this.entries.toString(); } } @Get(API_ADD_TO_COMPARE) public HttpAnswer addToCompare(@Param("venadName") String name) throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); CompareList cl = (CompareList) getSession().get(COMPARE_LIST_KEY); if (cl == null) { cl = new CompareList(); getSession().set(COMPARE_LIST_KEY, cl); } synchronized (cl) { cl.getEntries().add(name); } return HttpAnswers.newRedirectAnswer(PAGE_SCOREBOARD); } @Get(API_REMOVE_FROM_COMPARE) public HttpAnswer removeFromCompare(@Param("venadName") String name) throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); CompareList cl = (CompareList) getSession().get(COMPARE_LIST_KEY); if (cl != null) { synchronized (cl) { cl.getEntries().remove(name); } } return HttpAnswers.newRedirectAnswer(PAGE_SCOREBOARD); } @Get(value = PAGE_SCOREBOARD, name = SCOREBOARD_NAME_KEY) @OnRegister({ WebinterfaceManager.ADD_MENU_ENTRY, MSG.FAMILY, REVORIX_CATEGORY_KEY, SCOREBOARD_DESC_KEY, MyPlugin.SBE_PERMISSION }) public HttpAnswer scoreboardPage() throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); final Map<String, Object> c = createContext(CONTENT_SCOREBOARD); CompareList cl = (CompareList) getSession().get(COMPARE_LIST_KEY); if (cl == null) { cl = new CompareList(); getSession().set(COMPARE_LIST_KEY, cl); } c.put("compareList", cl); //$NON-NLS-1$ return this.makeAnswer(c); } @Get(value = PAGE_REPORTS, name = REPORTS_NAME_KEY) @OnRegister({ WebinterfaceManager.ADD_MENU_ENTRY, MSG.FAMILY, REVORIX_CATEGORY_KEY, REPORTS_DESC_KEY, FleetDBManager.VIEW_BATTLE_REPORT_PERMISSION }) public HttpAnswer reportsPage() throws AlternativeAnswerException { requirePermissions(FleetDBManager.VIEW_BATTLE_REPORT_PERMISSION); final Map<String, Object> c = createContext(CONTENT_REPORTS); return this.makeAnswer(c); } @Get(value = PAGE_CONFIGURE_AZ, name = CONFIG_AZ_NAME_KEY) @OnRegister({ WebinterfaceManager.ADD_MENU_ENTRY, MSG.FAMILY, REVORIX_CATEGORY_KEY, CONFIG_AZ_DESC_KEY, FleetDBManager.ADD_BATTLE_REPORT_PERMISSION }) public HttpAnswer configureAz() throws AlternativeAnswerException { requirePermissions(FleetDBManager.ADD_BATTLE_REPORT_PERMISSION); final User user = getSessionUser(); final List<AZEntry> entries = this.azManager.getEntries(user.getId()); final Map<String, Object> c = createContext(CONTENT_CONFIG_AZ); c.put("entries", entries); //$NON-NLS-1$ return this.makeAnswer(c); } @Get(API_ADD_AZ_ENTRY) public HttpAnswer addAzEntry(@Param("fleet") String fleet, @Param("az") String az, @Param("jumpTime") String jumpTime) throws AlternativeAnswerException, DatabaseException { requirePermissions(FleetDBManager.ADD_BATTLE_REPORT_PERMISSION); final User user = getSessionUser(); final Types t = getMyPolly().parse(az); if (!(t instanceof TimespanType)) { return new GsonHttpAnswer(200, new SuccessResult(false, MSG.httpAddAzIllegalFormat)); } this.azManager.addEntry(user.getId(), fleet, az, jumpTime); return new GsonHttpAnswer(200, new SuccessResult(true, "")); //$NON-NLS-1$ } @Get(API_DELETE_AZ_ENTRY) public HttpAnswer deleteAzEntry(@Param("entryId") int id) throws AlternativeAnswerException, DatabaseException { requirePermissions(FleetDBManager.ADD_BATTLE_REPORT_PERMISSION); final User user = getSessionUser(); try { this.azManager.deleteEntry(id, user.getId()); return new GsonHttpAnswer(200, new SuccessResult(true, "")); //$NON-NLS-1$ } catch (DatabaseException e) { return new GsonHttpAnswer(200, new SuccessResult(false, e.getMessage())); } } /*@Get(value = PAGE_GM_SCRIPTS, name = GM_SCRIPT_NAME_KEY) @OnRegister({ WebinterfaceManager.ADD_MENU_ENTRY, MSG.FAMILY, REVORIX_CATEGORY_KEY, GM_SCRIPT_DESC_KEY, RoleManager.REGISTERED_PERMISSION }) public HttpAnswer gmScripts() throws AlternativeAnswerException { this.requirePermissions(RoleManager.REGISTERED_PERMISSION); final Map<String, Object> c = this.createContext(CONTENT_GM_SCRIPTS); return this.makeAnswer(c); }*/ @Get(PAGE_COMPARE_SCORES) public HttpAnswer compare() throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); final Map<String, Object> c = createContext(CONTENT_COMPARE_SCORES); CompareList cl = (CompareList) getSession().get(COMPARE_LIST_KEY); c.put("compareList", cl); //$NON-NLS-1$ return this.makeAnswer(c); } @Get(PAGE_SCORE_DETAILS) public HttpAnswer venadDetails(@Param("venadName") String name) throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); final Map<String, Object> c = createContext(CONTENT_SCORE_DETAILS); c.put("venad", name); //$NON-NLS-1$ return this.makeAnswer(c); } @Post(API_POST_FLEET_SCAN) public HttpAnswer postFleetScan( @Param("scan") String scan, @Param("quadrant") String quadrant, @Param("x") int x, @Param("y") int y, @Param(value = "meta", optional = true) String meta) throws AlternativeAnswerException { requirePermissions(FleetDBManager.ADD_FLEET_SCAN_PERMISSION); try { final FleetScan fs = FleetScanParser.parseFleetScan( scan, quadrant, x, y, meta); this.fleetDb.addFleetScan(fs); } catch (ParseException | DatabaseException e) { return new GsonHttpAnswer(200, new SuccessResult(false, e.getMessage())); } return new GsonHttpAnswer(200, new SuccessResult(true, MSG.httpPostScanSuccess)); } @Post(API_POST_QFLEET_SCAN) public HttpAnswer postQFleetScan(@Param("scan") String scan, @Param("user") String user, @Param("pw") String pw) throws AlternativeAnswerException { final User u = checkLogin(user, pw); if (!getMyPolly().roles().hasPermission(u, FleetDBManager.ADD_FLEET_SCAN_PERMISSION)) { return new GsonHttpAnswer(200, new SuccessResult(false, MSG.httpNoPermission)); } try { final FleetScan fs = QFleetScanParser.parseFleetScan(scan); this.fleetDb.addFleetScan(fs); } catch (ParseException | DatabaseException e) { return new GsonHttpAnswer(200, new SuccessResult(false, e.getMessage())); } return new GsonHttpAnswer(200, new SuccessResult(true, MSG.httpPostScanSuccess)); } @Get(API_GRAPH_COMPARE) public HttpAnswer graphCompare(@Param("maxMonth") int maxMonths) throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); CompareList cl = (CompareList) getSession().get(COMPARE_LIST_KEY); if (cl == null) { return HttpAnswers.newStringAnswer(""); //$NON-NLS-1$ } final Collection<NamedPoint> allPoints = new ArrayList<>(); final OutputStream graph = this.sbManager.createMultiGraph(maxMonths, allPoints, cl.getEntries().toArray(new String[0])); final String imgName = MULTI_GRAPH_PREFIX + maxMonths; getSession().set(imgName, graph); final Map<String, Object> c = createContext(""); //$NON-NLS-1$ c.put("allPoints", allPoints); //$NON-NLS-1$ c.put("imgName", imgName); //$NON-NLS-1$ c.put("maxMonths", maxMonths); //$NON-NLS-1$ c.put("isCompare", true); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_GRAPH_COMPARE, c); } @Get(API_GRAPH_FOR_VENAD) public HttpAnswer graphForVenad(@Param("venadName") String name, @Param("maxMonth") int maxMonths) throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); final List<ScoreBoardEntry> entries = this.sbManager.getEntries(name); Collections.sort(entries, ScoreBoardEntry.BY_DATE); final Collection<NamedPoint> allPoints = new ArrayList<>(); final OutputStream graph = this.sbManager.createLatestGraph(entries, maxMonths, allPoints); final String imgName = SINGLE_GRAPH_PREFIX + name + maxMonths; getSession().set(imgName, graph); final Map<String, Object> c = createContext(""); //$NON-NLS-1$ c.put("allPoints", allPoints); //$NON-NLS-1$ c.put("venad", name); //$NON-NLS-1$ c.put("imgName", imgName); //$NON-NLS-1$ c.put("maxMonths", maxMonths); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_GRAPH_FOR_VENAD, c); } @Get(API_IMAGE_FROM_SESSION) public HttpAnswer imageFromSession(@Param("imgName") String imgName) throws AlternativeAnswerException, IOException { requirePermissions(MyPlugin.SBE_PERMISSION); final FastByteArrayOutputStream out = getSession().get(imgName); return new HttpInputStreamAnswer(200, out.getInputStreamForBuffer()); } @Get(FILES_VIEW) public HttpAnswer getFile() { final ClassLoader cl = this.getClass().getClassLoader(); return new HttpResourceAnswer(200, cl, getEvent().getPlainUri()); } @Post(API_POST_SCOREBOARD) public HttpAnswer postScoreboard(@Param("input") String input) throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); try { final Collection<ScoreBoardEntry> entries = ScoreBoardParser.parse(input, Time.currentTime()); this.sbManager.addEntries(entries); } catch (Exception e) { e.printStackTrace(); } return HttpAnswers.newRedirectAnswer(PAGE_SCOREBOARD); } public final class PostScoreBoardResult extends SuccessResult { public final EntryResult[] entries; public PostScoreBoardResult(String msg, EntryResult[] results) { super(true, msg); this.entries = results; } } @Post(API_POST_SCOREBOARD) public HttpAnswer postScoreboardExt( @Param("user") String user, @Param("pw") String pw, @Param("paste") String paste) throws AlternativeAnswerException { final User u = checkLogin(user, pw); if (!getMyPolly().roles().hasPermission(u, MyPlugin.SBE_PERMISSION)) { return new GsonHttpAnswer(200, new SuccessResult(false, MSG.httpNoPermission)); } try { final Collection<ScoreBoardEntry> entries = ScoreBoardParser.parse(paste, Time.currentTime()); final List<EntryResult> results = this.sbManager.addEntries(entries); final EntryResult[] resultsArr = new EntryResult[results.size()]; results.toArray(resultsArr); return new GsonHttpAnswer(200, new PostScoreBoardResult( MSG.bind(MSG.httpPostScoreboardSuccess, entries.size()), resultsArr)); } catch (ParseException | DatabaseException e) { return new GsonHttpAnswer(200, new SuccessResult(false, e.getMessage())); } } @Get(PAGE_REPORT_DETAILS) public HttpAnswer reportDetails(@Param("reportId") int reportId) throws AlternativeAnswerException { requirePermissions(FleetDBManager.VIEW_BATTLE_REPORT_PERMISSION); final BattleReport br = this.fleetDb.getReportById(reportId); final Map<String, Object> c = createContext(CONTENT_REPORT_DETAILS); c.put("report", br); //$NON-NLS-1$ c.put("df", new DecimalFormat("0.##")); //$NON-NLS-1$//$NON-NLS-2$ c.put("fleetDb", this.fleetDb); //$NON-NLS-1$ c.put("Math", Math.class); //$NON-NLS-1$ prepareContext(br.getAttackerShips(), "Attacker", c); //$NON-NLS-1$ prepareContext(br.getDefenderShips(), "Defender", c); //$NON-NLS-1$ return this.makeAnswer(c); } private void prepareContext(List<BattleReportShip> ships, String postfix, Map<String, Object> c) { int pzDamage = 0; int maxPzDamage = 0; int minPzDamage = Integer.MAX_VALUE; int avgPzDamage = 0; int shieldDamage = 0; int maxShieldDamage = 0; int minShieldDamage = Integer.MAX_VALUE; int avgShieldDamage = 0; int capiXp = 0; int maxCapiXp = 0; int minCapiXp = Integer.MAX_VALUE; int avgCapiXp = 0; int crewXp = 0; int maxCrewXp = 0; int minCrewXp = Integer.MAX_VALUE; int avgCrewXp = 0; int maxWend = 0; int minWend = Integer.MAX_VALUE; for (BattleReportShip ship : ships) { pzDamage += ship.getPzDamage(); maxPzDamage = Math.max(maxPzDamage, ship.getPzDamage()); minPzDamage = Math.min(minPzDamage, ship.getPzDamage()); shieldDamage += ship.getShieldDamage(); maxShieldDamage = Math.max(maxShieldDamage, ship.getShieldDamage()); minShieldDamage = Math.min(minShieldDamage, ship.getShieldDamage()); capiXp += ship.getCapiXp(); maxCapiXp = Math.max(maxCapiXp, ship.getCapiXp()); minCapiXp = Math.min(minCapiXp, ship.getCapiXp()); crewXp += ship.getCrewXp(); maxCrewXp = Math.max(maxCrewXp, ship.getCrewXp()); minCrewXp = Math.min(minCrewXp, ship.getCrewXp()); maxWend = Math.max(maxWend, ship.getMaxWend()); minWend = Math.min(minWend, ship.getMaxWend()); } avgPzDamage = pzDamage / ships.size(); avgShieldDamage = shieldDamage / ships.size(); avgCapiXp = capiXp / ships.size(); avgCrewXp = crewXp / ships.size(); c.put("pzDamage" + postfix, pzDamage); //$NON-NLS-1$ c.put("maxPzDamage" + postfix, maxPzDamage); //$NON-NLS-1$ c.put("minPzDamage" + postfix, minPzDamage); //$NON-NLS-1$ c.put("avgPzDamage" + postfix, avgPzDamage); //$NON-NLS-1$ c.put("shieldDamage" + postfix, shieldDamage); //$NON-NLS-1$ c.put("maxShieldDamage" + postfix, maxShieldDamage); //$NON-NLS-1$ c.put("minShieldDamage" + postfix, minShieldDamage); //$NON-NLS-1$ c.put("avgShieldDamage" + postfix, avgShieldDamage); //$NON-NLS-1$ c.put("capiXp" + postfix, capiXp); //$NON-NLS-1$ c.put("maxCapiXp" + postfix, maxCapiXp); //$NON-NLS-1$ c.put("minCapiXp" + postfix, minCapiXp); //$NON-NLS-1$ c.put("avgCapiXp" + postfix, avgCapiXp); //$NON-NLS-1$ c.put("crewXp" + postfix, crewXp); //$NON-NLS-1$ c.put("maxCrewXp" + postfix, maxCrewXp); //$NON-NLS-1$ c.put("minCrewXp" + postfix, minCrewXp); //$NON-NLS-1$ c.put("avgCrewXp" + postfix, avgCrewXp); //$NON-NLS-1$ c.put("maxWend" + postfix, maxWend); //$NON-NLS-1$ c.put("minWend" + postfix, minWend); //$NON-NLS-1$ } @Post(API_POST_REPORT) public HttpAnswer postReport(@Param("report") String report) throws AlternativeAnswerException { requirePermissions(FleetDBManager.ADD_BATTLE_REPORT_PERMISSION); try { final BattleReport br = BattleReportParser.parseReport(report, getSessionUser()); this.fleetDb.addBattleReport(br); } catch (ParseException | DatabaseException e) { return new GsonHttpAnswer(200, new SuccessResult(false, e.getMessage())); } return new GsonHttpAnswer(200, new SuccessResult(true, MSG.httpPostReportSuccess)); } public static class QReportResult extends SuccessResult { public final String lowPzShips; public final boolean lowPzWarning = true; public QReportResult(boolean success, String message, String lowPzShips) { super(success, message); this.lowPzShips = lowPzShips; } } @Post(API_POST_QREPORT) public HttpAnswer postQReport( @Param("user") String user, @Param("pw") String pw, @Param(value = "isLive", optional = true, defaultValue = "false") Boolean isLive, @Param("report") String report) throws AlternativeAnswerException { final User u = checkLogin(user, pw); final BattleReport br; try { br = QBattleReportParser.parse(report, u.getId()); } catch (ParseException e) { return new GsonHttpAnswer(200, new SuccessResult(false, e.getMessage())); } final NumberType pzWarning = (NumberType) u.getAttribute(MyPlugin.LOW_PZ_WARNING); final NumberType dockLevel = (NumberType) u.getAttribute(MyPlugin.DOCK_LEVEL); final int dockLvlInt = (int) dockLevel.getValue(); final TimespanType repairTimeWarning = (TimespanType) u.getAttribute(MyPlugin.REPAIR_TIME_WARNING); List<BattleReportShip> lowPzShips = new ArrayList<>(40); if (pzWarning.getValue() > 0.0) { final List<BattleReportShip> ships = br.getTactic() == BattleTactic.ALIEN ? br.getDefenderShips() : br.getAttackerShips(); for (final BattleReportShip ship : ships) { if (ship.getCurrentPz() < pzWarning.getValue()) { lowPzShips.add(ship); } } } final double seconds = br.getTactic() == BattleTactic.ALIEN ? br.getDefenderRepairTime(dockLvlInt) : br.getAttackerRepairTime(dockLvlInt); boolean doRepairTimeWarning = repairTimeWarning.getSpan() > 0 && seconds >= repairTimeWarning.getSpan(); if (isLive && u.getCurrentNickName() != null) { final BooleanType autoRemind = (BooleanType) u.getAttribute(MyPlugin.AUTO_REMIND); if (autoRemind.getValue()) { // get AZ for attacker fleet. This will fall back to the default az // time if no time for given fleet is configured final TimespanType az = this.azManager.getAz( br.getAttackerFleetName(), u); final String duration = az.getSpan() + "s"; //$NON-NLS-1$ final String command = MSG.bind(MSG.httpAutoRemindCommand, u.getCurrentNickName(), duration, br.getAttackerFleetName());; try { getMyPolly().commands().executeString(command, u.getCurrentNickName(), true, u, getMyPolly().irc()); } catch (Exception e) { // ignore e.printStackTrace(); } } } String message = MSG.httpPostReportSuccess; try { this.fleetDb.addBattleReport(br); } catch (DatabaseException e) { message = e.getMessage(); } if (!lowPzShips.isEmpty() || doRepairTimeWarning) { final StringBuilder b = new StringBuilder(); if (!lowPzShips.isEmpty()) { b.append(MSG.bind(MSG.httpShipsBelow, pzWarning.valueString(getMyPolly().formatting()))); b.append("\n"); //$NON-NLS-1$ for (final BattleReportShip lowPz : lowPzShips) { b.append(lowPz.getName()); b.append(" ("); //$NON-NLS-1$ b.append(lowPz.getCurrentPz()); b.append("pz)\n"); //$NON-NLS-1$ } } if (doRepairTimeWarning) { final String repTime = getMyPolly().formatting().formatTimeSpan( (int) seconds); b.append(MSG.bind(MSG.httpRepairWarning, repTime)); b.append("\n"); //$NON-NLS-1$ } return new GsonHttpAnswer(200, new QReportResult(true, message, b.toString())); } return new GsonHttpAnswer(200, new SuccessResult(true, message)); } @Get(API_DELETE_REPORT) public HttpAnswer deleteReport(@Param("reportId") int id) throws DatabaseException, AlternativeAnswerException { if (!getMyPolly().roles().hasPermission(getSessionUser(), FleetDBManager.DELETE_BATTLE_REPORT_PERMISSION)) { return new GsonHttpAnswer(200, new SuccessResult(false, MSG.httpNoPermission)); } this.fleetDb.deleteReportById(id); return new GsonHttpAnswer(200, new SuccessResult(true, "")); //$NON-NLS-1$ } @Get(API_REPORT_STATISTICS) public HttpAnswer battleReportStatistics() { if (!getMyPolly().roles().hasPermission(getSessionUser(), FleetDBManager.VIEW_BATTLE_REPORT_PERMISSION)) { return new GsonHttpAnswer(200, new SuccessResult(false, MSG.httpNoPermission)); } final User user = getSessionUser(); final String STATISTIC_KEY = STATS_PREFIX + user.getName(); BattleReportStatistics stats = (BattleReportStatistics) getSession().get(STATISTIC_KEY); if (stats == null) { stats = new BattleReportStatistics(); } synchronized (stats) { final DecimalFormat df = new DecimalFormat("#.##"); //$NON-NLS-1$ final Map<String, Object> c = createContext(""); //$NON-NLS-1$ c.put("df", df); //$NON-NLS-1$ c.put("capiXpSumAttacker", stats.capiXpSumAttacker); //$NON-NLS-1$ c.put("crewXpSumAttacker", stats.crewXpSumAttacker); //$NON-NLS-1$ c.put("capiXpSumDefender", stats.capiXpSumDefender); //$NON-NLS-1$ c.put("crewXpSumDefender", stats.crewXpSumDefender); //$NON-NLS-1$ c.put("pzDamageAttacker", stats.pzDamageAttacker); //$NON-NLS-1$ c.put("pzDamageDefender", stats.pzDamageDefender); //$NON-NLS-1$ c.put("repairTimeAttacker", Math.round(stats.repairTimeAttacker)); //$NON-NLS-1$ c.put("repairTimeDefender", Math.round(stats.repairTimeDefender)); //$NON-NLS-1$ c.put("repairCostDefender", stats.repairCostDefender); //$NON-NLS-1$ c.put("repairCostAttacker", stats.repairCostAttacker); //$NON-NLS-1$ c.put("kwAttacker", stats.kwAttacker); //$NON-NLS-1$ c.put("kwDefender", stats.kwDefender); //$NON-NLS-1$ c.put("artifacts", stats.artifacts); //$NON-NLS-1$ c.put("chance", stats.artifactChance * 100.0); //$NON-NLS-1$ c.put("dropSum", stats.dropSum); //$NON-NLS-1$ c.put("dropMax", stats.dropMax); //$NON-NLS-1$ c.put("dropMin", stats.dropMin); //$NON-NLS-1$ c.put("dropNetto", stats.dropNetto); //$NON-NLS-1$ c.put("dropPrices", stats.dropPrices); //$NON-NLS-1$ c.put("currentPrices", stats.currentPrices); //$NON-NLS-1$ c.put("dropPriceSum", stats.dropPriceSum); //$NON-NLS-1$ c.put("dropPriceSumAtDropTime", stats.dropPriceSumAtDropTime); //$NON-NLS-1$ c.put("dropPricesAtDropTime", stats.dropPricesAtDropTime); //$NON-NLS-1$ c.put("reportSize", stats.reportSize); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_REPORT_STATISTICS, c); } } @Get(GM_SCRAPE_SCOREBOARD) public HttpAnswer installScoreboard() throws AlternativeAnswerException { requirePermissions(MyPlugin.SBE_PERMISSION); final String host = createPollyUrl(); final Map<String, String> c = new HashMap<String, String>(); c.put("host", host); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_SCRAPE_SCOREBOARD, c); } @Get(GM_KB_REPORT) public HttpAnswer installLiveKB() throws AlternativeAnswerException { requirePermissions(FleetDBManager.ADD_BATTLE_REPORT_PERMISSION); final String host = createPollyUrl(); final Map<String, String> c = new HashMap<String, String>(); c.put("api", API_POST_QREPORT); //$NON-NLS-1$ c.put("host", host); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_KB_REPORT, c); } @Get(GM_FLEET_SCANS) public HttpAnswer installFleetScans() throws AlternativeAnswerException { requirePermissions(FleetDBManager.ADD_FLEET_SCAN_PERMISSION); final String host = createPollyUrl(); final Map<String, String> c = new HashMap<String, String>(); c.put("api", API_POST_QFLEET_SCAN); //$NON-NLS-1$ c.put("host", host); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_FLEET_SCANS, c); } @Get(GM_ORION) public HttpAnswer installOrion() throws AlternativeAnswerException { requirePermissions(FleetDBManager.ADD_FLEET_SCAN_PERMISSION); final String host = createPollyUrl(); final Map<String, String> c = new HashMap<String, String>(); c.put("sectorApi", OrionController.API_JSON_SECTOR); //$NON-NLS-1$ c.put("quadrantApi", OrionController.API_JSON_QUADRANT); //$NON-NLS-1$ c.put("postSectorApi", OrionController.API_JSON_POST_SECTOR); //$NON-NLS-1$ c.put("host", host); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_GM_ORION, c); } @Get(GM_ORIONV2_META) public HttpAnswer orionV2MetaData() { final Map<String, Object> c = createContext(""); //$NON-NLS-1$ final String host = createPollyUrl(); c.put("host", host); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_GM_ORIONV2_META, c); } @Get(GM_FLEET_PROFILES) public HttpAnswer installFleetProfiles() throws AlternativeAnswerException { return HttpAnswers.newTemplateAnswer(CONTENT_GM_FLEET_PROFILES, createContext("")); //$NON-NLS-1$ } @Get(GM_FLEET_PROFILES_META) public HttpAnswer fleetProfilesMetaData() { return HttpAnswers.newTemplateAnswer(CONTENT_GM_FLEET_PROFILES_META, createContext("")); //$NON-NLS-1$ } @Get(GM_ORIONV2) public HttpAnswer installOrionV2() throws AlternativeAnswerException { final String host = createPollyUrl(); final Map<String, Object> c = createContext(""); //$NON-NLS-1$ c.put("sectorApi", OrionController.API_JSON_SECTOR); //$NON-NLS-1$ c.put("quadrantApi", OrionController.API_JSON_QUADRANT); //$NON-NLS-1$ c.put("postSectorApi", OrionController.API_JSON_POST_SECTOR); //$NON-NLS-1$ c.put("host", host); //$NON-NLS-1$ return HttpAnswers.newTemplateAnswer(CONTENT_GM_ORIONV2, c); } @Get(API_TEST_LOGIN) public HttpAnswer testLogin(@Param("user") String userName, @Param("pw") String pwHash) { final User u = getMyPolly().users().getUser(userName); if (u == null || !u.getHashedPassword().equalsIgnoreCase(pwHash)) { return new GsonHttpAnswer(200, new SuccessResult(false, "")); //$NON-NLS-1$ } return new GsonHttpAnswer(200, new SuccessResult(true, "")); //$NON-NLS-1$; } private String createPollyUrl() { final String prefix = getMyPolly().webInterface().isSSL() ? "https://" : "http://"; //$NON-NLS-1$ //$NON-NLS-2$ final String host = prefix + getMyPolly().webInterface().getPublicHost() + ":" + getMyPolly().webInterface().getPort(); //$NON-NLS-1$ return host; } }