Skip to content

Commit a354250

Browse files
committed
fix: correct bank overflow for items/give
#1676 does not appear to happen anymore
1 parent e799f73 commit a354250

File tree

6 files changed

+120
-57
lines changed

6 files changed

+120
-57
lines changed

Intersect.Server.Core/Database/Item.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ public Item(
4343
Bag = bag;
4444
Properties = properties ?? new ItemProperties();
4545

46-
var descriptor = ItemBase.Get(ItemId);
47-
if (descriptor == null || properties != null)
46+
if (!ItemBase.TryGet(itemId, out var descriptor) || properties != null)
4847
{
4948
return;
5049
}

Intersect.Server.Core/Entities/BankInterface.cs

Lines changed: 88 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void SendCloseBank()
8686
_player?.SendPacket(new BankPacket(true, false, -1, null));
8787
}
8888

89-
public bool TryDepositItem(Item? slot, int inventorySlotIndex, int quantityHint, int bankSlotIndex = -1, bool sendUpdate = true)
89+
public bool TryDepositItem(Item? slot, int inventorySlotIndex, int quantityHint, int bankSlotIndex = -1, bool sendUpdate = true, bool giveItem = false)
9090
{
9191
//Permission Check
9292
if (_guild != null)
@@ -122,7 +122,7 @@ public bool TryDepositItem(Item? slot, int inventorySlotIndex, int quantityHint,
122122

123123
var sourceSlots = _player.Items.ToArray();
124124
var maximumStack = itemDescriptor.Stackable ? itemDescriptor.MaxBankStack : 1;
125-
var sourceQuantity = Item.FindQuantityOfItem(itemDescriptor.Id, sourceSlots);
125+
var sourceQuantity = giveItem ? quantityHint : Item.FindQuantityOfItem(itemDescriptor.Id, sourceSlots);
126126

127127
_bank.FillToCapacity();
128128

@@ -139,11 +139,22 @@ public bool TryDepositItem(Item? slot, int inventorySlotIndex, int quantityHint,
139139
targetSlots
140140
);
141141

142+
if (giveItem && slot.Quantity != movableQuantity)
143+
{
144+
PacketSender.SendChatMsg(
145+
_player,
146+
Strings.Banks.NotEnoughBankSpaceForItem.ToString(slot.Quantity, itemDescriptor.Name),
147+
ChatMessageType.Bank,
148+
CustomColors.Alerts.Error
149+
);
150+
return false;
151+
}
152+
142153
if (movableQuantity < 1)
143154
{
144155
PacketSender.SendChatMsg(
145156
_player,
146-
Strings.Items.NoSpaceForItem,
157+
Strings.Banks.NotEnoughBankSpaceForOneOfItem.ToString(itemDescriptor.Name),
147158
ChatMessageType.Bank,
148159
CustomColors.Alerts.Error
149160
);
@@ -159,31 +170,39 @@ public bool TryDepositItem(Item? slot, int inventorySlotIndex, int quantityHint,
159170
targetSlots
160171
);
161172

162-
if (!Item.TryFindSourceSlotsForItem(
163-
itemDescriptor.Id,
164-
inventorySlotIndex,
165-
movableQuantity,
166-
sourceSlots,
167-
out var slotIndicesToRemoveFrom
168-
))
173+
int[] slotIndicesToRemoveFrom = [];
174+
175+
if (!giveItem)
169176
{
170-
PacketSender.SendChatMsg(
171-
_player,
172-
Strings.Banks.WithdrawInvalid,
173-
ChatMessageType.Bank,
174-
CustomColors.Alerts.Error
175-
);
176-
return false;
177+
if (!Item.TryFindSourceSlotsForItem(
178+
itemDescriptor.Id,
179+
inventorySlotIndex,
180+
movableQuantity,
181+
sourceSlots,
182+
out slotIndicesToRemoveFrom
183+
))
184+
{
185+
PacketSender.SendChatMsg(
186+
_player,
187+
Strings.Banks.NotEnoughInInventory.ToString(movableQuantity, itemDescriptor.Name),
188+
ChatMessageType.Bank,
189+
CustomColors.Alerts.Error
190+
);
191+
return false;
192+
}
177193
}
178194

179195
var nextSlotIndexToRemoveFrom = 0;
180196
var remainingQuantity = movableQuantity;
181197
foreach (var slotIndexToFill in slotIndicesToFill)
182198
{
183-
if (slotIndicesToRemoveFrom.Length <= nextSlotIndexToRemoveFrom)
199+
if (!giveItem)
184200
{
185-
Log.Warn($"Ran out of slots to remove from for {_player.Id}");
186-
break;
201+
if (slotIndicesToRemoveFrom.Length <= nextSlotIndexToRemoveFrom)
202+
{
203+
Log.Warn($"Ran out of slots to remove from for {_player.Id}");
204+
break;
205+
}
187206
}
188207

189208
if (remainingQuantity < 1)
@@ -197,14 +216,21 @@ out var slotIndicesToRemoveFrom
197216

198217
if (slotToFill.ItemId == default && maximumStack <= 1)
199218
{
200-
if (slotIndicesToRemoveFrom.Length <= nextSlotIndexToRemoveFrom)
219+
if (giveItem)
201220
{
202-
break;
221+
slotToFill.Set(new Item(slot.ItemId, quantityToStoreInSlot));
203222
}
223+
else
224+
{
225+
if (slotIndicesToRemoveFrom.Length <= nextSlotIndexToRemoveFrom)
226+
{
227+
break;
228+
}
204229

205-
var slotIndexToRemoveFrom = slotIndicesToRemoveFrom[nextSlotIndexToRemoveFrom++];
206-
var sourceSlot = sourceSlots[slotIndexToRemoveFrom];
207-
slotToFill.Set(sourceSlot);
230+
var slotIndexToRemoveFrom = slotIndicesToRemoveFrom[nextSlotIndexToRemoveFrom++];
231+
var sourceSlot = sourceSlots[slotIndexToRemoveFrom];
232+
slotToFill.Set(sourceSlot);
233+
}
208234
remainingQuantity -= 1;
209235
continue;
210236
}
@@ -220,31 +246,39 @@ out var slotIndicesToRemoveFrom
220246
remainingQuantity -= quantityToStoreInSlot;
221247
}
222248

223-
var remainingQuantityToRemove = movableQuantity;
224-
foreach (var slotIndexToRemoveFrom in slotIndicesToRemoveFrom)
249+
int remainingQuantityToRemove;
250+
if (giveItem)
225251
{
226-
if (remainingQuantityToRemove < 1)
252+
remainingQuantityToRemove = 0;
253+
}
254+
else
255+
{
256+
remainingQuantityToRemove = movableQuantity;
257+
foreach (var slotIndexToRemoveFrom in slotIndicesToRemoveFrom)
227258
{
228-
Log.Error($"Potential inventory corruption for {_player.Id}");
229-
}
259+
if (remainingQuantityToRemove < 1)
260+
{
261+
Log.Error($"Potential inventory corruption for {_player.Id}");
262+
}
230263

231-
var slotToRemoveFrom = sourceSlots[slotIndexToRemoveFrom];
232-
Debug.Assert(slotToRemoveFrom != default);
233-
var quantityToRemoveFromSlot = Math.Min(remainingQuantityToRemove, slotToRemoveFrom.Quantity);
234-
slotToRemoveFrom.Quantity -= quantityToRemoveFromSlot;
264+
var slotToRemoveFrom = sourceSlots[slotIndexToRemoveFrom];
265+
Debug.Assert(slotToRemoveFrom != default);
266+
var quantityToRemoveFromSlot = Math.Min(remainingQuantityToRemove, slotToRemoveFrom.Quantity);
267+
slotToRemoveFrom.Quantity -= quantityToRemoveFromSlot;
235268

236-
// If the item is equipped equipment, we need to unequip it before taking it out of the inventory.
237-
if (itemDescriptor.ItemType == ItemType.Equipment && slotIndexToRemoveFrom > -1)
238-
{
239-
_player.EquipmentProcessItemLoss(slotIndexToRemoveFrom);
240-
}
269+
// If the item is equipped equipment, we need to unequip it before taking it out of the inventory.
270+
if (itemDescriptor.ItemType == ItemType.Equipment && slotIndexToRemoveFrom > -1)
271+
{
272+
_player.EquipmentProcessItemLoss(slotIndexToRemoveFrom);
273+
}
241274

242-
if (slotToRemoveFrom.Quantity < 1)
243-
{
244-
slotToRemoveFrom.Set(Item.None);
245-
}
275+
if (slotToRemoveFrom.Quantity < 1)
276+
{
277+
slotToRemoveFrom.Set(Item.None);
278+
}
246279

247-
remainingQuantityToRemove -= quantityToRemoveFromSlot;
280+
remainingQuantityToRemove -= quantityToRemoveFromSlot;
281+
}
248282
}
249283

250284
// ReSharper disable once ConvertIfStatementToSwitchStatement
@@ -300,10 +334,17 @@ out var slotIndicesToRemoveFrom
300334
}
301335
}
302336

