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

Add Reverends Stat Sheets #4278

Merged
merged 13 commits into from
Sep 22, 2023
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,10 @@ dependencies {

implementation 'com.github.jknack:handlebars:4.3.1'
implementation 'com.github.jknack:handlebars-helpers:4.3.1'


// Built In Add-on Libraries
implementation 'com.github.RPTools:maptool-builtin-addons:1.3'
}


Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAME
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public class LibraryManager {

static {
libraryTokenManager.init();
builtInLibraryManager.loadBuiltIns();
new MapToolEventBus().getMainEventBus().register(addOnSlashCommandManager);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ void initialize() {
}

/** Registers the stat sheets that this add-on defines. */
private void registerSheets() {
public void registerSheets() {
var statSheetManager = new StatSheetManager();
statSheetManager.removeNamespace(namespace);
for (StatSheet sheet : statSheets) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,33 @@ public AddOnLibrary importFromFile(File file) throws IOException {
}
}

public AddOnLibrary importFromClassPath(String path) throws IOException {
// Copy the data to temporary file, its a bit hacky, but it works, and we can't create a
// ZipFile from anything but a file.
if (!path.startsWith("/")) {
path = "/" + path;
}

File tempFile = File.createTempFile("mtlib", "tmp");
tempFile.deleteOnExit();

try (var outputStream = Files.newOutputStream(tempFile.toPath())) {
try (var inputStream = AddOnLibraryImporter.class.getResourceAsStream(path)) {
inputStream.transferTo(outputStream);
}
}

return importFromFile(tempFile);
}

/**
* Adds the metadata from the root directory of the zip file to the metadata directory.
*
* @param namespace namespace of the add-on library.
* @param zip the zipfile containing the add-on library.
* @param pathAssetMap the map of asset paths and asset details.
* @throws IOException
*/
private void addMetaData(
String namespace, ZipFile zip, Map<String, Pair<MD5Key, Type>> pathAssetMap)
throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@
*/
package net.rptools.maptool.model.library.builtin;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.model.library.Library;
import net.rptools.maptool.model.library.addon.AddOnLibrary;
import net.rptools.maptool.model.library.addon.AddOnLibraryImporter;

/** Class for managing {@link AddOnLibrary} objects. */
public class BuiltInLibraryManager {
Expand Down Expand Up @@ -117,4 +125,43 @@ public Library getLibrary(URL path) {
return null;
}
}

/** Initializes the built in libraries. */
public void loadBuiltIns() {
var classLoader = Thread.currentThread().getContextClassLoader();

URI uri;
try {
uri = classLoader.getResource(ClassPathAddOnLibrary.BUILTIN_LIB_CLASSPATH_DIR).toURI();
} catch (URISyntaxException e) {
MapTool.showError("msg.error.library.builtin.path", e);
return;
}

try (var fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) {
var resourcePath = fs.getPath(ClassPathAddOnLibrary.BUILTIN_LIB_CLASSPATH_DIR);
var libs =
Files.walk(resourcePath, 1)
.filter(p -> p.toString().endsWith(AddOnLibraryImporter.DROP_IN_LIBRARY_EXTENSION))
.toList();

libs.stream().forEach(System.out::println);
var importer = new AddOnLibraryImporter();
libs.stream()
.forEach(
l -> {
try {
var lib = importer.importFromClassPath(l.toString());
var clib = new ClassPathAddOnLibrary(l.toString(), lib);
registerLibrary(clib);
clib.initialize();

} catch (Exception e) {
MapTool.showError("msg.error.library.builtin.load", e);
}
});
} catch (IOException e) {
MapTool.showError("msg.error.library.builtin.load", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.model.library.builtin;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import net.rptools.lib.MD5Key;
import net.rptools.maptool.client.MapToolMacroContext;
import net.rptools.maptool.client.macro.MacroManager.MacroDetails;
import net.rptools.maptool.model.Asset;
import net.rptools.maptool.model.Token;
import net.rptools.maptool.model.library.LibraryInfo;
import net.rptools.maptool.model.library.MTScriptMacroInfo;
import net.rptools.maptool.model.library.addon.AddOnLibrary;
import net.rptools.maptool.model.library.data.LibraryData;

public class ClassPathAddOnLibrary implements BuiltInLibrary {

private final String resourceFilePath;

private final AddOnLibrary addOnLibrary;

/**
* Creates a new instance of {@link ClassPathAddOnLibrary}.
*
* @param resourceFilePath the resource path for the library.
* @param addOnLibrary the add-on library that was loaded.
*/
public ClassPathAddOnLibrary(String resourceFilePath, AddOnLibrary addOnLibrary) {
this.resourceFilePath = resourceFilePath;
this.addOnLibrary = addOnLibrary;
}

/** The directory on the class path for the built in libraries. */
public static final String BUILTIN_LIB_CLASSPATH_DIR = "net/rptools/maptool/libraries/builtin";

@Override
public CompletableFuture<String> getVersion() {
return addOnLibrary.getVersion();
}

@Override
public CompletableFuture<Boolean> locationExists(URL location) throws IOException {
return addOnLibrary.locationExists(location);
}

@Override
public CompletableFuture<Boolean> isAsset(URL location) {
return addOnLibrary.isAsset(location);
}

@Override
public CompletableFuture<Optional<MD5Key>> getAssetKey(URL location) {
return addOnLibrary.getAssetKey(location);
}

@Override
public CompletableFuture<String> readAsString(URL location) throws IOException {
return addOnLibrary.readAsString(location);
}

@Override
public CompletableFuture<String> readAsHTMLContent(URL location) throws IOException {
return BuiltInLibrary.super.readAsHTMLContent(location);
}

@Override
public CompletableFuture<InputStream> read(URL location) throws IOException {
return addOnLibrary.read(location);
}

@Override
public CompletableFuture<String> getWebsite() {
return addOnLibrary.getWebsite();
}

@Override
public CompletableFuture<String> getGitUrl() {
return addOnLibrary.getGitUrl();
}

@Override
public CompletableFuture<String[]> getAuthors() {
return addOnLibrary.getAuthors();
}

@Override
public CompletableFuture<String> getLicense() {
return addOnLibrary.getLicense();
}

@Override
public CompletableFuture<String> getNamespace() {
return addOnLibrary.getNamespace();
}

@Override
public CompletableFuture<String> getName() {
return addOnLibrary.getName();
}

@Override
public CompletableFuture<String> getDescription() {
return addOnLibrary.getDescription();
}

@Override
public CompletableFuture<String> getShortDescription() {
return addOnLibrary.getShortDescription();
}

@Override
public CompletableFuture<Boolean> allowsUriAccess() {
return addOnLibrary.allowsUriAccess();
}

@Override
public CompletableFuture<LibraryInfo> getLibraryInfo() {
return addOnLibrary.getLibraryInfo();
}

@Override
public CompletableFuture<Optional<MTScriptMacroInfo>> getMTScriptMacroInfo(String macroName) {
return addOnLibrary.getMTScriptMacroInfo(macroName);
}

@Override
public CompletableFuture<Optional<MTScriptMacroInfo>> getPrivateMacroInfo(String macroName) {
return addOnLibrary.getPrivateMacroInfo(macroName);
}

@Override
public CompletableFuture<List<String>> getAllFiles() {
return addOnLibrary.getAllFiles();
}

@Override
public CompletableFuture<LibraryData> getLibraryData() {
return addOnLibrary.getLibraryData();
}

@Override
public CompletableFuture<Optional<String>> getLegacyEventHandlerName(String eventName) {
return addOnLibrary.getLegacyEventHandlerName(eventName);
}

@Override
public CompletableFuture<Optional<Token>> getAssociatedToken() {
return addOnLibrary.getAssociatedToken();
}

@Override
public boolean canMTScriptAccessPrivate(MapToolMacroContext context) {
return addOnLibrary.canMTScriptAccessPrivate(context);
}

@Override
public CompletableFuture<Optional<Asset>> getReadMeAsset() {
return addOnLibrary.getReadMeAsset();
}

@Override
public CompletableFuture<Optional<Asset>> getLicenseAsset() {
return addOnLibrary.getLicenseAsset();
}

@Override
public void cleanup() {
addOnLibrary.cleanup();
}

@Override
public Set<MacroDetails> getSlashCommands() {
return addOnLibrary.getSlashCommands();
}

public String getResourceFilePath() {
return resourceFilePath;
}

void initialize() {
addOnLibrary.registerSheets();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2162,6 +2162,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}.
msg.error.playerDB.cantRemovePlayer = Can't remove player {0} to a database which doesn't support removing players.
msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database.
msg.error.parsing.handlebars = Error parsing handlebars template {0}.
msg.error.library.builtin.path = Can't read built-in library path.
msg.error.library.builtin.load = Can't load built-in library {0}.


msg.info.action.disableFoW = FoW disabled.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.net.URL;
import java.util.List;
import net.rptools.lib.net.RPTURLStreamHandlerFactory;
import net.rptools.maptool.model.library.url.LibraryURLStreamHandler;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.Completion;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
Expand All @@ -26,6 +29,15 @@ class MapToolScriptAutoCompleteTest {

@Test
void tagsAreStrippedFromAShortDesc() {
/*
* Protocol handlers, we need to register lib: protocol handler so that the UDF auto-complete
* doesn't pause with a dialog box containing an error message during tests as now tests
* wont run without any add-on loaded
*/
RPTURLStreamHandlerFactory factory = new RPTURLStreamHandlerFactory();
factory.registerProtocol("lib", new LibraryURLStreamHandler());
URL.setURLStreamHandlerFactory(factory);

MapToolScriptAutoComplete mapToolScriptAutoComplete = new MapToolScriptAutoComplete();
DefaultCompletionProvider completionProvider =
(DefaultCompletionProvider) mapToolScriptAutoComplete.get();
Expand Down