You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
fix(marketplace): avoid inventory desync on failed offer insert
Expose whether a marketplace offer was persisted before mutating inventory state, refuse sells whose database insert failed, and synchronize the sold timestamp into the online seller's in-memory offer when present. This keeps failed or racing marketplace operations from desynchronizing credits/items.
This commit is contained in:
+12
-2
@@ -279,8 +279,9 @@ public class MarketPlace {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int soldTimestamp = Emulator.getIntUnixTimestamp();
|
||||||
try (PreparedStatement updateOffer = connection.prepareStatement("UPDATE marketplace_items SET state = 2, sold_timestamp = ? WHERE id = ? AND state = 1")) {
|
try (PreparedStatement updateOffer = connection.prepareStatement("UPDATE marketplace_items SET state = 2, sold_timestamp = ? WHERE id = ? AND state = 1")) {
|
||||||
updateOffer.setInt(1, Emulator.getIntUnixTimestamp());
|
updateOffer.setInt(1, soldTimestamp);
|
||||||
updateOffer.setInt(2, offerId);
|
updateOffer.setInt(2, offerId);
|
||||||
int updated = updateOffer.executeUpdate();
|
int updated = updateOffer.executeUpdate();
|
||||||
if (updated == 0) {
|
if (updated == 0) {
|
||||||
@@ -307,7 +308,11 @@ public class MarketPlace {
|
|||||||
client.sendResponse(new MarketplaceBuyErrorComposer(MarketplaceBuyErrorComposer.REFRESH, 0, offerId, price));
|
client.sendResponse(new MarketplaceBuyErrorComposer(MarketplaceBuyErrorComposer.REFRESH, 0, offerId, price));
|
||||||
|
|
||||||
if (habbo != null) {
|
if (habbo != null) {
|
||||||
habbo.getInventory().getOffer(offerId).setState(MarketPlaceState.SOLD);
|
MarketPlaceOffer offer = habbo.getInventory().getOffer(offerId);
|
||||||
|
if (offer != null) {
|
||||||
|
offer.setState(MarketPlaceState.SOLD);
|
||||||
|
offer.setSoldTimestamp(soldTimestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,6 +374,11 @@ public class MarketPlace {
|
|||||||
event.item.setFromGift(false);
|
event.item.setFromGift(false);
|
||||||
|
|
||||||
MarketPlaceOffer offer = new MarketPlaceOffer(event.item, event.price, client.getHabbo());
|
MarketPlaceOffer offer = new MarketPlaceOffer(event.item, event.price, client.getHabbo());
|
||||||
|
if (!offer.isPersisted()) {
|
||||||
|
LOGGER.warn("Marketplace offer insert failed for user {} item {}", client.getHabbo().getHabboInfo().getId(), event.item.getId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
client.getHabbo().getInventory().addMarketplaceOffer(offer);
|
client.getHabbo().getInventory().addMarketplaceOffer(offer);
|
||||||
client.getHabbo().getInventory().getItemsComponent().removeHabboItem(event.item);
|
client.getHabbo().getInventory().getItemsComponent().removeHabboItem(event.item);
|
||||||
item.setUserId(-1);
|
item.setUserId(-1);
|
||||||
|
|||||||
+4
@@ -98,6 +98,10 @@ public class MarketPlaceOffer implements Runnable {
|
|||||||
return this.offerId;
|
return this.offerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPersisted() {
|
||||||
|
return this.offerId > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public void setOfferId(int offerId) {
|
public void setOfferId(int offerId) {
|
||||||
this.offerId = offerId;
|
this.offerId = offerId;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package com.eu.habbo.habbohotel.catalog.marketplace;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
|
||||||
|
class MarketPlaceOfferContractTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void exposesPersistenceState() {
|
||||||
|
assertDoesNotThrow(() -> MarketPlaceOffer.class.getDeclaredMethod("isPersisted"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user