303-
public bool TryDepositItem(Item item, bool sendUpdate = true) =>
304-
TryDepositItem(item, -1, item.Quantity, -1, sendUpdate);
337+
public bool TryDepositItem(Item item, bool sendUpdate = true, bool giveItem = false) =>
338+
TryDepositItem(
339+
slot: item,
340+
inventorySlotIndex: -1,
341+
quantityHint: item.Quantity,
342+
bankSlotIndex: -1,
343+
sendUpdate: sendUpdate,
344+
giveItem: giveItem
345+
);
305346

306-
public bool TryWithdrawItem(Item? slot, int bankSlotIndex, int quantityHint, int inventorySlotIndex = -1)
347+
public bool TryWithdrawItem(Item? slot, int bankSlotIndex, int quantityHint, int inventorySlotIndex = -1, bool takeItem = false)
307348
{
308349
//Permission Check
309350
if (_guild != null)

Intersect.Server.Core/Entities/IBankInterface.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,17 @@ public interface IBankInterface : IDisposable
77
void SendOpenBank();
88
void SendBankUpdate(int slot, bool sendToAll = true);
99
void SendCloseBank();
10-
bool TryDepositItem(Item slot, int inventorySlotIndex, int quantityHint, int bankSlotIndex = -1, bool sendUpdate = true);
11-
bool TryDepositItem(Item item, bool sendUpdate = true);
12-
bool TryWithdrawItem(Item slot, int bankSlotIndex, int quantityHint, int inventorySlotIndex = -1);
10+
11+
bool TryDepositItem(
12+
Item slot,
13+
int inventorySlotIndex,
14+
int quantityHint,
15+
int bankSlotIndex = -1,
16+
bool sendUpdate = true,
17+
bool giveItem = false
18+
);
19+
20+
bool TryDepositItem(Item item, bool sendUpdate = true, bool giveItem = false);
21+
bool TryWithdrawItem(Item slot, int bankSlotIndex, int quantityHint, int inventorySlotIndex = -1, bool takeItem = false);
1322
void SwapBankItems(int slotFrom, int slotTo);
1423
}

