Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functions json.get.path and json.set.path #612

Closed
Merudo opened this issue Aug 23, 2019 · 74 comments
Closed

Functions json.get.path and json.set.path #612

Merudo opened this issue Aug 23, 2019 · 74 comments
Assignees
Labels
feature Adding functionality that adds value M Medium impact. T-shirt style story pointing/scope macro changes This issue adds or changes macro functions. Extra work is required (testing, wiki, code editor) tested This issue has been QA tested by someone other than the developer.

Comments

@Merudo
Copy link
Member

Merudo commented Aug 23, 2019

Is your feature request related to a problem? Please describe.
It can be slow and cumbersome to deal with nested jsons.

For example, to get a "Level" field from a json, I might need

[att = json.get(json, "PrimaryAttributes")]
[st = json.get(att, "ST")]
[stLevel = json.get(st, "Level")]

The situation is worse when I need to set a property deep inside a nested json, in which case I need to update each level of the json.

Describe the solution you'd like
Functions json.get.path() and json.set.path() to automate the process.

For example, in my example I would only need

[stLevel = json.get.path(json, "PrimaryAttributes", "ST", "LEVEL")]

Similarly for set.path, to change the Level to 5 (say),

[stLevel = json.set.path(json, 5, "PrimaryAttributes", "ST", "LEVEL")]

@Phergus Phergus added the feature Adding functionality that adds value label Aug 23, 2019
@Azhrei
Copy link
Member

Azhrei commented Aug 23, 2019

This is a great proposal, but I'd like to see good error messages for when the user messes it up! Suppose the JSON looks like:

{ name: { first: "Bob", last: "Smith" },
  "class": [ "cleric", "fighter", "cleric", "cleric", "fighter" ],
  hp:  [ 5, 9, 6, 4, 8 ],
  ...
}

To get to the number of HP for the third level of cleric it would be:

JSON.get.path(json, "hp", 3)

Because the first level is an object and the second level is an array.

Giving a number instead of a string can work for an object, but not for an array, so the error message on arrays is pretty easy: "cannot access array element using a string in JSON.get.path() in parameter 3", for example.

Otherwise, I think this is great. It would make accessing JSON data much simpler (at least, until such time as JSON becomes a first class data type).

@JamzTheMan
Copy link
Member

I approve. I know a lot of JSON libs have a json.path built in. I haven't checked to see if the lib(s) we use have it or not.

They may or may not have standard error responses for errors.

@Merudo
Copy link
Member Author

Merudo commented Aug 23, 2019

I don't think the package net.sf.json has json.path, unfortunately.

Regarding error messages, are there cases where we would prefer to return "" instead of an error?

@aliasmask
Copy link

aliasmask commented Aug 30, 2019

This is the code I use in MapTool to json.set.path(), json.append.path() and json.get.path(). I was hoping if this was done in java there would be an easier method or at the very least be quicker in java.

@@ @json.set.path
<!-- json.set.path(jsonName,path,key,value)
   jsonName - json name to have data added to
   path - array of path to json data
   key - key name to insert
   value - value to insert
   json - original json will be updated using its name for reference.
   
   This will update the original json and insert data in to its structure given the path.
-->
[H: sub_jsonName = arg(0)]
[H: sub_path = arg(1)]
[H: sub_key = arg(2)]
[H: sub_value = arg(3)]

[H: sub_root = eval(sub_jsonName)]
[H: sub_tree = sub_root]
[H: sub_array = json.append("",sub_root)]

<!-- deconstruct items in path for update -->
[H, foreach(sub_limb,sub_path), code: {
   [H: sub_branch = json.get(sub_tree,sub_limb)]
   [H: sub_array = json.append(sub_array,sub_branch)]
   [H: sub_tree = sub_branch]
}]

<!-- add value to last branch -->
[H: sub_tree = json.set(sub_tree,sub_key,sub_value)]

<!-- reconstruct the object -->
[H: sub_pathRev = json.reverse(sub_path)]
[H: sub_array = json.reverse(sub_array)]
[H, foreach(sub_limb,sub_pathRev), code: {
   [H: sub_tree = json.set(json.get(sub_array,roll.count+1),sub_limb,sub_tree)]
}]

<!-- update original object -->
[H: set(sub_jsonName,sub_tree)]

!!
@@ @json.append.path
<!-- json.append.path(jsonName,path,value)
   jsonName - json name to have data added to
   path - array of path to json data
   value - value to insert
   json - original json will be updated using its name for reference.
   
   This will update the original json and insert data in to its structure given the path.
-->
[H: sub_jsonName = arg(0)]
[H: sub_path = arg(1)]
[H: sub_value = arg(2)]

[H: sub_root = eval(sub_jsonName)]
[H: sub_tree = sub_root]
[H: sub_array = json.append("",sub_root)]

<!-- deconstruct items in path for update -->
[H, foreach(sub_limb,sub_path), code: {
   [H: sub_branch = json.get(sub_tree,sub_limb)]
   [H: sub_array = json.append(sub_array,sub_branch)]
   [H: sub_tree = sub_branch]
}]

<!-- add value to last branch -->
[H: sub_tree = json.append(sub_tree,sub_value)]

<!-- reconstruct the object -->
[H: sub_pathRev = json.reverse(sub_path)]
[H: sub_array = json.reverse(sub_array)]
[H, foreach(sub_limb,sub_pathRev), code: {
   [H: sub_tree = json.set(json.get(sub_array,roll.count+1),sub_limb,sub_tree)]
}]

<!-- update original object -->
[H: set(sub_jsonName,sub_tree)]

!!
@@ @json.get.path
<!-- json.get.path(jsonName,path): data
   jsonName - text name of json
   path - json array of path to get
   data - value at the path
-->

[H: sub_jsonName = arg(0)]
[H: sub_path = arg(1)]

[H: sub_tree = eval(sub_jsonName)]

[H, foreach(sub_limb,sub_path): sub_tree = json.get(sub_tree,sub_limb)]

[H: macro.return = sub_tree]
!!

@Merudo
Copy link
Member Author

Merudo commented Sep 3, 2019

EDIT: Outdated, check json.path.read instead.

PR #651 adds json.get.path.

Example of use:

[h:troll = json.set("{}", "name", "Troll", "HP", 75, "Attacks", json.append("Claw", "Bite"))]
[h:orc = json.set("{}", "name", "Orc", "HP", 13, "Attacks", json.append("Sword", "Punch"))]
[h:monsters = json.set("{}", "Troll", troll, "Orc", orc)]

[h: path = json.append("Orc", "Attacks", 1))]
[r: json.get.path( monsters, path)]
[r: json.get.path( monsters, "Orc", "Attacks", 1)]

Which both return "Punch".

In case of an error due to invalid array index:

[r: json.get.path( monsters, "Orc", "Attacks", -1)]

returns

Invalid index "-1" at [Orc, Attacks] for array (size of 2) in function "json.get.path"

In case of an error due to invalid field:

[r: json.get.path( monsters, "Orc", "Spells", 0)]

returns

Invalid value for key "Spells" at [Orc] in function "json.get.path".

And, in the case of an error due to the object not being a JSON:

[r: json.get.path( monsters, "Orc", "Attacks", 0, "Damage")]

returns

Invalid path "Damage" at [Orc, Attacks, 0] in function "json.get.path". Object is not a JSON Array or a JSON Object.

