Compare commits

...

11 Commits

Author SHA1 Message Date
zzz
e1620742b3 bump -1 2024-05-12 10:45:18 -04:00
zzz
4fa1965b11 rrd4j: Hide axis ticks
as recommended by drzed
2024-05-12 10:43:08 -04:00
zzz
4e9ac43b55 rrd4j: Change unit scale from 'k' to 'K'
which is not correct by the SI standard,
but it matches the rest of the console and common practice.
Also fix rrd4j bug that used micro in one place and u in the other.
2024-05-12 10:12:21 -04:00
zzz
177fbad865 Console: Update rrd4j to 3.9.1 preview
from rrd4j github head.
Includes our ImageWorker contribution which should speed up rendering.
2024-05-12 09:58:42 -04:00
zzz
84dbf53f95 Tunnels: Validate peer RI expiration in TunnelPeerSelector
Previously, the expiration was not validated until BuildRequestor,
where the build would fail.
Old bug, but was exacerbated by recent change to KNDF.validate() to
enforce expiration at startup if the downtime was short.
2024-05-08 09:43:52 -04:00
zzz
3f2bfe8871 Router: Publish G cap if symmetric natted 2024-05-08 08:06:45 -04:00
zzz
603bca476a i2ptunnel: Fix custom options form width (light theme) 2024-05-08 06:56:14 -04:00
b3fc35541c Debian: check in updated Debian changelogs 2024-05-07 11:21:51 -04:00
44190bb52d CI: remove mavenCentral.deps target from CI since it's actually covered by maven-dev-release.sh 2024-05-06 18:28:57 -04:00
2facca2308 Checklist: add note about in-network update hosts 2024-05-06 18:11:23 -04:00
7cf9daa381 2.5.1: Update version 2024-05-06 15:38:00 -04:00
22 changed files with 354 additions and 176 deletions

View File

@ -56,8 +56,6 @@ jobs:
echo "noExe=true" >> override.properties
- name: test Debian build with Ant
run: ant distclean
- name: build mavenCentral deps with Ant
run: ant mavenCentral.deps
- name: build javadoc with Ant
run: ant distclean javadoc updater
- name: zip javadoc
@ -95,8 +93,6 @@ jobs:
echo "build.built-by=GitHub Actions" >> override.properties
echo "noExe=true" >> override.properties
echo "javac.compilerargs=-bootclasspath $HOME/openjdk-7/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar:$HOME/openjdk-7/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/jce.jar -Xlint:all" >> override.properties
- name: build mavenCentral deps with Ant
run: ant mavenCentral.deps
- name: build Maven dev build with Ant
run: ./installer/resources/maven-dev-release.sh 1
- name: Upload servlet-i2p.jar

View File

@ -267,7 +267,7 @@ Applications:
See licenses/LICENSE-Apache2.0.txt
See licenses/LICENSE-ECLIPSE-1.0.html
RRD4J 3.9 (jrobin.jar):
RRD4J 3.9.1 (jrobin.jar):
Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
Copyright (c) 2011 The OpenNMS Group, Inc.
Copyright 2011 The RRD4J Authors.

View File

@ -997,7 +997,7 @@
} // !isRouterContext
%>
</table>
<table class="tunnelConfig" id="customOptions">
<table class="tunnelConfig" id="advancedOptions">
<tr>
<th colspan="2">
<%=intl._t("Custom options")%>

View File

@ -930,6 +930,7 @@ input.tunnelName, input.tunnelDescriptionText, #userAgents, .freetext.tunnelDesc
#customOptions {
margin-top: 15px !important;
width: 99%;
}
#tunnelDepth, #tunnelVariance, #tunnelQuantity, #tunnelBackupQuantity,

View File

@ -66,7 +66,7 @@
<property name="workspace.changes.tr" value="" />
<jar destfile="./build/jrobin.jar" basedir="./build/obj" includes="**/*.class">
<manifest>
<attribute name="Implementation-Version" value="3.8" />
<attribute name="Implementation-Version" value="3.9.1" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />

View File