Intersect.Server.Core/Entities/Player.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2874,7 +2874,7 @@ public bool TryGiveItem(Item item, ItemHandling handler = ItemHandling.Normal, b
28742874
}
28752875

28762876
var bankInterface = new BankInterface<BankSlot>(this, Bank);
2877-
return bankOverflow && bankInterface.TryDepositItem(item, sendUpdate);
2877+
return bankOverflow && bankInterface.TryDepositItem(item: item, sendUpdate: sendUpdate, giveItem: true);
28782878
}
28792879

28802880
/// <summary>

Intersect.Server.Core/Localization/Strings.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,15 @@ public sealed partial class BankNamespace : LocaleNamespace
142142
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
143143
public readonly LocalizedString InvalidSlotToSwap = @"Invalid slots to swap!";
144144

145+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
146+
public readonly LocalizedString NotEnoughInInventory = @"There are not {00} of {01} in your inventory to deposit.";
147+
148+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
149+
public readonly LocalizedString NotEnoughBankSpaceForItem = @"There is not enough space in the bank to store {00} of {01}!";
150+
151+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
152+
public readonly LocalizedString NotEnoughBankSpaceForOneOfItem = @"There is not enough space in the bank to store a {00}!";
153+
145154
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
146155
public readonly LocalizedString WithdrawInvalid = @"Invalid item selected to withdraw!";
147156

Intersect.Server/Web/RestApi/Routes/V1/PlayerController.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,9 @@ public IActionResult ItemsGive(LookupKey lookupKey, [FromBody] ItemInfoRequestBo
416416
return BadRequest(lookupKey.IsIdInvalid ? @"Invalid player id." : @"Invalid player name.");
417417
}
418418

419-
if (ItemBase.Get(itemInfo.ItemId) == null)
419+
if (!ItemBase.TryGet(itemInfo.ItemId, out var descriptor))
420420
{
421-
return BadRequest(@"Invalid item id.");
421+
return NotFound($"No item found with ID '{itemInfo.ItemId}'");
422422
}
423423

424424
if (itemInfo.Quantity < 1)
@@ -433,7 +433,7 @@ public IActionResult ItemsGive(LookupKey lookupKey, [FromBody] ItemInfoRequestBo
433433

434434
if (!player.TryGiveItem(itemInfo.ItemId, itemInfo.Quantity, ItemHandling.Normal, itemInfo.BankOverflow, -1, true))
435435
{
436-
return InternalServerError($@"Failed to give player {itemInfo.Quantity} of '{itemInfo.ItemId}'.");
436+
return InternalServerError($@"Failed to give player {itemInfo.Quantity} of '{descriptor.Name}'.");
437437
}
438438

439439
using (var context = DbInterface.CreatePlayerContext(false))
@@ -475,9 +475,14 @@ public IActionResult ItemsTake(LookupKey lookupKey, [FromBody] ItemInfoRequestBo
475475
return NotFound($@"No player found for lookup key '{lookupKey}'");
476476
}
477477

478+
if (!ItemBase.TryGet(itemInfo.ItemId, out var descriptor))
479+
{
480+
return NotFound($"No item found with ID '{itemInfo.ItemId}'");
481+
}
482+
478483
if (!player.TryTakeItem(itemInfo.ItemId, itemInfo.Quantity))
479484
{
480-
return InternalServerError($@"Failed to take {itemInfo.Quantity} of '{itemInfo.ItemId}' from player.");
485+
return InternalServerError($@"Failed to take {itemInfo.Quantity} of '{descriptor.Name}' from player.");
481486
}
482487

483488
using (var context = DbInterface.CreatePlayerContext(false))

0 commit comments

Comments
 (0)