Skip to content

Commit 6c19d8f

Browse files
committed
Improve slot array handling for serverside sort, close #28
1 parent 55f1535 commit 6c19d8f

4 files changed

Lines changed: 86 additions & 28 deletions

File tree

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 1.3.3
4+
5+
- Fixed serverside sorting with certain storage mods
6+
37
## 1.3.2
48

59
- Fixed a crash on NeoForge introduced in v1.3.1

common/src/main/java/dev/terminalmc/clientsort/inventory/sort/InventorySorter.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
import dev.terminalmc.clientsort.compat.itemlocks.ItemLocksWrapper;
2121
import dev.terminalmc.clientsort.inventory.ContainerScreenHelper;
22+
import dev.terminalmc.clientsort.main.MainSort;
2223
import dev.terminalmc.clientsort.main.network.SortPayload;
2324
import dev.terminalmc.clientsort.network.InteractionManager;
2425
import dev.terminalmc.clientsort.platform.Services;
2526
import dev.terminalmc.clientsort.util.SoundManager;
2627
import dev.terminalmc.clientsort.util.inject.ISlot;
28+
import net.minecraft.client.Minecraft;
2729
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
30+
import net.minecraft.client.player.LocalPlayer;
2831
import net.minecraft.world.inventory.ClickType;
2932
import net.minecraft.world.inventory.Slot;
3033
import net.minecraft.world.item.*;
@@ -61,20 +64,25 @@ public InventorySorter(
6164
for (int i = 0; i < inventorySlots.length; i++) {
6265
stacks[i] = inventorySlots[i].getItem();
6366
}
67+
68+
logInventorySlots(inventorySlots);
6469
}
6570

6671
/**
6772
* Collects all slots that are valid for sorting in the context of
6873
* {@code originSlot}.
6974
*/
7075
private Slot[] collectSlots(Slot originSlot) {
76+
LocalPlayer player = Minecraft.getInstance().player;
7177
Scope originScope = screenHelper.getScope(originSlot);
7278
if (originScope == Scope.INVALID) return new Slot[0];
7379

7480
ArrayList<Slot> collectedSlots = new ArrayList<>();
7581
for (Slot slot : containerScreen.getMenu().slots) {
7682
// Ignore slots in different scope
7783
if (originScope != screenHelper.getScope(slot)) continue;
84+
// Ignore inaccessible slots
85+
if (player != null && !slot.mayPickup(player)) continue;
7886
// Ignore locked slots
7987
if (ItemLocksWrapper.isLocked(slot)) continue;
8088
// Slot is valid
@@ -375,4 +383,16 @@ protected void sortOnClient(int[] sortedIds, boolean playSound) {
375383
} while (!doneOrEmpty.get(id));
376384
}
377385
}
386+
387+
private static void logInventorySlots(Slot[] inventorySlots) {
388+
// Log inventory array
389+
StringBuilder arr = new StringBuilder("[");
390+
for (Slot inventorySlot : inventorySlots) {
391+
arr.append(inventorySlot.index);
392+
arr.append(":");
393+
arr.append(inventorySlot.getItem().getDisplayName().getString());
394+
arr.append(", ");
395+
}
396+
MainSort.LOG.warn(arr.length() == 1 ? "[]" : arr.substring(0, arr.length() - 2) + "]");
397+
}
378398
}

common/src/main/java/dev/terminalmc/clientsort/main/network/LogicalServerNetworking.java

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
import net.minecraft.world.inventory.Slot;
2929
import net.minecraft.world.item.ItemStack;
3030

31-
import java.util.List;
31+
import java.util.Map;
32+
import java.util.TreeMap;
3233