@aliasmask
Copy link

FYI, typical behavior for a json.get when the field doesn't exist (except for arrays) is it returns "". For example, [H: json.get(monsters,"Goblin")] would return "". There's no good way to test for something not there without full stop on the execution. So, for [r: json.get.path(monsters,"Orc","Spells")] I would prefer a "" return, but if the path has an invalid index then there should be an error. Also, if the path goes beyond an existing path by more than 1 there should be an error. So, all your examples above would be valid, I just want to make sure getting "Spells" would not toss an error.

This way you can get a path that may not always be there and be able to test the value without an error code.

@JamzTheMan
Copy link
Member

Why are we not using the standard dot notations? Eg json.get.path(obj, ".Orc.Spells")?

@aliasmask
Copy link

I would think that some keys are not dot notation friendly.

@JamzTheMan
Copy link
Member

JamzTheMan commented Sep 3, 2019

There shouldn't be. Also, there is sort of a standard. (See other libs and CLI like jq) Doing it this way is like reinventing regular expressions.

If I already know how to do JSON path notation in other apps, why do it special in MT?

See https://restfulapi.net/json-jsonpath/ for examples.

@JamzTheMan
Copy link
Member

FWIW I would rather include the jayway lib and change the signature so it's just json.get.path(json obj, string path)

It would also be more powerful and less cumbersome. You can walk the tree, mix arrays and objects etc. AFAIK this is the standard lib as it were.

Plus, documentation is easier, you can just link to external sites like https://www.baeldung.com/guide-to-jayway-jsonpath :)

@Azhrei
Copy link
Member

Azhrei commented Sep 3, 2019

I agree that standards are great. Everybody should have one.

But I’m with AM on this one. Imagine you have a three-level object and want to iterate over all elements of the middle level but keep the first and last level constant. Much simpler if they’re separate parameters. And besides, string concatenation is faster in Java — Forcing MTscript to do it is a loss. 😐

And there would be no way to specify a literal dot within a property using a single string path (without reverting to backslashes and then treating it special anyway because I’ll bet the library API doesn’t account for that).

@JamzTheMan
Copy link
Member

It's bad practice to use . in json key but if you do, in JQ you quote the key out.

I'm not sure without seeing your json and what you are trying get but "$..author" would get all the authors from store.book (3 levels deep)

Try looking at the examples/docs then present a case that can not be done using the lib but could be done via this implementation.

In fact, in this implementation it looks like I have to know the key names for all three levels?

Also, does this handle objects and arrays? Can I do weapons[].damage or weapons[2].damage?

Better yet, can I get all weapon damages that have a child type == piercing like:

weapons.[?(@.type == "piercing")].damage

@Merudo
Copy link
Member Author

Merudo commented Sep 3, 2019

I think writing a wrapper for jayway would be immensely useful and would be relatively easy. I was thinking the call could look like

jsonpath(json, path, tagValue)

As proposed, the functions json.get.path and json.set.path are replacements for the UDFs json.pget and json.pset that a lot of folks already use.

EDIT: Another problem with jayway is that it might not be compatible with the json library we are using.

@JamzTheMan
Copy link
Member

JamzTheMan commented Sep 3, 2019

I suppose I could possibly get behind that (although it does proliferate macro functions even further, ug, so many functions lol)

What's the tagValue, for sets? (and prefer to keep the . notation since we already have every other json function like that)

json.path(json, path, [tagValue])

Where if tagValue is passed sets the value for the path? Both return the result set?

Looks like if it's a single value it returns a string, otherwise it returns either an json array or object. (not sure what you want to do for this implementation?)

Also, I suppose this should now go to it's own issue for YAF.

@Merudo
Copy link
Member Author

Merudo commented Sep 3, 2019

I don't think jayway is compatible with the json library we are using ( json-lib aka net.sf.json), so that would be an issue.

Should we switch to a different json implementation? The one we are using has not been updated for almost a decade. Maybe Gson or Jackson would work well?

Merudo added a commit to Merudo/maptool that referenced this issue Sep 3, 2019
@JamzTheMan
Copy link
Member

I think gson is but in the Gradle? It has some nice features.

By not compatible, how does it have to interact with the current libs? Take a string as json and output a JSON as a string?

But otherwise I have no issue updating our json libs, we have several libs that need to be updated. Sadly we don't have coverage to test everything after such changes though.

@Merudo
Copy link
Member Author

Merudo commented Sep 4, 2019

I guess we could use both gson and the old json-lib for now. So we could use gson for the jsonPath stuff and json-lib for the rest.

That might end up being confusing though.

Merudo added a commit to Merudo/maptool that referenced this issue Sep 5, 2019
- Function takes a "json" and a "path" argument
- Path should be defined according to https://github.com/json-path/JsonPath
- Support inline predicates
- Errors are printed to chat but not according to our standards
- Progress on RPTools#612
@Merudo
Copy link
Member Author

Merudo commented Sep 5, 2019

New PR #657 offers json.path.read, which I believe to be a better alternative to my proposed json.get.path.

Now if we have

[h:troll = json.set("{}", "name", "Troll", "HP", 75, "Attacks", json.append("Claw", "Bite"))]
[h:orc = json.set("{}", "name", "Orc", "HP", 13, "Attacks", json.append("Sword", "Punch"))]
[h:monsters = json.set("{}", "Troll", troll, "Orc", orc)]

we can easily get a nested field, for example

[json.path.read(monsters, "Orc.Attacks.[1]")]

to returns Punch.

Additionally, if we want an array containing the attacks of each monster, we could type

[json.path.read(monsters, ".Attacks")]

which returns [["Claw","Bite"],["Sword","Punch"]]

Inline filters are also supported, so that if we want the name of the monsters with > 30 HPs, we can type

[json.path.read(monsters, ".[?(@.HP > 30)].name")]

which returns ["Troll"].

Errors

Jayway returns error messages in English which I use for the exceptions. So, if I type

[json.path.read(monsters, "Orc.Spells.[0]")]

I get the error

Error with function "json.path.read": Missing property in path $['Orc']['Spells']

Main issue is that the jayway error messages are not localized.

More information

Information on how to specify the path parameter can be found here.

Merudo added a commit to Merudo/maptool that referenced this issue Sep 5, 2019
- Function takes a "json" and a "path" argument
- Path should be defined according to https://github.com/json-path/JsonPath
- Support inline predicates
- Errors are printed to chat but not according to our standards
- Progress on RPTools#612
Merudo added a commit to Merudo/maptool that referenced this issue Sep 5, 2019
- Function can modify a nested json through json.path.set(json, path, value)
- Path should be defined according to https://github.com/json-path/JsonPath
- Closes RPTools#612
Merudo added a commit to Merudo/maptool that referenced this issue Sep 5, 2019
- Functions can modify a nested json array
- Path should be defined according to https://github.com/json-path/JsonPath
- Closes RPTools#612
- Details:

1. json.path.add(path, value) adds an element to a jsonArray at the path
2. json.path.set(path, value) sets an element in a jsonArray or jsonObject at the path
3. json.path.put(path, key, value) adds or sets an element in a jsonObject at the path
@Merudo
Copy link
Member Author

Merudo commented Sep 5, 2019

The PR now adds three functions: json.path.add, json.path.put and json.path.set.

