Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2fb3933
Update dependencies
Flowsqy Dec 23, 2021
ad07fb8
Update dependencies
Flowsqy Dec 25, 2021
ea6c6ea
Add missing provided scope for areashop dependency
Flowsqy Dec 25, 2021
d4dd282
Clean AreaShop repository url
Flowsqy Dec 25, 2021
f2a96f1
Set version to 1.14.0-SNAPSHOT
Flowsqy Dec 25, 2021
a77926b
Move plugin src directory into a sub module
Flowsqy Dec 27, 2021
51bee2d
Move plugin src directory to a sub module
Flowsqy Dec 27, 2021
2294cce
Install project library in maven local repository
Flowsqy Dec 27, 2021
9962be1
Set management and real pom section
Flowsqy Dec 27, 2021
d8c30a2
Change to relative path for target folders
Flowsqy Dec 27, 2021
fee706f
Remove warnings for overlapping META-INF/ files
Flowsqy Dec 27, 2021
be5d1dc
Fix plugin artifact id and remove redundant comments
Flowsqy Dec 27, 2021
80e27a5
Add nms structure
Flowsqy Dec 27, 2021
46257d2
Add implementation for data watcher dedicated to hologram
Flowsqy Dec 27, 2021
5123409
End hologram name implementation
Flowsqy Dec 28, 2021
d3079f6
Add #setLocation implementation
Flowsqy Dec 28, 2021
c054e6c
Add #spawn and #remove implementation
Flowsqy Dec 28, 2021
41a5206
Add reflection module for backward compatibility
Flowsqy Dec 28, 2021
2fda9bb
Add little more details in README.md in the build section
Flowsqy Dec 28, 2021
a7bc054
Change FakeArmorStand structure to implement FakeItem
Flowsqy Dec 29, 2021
320eb06
Remove "cd .." in install_local_dependencies.sh to be coherent with R…
Flowsqy Dec 29, 2021
1c48ae1
Add default version for nms implementation (Must be overridden)
Flowsqy Dec 29, 2021
730e10c
Set interface dependency to provided scope in nms submodules
Flowsqy Dec 29, 2021
5efdb35
Add exclusion for transitive system dependencies
Flowsqy Dec 29, 2021
b256015
Add #setAccessible call to access to private fields
Flowsqy Dec 29, 2021
b37ae0f
Add marker flag to the fake armorstand
Flowsqy Dec 29, 2021
278b446
Add FakeItem implementation
Flowsqy Dec 29, 2021
fe27bd5
Add reflection implementation structure
Flowsqy Dec 29, 2021
5f0b25c
Add implementation for FakeArmorStand in reflection
Flowsqy Dec 29, 2021
4ada3fb
Fix javadoc
Flowsqy Dec 29, 2021
7410f20
Add FakeItem implementation in reflection
Flowsqy Dec 29, 2021
b46bd95
Link plugin to nms sub modules
Flowsqy Dec 29, 2021
f4499b4
Remove useless method in Utils
Flowsqy Dec 29, 2021
15c39d6
Add 1.17.1 implementation
Flowsqy Dec 29, 2021
551b50b
Use chat-api and remove useless nms in plugin
Flowsqy Dec 29, 2021
d4cddca
Fix format breaking with replacement in /shop info
Flowsqy Dec 30, 2021
8b0bd54
Fix item preview in version >= 1.17
Flowsqy Dec 30, 2021
c74a4e5
Add missing return statement to stop the initialization of the plugin…
Flowsqy Dec 30, 2021
bc16a6b
Add 1.18 implementation
Flowsqy Dec 30, 2021
9e1f715
Change javadoc goal to aggregate-jar
Flowsqy Dec 30, 2021
59152bb
Fix javadoc
Flowsqy Dec 30, 2021
c58f39c
Handle error properly
Flowsqy Dec 30, 2021
dea7867
Update to spigot dependency to version 1.18.1
Flowsqy Dec 30, 2021
fd3b3b3
Fix platform loading for 1.17.1
Flowsqy Jan 1, 2022
5c001ae
Bump PlotSquared v6 to version 6.5.0
Flowsqy Feb 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/bin/
/target/
target/

/.idea/
*.iml
Expand Down
12 changes: 12 additions & 0 deletions .mvn/local-settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd">
<mirrors>
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>dummy</mirrorOf>
<name>Dummy mirror to override default blocking mirror that blocks http</name>
<url>http://0.0.0.0/</url>
</mirror>
</mirrors>
</settings>
1 change: 1 addition & 0 deletions .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--settings ./.mvn/local-settings.xml
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ To use the API, you need to add the following repository and dependency in your
You can find the javadoc here: https://epicericee.github.io/ShopChest/javadoc/

