--- a/net/minecraft/world/level/block/entity/ContainerOpenersCounter.java
+++ b/net/minecraft/world/level/block/entity/ContainerOpenersCounter.java
@@ -13,6 +13,7 @@
 
     private static final int CHECK_TICK_DELAY = 5;
     private int openCount;
+    public boolean opened; // CraftBukkit
 
     public ContainerOpenersCounter() {}
 
@@ -22,11 +23,36 @@
 
     protected abstract void openerCountChanged(World world, BlockPosition blockposition, IBlockData iblockdata, int i, int j);
 
+    // CraftBukkit start
+    public void onAPIOpen(World world, BlockPosition blockposition, IBlockData iblockdata) {
+        onOpen(world, blockposition, iblockdata);
+    }
+
+    public void onAPIClose(World world, BlockPosition blockposition, IBlockData iblockdata) {
+        onClose(world, blockposition, iblockdata);
+    }
+
+    public void openerAPICountChanged(World world, BlockPosition blockposition, IBlockData iblockdata, int i, int j) {
+        openerCountChanged(world, blockposition, iblockdata, i, j);
+    }
+    // CraftBukkit end
+
     protected abstract boolean isOwnContainer(EntityHuman entityhuman);
 
     public void incrementOpeners(EntityHuman entityhuman, World world, BlockPosition blockposition, IBlockData iblockdata) {
+        int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
         int i = this.openCount++;
 
+        // CraftBukkit start - Call redstone event
+        if (world.getBlockState(blockposition).is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
+            int newPower = Math.max(0, Math.min(15, this.openCount));
+
+            if (oldPower != newPower) {
+                org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, blockposition, oldPower, newPower);
+            }
+        }
+        // CraftBukkit end
+
         if (i == 0) {
             this.onOpen(world, blockposition, iblockdata);
             world.gameEvent((Entity) entityhuman, GameEvent.CONTAINER_OPEN, blockposition);
@@ -37,8 +63,19 @@
     }
 
     public void decrementOpeners(EntityHuman entityhuman, World world, BlockPosition blockposition, IBlockData iblockdata) {
+        int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
         int i = this.openCount--;
 
+        // CraftBukkit start - Call redstone event
+        if (world.getBlockState(blockposition).is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) {
+            int newPower = Math.max(0, Math.min(15, this.openCount));
+
+            if (oldPower != newPower) {
+                org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, blockposition, oldPower, newPower);
+            }
+        }
+        // CraftBukkit end
+
         if (this.openCount == 0) {
             this.onClose(world, blockposition, iblockdata);
             world.gameEvent((Entity) entityhuman, GameEvent.CONTAINER_CLOSE, blockposition);
@@ -59,6 +96,7 @@
 
     public void recheckOpeners(World world, BlockPosition blockposition, IBlockData iblockdata) {
         int i = this.getOpenCount(world, blockposition);
+        if (opened) i++; // CraftBukkit - add dummy count from API
         int j = this.openCount;
 
         if (j != i) {
