From 93586d05d8bdaf3ae921f599aacecb5d68f0a143 Mon Sep 17 00:00:00 2001 From: bubblobill Date: Tue, 20 Jan 2026 18:36:13 +0800 Subject: [PATCH 1/6] added toJson options to ShapeDrawable and AbstractDrawing added extended delimiter parameters to shape.properties to resolve nested string property list and string list issues. --- .../client/functions/ShapeFunctions.java | 70 +++++++++++-------- .../model/drawing/AbstractDrawing.java | 10 +++ .../maptool/model/drawing/ShapeDrawable.java | 22 ++++-- .../rptools/maptool/language/i18n.properties | 1 + 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java b/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java index 0edb8b6288..af92612bc5 100644 --- a/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java @@ -17,16 +17,13 @@ // @formatter:off import com.google.common.primitives.Floats; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import com.google.gson.*; import java.awt.*; import java.awt.geom.*; import java.util.*; import java.util.List; import java.util.function.BiFunction; import net.rptools.maptool.client.MapTool; -import net.rptools.maptool.client.functions.json.JSONMacroFunctions; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.GUID; import net.rptools.maptool.model.Zone; @@ -78,22 +75,23 @@ public class ShapeFunctions extends AbstractFunction { public static final Map SOURCE_LINKS = Map.of( "arc", - "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Arc2D.Double.html#Double-double-double-double-double-double-double-int-", + "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Arc2D.Double.html#Double-double-double-double-double-double-double-int-", "cubicCurve", - "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/CubicCurve2D.Double.html#Double-double-double-double-double-double-double-double-double-", + "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/CubicCurve2D.Double.html#Double-double-double-double-double-double-double-double-double-", "ellipse", - "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Ellipse2D.Double.html#Double-double-double-double-double-", + "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Ellipse2D.Double.html#Double-double-double-double-double-", "line", - "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Line2D.Double.html#Double-double-double-double-double-", + "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Line2D.Double.html#Double-double-double-double-double-", "polygon", - "https://xmlgraphics.apache.org/batik/javadoc/org/apache/batik/ext/awt/geom/Polygon2D.html#Polygon2D-float:A-float:A-int-", + "https://xmlgraphics.apache.org/batik/javadoc/org/apache/batik/ext/awt/geom/Polygon2D.html#Polygon2D-float:A-float:A-int-", "quadCurve", - "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/QuadCurve2D.Double.html#Double-double-double-double-double-double-double-", + "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/QuadCurve2D.Double.html#Double-double-double-double-double-double-double-", "rectangle", - "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Rectangle2D.Double.html#Double-double-double-double-double-", + "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Rectangle2D.Double.html#Double-double-double-double-double-", "roundRectangle", - "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/RoundRectangle2D.Double.html#Double-double-double-double-double-double-double-", - "svgPath", "https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths"); + "https://docs.oracle.com/javase/8/docs/api/java/awt/geom/RoundRectangle2D.Double.html#Double-double-double-double-double-double-double-", + "svgPath", + "https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths"); public static final String[] SHAPE_TYPES = new String[] { "arc", @@ -592,12 +590,30 @@ private Object drawShape( private Object getProperties( Parser parser, VariableResolver resolver, String functionName, List parameters) throws ParserException { - /* name, delimiter */ + /* name, delimiter, nested delimiter */ String name = FunctionUtil.paramAsString(functionName, parameters, 0, false); - String delimiter = + String delimiter1 = parameters.size() < 2 ? ";" : FunctionUtil.paramAsString(functionName, parameters, 1, false); + String delimiter2 = + parameters.size() < 3 + ? "," + : FunctionUtil.paramAsString(functionName, parameters, 2, false); + String delimiter3 = + parameters.size() < 4 + ? ":" + : FunctionUtil.paramAsString(functionName, parameters, 3, false); + if (delimiter1.equals(delimiter2)) { + throw new RuntimeException( + I18N.getText("macro.function.general.argumentTypeB", functionName, 3, 2)); + } else if (delimiter2.equals(delimiter3)) { + throw new RuntimeException( + I18N.getText("macro.function.general.argumentTypeB", functionName, 4, 3)); + } else if (delimiter3.equals(delimiter1)) { + throw new RuntimeException( + I18N.getText("macro.function.general.argumentTypeB", functionName, 4, 2)); + } if (!CACHED_SHAPES.containsKey(name)) { return false; } @@ -614,23 +630,17 @@ private Object getProperties( seg, coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6])); pi.next(); } - StringBuilder stringBuilder = new StringBuilder(sd.toNonLocalisedString()); - stringBuilder.append("segments=").append(String.join(",", segments)).append(";"); - - if (delimiter.equalsIgnoreCase("json")) { - JsonObject jsonObject = - JSONMacroFunctions.getInstance() - .getJsonObjectFunctions() - .fromStrProp(stringBuilder.toString(), ";"); - jsonObject.add( - "segments", - JSONMacroFunctions.getInstance() - .getJsonArrayFunctions() - .fromStringList(String.join("##", segments), "##")); + + if (delimiter1.equalsIgnoreCase("json")) { + JsonObject jsonObject = sd.toJson(); + jsonObject.add("segments", new Gson().toJsonTree(segments)); return jsonObject; } else { - stringBuilder.append("segments=\"").append(String.join("\",\"", segments)).append("\";"); - return stringBuilder.toString(); + return sd.toNonLocalisedString().replaceAll(";", delimiter1) + + delimiter1 + + "segments=" + + String.join( + delimiter2, segments.stream().map(s -> s.replaceAll(",", delimiter3)).toList()); } } diff --git a/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java b/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java index 31c662a051..41183d1faa 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java +++ b/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java @@ -15,6 +15,8 @@ package net.rptools.maptool.model.drawing; import com.google.common.annotations.VisibleForTesting; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import java.awt.*; import java.awt.image.ImageObserver; import net.rptools.maptool.client.MapTool; @@ -152,6 +154,14 @@ public String toNonLocalisedString() { return "name=" + getName() + ";" + "layer=" + getLayer().name() + ";" + "id=" + getId() + ";"; } + public JsonObject toJson() { + JsonObject jo = new JsonObject(); + jo.add("name", new JsonPrimitive(getName())); + jo.add("layer", new JsonPrimitive(getLayer().name())); + jo.add("id", new JsonPrimitive(getId().toString())); + return jo; + } + //// // IMAGE OBSERVER public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { diff --git a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java index 88a202bd61..237421d67f 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java +++ b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java @@ -14,6 +14,8 @@ */ package net.rptools.maptool.model.drawing; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import com.google.protobuf.StringValue; import java.awt.*; import java.awt.Rectangle; @@ -185,7 +187,6 @@ public String toString() { + "shapeType=" + getShapeTypeName() + ";" - + "bounds=\"" + "x=" + getBounds().x + ";" @@ -196,8 +197,7 @@ public String toString() { + getBounds().width + ";" + "height=" - + getBounds().height - + "\";"; + + getBounds().height; } public String toNonLocalisedString() { @@ -208,7 +208,6 @@ public String toNonLocalisedString() { + "shapeType=" + getShapeTypeName() + ";" - + "bounds=\"" + "x=" + getBounds().x + ";" @@ -219,8 +218,19 @@ public String toNonLocalisedString() { + getBounds().width + ";" + "height=" - + getBounds().height - + "\";"; + + getBounds().height; + } + + @Override + public JsonObject toJson() { + JsonObject jo = super.toJson(); + jo.add("antiAliasing", new JsonPrimitive(getName())); + jo.add("shapeType", new JsonPrimitive(getLayer().name())); + jo.add("x", new JsonPrimitive(getBounds().x)); + jo.add("y", new JsonPrimitive(getBounds().y)); + jo.add("width", new JsonPrimitive(getBounds().width)); + jo.add("height", new JsonPrimitive(getBounds().height)); + return jo; } private void restoreAA(Graphics2D g, Object oldAA) { diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index eee02f0da2..7d7ce6376c 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -2084,6 +2084,7 @@ macro.function.general.argumentKeyTypeD = Argument key "{1}" to funct macro.function.general.argumentKeyTypeG = Argument key "{1}" to function "{0}" must be a GUID. macro.function.general.argumentKeyTypeI = Argument key "{1}" to function "{0}" must be an integer. macro.function.general.argumentTypeA = Argument number {1} to function "{0}" must be a JSON Array. +macro.function.general.argumentTypeB = Argument number {1} to function "{0}" cannot be the same as argument number {2}. macro.function.general.argumentTypeI = Argument number {1} "{2}" to function "{0}" must be an integer. macro.function.general.argumentTypeInvalid = Argument number {1} invalid argument type for function "{0}". macro.function.general.argumentTypeJ = Argument number {1} to function "{0}" must be a JSON Array or Object. From 5aeed4a57f6691fca1dd3742cf029cdc28ec0e8e Mon Sep 17 00:00:00 2001 From: bubblobill Date: Tue, 17 Mar 2026 20:32:08 +0800 Subject: [PATCH 2/6] Fix "antiAliasing" toString value --- .../java/net/rptools/maptool/model/drawing/ShapeDrawable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java index 237421d67f..9d8f945d62 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java +++ b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java @@ -224,7 +224,7 @@ public String toNonLocalisedString() { @Override public JsonObject toJson() { JsonObject jo = super.toJson(); - jo.add("antiAliasing", new JsonPrimitive(getName())); + jo.add("antiAliasing", new JsonPrimitive(getUseAntiAliasing())); jo.add("shapeType", new JsonPrimitive(getLayer().name())); jo.add("x", new JsonPrimitive(getBounds().x)); jo.add("y", new JsonPrimitive(getBounds().y)); From 206e7376e3a8bec3d5f0bce50138e1113e12b71d Mon Sep 17 00:00:00 2001 From: bubblobill Date: Tue, 17 Mar 2026 20:33:41 +0800 Subject: [PATCH 3/6] Fix "shapeType" toString value --- .../java/net/rptools/maptool/model/drawing/ShapeDrawable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java index 9d8f945d62..10dda22528 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java +++ b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java @@ -225,7 +225,7 @@ public String toNonLocalisedString() { public JsonObject toJson() { JsonObject jo = super.toJson(); jo.add("antiAliasing", new JsonPrimitive(getUseAntiAliasing())); - jo.add("shapeType", new JsonPrimitive(getLayer().name())); + jo.add("shapeType", new JsonPrimitive(getShapeTypeName())); jo.add("x", new JsonPrimitive(getBounds().x)); jo.add("y", new JsonPrimitive(getBounds().y)); jo.add("width", new JsonPrimitive(getBounds().width)); From c5ef739c1cf114e3173d0411af66429598a6f83e Mon Sep 17 00:00:00 2001 From: bubblobill Date: Fri, 20 Mar 2026 20:13:42 +0800 Subject: [PATCH 4/6] null check for name added to JSON Object construction. --- .../net/rptools/maptool/model/drawing/AbstractDrawing.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java b/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java index 41183d1faa..5bf30fb4f4 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java +++ b/src/main/java/net/rptools/maptool/model/drawing/AbstractDrawing.java @@ -156,7 +156,8 @@ public String toNonLocalisedString() { public JsonObject toJson() { JsonObject jo = new JsonObject(); - jo.add("name", new JsonPrimitive(getName())); + String nm = getName(); + jo.add("name", new JsonPrimitive(nm == null ? "" : nm)); jo.add("layer", new JsonPrimitive(getLayer().name())); jo.add("id", new JsonPrimitive(getId().toString())); return jo; From 5c8a4a66569506fe46198875d0fbe2fe2ec46ca1 Mon Sep 17 00:00:00 2001 From: bubblobill Date: Fri, 20 Mar 2026 20:16:52 +0800 Subject: [PATCH 5/6] Changed function exceptions to correct type. --- .../rptools/maptool/client/functions/ShapeFunctions.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java b/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java index af92612bc5..b6f36a28fd 100644 --- a/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/ShapeFunctions.java @@ -605,13 +605,13 @@ private Object getProperties( ? ":" : FunctionUtil.paramAsString(functionName, parameters, 3, false); if (delimiter1.equals(delimiter2)) { - throw new RuntimeException( + throw new ParserException( I18N.getText("macro.function.general.argumentTypeB", functionName, 3, 2)); } else if (delimiter2.equals(delimiter3)) { - throw new RuntimeException( + throw new ParserException( I18N.getText("macro.function.general.argumentTypeB", functionName, 4, 3)); } else if (delimiter3.equals(delimiter1)) { - throw new RuntimeException( + throw new ParserException( I18N.getText("macro.function.general.argumentTypeB", functionName, 4, 2)); } if (!CACHED_SHAPES.containsKey(name)) { From 89986e359c0259c49713a5cc8593752bb48a31a2 Mon Sep 17 00:00:00 2001 From: bubblobill Date: Fri, 20 Mar 2026 20:58:19 +0800 Subject: [PATCH 6/6] Compromise - added back old bounds string prop to toString --- .../maptool/model/drawing/ShapeDrawable.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java index 10dda22528..a4a760beaf 100644 --- a/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java +++ b/src/main/java/net/rptools/maptool/model/drawing/ShapeDrawable.java @@ -197,7 +197,21 @@ public String toString() { + getBounds().width + ";" + "height=" - + getBounds().height; + + getBounds().height + + ";" + + "bounds=\"" + + "x=" + + getBounds().x + + ";" + + "y=" + + getBounds().y + + ";" + + "width=" + + getBounds().width + + ";" + + "height=" + + getBounds().height + + "\""; } public String toNonLocalisedString() { @@ -218,7 +232,21 @@ public String toNonLocalisedString() { + getBounds().width + ";" + "height=" - + getBounds().height; + + getBounds().height + + ";" + + "bounds=\"" + + "x=" + + getBounds().x + + ";" + + "y=" + + getBounds().y + + ";" + + "width=" + + getBounds().width + + ";" + + "height=" + + getBounds().height + + "\""; } @Override