## Build
Clone this repository and use ``mvn clean package`` or ``mvn clean install``.
After the build succeeded, the ShopChest.jar is found in the ``/target/`` folder.
Clone this repository and use ``sh lib/install_local_depedencies.sh`` to import local dependencies.
After importation, use ``mvn clean package`` or ``mvn clean install`` to build the project.
After the build succeeded, the ShopChest.jar is found in the ``/plugin/target/`` folder.

## Issues
If you find any issues, please provide them in the [Issues Section](https://github.com/EpicEricEE/ShopChest/issues) with a good description of how to reproduce it. If you get any error messages in the console, please also provide them.
Expand Down
1 change: 1 addition & 0 deletions lib/install_local_dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mvn -N install:install-file -Dfile=lib/IslandWorld-8.5.jar -DgroupId=pl.gnacik.islandworld -DartifactId=IslandWorld -Dversion=8.5 -Dpackaging=jar -DgeneratePom=true
23 changes: 23 additions & 0 deletions nms/interface/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ShopChest-parent</artifactId>
<groupId>de.epiceric</groupId>
<version>1.14.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>shopchest-nms-interface</artifactId>
<version>1.0.0</version>

<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package de.epiceric.shopchest.nms;

import org.bukkit.Location;
import org.bukkit.entity.Player;

public interface FakeArmorStand extends FakeEntity {

void sendData(String name, Iterable<Player> receivers);

void setLocation(Location location, Iterable<Player> receivers);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package de.epiceric.shopchest.nms;

import org.bukkit.Location;
import org.bukkit.entity.Player;

import java.util.UUID;

public interface FakeEntity {

int getEntityId();

void spawn(UUID uuid, Location location, Iterable<Player> receivers);

void remove(Iterable<Player> receivers);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package de.epiceric.shopchest.nms;

import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

public interface FakeItem extends FakeEntity{

void sendData(ItemStack item, Iterable<Player> receivers);

void resetVelocity(Iterable<Player> receivers);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package de.epiceric.shopchest.nms;

public interface Platform {

FakeArmorStand createFakeArmorStand();

FakeItem createFakeItem();

TextComponentHelper getTextComponentHelper();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package de.epiceric.shopchest.nms;

import net.md_5.bungee.api.chat.*;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.Text;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public interface TextComponentHelper {

default void sendUpdateMessage(Player player, String updateMessage, String hoverMessage, String downloadUrl){
final TextComponent component = new TextComponent();
component.setExtra(Arrays.asList(TextComponent.fromLegacyText(updateMessage)));
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hoverMessage)));
component.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, downloadUrl));
player.spigot().sendMessage(component);
}

/**
* Get the 'tag' json object containing the item's data
* @param itemStack The item stack that will be displayed
* @return A string representing a json object of the 'tag'
*/
String getNbt(ItemStack itemStack);

default Consumer<Player> getSendableItemInfo(String message, String itemPlaceHolder, ItemStack itemStack, String productName){
final TextComponent baseComponent = new TextComponent();
final TextComponent replacement = new TextComponent(productName);
replacement.setHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_ITEM,
new Item(
itemStack.getType().getKey().toString(),
1,
ItemTag.ofNbt(getNbt(itemStack))
)
));
final List<BaseComponent> extras = new ArrayList<>();
final Matcher matcher = Pattern.compile(itemPlaceHolder, Pattern.LITERAL).matcher(message);
if (matcher.find()) {
int cursor = 0;
do {
final String pre = message.substring(cursor, matcher.start());
if (!pre.isEmpty()) {
extras.addAll(Arrays.asList(TextComponent.fromLegacyText(pre)));
}
extras.add(copyPreviousFormatting(extras, replacement));
cursor = matcher.end();
} while (matcher.find());
final String end = message.substring(cursor);
if (!end.isEmpty()) {
TextComponent endBaseComponent = new TextComponent();
endBaseComponent = copyPreviousFormatting(extras, endBaseComponent);
endBaseComponent.setExtra(Arrays.asList(TextComponent.fromLegacyText(end)));
extras.add(endBaseComponent);
}
}
else {
extras.addAll(Arrays.asList(TextComponent.fromLegacyText(message)));
}
baseComponent.setExtra(extras);

return player -> player.spigot().sendMessage(baseComponent);
}

