Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Source/ACE.Server/WorldObjects/Player_Inventory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2541,6 +2541,15 @@ public void HandleActionStackableSplitTo3D(uint stackId, int amount)
return;
}

// We make sure the stack is still valid. It could have changed during our pickup animation
if (FindObject(stack.Guid, SearchLocations.MyInventory | SearchLocations.MyEquippedItems, out stackFoundInContainer, out stackRootOwner, out _) != stack || stack.StackSize <= amount)
{
log.DebugFormat("Player 0x{0:X8}:{1} tried to split an item that's no longer valid 0x{2:X8}:{3}.", Guid.Full, Name, stack.Guid.Full, stack.Name);
Session.Network.EnqueueSend(new GameEventCommunicationTransientString(Session, "Split failed!")); // Custom error message
Session.Network.EnqueueSend(new GameEventInventoryServerSaveFailed(Session, stackId, WeenieError.ActionCancelled));
return;
}

if (!AdjustStack(stack, -amount, stackFoundInContainer, stackRootOwner))
{
Session.Network.EnqueueSend(new GameEventInventoryServerSaveFailed(Session, stackId, WeenieError.ActionCancelled));
Expand Down Expand Up @@ -3249,6 +3258,15 @@ public void HandleActionGiveObjectRequest(uint targetGuid, uint itemGuid, int am
return;
}

// We make sure the item is still valid. It could have changed during our movement
if (FindObject(item.Guid, SearchLocations.MyInventory | SearchLocations.MyEquippedItems, out itemFoundInContainer, out itemRootOwner, out itemWasEquipped) != item || item.StackSize < amount)
{
log.DebugFormat("Player 0x{0:X8}:{1} tried to give an item that's no longer valid 0x{2:X8}:{3}.", Guid.Full, Name, item.Guid.Full, item.Name);
Session.Network.EnqueueSend(new GameEventCommunicationTransientString(Session, "Give failed!")); // Custom error message
Session.Network.EnqueueSend(new GameEventInventoryServerSaveFailed(Session, itemGuid, WeenieError.ActionCancelled));
return;
}

if (target is Player targetAsPlayer)
GiveObjectToPlayer(targetAsPlayer, item, itemFoundInContainer, itemRootOwner, itemWasEquipped, amount);
else
Expand Down
10 changes: 8 additions & 2 deletions Source/ACE.Server/WorldObjects/Player_Trade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,16 @@ private void FinalizeTrade(Player target)
actionChain.AddAction(CurrentLandblock, () =>
{
foreach (var wo in myEscrow)
TryCreateInInventoryWithNetworking(wo);
{
if (!TryCreateInInventoryWithNetworking(wo) && !target.TryCreateInInventoryWithNetworking(wo))
log.WarnFormat("Item 0x{0:X8}:{1} for player {2} lost from FinalizeTrade failure.", wo.Guid.Full, wo.Name, target.Name);
}

foreach (var wo in targetEscrow)
target.TryCreateInInventoryWithNetworking(wo);
{
if (!target.TryCreateInInventoryWithNetworking(wo) && !TryCreateInInventoryWithNetworking(wo))
log.WarnFormat("Item 0x{0:X8}:{1} for player {2} lost from FinalizeTrade failure.", wo.Guid.Full, wo.Name, Name);
}

Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.TradeComplete));
target.Session.Network.EnqueueSend(new GameEventWeenieError(target.Session, WeenieError.TradeComplete));
Expand Down
16 changes: 16 additions & 0 deletions Source/ACE.Server/WorldObjects/Vendor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ public bool BuyItems_ValidateTransaction(List<ItemProfile> itemProfiles, Player
var defaultItemProfiles = new List<ItemProfile>();
var uniqueItems = new List<WorldObject>();

var requestedGuids = new HashSet<uint>();

// find item profiles in default and unique items
foreach (var itemProfile in itemProfiles)
{
Expand All @@ -450,11 +452,25 @@ public bool BuyItems_ValidateTransaction(List<ItemProfile> itemProfiles, Player
return false;
}

if (!requestedGuids.Add(itemProfile.ObjectGuid))
{
log.Warn($"[VENDOR] {player.Name} tried to buy duplicate item {itemProfile.ObjectGuid:X8} from {Name}");
player.SendTransientError($"Invalid item");
return false;
}

var itemGuid = new ObjectGuid(itemProfile.ObjectGuid);

// check default items
if (DefaultItemsForSale.TryGetValue(itemGuid, out var defaultItemForSale))
{
// services are not limited by pack space, so only allow one per request
if (itemProfile.Amount > 1 && (defaultItemForSale.GetProperty(PropertyBool.VendorService) ?? false))
{
player.SendTransientError($"Invalid amount");
return false;
}

itemProfile.WeenieClassId = defaultItemForSale.WeenieClassId;
itemProfile.Palette = defaultItemForSale.PaletteTemplate;
itemProfile.Shade = defaultItemForSale.Shade;
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ services:
volumes:
- ./db-data:/var/lib/mysql
ports:
- "3306:3306/tcp"
- "127.0.0.1:3306:3306/tcp"
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
Expand Down