add 1.15 anvils, add close method for Gui

This commit is contained in:
jascotty2 2020-02-02 15:10:37 -06:00
parent 39f119cdeb
commit 9e7b513288
9 changed files with 328 additions and 0 deletions

View File

@ -182,6 +182,13 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_15_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- End NMS -->
<!-- Start Plugin Hooks -->
<dependency>

View File

@ -16,6 +16,8 @@ public class MySQLConnector implements DatabaseConnector {
public MySQLConnector(Plugin plugin, String hostname, int port, String database, String username, String password, boolean useSSL) {
this.plugin = plugin;
System.out.println("connecting to " + hostname + " : " + port + " with " + password);
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://" + hostname + ":" + port + "/" + database + "?useSSL=" + useSSL);
config.setUsername(username);

View File

@ -156,6 +156,18 @@ public class Gui {
.forEach(Player::closeInventory);
}
/**
* Close the GUI as if the player closed it normally
*/
public void close() {
allowClose = true;
inventory.getViewers().stream()
.filter(e -> e instanceof Player)
.map(e -> (Player) e)
.collect(Collectors.toList())
.forEach(Player::closeInventory);
}
@NotNull
public GuiType getType() {
return inventoryType;

View File

@ -40,6 +40,8 @@ public class NmsManager {
return new com.songoda.core.nms.v1_13_R2.NMS();
case "v1_14_R1":
return new com.songoda.core.nms.v1_14_R1.NMS();
case "v1_15_R1":
return new com.songoda.core.nms.v1_15_R1.NMS();
}
Logger.getLogger(NmsManager.class.getName()).log(Level.SEVERE, "Failed to load NMS for this server version: version {0} not found", serverPackageVersion);
return null;

29
NMS/NMS-v1_15_R1/pom.xml Normal file
View File

@ -0,0 +1,29 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<parent>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore-Modules</artifactId>
<version>maven-version-number</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>SongodaCore-NMS-v1_15_R1</artifactId>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.destroystokyo.papermc</groupId>
<artifactId>paper</artifactId>
<version>1.15.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore-NMS-API</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.songoda.core.nms.v1_15_R1;
import net.minecraft.server.v1_15_R1.ContainerAnvil;
import net.minecraft.server.v1_15_R1.IInventory;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryAnvil;
import org.bukkit.inventory.InventoryHolder;
public class AnvilInventoryCustom extends CraftInventoryAnvil {
final InventoryHolder holder;
public AnvilInventoryCustom(InventoryHolder holder, Location location, IInventory inventory, IInventory resultInventory, ContainerAnvil container) {
super(location, inventory, resultInventory, container);
this.holder = holder;
}
@Override
public InventoryHolder getHolder() {
return holder;
}
}

View File

@ -0,0 +1,229 @@
package com.songoda.core.nms.v1_15_R1;
import com.songoda.core.nms.CustomAnvil;
import com.songoda.core.nms.methods.AnvilTextChange;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.server.v1_15_R1.BlockPosition;
import net.minecraft.server.v1_15_R1.ChatMessage;
import net.minecraft.server.v1_15_R1.Container;
import net.minecraft.server.v1_15_R1.ContainerAccess;
import net.minecraft.server.v1_15_R1.ContainerAnvil;
import net.minecraft.server.v1_15_R1.Containers;
import net.minecraft.server.v1_15_R1.EntityHuman;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.IInventory;
import net.minecraft.server.v1_15_R1.PacketPlayOutOpenWindow;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
public class AnvilView extends ContainerAnvil implements CustomAnvil {
private final EntityPlayer entity;
private final Inventory inventory;
private String customTitle = "Repairing";
private int cost = -1;
private boolean canUse = true;
private AnvilTextChange textChange = null;
// used for setting custom inventory
static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result
static Field mc_ContainerAnvil_resultInventory; // full inventory
static Field mc_ContainerAnvil_bukkitEntity;
static {
try {
mc_ContainerAnvil_repairInventory = ContainerAnvil.class.getDeclaredField("repairInventory");
mc_ContainerAnvil_repairInventory.setAccessible(true);
mc_ContainerAnvil_resultInventory = ContainerAnvil.class.getDeclaredField("resultInventory");
mc_ContainerAnvil_resultInventory.setAccessible(true);
mc_ContainerAnvil_bukkitEntity = ContainerAnvil.class.getDeclaredField("bukkitEntity");
mc_ContainerAnvil_bukkitEntity.setAccessible(true);
} catch (Exception ex) {
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Setup Error", ex);
}
}
static Method mc_ContainerProperty_set;
static Method mc_ContainerProperty_get;
// 1.15 made this field public again, but now it's final. idk.
static Field mc_Container_windowId;
// 1.14 also introduced a title field, also private, which can only be set once and can't be checked
static Field mc_Container_title;
static {
try {
mc_Container_title = Container.class.getDeclaredField("title");
mc_Container_title.setAccessible(true);
mc_Container_windowId = Container.class.getDeclaredField("windowId");
mc_Container_windowId.setAccessible(true);
// remove the final modifier
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(mc_Container_windowId, mc_Container_windowId.getModifiers() & ~Modifier.FINAL);
} catch (Exception ex) {
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Setup Error", ex);
}
}
public AnvilView(int id, EntityPlayer entity, InventoryHolder holder) {
super(id, entity.inventory, ContainerAccess.at(entity.world, new BlockPosition(0, 0, 0)));
this.setTitle(new ChatMessage(customTitle != null ? customTitle : ""));
this.checkReachable = false;
this.entity = entity;
if(holder != null) {
this.inventory = getBukkitView(entity, holder).getTopInventory();
} else {
this.inventory = getBukkitView().getTopInventory();
}
}
public CraftInventoryView getBukkitView(EntityHuman player, InventoryHolder holder) {
try {
AnvilInventoryCustom craftInventory = new AnvilInventoryCustom(holder,
new Location(entity.world.getWorld(), 0, 0, 0),
(IInventory) mc_ContainerAnvil_repairInventory.get(this),
(IInventory) mc_ContainerAnvil_resultInventory.get(this), this);
CraftInventoryView view = new CraftInventoryView(player.getBukkitEntity(), craftInventory, this);
mc_ContainerAnvil_bukkitEntity.set(this, view);
return view;
} catch (Exception ex) {
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Setup Error", ex);
}
return getBukkitView();
}
@Override
public boolean canUse(EntityHuman entityhuman) {
return canUse;
}
@Override
public void e() {
super.e();
if (cost >= 0) {
this.levelCost.set(cost);
}
textChange.onChange();
}
@Override
public void update() {
e();
}
@Override
public String getRenameText() {
return this.renameText;
}
@Override
public void setRenameText(String text) {
this.a(text);
}
@Override
public void setOnChange(AnvilTextChange handler) {
textChange = handler;
}
@Override
public String getCustomTitle() {
return customTitle;
}
@Override
public void setCustomTitle(String title) {
this.customTitle = title;
try {
mc_Container_title.set(this, new ChatMessage(customTitle != null ? customTitle : ""));
} catch (Exception ex) {
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Error", ex);
}
}
@Override
public void setLevelCost(int cost) {
this.cost = cost;
}
@Override
public int getLevelCost() {
if (cost >= 0) {
return cost;
} else {
return this.levelCost.get();
}
}
@Override
public void setCanUse(boolean bool) {
this.canUse = bool;
}
@Override
public ItemStack getLeftInput() {
return inventory.getItem(0);
}
@Override
public ItemStack getRightInput() {
return inventory.getItem(1);
}
@Override
public ItemStack getOutput() {
return inventory.getItem(2);
}
@Override
public void setLeftInput(ItemStack item) {
inventory.setItem(0, item);
}
@Override
public void setRightInput(ItemStack item) {
inventory.setItem(1, item);
}
@Override
public void setOutput(ItemStack item) {
inventory.setItem(2, item);
}
@Override
public Inventory getInventory() {
return inventory;
}
@Override
public void open() {
// Counter stuff that the game uses to keep track of inventories
int id = entity.nextContainerCounter();
// Send the packet
entity.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.ANVIL, new ChatMessage(customTitle != null ? customTitle : "")));
// Set their active container to this anvil
entity.activeContainer = this;
try {
// Set their active container window id to that counter stuff
mc_Container_windowId.set(this, id);
} catch (Exception ex) {
Logger.getLogger(AnvilView.class.getName()).log(Level.SEVERE, "Anvil Create Error", ex);
}
// Add the slot listener
entity.activeContainer.addSlotListener(entity);
}
}

View File

@ -0,0 +1,24 @@
package com.songoda.core.nms.v1_15_R1;
import com.songoda.core.nms.CoreNMS;
import com.songoda.core.nms.CustomAnvil;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryHolder;
public class NMS implements CoreNMS {
@Override
public CustomAnvil createAnvil(Player player) {
EntityPlayer p = ((CraftPlayer) player).getHandle();
return new AnvilView(p.nextContainerCounter(), p, null);
}
@Override
public CustomAnvil createAnvil(Player player, InventoryHolder holder) {
EntityPlayer p = ((CraftPlayer) player).getHandle();
return new AnvilView(p.nextContainerCounter(), p, holder);
}
}

View File

@ -20,6 +20,7 @@
<module>NMS/NMS-v1_13_R1</module>
<module>NMS/NMS-v1_13_R2</module>
<module>NMS/NMS-v1_14_R1</module>
<module>NMS/NMS-v1_15_R1</module>
</modules>
<build>