Update 1.0.11

- potentially fix color cache error
- added /imagemap cleanup command
- added /imagemap debuginfo command
This commit is contained in:
SydMontague 2023-05-01 11:05:42 +02:00
parent 67ed74b006
commit b70a163c3c
23 changed files with 2050 additions and 1902 deletions

24
.github/FUNDING.yml vendored
View File

@ -1,13 +1,13 @@
# These are supported funding model platforms
custom: ["paypal.me/sydmontague"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
# github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
# patreon: # Replace with a single Patreon username
# open_collective: # Replace with a single Open Collective username
# ko_fi: # Replace with a single Ko-fi username
# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
# liberapay: # Replace with a single Liberapay username
# issuehunt: # Replace with a single IssueHunt username
# These are supported funding model platforms
custom: ["paypal.me/sydmontague"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
# github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
# patreon: # Replace with a single Patreon username
# open_collective: # Replace with a single Open Collective username
# ko_fi: # Replace with a single Ko-fi username
# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
# liberapay: # Replace with a single Liberapay username
# issuehunt: # Replace with a single IssueHunt username
# otechie: # Replace with a single Otechie username

View File

@ -1,33 +1,33 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: |
mkdir -p ~/.m2
echo "<settings><servers><server><id>github</id><username>${{ github.actor }}</username><password>${{ github.token }}</password></server></servers></settings>" > ~/.m2/settings.xml
mvn -B package --file pom.xml
- uses: actions/upload-artifact@v1
with:
name: Package
path: target/ImageMaps.jar
- name: Publish to GitHub Packages Apache Maven
run: mvn deploy
env:
GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: |
mkdir -p ~/.m2
echo "<settings><servers><server><id>github</id><username>${{ github.actor }}</username><password>${{ github.token }}</password></server></servers></settings>" > ~/.m2/settings.xml
mvn -B package --file pom.xml
- uses: actions/upload-artifact@v1
with:
name: Package
path: target/ImageMaps.jar
- name: Publish to GitHub Packages Apache Maven
run: mvn deploy
env:
GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password

42
LICENSE
View File

@ -1,21 +1,21 @@
MIT License
Copyright (c) 2020 SydMontague
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
MIT License
Copyright (c) 2020 SydMontague
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

196
README.MD
View File

@ -1,99 +1,99 @@
# ImageMaps
ImageMaps is a plugin for Bukkit Minecraft servers that enables you to place custom images in your world
by rendering them onto maps and placing them in item frames.
This can be used to create info graphics, custom paintings and even the appearance of custom textures.
![Example Screenshot](./screenshot.png)
## Installation
You will need a Server that implements Bukkit 1.13 or newer and the Spigot-API. Some features are only available in newer
releases. Make sure to use the latest release of your server software before reporting issues.
Put the plugin into your servers `plugins` folder and start it up. A folder for the plugin will be created
automatically. You can place your images in the `images` folder inside it.
### Upgrading from versions &lt; 1.0.0
The plugin should convert your maps.yml automatically. It will attempt to create a backup before doing so,
but it is recommended to do one manually as well.
## Usage
In order for you use place images they must be present in the `images` folder. You can either put them
there via FTP or just copying it, or by using the plugin's download command, allowing you to access
images from the Internet.
To place images just run the `/imagemap place` command and right click the block that should be the
upper left corner of the image (based on your perspective).
Images will by default split into 128x128 pixel sub-images to fit on a map. The image may be scaled via
command parameters, however **it is recommended to prepare correctly scaled images**.
The color palette of Minecraft maps is very limited, requiring the plugin/Bukkit to convert the input image.
This will result in your images looking different ingame than the source. The available color table can be
found here: https://minecraft.gamepedia.com/Map_item_format#Color_table
![Example of color conversion](./colorConversion.png)
The invisible and fixed (-> can't be modified) item frame properties are only available in 1.16+. You can modify them for any item frame
by using a configurable (default a wooden hoe) items. Right click to toggle visibility and Shift+Right click to
toggle the fixed state.
### Commands
* /imagemap place &lt;filename> [frameInvisible] [frameFixed] [frameGlowing] [size]
* Starts the placement process
* frameInvisible and frameFixed are only available on 1.16+
* frameGlowing is only available on 1.17+
* /imagemap download &lt;filename> &lt;sourceURL>
* downloads an image from the given URL into the `images` folder
* /imagemap delete &lt;filename>
* deletes an image from the `images` folder
* /imagemap info &lt;filename>
* prints info, such as resolution and expected size
* /imagemap reload &lt;filename>
* reloads an image, to be used when the image file changed
* /imagemap list [page]
* lists all images in the `images` folder
* /imagemap help [command]
* prints help for commands
### Permissions
`imagemaps.*` - grants access to all permissions
`imagemaps.place` - grants access to /imagemap place command
`imagemaps.download` - grants access to /imagemap download command
`imagemaps.delete` - grants access to /imagemap delete command
`imagemaps.info` - grants access to /imagemap info command
`imagemaps.list` - grants access to /imagemap list command
`imagemaps.reload` - grants access to /imagemap reload command
`imagemaps.help` - grants access to /imagemap help command
`imagemaps.toggleFixed` - allows to toggle the "fixed" state of frames with a wooden hoe
`imagemaps.toggleVisible` - allows to toggle the "visible" state of frames with a wooden hoe
All permissions are default true for OPs.
## Maven
You will need to [configure your environment to access GitHub repositories](https://docs.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-apache-maven-for-use-with-github-packages).
```
<repository>
<id>github</id>
<name>ImageMaps repository</name>
<url>https://maven.pkg.github.com/SydMontague/ImageMaps</url>
</repository>
```
```
<dependency>
<groupId>net.craftcitizen</groupId>
<artifactId>imagemaps</artifactId>
<version>1.0.1</version>
</dependency>
```
## Contact
* Discord: SydMontague#8056
* directly on GitHub
* E-Mail: sydmontague@web.de
* Spigot: https://www.spigotmc.org/members/sydmontague.37699/
# ImageMaps
ImageMaps is a plugin for Bukkit Minecraft servers that enables you to place custom images in your world
by rendering them onto maps and placing them in item frames.
This can be used to create info graphics, custom paintings and even the appearance of custom textures.
![Example Screenshot](./screenshot.png)
## Installation
You will need a Server that implements Bukkit 1.13 or newer and the Spigot-API. Some features are only available in newer
releases. Make sure to use the latest release of your server software before reporting issues.
Put the plugin into your servers `plugins` folder and start it up. A folder for the plugin will be created
automatically. You can place your images in the `images` folder inside it.
### Upgrading from versions &lt; 1.0.0
The plugin should convert your maps.yml automatically. It will attempt to create a backup before doing so,
but it is recommended to do one manually as well.
## Usage
In order for you use place images they must be present in the `images` folder. You can either put them
there via FTP or just copying it, or by using the plugin's download command, allowing you to access
images from the Internet.
To place images just run the `/imagemap place` command and right click the block that should be the
upper left corner of the image (based on your perspective).
Images will by default split into 128x128 pixel sub-images to fit on a map. The image may be scaled via
command parameters, however **it is recommended to prepare correctly scaled images**.
The color palette of Minecraft maps is very limited, requiring the plugin/Bukkit to convert the input image.
This will result in your images looking different ingame than the source. The available color table can be
found here: https://minecraft.gamepedia.com/Map_item_format#Color_table
![Example of color conversion](./colorConversion.png)
The invisible and fixed (-> can't be modified) item frame properties are only available in 1.16+. You can modify them for any item frame
by using a configurable (default a wooden hoe) items. Right click to toggle visibility and Shift+Right click to
toggle the fixed state.
### Commands
* /imagemap place &lt;filename> [frameInvisible] [frameFixed] [frameGlowing] [size]
* Starts the placement process
* frameInvisible and frameFixed are only available on 1.16+
* frameGlowing is only available on 1.17+
* /imagemap download &lt;filename> &lt;sourceURL>
* downloads an image from the given URL into the `images` folder
* /imagemap delete &lt;filename>
* deletes an image from the `images` folder
* /imagemap info &lt;filename>
* prints info, such as resolution and expected size
* /imagemap reload &lt;filename>
* reloads an image, to be used when the image file changed
* /imagemap list [page]
* lists all images in the `images` folder
* /imagemap help [command]
* prints help for commands
### Permissions
`imagemaps.*` - grants access to all permissions
`imagemaps.place` - grants access to /imagemap place command
`imagemaps.download` - grants access to /imagemap download command
`imagemaps.delete` - grants access to /imagemap delete command
`imagemaps.info` - grants access to /imagemap info command
`imagemaps.list` - grants access to /imagemap list command
`imagemaps.reload` - grants access to /imagemap reload command
`imagemaps.help` - grants access to /imagemap help command
`imagemaps.toggleFixed` - allows to toggle the "fixed" state of frames with a wooden hoe
`imagemaps.toggleVisible` - allows to toggle the "visible" state of frames with a wooden hoe
All permissions are default true for OPs.
## Maven
You will need to [configure your environment to access GitHub repositories](https://docs.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-apache-maven-for-use-with-github-packages).
```
<repository>
<id>github</id>
<name>ImageMaps repository</name>
<url>https://maven.pkg.github.com/SydMontague/ImageMaps</url>
</repository>
```
```
<dependency>
<groupId>net.craftcitizen</groupId>
<artifactId>imagemaps</artifactId>
<version>1.0.1</version>
</dependency>
```
## Contact
* Discord: SydMontague#8056
* directly on GitHub
* E-Mail: sydmontague@web.de
* Spigot: https://www.spigotmc.org/members/sydmontague.37699/
This plugin has been developed for the [CraftCitizen](https://craftcitizen.net) survival Minecraft server.

228
pom.xml
View File

@ -1,115 +1,115 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.craftcitizen</groupId>
<artifactId>imagemaps</artifactId>
<version>1.0.10</version>
<name>ImageMaps</name>
<description>Render Images onto maps!</description>
<distributionManagement>
<repository>
<id>github</id>
<name>GitHub ImageMaps Packages</name>
<url>https://maven.pkg.github.com/SydMontague/ImageMaps</url>
</repository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>github</id>
<name>GitHub CLCore Packages</name>
<url>https://maven.pkg.github.com/SydMontague/CLCore</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17.1-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.craftlancer</groupId>
<artifactId>clcore</artifactId>
<version>0.4.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<filters>
<filter>
<artifact>de.craftlancer:clcore</artifact>
<includes>
<include>de/craftlancer/core/command/*</include>
<include>de/craftlancer/core/util/*</include>
<include>de/craftlancer/core/LambdaRunnable*</include>
<include>de/craftlancer/core/Utils*</include>
<include>de/craftlancer/core/SemanticVersion*</include>
</includes>
</filter>
</filters>
<artifactSet>
<includes>
<include>de.craftlancer:clcore</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>de.craftlancer.core</pattern>
<shadedPattern>net.craftcitizen.imagemaps.clcore</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.craftcitizen</groupId>
<artifactId>imagemaps</artifactId>
<version>1.0.11</version>
<name>ImageMaps</name>
<description>Render Images onto maps!</description>
<distributionManagement>
<repository>
<id>github</id>
<name>GitHub ImageMaps Packages</name>
<url>https://maven.pkg.github.com/SydMontague/ImageMaps</url>
</repository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>github</id>
<name>GitHub CLCore Packages</name>
<url>https://maven.pkg.github.com/SydMontague/CLCore</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17.1-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.craftlancer</groupId>
<artifactId>clcore</artifactId>
<version>0.4.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<filters>
<filter>
<artifact>de.craftlancer:clcore</artifact>
<includes>
<include>de/craftlancer/core/command/*</include>
<include>de/craftlancer/core/util/*</include>
<include>de/craftlancer/core/LambdaRunnable*</include>
<include>de/craftlancer/core/Utils*</include>
<include>de/craftlancer/core/SemanticVersion*</include>
</includes>
</filter>
</filters>
<artifactSet>
<includes>
<include>de.craftlancer:clcore</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>de.craftlancer.core</pattern>
<shadedPattern>net.craftcitizen.imagemaps.clcore</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,91 +1,92 @@
package net.craftcitizen.imagemaps;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import java.util.HashMap;
import java.util.Map;
@SerializableAs("ImageMaps.Map")
public class ImageMap implements ConfigurationSerializable {
private String filename;
private int x;
private int y;
private double scale;
public ImageMap(String filename, int x, int y, double scale) {
this.filename = filename;
this.x = x;
this.y = y;
this.scale = scale;
}
public ImageMap(Map<?, ?> map) {
this.filename = map.get("image").toString();
this.x = (Integer) map.get("x");
this.y = (Integer) map.get("y");
this.scale = (Double) map.get("scale");
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
map.put("image", filename);
map.put("x", x);
map.put("y", y);
map.put("scale", scale);
return map;
}
public String getFilename() {
return filename;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public double getScale() {
return scale;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((filename == null) ? 0 : filename.hashCode());
long temp;
temp = Double.doubleToLongBits(scale);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof ImageMap))
return false;
ImageMap other = (ImageMap) obj;
if (filename == null) {
if (other.filename != null)
return false;
} else if (!filename.equals(other.filename))
return false;
if (Double.doubleToLongBits(scale) != Double.doubleToLongBits(other.scale))
return false;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
package net.craftcitizen.imagemaps;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import java.util.HashMap;
import java.util.Map;
@SerializableAs("ImageMaps.Map")
public class ImageMap implements ConfigurationSerializable {
private String filename;
private int x;
private int y;
private double scale;
public ImageMap(String filename, int x, int y, double scale) {
this.filename = filename;
this.x = x;
this.y = y;
this.scale = scale;
}
public ImageMap(Map<?, ?> map) {
this.filename = map.get("image").toString();
this.x = (Integer) map.get("x");
this.y = (Integer) map.get("y");
this.scale = (Double) map.get("scale");
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
map.put("image", filename);
map.put("x", x);
map.put("y", y);
map.put("scale", scale);
return map;
}
public String getFilename() {
return filename;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public double getScale() {
return scale;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((filename == null) ? 0 : filename.hashCode());
long temp;
temp = Double.doubleToLongBits(scale);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof ImageMap))
return false;
ImageMap other = (ImageMap) obj;
if (filename == null) {
if (other.filename != null)
return false;
}
else if (!filename.equals(other.filename))
return false;
if (Double.doubleToLongBits(scale) != Double.doubleToLongBits(other.scale))
return false;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}

View File

@ -0,0 +1,37 @@
package net.craftcitizen.imagemaps;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
public class ImageMapCleanupCommand extends ImageMapSubCommand {
public ImageMapCleanupCommand(ImageMaps plugin) {
super("imagemaps.admin", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
int removedMaps = getPlugin().cleanupMaps();
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Removed " + removedMaps + " invalid images/maps.");
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Removes maps with invalid IDs or missing image files.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING,
"This action is not reverseable. It is recommended to create a backup of your maps.yml first!");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap cleanup");
}
}

View File

@ -1,16 +1,18 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.command.CommandHandler;
public class ImageMapCommandHandler extends CommandHandler {
public ImageMapCommandHandler(ImageMaps plugin) {
super(plugin);
registerSubCommand("download", new ImageMapDownloadCommand(plugin));
registerSubCommand("delete", new ImageMapDeleteCommand(plugin));
registerSubCommand("place", new ImageMapPlaceCommand(plugin));
registerSubCommand("info", new ImageMapInfoCommand(plugin));
registerSubCommand("list", new ImageMapListCommand(plugin));
registerSubCommand("reload", new ImageMapReloadCommand(plugin));
registerSubCommand("help", new ImageMapHelpCommand(plugin, getCommands()), "?");
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.command.CommandHandler;
public class ImageMapCommandHandler extends CommandHandler {
public ImageMapCommandHandler(ImageMaps plugin) {
super(plugin);
registerSubCommand("download", new ImageMapDownloadCommand(plugin));
registerSubCommand("delete", new ImageMapDeleteCommand(plugin));
registerSubCommand("place", new ImageMapPlaceCommand(plugin));
registerSubCommand("info", new ImageMapInfoCommand(plugin));
registerSubCommand("list", new ImageMapListCommand(plugin));
registerSubCommand("reload", new ImageMapReloadCommand(plugin));
registerSubCommand("cleanup", new ImageMapCleanupCommand(plugin));
registerSubCommand("debuginfo", new ImageMapDebugInfoCommand(plugin));
registerSubCommand("help", new ImageMapHelpCommand(plugin, getCommands()), "?");
}
}

View File

@ -0,0 +1,39 @@
package net.craftcitizen.imagemaps;
import javax.imageio.ImageIO;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
public class ImageMapDebugInfoCommand extends ImageMapSubCommand {
public ImageMapDebugInfoCommand(ImageMaps plugin) {
super("imagemaps.admin", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"ImageMaps Version " + getPlugin().getDescription().getVersion());
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "OS: " + System.getProperty("os.name"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "ImageIO Params:");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Formats: " + String.join(", ", ImageIO.getReaderFormatNames()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Suffixes: " + String.join(", ", ImageIO.getReaderFileSuffixes()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"MIME: " + String.join(", ", ImageIO.getReaderMIMETypes()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Uses Cache: " + Boolean.toString(ImageIO.getUseCache()));
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Prints some debug output.");
}
}

View File

@ -1,64 +1,65 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class ImageMapDeleteCommand extends ImageMapSubCommand {
public ImageMapDeleteCommand(ImageMaps plugin) {
super("imagemaps.delete", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
if (!getPlugin().hasImage(filename)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "No image with this name exists.");
return null;
}
if (getPlugin().deleteImage(filename)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "File deleted.");
} else {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Failed to delete file.");
}
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Deletes an image.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap delete <filename>");
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 2)
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
return Collections.emptyList();
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class ImageMapDeleteCommand extends ImageMapSubCommand {
public ImageMapDeleteCommand(ImageMaps plugin) {
super("imagemaps.delete", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
if (!getPlugin().hasImage(filename)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "No image with this name exists.");
return null;
}
if (getPlugin().deleteImage(filename)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "File deleted.");
}
else {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Failed to delete file.");
}
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Deletes an image.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap delete <filename>");
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 2)
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
return Collections.emptyList();
}
}

View File

@ -1,114 +1,122 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.LambdaRunnable;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class ImageMapDownloadCommand extends ImageMapSubCommand {
public ImageMapDownloadCommand(ImageMaps plugin) {
super("imagemaps.download", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 3) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name and a download link.");
return null;
}
String filename = args[1];
String url = args[2];
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
new LambdaRunnable(() -> download(sender, url, filename)).runTaskAsynchronously(plugin);
return null;
}
private void download(CommandSender sender, String input, String filename) {
try {
URL srcURL = new URL(input);
if (!srcURL.getProtocol().startsWith("http")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Download URL is not valid.");
return;
}
URLConnection connection = srcURL.openConnection();
if (!(connection instanceof HttpURLConnection)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Download URL is not valid.");
return;
}
connection.setRequestProperty("User-Agent", "ImageMaps/0");
if (((HttpURLConnection) connection).getResponseCode() != 200) {
MessageUtil.sendMessage(getPlugin(),
sender,
MessageLevel.WARNING,
String.format("Download failed, HTTP Error code %d.", ((HttpURLConnection) connection).getResponseCode()));
return;
}
String mimeType = connection.getHeaderField("Content-type");
if (!(mimeType.startsWith("image/"))) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, String.format("Download is a %s file, not image.", mimeType));
return;
}
try (InputStream str = connection.getInputStream()) {
BufferedImage image = ImageIO.read(str);
if (image == null) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Downloaded file is not an image!");
return;
}
File outFile = new File(plugin.getDataFolder(), "images" + File.separatorChar + filename);
boolean fileExisted = outFile.exists();
ImageIO.write(image, "PNG", outFile);
if (fileExisted) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "File already exists, overwriting!");
getPlugin().reloadImage(filename);
}
} catch (IllegalArgumentException ex) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Received no data");
return;
}
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Download complete.");
} catch (MalformedURLException ex) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Malformatted URL");
} catch (IOException ex) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.ERROR, "An IO Exception happened, see server log");
ex.printStackTrace();
}
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Downloads an image from an URL.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap download <filename> <sourceURL>");
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.LambdaRunnable;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class ImageMapDownloadCommand extends ImageMapSubCommand {
public ImageMapDownloadCommand(ImageMaps plugin) {
super("imagemaps.download", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 3) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING,
"You must specify a file name and a download link.");
return null;
}
String filename = args[1];
String url = args[2];
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
new LambdaRunnable(() -> download(sender, url, filename)).runTaskAsynchronously(plugin);
return null;
}
private void download(CommandSender sender, String input, String filename) {
try {
URL srcURL = new URL(input);
if (!srcURL.getProtocol().startsWith("http")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Download URL is not valid.");
return;
}
URLConnection connection = srcURL.openConnection();
if (!(connection instanceof HttpURLConnection)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Download URL is not valid.");
return;
}
connection.setRequestProperty("User-Agent", "ImageMaps/0");
if (((HttpURLConnection) connection).getResponseCode() != 200) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING,
String.format("Download failed, HTTP Error code %d.",
((HttpURLConnection) connection).getResponseCode()));
return;
}
String mimeType = connection.getHeaderField("Content-type");
if (!(mimeType.startsWith("image/"))) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING,
String.format("Download is a %s file, not image.", mimeType));
return;
}
try (InputStream str = connection.getInputStream()) {
BufferedImage image = ImageIO.read(str);
if (image == null) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING,
"Downloaded file is not an image!");
return;
}
File outFile = new File(plugin.getDataFolder(), "images" + File.separatorChar + filename);
boolean fileExisted = outFile.exists();
ImageIO.write(image, "PNG", outFile);
if (fileExisted) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING,
"File already exists, overwriting!");
getPlugin().reloadImage(filename);
}
}
catch (IllegalArgumentException ex) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Received no data");
return;
}
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Download complete.");
}
catch (MalformedURLException ex) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Malformatted URL");
}
catch (IOException ex) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.ERROR,
"An IO Exception happened, see server log");
ex.printStackTrace();
}
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Downloads an image from an URL.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO,
"Usage: /imagemap download <filename> <sourceURL>");
}
}

View File

@ -1,58 +1,67 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.command.HelpCommand;
import de.craftlancer.core.command.SubCommand;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import java.util.Map;
public class ImageMapHelpCommand extends HelpCommand {
public ImageMapHelpCommand(Plugin plugin, Map<String, SubCommand> map) {
super("imagemaps.help", plugin, map);
}
@Override
public void help(CommandSender sender) {
if (((ImageMaps) getPlugin()).isGlowingSupported()) {
MessageUtil.sendMessage(getPlugin(),
sender,
MessageLevel.NORMAL,
buildMessage("/imagemap place <filename> [frameInvisible] [frameFixed] [frameGlowing] [size]", " - starts image placement"));
} else if (((ImageMaps) getPlugin()).isInvisibilitySupported()) {
MessageUtil.sendMessage(getPlugin(),
sender,
MessageLevel.NORMAL,
buildMessage("/imagemap place <filename> [frameInvisible] [frameFixed] [size]", " - starts image placement"));
} else {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, buildMessage("/imagemap place <filename> [size]", " - starts image placement"));
}
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, buildMessage("/imagemap download <filename> <sourceURL>", " - downloads an image"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, buildMessage("/imagemap delete <filename>", " - deletes an image"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, buildMessage("/imagemap info <filename>", " - displays image info"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, buildMessage("/imagemap reload <filename>", " - reloads an image from disk"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, buildMessage("/imagemap list [page]", " - lists all files in the images folder"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, buildMessage("/imagemap help [command]", " - shows help"));
}
private static BaseComponent buildMessage(String str1, String str2) {
BaseComponent combined = new TextComponent();
BaseComponent comp1 = new TextComponent(str1);
comp1.setColor(ChatColor.WHITE);
BaseComponent comp2 = new TextComponent(str2);
comp2.setColor(ChatColor.GRAY);
combined.addExtra(comp1);
combined.addExtra(comp2);
return combined;
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.command.HelpCommand;
import de.craftlancer.core.command.SubCommand;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import java.util.Map;
public class ImageMapHelpCommand extends HelpCommand {
public ImageMapHelpCommand(Plugin plugin, Map<String, SubCommand> map) {
super("imagemaps.help", plugin, map);
}
@Override
public void help(CommandSender sender) {
if (((ImageMaps) getPlugin()).isGlowingSupported()) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap place <filename> [frameInvisible] [frameFixed] [frameGlowing] [size]",
" - starts image placement"));
}
else if (((ImageMaps) getPlugin()).isInvisibilitySupported()) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap place <filename> [frameInvisible] [frameFixed] [size]",
" - starts image placement"));
}
else {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap place <filename> [size]", " - starts image placement"));
}
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap download <filename> <sourceURL>", " - downloads an image"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap delete <filename>", " - deletes an image"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap info <filename>", " - displays image info"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap reload <filename>", " - reloads an image from disk"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap cleanup", " - removes invalid maps from plugin"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap list [page]", " - lists all files in the images folder"));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
buildMessage("/imagemap help [command]", " - shows help"));
}
private static BaseComponent buildMessage(String str1, String str2) {
BaseComponent combined = new TextComponent();
BaseComponent comp1 = new TextComponent(str1);
comp1.setColor(ChatColor.WHITE);
BaseComponent comp2 = new TextComponent(str2);
comp2.setColor(ChatColor.GRAY);
combined.addExtra(comp1);
combined.addExtra(comp2);
return combined;
}
}

View File

@ -1,84 +1,89 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import de.craftlancer.core.util.Tuple;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class ImageMapInfoCommand extends ImageMapSubCommand {
public ImageMapInfoCommand(ImageMaps plugin) {
super("imagemaps.info", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
BufferedImage image = getPlugin().getImage(filename);
if (image == null) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "No image with this name exists.");
return null;
}
Tuple<Integer, Integer> size = getPlugin().getImageSize(filename, null);
BaseComponent reloadAction = new TextComponent("[Reload]");
reloadAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/imagemap reload \"%s\"", filename)));
reloadAction.setColor(ChatColor.GOLD);
BaseComponent placeAction = new TextComponent("[Place]");
placeAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/imagemap place \"%s\"", filename)));
placeAction.setColor(ChatColor.GOLD);
BaseComponent deleteAction = new TextComponent("[Delete]");
deleteAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/imagemap delete \"%s\"", filename)));
deleteAction.setColor(ChatColor.RED);
BaseComponent actions = new TextComponent("Action: ");
actions.addExtra(reloadAction);
actions.addExtra(" ");
actions.addExtra(placeAction);
actions.addExtra(" ");
actions.addExtra(deleteAction);
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Image Information: ");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, String.format("File Name: %s", filename));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, String.format("Resolution: %dx%d", image.getWidth(), image.getHeight()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, String.format("Ingame Size: %dx%d", size.getKey(), size.getValue()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, actions);
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Displays information about an image.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap info <filename>");
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 2)
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
return Collections.emptyList();
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import de.craftlancer.core.util.Tuple;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class ImageMapInfoCommand extends ImageMapSubCommand {
public ImageMapInfoCommand(ImageMaps plugin) {
super("imagemaps.info", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
BufferedImage image = getPlugin().getImage(filename);
if (image == null) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "No image with this name exists.");
return null;
}
Tuple<Integer, Integer> size = getPlugin().getImageSize(filename, null);
BaseComponent reloadAction = new TextComponent("[Reload]");
reloadAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format("/imagemap reload \"%s\"", filename)));
reloadAction.setColor(ChatColor.GOLD);
BaseComponent placeAction = new TextComponent("[Place]");
placeAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format("/imagemap place \"%s\"", filename)));
placeAction.setColor(ChatColor.GOLD);
BaseComponent deleteAction = new TextComponent("[Delete]");
deleteAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format("/imagemap delete \"%s\"", filename)));
deleteAction.setColor(ChatColor.RED);
BaseComponent actions = new TextComponent("Action: ");
actions.addExtra(reloadAction);
actions.addExtra(" ");
actions.addExtra(placeAction);
actions.addExtra(" ");
actions.addExtra(deleteAction);
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Image Information: ");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, String.format("File Name: %s", filename));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
String.format("Resolution: %dx%d", image.getWidth(), image.getHeight()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
String.format("Ingame Size: %dx%d", size.getKey(), size.getValue()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, actions);
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Displays information about an image.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap info <filename>");
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 2)
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
return Collections.emptyList();
}
}

View File

@ -1,84 +1,88 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ClickEvent.Action;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.io.File;
public class ImageMapListCommand extends ImageMapSubCommand {
public ImageMapListCommand(ImageMaps plugin) {
super("imagemaps.list", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
String[] fileList = new File(plugin.getDataFolder(), "images").list();
long page = args.length >= 2 ? Utils.parseIntegerOrDefault(args[1], 0) - 1 : 0;
int numPages = (int) Math.ceil((double) fileList.length / Utils.ELEMENTS_PER_PAGE);
MessageUtil.sendMessage(plugin, sender, MessageLevel.INFO, String.format("## Image List Page %d of %d ##", page + 1, numPages));
boolean even = false;
for (String filename : Utils.paginate(fileList, page)) {
BaseComponent infoAction = new TextComponent("[Info]");
infoAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/imagemap info \"%s\"", filename)));
infoAction.setColor(ChatColor.GOLD);
BaseComponent reloadAction = new TextComponent("[Reload]");
reloadAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/imagemap reload \"%s\"", filename)));
reloadAction.setColor(ChatColor.GOLD);
BaseComponent placeAction = new TextComponent("[Place]");
placeAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/imagemap place \"%s\"", filename)));
placeAction.setColor(ChatColor.GOLD);
BaseComponent deleteAction = new TextComponent("[Delete]");
deleteAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/imagemap delete \"%s\"", filename)));
deleteAction.setColor(ChatColor.RED);
BaseComponent message = new TextComponent(filename);
message.setColor(even ? ChatColor.GRAY : ChatColor.WHITE);
message.addExtra(" ");
message.addExtra(infoAction);
message.addExtra(" ");
message.addExtra(reloadAction);
message.addExtra(" ");
message.addExtra(placeAction);
message.addExtra(" ");
message.addExtra(deleteAction);
MessageUtil.sendMessage(plugin, sender, MessageLevel.NORMAL, message);
even = !even;
}
BaseComponent navigation = new TextComponent();
BaseComponent prevPage = new TextComponent(String.format("<< Page %d", Math.max(page, 1)));
BaseComponent nextPage = new TextComponent(String.format("Page %d >>", Math.min(page + 1, numPages)));
prevPage.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/imagemap list " + Math.max(page, 1)));
nextPage.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/imagemap list " + Math.min(page + 2, numPages)));
navigation.addExtra(prevPage);
navigation.addExtra(" | ");
navigation.addExtra(nextPage);
MessageUtil.sendMessage(plugin, sender, MessageLevel.INFO, navigation);
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Lists all files in the images folder.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap list [page]");
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ClickEvent.Action;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.io.File;
public class ImageMapListCommand extends ImageMapSubCommand {
public ImageMapListCommand(ImageMaps plugin) {
super("imagemaps.list", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
String[] fileList = new File(plugin.getDataFolder(), "images").list();
long page = args.length >= 2 ? Utils.parseIntegerOrDefault(args[1], 0) - 1 : 0;
int numPages = (int) Math.ceil((double) fileList.length / Utils.ELEMENTS_PER_PAGE);
MessageUtil.sendMessage(plugin, sender, MessageLevel.INFO,
String.format("## Image List Page %d of %d ##", page + 1, numPages));
boolean even = false;
for (String filename : Utils.paginate(fileList, page)) {
BaseComponent infoAction = new TextComponent("[Info]");
infoAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format("/imagemap info \"%s\"", filename)));
infoAction.setColor(ChatColor.GOLD);
BaseComponent reloadAction = new TextComponent("[Reload]");
reloadAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format("/imagemap reload \"%s\"", filename)));
reloadAction.setColor(ChatColor.GOLD);
BaseComponent placeAction = new TextComponent("[Place]");
placeAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format("/imagemap place \"%s\"", filename)));
placeAction.setColor(ChatColor.GOLD);
BaseComponent deleteAction = new TextComponent("[Delete]");
deleteAction.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format("/imagemap delete \"%s\"", filename)));
deleteAction.setColor(ChatColor.RED);
BaseComponent message = new TextComponent(filename);
message.setColor(even ? ChatColor.GRAY : ChatColor.WHITE);
message.addExtra(" ");
message.addExtra(infoAction);
message.addExtra(" ");
message.addExtra(reloadAction);
message.addExtra(" ");
message.addExtra(placeAction);
message.addExtra(" ");
message.addExtra(deleteAction);
MessageUtil.sendMessage(plugin, sender, MessageLevel.NORMAL, message);
even = !even;
}
BaseComponent navigation = new TextComponent();
BaseComponent prevPage = new TextComponent(String.format("<< Page %d", Math.max(page, 1)));
BaseComponent nextPage = new TextComponent(String.format("Page %d >>", Math.min(page + 2, numPages)));
prevPage.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/imagemap list " + Math.max(page, 1)));
nextPage.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/imagemap list " + Math.min(page + 2, numPages)));
navigation.addExtra(prevPage);
navigation.addExtra(" | ");
navigation.addExtra(nextPage);
MessageUtil.sendMessage(plugin, sender, MessageLevel.INFO, navigation);
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Lists all files in the images folder.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap list [page]");
}
}

View File

@ -1,128 +1,133 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import de.craftlancer.core.util.Tuple;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ImageMapPlaceCommand extends ImageMapSubCommand {
public ImageMapPlaceCommand(ImageMaps plugin) {
super("imagemaps.place", plugin, false);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
boolean isInvisible = false;
boolean isFixed = false;
boolean isGlowing = false;
Tuple<Integer, Integer> scale;
if (getPlugin().isInvisibilitySupported()) {
isInvisible = args.length >= 3 && Boolean.parseBoolean(args[2]);
isFixed = args.length >= 4 && Boolean.parseBoolean(args[3]);
if (getPlugin().isGlowingSupported()) {
isGlowing = args.length >= 5 && Boolean.parseBoolean(args[4]);
scale = args.length >= 6 ? parseScale(args[5]) : new Tuple<>(-1, -1);
} else {
scale = args.length >= 5 ? parseScale(args[4]) : new Tuple<>(-1, -1);
}
} else {
scale = args.length >= 3 ? parseScale(args[2]) : new Tuple<>(-1, -1);
}
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
if (!getPlugin().hasImage(filename)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "No image with this name exists.");
return null;
}
Player player = (Player) sender;
player.setMetadata(ImageMaps.PLACEMENT_METADATA, new FixedMetadataValue(getPlugin(), new PlacementData(filename, isInvisible, isFixed, isGlowing, scale)));
Tuple<Integer, Integer> size = getPlugin().getImageSize(filename, scale);
MessageUtil.sendMessage(getPlugin(),
sender,
MessageLevel.NORMAL,
String.format("Started placing of %s. It needs a %d by %d area.", args[1], size.getKey(), size.getValue()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Right click on the block, that should be the upper left corner.");
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Starts placing an image.");
if (getPlugin().isGlowingSupported()) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap place <filename> [frameInvisible] [frameFixed] [frameGlowing] [size]");
} else if (getPlugin().isInvisibilitySupported()) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap place <filename> [frameInvisible] [frameFixed] [size]");
} else {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap place <filename> [size]");
}
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Size format: XxY -> 5x2, use -1 for default");
MessageUtil.sendMessage(getPlugin(),
sender,
MessageLevel.NORMAL,
"The plugin will scale the map to not be larger than the given size while maintaining the aspect ratio.");
MessageUtil.sendMessage(getPlugin(),
sender,
MessageLevel.NORMAL,
"It's recommended to avoid the size function in favor of using properly sized source images.");
}
private static Tuple<Integer, Integer> parseScale(String string) {
String[] tmp = string.split("x");
if (tmp.length < 2)
return new Tuple<>(-1, -1);
return new Tuple<>(Utils.parseIntegerOrDefault(tmp[0], -1), Utils.parseIntegerOrDefault(tmp[1], -1));
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length > 2 && !getPlugin().isInvisibilitySupported()
|| args.length > 4 && !getPlugin().isGlowingSupported()) {
return Collections.emptyList();
}
switch (args.length) {
case 2:
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
case 3:
return Utils.getMatches(args[2], Arrays.asList("true", "false"));
case 4:
return Utils.getMatches(args[3], Arrays.asList("true", "false"));
case 5:
return Utils.getMatches(args[4], Arrays.asList("true", "false"));
default:
return Collections.emptyList();
}
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import de.craftlancer.core.util.Tuple;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ImageMapPlaceCommand extends ImageMapSubCommand {
public ImageMapPlaceCommand(ImageMaps plugin) {
super("imagemaps.place", plugin, false);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
boolean isInvisible = false;
boolean isFixed = false;
boolean isGlowing = false;
Tuple<Integer, Integer> scale;
if (getPlugin().isInvisibilitySupported()) {
isInvisible = args.length >= 3 && Boolean.parseBoolean(args[2]);
isFixed = args.length >= 4 && Boolean.parseBoolean(args[3]);
if (getPlugin().isGlowingSupported()) {
isGlowing = args.length >= 5 && Boolean.parseBoolean(args[4]);
scale = args.length >= 6 ? parseScale(args[5]) : new Tuple<>(-1, -1);
}
else {
scale = args.length >= 5 ? parseScale(args[4]) : new Tuple<>(-1, -1);
}
}
else {
scale = args.length >= 3 ? parseScale(args[2]) : new Tuple<>(-1, -1);
}
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
if (!getPlugin().hasImage(filename)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "No image with this name exists.");
return null;
}
Player player = (Player) sender;
player.setMetadata(ImageMaps.PLACEMENT_METADATA,
new FixedMetadataValue(getPlugin(),
new PlacementData(filename, isInvisible, isFixed, isGlowing, scale)));
Tuple<Integer, Integer> size = getPlugin().getImageSize(filename, scale);
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
String.format("Started placing of %s. It needs a %d by %d area.", args[1],
size.getKey(), size.getValue()));
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Right click on the block, that should be the upper left corner.");
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Starts placing an image.");
if (getPlugin().isGlowingSupported()) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO,
"Usage: /imagemap place <filename> [frameInvisible] [frameFixed] [frameGlowing] [size]");
}
else if (getPlugin().isInvisibilitySupported()) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO,
"Usage: /imagemap place <filename> [frameInvisible] [frameFixed] [size]");
}
else {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap place <filename> [size]");
}
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Size format: XxY -> 5x2, use -1 for default");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"The plugin will scale the map to not be larger than the given size while maintaining the aspect ratio.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"It's recommended to avoid the size function in favor of using properly sized source images.");
}
private static Tuple<Integer, Integer> parseScale(String string) {
String[] tmp = string.split("x");
if (tmp.length < 2)
return new Tuple<>(-1, -1);
return new Tuple<>(Utils.parseIntegerOrDefault(tmp[0], -1), Utils.parseIntegerOrDefault(tmp[1], -1));
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length > 2 && !getPlugin().isInvisibilitySupported()
|| args.length > 4 && !getPlugin().isGlowingSupported()) {
return Collections.emptyList();
}
switch (args.length) {
case 2:
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
case 3:
return Utils.getMatches(args[2], Arrays.asList("true", "false"));
case 4:
return Utils.getMatches(args[3], Arrays.asList("true", "false"));
case 5:
return Utils.getMatches(args[4], Arrays.asList("true", "false"));
default:
return Collections.emptyList();
}
}
}

View File

@ -1,61 +1,64 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class ImageMapReloadCommand extends ImageMapSubCommand {
public ImageMapReloadCommand(ImageMaps plugin) {
super("imagemap.reload", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
if (getPlugin().reloadImage(filename))
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Image reloaded.");
else
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Image couldn't be reloaded (does it exist?).");
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Reloads an image from disk, to be used when the file changed.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Avoid resolution changes, since they won't be scaled.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap reload <filename>");
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 2)
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
return Collections.emptyList();
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.Utils;
import de.craftlancer.core.util.MessageLevel;
import de.craftlancer.core.util.MessageUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class ImageMapReloadCommand extends ImageMapSubCommand {
public ImageMapReloadCommand(ImageMaps plugin) {
super("imagemap.reload", plugin, true);
}
@Override
protected String execute(CommandSender sender, Command cmd, String label, String[] args) {
if (!checkSender(sender)) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You can't run this command.");
return null;
}
if (args.length < 2) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "You must specify a file name.");
return null;
}
String filename = args[1];
if (filename.contains("/") || filename.contains("\\") || filename.contains(":")) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.WARNING, "Filename contains illegal character.");
return null;
}
if (getPlugin().reloadImage(filename))
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL, "Image reloaded.");
else
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Image couldn't be reloaded (does it exist?).");
return null;
}
@Override
public void help(CommandSender sender) {
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Reloads an image from disk, to be used when the file changed.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.NORMAL,
"Avoid resolution changes, since they won't be scaled.");
MessageUtil.sendMessage(getPlugin(), sender, MessageLevel.INFO, "Usage: /imagemap reload <filename>");
}
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
if (args.length == 2)
return Utils.getMatches(args[1], new File(plugin.getDataFolder(), "images").list());
return Collections.emptyList();
}
}

View File

@ -1,79 +1,69 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.LambdaRunnable;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
public class ImageMapRenderer extends MapRenderer {
private ImageMaps plugin;
private BufferedImage image = null;
private boolean first = true;
private final int x;
private final int y;
private final double scale;
public ImageMapRenderer(ImageMaps plugin, BufferedImage image, int x, int y, double scale) {
this.plugin = plugin;
this.x = x;
this.y = y;
this.scale = scale;
recalculateInput(image);
}
public void recalculateInput(BufferedImage input) {
if (x * ImageMaps.MAP_WIDTH > Math.round(input.getWidth() * scale) || y * ImageMaps.MAP_HEIGHT > Math.round(input.getHeight() * scale))
return;
int x1 = (int) Math.floor(x * ImageMaps.MAP_WIDTH / scale);
int y1 = (int) Math.floor(y * ImageMaps.MAP_HEIGHT / scale);
int x2 = (int) Math.ceil(Math.min(input.getWidth(), ((x + 1) * ImageMaps.MAP_WIDTH / scale)));
int y2 = (int) Math.ceil(Math.min(input.getHeight(), ((y + 1) * ImageMaps.MAP_HEIGHT / scale)));
if (x2 - x1 <= 0 || y2 - y1 <= 0)
return;
this.image = input.getSubimage(x1, y1, x2 - x1, y2 - y1);
if (scale != 1D) {
BufferedImage resized = new BufferedImage(ImageMaps.MAP_WIDTH, ImageMaps.MAP_HEIGHT, input.getType() == 0 ? image.getType() : input.getType());
AffineTransform at = new AffineTransform();
at.scale(scale, scale);
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
this.image = scaleOp.filter(this.image, resized);
}
first = true;
}
@Override
public void render(MapView view, MapCanvas canvas, Player player) {
if (image != null && first) {
new LambdaRunnable(() -> {
@SuppressWarnings("deprecation")
byte[] imageData = MapPalette.imageToBytes(image);
new LambdaRunnable(() -> {
for (int x2 = 0; x2 < image.getWidth(null); ++x2) {
for (int y2 = 0; y2 < image.getHeight(null); ++y2) {
canvas.setPixel(x2, y2, imageData[y2 * image.getWidth(null) + x2]);
}
}
}).runTaskLater(plugin, System.nanoTime() % 20);
// spread out pseudo randomly in a very naive way
}).runTaskAsynchronously(plugin);
first = false;
}
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.LambdaRunnable;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
public class ImageMapRenderer extends MapRenderer {
private ImageMaps plugin;
private BufferedImage image = null;
private boolean first = true;
private final int x;
private final int y;
private final double scale;
public ImageMapRenderer(ImageMaps plugin, BufferedImage image, int x, int y, double scale) {
this.plugin = plugin;
this.x = x;
this.y = y;
this.scale = scale;
recalculateInput(image);
}
public void recalculateInput(BufferedImage input) {
if (x * ImageMaps.MAP_WIDTH > Math.round(input.getWidth() * scale)
|| y * ImageMaps.MAP_HEIGHT > Math.round(input.getHeight() * scale))
return;
int x1 = (int) Math.floor(x * ImageMaps.MAP_WIDTH / scale);
int y1 = (int) Math.floor(y * ImageMaps.MAP_HEIGHT / scale);
int x2 = (int) Math.ceil(Math.min(input.getWidth(), ((x + 1) * ImageMaps.MAP_WIDTH / scale)));
int y2 = (int) Math.ceil(Math.min(input.getHeight(), ((y + 1) * ImageMaps.MAP_HEIGHT / scale)));
if (x2 - x1 <= 0 || y2 - y1 <= 0)
return;
this.image = input.getSubimage(x1, y1, x2 - x1, y2 - y1);
if (scale != 1D) {
BufferedImage resized = new BufferedImage(ImageMaps.MAP_WIDTH, ImageMaps.MAP_HEIGHT,
input.getType() == 0 ? image.getType() : input.getType());
AffineTransform at = new AffineTransform();
at.scale(scale, scale);
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
this.image = scaleOp.filter(this.image, resized);
}
first = true;
}
@Override
public void render(MapView view, MapCanvas canvas, Player player) {
if (image != null && first) {
new LambdaRunnable(() -> canvas.drawImage(0, 0, image)).runTaskLater(plugin, System.nanoTime() % 60);
// spread out pseudo randomly in a very naive way
first = false;
}
}
}

View File

@ -1,15 +1,15 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.command.SubCommand;
public abstract class ImageMapSubCommand extends SubCommand {
public ImageMapSubCommand(String permission, ImageMaps plugin, boolean console) {
super(permission, plugin, console);
}
@Override
public ImageMaps getPlugin() {
return (ImageMaps) super.getPlugin();
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.command.SubCommand;
public abstract class ImageMapSubCommand extends SubCommand {
public ImageMapSubCommand(String permission, ImageMaps plugin, boolean console) {
super(permission, plugin, console);
}
@Override
public ImageMaps getPlugin() {
return (ImageMaps) super.getPlugin();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +1,118 @@
package net.craftcitizen.imagemaps;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when an image is attempted to be placed.
*/
public class ImagePlaceEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final Player player;
private final Block block;
private final BlockFace widthDirection;
private final BlockFace heightDirection;
private final int width;
private final int height;
private final PlacementData cache;
private boolean cancelled;
public ImagePlaceEvent(Player player, Block block, BlockFace widthDirection, BlockFace heightDirection, int width, int height, PlacementData cache) {
this.player = player;
this.block = block;
this.widthDirection = widthDirection;
this.heightDirection = heightDirection;
this.width = width;
this.height = height;
this.cache = cache;
}
/**
* The player attempting to place the image
*
* @return the player attempting to place the image
*/
public Player getPlayer() {
return player;
}
/**
* The initial block the image is placed against.
*
* @return the initial block the image is placed against
*/
public Block getBlock() {
return block;
}
/**
* The direction in which maps are placed in the height direction of the image.
*
* @return the height direction of the map placement
*/
public BlockFace getHeightDirection() {
return heightDirection;
}
/**
* The direction in which maps are placed in the width direction of the image.
*
* @return the width direction of the map placement
*/
public BlockFace getWidthDirection() {
return widthDirection;
}
/**
* The width of the image in maps
*
* @return the width of the image in maps
*/
public int getWidth() {
return width;
}
/**
* The height of the image in maps
*
* @return the height of the image in maps
*/
public int getHeight() {
return height;
}
/**
* The placement data used to place the image
*
* @return the placement data
*/
public PlacementData getCacheEntry() {
return cache;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
public static HandlerList getHandlerList() {
return handlers;
}
}
package net.craftcitizen.imagemaps;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when an image is attempted to be placed.
*/
public class ImagePlaceEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final Player player;
private final Block block;
private final BlockFace widthDirection;
private final BlockFace heightDirection;
private final int width;
private final int height;
private final PlacementData cache;
private boolean cancelled;
public ImagePlaceEvent(Player player, Block block, BlockFace widthDirection, BlockFace heightDirection, int width,
int height, PlacementData cache) {
this.player = player;
this.block = block;
this.widthDirection = widthDirection;
this.heightDirection = heightDirection;
this.width = width;
this.height = height;
this.cache = cache;
}
/**
* The player attempting to place the image
*
* @return the player attempting to place the image
*/
public Player getPlayer() {
return player;
}
/**
* The initial block the image is placed against.
*
* @return the initial block the image is placed against
*/
public Block getBlock() {
return block;
}
/**
* The direction in which maps are placed in the height direction of the image.
*
* @return the height direction of the map placement
*/
public BlockFace getHeightDirection() {
return heightDirection;
}
/**
* The direction in which maps are placed in the width direction of the image.
*
* @return the width direction of the map placement
*/
public BlockFace getWidthDirection() {
return widthDirection;
}
/**
* The width of the image in maps
*
* @return the width of the image in maps
*/
public int getWidth() {
return width;
}
/**
* The height of the image in maps
*
* @return the height of the image in maps
*/
public int getHeight() {
return height;
}
/**
* The placement data used to place the image
*
* @return the placement data
*/
public PlacementData getCacheEntry() {
return cache;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -1,80 +1,80 @@
package net.craftcitizen.imagemaps;
import de.craftlancer.core.util.Tuple;
/**
* Data associated with placing an image.
*/
public class PlacementData {
private final String filename;
private final boolean isInvisible;
private final boolean isFixed;
private final boolean isGlowing;
private final Tuple<Integer, Integer> scale;
public PlacementData(String filename, boolean isInvisible, boolean isFixed, boolean isGlowing, Tuple<Integer, Integer> scale) {
this.filename = filename;
this.isInvisible = isInvisible;
this.isFixed = isFixed;
this.isGlowing = isGlowing;
this.scale = scale;
}
/**
* The file name of the image to be placed
*
* @return the file name of the image
*/
public String getFilename() {
return filename;
}
/**
* Whether the placed item frame will have the "fixed" property set.
* A fixed frame can't be destroyed or modified by survival players.
* <p>
* Only supported in 1.16 or higher!
*
* @return whether the placed frames will be fixed or not
*/
public boolean isFixed() {
return isFixed;
}
/**
* Whether the placed item frame will have the "invisible" property set.
* An invisible frame won't be rendered, leaving only the item/map visible.
* <p>
* Only supported in 1.16 or higher!
*
* @return whether the placed frames will be invisible or not
*/
public boolean isInvisible() {
return isInvisible;
}
/**
* Whether the placed item frame will be a glowing one.
* <p>
* Only supported in 1.17 or higher!
*
* @return whether the placed frames will be a glowing one
*/
public boolean isGlowing() {
return isGlowing;
}
/**
* The <b>requested</b> size of the image. The actual size might be smaller
* since the plugin won't modify aspect ratios.
* <p>
* Values of -1 stand for the default value of an unscaled map.
*
* @return the requested size of the image
*/
public Tuple<Integer, Integer> getSize() {
return scale;
}
}
package net.craftcitizen.imagemaps;
import de.craftlancer.core.util.Tuple;
/**
* Data associated with placing an image.
*/
public class PlacementData {
private final String filename;
private final boolean isInvisible;
private final boolean isFixed;
private final boolean isGlowing;
private final Tuple<Integer, Integer> scale;
public PlacementData(String filename, boolean isInvisible, boolean isFixed, boolean isGlowing,
Tuple<Integer, Integer> scale) {
this.filename = filename;
this.isInvisible = isInvisible;
this.isFixed = isFixed;
this.isGlowing = isGlowing;
this.scale = scale;
}
/**
* The file name of the image to be placed
*
* @return the file name of the image
*/
public String getFilename() {
return filename;
}
/**
* Whether the placed item frame will have the "fixed" property set. A fixed frame can't be destroyed or modified by
* survival players.
* <p>
* Only supported in 1.16 or higher!
*
* @return whether the placed frames will be fixed or not
*/
public boolean isFixed() {
return isFixed;
}
/**
* Whether the placed item frame will have the "invisible" property set. An invisible frame won't be rendered,
* leaving only the item/map visible.
* <p>
* Only supported in 1.16 or higher!
*
* @return whether the placed frames will be invisible or not
*/
public boolean isInvisible() {
return isInvisible;
}
/**
* Whether the placed item frame will be a glowing one.
* <p>
* Only supported in 1.17 or higher!
*
* @return whether the placed frames will be a glowing one
*/
public boolean isGlowing() {
return isGlowing;
}
/**
* The <b>requested</b> size of the image. The actual size might be smaller since the plugin won't modify aspect
* ratios.
* <p>
* Values of -1 stand for the default value of an unscaled map.
*
* @return the requested size of the image
*/
public Tuple<Integer, Integer> getSize() {
return scale;
}
}

View File

@ -1,11 +1,11 @@
package net.craftcitizen.imagemaps;
public enum PlacementResult {
INVALID_FACING,
EVENT_CANCELLED,
INVALID_DIRECTION,
INSUFFICIENT_WALL,
INSUFFICIENT_SPACE,
SUCCESS,
OVERLAPPING_ENTITY;
}
package net.craftcitizen.imagemaps;
public enum PlacementResult {
INVALID_FACING,
EVENT_CANCELLED,
INVALID_DIRECTION,
INSUFFICIENT_WALL,
INSUFFICIENT_SPACE,
SUCCESS,
OVERLAPPING_ENTITY;
}

View File

@ -1,48 +1,52 @@
main: net.craftcitizen.imagemaps.ImageMaps
author: SydMontague
version: ${project.version}
api-version: 1.13
name: ImageMaps
commands:
imagemap:
description: ImageMaps plugin commands, place images on walls
permission-message: You do not have permission to use this command.
usage: |
/imagemap place <filename> [frameVisible] [frameFixed] [frameGlowing] [size] - starts image placement
/imagemap download <filename> <sourceURL> - downloads an image
/imagemap delete <filename> - deletes an image
/imagemap info <filename> - displays image info
/imagemap reload <filename> - reloads an image from disk
/imagemap list [page] - lists all files in the images folder
/imagemap help [command] - shows help
permissions:
imagemaps.*:
default: op
children:
imagemaps.place: true
imagemaps.download: true
imagemaps.delete: true
imagemaps.info: true
imagemaps.list: true
imagemaps.reload: true
imagemaps.help: true
imagemaps.toggleFixed: true
imagemaps.toggleVisible: true
imagemaps.place:
default: op
imagemaps.download:
default: op
imagemaps.delete:
default: op
imagemaps.info:
default: op
imagemaps.list:
default: op
imagemaps.reload:
default: op
imagemaps.help:
default: op
imagemaps.toggleFixed:
default: op
imagemaps.toggleVisible:
default: op
main: net.craftcitizen.imagemaps.ImageMaps
author: SydMontague
version: ${project.version}
api-version: 1.13
name: ImageMaps
commands:
imagemap:
description: ImageMaps plugin commands, place images on walls
permission-message: You do not have permission to use this command.
usage: |
/imagemap place <filename> [frameVisible] [frameFixed] [frameGlowing] [size] - starts image placement
/imagemap download <filename> <sourceURL> - downloads an image
/imagemap delete <filename> - deletes an image
/imagemap info <filename> - displays image info
/imagemap reload <filename> - reloads an image from disk
/imagemap list [page] - lists all files in the images folder
/imagemap help [command] - shows help
permissions:
imagemaps.*:
default: op
children:
imagemaps.place: true
imagemaps.download: true
imagemaps.delete: true
imagemaps.info: true
imagemaps.list: true
imagemaps.reload: true
imagemaps.help: true
imagemaps.toggleFixed: true
imagemaps.toggleVisible: true
imagemaps.place:
default: op
imagemaps.download:
default: op
imagemaps.delete:
default: op
imagemaps.info:
default: op
imagemaps.list:
default: op
imagemaps.reload:
default: op
imagemaps.help:
default: op
imagemaps.toggleFixed:
default: op
imagemaps.toggleVisible:
default: op
imagemaps.admin:
default: op
children:
imagemaps.*: true