🎉 First commit!
This commit is contained in:
commit
4dc99283f4
42 changed files with 4068 additions and 0 deletions
94
.gitignore
vendored
Normal file
94
.gitignore
vendored
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
### Jetbrains ###
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
.idea/artifacts
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/*.iml
|
||||||
|
.idea/modules
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### Maven ###
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
# Eclipse m2e generated files
|
||||||
|
# Eclipse Core
|
||||||
|
.project
|
||||||
|
# JDT-specific (Eclipse Java Development Tools)
|
||||||
|
.classpath
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
7
.idea/discord.xml
generated
Normal file
7
.idea/discord.xml
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="PROJECT_FILES" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
27
.idea/encodings.xml
generated
Normal file
27
.idea/encodings.xml
generated
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/API/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/API/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/Dist/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/Dist/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_12_R1/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_12_R1/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_13_R2/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_13_R2/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_14_R1/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_14_R1/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_15_R1/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_15_R1/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_16_R3/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_16_R3/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_17_R1/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_17_R1/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_18_R2/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_18_R2/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_19_R1/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/NMS-v1_19_R1/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
22
.idea/misc.xml
generated
Normal file
22
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ComposerSettings">
|
||||||
|
<execution />
|
||||||
|
</component>
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
|
||||||
|
</list>
|
||||||
|
</component>
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="MavenProjectsManager">
|
||||||
|
<option name="originalFiles">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
82
API/pom.xml
Normal file
82
API/pom.xml
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>nexus-snapshots</id>
|
||||||
|
<url>https://repo.sbdevelopment.tech/repository/maven-snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<jdk.version>11</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
|
<version>1.6.13</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-deploy</id>
|
||||||
|
<phase>deploy</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>deploy</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<serverId>nexus-snapshots</serverId>
|
||||||
|
<nexusUrl>https://repo.sbdevelopment.tech/</nexusUrl>
|
||||||
|
<skipStaging>true</skipStaging>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>MG-Dev Jenkins CI Maven Repository</id>
|
||||||
|
<url>https://ci.mg-dev.eu/plugin/repository/everything</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bergerkiller.bukkit</groupId>
|
||||||
|
<artifactId>BKCommonLib</artifactId>
|
||||||
|
<version>1.19-v1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,48 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi;
|
||||||
|
|
||||||
|
import com.bergerkiller.bukkit.common.map.MapColorPalette;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
public class ArrayImage {
|
||||||
|
public byte[] array;
|
||||||
|
public int minX = 0;
|
||||||
|
public int minY = 0;
|
||||||
|
public int maxX = 128;
|
||||||
|
public int maxY = 128;
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private int imageType = BufferedImage.TYPE_4BYTE_ABGR;
|
||||||
|
|
||||||
|
public ArrayImage(byte[] data) {
|
||||||
|
this.array = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a {@link BufferedImage} to an ArrayImage
|
||||||
|
*
|
||||||
|
* @param image image to convert
|
||||||
|
*/
|
||||||
|
public ArrayImage(BufferedImage image) {
|
||||||
|
this.imageType = image.getType();
|
||||||
|
|
||||||
|
this.width = image.getWidth();
|
||||||
|
this.height = image.getHeight();
|
||||||
|
|
||||||
|
BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D graphics = temp.createGraphics();
|
||||||
|
graphics.drawImage(image, 0, 0, null);
|
||||||
|
graphics.dispose();
|
||||||
|
|
||||||
|
int[] pixels = new int[temp.getWidth() * temp.getHeight()];
|
||||||
|
temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth());
|
||||||
|
|
||||||
|
byte[] result = new byte[temp.getWidth() * temp.getHeight()];
|
||||||
|
for (int i = 0; i < pixels.length; i++) {
|
||||||
|
result[i] = MapColorPalette.getColor(new Color(pixels[i], true));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.array = result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi;
|
||||||
|
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
public interface MapController {
|
||||||
|
/**
|
||||||
|
* Add a viewer
|
||||||
|
*
|
||||||
|
* @param player {@link Player} to add
|
||||||
|
*/
|
||||||
|
void addViewer(Player player) throws MapLimitExceededException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a viewer
|
||||||
|
*
|
||||||
|
* @param player {@link OfflinePlayer} to remove
|
||||||
|
*/
|
||||||
|
void removeViewer(OfflinePlayer player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all viewers
|
||||||
|
*/
|
||||||
|
void clearViewers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a player is viewing
|
||||||
|
*
|
||||||
|
* @param player {@link OfflinePlayer} to check
|
||||||
|
* @return <code>true</code> if the player is viewing
|
||||||
|
*/
|
||||||
|
boolean isViewing(OfflinePlayer player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the map ID for a player
|
||||||
|
*
|
||||||
|
* @param player {@link OfflinePlayer} to get the ID for
|
||||||
|
* @return the ID, or <code>-1</code> if no ID exists (i.e. the player is not viewing)
|
||||||
|
*/
|
||||||
|
int getMapId(OfflinePlayer player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the image
|
||||||
|
*
|
||||||
|
* @param content new {@link ArrayImage} content
|
||||||
|
*/
|
||||||
|
void update(ArrayImage content);
|
||||||
|
|
||||||
|
ArrayImage getContent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the content to a player
|
||||||
|
*
|
||||||
|
* @param player {@link Player} receiver of the content
|
||||||
|
*/
|
||||||
|
void sendContent(Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the content to a player
|
||||||
|
*
|
||||||
|
* @param player {@link Player} receiver of the content
|
||||||
|
* @param withoutQueue if <code>true</code>, the content will be sent immediately
|
||||||
|
*/
|
||||||
|
void sendContent(Player player, boolean withoutQueue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in a player's inventory
|
||||||
|
*
|
||||||
|
* @param player {@link Player}
|
||||||
|
* @param slot slot to show the map in
|
||||||
|
* @param force if <code>false</code>, the map will not be shown if the player is in creative mode
|
||||||
|
*/
|
||||||
|
void showInInventory(Player player, int slot, boolean force);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in a player's inventory
|
||||||
|
*
|
||||||
|
* @param player {@link Player}
|
||||||
|
* @param slot slot to show the map in
|
||||||
|
*/
|
||||||
|
void showInInventory(Player player, int slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in a player's hand
|
||||||
|
*
|
||||||
|
* @param player {@link Player}
|
||||||
|
* @param force if <code>false</code>, the map will not be shown if the player is not holding a map, or is in creative mode
|
||||||
|
* @see #showInFrame(Player, ItemFrame, boolean)
|
||||||
|
*/
|
||||||
|
void showInHand(Player player, boolean force);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in a player's hand
|
||||||
|
*
|
||||||
|
* @param player {@link Player}
|
||||||
|
*/
|
||||||
|
void showInHand(Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in an {@link ItemFrame}
|
||||||
|
*
|
||||||
|
* @param player {@link Player} that will be able to see the map
|
||||||
|
* @param frame {@link ItemFrame} to show the map in
|
||||||
|
*/
|
||||||
|
void showInFrame(Player player, ItemFrame frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in an {@link ItemFrame}
|
||||||
|
*
|
||||||
|
* @param player {@link Player} that will be able to see the map
|
||||||
|
* @param frame {@link ItemFrame} to show the map in
|
||||||
|
* @param force if <code>false</code>, the map will not be shown if there is not Map-Item in the ItemFrame
|
||||||
|
*/
|
||||||
|
void showInFrame(Player player, ItemFrame frame, boolean force);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in an {@link ItemFrame}
|
||||||
|
*
|
||||||
|
* @param player {@link Player} that will be able to see the map
|
||||||
|
* @param entityId Entity-ID of the {@link ItemFrame} to show the map in
|
||||||
|
*/
|
||||||
|
void showInFrame(Player player, int entityId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show in an {@link ItemFrame}
|
||||||
|
*
|
||||||
|
* @param player {@link Player} that will be able to see the map
|
||||||
|
* @param entityId Entity-ID of the {@link ItemFrame} to show the map in
|
||||||
|
* @param debugInfo {@link String} to show when a player looks at the map, or <code>null</code>
|
||||||
|
*/
|
||||||
|
void showInFrame(Player player, int entityId, String debugInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear a frame
|
||||||
|
*
|
||||||
|
* @param player {@link Player} that will be able to see the cleared frame
|
||||||
|
* @param entityId Entity-ID of the {@link ItemFrame} to clear
|
||||||
|
*/
|
||||||
|
void clearFrame(Player player, int entityId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear a frame
|
||||||
|
*
|
||||||
|
* @param player {@link Player} that will be able to see the cleared frame
|
||||||
|
* @param frame {@link ItemFrame} to clear
|
||||||
|
*/
|
||||||
|
void clearFrame(Player player, ItemFrame frame);
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
public class MapManager {
|
||||||
|
protected final Set<Integer> OCCUPIED_IDS = new HashSet<>();
|
||||||
|
private final List<MapWrapper> MANAGED_MAPS = new CopyOnWriteArrayList<>();
|
||||||
|
private final Class<?> wrapperClass;
|
||||||
|
|
||||||
|
public MapManager() throws IllegalStateException {
|
||||||
|
String packageName = Bukkit.getServer().getClass().getPackage().getName();
|
||||||
|
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Class<?> clazz = Class.forName("tech.sbdevelopment.mapreflectionapi.nms.MapWrapper_" + version);
|
||||||
|
if (MapWrapper.class.isAssignableFrom(clazz)) {
|
||||||
|
wrapperClass = clazz;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Plugin corrupted! Detected invalid MapWrapper class.");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new IllegalStateException("This Spigot version is not supported! Contact the developer to get support.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public MapWrapper wrapImage(BufferedImage image) {
|
||||||
|
return wrapImage(new ArrayImage(image));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public MapWrapper wrapImage(ArrayImage image) {
|
||||||
|
for (MapWrapper wrapper : MANAGED_MAPS) {
|
||||||
|
if (wrapper.getContent().equals(image)) return wrapper;
|
||||||
|
}
|
||||||
|
return wrapNewImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapWrapper wrapNewImage(ArrayImage image) {
|
||||||
|
try {
|
||||||
|
MapWrapper wrapper = (MapWrapper) wrapperClass.getDeclaredConstructor().newInstance();
|
||||||
|
MANAGED_MAPS.add(wrapper);
|
||||||
|
return wrapper;
|
||||||
|
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
|
||||||
|
InvocationTargetException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unwrapImage(MapWrapper wrapper) {
|
||||||
|
//TODO Cancel IDs
|
||||||
|
|
||||||
|
wrapper.getController().clearViewers();
|
||||||
|
MANAGED_MAPS.remove(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<MapWrapper> getMapsVisibleTo(OfflinePlayer player) {
|
||||||
|
Set<MapWrapper> visible = new HashSet<>();
|
||||||
|
for (MapWrapper wrapper : MANAGED_MAPS) {
|
||||||
|
if (wrapper.getController().isViewing(player)) {
|
||||||
|
visible.add(wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapWrapper getWrapperForId(OfflinePlayer player, int id) {
|
||||||
|
for (MapWrapper wrapper : getMapsVisibleTo(player)) {
|
||||||
|
if (wrapper.getController().getMapId(player) == id) {
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerOccupiedID(int id) {
|
||||||
|
OCCUPIED_IDS.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterOccupiedID(int id) {
|
||||||
|
OCCUPIED_IDS.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Integer> getOccupiedIdsFor(OfflinePlayer player) {
|
||||||
|
Set<Integer> ids = new HashSet<>();
|
||||||
|
for (MapWrapper wrapper : MANAGED_MAPS) {
|
||||||
|
int s = wrapper.getController().getMapId(player);
|
||||||
|
if (s >= 0) {
|
||||||
|
ids.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIdUsedBy(OfflinePlayer player, int id) {
|
||||||
|
return id > 0 && getOccupiedIdsFor(player).contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNextFreeIdFor(Player player) throws MapLimitExceededException {
|
||||||
|
Set<Integer> occupied = getOccupiedIdsFor(player);
|
||||||
|
//Add the 'default' occupied IDs
|
||||||
|
occupied.addAll(OCCUPIED_IDS);
|
||||||
|
|
||||||
|
int largest = 0;
|
||||||
|
for (Integer s : occupied) {
|
||||||
|
if (s > largest) {
|
||||||
|
largest = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Simply increase the maximum id if it's still small enough
|
||||||
|
if (largest + 1 < Integer.MAX_VALUE) {
|
||||||
|
return largest + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Otherwise iterate through all options until there is an unused id
|
||||||
|
for (int s = 0; s < Integer.MAX_VALUE; s++) {
|
||||||
|
if (!occupied.contains(s)) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we end up here, this player has no more free ids. Let's hope nobody uses this many Maps.
|
||||||
|
throw new MapLimitExceededException("'" + player + "' reached the maximum amount of available Map-IDs");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAllMapsFor(OfflinePlayer player) {
|
||||||
|
for (MapWrapper wrapper : getMapsVisibleTo(player)) {
|
||||||
|
wrapper.getController().removeViewer(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapWrapper getDuplicate(ArrayImage image) {
|
||||||
|
for (MapWrapper wrapper : MANAGED_MAPS) {
|
||||||
|
if (image.equals(wrapper.getContent())) {
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class MapReflectionAPI extends JavaPlugin {
|
||||||
|
private static MapReflectionAPI instance;
|
||||||
|
private static MapManager mapManager;
|
||||||
|
|
||||||
|
public static MapReflectionAPI getInstance() {
|
||||||
|
if (instance == null) throw new IllegalStateException("The plugin is not enabled yet!");
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MapManager getMapManager() {
|
||||||
|
if (mapManager == null) throw new IllegalStateException("The plugin is not enabled yet!");
|
||||||
|
return mapManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
instance = this;
|
||||||
|
|
||||||
|
if (!Bukkit.getPluginManager().isPluginEnabled("BKCommonLib")) {
|
||||||
|
getLogger().severe("MapReflectionAPI requires BKCommonLib to function!");
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
mapManager = new MapManager();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLogger().info("MapReflectionAPI is enabled!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi;
|
||||||
|
|
||||||
|
public interface MapWrapper {
|
||||||
|
MapController getController();
|
||||||
|
|
||||||
|
ArrayImage getContent();
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.exceptions;
|
||||||
|
|
||||||
|
public class MapLimitExceededException extends Exception {
|
||||||
|
public MapLimitExceededException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
8
API/src/main/resources/plugin.yml
Normal file
8
API/src/main/resources/plugin.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
name: MapReflectionAPI
|
||||||
|
version: '${project.version}'
|
||||||
|
main: tech.sbdevelopment.mapreflectionapi.MapReflectionAPI
|
||||||
|
api-version: 1.13
|
||||||
|
authors: [ inventivetalent, SBDeveloper ]
|
||||||
|
description: This API helps developer with viewing images on maps.
|
||||||
|
website: https://sbdevelopment.tech
|
||||||
|
softdepend: [ BKCommonLib ]
|
101
Dist/pom.xml
Normal file
101
Dist/pom.xml
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-Dist</artifactId>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<directory>../target</directory>
|
||||||
|
<finalName>${project.parent.name}-${project.version}</finalName>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
|
||||||
|
<!-- Include all the dependencies required by the plugin -->
|
||||||
|
<artifactSet>
|
||||||
|
<includes>
|
||||||
|
<include>tech.sbdevelopment:MapReflectionAPI*</include>
|
||||||
|
</includes>
|
||||||
|
</artifactSet>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_19_R1</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_18_R2</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_16_R3</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_17_R1</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_15_R1</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_14_R1</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_13_R2</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_12_R1</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) inventivetalent / SBDevelopment
|
||||||
|
|
||||||
|
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.
|
54
NMS-v1_12_R1/pom.xml
Normal file
54
NMS-v1_12_R1/pom.xml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_12_R1</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.12.2-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>11</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>craftbukkit</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,116 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_12_R1.PacketPlayOutMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MapSender_v1_12_R1 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //???
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
content.array, //Data
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY //Y size (2nd Y pos)
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class QueuedMap {
|
||||||
|
private final int id;
|
||||||
|
private final ArrayImage image;
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
this.id = id;
|
||||||
|
this.image = image;
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
QueuedMap that = (QueuedMap) obj;
|
||||||
|
return this.id == that.id &&
|
||||||
|
Objects.equals(this.image, that.image) &&
|
||||||
|
Objects.equals(this.player, that.player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id, image, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "QueuedMap[" +
|
||||||
|
"id=" + id + ", " +
|
||||||
|
"image=" + image + ", " +
|
||||||
|
"player=" + player + ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_12_R1.*;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_12_R1 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_12_R1.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_12_R1.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_12_R1.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_12_R1.sendMap(id, MapWrapper_v1_12_R1.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_12_R1.addToQueue(id, MapWrapper_v1_12_R1.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().defaultContainer.windowId;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_12_R1.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
|
||||||
|
if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getTag().setInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.f), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
54
NMS-v1_13_R2/pom.xml
Normal file
54
NMS-v1_13_R2/pom.xml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_13_R2</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.13.2-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>11</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>craftbukkit</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,116 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_13_R2.PacketPlayOutMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MapSender_v1_13_R2 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //???
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
content.array, //Data
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY //Y size (2nd Y pos)
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class QueuedMap {
|
||||||
|
private final int id;
|
||||||
|
private final ArrayImage image;
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
this.id = id;
|
||||||
|
this.image = image;
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (QueuedMap) obj;
|
||||||
|
return this.id == that.id &&
|
||||||
|
Objects.equals(this.image, that.image) &&
|
||||||
|
Objects.equals(this.player, that.player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id, image, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "QueuedMap[" +
|
||||||
|
"id=" + id + ", " +
|
||||||
|
"image=" + image + ", " +
|
||||||
|
"player=" + player + ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_13_R2.*;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_13_R2 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_13_R2.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_13_R2.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_13_R2.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_13_R2.sendMap(id, MapWrapper_v1_13_R2.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_13_R2.addToQueue(id, MapWrapper_v1_13_R2.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().defaultContainer.windowId;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.server.v1_13_R2.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_13_R2.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
|
||||||
|
if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.server.v1_13_R2.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getOrCreateTag().setInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.g), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
54
NMS-v1_14_R1/pom.xml
Normal file
54
NMS-v1_14_R1/pom.xml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_14_R1</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.14.4-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>11</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>craftbukkit</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,117 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_14_R1.PacketPlayOutMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MapSender_v1_14_R1 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //Tracking position
|
||||||
|
false, //Locked
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
content.array, //Data
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY //Y size (2nd Y pos)
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class QueuedMap {
|
||||||
|
private final int id;
|
||||||
|
private final ArrayImage image;
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
this.id = id;
|
||||||
|
this.image = image;
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (QueuedMap) obj;
|
||||||
|
return this.id == that.id &&
|
||||||
|
Objects.equals(this.image, that.image) &&
|
||||||
|
Objects.equals(this.player, that.player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id, image, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "QueuedMap[" +
|
||||||
|
"id=" + id + ", " +
|
||||||
|
"image=" + image + ", " +
|
||||||
|
"player=" + player + ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_14_R1.*;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_14_R1 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_14_R1.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_14_R1.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_14_R1.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_14_R1.sendMap(id, MapWrapper_v1_14_R1.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_14_R1.addToQueue(id, MapWrapper_v1_14_R1.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().defaultContainer.windowId;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.server.v1_14_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_14_R1.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
|
||||||
|
if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.server.v1_14_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getOrCreateTag().setInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.g), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
54
NMS-v1_15_R1/pom.xml
Normal file
54
NMS-v1_15_R1/pom.xml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_15_R1</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.15.2-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>11</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>craftbukkit</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,117 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_15_R1.PacketPlayOutMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MapSender_v1_15_R1 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //Tracking position
|
||||||
|
false, //Locked
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
content.array, //Data
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY //Y size (2nd Y pos)
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class QueuedMap {
|
||||||
|
private final int id;
|
||||||
|
private final ArrayImage image;
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
this.id = id;
|
||||||
|
this.image = image;
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (QueuedMap) obj;
|
||||||
|
return this.id == that.id &&
|
||||||
|
Objects.equals(this.image, that.image) &&
|
||||||
|
Objects.equals(this.player, that.player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id, image, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "QueuedMap[" +
|
||||||
|
"id=" + id + ", " +
|
||||||
|
"image=" + image + ", " +
|
||||||
|
"player=" + player + ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_15_R1.*;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_15_R1 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_15_R1.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_15_R1.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_15_R1.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_15_R1.sendMap(id, MapWrapper_v1_15_R1.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_15_R1.addToQueue(id, MapWrapper_v1_15_R1.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().defaultContainer.windowId;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.server.v1_15_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_15_R1.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
|
||||||
|
if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.server.v1_15_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getOrCreateTag().setInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.g), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
54
NMS-v1_16_R3/pom.xml
Normal file
54
NMS-v1_16_R3/pom.xml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_16_R3</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.16.4-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>11</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>craftbukkit</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,117 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_16_R3.PacketPlayOutMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MapSender_v1_16_R3 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //Tracking position
|
||||||
|
false, //Locked
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
content.array, //Data
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY //Y size (2nd Y pos)
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class QueuedMap {
|
||||||
|
private final int id;
|
||||||
|
private final ArrayImage image;
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
this.id = id;
|
||||||
|
this.image = image;
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (QueuedMap) obj;
|
||||||
|
return this.id == that.id &&
|
||||||
|
Objects.equals(this.image, that.image) &&
|
||||||
|
Objects.equals(this.player, that.player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id, image, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "QueuedMap[" +
|
||||||
|
"id=" + id + ", " +
|
||||||
|
"image=" + image + ", " +
|
||||||
|
"player=" + player + ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_16_R3.*;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_16_R3 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_16_R3.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_16_R3.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_16_R3.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_16_R3.sendMap(id, MapWrapper_v1_16_R3.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_16_R3.addToQueue(id, MapWrapper_v1_16_R3.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().defaultContainer.windowId;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_16_R3.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
|
||||||
|
if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getOrCreateTag().setInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.g), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
98
NMS-v1_17_R1/pom.xml
Normal file
98
NMS-v1_17_R1/pom.xml
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_17_R1</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.17.1-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>16</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>specialsource-maven-plugin</artifactId>
|
||||||
|
<version>1.2.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-obf</id>
|
||||||
|
<configuration>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:${NMSVersion}:txt:maps-mojang</srgIn>
|
||||||
|
<reverse>true</reverse>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:${NMSVersion}:jar:remapped-mojang
|
||||||
|
</remappedDependencies>
|
||||||
|
<remappedArtifactAttached>true</remappedArtifactAttached>
|
||||||
|
<remappedClassifierName>remapped-obf</remappedClassifierName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-spigot</id>
|
||||||
|
<configuration>
|
||||||
|
<inputFile>
|
||||||
|
${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
|
||||||
|
</inputFile>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:${NMSVersion}:csrg:maps-spigot</srgIn>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:${NMSVersion}:jar:remapped-obf
|
||||||
|
</remappedDependencies>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>minecraft-server</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<classifier>remapped-mojang</classifier>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,88 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutMap;
|
||||||
|
import net.minecraft.world.level.saveddata.maps.WorldMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MapSender_v1_17_R1 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
WorldMap.b updateData = new WorldMap.b(
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY, //Y size (2nd Y pos)
|
||||||
|
content.array //Data
|
||||||
|
);
|
||||||
|
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //Show icons
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
updateData
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().connection.send(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
record QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutSetSlot;
|
||||||
|
import net.minecraft.network.syncher.DataWatcher;
|
||||||
|
import net.minecraft.network.syncher.DataWatcherRegistry;
|
||||||
|
import net.minecraft.server.level.EntityPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.decoration.EntityItemFrame;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_17_R1 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_17_R1.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_17_R1.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_17_R1.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_17_R1.sendMap(id, MapWrapper_v1_17_R1.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_17_R1.addToQueue(id, MapWrapper_v1_17_R1.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().inventoryMenu.containerId;
|
||||||
|
int stateId = craftPlayer.getHandle().inventoryMenu.getStateId();
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, stateId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).connection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_17_R1.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
if (entity instanceof ItemFrame) return (ItemFrame) entity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getOrCreateTag().setInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.ITEM_STACK), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).connection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
98
NMS-v1_18_R2/pom.xml
Normal file
98
NMS-v1_18_R2/pom.xml
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_18_R2</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.18.2-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>17</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>specialsource-maven-plugin</artifactId>
|
||||||
|
<version>1.2.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-obf</id>
|
||||||
|
<configuration>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:${NMSVersion}:txt:maps-mojang</srgIn>
|
||||||
|
<reverse>true</reverse>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:${NMSVersion}:jar:remapped-mojang
|
||||||
|
</remappedDependencies>
|
||||||
|
<remappedArtifactAttached>true</remappedArtifactAttached>
|
||||||
|
<remappedClassifierName>remapped-obf</remappedClassifierName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-spigot</id>
|
||||||
|
<configuration>
|
||||||
|
<inputFile>
|
||||||
|
${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
|
||||||
|
</inputFile>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:${NMSVersion}:csrg:maps-spigot</srgIn>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:${NMSVersion}:jar:remapped-obf
|
||||||
|
</remappedDependencies>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>minecraft-server</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<classifier>remapped-mojang</classifier>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,88 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutMap;
|
||||||
|
import net.minecraft.world.level.saveddata.maps.WorldMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MapSender_v1_18_R2 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
WorldMap.b updateData = new WorldMap.b(
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY, //Y size (2nd Y pos)
|
||||||
|
content.array //Data
|
||||||
|
);
|
||||||
|
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //Show icons
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
updateData
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().connection.send(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
record QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutSetSlot;
|
||||||
|
import net.minecraft.network.syncher.DataWatcher;
|
||||||
|
import net.minecraft.network.syncher.DataWatcherRegistry;
|
||||||
|
import net.minecraft.server.level.EntityPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.decoration.EntityItemFrame;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_18_R2 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_18_R2.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_18_R2.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_18_R2.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_18_R2.sendMap(id, MapWrapper_v1_18_R2.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_18_R2.addToQueue(id, MapWrapper_v1_18_R2.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().inventoryMenu.containerId;
|
||||||
|
int stateId = craftPlayer.getHandle().inventoryMenu.getStateId();
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, stateId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_18_R2.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
if (entity instanceof ItemFrame) return (ItemFrame) entity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getOrCreateTag().putInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.defineId(EntityItemFrame.class, DataWatcherRegistry.ITEM_STACK), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).connection.send(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
98
NMS-v1_19_R1/pom.xml
Normal file
98
NMS-v1_19_R1/pom.xml
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>MapReflectionAPI-NMS-v1_19_R1</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<NMSVersion>1.19-R0.1-SNAPSHOT</NMSVersion>
|
||||||
|
<jdk.version>17</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0-SNAPSHOT</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>specialsource-maven-plugin</artifactId>
|
||||||
|
<version>1.2.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-obf</id>
|
||||||
|
<configuration>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:${NMSVersion}:txt:maps-mojang</srgIn>
|
||||||
|
<reverse>true</reverse>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:${NMSVersion}:jar:remapped-mojang
|
||||||
|
</remappedDependencies>
|
||||||
|
<remappedArtifactAttached>true</remappedArtifactAttached>
|
||||||
|
<remappedClassifierName>remapped-obf</remappedClassifierName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-spigot</id>
|
||||||
|
<configuration>
|
||||||
|
<inputFile>
|
||||||
|
${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
|
||||||
|
</inputFile>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:${NMSVersion}:csrg:maps-spigot</srgIn>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:${NMSVersion}:jar:remapped-obf
|
||||||
|
</remappedDependencies>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>minecraft-server</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>${NMSVersion}</version>
|
||||||
|
<classifier>remapped-mojang</classifier>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI-API</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,88 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutMap;
|
||||||
|
import net.minecraft.world.level.saveddata.maps.WorldMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MapSender_v1_19_R1 {
|
||||||
|
private static final List<QueuedMap> sendQueue = new ArrayList<>();
|
||||||
|
private static int senderID = -1;
|
||||||
|
|
||||||
|
public static void addToQueue(final int id, final ArrayImage content, final Player player) {
|
||||||
|
QueuedMap toSend = new QueuedMap(id, content, player);
|
||||||
|
if (sendQueue.contains(toSend)) return;
|
||||||
|
sendQueue.add(toSend);
|
||||||
|
|
||||||
|
runSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSender() {
|
||||||
|
if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
if (sendQueue.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) {
|
||||||
|
QueuedMap current = sendQueue.get(0);
|
||||||
|
if (current == null) return;
|
||||||
|
|
||||||
|
sendMap(current.id, current.image, current.player);
|
||||||
|
|
||||||
|
if (!sendQueue.isEmpty()) sendQueue.remove(0);
|
||||||
|
}
|
||||||
|
}, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMap(final int id0, final ArrayImage content, final Player player) {
|
||||||
|
if (player == null || !player.isOnline()) {
|
||||||
|
List<QueuedMap> toRemove = new ArrayList<>();
|
||||||
|
for (QueuedMap qMap : sendQueue) {
|
||||||
|
if (qMap == null) continue;
|
||||||
|
|
||||||
|
if (qMap.player == null || !qMap.player.isOnline()) {
|
||||||
|
toRemove.add(qMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().cancelTask(senderID);
|
||||||
|
sendQueue.removeAll(toRemove);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = -id0;
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
try {
|
||||||
|
WorldMap.b updateData = new WorldMap.b(
|
||||||
|
content.minX, //X pos
|
||||||
|
content.minY, //Y pos
|
||||||
|
content.maxX, //X size (2nd X pos)
|
||||||
|
content.maxY, //Y size (2nd Y pos)
|
||||||
|
content.array //Data
|
||||||
|
);
|
||||||
|
|
||||||
|
PacketPlayOutMap packet = new PacketPlayOutMap(
|
||||||
|
id, //ID
|
||||||
|
(byte) 0, //Scale
|
||||||
|
false, //Show icons
|
||||||
|
new ArrayList<>(), //Icons
|
||||||
|
updateData
|
||||||
|
);
|
||||||
|
|
||||||
|
((CraftPlayer) player).getHandle().connection.send(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
record QueuedMap(int id, ArrayImage image, Player player) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
package tech.sbdevelopment.mapreflectionapi.nms;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
|
||||||
|
import net.minecraft.network.protocol.game.PacketPlayOutSetSlot;
|
||||||
|
import net.minecraft.network.syncher.DataWatcher;
|
||||||
|
import net.minecraft.network.syncher.DataWatcherRegistry;
|
||||||
|
import net.minecraft.server.level.EntityPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.decoration.EntityItemFrame;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.ArrayImage;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapController;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MapWrapper_v1_19_R1 implements MapWrapper {
|
||||||
|
protected ArrayImage content;
|
||||||
|
|
||||||
|
protected MapController controller = new MapController() {
|
||||||
|
private final Map<UUID, Integer> viewers = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewer(Player player) throws MapLimitExceededException {
|
||||||
|
if (!isViewing(player)) {
|
||||||
|
viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeViewer(OfflinePlayer player) {
|
||||||
|
viewers.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearViewers() {
|
||||||
|
for (UUID uuid : viewers.keySet()) {
|
||||||
|
viewers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewing(OfflinePlayer player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
return viewers.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapId(OfflinePlayer player) {
|
||||||
|
if (isViewing(player)) {
|
||||||
|
return viewers.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ArrayImage content) {
|
||||||
|
MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content);
|
||||||
|
if (duplicate != null) {
|
||||||
|
MapWrapper_v1_19_R1.this.content = duplicate.getContent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWrapper_v1_19_R1.this.content = content;
|
||||||
|
|
||||||
|
for (UUID id : viewers.keySet()) {
|
||||||
|
sendContent(Bukkit.getPlayer(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return MapWrapper_v1_19_R1.this.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player) {
|
||||||
|
sendContent(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContent(Player player, boolean withoutQueue) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
int id = getMapId(player);
|
||||||
|
if (withoutQueue) {
|
||||||
|
MapSender_v1_19_R1.sendMap(id, MapWrapper_v1_19_R1.this.content, player);
|
||||||
|
} else {
|
||||||
|
MapSender_v1_19_R1.addToQueue(id, MapWrapper_v1_19_R1.this.content, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot, boolean force) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
if (player.getGameMode() == GameMode.CREATIVE && !force) return;
|
||||||
|
|
||||||
|
if (slot < 9) {
|
||||||
|
slot += 36;
|
||||||
|
} else if (slot > 35 && slot != 45) {
|
||||||
|
slot = 8 - (slot - 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftPlayer craftPlayer = (CraftPlayer) player;
|
||||||
|
int windowId = craftPlayer.getHandle().inventoryMenu.containerId;
|
||||||
|
int stateId = craftPlayer.getHandle().inventoryMenu.getStateId();
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
|
||||||
|
PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, stateId, slot, nmsStack);
|
||||||
|
((EntityPlayer) player).connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInInventory(Player player, int slot) {
|
||||||
|
showInInventory(player, slot, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player, boolean force) {
|
||||||
|
if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return;
|
||||||
|
showInInventory(player, player.getInventory().getHeldItemSlot(), force);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInHand(Player player) {
|
||||||
|
showInHand(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame) {
|
||||||
|
showInFrame(player, frame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, ItemFrame frame, boolean force) {
|
||||||
|
if (frame.getItem().getType() != Material.MAP && !force) return;
|
||||||
|
showInFrame(player, frame.getEntityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId) {
|
||||||
|
showInFrame(player, entityId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showInFrame(Player player, int entityId, String debugInfo) {
|
||||||
|
if (!isViewing(player)) return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(Material.MAP, 1);
|
||||||
|
if (debugInfo != null) {
|
||||||
|
ItemMeta itemMeta = stack.getItemMeta();
|
||||||
|
itemMeta.setDisplayName(debugInfo);
|
||||||
|
stack.setItemMeta(itemMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> {
|
||||||
|
ItemFrame frame = getItemFrameById(player.getWorld(), entityId);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance());
|
||||||
|
frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_19_R1.this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendItemFramePacket(player, entityId, stack, getMapId(player));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, int entityId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearFrame(Player player, ItemFrame frame) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
if (entity instanceof ItemFrame) return (ItemFrame) entity;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) {
|
||||||
|
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||||
|
nmsStack.getOrCreateTag().putInt("map", mapId);
|
||||||
|
|
||||||
|
DataWatcher watcher = new DataWatcher(null);
|
||||||
|
watcher.set(DataWatcher.defineId(EntityItemFrame.class, DataWatcherRegistry.ITEM_STACK), nmsStack);
|
||||||
|
|
||||||
|
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, watcher, true);
|
||||||
|
((EntityPlayer) player).connection.send(packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayImage getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
12
README.md
Normal file
12
README.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# MapReflectionAPI
|
||||||
|
|
||||||
|
This API helps developer with viewing images on maps. It supports Spigot 1.12 - 1.19.
|
||||||
|
|
||||||
|
## Dependencies:
|
||||||
|
|
||||||
|
- [BKCommonLib](https://www.spigotmc.org/resources/bkcommonlib.39590/)
|
||||||
|
|
||||||
|
## Credits:
|
||||||
|
|
||||||
|
The source is based on [MapManager](https://github.com/InventivetalentDev/MapManager). It removes the PacketListenerAPI
|
||||||
|
dependency and uses NMS with submodules instead of reflection to make the code easier to edit.
|
88
pom.xml
Normal file
88
pom.xml
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
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>tech.sbdevelopment</groupId>
|
||||||
|
<artifactId>MapReflectionAPI</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<version>${revision}</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<revision>1.0-SNAPSHOT</revision>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<jdk.version>11</jdk.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>API</module>
|
||||||
|
<module>Dist</module>
|
||||||
|
<module>NMS-v1_19_R1</module>
|
||||||
|
<module>NMS-v1_18_R2</module>
|
||||||
|
<module>NMS-v1_17_R1</module>
|
||||||
|
<module>NMS-v1_16_R3</module>
|
||||||
|
<module>NMS-v1_15_R1</module>
|
||||||
|
<module>NMS-v1_14_R1</module>
|
||||||
|
<module>NMS-v1_13_R2</module>
|
||||||
|
<module>NMS-v1_12_R1</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<defaultGoal>clean package</defaultGoal>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-toolchains-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>toolchain</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<toolchains>
|
||||||
|
<jdk>
|
||||||
|
<version>${jdk.version}</version>
|
||||||
|
</jdk>
|
||||||
|
</toolchains>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.10.1</version>
|
||||||
|
<configuration>
|
||||||
|
<release>${jdk.version}</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M2</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spigot-repo</id>
|
||||||
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
<version>1.19-R0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
Loading…
Add table
Reference in a new issue