To add an element to an array at a path, use json.path.add. For example, to add an attack to our Orc:

[json.path.add(monsters, "Orc.Attacks", "Bow")]

To replace a value in an array, for example to replace "Sword" by "Axe", we need to use json.path.set instead:

[json.path.set(monsters, "Orc.Attacks.[0]", "Axe")]

And, to add or replace a value in an object, we need to use json.path.put,

[json.path.put(monsters, "Orc", "AC", 12)]

Together, the three function call would return

{"Troll":{"name":"Troll","HP":75,"Attacks":["Claw","Bite"]},"Orc":{"name":"Orc","HP":13,"Attacks":["Axe","Punch","Bow"],"AC":12}}

EDIT: Also added a json.path.delete, to delete a jsonObject field or a jsonArray element. Example:

[json.path.delete(monsters, "Troll.Attacks.[0]")]

and

[json.path.delete(monsters, "Troll.Attacks[?(@ == 'Claw')]")]

can each delete the "Claw" attack of the Troll.

@Merudo
Copy link
Member Author

Merudo commented Sep 5, 2019

Should put and set be combined in a single function?

@Merudo
Copy link
Member Author

Merudo commented Sep 15, 2019

[r: test = json.path.put("{}", "$", "new-key", "new-val")]

@JamzTheMan change the sign $ to @:

[r: test = json.path.put("{}", "@", "new-key", "new-val")]

@JamzTheMan
Copy link
Member

JamzTheMan commented Sep 15, 2019

Ok, ya, did that but now how do you add an object to an object?

So this fails because it's escaping and putting extra quotes in it looks like:

[r: summary = json.path.put("{}", "@", "Summary", "A mechanical race")]
<br>
[r: races = json.path.put("{}", "@", "Android", summary)]

{"Summary":"A mechanical race"}
{"Android":"{\"Summary\":\"A mechanical race\"}"}

[r: test = json.path.read(races, "Android.Summary")]
Errors with

Error with function "json.path.read": Expected to find an object with property ['Summary'] in path $['Android'] but found 'java.lang.String'. This is not a json object according to the JsonProvider: 'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'.

Where as this works ok:

[r: test = json.path.read('{"Android": {"Summary": "A mechanical race"} }', "Android.Summary")]

A mechanical race

I can't seem to create this easy object: {"Android": {"Summary": "A mechanical race"} } using .put. Ideally creating it in one put statement would be great but even in 2 steps it fails. I'm trying to google to see if we can even do it in one step but haven't found anything yet...

@Merudo
Copy link
Member Author

Merudo commented Sep 15, 2019

I probably just need to add a conversion to json if the object in put is a json string.

@JamzTheMan
Copy link
Member

JamzTheMan commented Sep 15, 2019

@Merudo Thanks! That seemed to do the trick. At least for the escaping of quotes.

Do you know if it's possible to create a nested object is possible, like:
[r: races = json.path.put("{}", "@", "Android.Summary", "a mechanical race")]

@Phergus
Copy link
Contributor

Phergus commented Sep 21, 2019