@ -310,10 +310,7 @@ public abstract class RrdBackendFactory implements Closeable {
}
@Override
public void clear() {
try {
backend.close();
} catch (IOException e) {
}
// backend doesn't need to be closed here as it already happens in RrdBackend.rrdClose()
backend = null;
super.clear();
}

View File

@ -300,6 +300,9 @@ public class RrdDbPool {
RrdEntry ref;
try {
ref = getEntry(dburi, false);
} catch (IllegalStateException e) {
// This means that corresponding database has been already closed before, so returning immediately.
return;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("Release interrupted for " + rrdDb.getPath(), e);

View File

@ -0,0 +1,161 @@
package org.rrd4j.graph;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;
class BufferedImageWorker extends ImageWorker {
static class Builder {
private int width = 1;
private int height = 1;
private RrdGraphDef gdef;
private ImageWriter writer;
private ImageWriteParam imageWriteParam;
BufferedImageWorker build() {
return new BufferedImageWorker(this);
}
private ImageWriteParam getImageParams() {
ImageWriteParam iwp = writer.getDefaultWriteParam();
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
//If lossy compression, use the quality
if (! imgProvider.isFormatLossless()) {
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(gdef.imageQuality);
}
if (iwp.canWriteProgressive()) {
iwp.setProgressiveMode(gdef.interlaced ? ImageWriteParam.MODE_DEFAULT:ImageWriteParam.MODE_DISABLED);
}
return iwp;
}
public Builder setWidth(int width) {
this.width = width;
return this;
}
public Builder setHeight(int height) {
this.height = height;
return this;
}
public Builder setGdef(RrdGraphDef gdef) {
this.gdef = gdef;
if (this.writer == null) {
this.writer = ImageIO.getImageWritersByFormatName(gdef.imageFormat).next();
}
if (this.imageWriteParam == null) {
this.imageWriteParam = getImageParams();
}
return this;
}
public Builder setWriter(ImageWriter writer) {
this.writer = writer;
if (this.imageWriteParam == null) {
this.imageWriteParam = getImageParams();
}
return this;
}
public Builder setImageWriteParam(ImageWriteParam imageWriteParam) {
this.imageWriteParam = imageWriteParam;
return this;
}
}
public static Builder getBuilder() {
return new Builder();
}
private BufferedImage img;
private int imgWidth;
private int imgHeight;
private AffineTransform initialAffineTransform;
private final ImageWriter writer;
private final ImageWriteParam iwp;
private BufferedImageWorker(Builder builder) {
this.imgHeight = builder.height;
this.imgWidth = builder.width;
this.writer = builder.writer;
this.iwp = builder.imageWriteParam;
resize(imgWidth, imgHeight);
}
/*
* Not for use, only for tests
*/
BufferedImageWorker(int width, int height) {
this.imgHeight = height;
this.imgWidth = width;
this.writer = ImageIO.getImageWritersByFormatName("png").next();
this.iwp = writer.getDefaultWriteParam();
resize(imgWidth, imgHeight);
}
protected void resize(int width, int height) {
imgWidth = width;
imgHeight = height;
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
setG2d(g2d);
initialAffineTransform = g2d.getTransform();
setAntiAliasing(false);
setTextAntiAliasing(false);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
}
protected void reset(Graphics2D g2d) {
g2d.setTransform(initialAffineTransform);
g2d.setClip(0, 0, imgWidth, imgHeight);
}
protected void makeImage(OutputStream stream) throws IOException {
BufferedImage outputImage = img;
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
img.coerceData(false);
// Some format can't manage 16M colors images
// JPEG don't like transparency
if (! imgProvider.canEncodeImage(outputImage) || "image/jpeg".equalsIgnoreCase(imgProvider.getMIMETypes()[0])) {
int w = img.getWidth();
int h = img.getHeight();
outputImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
outputImage.getGraphics().drawImage(img, 0, 0, w, h, null);
if (! imgProvider.canEncodeImage(outputImage)) {
throw new IllegalArgumentException("Invalid image type");
}
}
if (! imgProvider.canEncodeImage(outputImage)) {
throw new IllegalArgumentException("Invalid image type");
}
try (ImageOutputStream imageStream = ImageIO.createImageOutputStream(stream)) {
writer.setOutput(imageStream);
writer.write(null, new IIOImage(outputImage, null, null), iwp);
imageStream.flush();
} catch (IOException e) {
writer.abort();
throw e;
} finally {
writer.dispose();
}
}
}

View File

@ -1,223 +1,211 @@
package org.rrd4j.graph;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.*;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;
/**
* An abstract class, that allows to use custom {@link Graphics2D}. To use it the construct should build it and call
* {@link #setG2d(Graphics2D)} when finished.
*/
public abstract class ImageWorker {
class ImageWorker {
private static final String DUMMY_TEXT = "Dummy";
private static final int IMG_BUFFER_CAPACITY = 10000; // bytes
private BufferedImage img;
private Graphics2D g2d;
private int imgWidth, imgHeight;
private AffineTransform initialAffineTransform;
ImageWorker(int width, int height) {
resize(width, height);
}
void resize(int width, int height) {
protected void setG2d(Graphics2D g2d) {
if (g2d != null) {
dispose();
}
imgWidth = width;
imgHeight = height;
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
initialAffineTransform = g2d.getTransform();
setAntiAliasing(false);
setTextAntiAliasing(false);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
this.g2d = g2d;
}
void clip(int x, int y, int width, int height) {
protected abstract void resize(int width, int height);
protected void clip(int x, int y, int width, int height) {
g2d.setClip(x, y, width, height);
}
void transform(int x, int y, double angle) {
protected void transform(int x, int y, double angle) {
g2d.translate(x, y);
g2d.rotate(angle);
}
void reset() {
g2d.setTransform(initialAffineTransform);
g2d.setClip(0, 0, imgWidth, imgHeight);
protected void reset() {
reset(g2d);
}
void fillRect(int x, int y, int width, int height, Paint paint) {
/**
* reset the dimensions of the {@link Graphics2D}
*/
protected abstract void reset(Graphics2D g2d);
protected void fillRect(int x, int y, int width, int height, Paint paint) {
g2d.setPaint(paint);
g2d.fillRect(x, y, width, height);
}
void fillPolygon(int[] x, int[] y, Paint paint) {
g2d.setPaint(paint);
g2d.fillPolygon(x, y, x.length);
}
void fillPolygon(double[] x, double yBottom, double[] yTop, Paint paint) {
protected void fillPolygon(double[] x, double yBottom, double[] yTop, Paint paint) {
g2d.setPaint(paint);
PathIterator path = new PathIterator(yTop);
for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
int start = pos[0], end = pos[1], n = end - start;
int[] xDev = new int[n + 2], yDev = new int[n + 2];
int c = 0;
for (int i = start; i < end; i++) {
xDev[i - start] = (int) x[i];
yDev[i - start] = (int) yTop[i];
int cx = (int) x[i];
int cy = (int) yTop[i];
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
// collapse horizontal lines
xDev[c - 1] = cx;
} else {
xDev[c] = cx;
yDev[c++] = cy;
}
}
}
xDev[n] = xDev[n - 1];
xDev[n + 1] = xDev[0];
yDev[n] = yDev[n + 1] = (int) yBottom;
g2d.fillPolygon(xDev, yDev, xDev.length);
g2d.drawPolygon(xDev, yDev, xDev.length);
xDev[c] = xDev[c - 1];
xDev[c + 1] = xDev[0];
yDev[c] = yDev[c + 1] = (int) yBottom;
g2d.fillPolygon(xDev, yDev, c + 2);
}
}
void fillPolygon(double[] x, double[] yBottom, double[] yTop, Paint paint) {
protected void fillPolygon(double[] x, double[] yBottom, double[] yTop, Paint paint) {
g2d.setPaint(paint);
PathIterator path = new PathIterator(yTop);
for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
int start = pos[0], end = pos[1], n = end - start;
int[] xDev = new int[n * 2], yDev = new int[n * 2];
int c = 0;
for (int i = start; i < end; i++) {
int ix1 = i - start, ix2 = n * 2 - 1 - i + start;
xDev[ix1] = xDev[ix2] = (int) x[i];
yDev[ix1] = (int) yTop[i];
yDev[ix2] = (int) yBottom[i];
int cx = (int) x[i];
int cy = (int) yTop[i];
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
// collapse horizontal lines
xDev[c - 1] = cx;
} else {
xDev[c] = cx;
yDev[c++] = cy;
}
}
}
g2d.fillPolygon(xDev, yDev, xDev.length);
for (int i = end - 1; i >= start; i--) {
int cx = (int) x[i];
int cy = (int) yBottom[i];
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
// collapse horizontal lines
xDev[c - 1] = cx;
} else {
xDev[c] = cx;
yDev[c++] = cy;
}
}
}
g2d.fillPolygon(xDev, yDev, c);
}
}
void drawLine(int x1, int y1, int x2, int y2, Paint paint, Stroke stroke) {
protected void drawLine(int x1, int y1, int x2, int y2, Paint paint, Stroke stroke) {
g2d.setStroke(stroke);
g2d.setPaint(paint);
g2d.drawLine(x1, y1, x2, y2);
}
void drawPolyline(int[] x, int[] y, Paint paint, Stroke stroke) {
g2d.setStroke(stroke);
g2d.setPaint(paint);
g2d.drawPolyline(x, y, x.length);
}
void drawPolyline(double[] x, double[] y, Paint paint, Stroke stroke) {
protected void drawPolyline(double[] x, double[] y, Paint paint, Stroke stroke) {
g2d.setPaint(paint);
g2d.setStroke(stroke);
PathIterator path = new PathIterator(y);
for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
int start = pos[0], end = pos[1];
int[] xDev = new int[end - start], yDev = new int[end - start];
int c = 0;
for (int i = start; i < end; i++) {
xDev[i - start] = (int) x[i];
yDev[i - start] = (int) y[i];
int cx = (int) x[i];
int cy = (int) y[i];
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
// collapse horizontal lines
xDev[c - 1] = cx;
} else {
xDev[c] = cx;
yDev[c++] = cy;
}
}
}
g2d.drawPolyline(xDev, yDev, xDev.length);
g2d.drawPolyline(xDev, yDev, c);
}
}
void drawString(String text, int x, int y, Font font, Paint paint) {
protected void drawString(String text, int x, int y, Font font, Paint paint) {
g2d.setFont(font);
g2d.setPaint(paint);
g2d.drawString(text, x, y);
}
double getFontAscent(Font font) {
protected double getFontAscent(Font font) {
LineMetrics lm = font.getLineMetrics(DUMMY_TEXT, g2d.getFontRenderContext());
return lm.getAscent();
}
double getFontHeight(Font font) {
protected double getFontHeight(Font font) {
LineMetrics lm = font.getLineMetrics(DUMMY_TEXT, g2d.getFontRenderContext());
return lm.getAscent() + lm.getDescent();
}
double getStringWidth(String text, Font font) {
protected double getStringWidth(String text, Font font) {
return font.getStringBounds(text, 0, text.length(), g2d.getFontRenderContext()).getBounds().getWidth();
}
void setAntiAliasing(boolean enable) {
protected void setAntiAliasing(boolean enable) {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
enable ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
}
void setTextAntiAliasing(boolean enable) {
protected void setTextAntiAliasing(boolean enable) {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
enable ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
void dispose() {
g2d.dispose();
}
void makeImage(Object stream, ImageWriter writer, ImageWriteParam iwp) throws IOException {
BufferedImage outputImage = img;
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
img.coerceData(false);
// Some format can't manage 16M colors images
// JPEG don't like transparency
if (! imgProvider.canEncodeImage(outputImage) || "image/jpeg".equalsIgnoreCase(imgProvider.getMIMETypes()[0])) {
int w = img.getWidth();
int h = img.getHeight();
outputImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
outputImage.getGraphics().drawImage(img, 0, 0, w, h, null);
if (! imgProvider.canEncodeImage(outputImage)) {
throw new RuntimeException("Invalid image type");
}
}
if (! imgProvider.canEncodeImage(outputImage)) {
throw new RuntimeException("Invalid image type");
}
try (ImageOutputStream imageStream = ImageIO.createImageOutputStream(stream)) {
writer.setOutput(imageStream);
writer.write(null, new IIOImage(outputImage, null, null), iwp);
imageStream.flush();
} catch (IOException e) {
writer.abort();
throw e;
} finally {
writer.dispose();
}
}
void saveImage(String path, ImageWriter writer, ImageWriteParam iwp) throws IOException {
makeImage(Paths.get(path).toFile(), writer, iwp);
}
byte[] getImageBytes(ImageWriter writer, ImageWriteParam iwp) throws IOException {
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(IMG_BUFFER_CAPACITY)){
makeImage(stream, writer, iwp);
return stream.toByteArray();
}
}
void loadImage(RrdGraphDef.ImageSource imageSource, int x, int y, int w, int h) throws IOException {
protected void loadImage(RrdGraphDef.ImageSource imageSource, int x, int y, int w, int h) throws IOException {
BufferedImage wpImage = imageSource.apply(w, h).getSubimage(0, 0, w, h);
g2d.drawImage(wpImage, new AffineTransform(1f, 0f, 0f, 1f, x, y), null);
}
protected void dispose() {
if (g2d != null) {
g2d.dispose();
}
}
protected void makeImage(Path path) throws IOException {
try (OutputStream os = Files.newOutputStream(path)) {
makeImage(os);
}
}
protected abstract void makeImage(OutputStream os) throws IOException ;
protected void saveImage(String path) throws IOException {
makeImage(Paths.get(path));
}
protected byte[] getImageBytes() throws IOException {
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(IMG_BUFFER_CAPACITY)){
makeImage(stream);
return stream.toByteArray();
}
}
}

View File

@ -12,10 +12,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.swing.ImageIcon;
import org.rrd4j.core.Util;
@ -38,7 +36,7 @@ public class RrdGraph implements RrdGraphConstants {
};
private static final int SYMBOLS_CENTER = 8;
private static final char[] SYMBOLS = {'y', 'z', 'a', 'f', 'p', 'n', 'µ', 'm', ' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
private static final char[] SYMBOLS = {'y', 'z', 'a', 'f', 'p', 'n', 'µ', 'm', ' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
final RrdGraphDef gdef;
final ImageParameters im;
@ -47,8 +45,6 @@ public class RrdGraph implements RrdGraphConstants {
Mapper mapper;
private final RrdGraphInfo info = new RrdGraphInfo();
private final String signature;
private final ImageWriter writer;
private final ImageWriteParam param;
/**
* Creates graph from the corresponding {@link org.rrd4j.graph.RrdGraphDef} object.
@ -60,9 +56,8 @@ public class RrdGraph implements RrdGraphConstants {
this.gdef = gdef;
signature = gdef.getSignature();
im = new ImageParameters();
worker = new ImageWorker(1, 1); // Dummy worker, just to start with something
writer = ImageIO.getImageWritersByFormatName(gdef.imageFormat).next();
param = getImageParams();
worker = BufferedImageWorker.getBuilder().setGdef(gdef).build();
try {
createGraph();
}
@ -73,6 +68,28 @@ public class RrdGraph implements RrdGraphConstants {
}
}
/**
* Create graph from a custom image worker
* @param gdef
* @param worker
* @throws IOException
*/
public RrdGraph(RrdGraphDef gdef, ImageWorker worker) throws IOException {
this.gdef = gdef;
signature = gdef.getSignature();
im = new ImageParameters();
this.worker = worker;
try {
createGraph();
}
finally {
worker.dispose();
this.worker = null;
dproc = null;
}
}
/**
* <p>Creates graph from the corresponding {@link org.rrd4j.graph.RrdGraphDef} object.</p>
* <p>The graph will be created using customs {@link javax.imageio.ImageWriter} and {@link javax.imageio.ImageWriteParam} given.</p>
@ -88,9 +105,7 @@ public class RrdGraph implements RrdGraphConstants {
this.gdef = gdef;
signature = gdef.getSignature();
im = new ImageParameters();
worker = new ImageWorker(1, 1); // Dummy worker, just to start with something
this.writer = writer;
this.param = param;
worker = BufferedImageWorker.getBuilder().setGdef(gdef).setWriter(writer).setImageWriteParam(param).build();
try {
createGraph();
}
@ -110,21 +125,6 @@ public class RrdGraph implements RrdGraphConstants {
return info;
}
private ImageWriteParam getImageParams() {
ImageWriteParam iwp = writer.getDefaultWriteParam();
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
//If lossy compression, use the quality
if (! imgProvider.isFormatLossless()) {
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(gdef.imageQuality);
}
if (iwp.canWriteProgressive()) {
iwp.setProgressiveMode(gdef.interlaced ? ImageWriteParam.MODE_DEFAULT:ImageWriteParam.MODE_DISABLED);
}
return iwp;
}
private void createGraph() throws IOException {
boolean lazy = lazyCheck();
if (!lazy || gdef.printStatementCount() != 0) {
@ -177,7 +177,7 @@ public class RrdGraph implements RrdGraphConstants {
private void saveImage() throws IOException {
if (! RrdGraphConstants.IN_MEMORY_IMAGE.equals(gdef.filename)) {
Path imgpath = Paths.get(gdef.filename);
worker.saveImage(gdef.filename, writer, param);
worker.saveImage(gdef.filename);
info.bytesSource = () -> {
try {
return Files.readAllBytes(imgpath);
@ -194,7 +194,7 @@ public class RrdGraph implements RrdGraphConstants {
};
}
else {
byte[] content = worker.getImageBytes(writer, param);
byte[] content = worker.getImageBytes();
info.bytesSource = () -> Arrays.copyOf(content, content.length);
info.bytesCount = () -> content.length;
}

View File

@ -3,7 +3,7 @@ package org.rrd4j.graph;
class ValueScaler {
static final String UNIT_UNKNOWN = "?";
static final String[] UNIT_SYMBOLS = {
"a", "f", "p", "n", "u", "m", " ", "k", "M", "G", "T", "P", "E"
"a", "f", "p", "n", "µ", "m", " ", "K", "M", "G", "T", "P", "E"
};
static final int SYMB_CENTER = 6;

View File

@ -83,6 +83,8 @@ class SummaryRenderer {
private static final long[] RATES = new long[] { 60*60*1000 };
// dotted line
private static final Stroke GRID_STROKE = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[] {1, 1}, 0);
// hide grid
private static final Stroke TICK_STROKE = new BasicStroke(0);
public SummaryRenderer(I2PAppContext ctx, SummaryListener lsnr) {
_log = ctx.logManager().getLog(SummaryRenderer.class);
@ -337,6 +339,7 @@ class SummaryRenderer {
def.setAntiAliasing(false);
def.setTextAntiAliasing(true);
def.setGridStroke(GRID_STROKE);
def.setTickStroke(TICK_STROKE);
//System.out.println("Rendering: \n" + def.exportXmlTemplate());
//System.out.println("*****************\nData: \n" + _listener.getData().dump());
def.setWidth(width);

View File

@ -31,7 +31,7 @@ public class CoreVersion {
* Otherwise, the same as PUBLISHED_VERSION.
* RouterVersion.FULL_VERSION is suggested for display to the user.
*/
public final static String VERSION = "2.5.0";
public final static String VERSION = "2.5.1";
/**
* The version published in the netdb via StatisticsManager.

View File

@ -1,3 +1,9 @@
i2p (2.5.1-1~bionic+1) bionic; urgency=medium
* New upstream version 2.5.1
-- idk <hankhill19580@gmail.com> Tue, 07 May 2024 11:18:05 -0400
i2p (2.5.0-1~bionic+1) bionic; urgency=medium
* New upstream version 2.5.0

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
i2p (2.5.1-1~ubuntu1) focal; urgency=medium
* New upstream version 2.5.1
-- idk <hankhill19580@gmail.com> Tue, 07 May 2024 11:17:09 -0400
i2p (2.5.0-1~ubuntu1) focal; urgency=medium
* New upstream version 2.5.0

View File

@ -1,3 +1,13 @@
2024-05-12 zzz
* Console: Update rrd4j to 3.9.1 preview
2024-05-08 zzz
* i2ptunnel: Fix custom options form width (light theme)
* Router: Publish G cap if symmetric natted
* Tunnels: Validate peer RI expiration in TunnelPeerSelector
2024-05-06 2.5.1 (API 0.9.62) released
2024-05-05 zzz
* NetDB: Various fixes and adjustments
* Pull translations from Transifex
@ -8,7 +18,7 @@
* Tunnels: OBEP distributor: Check and charge RI lookup bandwidth
2024-05-02 zzz
* Profiles: Fixes for firstHeardAbout and/or lastHeardAbout being zero
* Profiles: Fixes for firstHeardAbout and/or lastHeardAbout being zero
2024-05-01 zzz
* NetDB:

View File

@ -4,7 +4,7 @@
<info>
<appname>i2p</appname>
<appversion>2.5.0</appversion>
<appversion>2.5.1</appversion>
<authors>
<author name="I2P" email="https://geti2p.net/"/>
</authors>

View File

@ -10,7 +10,7 @@
<info>
<appname>i2p</appname>
<appversion>2.5.0</appversion>
<appversion>2.5.1</appversion>
<authors>
<author name="I2P" email="https://geti2p.net/"/>
</authors>

View File

@ -196,7 +196,7 @@
2. Add i2pupdate-1.xx.0.su3 torrent to tracker2.postman.i2p and start seeding
3. Notify the following people:
- All in-network update hosts
- All in-network update hosts(zzz(stats.i2p) and idk(mgp**.b32.i2p)), they will need the i2pupdate.su3 file
- PPA maintainer
- news.xml maintainer
- backup news.xml maintainer

View File

@ -1203,6 +1203,7 @@ public class Router implements RouterClock.ClockShiftListener {
// rv.append(CAPABILITY_NO_TUNNELS);
return rv.toString();
}
boolean forceG = false;
switch (_context.commSystem().getStatus()) {
case OK:
case IPV4_OK_IPV6_UNKNOWN:
@ -1215,18 +1216,21 @@ public class Router implements RouterClock.ClockShiftListener {
break;
case DIFFERENT:
case HOSED:
case IPV4_SNAT_IPV6_UNKNOWN:
forceG = true;
// fall through
case REJECT_UNSOLICITED:
case IPV4_DISABLED_IPV6_FIREWALLED:
rv.append(CAPABILITY_UNREACHABLE);
break;
case DISCONNECTED:
case HOSED:
case UNKNOWN:
case IPV4_UNKNOWN_IPV6_FIREWALLED:
case IPV4_DISABLED_IPV6_UNKNOWN:
case IPV4_FIREWALLED_IPV6_UNKNOWN:
case IPV4_SNAT_IPV6_UNKNOWN:
default:
// no explicit capability
break;
@ -1234,7 +1238,7 @@ public class Router implements RouterClock.ClockShiftListener {
char cong = 0;
int maxTunnels = _context.getProperty(RouterThrottleImpl.PROP_MAX_TUNNELS, RouterThrottleImpl.DEFAULT_MAX_TUNNELS);
if (maxTunnels <= 0) {
if (forceG || maxTunnels <= 0) {
cong = CAPABILITY_NO_TUNNELS;
} else if (maxTunnels <= 50 || SystemVersion.isSlow()) {
cong = CAPABILITY_CONGESTION_MODERATE;

View File

@ -20,7 +20,7 @@ public class RouterVersion {
public final static String VERSION = CoreVersion.VERSION;
/** for example: "beta", "alpha", "rc" */
public final static String QUALIFIER = "";
public final static long BUILD = 4;
public final static long BUILD = 1;
/** for example "-test" */
public final static String EXTRA = "";
public final static String FULL_VERSION = VERSION + "-" + BUILD + QUALIFIER + EXTRA;

View File

@ -229,7 +229,10 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
if (ctx.commSystem().wasUnreachable(h))
return true;
RouterInfo info = (RouterInfo) ctx.netDb().lookupLocallyWithoutValidation(h);
// Here, we use validation, because BuildRequestor does,
// so if we don't skip old routers here, it gets all the way to BuildRequestor
// before failing.
RouterInfo info = (RouterInfo) ctx.netDb().lookupLocally(h);
if (info == null)
return true;