Skip to content

Commit

Permalink
initial experimental inventory retaining system
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Oct 30, 2019
1 parent 4141e05 commit 1a6a767
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 8 deletions.
2 changes: 2 additions & 0 deletions plugin/src/main/java/com/denizenscript/denizen/Denizen.java
Expand Up @@ -5,6 +5,7 @@
import com.denizenscript.denizen.events.core.*;
import com.denizenscript.denizen.flags.FlagManager;
import com.denizenscript.denizen.objects.EntityTag;
import com.denizenscript.denizen.objects.InventoryTag;
import com.denizenscript.denizen.objects.NPCTag;
import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizen.objects.notable.NotableManager;
Expand Down Expand Up @@ -451,6 +452,7 @@ public void run() {
DenizenCore.tick(50); // Sadly, minecraft has no delta timing, so a tick is always 50ms.
}
}, 1, 1);
InventoryTag.setupInventoryTracker();
}
catch (Exception e) {
Debug.echoError(e);
Expand Down
Expand Up @@ -2,6 +2,7 @@

import com.denizenscript.denizen.scripts.containers.core.InventoryScriptContainer;
import com.denizenscript.denizen.scripts.containers.core.InventoryScriptHelper;
import com.denizenscript.denizen.utilities.DenizenAPI;
import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizen.utilities.depends.Depends;
Expand Down Expand Up @@ -32,6 +33,11 @@
import org.bukkit.block.DoubleChest;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.*;
import org.bukkit.inventory.meta.BookMeta;
Expand Down Expand Up @@ -68,19 +74,111 @@ public class InventoryTag implements ObjectTag, Notable, Adjustable {
//
// -->

public static class InventoryTrackerSystem implements Listener {

public static HashMap<Long, InventoryTag> idTrackedInventories = new HashMap<>(512);

public static long temporaryInventoryIdCounter = 0;

public static HashMap<Inventory, InventoryTag> temporaryInventoryLinks = new HashMap<>(512);

public static HashMap<Inventory, InventoryTag> retainedInventoryLinks = new HashMap<>(512);

public static InventoryTag getTagFormFor(Inventory inventory) {
if (inventory == null) {
return null;
}
InventoryTag result = temporaryInventoryLinks.get(inventory);
if (result != null) {
return result;
}
return retainedInventoryLinks.get(inventory);
}

@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerOpensInventory(InventoryOpenEvent event) {
if (event.isCancelled()) {
return;
}
InventoryTag tagForm = getTagFormFor(event.getInventory());
if (tagForm != null && tagForm.getIdType() != null && tagForm.getIdType().equalsIgnoreCase("generic")) {
retainedInventoryLinks.put(event.getInventory(), tagForm);
}
}

@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerCloseInventory(InventoryCloseEvent event) {
Inventory inv = event.getInventory();
Bukkit.getScheduler().scheduleSyncDelayedTask(DenizenAPI.getCurrentInstance(), new Runnable() {
@Override
public void run() {
if (inv.getViewers().isEmpty()) {
InventoryTag removed = retainedInventoryLinks.remove(inv);
if (removed != null && removed.uniquifier != null) {
idTrackedInventories.remove(removed.uniquifier);
temporaryInventoryLinks.put(inv, removed);
}
}
}
}, 1);
}

public static void trackTemporaryInventory(Inventory inventory, InventoryTag tagForm) {
if (inventory == null || tagForm == null) {
return;
}
String title = NMSHandler.getInstance().getTitle(inventory);
if (InventoryScriptHelper.notableInventories.containsKey(title)) {
return;
}
if (tagForm.getIdType() != null && tagForm.getIdType().equalsIgnoreCase("generic")) {
if (tagForm.uniquifier == null) {
tagForm.uniquifier = temporaryInventoryIdCounter++;
}
if (!idTrackedInventories.containsKey(tagForm.uniquifier)) {
idTrackedInventories.put(tagForm.uniquifier, tagForm);
}
}
temporaryInventoryLinks.put(inventory, tagForm);
}

public static void setup() {
Bukkit.getScheduler().scheduleSyncRepeatingTask(DenizenAPI.getCurrentInstance(), new Runnable() {
@Override
public void run() {
InventoryTrackerSystem.temporaryInventoryLinks.clear();
}
}, 20, 20);
Bukkit.getPluginManager().registerEvents(new InventoryTrackerSystem(), DenizenAPI.getCurrentInstance());
}
}

public static void trackTemporaryInventory(InventoryTag tagForm) {
InventoryTrackerSystem.trackTemporaryInventory(tagForm.inventory, tagForm);
}

public static void setupInventoryTracker() {
InventoryTrackerSystem.setup();
}

public static InventoryTag mirrorBukkitInventory(Inventory inventory) {
if (inventory == null) {
return null;
}
InventoryTag result = InventoryTrackerSystem.getTagFormFor(inventory);
if (result != null) {
return result;
}
// Scripts have priority over notables
if (InventoryScriptHelper.tempInventoryScripts.containsKey(inventory)) {
return new InventoryTag(inventory).setIdentifiers("script",
InventoryScriptHelper.tempInventoryScripts.get(inventory));
String scriptResult = InventoryScriptHelper.tempInventoryScripts.get(inventory);
if (scriptResult != null) {
return new InventoryTag(inventory).setIdentifiers("script", scriptResult);
}
// Use the map to get notable inventories
String title = NMSHandler.getInstance().getTitle(inventory);
if (InventoryScriptHelper.notableInventories.containsKey(title)) {
return InventoryScriptHelper.notableInventories.get(title);
result = InventoryScriptHelper.notableInventories.get(title);
if (result != null) {
return result;
}
// Iterate through offline player inventories
for (Map.Entry<UUID, PlayerInventory> inv : ImprovedOfflinePlayer.offlineInventories.entrySet()) {
Expand Down Expand Up @@ -205,8 +303,17 @@ public static InventoryTag valueOf(String string, PlayerTag player, NPCTag npc,
// Handle objects with properties through the object fetcher
Matcher describedMatcher = ObjectFetcher.DESCRIBED_PATTERN.matcher(string);
if (describedMatcher.matches()) {
return ObjectFetcher.getObjectFrom(InventoryTag.class, string,
InventoryTag result = ObjectFetcher.getObjectFrom(InventoryTag.class, string,
new BukkitTagContext(player, npc, false, null, false, null));
if (result != null && result.uniquifier != null) {
InventoryTag fixedResult = InventoryTrackerSystem.idTrackedInventories.get(result.uniquifier);
if (fixedResult != null) {
trackTemporaryInventory(fixedResult);
return fixedResult;
}
}
trackTemporaryInventory(result);
return result;
}

if (string.startsWith("in@")) {
Expand Down Expand Up @@ -279,6 +386,8 @@ public static boolean matches(String arg) {
String idType = null;
String idHolder = null;

public Long uniquifier = null;

public String scriptName = null;

public InventoryTag(Inventory inventory) {
Expand Down Expand Up @@ -495,6 +604,7 @@ private void loadIdentifiers(final InventoryHolder holder) {
if (inventory == null) {
return;
}
trackTemporaryInventory(this);

if (holder != null) {
if (holder instanceof NPCTag) {
Expand Down
Expand Up @@ -94,6 +94,7 @@ public static void registermainProperties() {
PropertyParser.registerProperty(InventoryContents.class, InventoryTag.class);
PropertyParser.registerProperty(InventoryScriptName.class, InventoryTag.class);
PropertyParser.registerProperty(InventoryTitle.class, InventoryTag.class);
PropertyParser.registerProperty(InventoryUniquifier.class, InventoryTag.class);

// register core ItemTag properties
PropertyParser.registerProperty(ItemApple.class, ItemTag.class);
Expand Down
@@ -0,0 +1,65 @@
package com.denizenscript.denizen.objects.properties.inventory;

import com.denizenscript.denizen.objects.InventoryTag;
import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.properties.Property;

public class InventoryUniquifier implements Property {

public static boolean describes(ObjectTag inventory) {
// All inventories can potentially have a uniquifier
return inventory instanceof InventoryTag;
}

public static InventoryUniquifier getFrom(ObjectTag inventory) {
if (!describes(inventory)) {
return null;
}
return new InventoryUniquifier((InventoryTag) inventory);
}

public static final String[] handledMechs = new String[] {
"uniquifier"
};

///////////////////
// Instance Fields and Methods
/////////////

InventoryTag inventory;

public InventoryUniquifier(InventoryTag inventory) {
this.inventory = inventory;
}

/////////
// Property Methods
///////

@Override
public String getPropertyString() {
if (inventory.uniquifier == null) {
return null;
}
return String.valueOf(inventory.uniquifier);
}

@Override
public String getPropertyId() {
return "uniquifier";
}

public static void registerTags() {
// Intentionally no tags.
}

@Override
public void adjust(Mechanism mechanism) {

// Undocumented / internal
if (mechanism.matches("uniquifier")) {
inventory.uniquifier = mechanism.getValue().asLong();
}
}
}
Expand Up @@ -104,11 +104,15 @@ else if (arg.matchesArgumentList(ItemTag.class)) {
}
else if (LocationTag.matches(string)) {
InventoryTag inv = LocationTag.valueOf(string).getInventory();
return new AbstractMap.SimpleEntry<>(inv.getContents().length, inv);
if (inv != null) {
return new AbstractMap.SimpleEntry<>(inv.getContents().length, inv);
}
}
else if (EntityTag.matches(string)) {
InventoryTag inv = EntityTag.valueOf(string).getInventory();
return new AbstractMap.SimpleEntry<>(inv.getContents().length, inv);
if (inv != null) {
return new AbstractMap.SimpleEntry<>(inv.getContents().length, inv);
}
}

return null;
Expand Down

0 comments on commit 1a6a767

Please sign in to comment.