Skip to content

Commit

Permalink
Split up BMUtils class into BMCopy and BMSkin
Browse files Browse the repository at this point in the history
  • Loading branch information
TechnicJelle committed Feb 19, 2024
1 parent adceff7 commit d656453
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 91 deletions.
49 changes: 35 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,64 @@ and to abide by the [license](LICENSE) terms!
This section just contains a brief overview of some of the most useful features of this library.\
Please see the javadoc for the full API reference: [technicjelle.com/BMUtils](https://technicjelle.com/BMUtils/com/technicjelle/BMUtils.html)

- [Copy Jar Resource to BlueMap](#copy-jar-resource-to-bluemap)
- [Copy Any File to BlueMap](#copy-any-file-to-bluemap)
- [Copy Any Stream to BlueMap](#copy-any-stream-to-bluemap)
- [Copying Assets](#copying-assets)
- [Copy Jar Resource](#copy-jar-resource)
- [Copy Any File](#copy-any-file)
- [Copy Any Stream](#copy-any-stream)
- [Get Player Head Icon Address](#get-player-head-icon-address)
- [Create Marker around a Claimed Area](#create-marker-around-a-claimed-area)
- [Expand/Shrink a Shape](#expandshrink-a-shape)

### Copy Jar Resource to BlueMap
### Copying Assets
#### Copy Jar Resource
This function copies any resource file from your jar to the BlueMap assets folder.\
Useful for adding custom icons, scripts, or styles from your own addon.\
Any scripts or styles that are copied with this function will be automatically registered with BlueMap.
```java
copyJarResourceToBlueMap(BlueMapAPI, ClassLoader, String fromResource, String toAsset, boolean overwrite)
BMCopy.jarResourceToWebApp(BlueMapAPI, ClassLoader, String fromResource, String toAsset, boolean overwrite)
```

### Copy Any File to BlueMap
Also available for copying to a specific BlueMap map's [asset storage](https://bluecolored.de/bluemapapi/latest/de/bluecolored/bluemap/api/AssetStorage.html).\
Do not use this method for copying scripts or styles, as those need to be installed in the webapp.
```java
BMCopy.jarResourceToMap(BlueMapMap, ClassLoader, String fromResource, String toAsset, boolean overwrite)
```

#### Copy Any File
This function copies any file to the BlueMap assets folder.\
Useful for copying user-provided assets to BlueMap, from a configuration directory for example.
Useful for copying user-provided assets to BlueMap, from a configuration directory for example.\
Any scripts or styles that are copied with this function will be automatically registered with BlueMap.
```java
copyFileToBlueMap(BlueMapAPI, Path from, String toAsset, boolean overwrite)
BMCopy.fileToWebApp(BlueMapAPI, Path from, String toAsset, boolean overwrite)
```

### Copy Any Stream to BlueMap
Also available for copying to a specific BlueMap map's [asset storage](https://bluecolored.de/bluemapapi/latest/de/bluecolored/bluemap/api/AssetStorage.html).\
Do not use this method for copying scripts or styles, as those need to be installed in the webapp.
```java
BMCopy.fileToMap(BlueMapMap, Path from, String toAsset, boolean overwrite)
```

#### Copy Any Stream
This function copies any stream to the BlueMap assets folder.\
Useful for when you have a stream of data, for example from a URL.
Useful for when you have a stream of data, for example from a URL.\
Any scripts or styles that are copied with this function will be automatically registered with BlueMap.
```java
copyStreamToBlueMap(BlueMapAPI, InputStream in, String toAsset, boolean overwrite)
BMCopy.streamToWebApp(BlueMapAPI, InputStream in, String toAsset, boolean overwrite)
```

Also available for copying to a specific BlueMap map's [asset storage](https://bluecolored.de/bluemapapi/latest/de/bluecolored/bluemap/api/AssetStorage.html).\
Do not use this method for copying scripts or styles, as those need to be installed in the webapp.
```java
BMCopy.streamToMap(BlueMapMap, InputStream in, String toAsset, boolean overwrite)
```

### Get Player Head Icon Address
This function returns the address of a player head icon.\
Useful when you want to use a playerhead from the map.
This function returns the address of a player head icon,
and automatically generates the icon if it doesn't exist yet.\
Useful when you want to use a playerhead from the map.\
For example, when adding custom icons to the map that involve the player head.
```java
getPlayerHeadIconAddress(BlueMapAPI, UUID playerUUID, BlueMapMap blueMapMap)
BMSkin.getPlayerHeadIconAddress(BlueMapAPI, UUID playerUUID, BlueMapMap)
```

### Create Marker around a Claimed Area
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,18 @@

import de.bluecolored.bluemap.api.BlueMapAPI;
import de.bluecolored.bluemap.api.BlueMapMap;
import de.bluecolored.bluemap.api.plugin.SkinProvider;
import org.jetbrains.annotations.NotNull;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Consumer;

public class BMUtils {
private static final String FALLBACK_ICON = "assets/steve.png";

private BMUtils() {
public class BMCopy {
private BMCopy() {
throw new IllegalStateException("Utility class");
}

Expand All @@ -47,7 +40,7 @@ private BMUtils() {
* @param overwrite Whether to overwrite the asset if it already exists
* @throws IOException If the resource could not be copied
*/
public static void copyStreamToBlueMapWebApp(
public static void streamToWebApp(
final @NotNull BlueMapAPI blueMapAPI,
final @NotNull InputStream in,
final @NotNull String toAsset,
Expand Down Expand Up @@ -80,7 +73,7 @@ public static void copyStreamToBlueMapWebApp(
* @param overwrite Whether to overwrite the asset if it already exists
* @throws IOException If the resource could not be copied
*/
public static void copyStreamToBlueMapMap(
public static void streamToMap(
final @NotNull BlueMapMap map,
final @NotNull InputStream in,
final @NotNull String toAsset,
Expand All @@ -106,7 +99,7 @@ public static void copyStreamToBlueMapMap(
* @param overwrite Whether to overwrite the asset if it already exists
* @throws IOException If the resource could not be found or copied
*/
public static void copyFileToBlueMapWebApp(
public static void fileToWebApp(
final @NotNull BlueMapAPI blueMapAPI,
final @NotNull Path from,
final @NotNull String toAsset,
Expand All @@ -115,7 +108,7 @@ public static void copyFileToBlueMapWebApp(
try (
final InputStream in = Files.newInputStream(from)
) {
copyStreamToBlueMapWebApp(blueMapAPI, in, toAsset, overwrite);
streamToWebApp(blueMapAPI, in, toAsset, overwrite);
}
}

Expand All @@ -129,16 +122,16 @@ public static void copyFileToBlueMapWebApp(
* @param overwrite Whether to overwrite the asset if it already exists
* @throws IOException If the resource could not be found or copied
*/
public static void copyFileToBlueMapMap(
public static void fileToMap(
final @NotNull BlueMapMap map,
final @NotNull Path from,
final @NotNull String toAsset,
final boolean overwrite
) throws IOException {
try (
final InputStream in = Files.newInputStream(from);
final InputStream in = Files.newInputStream(from)
) {
copyStreamToBlueMapMap(map, in, toAsset, overwrite);
streamToMap(map, in, toAsset, overwrite);
}
}

Expand All @@ -154,7 +147,7 @@ public static void copyFileToBlueMapMap(
* @param overwrite Whether to overwrite the asset if it already exists
* @throws IOException If the resource could not be found or copied
*/
public static void copyJarResourceToBlueMapWebApp(
public static void jarResourceToWebApp(
final @NotNull BlueMapAPI blueMapAPI,
final @NotNull ClassLoader classLoader,
final @NotNull String fromResource,
Expand All @@ -165,7 +158,7 @@ public static void copyJarResourceToBlueMapWebApp(
final InputStream in = classLoader.getResourceAsStream(fromResource)
) {
if (in == null) throw new IOException("Resource not found: " + fromResource);
copyStreamToBlueMapWebApp(blueMapAPI, in, toAsset, overwrite);
streamToWebApp(blueMapAPI, in, toAsset, overwrite);
}
}

Expand All @@ -180,74 +173,18 @@ public static void copyJarResourceToBlueMapWebApp(
* @param overwrite Whether to overwrite the asset if it already exists
* @throws IOException If the resource could not be found or copied
*/
public static void copyJarResourceToBlueMapMap(
public static void jarResourceToMap(
final @NotNull BlueMapMap map,
final @NotNull ClassLoader classLoader,
final @NotNull String fromResource,
final @NotNull String toAsset,
final boolean overwrite
) throws IOException {
try (
final InputStream in = classLoader.getResourceAsStream(fromResource);
final InputStream in = classLoader.getResourceAsStream(fromResource)
) {
if (in == null) throw new IOException("Resource not found: " + fromResource);
copyStreamToBlueMapMap(map, in, toAsset, overwrite);
}
}

/**
* Gets the URL to a player head icon for a specific map.<br>
* If the icon doesn't exist yet, it will be created.
*
* @param blueMapAPI The BlueMapAPI instance
* @param playerUUID The player to get the head of
* @param blueMapMap The map to get the head for (each map has its own playerheads folder)
* @return The URL to the player head, relative to BlueMap's web root,<br>
* or a Steve head if the head couldn't be found
*/
public static String getPlayerHeadIconAddress(
final @NotNull BlueMapAPI blueMapAPI,
final @NotNull UUID playerUUID,
final @NotNull BlueMapMap blueMapMap
) {
final String assetName = "playerheads/" + playerUUID + ".png";

try {
if (!blueMapMap.getAssetStorage().assetExists(assetName)) {
createPlayerHead(blueMapAPI, playerUUID, assetName, blueMapMap);
}
} catch (IOException e) {
return FALLBACK_ICON;
}

return blueMapMap.getAssetStorage().getAssetUrl(assetName);
}

/**
* For when BlueMap doesn't have an icon for this player yet, so we need to make it create one.
*/
private static void createPlayerHead(
final @NotNull BlueMapAPI blueMapAPI,
final @NotNull UUID playerUUID,
final @NotNull String assetName,
final @NotNull BlueMapMap map
) throws IOException {
final SkinProvider skinProvider = blueMapAPI.getPlugin().getSkinProvider();
try {
final Optional<BufferedImage> oImgSkin = skinProvider.load(playerUUID);
if (oImgSkin.isEmpty()) {
throw new IOException(playerUUID + " doesn't have a skin");
}

try (OutputStream out = map.getAssetStorage().writeAsset(assetName)) {
final BufferedImage head = blueMapAPI.getPlugin().getPlayerMarkerIconFactory()
.apply(playerUUID, oImgSkin.get());
ImageIO.write(head, "png", out);
} catch (IOException e) {
throw new IOException("Failed to write " + playerUUID + "'s head to asset-storage", e);
}
} catch (IOException e) {
throw new IOException("Failed to load skin for player " + playerUUID, e);
streamToMap(map, in, toAsset, overwrite);
}
}
}
89 changes: 89 additions & 0 deletions src/main/java/com/technicjelle/BMSkin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* This file is part of BMUtils, licensed under the MPL2 License (MPL).
* Please keep tabs on https://github.com/TechnicJelle/BMUtils for updates.
*
* Copyright (c) TechnicJelle <https://technicjelle.com>
* Copyright (c) contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

package com.technicjelle;

import de.bluecolored.bluemap.api.BlueMapAPI;
import de.bluecolored.bluemap.api.BlueMapMap;
import de.bluecolored.bluemap.api.plugin.SkinProvider;
import org.jetbrains.annotations.NotNull;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Optional;
import java.util.UUID;

public class BMSkin {
private BMSkin() {
throw new IllegalStateException("Utility class");
}

private static final String FALLBACK_ICON = "assets/steve.png";

/**
* Gets the URL to a player head icon for a specific map.<br>
* If the icon doesn't exist yet, it will be created.
*
* @param blueMapAPI The BlueMapAPI instance
* @param playerUUID The player to get the head of
* @param blueMapMap The map to get the head for (each map has its own playerheads folder)
* @return The URL to the player head, relative to BlueMap's web root,<br>
* or a Steve head if the head couldn't be found
*/
public static String getPlayerHeadIconAddress(
final @NotNull BlueMapAPI blueMapAPI,
final @NotNull UUID playerUUID,
final @NotNull BlueMapMap blueMapMap
) {
final String assetName = "playerheads/" + playerUUID + ".png";

try {
if (!blueMapMap.getAssetStorage().assetExists(assetName)) {
createPlayerHead(blueMapAPI, playerUUID, assetName, blueMapMap);
}
} catch (IOException e) {
return FALLBACK_ICON;
}

return blueMapMap.getAssetStorage().getAssetUrl(assetName);
}

/**
* For when BlueMap doesn't have an icon for this player yet, so we need to make it create one.
*/
private static void createPlayerHead(
final @NotNull BlueMapAPI blueMapAPI,
final @NotNull UUID playerUUID,
final @NotNull String assetName,
final @NotNull BlueMapMap map
) throws IOException {
final SkinProvider skinProvider = blueMapAPI.getPlugin().getSkinProvider();
try {
final Optional<BufferedImage> oImgSkin = skinProvider.load(playerUUID);
if (oImgSkin.isEmpty()) {
throw new IOException(playerUUID + " doesn't have a skin");
}

try (OutputStream out = map.getAssetStorage().writeAsset(assetName)) {
final BufferedImage head = blueMapAPI.getPlugin().getPlayerMarkerIconFactory()
.apply(playerUUID, oImgSkin.get());
ImageIO.write(head, "png", out);
} catch (IOException e) {
throw new IOException("Failed to write " + playerUUID + "'s head to asset-storage", e);
}
} catch (IOException e) {
throw new IOException("Failed to load skin for player " + playerUUID, e);
}
}
}

0 comments on commit d656453

Please sign in to comment.