Files
leagues-tools/group-ironmen-master/cache/MapLabelDumper.java

265 lines
7.1 KiB
Java

package net.runelite.cache;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import net.runelite.cache.definitions.AreaDefinition;
import net.runelite.cache.definitions.FontDefinition;
import net.runelite.cache.definitions.SpriteDefinition;
import net.runelite.cache.definitions.WorldMapElementDefinition;
import net.runelite.cache.fs.Store;
import net.runelite.cache.region.Position;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class MapLabelDumper
{
private static String outputDirectory;
public static void main(String[] args) throws IOException
{
Options options = new Options();
options.addOption(Option.builder().longOpt("cachedir").hasArg().required().build());
options.addOption(Option.builder().longOpt("outputdir").hasArg().required().build());
CommandLineParser parser = new DefaultParser();
CommandLine cmd;
try
{
cmd = parser.parse(options, args);
}
catch (ParseException ex)
{
System.err.println("Error parsing command line options: " + ex.getMessage());
System.exit(-1);
return;
}
final String cacheDirectory = cmd.getOptionValue("cachedir");
outputDirectory = cmd.getOptionValue("outputdir");
File base = new File(cacheDirectory);
File outDir = new File(outputDirectory);
outDir.mkdirs();
try (Store store = new Store(base))
{
store.load();
WorldMapManager worldMapManager = new WorldMapManager(store);
worldMapManager.load();
AreaManager areas = new AreaManager(store);
areas.load();
FontManager fonts = new FontManager(store);
fonts.load();
SpriteManager sprites = new SpriteManager(store);
sprites.load();
List<Object[]> result = new ArrayList<>();
FontName[] fontSizes = new FontName[]{FontName.VERDANA_11, FontName.VERDANA_13, FontName.VERDANA_15};
List<WorldMapElementDefinition> elements = worldMapManager.getElements();
int x = 0;
for (WorldMapElementDefinition element : elements)
{
AreaDefinition area = areas.getArea(element.getAreaDefinitionId());
Position worldPosition = element.getWorldPosition();
if (area == null || area.getName() == null)
{
continue;
}
result.add(new Object[]{
worldPosition.getX(),
worldPosition.getY(),
worldPosition.getZ()
});
FontName fontSize = fontSizes[area.getTextScale()];
FontDefinition font = fonts.findFontByName(fontSize.getName());
String areaLabel = area.getName();
String[] lines = areaLabel.split("<br>");
int ascent = 0;
int startImageWidth = 0;
for (String line : lines)
{
startImageWidth = Math.max(startImageWidth, font.stringWidth(line));
}
startImageWidth += 200;
int startImageHeight = 300;
BufferedImage image = new BufferedImage(startImageWidth, startImageHeight, BufferedImage.TYPE_INT_ARGB);
for (String line : lines)
{
int advance = 0;
int stringWidth = font.stringWidth(line);
for (int i = 0; i < line.length(); ++i)
{
char c = line.charAt(i);
SpriteDefinition sprite = sprites.findSpriteByArchiveName(fontSize.getName(), c);
if (sprite.getWidth() != 0 && sprite.getHeight() != 0)
{
blitGlyph(image,
advance + (startImageWidth / 2) - (stringWidth / 2),
ascent + (startImageHeight / 2),
area.getTextColor(),
sprite
);
}
advance += font.getAdvances()[c];
}
ascent += font.getAscent() / 2;
}
int imageTop = 0;
int imageBottom = 0;
for (int y = 0; y < startImageHeight; ++y) {
boolean lineHasPixels = false;
for (int xx = 0; xx < startImageWidth; ++xx)
{
if (image.getRGB(xx, y) != 0)
{
lineHasPixels = true;
}
}
if (lineHasPixels)
{
if (imageTop == 0)
{
imageTop = y;
}
else
{
imageBottom = Math.max(imageBottom, y);
}
}
}
imageBottom += 1;
int imageLeft = 0;
int imageRight = 0;
for (int xx = 0; xx < startImageWidth; ++xx)
{
boolean columnHasPixels = false;
for (int y = 0; y < startImageHeight; ++y)
{
if (image.getRGB(xx, y) != 0)
{
columnHasPixels = true;
}
}
if (columnHasPixels)
{
if (imageLeft == 0)
{
imageLeft = xx;
}
else
{
imageRight = Math.max(imageRight, xx);
}
}
}
imageRight += 1;
int imageHeight = imageBottom - imageTop;
int imageWidth = imageRight - imageLeft;
BufferedImage finalImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = finalImage.createGraphics();
g.drawImage(
image,
0,
0,
imageWidth,
imageHeight,
imageLeft,
imageTop,
imageRight,
imageBottom,
null
);
File imageFile = new File(outDir, "" + (x++) + ".png");
ImageIO.write(finalImage, "png", imageFile);
}
try {
Gson gson = new Gson();
File jsonFile = new File(outDir, "map-labels.json");
FileWriter writer = new FileWriter(jsonFile);
gson.toJson(result, writer);
writer.flush();
writer.close();
} catch (Exception ex) {
log.error("Failed to write map-labels.json", ex);
}
}
}
private static void blitGlyph(BufferedImage dst, int x, int y, int color, SpriteDefinition glyph)
{
int[] pixels = glyph.getPixels();
int[] shadowPixels = new int[pixels.length];
for (int i = 0; i < pixels.length; ++i)
{
if (pixels[i] != 0)
{
pixels[i] = color;
shadowPixels[i] = 0xFF000000;
}
}
SpriteDefinition shadow = new SpriteDefinition();
shadow.setPixels(shadowPixels);
shadow.setOffsetX(glyph.getOffsetX());
shadow.setOffsetY(glyph.getOffsetY());
shadow.setWidth(glyph.getWidth());
shadow.setHeight(glyph.getHeight());
blitIcon(dst, x + 1, y + 1, shadow);
blitIcon(dst, x, y, glyph);
}
private static void blitIcon(BufferedImage dst, int x, int y, SpriteDefinition sprite)
{
x += sprite.getOffsetX();
y += sprite.getOffsetY();
int ymin = Math.max(0, -y);
int ymax = Math.min(sprite.getHeight(), dst.getHeight() - y);
int xmin = Math.max(0, -x);
int xmax = Math.min(sprite.getWidth(), dst.getWidth() - x);
for (int yo = ymin; yo < ymax; yo++)
{
for (int xo = xmin; xo < xmax; xo++)
{
int rgb = sprite.getPixels()[xo + (yo * sprite.getWidth())];
if (rgb != 0)
{
dst.setRGB(x + xo, y + yo, rgb | 0xFF000000);
}
}
}
}
}