Skip to content

Commit

Permalink
Merge branch 'develop' into l18n_develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Phergus authored Nov 14, 2021
2 parents fd92fb4 + 7a5d9a6 commit a940e3d
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,12 @@ public Object childEvaluate(
String namespace = parameters.get(0).toString();
String path = parameters.get(1).toString();
var context = MapTool.getParser().getContext();
var libOpt = new LibraryManager().getLibrary(namespace);
var libOpt = new LibraryManager().getLibraryForMTScriptCall(namespace, context);
var lib =
libOpt.orElseThrow(
() -> new ParserException(I18N.getText("library.error.notFound", namespace)));
DataValue dataValue;
if (lib.canMTScriptAccessPrivate(context, namespace)) {
if (lib.canMTScriptAccessPrivate(context)) {
dataValue = lib.getLibraryData().thenCompose(data -> data.getStaticData(path)).join();
} else {
dataValue =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ public class TokenCopyDeleteFunctions extends AbstractFunction {
private static final String COPY_FUNC = "copyToken";
private static final String REMOVE_FUNC = "removeToken";

private static final String CREATE_TOKEN_FUNC = "createToken";

private static final String CREATE_TOKENS_FUNC = "createTokens";

private TokenCopyDeleteFunctions() {
super(1, 4, COPY_FUNC, REMOVE_FUNC);
super(1, 4, COPY_FUNC, REMOVE_FUNC, CREATE_TOKEN_FUNC, CREATE_TOKENS_FUNC);
}

public static TokenCopyDeleteFunctions getInstance() {
Expand All @@ -67,8 +71,11 @@ public Object childEvaluate(
Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 0, 2);
int nCopies = psize > 1 ? FunctionUtil.paramAsInteger(functionName, parameters, 1, false) : 1;
JsonObject newVals;
if (psize > 3) newVals = FunctionUtil.paramAsJsonObject(functionName, parameters, 3);
else newVals = new JsonObject();
if (psize > 3) {
newVals = FunctionUtil.paramAsJsonObject(functionName, parameters, 3);
} else {
newVals = new JsonObject();
}

return copyTokens((MapToolVariableResolver) resolver, token, nCopies, newVals);
}
Expand All @@ -80,9 +87,60 @@ public Object childEvaluate(
return deleteToken(token);
}

if (functionName.equalsIgnoreCase(CREATE_TOKEN_FUNC)) {
FunctionUtil.checkNumberParam(functionName, parameters, 1, 1);
JsonObject vals = FunctionUtil.paramAsJsonObject(functionName, parameters, 0);
return createToken((MapToolVariableResolver) resolver, vals);
}

if (functionName.equalsIgnoreCase(CREATE_TOKENS_FUNC)) {
FunctionUtil.checkNumberParam(functionName, parameters, 1, 1);
JsonArray vals = FunctionUtil.paramAsJsonArray(functionName, parameters, 0);
var tokenIds = new JsonArray();
for (int i = 0; i < vals.size(); i++) {
tokenIds.add(
createToken((MapToolVariableResolver) resolver, vals.get(i).getAsJsonObject()));
}
return tokenIds;
}

throw new ParserException(I18N.getText("macro.function.general.unknownFunction", functionName));
}

private String createToken(MapToolVariableResolver resolver, JsonObject vals)
throws ParserException {

if (!vals.has("name")) {
throw new ParserException(I18N.getText("macro.function.tokenCopyDelete.noName"));
}
String name = vals.get("name").getAsString();

if (!vals.has("tokenImage")) {
throw new ParserException(I18N.getText("macro.function.tokenCopyDelete.noImage"));
}
String tokenImage = vals.get("tokenImage").getAsString();

Zone zone = MapTool.getFrame().getCurrentZoneRenderer().getZone();
List<Token> allTokens = zone.getTokens();
Token t = new Token(name, new MD5Key(tokenImage));

// Make sure the exposedAreaGUID stays unique
if (allTokens != null) {
for (Token tok : allTokens) {
GUID tea = tok.getExposedAreaGUID();
if (tea != null && tea.equals(t.getExposedAreaGUID())) {
t.setExposedAreaGUID(new GUID());
}
}
}
// setTokenValues() handles the naming of the new token and must be called even if
// nothing was passed for the updates parameter (newVals).
setTokenValues(t, vals, zone, resolver);

MapTool.serverCommand().putToken(zone.getId(), t);
return t.getId().toString();
}

/**
* Deletes the token.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@
import net.rptools.maptool.client.ui.syntax.MapToolScriptSyntax;
import net.rptools.maptool.language.I18N;
import net.rptools.maptool.model.MacroButtonProperties;
import net.rptools.maptool.model.library.Library;
import net.rptools.maptool.model.Token;
import net.rptools.maptool.model.library.LibraryManager;
import net.rptools.maptool.util.EventMacroUtil;
import net.rptools.maptool.util.threads.ThreadExecutionHelper;
import net.rptools.parser.Parser;
import net.rptools.parser.ParserException;
import net.rptools.parser.VariableResolver;
Expand Down Expand Up @@ -244,29 +243,12 @@ public boolean isFunctionDefined(String name) {
*/
public void handleCampaignLoadMacroEvent() {
userDefinedFunctions.clear();
new LibraryManager()
.getLegacyEventTargets(ON_LOAD_CAMPAIGN_CALLBACK)
.thenApply(
libs -> {
new ThreadExecutionHelper<Void>()
.runOnSwingThread(
() -> {
for (Library lib : libs) {
var token = lib.getAssociatedToken().get();
if (token.isPresent()) { // only supported for lib tokens
EventMacroUtil.callEventHandler(
ON_LOAD_CAMPAIGN_CALLBACK,
lib.getNamespace().get(),
"",
token.get(),
Collections.emptyMap(),
true);
}
}
return null;
});
return null;
});
List<Token> libTokens = EventMacroUtil.getEventMacroTokens(ON_LOAD_CAMPAIGN_CALLBACK);
String prefix = ON_LOAD_CAMPAIGN_CALLBACK + "@";
for (Token handler : libTokens) {
EventMacroUtil.callEventHandlerOld(
prefix + handler.getName(), "", handler, Collections.emptyMap(), true);
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/rptools/maptool/model/Asset.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public enum Type {
private final boolean stringType;

/** Method uses to create an {@code Asset} of this type. */
private final BiFunction<String, byte[], Asset> factory;
private final transient BiFunction<String, byte[], Asset> factory;

/** The default extension for this type. */
private final String defaultExtension;
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/net/rptools/maptool/model/library/Library.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,7 @@ public interface Library {
* Returns if the context is able to access the private values in the library.
*
* @param context the current MTScript context to check.
* @param namespace the namespace of the library.
* @return if the context is able to access the private values in the library.
*/
boolean canMTScriptAccessPrivate(MapToolMacroContext context, String namespace);
boolean canMTScriptAccessPrivate(MapToolMacroContext context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.stream.Collectors;
import net.rptools.maptool.client.AppActions;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.client.MapToolMacroContext;
import net.rptools.maptool.model.library.addon.AddOnLibrary;
import net.rptools.maptool.model.library.addon.AddOnLibraryManager;
import net.rptools.maptool.model.library.addon.TransferableAddOnLibrary;
Expand Down Expand Up @@ -231,6 +232,26 @@ public Optional<LibraryInfo> getLibraryInfo(String namespace)
}
}

/**
* Returns the library with the specified namespace. This version of the method can be used to map
* "@this" to the current library a MTScript macro is running from.
*
* @param namespace the namespace of the library to get.
* @param context the context to use when mapping "@this" to the current library.
* @return the library with the specified namespace.
*/
public Optional<Library> getLibraryForMTScriptCall(
String namespace, MapToolMacroContext context) {
String ns = namespace;
if ("@this".equalsIgnoreCase(namespace)) {
if (context == null || context.getSource() == null || context.getSource().isEmpty()) {
return Optional.empty();
}
ns = context.getSource().replaceFirst("(?i)^lib:", "");
}
return getLibrary(ns);
}

/**
* Returns the library for a given namespace.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public CompletableFuture<Optional<Token>> getAssociatedToken() {
}

@Override
public boolean canMTScriptAccessPrivate(MapToolMacroContext context, String namespace) {
public boolean canMTScriptAccessPrivate(MapToolMacroContext context) {
String source = context.getSource().replaceFirst("(?i)^lib:", "");
return context == null || source.equalsIgnoreCase(namespace);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ static boolean handles(URL path) {
}
}

/**
* Returns the namespace for a lib token.
*
* @param name the name of the lib token.
* @return the namespace for the lib token.
*/
static String namespaceForName(String name) {
return name.substring(4);
}

/**
* Creates a new {@code LibraryToken} for the lib:token id.
*
Expand All @@ -127,7 +137,7 @@ static boolean handles(URL path) {
LibraryToken(Token token) {
id = token.getId();
name = token.getName();
namespace = token.getName().substring(4);
namespace = namespaceForName(token.getName());
version =
Objects.requireNonNullElse(
token.getProperty(LIB_VERSION_PROPERTY_NAME), LIB_VERSION_UNKNOWN)
Expand Down Expand Up @@ -334,7 +344,7 @@ public CompletableFuture<Optional<Token>> getAssociatedToken() {
}

@Override
public boolean canMTScriptAccessPrivate(MapToolMacroContext context, String namespace) {
public boolean canMTScriptAccessPrivate(MapToolMacroContext context) {
return false; // Library Tokens don't have private data
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void tokenRemoved(TokensRemovedEvent event) {
removeTokens(
event.info().stream()
.filter(t -> t.name().toLowerCase().startsWith("lib:"))
.map(t -> new LibraryToken(t.token()))
.map(t -> LibraryToken.namespaceForName(t.name()))
.toList());
});
}
Expand Down Expand Up @@ -131,12 +131,8 @@ private void addTokens(Collection<LibraryToken> libs) {
});
}

private void removeTokens(Collection<LibraryToken> libs) {
libs.forEach(
l -> {
String namespace = l.getNamespace().join();
libraryTokens.remove(namespace);
});
private void removeTokens(Collection<String> namespaces) {
namespaces.forEach(libraryTokens::remove);
}

private void changeTokens(Collection<LibraryToken> libs) {
Expand All @@ -145,7 +141,7 @@ private void changeTokens(Collection<LibraryToken> libs) {
// name may have changed so we need to search by id
GUID id = l.getId();
var old = libraryTokens.values().stream().filter(l2 -> id.equals(l2.getId())).findFirst();
old.ifPresent(libraryToken -> removeTokens(List.of(libraryToken)));
old.ifPresent(libraryToken -> removeTokens(List.of(libraryToken.getNamespace().join())));
addTokens(List.of(l));
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,26 @@ private DataValue getData(String key) {
} else if (val instanceof String s) {
if (s.trim().startsWith("{") || s.startsWith("[")) {
var jsonElement = JsonParser.parseString(s);
if (jsonElement.isJsonArray()) {
return DataValueFactory.fromJsonArray(key, jsonElement.getAsJsonArray());
} else if (jsonElement.isJsonObject()) {
return DataValueFactory.fromJsonObject(key, jsonElement.getAsJsonObject());
try {
if (jsonElement.isJsonArray()) {
return DataValueFactory.fromJsonArray(key, jsonElement.getAsJsonArray());
} else if (jsonElement.isJsonObject()) {
return DataValueFactory.fromJsonObject(key, jsonElement.getAsJsonObject());
}
} catch (Exception e) {
// Do nothing if the json is invalid
}
}
try {
double dval = Double.parseDouble(s.trim());
if (dval == (long) dval) {
return DataValueFactory.fromLong(key, (long) dval);
} else {
return DataValueFactory.fromDouble(key, dval);
}
} catch (NumberFormatException e) {
// Do nothing if can't be parsed as a number
}
return DataValueFactory.fromString(key, s);
} else {
return DataValueFactory.fromString(key, val.toString());
Expand Down
63 changes: 63 additions & 0 deletions src/main/java/net/rptools/maptool/util/EventMacroUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,67 @@ public static MapToolVariableResolver callEventHandler(
}
return newResolver;
}

/**
* Utility wrapper for running a specified macro as an event handler, getting back the variable
* resolver instance that can be checked for any particular outputs.
*
* <p>Called macros will output to chat as normal - to suppress, see {@link
* #callEventHandlerOld(String, String, Token, Map, boolean)}
*
* @param macroTarget the fully-qualified macro name
* @param args the argument string to pass
* @param tokenInContext token to set as current, if any
* @param varsToSet any variables that should be initialized in the macro scope
* @return the variable resolver containing the resulting variable states
*/
public static MapToolVariableResolver callEventHandlerOld(
final String macroTarget,
final String args,
final Token tokenInContext,
Map<String, Object> varsToSet) {
return callEventHandlerOld(macroTarget, args, tokenInContext, varsToSet, false);
}

/**
* Utility wrapper for running a specified macro as an event handler, getting back the variable
* resolver instance that can be checked for any particular outputs.
*
* <p>Optionally suppresses chat output.
*
* @param macroTarget the fully-qualified macro name
* @param args the argument string to pass
* @param tokenInContext token to set as current, if any
* @param varsToSet any variables that should be initialized in the macro scope
* @param suppressChatOutput whether normal macro chat output should be suppressed
* @return the variable resolver containing the resulting variable states
*/
public static MapToolVariableResolver callEventHandlerOld(
final String macroTarget,
final String args,
final Token tokenInContext,
Map<String, Object> varsToSet,
boolean suppressChatOutput) {
if (varsToSet == null) varsToSet = Collections.emptyMap();
MapToolVariableResolver newResolver = new MapToolVariableResolver(tokenInContext);
try {
for (Map.Entry<String, Object> entry : varsToSet.entrySet()) {
newResolver.setVariable(entry.getKey(), entry.getValue());
}
String resultVal =
MapTool.getParser().runMacro(newResolver, tokenInContext, macroTarget, args, false);
if (!suppressChatOutput && resultVal != null && !resultVal.equals("")) {
MapTool.addMessage(
new TextMessage(
TextMessage.Channel.SAY, null, MapTool.getPlayer().getName(), resultVal, null));
}
} catch (AbortFunctionException afe) {
// Do nothing
} catch (ParserException e) {
MapTool.addLocalMessage(
"Event continuing after error running " + macroTarget + ": " + e.getMessage());
LOGGER.debug("error running {}: {}", macroTarget, e.getMessage(), e);
}
return newResolver;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1817,7 +1817,8 @@ macro.function.tokenBarFunction.unknownBar = Error with function "{0}":
# String Property
# {0} = value the user passed.
macro.function.varsFromstrProp.wrongArgs = varsFromStrProp called with 3 arguments, but second argument "{0}" was not one of NONE, SUFFIXED, or UNSUFFIXED.

macro.function.tokenCopyDelete.noName = No name specified for token.
macro.function.tokenCopyDelete.noImage = No image specified for token.

macro.function.markdown.unknownType = Unknown Markdown type {0}.

Expand Down

0 comments on commit a940e3d

Please sign in to comment.