use of com.demod.dcba.CommandReporting in project Factorio-FBSR by demodude4u.
the class BlueprintBotDiscordService method processBlueprints.
private List<EmbedBuilder> processBlueprints(List<BlueprintStringData> blueprintStrings, CommandReporting reporting, JSONObject options) throws IOException {
List<EmbedBuilder> embedBuilders = new ArrayList<>();
List<Entry<Optional<String>, BufferedImage>> images = new ArrayList<>();
for (BlueprintStringData blueprintString : blueprintStrings) {
System.out.println("Parsing blueprints: " + blueprintString.getBlueprints().size());
for (Blueprint blueprint : blueprintString.getBlueprints()) {
try {
BufferedImage image = FBSR.renderBlueprint(blueprint, reporting, options);
images.add(new SimpleEntry<>(blueprint.getLabel(), image));
} catch (Exception e) {
reporting.addException(e);
}
}
}
List<Long> renderTimes = blueprintStrings.stream().flatMap(d -> d.getBlueprints().stream()).flatMap(b -> (b.getRenderTime().isPresent() ? Arrays.asList(b.getRenderTime().getAsLong()) : ImmutableList.<Long>of()).stream()).collect(Collectors.toList());
if (!renderTimes.isEmpty()) {
reporting.addField(new Field("Render Time", renderTimes.stream().mapToLong(l -> l).sum() + " ms" + (renderTimes.size() > 1 ? (" [" + renderTimes.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]") : ""), true));
}
if (images.size() == 0) {
embedBuilders.add(new EmbedBuilder().setDescription("Blueprint not found!"));
} else if (images.size() == 1) {
Entry<Optional<String>, BufferedImage> entry = images.get(0);
BufferedImage image = entry.getValue();
String url = WebUtils.uploadToHostingService("blueprint.png", image);
EmbedBuilder builder = new EmbedBuilder();
builder.setImage(url);
embedBuilders.add(builder);
} else {
List<Entry<String, String>> links = new ArrayList<>();
for (Entry<Optional<String>, BufferedImage> entry : images) {
BufferedImage image = entry.getValue();
links.add(new SimpleEntry<>(WebUtils.uploadToHostingService("blueprint.png", image), entry.getKey().orElse("")));
}
ArrayDeque<String> lines = new ArrayDeque<>();
for (int i = 0; i < links.size(); i++) {
Entry<String, String> entry = links.get(i);
if (entry.getValue() != null && !entry.getValue().trim().isEmpty()) {
lines.add("[" + entry.getValue().trim() + "](" + entry.getKey() + ")");
} else {
lines.add("[Blueprint Image " + (i + 1) + "](" + entry.getKey() + ")");
}
}
while (!lines.isEmpty()) {
EmbedBuilder builder = new EmbedBuilder();
for (int i = 0; i < 3 && !lines.isEmpty(); i++) {
StringBuilder description = new StringBuilder();
while (!lines.isEmpty()) {
if (description.length() + lines.peek().length() + 1 < MessageEmbed.VALUE_MAX_LENGTH) {
description.append(lines.pop()).append('\n');
} else {
break;
}
}
builder.addField("", description.toString(), true);
}
embedBuilders.add(builder);
}
}
if (!blueprintStrings.isEmpty() && !embedBuilders.isEmpty()) {
List<String> links = new ArrayList<>();
for (int i = 0; i < blueprintStrings.size(); i++) {
BlueprintStringData blueprintString = blueprintStrings.get(i);
String label = blueprintString.getLabel().orElse((blueprintString.getBlueprints().size() > 1 ? "Blueprint Book " : "Blueprint ") + (i + 1));
String link = WebUtils.uploadToHostingService("blueprint.txt", blueprintString.toString().getBytes());
links.add("[" + label + "](" + link + ")");
}
embedBuilders.get(0).getFields().add(0, new Field("Blueprint String" + (blueprintStrings.size() > 1 ? "s" : ""), links.stream().collect(Collectors.joining("\n")), false));
}
return embedBuilders;
}
use of com.demod.dcba.CommandReporting in project Factorio-FBSR by demodude4u.
the class FBSR method applyRendering.
private static BufferedImage applyRendering(CommandReporting reporting, int tileSize, List<Renderer> renderers, ArrayListMultimap<Direction, PanelRenderer> borderPanels, JSONObject options) throws JSONException {
Rectangle2D.Double worldBounds = computeBounds(renderers);
worldBounds.setFrameFromDiagonal(Math.floor(worldBounds.getMinX() + 0.4) - 1, Math.floor(worldBounds.getMinY() + 0.4) - 1, Math.ceil(worldBounds.getMaxX() - 0.4) + 1, Math.ceil(worldBounds.getMaxY() - 0.4) + 1);
Rectangle2D.Double centerBounds = new Rectangle2D.Double(worldBounds.x, worldBounds.y, worldBounds.width, worldBounds.height);
for (Entry<Direction, PanelRenderer> entry : borderPanels.entries()) {
Direction dir = entry.getKey();
PanelRenderer panel = entry.getValue();
switch(dir) {
case NORTH:
case SOUTH:
centerBounds.width = Math.max(centerBounds.width, panel.minWidth);
break;
case EAST:
case WEST:
centerBounds.height = Math.max(centerBounds.height, panel.minHeight);
break;
default:
System.err.println("INVALID BORDER DIRECTION: " + dir);
break;
}
}
float worldRenderScale = 1;
while (((long) (centerBounds.getWidth() * worldRenderScale * tileSize) * (long) (centerBounds.getHeight() * worldRenderScale * tileSize)) > MAX_WORLD_RENDER_PIXELS) {
worldRenderScale /= 2;
}
double borderTop = 0, borderRight = 0, borderBottom = 0, borderLeft = 0;
double borderRightBudget = 0;
for (Entry<Direction, PanelRenderer> entry : borderPanels.entries()) {
Direction dir = entry.getKey();
PanelRenderer panel = entry.getValue();
switch(dir) {
case NORTH:
borderTop += panel.minHeight;
break;
case EAST:
if (borderRightBudget + panel.minHeight > centerBounds.height) {
borderRightBudget = 0;
}
if (borderRightBudget == 0) {
borderRight += panel.minWidth;
}
borderRightBudget += panel.minHeight;
break;
case SOUTH:
borderBottom += panel.minHeight;
break;
case WEST:
borderLeft += panel.minWidth;
break;
default:
System.err.println("INVALID BORDER DIRECTION: " + dir);
break;
}
}
if (options.has("max-width")) {
int width = (int) ((centerBounds.width + borderLeft / worldRenderScale + borderRight / worldRenderScale) * worldRenderScale * tileSize);
int maxWidth = options.getInt("max-width");
if (maxWidth < 10) {
maxWidth = 10;
}
if (width > maxWidth) {
worldRenderScale = (float) ((maxWidth - tileSize * (borderLeft + borderRight)) / (centerBounds.width * tileSize));
}
}
if (options.has("max-height")) {
int height = (int) ((centerBounds.height + borderTop / worldRenderScale + borderBottom / worldRenderScale) * worldRenderScale * tileSize);
int maxHeight = options.getInt("max-height");
if (maxHeight < 10) {
maxHeight = 10;
}
if (height > maxHeight) {
worldRenderScale = (float) ((maxHeight - tileSize * (borderTop + borderBottom)) / (centerBounds.height * tileSize));
}
}
Rectangle2D.Double totalBounds = new Rectangle2D.Double(centerBounds.x - borderLeft / worldRenderScale, centerBounds.y - borderTop / worldRenderScale, centerBounds.width + borderLeft / worldRenderScale + borderRight / worldRenderScale, centerBounds.height + borderTop / worldRenderScale + borderBottom / worldRenderScale);
// System.out.println("IMAGE SCALE: " + worldRenderScale);
// System.out.println("IMAGE DIM: " + (int) (totalBounds.getWidth() *
// worldRenderScale * tileSize) + ","
// + (int) (totalBounds.getHeight() * worldRenderScale * tileSize));
int imageWidth = (int) (totalBounds.getWidth() * worldRenderScale * tileSize);
int imageHeight = (int) (totalBounds.getHeight() * worldRenderScale * tileSize);
System.out.println("\t" + imageWidth + "x" + imageHeight + " (" + worldRenderScale + ")");
BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
BufferedImage shadowImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D shadowG = shadowImage.createGraphics();
AffineTransform noXform = g.getTransform();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.scale(image.getWidth() / totalBounds.getWidth(), image.getHeight() / totalBounds.getHeight());
g.translate(-totalBounds.getX(), -totalBounds.getY());
AffineTransform worldXform = g.getTransform();
shadowG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
shadowG.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
shadowG.setTransform(worldXform);
// Background
g.setColor(GROUND_COLOR);
g.fill(totalBounds);
// Grid Lines
g.setStroke(GRID_STROKE);
g.setColor(GRID_COLOR);
for (double x = Math.round(worldBounds.getMinX()); x <= worldBounds.getMaxX(); x++) {
g.draw(new Line2D.Double(x, worldBounds.getMinY(), x, worldBounds.getMaxY()));
}
for (double y = Math.round(worldBounds.getMinY()); y <= worldBounds.getMaxY(); y++) {
g.draw(new Line2D.Double(worldBounds.getMinX(), y, worldBounds.getMaxX(), y));
}
renderers.stream().filter(r -> r instanceof EntityRenderer).map(r -> (EntityRenderer) r).forEach(r -> {
try {
r.renderShadows(shadowG);
} catch (Exception e) {
reporting.addException(e);
}
});
shadowG.dispose();
RenderUtils.halveAlpha(shadowImage);
renderers.add(new Renderer(Layer.SHADOW_BUFFER, worldBounds) {
@Override
public void render(Graphics2D g) throws Exception {
AffineTransform tempXform = g.getTransform();
g.setTransform(noXform);
g.drawImage(shadowImage, 0, 0, null);
g.setTransform(tempXform);
}
});
boolean debugBounds = options.optBoolean("debug-bounds");
renderers.stream().sorted((r1, r2) -> {
int ret;
ret = r1.getLayer().compareTo(r2.getLayer());
if (ret != 0) {
return ret;
}
Rectangle2D.Double b1 = r1.getBounds();
Rectangle2D.Double b2 = r2.getBounds();
ret = Double.compare(b1.getMinY(), b2.getMinY());
if (ret != 0) {
return ret;
}
ret = Double.compare(b1.getMinX(), b2.getMinX());
if (ret != 0) {
return ret;
}
ret = r1.getLayer().compareTo(r2.getLayer());
return ret;
}).forEach(r -> {
try {
r.render(g);
if (debugBounds) {
g.setStroke(new BasicStroke(1f / 32f));
g.setColor(Color.magenta);
g.draw(r.bounds);
}
} catch (Exception e) {
reporting.addException(e);
}
});
g.setTransform(worldXform);
// Grid Numbers
g.setColor(GRID_COLOR);
g.setFont(new Font("Monospaced", Font.BOLD, 1).deriveFont(0.6f));
for (double x = Math.round(worldBounds.getMinX()) + 1, i = 1; x <= worldBounds.getMaxX() - 2; x++, i++) {
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) x + 0.2f, (float) (worldBounds.getMaxY() - 1 + 0.65f));
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) x + 0.2f, (float) (worldBounds.getMinY() + 0.65f));
}
for (double y = Math.round(worldBounds.getMinY()) + 1, i = 1; y <= worldBounds.getMaxY() - 2; y++, i++) {
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) (worldBounds.getMaxX() - 1 + 0.2f), (float) y + 0.65f);
g.drawString(String.format("%02d", (int) Math.round(i) % 100), (float) (worldBounds.getMinX() + 0.2f), (float) y + 0.65f);
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMinX(), centerBounds.getMinY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.NORTH)) {
g.setTransform(worldXform);
bounds.y -= panel.minHeight / worldRenderScale;
bounds.width = centerBounds.width;
bounds.height = panel.minHeight;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
}
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMaxX(), centerBounds.getMinY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.EAST)) {
g.setTransform(worldXform);
if (bounds.y + panel.minHeight > centerBounds.getMaxY()) {
bounds.y = centerBounds.getMinY();
bounds.x += panel.minWidth;
}
bounds.width = panel.minWidth;
bounds.height = panel.minHeight;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
bounds.y += panel.minHeight / worldRenderScale;
}
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMinX(), centerBounds.getMaxY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.SOUTH)) {
g.setTransform(worldXform);
bounds.width = centerBounds.width;
bounds.height = panel.minHeight;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
bounds.y += panel.minHeight / worldRenderScale;
}
}
{
Rectangle2D.Double bounds = new Rectangle2D.Double(centerBounds.getMinX(), centerBounds.getMinY(), 0, 0);
for (PanelRenderer panel : borderPanels.get(Direction.WEST)) {
g.setTransform(worldXform);
bounds.x -= panel.minWidth / worldRenderScale;
bounds.width = panel.minWidth;
bounds.height = centerBounds.height;
g.translate(bounds.x, bounds.y);
g.scale(1 / worldRenderScale, 1 / worldRenderScale);
try {
panel.render(g, bounds.width, bounds.height);
} catch (Exception e) {
reporting.addException(e);
}
}
}
Level level = reporting.getLevel();
if (level != Level.INFO) {
g.setTransform(worldXform);
g.setStroke(GRID_STROKE);
g.setColor(level.getColor().darker());
g.draw(centerBounds);
}
g.dispose();
return image;
}
use of com.demod.dcba.CommandReporting in project Factorio-FBSR by demodude4u.
the class WebAPIService method startUp.
@Override
protected void startUp() {
ServiceFinder.addService(this);
configJson = Config.get().getJSONObject("webapi");
String address = configJson.optString("bind", "0.0.0.0");
int port = configJson.optInt("port", 80);
On.address(address).port(port);
On.post("/blueprint").serve((req, resp) -> {
System.out.println("Web API POST!");
CommandReporting reporting = new CommandReporting("Web API / " + req.clientIpAddress() + " / " + Optional.ofNullable(req.header("User-Agent", null)).orElse("<Unknown>"), null, Instant.now());
try {
JSONObject body = null;
BufferedImage returnSingleImage = null;
List<String> infos = new ArrayList<>();
List<Entry<Optional<String>, String>> imageLinks = new ArrayList<>();
boolean useLocalStorage = configJson.optBoolean("use-local-storage", false);
try {
if (req.body() == null) {
resp.code(400);
resp.plain("Body is empty!");
reporting.addException(new IllegalArgumentException("Body is empty!"));
return resp;
}
try {
body = new JSONObject(new String(req.body()));
} catch (Exception e) {
reporting.addException(e);
resp.code(400);
resp.plain("Malformed JSON: " + e.getMessage());
return resp;
}
reporting.setCommand(body.toString(2));
/*
* { "blueprint": "0e...", (required) "max-width": 1234, "max-height": 1234,
* "show-info-panels": false } | v { "info": [ "message 1!", "message 2!", ...
* ], "images": [ { "label": "Blueprint Label", "link":
* "https://cdn.discordapp.com/..." (or) "1563569893008.png" } ] }
*/
String content = body.getString("blueprint");
List<BlueprintStringData> blueprintStrings = BlueprintFinder.search(content, reporting);
List<Blueprint> blueprints = blueprintStrings.stream().flatMap(s -> s.getBlueprints().stream()).collect(Collectors.toList());
for (Blueprint blueprint : blueprints) {
try {
BufferedImage image = FBSR.renderBlueprint(blueprint, reporting, body);
if (body.optBoolean("return-single-image")) {
returnSingleImage = image;
break;
}
if (useLocalStorage) {
File localStorageFolder = new File(configJson.getString("local-storage"));
String imageLink = saveToLocalStorage(localStorageFolder, image);
imageLinks.add(new SimpleEntry<>(blueprint.getLabel(), imageLink));
} else {
imageLinks.add(new SimpleEntry<>(blueprint.getLabel(), WebUtils.uploadToHostingService("blueprint.png", image).toString()));
}
} catch (Exception e) {
reporting.addException(e);
}
}
List<Long> renderTimes = blueprintStrings.stream().flatMap(d -> d.getBlueprints().stream()).flatMap(b -> (b.getRenderTime().isPresent() ? Arrays.asList(b.getRenderTime().getAsLong()) : ImmutableList.<Long>of()).stream()).collect(Collectors.toList());
if (!renderTimes.isEmpty()) {
reporting.addField(new Field("Render Time", renderTimes.stream().mapToLong(l -> l).sum() + " ms" + (renderTimes.size() > 1 ? (" [" + renderTimes.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]") : ""), true));
}
if (blueprintStrings.stream().anyMatch(d -> d.getBlueprints().stream().anyMatch(b -> b.isModsDetected()))) {
infos.add("(Modded features are shown as question marks)");
}
} catch (Exception e) {
reporting.addException(e);
}
if (returnSingleImage != null) {
resp.contentType(MediaType.IMAGE_PNG);
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(returnSingleImage, "PNG", baos);
baos.flush();
resp.body(baos.toByteArray());
}
return resp;
} else {
JSONObject result = new JSONObject();
Utils.terribleHackToHaveOrderedJSONObject(result);
if (!reporting.getExceptions().isEmpty()) {
resp.code(400);
infos.add("There was a problem completing your request.");
reporting.getExceptions().forEach(Exception::printStackTrace);
}
if (!infos.isEmpty()) {
result.put("info", new JSONArray(infos));
}
if (imageLinks.size() == 1 && !useLocalStorage) {
reporting.setImageURL(imageLinks.get(0).getValue());
}
if (!imageLinks.isEmpty()) {
JSONArray images = new JSONArray();
for (Entry<Optional<String>, String> pair : imageLinks) {
JSONObject image = new JSONObject();
Utils.terribleHackToHaveOrderedJSONObject(image);
pair.getKey().ifPresent(l -> image.put("label", l));
image.put("link", pair.getValue());
images.put(image);
}
result.put("images", images);
}
resp.contentType(MediaType.JSON);
String responseBody = result.toString(2);
resp.body(responseBody.getBytes());
reporting.addField(new Field("Response", responseBody, false));
return resp;
}
} finally {
ServiceFinder.findService(BlueprintBotDiscordService.class).ifPresent(s -> s.getBot().submitReport(reporting));
}
});
System.out.println("Web API Initialized at " + address + ":" + port);
}
use of com.demod.dcba.CommandReporting in project Factorio-FBSR by demodude4u.
the class BlueprintBotDiscordService method startUp.
@Override
protected void startUp() throws JSONException, IOException {
configJson = Config.get().getJSONObject("discord");
DataTable table = FactorioData.getTable();
System.out.println("Factorio " + FBSR.getVersion() + " Data Loaded.");
bot = //
DCBA.builder().setInfo(//
"Blueprint Bot").withSupport(//
"Find Demod and complain to him!\nYou can find him over in the [Factorio Discord.](https://discord.gg/factorio)").withTechnology("[FBSR](https://github.com/demodude4u/Factorio-FBSR)", //
"Factorio Blueprint String Renderer").withTechnology("[FactorioDataWrapper](https://github.com/demodude4u/Java-Factorio-Data-Wrapper)", //
"Factorio Data Scraper").withCredits("Attribution", //
"[Factorio](https://www.factorio.com/) - Made by Wube Software").withCredits("Contributors", //
"Demod").withCredits("Contributors", //
"Bilka").withCredits("Contributors", //
"FactorioBlueprints").withCredits("Contributors", //
"acid").withCredits("Contributors", //
"Vilsol").withInvite(new Permission[] { //
Permission.VIEW_CHANNEL, //
Permission.MESSAGE_SEND, //
Permission.MESSAGE_ATTACH_FILES, //
Permission.MESSAGE_EXT_EMOJI, //
Permission.MESSAGE_EMBED_LINKS, //
Permission.MESSAGE_HISTORY, //
Permission.MESSAGE_ADD_REACTION }).withCustomField("Need old !blueprint commands?", //
"[BlueprintBot Legacy Invite Link](https://discord.com/oauth2/authorize?scope=bot&client_id=958469202824552498&permissions=379968)").addMessageCommand("Blueprint Image", event -> handleBlueprintMessageCommand(event)).addSlashCommand("blueprint/string", "Renders an image of the blueprint string.", //
event -> handleBlueprintSlashCommand(event)).withParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.BOOLEAN, "simple", "Set True to show just the image, no side panels.").withOptionalParam(OptionType.INTEGER, "max-width", "Maximum width of image, in pixels.").withOptionalParam(OptionType.INTEGER, "max-height", "Maximum height of image, in pixels.").withLegacyWarning("blueprint", //
"bp").addSlashCommand("blueprint/url", "Renders an image of the blueprint url.", //
event -> handleBlueprintSlashCommand(event)).withParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.BOOLEAN, "simple", "Set True to show just the image, no side panels.").withOptionalParam(OptionType.INTEGER, "max-width", "Maximum width of image, in pixels.").withOptionalParam(OptionType.INTEGER, "max-height", "Maximum height of image, in pixels.").addSlashCommand("blueprint/file", "Renders an image of the blueprint attachment.", //
event -> handleBlueprintSlashCommand(event)).withParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withOptionalParam(OptionType.BOOLEAN, "simple", "Set True to show just the image, no side panels.").withOptionalParam(OptionType.INTEGER, "max-width", "Maximum width of image, in pixels.").withOptionalParam(OptionType.INTEGER, "max-height", "Maximum height of image, in pixels.").addSlashCommand("json", "Provides a dump of the json data in the specified blueprint string.", //
event -> handleBlueprintJsonCommand(event)).withOptionalParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withLegacyWarning(//
"blueprintJSON").addSlashCommand("upgrade/belts", "Converts all yellow belts into red belts, and all red belts into blue belts.", //
event -> handleBlueprintUpgradeBeltsCommand(event)).withOptionalParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withLegacyWarning(//
"blueprintUpgradeBelts").addSlashCommand("items", "Prints out all of the items needed by the blueprint.", //
event -> handleBlueprintItemsCommand(event)).withOptionalParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withLegacyWarning("blueprintItems", //
"bpItems").addSlashCommand("raw/items", "Prints out all of the raw items needed by the blueprint.", //
event -> handleBlueprintItemsRawCommand(event)).withOptionalParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withLegacyWarning("blueprintRawItems", //
"bpRawItems").addSlashCommand("counts", "Prints out the total counts of entities, items and tiles needed by the blueprint.", event -> handleBlueprintTotalsCommand(event)).withOptionalParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withLegacyWarning("blueprintCounts", //
"bpCounts").addSlashCommand("book/extract", "Provides an collection of blueprint strings contained within the specified blueprint book.", //
event -> handleBlueprintBookExtractCommand(event)).withOptionalParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withLegacyWarning(//
"blueprintBookExtract").addSlashCommand("book/assemble", "Combines all blueprints (including from other books) from multiple strings into a single book.", //
event -> handleBlueprintBookAssembleCommand(event)).withOptionalParam(OptionType.STRING, "string", //
"Blueprint string.").withOptionalParam(OptionType.STRING, "url", //
"Url containing blueprint string.").withOptionalParam(OptionType.ATTACHMENT, "file", //
"File containing blueprint string.").withLegacyWarning(//
"blueprintBookAssemble").addSlashCommand("prototype/entity", "Lua data for the specified entity prototype.", createPrototypeCommandHandler("entity", table.getEntities()), //
createPrototypeAutoCompleteHandler(table.getEntities())).withAutoParam(OptionType.STRING, "name", //
"Prototype name of the entity.").withLegacyWarning(//
"prototypeEntity").addSlashCommand("prototype/recipe", "Lua data for the specified recipe prototype.", createPrototypeCommandHandler("recipe", table.getRecipes()), //
createPrototypeAutoCompleteHandler(table.getRecipes())).withAutoParam(OptionType.STRING, "name", //
"Prototype name of the recipe.").withLegacyWarning(//
"prototypeRecipe").addSlashCommand("prototype/fluid", "Lua data for the specified fluid prototype.", createPrototypeCommandHandler("fluid", table.getFluids()), //
createPrototypeAutoCompleteHandler(table.getFluids())).withAutoParam(OptionType.STRING, "name", //
"Prototype name of the fluid.").withLegacyWarning(//
"prototypeFluid").addSlashCommand("prototype/item", "Lua data for the specified item prototype.", createPrototypeCommandHandler("item", table.getItems()), //
createPrototypeAutoCompleteHandler(table.getItems())).withAutoParam(OptionType.STRING, "name", //
"Prototype name of the item.").withLegacyWarning(//
"prototypeItem").addSlashCommand("prototype/technology", "Lua data for the specified technology prototype.", createPrototypeCommandHandler("technology", table.getTechnologies()), //
createPrototypeAutoCompleteHandler(table.getTechnologies())).withAutoParam(OptionType.STRING, "name", //
"Prototype name of the technology.").withLegacyWarning(//
"prototypeTechnology").addSlashCommand("prototype/equipment", "Lua data for the specified equipment prototype.", createPrototypeCommandHandler("equipment", table.getEquipments()), //
createPrototypeAutoCompleteHandler(table.getEquipments())).withAutoParam(OptionType.STRING, "name", //
"Prototype name of the equipment.").withLegacyWarning(//
"prototypeEquipment").addSlashCommand("prototype/tile", "Lua data for the specified tile prototype.", createPrototypeCommandHandler("tile", table.getTiles()), //
createPrototypeAutoCompleteHandler(table.getTiles())).withAutoParam(OptionType.STRING, "name", //
"Prototype name of the tile.").withLegacyWarning(//
"prototypeTile").addSlashCommand("data/raw", "Lua from `data.raw` for the specified key.", //
createDataRawCommandHandler(table::getRaw)).withParam(OptionType.STRING, "path", //
"Path to identify which key.").withLegacyWarning(//
"dataRaw").withCustomSetup(builder -> {
return //
builder.setChunkingFilter(//
ChunkingFilter.NONE);
}).create();
bot.startAsync().awaitRunning();
hostingChannelID = configJson.getString("hosting_channel_id");
ServiceFinder.addService(this);
ServiceFinder.addService(WatchdogReporter.class, new WatchdogReporter() {
@Override
public void notifyInactive(String label) {
CommandReporting reporting = new CommandReporting("Watchdog Reporter", null, null);
reporting.addWarning(label + " has gone inactive!");
bot.submitReport(reporting);
}
@Override
public void notifyReactive(String label) {
CommandReporting reporting = new CommandReporting("Watchdog Reporter", null, null);
reporting.addWarning(label + " is now active again!");
bot.submitReport(reporting);
}
});
}
use of com.demod.dcba.CommandReporting in project Factorio-FBSR by demodude4u.
the class BlueprintBotRedditService method processContent.
private List<String> processContent(String content, String link, String category, String author, Optional<WatchdogService> watchdog) {
String contentLowerCase = content.toLowerCase();
if (!contentLowerCase.contains(summonKeyword) && !contentLowerCase.contains(myUserNameMention)) {
return ImmutableList.of();
}
CommandReporting reporting = new CommandReporting("Reddit / " + category + " / " + author, REDDIT_AUTHOR_URL, Instant.now());
reporting.setCommand(content);
List<String> infos = new ArrayList<>();
List<Entry<Optional<String>, String>> imageLinks = new ArrayList<>();
try {
List<BlueprintStringData> blueprintStrings = BlueprintFinder.search(content, reporting);
List<Blueprint> blueprints = blueprintStrings.stream().flatMap(s -> s.getBlueprints().stream()).collect(Collectors.toList());
for (Blueprint blueprint : blueprints) {
watchdog.ifPresent(w -> w.notifyActive(WATCHDOG_LABEL));
try {
BufferedImage image = FBSR.renderBlueprint(blueprint, reporting);
imageLinks.add(new SimpleEntry<>(blueprint.getLabel(), WebUtils.uploadToHostingService("blueprint.png", image).toString()));
} catch (Exception e) {
reporting.addException(e);
}
}
List<Long> renderTimes = blueprintStrings.stream().flatMap(d -> d.getBlueprints().stream()).flatMap(b -> (b.getRenderTime().isPresent() ? Arrays.asList(b.getRenderTime().getAsLong()) : ImmutableList.<Long>of()).stream()).collect(Collectors.toList());
if (!renderTimes.isEmpty()) {
reporting.addField(new Field("Render Time", renderTimes.stream().mapToLong(l -> l).sum() + " ms" + (renderTimes.size() > 1 ? (" [" + renderTimes.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]") : ""), true));
}
if (blueprintStrings.stream().anyMatch(d -> d.getBlueprints().stream().anyMatch(b -> b.isModsDetected()))) {
infos.add("(Modded features are shown as question marks)");
}
} catch (Exception e) {
reporting.addException(e);
}
List<String> lines = new ArrayList<>();
if (imageLinks.size() > 1) {
int id = 1;
List<Entry<URL, String>> links = new ArrayList<>();
for (Entry<Optional<String>, String> pair : imageLinks) {
Optional<String> label = pair.getKey();
String url = pair.getValue();
try {
links.add(new SimpleEntry<>(new URL(url), label.orElse(null)));
} catch (MalformedURLException e) {
reporting.addException(e);
}
}
lines.add("Blueprint Images:");
for (Entry<Optional<String>, String> pair : imageLinks) {
Optional<String> label = pair.getKey();
String url = pair.getValue();
lines.add("[" + (id++) + ": " + label.orElse("Blueprint") + "](" + url + ")");
}
} else if (!imageLinks.isEmpty()) {
Entry<Optional<String>, String> pair = imageLinks.get(0);
Optional<String> label = pair.getKey();
String url = pair.getValue();
lines.add("[Blueprint Image" + label.map(s -> " (" + s + ")").orElse("") + "](" + url + ")");
reporting.setImageURL(url);
}
for (String info : infos) {
lines.add(" " + info);
}
if (!reporting.getExceptions().isEmpty()) {
lines.add(" Sorry, There was a problem completing your request.");
}
ServiceFinder.findService(BlueprintBotDiscordService.class).ifPresent(s -> s.getBot().submitReport(reporting));
if (!lines.isEmpty()) {
List<String> res = new ArrayList<>();
String message = "";
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i) + "\n\n";
if (message.length() + line.length() < 10000) {
message += line;
} else {
res.add(message);
message = "Blueprint Images (Continued):\n\n";
}
}
res.add(message);
return res;
} else {
return ImmutableList.of();
}
}
Aggregations