3334
/**
3435
* Handles sorting via a {@link SortPayload} on the logical server side.
@@ -62,47 +63,54 @@ public static void onSortPayload(SortPayload payload, MinecraftServer server,
6263
*/
6364
private static void sort(Player player, AbstractContainerMenu screenHandler,
6465
int[] slotMapping) {
65-
if (!validMapping(player, screenHandler, slotMapping)) {
66+
Map<Integer,Slot> slots = new TreeMap<>();
67+
Map<Integer,ItemStack> stacks = new TreeMap<>();
68+
for (Slot slot : screenHandler.slots) {
69+
slots.put(slot.index, slot);
70+
stacks.put(slot.index, slot.getItem());
71+
}
72+
73+
logScreenHandlerSlots(screenHandler);
74+
logSlotMapping(slotMapping);
75+
76+
if (!validMapping(player, slots, slotMapping)) {
6677
MainSort.LOG.warn("Sort payload from player {} contains invalid data, ignoring!",
6778
player);
6879
return;
6980
}
7081

71-
List<ItemStack> stacks = screenHandler.slots.stream().map(Slot::getItem).toList();
72-
73-
for (int i = 0; i < slotMapping.length; i += 2) {
82+
for (int i = 0; i < slotMapping.length - 1; i += 2) {
7483
int originSlotId = slotMapping[i];
7584
int destSlotId = slotMapping[i + 1];
76-
77-
screenHandler.slots.get(destSlotId).setByPlayer(stacks.get(originSlotId));
85+
slots.get(destSlotId).setByPlayer(stacks.get(originSlotId));
7886
}
7987
}
8088

8189
/**
8290
* @return {@code true} if the specified slot mapping is valid.
8391
*/
84-
private static boolean validMapping(Player player, AbstractContainerMenu screenHandler,
85-
int[] slotMapping) {
92+
private static boolean validMapping(Player player, Map<Integer,Slot> slots, int[] slotMapping) {
8693
if (slotMapping.length < 4) {
87-
MainSort.LOG.warn("Sort payload contains too few slots!");
94+
MainSort.LOG.warn("Sort payload contains too few slots! Got {}, expected at least {}",
95+
slotMapping.length, 4);
8896
return false;
8997
}
9098

9199
IntSet requestedSlots = new IntAVLTreeSet();
92100
Container targetInv;
93101

94-
if (!validSlotId(screenHandler, slotMapping[0])) {
102+
if (!validSlotId(slots, slotMapping[0])) {
95103
return false;
96104
}
97-
Slot firstSlot = screenHandler.slots.get(slotMapping[0]);
105+
Slot firstSlot = slots.get(slotMapping[0]);
98106
targetInv = firstSlot.container;
99107

100108
// Check each slot mapping
101109
for (int i = 0; i < slotMapping.length; i += 2) {
102110
int originSlotId = slotMapping[i];
103111
int destSlotId = slotMapping[i + 1];
104112

105-
if (!validSlot(screenHandler, originSlotId, targetInv)) {
113+
if (!validSlot(slots, originSlotId, targetInv)) {
106114
return false;
107115
}
108116

@@ -112,25 +120,26 @@ private static boolean validMapping(Player player, AbstractContainerMenu screenH
112120
return false;
113121
}
114122

115-
if (!validSlot(screenHandler, destSlotId, targetInv)) {
123+
if (!validSlot(slots, destSlotId, targetInv)) {
116124
return false;
117125
}
118126

119127
if (originSlotId == destSlotId) {
120128
continue;
121129
}
122130

123-
Slot originSlot = screenHandler.getSlot(originSlotId);
131+
Slot originSlot = slots.get(originSlotId);
124132
if (!originSlot.mayPickup(player)) {
125-
MainSort.LOG.warn("Player {} tried to sort slot {}, but that slot " +
126-
"doesn't allow taking items!", player, originSlotId);
133+
MainSort.LOG.warn("Player {} tried to sort slot {} with stack [{}], but that slot " +
134+
"doesn't allow taking items!", player, originSlotId, originSlot.getItem());
127135
return false;
128136
}
129137

130-
Slot destSlot = screenHandler.getSlot(destSlotId);
138+
Slot destSlot = slots.get(destSlotId);
131139
if (!destSlot.mayPlace(originSlot.getItem())) {
132-
MainSort.LOG.warn("Player {} tried to sort slot {}, but that slot " +
133-
"doesn't allow inserting the origin stack!", player, destSlotId);
140+
MainSort.LOG.warn("Player {} tried to sort slot {} with stack [{}], but that slot " +
141+
"doesn't allow inserting the origin stack [{}]!", player, destSlotId,
142+
destSlot.getItem(), originSlot.getItem());
134143
return false;
135144
}
136145
}
@@ -156,10 +165,12 @@ private static boolean validMapping(Player player, AbstractContainerMenu screenH
156165
* @return {@code true} if the specified slot ID is a valid index.
157166
*/
158167
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
159-
private static boolean validSlotId(AbstractContainerMenu screenHandler, int slotId) {
160-
if (slotId < 0 || slotId >= screenHandler.slots.size()) {
161-
MainSort.LOG.warn("Sort payload contains invalid slot id {} out of bounds " +
162-
"for length {}!", slotId, screenHandler.slots.size());
168+
private static boolean validSlotId(Map<Integer,Slot> slots, int slotId) {
169+
if (!slots.containsKey(slotId)) {
170+
StringBuilder sb = new StringBuilder();
171+
slots.keySet().forEach((key) -> sb.append(key).append(", "));
172+
MainSort.LOG.warn("Sort payload contains invalid slot id {} not found in list [{}]!",
173+
slotId, sb.toString());
163174
return false;
164175
}
165176

@@ -171,12 +182,12 @@ private static boolean validSlotId(AbstractContainerMenu screenHandler, int slot
171182
* specified {@link Container}.
172183
*/
173184
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
174-
private static boolean validSlot(AbstractContainerMenu screenHandler, int slotId, Container targetInv) {
175-
if (!validSlotId(screenHandler, slotId)) {
185+
private static boolean validSlot(Map<Integer,Slot> slots, int slotId, Container targetInv) {
186+
if (!validSlotId(slots, slotId)) {
176187
return false;
177188
}
178189

179-
Slot slot = screenHandler.getSlot(slotId);
190+
Slot slot = slots.get(slotId);
180191

181192
if (targetInv != slot.container) {
182193
MainSort.LOG.warn("Sort payload contains slots from different inventories, " +
@@ -186,4 +197,27 @@ private static boolean validSlot(AbstractContainerMenu screenHandler, int slotId
186197

187198
return true;
188199
}
200+
201+
private static void logScreenHandlerSlots(AbstractContainerMenu screenHandler) {
202+
// Log inventory array
203+
StringBuilder arr = new StringBuilder("[");
204+
for (Slot slot : screenHandler.slots) {
205+
arr.append(slot.index);
206+
arr.append(":");
207+
arr.append(slot.getItem().getDisplayName().getString());
208+
arr.append(", ");
209+
}
210+
MainSort.LOG.warn(arr.length() == 1 ? "[]" : arr.substring(0, arr.length() - 2) + "]");
211+
}
212+
213+
private static void logSlotMapping(int[] slotMapping) {
214+
StringBuilder arr = new StringBuilder("[");
215+
for (int i = 0; i < slotMapping.length - 1; i += 2) {
216+
arr.append(slotMapping[i]);
217+
arr.append("->");
218+
arr.append(slotMapping[i+1]);
219+
arr.append(", ");
220+
}
221+
MainSort.LOG.warn(arr.length() == 1 ? "[]" : arr.substring(0, arr.length() - 2) + "]");
222+
}
189223
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Neo/Forge version ranges: https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html
44

55
# Project
6-
mod_version=1.3.2
6+
mod_version=1.3.3
77
mod_group=dev.terminalmc
88
mod_id=clientsort
99
mod_name=ClientSort

0 commit comments

Comments
 (0)