@JamzTheMan If you were expecting `{"Android":{"Summary":"a mechanical race"}} then the answer is no.

@Phergus
Copy link
Contributor

Phergus commented Sep 21, 2019

Wiki updated by Merudo for json.path.add, .delete, .put and .set functions.

@Phergus
Copy link
Contributor

Phergus commented Sep 26, 2019

@Merudo
For this data:

{
  "$id": "10639",
  "editionNumber": "5e",
  "language": "de-de",
  "siNnerMetaData":   {
    "$id": "10640",
    "id": "009f0da8",
    "visibility":     {
      "$id": "10641",
      "id": null,
      "isPublic": false,
      "isGroupVisible": false,
      "userRights": []
    }
  }
}

Expected this to work:
[r: vis = json.path.read(data,"$.siNnerMetaData.visibility")]

But get this:
java.lang.IllegalArgumentException: Illegal group reference error executing expression vis = json.path.read(test,"$.siNnerMetaData.visibility")

The path works on the Jayway Json Path Evalutor

And it works if I take out the "$.".

Have to escape the dollar sign.
[r: vis = json.path.read(data,"\$.siNnerMetaData.visibility")]

That should probably be in the wiki since it points to the Jayway docs which states:

$ - The root element to query. This starts all path expressions.

@Merudo
Copy link
Member Author

Merudo commented Sep 26, 2019

Here is the code to create @Phergus's json if anyone wants to try it out:

[h: visibility = json.set("{}", "id", "null", "isPublic", "false", "isGroupVisibile", "false", "userRights", "[]")]
[h: siNnerMetaData = json.set("{}", "\$id", "10640","id", "009f0da8","visibility", visibility)]
[h: data = json.set("{}", "\$id", "10639", "editionNumber", "5e", "language", "de-de", "siNnerMetaData", siNnerMetaData)]

@Phergus
Copy link
Contributor

Phergus commented Sep 26, 2019

I just cheat and paste it into a token notes field and then read it from there. Cuz I'm just testing stuff.

[h: data = getNotes("Chummer")]
[r: vis = json.path.read(data,"siNnerMetaData.visibility")]

@rkathey
Copy link
Contributor

rkathey commented Sep 26, 2019

Is there a need for the $ in the id field? Does it serve a purpose in the json.path calls?

@Phergus
Copy link
Contributor

Phergus commented Sep 26, 2019

That's just how the data was when I got it from the Chummer guys. This is actually a tiny snippet of a much large character data collection.

@Phergus
Copy link
Contributor

Phergus commented Sep 26, 2019

@Merudo Is "$." automatically being prepended to the path internally?

@Merudo
Copy link
Member Author

Merudo commented Sep 26, 2019

@Merudo Is "$." automatically being prepended to the path internally?

No, it is not, but it could be.

Is there any reason not to start the path with $?

@Phergus
Copy link
Contributor

Phergus commented Sep 26, 2019

It acts like it is. The online evaluator will take this $..visibility and return the same result as MapTool does with [r: vis = json.path.read(data,".visibility")].

So far any example I find online that starts with "$.", I just take those off and use the remainder in MapTool for the json.path.read() command.

@Phergus
Copy link
Contributor

Phergus commented Sep 26, 2019

Just testing the new functions with examples of normal JSON paths functionality from the JsonPath docs to verify our implementaton is working as expected.

@rkathey
Copy link
Contributor

rkathey commented Sep 26, 2019

I'm testing as well to see how versatile it is. I did find one thing that diverges from the jaway docs.

[h: j='{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } }, "expensive": 10 }'] [r:q=".title"] [r:json.path.read(j,q)]<br> [r:q=".author"] [r:json.path.read(j,q)]<br> [r:q=".bicycle"] [r:json.path.read(j,q)]<br> [r:q=".color"] [r:json.path.read(j,q)]<br> [r:q=".store.book[*].author"] [r:json.path.read(j,q)]<br> [r:q=".*.book[2]"] [r:json.path.read(j,q)]<br> [r:q="..book[2]"] [r:json.path.read(j,q)]<br>

The last one fails. It works if you add the wild card like the statement above.
See https://github.com/json-path/JsonPath/blob/master/README.md for additional queries.

@Phergus
Copy link
Contributor

Phergus commented Sep 26, 2019

Yeah. json.path.read doesn't like the deep scan syntax (".."). If you just leave off the first period it will work. See my comments two posts prior.

@Phergus
Copy link
Contributor

Phergus commented Sep 28, 2019

Basic testing of new functions completed.

  • json.path.add
  • json.path.set
  • json.path.put
  • json.path.read
  • json.path.delete

Closing.

@Phergus Phergus closed this as completed Sep 28, 2019
@Phergus Phergus added the tested This issue has been QA tested by someone other than the developer. label Sep 28, 2019
JamzTheMan added a commit that referenced this issue Oct 4, 2019
* Fix token ids reset on server start

- Fix so that token ids stay the same after server start
- Add javadocs info for Zone & Campaign constructors
- Close #619

* Fix cut & paste changes token id

- Fix so that Cut & paste doesn't change token id
- Subsequent pastes will result in different token ids
- Close #624

* Fix "paste" option remaining grayed out after Copy/Cut token

- Fix "Paste" menu not getting updated after performing the Copy/Cut action from popup menu
- Close #621

* Fix switching from/to the measure tool not updating cursor right away

- Change how the measurer tool cursor updates, now based on attach/detach instead on paintOverlay
- Fix cursor not updating right away when switching from measurer to pointer
- Fix cursor not updating right away when switching to measurer from label, fog or VBL tool
- Close #601

* Fix bug created by dragging token from library to map

- Fix token having duplicated ids if a cut was followed by dragging token to map then a paste (induced by #625)
- Fix dragging token from library to map not ungraying the "Paste" option (fully completes #630)

* Fix incorrect message for assert() when the second parameter is number

- New message: Second argument to "assert": "{second parameter}" must be of type String
- Close #637

* Translate a few UI elements in french

* Consolidate utility methods for macro functions in FunctionUtil

- New class FunctionUtil to handle checks and type conversions for macro functions
- New internal methods checkNumberParam, getTokenFromParam, paramAsBigDecimal, paramAsBoolean, paramAsInteger, paramAsDouble, paramAsFloat, paramAsJson, paramAsJsonObject and paramAsJsonArray
- Change TokenLightFunctions hasLightSource, clearLights, setLight, and getLights to use these new methods
- Methods tested: checkNumberParam, getTokenFromParam, and paramAsBigDecimal
- First step to solve #613

* Add parameter in FunctionUtil to allow/disallow text to BigDecimal

- Add parameter allowString: if set to false, raises exception when parameter is a string that could be converted to number( ex: "0", "5", etc).

* Change ZoomFunction to use FunctionUtil

- Functions getZoom, setZoom, getViewArea, setViewArea, and getViewCenter now use FunctionUtil
- Fix functions getZoom and setViewArea not displaying errors when given too many parameters
- Fix javadocs errors
- Remove extra delimiter at the end of getViewCenter

* Add translation support for "Select Map" button

- Select Map button (top right of screen) is now properly translated
- Tested for English and French

* Change wrong nb of parameters error messages to display function name

- Change wrong number of parameters error messages to always display name of function
- Builds on RPTools/parser#3 to work
- Close #629

* Change parser implementation to 1.5.4

* Add json.path.read function (based on jayway)

- Function takes a "json" and a "path" argument
- Path should be defined according to https://github.com/json-path/JsonPath
- Support inline predicates
- Errors are printed to chat but not according to our standards
- Progress on #612

* Add error handling for json.path.read

* Add json.path.add, json.path.add/put/set, and json.path.delete functions

- Functions can modify a nested json array
- Path should be defined according to https://github.com/json-path/JsonPath
- Closes #612
- Details:

1. json.path.add(json, path, value) adds an element to a jsonArray at the path
2. json.path.set(json, path, value) sets an element in a jsonArray or jsonObject at the path
3. json.path.put(json, path, key, value) adds or sets an element in a jsonObject at the path
4. json.path.delete(json, path) deletes an element in a jsonArray or jsonObject at the path

* Consolidate methods checkNumberOfParameters and getTokenFromParam

- Replace checkNumberOfParameters by FunctionUtil.checkNumberParam
- Replace getTokenFromParam by FunctionUtil.getTokenFromParam
- Fix #613

* Fix bring to front/send to back need to be done twice

- Add ZOrder sorting of the tokens on the server at the end of bringTokensToFront / sendTokensToBack

* Update build.gradle

compile is deprecated and replaced with implementation

* Fix for ConcurrentModificationException

 * Make partialPaths thread safe and Close #328

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Spotless applied

* Add new Server Option for GM to Reveal FoW for Unowned Tokens

 * Closes #665 and Closes #663
 * Added abeille-maptool-forms.jfpr project file to buil-resources

* Add playStream, stopStream, and editStream functions to stream audio

- Add playStream(uri, cycleCount, volume) to play audio from url or local file.
- cycleCount: number of times to play the resource. -1 for infinite loop. Default: 1.
- volume: volume value from 0-1. Default: 1.
- Add stopStream(uri, remove) to stop a stream. If remove is set to 1, unload the stream from memory. Default: 1. If no uri specified, stop all sounds.
- Add editStream(uri, cycleCount, volume) to change the cycleCount or volume of stream.
- Add AppPreference playStreams to enable/disable playing streams
- Ex:

[playStream("https://www.fesliyanstudios.com/musicfiles/2019-05-01_-_Undercover_Spy_Agent_-_David_Fesliyan.mp3", -1, 0.8)]

* Fix disabling streams, and make stream functions thread-safe

- Fix access HashMap to be thread safe (now accessed solely from the JavaFX app single thread)
- Fix so that disabling streams in settings also stops all streams

* Add features to playStream functions

- Move streaming methods to class MediaPlayerAdapter, as discussed in #668
- Add new parameters: startTime and stopTime to playStream & editStream
- playStream with cycleCount 0 preloads the stream but does not play it
- Add function getStreamProperties as suggested in #667
- Add support for volume slider through setGlobalVolume, but the slider needs to be created

* Fix getStreamProperties wrongly returning "PLAYING" , change ms to secs

- Fix getStreamProperties to return status "STOPPED" after song finished playing
- Change parameters startTime and stopTime to take seconds instead of ms

* Add Volume Slider and Mute Button to Toolbar

- Icons provided by @JamzTheMan

Co-Authored-By: Jamz <jamz@nerps.net>

* Add "fadeout" parameter to stopStream

- Add optional fadeout (in seconds) before closing a stream
- 0: no fadeout (default)
- Stream will stop once the fadeout period is over
- Suggested by @dorpond in #615

* Add DebounceExecutor, update ZoneRenderer.java to use debounced repaint (#611)

dispatcher.

* Add sound icons to the github directory

- Add back,forward,next,pause,play,previous,record,record_on,repeat,shuffle,shuffle_on, and stop icons
- Move mute & volume icons to correct directory
- Icons will be used for #615
- Icons provided by @JamzTheMan

Co-Authored-By: Jamz <jamz@nerps.net>

* Add support for space in uri for stream functions

- Add conversion of string to uri, replacing space into %20
- Add "FILE/:" at the start of uri if it is missing
- Fix issues raised in #667

* Fix PRs automatically failed

- Change to using jitpack for clientserver
- Fix #679

* Fix bug: "*" stop working as path in stopStream, getStreamProperties (#682)

- Add special case so that "*" isn't modified
- Fix regression created by #678
- Fix #681

* Add propertyType option for getTokens(), improve getTokens() (#677)

- Add new option "propertyType" to conditions in getTokens()
- Value can be a single type as string, or an array of types
- Simplify getTokens() code by removing the second loop. Now include/exclude is a filter property ("match")
- Improve performance of getTokens() by trimming the list continuously instead of constantly filtering the list of all tokens
- Close #676

* Json, store "null" "false" and "true" as their revelant java type internally (#672)

* jsonify "null", "true" and "false" into null true and false

* fix null handling, using the library Null object

* jsonify should be static and public

* Change getTokens to be much faster with area option (#686)

- Change so overlap is computed explicitely instead of using A*
- Much better performance
- Solves #683 for "area" but not for "range"

* ImagePanel QOL improvements (#691)

- Request only images in view from ImageManager
- Trigger repaint() from paint-affecting properties only if property
actually changes
- Calculate truncated caption heuristically
- Improve spacing
- Include caption in mouse capture area
- Antialias text
- Use interpolation when rendering scaled images

* Fix Manhattan distance, metric distance parameter with iso maps (#690)

- Fix manhattan distance while moving tokens & in distance functions
- Fix getDistance, getDistanceToXY, getTokens ignoring metric parameter for isometric maps
- Close #688

* Fix json.path functions adding extra / and \ to json objects (#693)

- Fix issue raised in #612

* Resolve #694 -- Fix asset panel scaling (#695)

* #696 Implement dragTheshold in DefaultTool

* Fix NullPointer exception when closing maptool

Fix #700

* Change getDistance to use explicit closed-form

- Improve speed dramatically while using getTokens() with a distance option
- Previous walker-based approach kept as it could be extended to take VBL & terrain into account
- Distance returned tested to be the same as previous code
- Close #683

* Fix two issues from moving token when "Snap Token While Dragging" is off

- Fix token "jumping" to a different spot once Snap-to-Grid is disabled
- Fix getDistance returning incorrect distance with NO_GRID metric
- Close #699

* Fix to getDistanceToXY and getDistance with NO_GRID metric

- Change so that getDistanceToXY and getDistance now calculate the distance from the center of the token when the token is large
- Add new "pixel" parameter to getDistanceToXY. It indicates if the x,y are for a cell or pixel (pixel: false by default)
- pixel false: getDistanceToXY gets the distance from the center of the token to the center of the specified cell
- Close #684

* Fix bug in #699 (#711)

- Fix incorrect boolean check
- Fix missing CellPoint to ZonePoint conversion

* Change volume slider to affect system sounds

- Change system sounds to be affected by volume slider & mute button
- Change system sounds to use JavaFX
- Close #709

* Fix campaign macro changes not received when connecting to server

- Fix so macro changes are now properly updated to the server
- Close #713

* Fix bug introduced by #707 with default metrics

- Fix bug where the default metric is the user's preferred one instead of the server's.
- Function affected: getDistance, getDistanceToXY, getTokens
- Fix issue mentioned in #684

* Add option "gm-self", "self", & "all" to broadcast

Close #718

* Fix getViewArea and getViewCenter returning incorrect pixels

- Change so getViewArea and getViewCenter return the actual pixels as used in setViewArea, for example.
- Close #724

Co-Authored-By: Phergus <phergus@users.noreply.github.com>

* Add parameter "players" and "delim" to execLink (#721)

- Add new parameter "players" to execLink. All players specified will have the macro run for them. Default: self.
- The parameter "players" can be a string, a list, or json array. Use new delim parameter for list or array (defaults to ",").
- execLink also accepts "gm", "gm-self", "self", "all", and "none".
- Close #716

* Add scrolling to Select Map menu (#723)

- Add new class "JScrollPopupMenu" to handle scrolling
- Class is fully functional but not complete.  Other methods relying on indexes of the components should be reimplemented before they are used
- Maximum of maps displayed at a time: 20 (scrolling will reveal them all)
- Close #356

* Add function json.toVars to turn jsonObject into variables

- keys become variable names
- values become the content of the variables
- Close #591

* Improvement to json.toVars

- Change: parameter "suffixed" is now replaced by "prefix" and "suffix", which can add a prefix and/or suffix to the names.
- Change: spaces in keys are now turned into underscore
- Change: characters not alpha-numerical other than "." and "_" are deleted from var names
- Change: function now return a JSONArray with the variable names

* Fix javadocs errors

- Fix javadocs errors; it's now possible to generate the full javaDocs
- No actual code changed
- Warnings still present, but the errors should be fixed
- Close #731

* Update ChangeLog for 1.5.5 release (#736)

First pass.

* More updates to ChangeLog plus updated credits. (#737)

* Update ChangeLog for 1.5.5 release

First pass.

* Fix ChangeLog and update credits.html

Fixed typos and missing linkage in ChangeLog.
Updated credits.html file.

Issue #735

* Changed getInfo("server") macro to use ServerPolicy.toJSON directly (#738)

Updated getInfo("server") macro function to pull JSON object from ServerPolicy instead of having duplicated code.
Updated ServerPolicy.toJSON() to include isAutoRevealMovement and isUseIndividualFOW.

* Junit tests for Json function (#741)

* jsonify "null", "true" and "false" into null true and false

* fix null handling, using the library Null object

* jsonify should be static and public

* json unitary tests

* use a resource fiel for json rather that constructed within the test code

* spotless on json tests

* Updated with Issue #670 (#743)

* Update ChangeLog for 1.5.5 release

First pass.

* Fix ChangeLog and update credits.html

Fixed typos and missing linkage in ChangeLog.
Updated credits.html file.

Issue #735

* Add missing issue 670

Updated with issue 670.

* Update parser to 1.5.5

Removed self dependency in Parser project.

* Update build.gradle to pull dicelib v1.5.5 (#749)

build.gradle updated to pull in dicelib v1.5.5
Completes issue #746.

* Closes #751

Due to how the uberJar is packaged, we need to register JAI imageIO for jpeg2000
The same fix was applied to TokenTool for the same issue.

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Updates to Change Log and Credits (#754)

* Update ChangeLog for 1.5.5 release

First pass.

* Fix ChangeLog and update credits.html

Fixed typos and missing linkage in ChangeLog.
Updated credits.html file.

Issue #735

* Add missing issue 670

Updated with issue 670.

* Update ChangeLog and Credits

Updated Change Log for issues 731, 746 & 751.  Updated MapTool credits  with recent contributor and missing `</td>` tags.
@Phergus
Copy link
Contributor

Phergus commented Nov 9, 2019

@Merudo What happened to the idea of either using the DEFAULT_PATH_LEAF_TO_NULL configuration or having a 3rd parameter for json.path.read to set the desired behavior?

See comment above.

Never mind. I see that was PR #871 that got deferred.

BearFather added a commit to BearFather/maptool that referenced this issue Nov 16, 2019
* Spotless applied

* Add new Server Option for GM to Reveal FoW for Unowned Tokens

 * Closes RPTools#665 and Closes RPTools#663
 * Added abeille-maptool-forms.jfpr project file to buil-resources

* Add playStream, stopStream, and editStream functions to stream audio

- Add playStream(uri, cycleCount, volume) to play audio from url or local file.
- cycleCount: number of times to play the resource. -1 for infinite loop. Default: 1.
- volume: volume value from 0-1. Default: 1.
- Add stopStream(uri, remove) to stop a stream. If remove is set to 1, unload the stream from memory. Default: 1. If no uri specified, stop all sounds.
- Add editStream(uri, cycleCount, volume) to change the cycleCount or volume of stream.
- Add AppPreference playStreams to enable/disable playing streams
- Ex:

[playStream("https://www.fesliyanstudios.com/musicfiles/2019-05-01_-_Undercover_Spy_Agent_-_David_Fesliyan.mp3", -1, 0.8)]

* Fix disabling streams, and make stream functions thread-safe

- Fix access HashMap to be thread safe (now accessed solely from the JavaFX app single thread)
- Fix so that disabling streams in settings also stops all streams

* Add features to playStream functions

- Move streaming methods to class MediaPlayerAdapter, as discussed in RPTools#668
- Add new parameters: startTime and stopTime to playStream & editStream
- playStream with cycleCount 0 preloads the stream but does not play it
- Add function getStreamProperties as suggested in RPTools#667
- Add support for volume slider through setGlobalVolume, but the slider needs to be created

* Fix getStreamProperties wrongly returning "PLAYING" , change ms to secs

- Fix getStreamProperties to return status "STOPPED" after song finished playing
- Change parameters startTime and stopTime to take seconds instead of ms

* Add Volume Slider and Mute Button to Toolbar

- Icons provided by @JamzTheMan

Co-Authored-By: Jamz <jamz@nerps.net>

* Add "fadeout" parameter to stopStream

- Add optional fadeout (in seconds) before closing a stream
- 0: no fadeout (default)
- Stream will stop once the fadeout period is over
- Suggested by @dorpond in RPTools#615

* Add DebounceExecutor, update ZoneRenderer.java to use debounced repaint (RPTools#611)

dispatcher.

* Add sound icons to the github directory

- Add back,forward,next,pause,play,previous,record,record_on,repeat,shuffle,shuffle_on, and stop icons
- Move mute & volume icons to correct directory
- Icons will be used for RPTools#615
- Icons provided by @JamzTheMan

Co-Authored-By: Jamz <jamz@nerps.net>

* Add support for space in uri for stream functions

- Add conversion of string to uri, replacing space into %20
- Add "FILE/:" at the start of uri if it is missing
- Fix issues raised in RPTools#667

* Fix PRs automatically failed

- Change to using jitpack for clientserver
- Fix RPTools#679

* Fix bug: "*" stop working as path in stopStream, getStreamProperties (RPTools#682)

- Add special case so that "*" isn't modified
- Fix regression created by RPTools#678
- Fix RPTools#681

* Add propertyType option for getTokens(), improve getTokens() (RPTools#677)

- Add new option "propertyType" to conditions in getTokens()
- Value can be a single type as string, or an array of types
- Simplify getTokens() code by removing the second loop. Now include/exclude is a filter property ("match")
- Improve performance of getTokens() by trimming the list continuously instead of constantly filtering the list of all tokens
- Close RPTools#676

* Json, store "null" "false" and "true" as their revelant java type internally (RPTools#672)

* jsonify "null", "true" and "false" into null true and false

* fix null handling, using the library Null object

* jsonify should be static and public

* Change getTokens to be much faster with area option (RPTools#686)

- Change so overlap is computed explicitely instead of using A*
- Much better performance
- Solves RPTools#683 for "area" but not for "range"

* ImagePanel QOL improvements (RPTools#691)

- Request only images in view from ImageManager
- Trigger repaint() from paint-affecting properties only if property
actually changes
- Calculate truncated caption heuristically
- Improve spacing
- Include caption in mouse capture area
- Antialias text
- Use interpolation when rendering scaled images

* Fix Manhattan distance, metric distance parameter with iso maps (RPTools#690)

- Fix manhattan distance while moving tokens & in distance functions
- Fix getDistance, getDistanceToXY, getTokens ignoring metric parameter for isometric maps
- Close RPTools#688

* Fix json.path functions adding extra / and \ to json objects (RPTools#693)

- Fix issue raised in RPTools#612

* Resolve RPTools#694 -- Fix asset panel scaling (RPTools#695)

* RPTools#696 Implement dragTheshold in DefaultTool

* Fix NullPointer exception when closing maptool

Fix RPTools#700

* Change getDistance to use explicit closed-form

- Improve speed dramatically while using getTokens() with a distance option
- Previous walker-based approach kept as it could be extended to take VBL & terrain into account
- Distance returned tested to be the same as previous code
- Close RPTools#683

* Fix two issues from moving token when "Snap Token While Dragging" is off

- Fix token "jumping" to a different spot once Snap-to-Grid is disabled
- Fix getDistance returning incorrect distance with NO_GRID metric
- Close RPTools#699

* Fix to getDistanceToXY and getDistance with NO_GRID metric

- Change so that getDistanceToXY and getDistance now calculate the distance from the center of the token when the token is large
- Add new "pixel" parameter to getDistanceToXY. It indicates if the x,y are for a cell or pixel (pixel: false by default)
- pixel false: getDistanceToXY gets the distance from the center of the token to the center of the specified cell
- Close RPTools#684

* Fix bug in RPTools#699 (RPTools#711)

- Fix incorrect boolean check
- Fix missing CellPoint to ZonePoint conversion

* Change volume slider to affect system sounds

- Change system sounds to be affected by volume slider & mute button
- Change system sounds to use JavaFX
- Close RPTools#709

* Fix campaign macro changes not received when connecting to server

- Fix so macro changes are now properly updated to the server
- Close RPTools#713

* Fix bug introduced by RPTools#707 with default metrics

- Fix bug where the default metric is the user's preferred one instead of the server's.
- Function affected: getDistance, getDistanceToXY, getTokens
- Fix issue mentioned in RPTools#684

* Add option "gm-self", "self", & "all" to broadcast

Close RPTools#718

* Fix getViewArea and getViewCenter returning incorrect pixels

- Change so getViewArea and getViewCenter return the actual pixels as used in setViewArea, for example.
- Close RPTools#724

Co-Authored-By: Phergus <phergus@users.noreply.github.com>

* Add parameter "players" and "delim" to execLink (RPTools#721)

- Add new parameter "players" to execLink. All players specified will have the macro run for them. Default: self.
- The parameter "players" can be a string, a list, or json array. Use new delim parameter for list or array (defaults to ",").
- execLink also accepts "gm", "gm-self", "self", "all", and "none".
- Close RPTools#716

* Add scrolling to Select Map menu (RPTools#723)

- Add new class "JScrollPopupMenu" to handle scrolling
- Class is fully functional but not complete.  Other methods relying on indexes of the components should be reimplemented before they are used
- Maximum of maps displayed at a time: 20 (scrolling will reveal them all)
- Close RPTools#356

* Add function json.toVars to turn jsonObject into variables

- keys become variable names
- values become the content of the variables
- Close RPTools#591

* Improvement to json.toVars

- Change: parameter "suffixed" is now replaced by "prefix" and "suffix", which can add a prefix and/or suffix to the names.
- Change: spaces in keys are now turned into underscore
- Change: characters not alpha-numerical other than "." and "_" are deleted from var names
- Change: function now return a JSONArray with the variable names

* Fix javadocs errors

- Fix javadocs errors; it's now possible to generate the full javaDocs
- No actual code changed
- Warnings still present, but the errors should be fixed
- Close RPTools#731

* Update ChangeLog for 1.5.5 release (RPTools#736)

First pass.

* More updates to ChangeLog plus updated credits. (RPTools#737)

* Update ChangeLog for 1.5.5 release

First pass.

* Fix ChangeLog and update credits.html

Fixed typos and missing linkage in ChangeLog.
Updated credits.html file.

Issue RPTools#735

* Changed getInfo("server") macro to use ServerPolicy.toJSON directly (RPTools#738)

Updated getInfo("server") macro function to pull JSON object from ServerPolicy instead of having duplicated code.
Updated ServerPolicy.toJSON() to include isAutoRevealMovement and isUseIndividualFOW.

* Junit tests for Json function (RPTools#741)

* jsonify "null", "true" and "false" into null true and false

* fix null handling, using the library Null object

* jsonify should be static and public

* json unitary tests

* use a resource fiel for json rather that constructed within the test code

* spotless on json tests

* Updated with Issue RPTools#670 (RPTools#743)

* Update ChangeLog for 1.5.5 release

First pass.

* Fix ChangeLog and update credits.html

Fixed typos and missing linkage in ChangeLog.
Updated credits.html file.

Issue RPTools#735

* Add missing issue 670

Updated with issue 670.

* Update parser to 1.5.5

Removed self dependency in Parser project.

* Update build.gradle to pull dicelib v1.5.5 (RPTools#749)

build.gradle updated to pull in dicelib v1.5.5
Completes issue RPTools#746.

* Closes RPTools#751

Due to how the uberJar is packaged, we need to register JAI imageIO for jpeg2000
The same fix was applied to TokenTool for the same issue.

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Updates to Change Log and Credits (RPTools#754)

* Update ChangeLog for 1.5.5 release

First pass.

* Fix ChangeLog and update credits.html

Fixed typos and missing linkage in ChangeLog.
Updated credits.html file.

Issue RPTools#735

* Add missing issue 670

Updated with issue 670.

* Update ChangeLog and Credits

Updated Change Log for issues 731, 746 & 751.  Updated MapTool credits  with recent contributor and missing `</td>` tags.

* Fix prompt to "update" to old version when on pre-release (RPTools#757)

* Fix prompt to "update" to old release when on pre-release

- Fix so that a release candidate / alpha / beta no longer gives prompt to "update" to an older release
- Change: users on a pre-release now get a prompt to update to the newest version, such as a newer release candidate
- No change for those on releases
- Close RPTools#627

* Change pre-release detection to use github API

- Change so that pre-release status is detected by parsing the json of all releases and finding the one corresponding to the commit SHA

* blah

* Add Panel for GM macros

- Add a new panel to hold GM macros
- Macros in this panel are only visible to GMs
- Campaign panel left as-is
- Close RPTools#642

* Remove putTokens in macro functions

- Change so that many token functions now only update the relevant information instead of sending the whole token
- Close RPTools#761
- Function affected: addToInitiative, setInitiative, setInitiativeHold, setBar, setBarVisible, setName, setGMName, setHalo, setTokenOpacity, setImageAsset, setPortraitImage, setCharsheetImage, setLabel, resetProperty, setTerrainModifier, setVisible, setOwnerOnlyVisible, setAlwaysVisible, setTokenVBL

* Fix copyToken so copy can be modified in the same macro

- Fix: tokens created by copyToken no longer have their changes reverted at the end of the macro
- Exception: z order is reverted at end of macro
- Fix RPTools#769

* Add "light" option to getTokens and getTokenNames

- light option can be a JSONObject with "value", "category" and "name" fields
- value can be a 0 or a 1, determining if the tokens need to have a light or not
- category and name determine what type of lights the tokens need to have (or not, if value is 0)
- light can also be a 1 or 0 instead of a JSONObject, in which case all tokens with a light (or no lights) are returned
- Close RPTools#745

* Fix json.path.read returning bad JSON object from array

- Change json provider from JsonSmart to Gson
- Close RPTools#775

* Add options not-gm, not-self, and not-gm-self to broadcast

- Close RPTools#782

* Add json.toVars support for JSONArrays

- Change json.toVars to take the elements of a JSONArray and put them into a variable, using the method

json.toVars(jsonArray, variablePrefix)

- Variables will take the names variablePrefix0, variablePrefix1, ...
- Close RPTools#784

* Fix bar functions returning wrong values if bar not defined

- Change to throw exception if the name of the bar is not valid
- Change getBar to return an empty string instead of a null if the bar is defined but isn't visible
- Close RPTools#786

* Release 1.5.6 (RPTools#777)

* Emergency fix for NPE on Mac OS (RPTools#765)

* Update Change Log for 1.5.6

Added notes for 1.5.6 release.

* Added noise rendering to background textures

* Ability to add noise to background tiled textures

* Spoltess apply

* ignore .gradletasknamecache

* removed .gradletasknamecache

* removed unwated files

* Background texture noise (RPTools#791)

* blah

* Added noise rendering to background textures

* Ability to add noise to background tiled textures

* Spoltess apply

* ignore .gradletasknamecache

* removed .gradletasknamecache

* removed unwated files

* Added ability to turn off noise and comments

* Redraw background when noise toggled

* Renamed DrableNoise to make it clearer it doesnt subclass Pant

* Add preferences setting for frame rate cap used in debouncer

Preference setting Frame Rate Cap added for the debouncer. Default of 60 fps.  Issue RPTools#767

* Fix broken smileys

- Remove \b (word boundary) in regular expression as it doesn't work with non-word characters such as smileys
- Add negative lookbehind/ahead instead to prevent unwanted characters near smileys
- Only space, tab, and newline are allowed before/after smiley
- Close RPTools#529

* Update CHANGE_LOG.md

First pass on updating change log for 1.5.7 release.

* Update TaskBarFlasher.java

Chat notification flash now determines the flash color based on the brightness level of the task bar.  This will improve visibility on different color schemes.  Issue RPTools#804.

* Fix getStreamProps() returning malformed JSON

- Remove incorrect space in front of getStreamProperties values
- Close RPTools#803

* Update TaskBarFlasher.java

Spotless pass.

* Update CHANGE_LOG.md

More updates 800, 803, 804

* Add token & mapname parameters to getTokenStates

- New token parameter: if specified, getTokenStates returns the list of all states of the specified group that are enabled on the token
- Set group to "*" to get all states of the token
- If no token parameter specified, the function returns the list of all campaign states
- Close RPTools#801

* Fix Incorrect tooltip for Show Chat Notification Background

- Change tooltip to "If enabled, shows a background frame underneath the typing notification."
- Change name to "Typing Notification Background"
- Close RPTools#800

* Update CHANGE_LOG.md

Missed linkage for 800.

* Fix getTokenStates returning wrong list of states

- Fix issue disclosed by @Phergus in PR RPTools#809

* Add execFunction : functions can now be ran on clients

- Add execFunction(functionName,args,defer, targets, delim)
- args is a json array containing the arguments to the function
- defer, targets and delim work as in execLink
- Close RPTools#790

* Fix exception when copyToken is used

- Fix updates x, y, layer, tokenImage, portraitImage, & handoutImage so they no longer throw an exception
- Close RPTools#814

* Update CHANGE_LOG.md

Typo fixed.

Co-Authored-By: Guillaume F. <filteau.guillaume@gmail.com>

* Update CHANGE_LOG.md

Typos, missing links and other tweaks.

* Change copyToken options to tokenHandout, tokenPortrait

- Change handoutImage update field to tokenHandout
- Change portraitImage update field to tokenPortrait
- Legacy: old values still work
- Fix null pointer exception to propert error message if the image token cannot be found
- Solve issues raised by @Phergus in RPTools#814

* Updating code style and guidelines

First past at incorporating updates and changes per issue RPTools#813.

* More updates

Dumped the ambiguous rule 3.
Allowed some slack on rule 2.

* Update CHANGE_LOG.md

Added issue RPTools#814 and changed list markers to dashes.

* Fix NPE thrown in MapToolFrame

Fixes issue RPTools#740.  ImagePanel getImageIDAt() wasn't checking return value of getIndex().

* Fix for issue RPTools#687

For Table functions `addTableEntry`, `createTable`,  `setTableImage` and `setTableEntry`,  passing an empty AssetID string will no longer apply the bad "Asset://" string to the relevant image entry.  Also fixed: getTableImage() was throwing an NPE if no table image was set.

* Update LookupTableFunction.java

spotlessApply pass

* Fix execLink / execFunction not running locally immediately

- Change so execLink / execFunction are ran immediately for the current player when defer is set to 0.
- Add target options "not-self", "not-gm", and "not-gm-self".
- Fix RPTools#820

* Add playClip, stopClip and getClipProperties functions

- playClip works much like playStream, but preloads the decompresssed sound in memory. This leads to better performances for short sounds.
- playCount of 0: preload the sound
- clips are "fire and forget", and can't be edited once played
- The same clip can be played multiple times simultaneously
- Close RPTools#810

* Change stopStream/getStreamProperties to work with clips

- Change names of stopStream and getStreamProperties to stopSound and getSoundProperties. The new functions work with both streams and clips.
- Add function "defineAudioSource". You can now define a nickname for an audio file, with defineAudioSource(nickname, uri).
- Add already included sounds Dink and Clink as defined audio sources. They can now be played with playClip("Dink") and playClip("Clink")
- Resolve issues discussed in RPTools#810

* Update CHANGE_LOG.md

Added issues 687, 740, 790, 810.

* Fix stream / clip issues

- Change so that playClip / playStream have their default parameter values be those used during the previous play of the clip/stream, or the values changed by editStream
- Add parameter "preload" to defineAudioSource. If set to "stream", preload the sound as stream; if set to "clip", preload the sound as clip.
- Add parameters to defineAudioSource: cycleCount, volume, start and stop. These parameters will be used as default until they are replaced by using playStream/playClip
- Add list of nicknames to getSoundProperties
- Internal change: start and stop are now defined in seconds everywhere
- Fix issues discussed in RPTools#810 and RPTools#822

* Fix incorrect Campaign Name in Title Bar for clients

- Fix so clients see the proper campaign name instead of the name of the last campaign file they loaded
- Close RPTools#788

* Update CHANGE_LOG.md

Add 788, 820, 822

* Added titleCase() macro function

* spotless apply

* Bump sentry from 1.7.5 to 1.7.28

Bumps sentry from 1.7.5 to 1.7.28.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Bump commons-net from 3.2 to 3.6

Bumps commons-net from 3.2 to 3.6.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Bump autocomplete from 3.0.0 to 3.0.2

Bumps [autocomplete](https://github.com/bobbylight/AutoComplete) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/bobbylight/AutoComplete/releases)
- [Commits](bobbylight/AutoComplete@3.0.0...3.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Bump gson from 2.8.5 to 2.8.6

Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.6.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](google/gson@gson-parent-2.8.5...gson-parent-2.8.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Bump xstream from 1.4.9 to 1.4.11.1

Bumps [xstream](https://github.com/x-stream/xstream) from 1.4.9 to 1.4.11.1.
- [Release notes](https://github.com/x-stream/xstream/releases)
- [Commits](https://github.com/x-stream/xstream/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* renamed titleCase to capitalize

* Revert "Bump xstream from 1.4.9 to 1.4.11.1"

* Revert "Bump commons-net from 3.2 to 3.6"

* Update ServerPolicy.java (RPTools#847)

Set "hosting server" JSON returned by `toJSON()` to BigDecimal instead of Boolean for consistency with other settings and compatibility with parser.

* Closes RPTools#848

Add missing "file sync directory" to client info.develop.

Documentation/Wiki should be updated to reflect changes. *Side note: file sync directory preference technically can be ANY directory on the users system. It's used internally for HeroLab portfolio linking and but can be used for other uses such as streaming audio or exportData macro's*

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Closes RPTools#850 - Add log.trace to log macro group

Add log.trace(message) to macro function log group.

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Revert "Bump gson from 2.8.5 to 2.8.6" (RPTools#853)

* Revert "Bump sentry from 1.7.5 to 1.7.28" (RPTools#854)

* Added lastest commits. (RPTools#852)

Added 829, 846, 848 and 850.

* Workaround for RPTools#640 Error which would (previously) cause a bunch of scary errors to appear due to a bug in the jdk when using three monitors.

* Updated changelog

* Updated comments

* Add mapname parameter to getTokens and getTokenNames

- Add optional mapname parameters (defaults to current map)
- Add error message for incorrect number of parameters for FindToken functions
- Close RPTools#867

* Change getTokens "mapName" parameter to condition

- Change so that getTokens/getTokenNames parameter "mapName" added by RPTools#868 is instead specified as a condition
- Discussed in RPTools#867

* Add metadata to getMacroProps function, fixes RPTools#872

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Changed REST.delete to follow post, patch, put format, fixes RPTools#874

It now accepts body/payload.

This changes the signature of the macro a bit so Wiki update is needed as it no long follows REST.get signature.
This fixes an issue where some API's (like GitHub API) require data to be posted in the body.

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Add metadata to getMacroProps function, fixes RPTools#872

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Applied Google Code Formatting

Signed-off-by: Lee Foster <Jamz@Nerps.net>

* Update CHANGE_LOG.md (RPTools#876)

Added RPTools#872, RPTools#874.

* Adds ISO Formatted time with UTC offset

Signed-off-by: JamzTheMan <JamzTheMan@gmail.com>

* Fix for strings being returned with quotes (RPTools#881)

Fixes RPTools#775.  Strings were being returned with quotes.

* Work around JDK bug https://bugs.openjdk.java.net/browse/JDK-8208712

* Add fix for introduced NPE on quit using accel key

* Phergus change log patch 3 (RPTools#889)

* Update CHANGE_LOG.md

* Update CHANGE_LOG.md

Added info on 831 and 883.  Cleanup.

* Fix for RPTools#831 - numbers being returned as strings. (RPTools#888)

* Fix for RPTools#831 - numbers being returned as strings.

json.path.read() was returning numbers as strings.  Fixed.

* Forgot to run spotless

Gotta have that space in there. lol

* Update Crowdin configuration file

* Added badge for localization.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Adding functionality that adds value M Medium impact. T-shirt style story pointing/scope macro changes This issue adds or changes macro functions. Extra work is required (testing, wiki, code editor) tested This issue has been QA tested by someone other than the developer.
Projects
None yet
Development

No branches or pull requests

6 participants