static TextComponent copyPreviousFormatting(List<BaseComponent> extras, TextComponent replacement){
TextComponent formattedReplacement = replacement;
if(!extras.isEmpty()) {
formattedReplacement = replacement.duplicate();
final BaseComponent previousComponent = extras.get(extras.size() - 1);
// Check parent also (not done in copyFormatting)
if (formattedReplacement.getColorRaw() == null) {
formattedReplacement.setColor(previousComponent.getColor());
}
if (formattedReplacement.getFontRaw() == null) {
formattedReplacement.setFont(previousComponent.getFont());
}
if (formattedReplacement.isBoldRaw() == null) {
formattedReplacement.setBold(previousComponent.isBold());
}
if (formattedReplacement.isItalicRaw() == null) {
formattedReplacement.setItalic(previousComponent.isItalic());
}
if (formattedReplacement.isUnderlinedRaw() == null) {
formattedReplacement.setUnderlined(previousComponent.isUnderlined());
}
if (formattedReplacement.isStrikethroughRaw() == null) {
formattedReplacement.setStrikethrough(previousComponent.isStrikethrough());
}
if (formattedReplacement.isObfuscatedRaw() == null) {
formattedReplacement.setObfuscated(previousComponent.isObfuscated());
}
if (formattedReplacement.getInsertion() == null) {
formattedReplacement.setInsertion(previousComponent.getInsertion());
}
}
return formattedReplacement;
}

}
33 changes: 33 additions & 0 deletions nms/reflection/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ShopChest-parent</artifactId>
<groupId>de.epiceric</groupId>
<version>1.14.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>shopchest-nms-reflection</artifactId>
<version>1.0.0</version>

<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
</dependency>
<dependency>
<groupId>de.epiceric</groupId>
<artifactId>shopchest-nms-interface</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.inventivetalent</groupId>
<artifactId>reflectionhelper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package de.epiceric.shopchest.nms.reflection;

import de.epiceric.shopchest.nms.FakeArmorStand;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;

import java.lang.reflect.Field;
import java.util.UUID;

public class FakeArmorStandImpl extends FakeEntityImpl implements FakeArmorStand {

private final Class<?> packetPlayOutEntityTeleportClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityTeleport");

public FakeArmorStandImpl(ShopChestDebug debug) {
super(debug);
}

@Override
public void sendData(String name, Iterable<Player> receivers) {
Object dataWatcher = ReflectionUtils.createDataWatcher(debug, name, null);
try {
for (Player receiver : receivers) {
ReflectionUtils.sendPacket(debug, packetPlayOutEntityMetadataClass.getConstructor(int.class, dataWatcherClass, boolean.class)
.newInstance(entityId, dataWatcher, true), receiver);
}
} catch (ReflectiveOperationException e) {
debug.getLogger().severe("Could not set hologram data");
debug.debug("Could not set armor stand data");
debug.debug(e);
}
}

@Override
public void setLocation(Location location, Iterable<Player> receivers) {
double y = location.getY() + (ReflectionUtils.getServerVersion().equals("v1_8_R1") ? 0 : 1.975);
try {
Object packet = packetPlayOutEntityTeleportClass.getConstructor().newInstance();
Field[] fields = packetPlayOutEntityTeleportClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
}

boolean isPre9 = ReflectionUtils.getMajorVersion() < 9;
fields[0].set(packet, entityId);

if (isPre9) {
fields[1].set(packet, (int)(location.getX() * 32));
fields[2].set(packet, (int)(y * 32));
fields[3].set(packet, (int)(location.getZ() * 32));
} else {
fields[1].set(packet, location.getX());
fields[2].set(packet, y);
fields[3].set(packet, location.getZ());
}
fields[4].set(packet, (byte) 0);
fields[5].set(packet, (byte) 0);
fields[6].set(packet, true);

if (packet == null) {
debug.getLogger().severe("Could not set hologram location");
debug.debug("Could not set armor stand location: Packet is null");
return;
}

for (Player receiver : receivers) {
ReflectionUtils.sendPacket(debug, packet, receiver);
}
}catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}

@Override
public void spawn(UUID uuid, Location location, Iterable<Player> receivers) {
for(Player receiver : receivers) {
ReflectionUtils.sendPacket(debug, ReflectionUtils.createPacketSpawnEntity(debug, entityId, uuid, location, EntityType.ARMOR_STAND), receiver);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package de.epiceric.shopchest.nms.reflection;

import de.epiceric.shopchest.nms.FakeEntity;
import org.bukkit.entity.Player;
import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver;

public abstract class FakeEntityImpl implements FakeEntity {

protected final NMSClassResolver nmsClassResolver = new NMSClassResolver();
protected final Class<?> packetPlayOutEntityDestroyClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityDestroy");
protected final Class<?> packetPlayOutEntityMetadataClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityMetadata");
protected final Class<?> dataWatcherClass = nmsClassResolver.resolveSilent("network.syncher.DataWatcher");

protected final int entityId;
protected final ShopChestDebug debug;

public FakeEntityImpl(ShopChestDebug debug) {
this.entityId = ReflectionUtils.getFreeEntityId();
this.debug = debug;
}

@Override
public int getEntityId() {
return entityId;
}

@Override
public void remove(Iterable<Player> receivers) {
try {
for(Player receiver : receivers) {
ReflectionUtils.sendPacket(debug, packetPlayOutEntityDestroyClass.getConstructor(int[].class).newInstance((Object) new int[]{entityId}), receiver);
}
} catch (ReflectiveOperationException e){
debug.getLogger().severe("Could not remove hologram");
debug.debug("Could not remove hologram");
debug.debug(e);
}
}
}
Loading