44import dan200 .computercraft .api .lua .LuaFunction ;
55import dan200 .computercraft .api .lua .MethodResult ;
66import dan200 .computercraft .api .peripheral .IComputerAccess ;
7- import dan200 .computercraft .api .peripheral .IPeripheral ;
87import de .srendi .advancedperipherals .common .addons .computercraft .peripheral .InventoryManagerPeripheral ;
98import de .srendi .advancedperipherals .common .util .EmptyLuaTable ;
9+ import de .srendi .advancedperipherals .common .util .LuaConverter ;
1010import de .srendi .advancedperipherals .common .util .Pair ;
1111import net .minecraft .server .level .ServerPlayer ;
1212import net .minecraft .world .entity .player .Inventory ;
1313import net .minecraft .world .item .ItemStack ;
1414import net .neoforged .neoforge .capabilities .Capabilities ;
15+ import net .neoforged .neoforge .fluids .capability .IFluidHandler ;
16+ import net .neoforged .neoforge .fluids .capability .IFluidHandlerItem ;
1517import net .neoforged .neoforge .items .IItemHandler ;
1618import net .neoforged .neoforge .items .wrapper .PlayerInvWrapper ;
1719import org .jetbrains .annotations .NotNull ;
1820import org .jetbrains .annotations .Nullable ;
1921
2022import java .lang .ref .WeakReference ;
23+ import java .util .HashMap ;
2124import java .util .Map ;
2225import java .util .Optional ;
26+ import java .util .function .BiConsumer ;
2327import java .util .function .Function ;
2428
25- // TODO: fluid variant?
2629public class PlayerStorageItemWrapper {
2730 private final IComputerAccess computer ;
28- private final WeakReference < InventoryManagerPeripheral > peripheral ;
31+ private final InventoryManagerPeripheral peripheral ;
2932 private final WeakReference <ServerPlayer > player ;
3033 private final Function <ServerPlayer , ItemStack > itemProvider ;
31- private final ItemStack stack ;
34+ private final BiConsumer <ServerPlayer , ItemStack > itemUpdater ;
35+ private ItemStack stack ;
3236 private final IItemHandler itemHandler ;
37+ private final IFluidHandler fluidHandler ;
3338
3439 protected PlayerStorageItemWrapper (
3540 IComputerAccess computer ,
3641 InventoryManagerPeripheral peripheral ,
3742 ServerPlayer player ,
3843 Function <ServerPlayer , ItemStack > itemProvider ,
44+ BiConsumer <ServerPlayer , ItemStack > itemUpdater ,
3945 ItemStack stack ,
40- IItemHandler itemHandler
46+ @ Nullable IItemHandler itemHandler ,
47+ @ Nullable IFluidHandler fluidHandler
4148 ) {
4249 this .computer = computer ;
43- this .peripheral = new WeakReference <>( peripheral ) ;
50+ this .peripheral = peripheral ;
4451 this .player = new WeakReference <>(player );
4552 this .itemProvider = itemProvider ;
53+ this .itemUpdater = itemUpdater ;
4654 this .stack = stack ;
4755 this .itemHandler = itemHandler ;
56+ this .fluidHandler = fluidHandler ;
4857 }
4958
5059 @ Nullable
@@ -55,20 +64,31 @@ public static PlayerStorageItemWrapper create(IComputerAccess computer, Inventor
5564 return ItemStack .EMPTY ;
5665 }
5766 return inventory .getItem (slot );
67+ }, (p , stack ) -> {
68+ Inventory inventory = p .getInventory ();
69+ inventory .setItem (slot , stack );
70+ inventory .setChanged ();
5871 });
5972 }
6073
6174 @ Nullable
62- public static PlayerStorageItemWrapper create (IComputerAccess computer , InventoryManagerPeripheral peripheral , @ NotNull ServerPlayer player , Function <ServerPlayer , ItemStack > itemProvider ) {
75+ public static PlayerStorageItemWrapper create (
76+ IComputerAccess computer ,
77+ InventoryManagerPeripheral peripheral ,
78+ @ NotNull ServerPlayer player ,
79+ Function <ServerPlayer , ItemStack > itemProvider ,
80+ BiConsumer <ServerPlayer , ItemStack > itemUpdater
81+ ) {
6382 ItemStack stack = itemProvider .apply (player );
6483 if (stack .isEmpty ()) {
6584 return null ;
6685 }
6786 IItemHandler itemHandler = stack .getCapability (Capabilities .ItemHandler .ITEM );
68- if (itemHandler == null ) {
87+ IFluidHandler fluidHandler = stack .getCapability (Capabilities .FluidHandler .ITEM );
88+ if (itemHandler == null && fluidHandler == null ) {
6989 return null ;
7090 }
71- return new PlayerStorageItemWrapper (computer , peripheral , player , itemProvider , stack , itemHandler );
91+ return new PlayerStorageItemWrapper (computer , peripheral , player , itemProvider , itemUpdater , stack , itemHandler , fluidHandler );
7292 }
7393
7494 public boolean isValid () {
@@ -79,11 +99,10 @@ public boolean isValid() {
7999 if (this .itemProvider .apply (player ) != this .stack ) {
80100 return false ;
81101 }
82- InventoryManagerPeripheral peripheral = this .peripheral .get ();
83- if (peripheral == null || !peripheral .isAccessValid (this .computer )) {
102+ if (!this .peripheral .isAccessValid (this .computer )) {
84103 return false ;
85104 }
86- return peripheral .getOwnerPlayer () == player ;
105+ return this . peripheral .getOwnerPlayer () == player ;
87106 }
88107
89108 protected final void assertValid () throws LuaException {
@@ -92,51 +111,126 @@ protected final void assertValid() throws LuaException {
92111 }
93112 }
94113
114+ protected final void assertValidItemHandler () throws LuaException {
115+ if (this .itemHandler == null ) {
116+ throw new LuaException ("Storage item is not an item storage" );
117+ }
118+ this .assertValid ();
119+ }
120+
121+ protected final void assertValidFluidHandler () throws LuaException {
122+ if (this .fluidHandler == null ) {
123+ throw new LuaException ("Storage item is not a fluid storage" );
124+ }
125+ this .assertValid ();
126+ }
127+
95128 @ LuaFunction (value = "isValid" , mainThread = true )
96129 public final boolean isValidLua () {
97130 return this .isValid ();
98131 }
99132
133+ @ LuaFunction
134+ public final boolean isItemStorage () {
135+ return this .itemHandler != null ;
136+ }
137+
138+ @ LuaFunction
139+ public final boolean isFluidStorage () {
140+ return this .fluidHandler != null ;
141+ }
142+
143+ //// BEGIN ITEM METHODS ////
144+
100145 @ LuaFunction (mainThread = true )
101146 public final int size () throws LuaException {
102- this .assertValid ();
147+ this .assertValidItemHandler ();
103148 return this .itemHandler .getSlots ();
104149 }
105150
106151 @ LuaFunction (mainThread = true )
107152 public final Map <Integer , ?> list () throws LuaException {
108- this .assertValid ();
153+ this .assertValidItemHandler ();
109154 return InventoryUtil .list (this .itemHandler );
110155 }
111156
112157 @ LuaFunction (mainThread = true )
113158 public final MethodResult pushItems (String toName , Optional <Map <?, ?>> filterTable ) throws LuaException {
114- this .assertValid ();
159+ this .assertValidItemHandler ();
160+
161+ IItemHandler inventoryTo = this .getItemHandler (toName );
115162
116163 Pair <ItemFilter , String > filter = ItemFilter .parse (EmptyLuaTable .orEmpty (filterTable .orElse (null )));
117164 if (filter .rightPresent ()) {
118165 return MethodResult .of (null , filter .right ());
119166 }
120167
121- IItemHandler inventoryTo = this .getItemHandler (toName );
122-
123168 return MethodResult .of (ItemUtil .moveItem (this .itemHandler , inventoryTo , filter .left ()));
124169 }
125170
126171 @ LuaFunction (mainThread = true )
127172 public final MethodResult pullItems (String fromName , Optional <Map <?, ?>> filterTable ) throws LuaException {
128- this .assertValid ();
173+ this .assertValidItemHandler ();
174+
175+ IItemHandler inventoryFrom = this .getItemHandler (fromName );
129176
130177 Pair <ItemFilter , String > filter = ItemFilter .parse (EmptyLuaTable .orEmpty (filterTable .orElse (null )));
131178 if (filter .rightPresent ()) {
132179 return MethodResult .of (null , filter .right ());
133180 }
134181
135- IItemHandler inventoryFrom = this .getItemHandler (fromName );
136-
137182 return MethodResult .of (ItemUtil .moveItem (inventoryFrom , this .itemHandler , filter .left ()));
138183 }
139184
185+ //// END ITEM METHODS ////
186+
187+ //// BEGIN FLUID METHODS ////
188+
189+ @ LuaFunction (mainThread = true )
190+ public final Map <Integer , ?> tanks () throws LuaException {
191+ this .assertValidFluidHandler ();
192+ Map <Integer , Map <String , ?>> data = new HashMap <>();
193+ int size = this .fluidHandler .getTanks ();
194+ for (int i = 0 ; i < size ; i ++) {
195+ data .put (i + 1 , LuaConverter .fluidStackToLua (this .fluidHandler .getFluidInTank (i )));
196+ }
197+ return data ;
198+ }
199+
200+ @ LuaFunction (mainThread = true )
201+ public final MethodResult pushFluid (String toName , Optional <Map <?, ?>> filterTable ) throws LuaException {
202+ this .assertValidFluidHandler ();
203+
204+ IFluidHandler inventoryTo = this .peripheral .getFluidHandler (this .computer , toName );
205+
206+ Pair <FluidFilter , String > filter = FluidFilter .parse (EmptyLuaTable .orEmpty (filterTable .orElse (null )));
207+ if (filter .rightPresent ()) {
208+ return MethodResult .of (null , filter .right ());
209+ }
210+
211+ int amount = FluidUtil .moveFluid (this .fluidHandler , inventoryTo , filter .left ());
212+ this .postFluidUpdate ();
213+ return MethodResult .of (amount );
214+ }
215+
216+ @ LuaFunction (mainThread = true )
217+ public final MethodResult pullFluid (String fromName , Optional <Map <?, ?>> filterTable ) throws LuaException {
218+ this .assertValidFluidHandler ();
219+
220+ IFluidHandler inventoryFrom = this .peripheral .getFluidHandler (this .computer , fromName );
221+
222+ Pair <FluidFilter , String > filter = FluidFilter .parse (EmptyLuaTable .orEmpty (filterTable .orElse (null )));
223+ if (filter .rightPresent ()) {
224+ return MethodResult .of (null , filter .right ());
225+ }
226+
227+ int amount = FluidUtil .moveFluid (inventoryFrom , this .fluidHandler , filter .left ());
228+ this .postFluidUpdate ();
229+ return MethodResult .of (amount );
230+ }
231+
232+ //// END FLUID METHODS ////
233+
140234 @ NotNull
141235 private IItemHandler getItemHandler (String name ) throws LuaException {
142236 if (name .equals (InventoryManagerPeripheral .PLAYER_INV_MAGIC_NAME )) {
@@ -146,14 +240,17 @@ private IItemHandler getItemHandler(String name) throws LuaException {
146240 }
147241 return new PlayerInvWrapper (player .getInventory ());
148242 }
149- IPeripheral toPeripheral = this .computer .getAvailablePeripheral (name );
150- if (toPeripheral == null ) {
151- throw new LuaException ("Target '" + name + "' does not exist" );
152- }
153- IItemHandler inventory = ItemUtil .extractHandler (toPeripheral );
154- if (inventory == null ) {
155- throw new LuaException ("Target '" + name + "' is not an inventory" );
243+ return this .peripheral .getItemHandler (this .computer , name );
244+ }
245+
246+ protected void postFluidUpdate () {
247+ ServerPlayer player = this .player .get ();
248+ if (this .fluidHandler instanceof IFluidHandlerItem handler ) {
249+ ItemStack stack = handler .getContainer ();
250+ if (this .itemProvider .apply (player ) != stack ) {
251+ this .stack = stack ;
252+ this .itemUpdater .accept (player , stack );
253+ }
156254 }
157- return inventory ;
158255 }
159256}
0 commit comments