ge plugin: submit partially completed trades
This commit is contained in:
@@ -30,7 +30,10 @@ import lombok.Data;
|
||||
public class GrandExchangeTrade
|
||||
{
|
||||
private boolean buy;
|
||||
private boolean cancel;
|
||||
private int itemId;
|
||||
private int quantity;
|
||||
private int total;
|
||||
private int price;
|
||||
private int offer;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import net.runelite.http.service.account.AuthFilter;
|
||||
import net.runelite.http.service.account.beans.SessionEntry;
|
||||
@@ -58,14 +59,23 @@ public class GrandExchangeController
|
||||
@PostMapping
|
||||
public void submit(HttpServletRequest request, HttpServletResponse response, @RequestBody GrandExchangeTrade grandExchangeTrade) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
SessionEntry session = null;
|
||||
if (request.getHeader(RuneLiteAPI.RUNELITE_AUTH) != null)
|
||||
{
|
||||
return;
|
||||
session = authFilter.handle(request, response);
|
||||
if (session == null)
|
||||
{
|
||||
// error is set here on the response, so we shouldn't continue
|
||||
return;
|
||||
}
|
||||
}
|
||||
Integer userId = session == null ? null : session.getUser();
|
||||
|
||||
grandExchangeService.add(session.getUser(), grandExchangeTrade);
|
||||
// We don't keep track of pending trades in the web UI, so only add cancelled or completed trades
|
||||
if (userId != null && (grandExchangeTrade.isCancel() || grandExchangeTrade.getQuantity() == grandExchangeTrade.getTotal()))
|
||||
{
|
||||
grandExchangeService.add(userId, grandExchangeTrade);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
|
||||
@@ -371,39 +371,88 @@ public class GrandExchangePlugin extends Plugin
|
||||
BufferedImage itemImage = itemManager.getImage(offer.getItemId(), offer.getTotalQuantity(), shouldStack);
|
||||
SwingUtilities.invokeLater(() -> panel.getOffersPanel().updateOffer(offerItem, itemImage, offer, slot));
|
||||
|
||||
submitTrades(slot, offer);
|
||||
submitTrade(slot, offer);
|
||||
|
||||
updateConfig(slot, offer);
|
||||
}
|
||||
|
||||
private void submitTrades(int slot, GrandExchangeOffer offer)
|
||||
@VisibleForTesting
|
||||
void submitTrade(int slot, GrandExchangeOffer offer)
|
||||
{
|
||||
if (offer.getState() != GrandExchangeOfferState.BOUGHT && offer.getState() != GrandExchangeOfferState.SOLD &&
|
||||
offer.getState() != GrandExchangeOfferState.CANCELLED_BUY && offer.getState() != GrandExchangeOfferState.CANCELLED_SELL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GrandExchangeOfferState state = offer.getState();
|
||||
|
||||
// Cancelled offers may have been cancelled before buying/selling any items
|
||||
if (offer.getQuantitySold() == 0)
|
||||
if (state != GrandExchangeOfferState.CANCELLED_BUY && state != GrandExchangeOfferState.CANCELLED_SELL && state != GrandExchangeOfferState.BUYING && state != GrandExchangeOfferState.SELLING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SavedOffer savedOffer = getOffer(slot);
|
||||
if (!shouldUpdate(savedOffer, offer))
|
||||
if (savedOffer == null && (state == GrandExchangeOfferState.BUYING || state == GrandExchangeOfferState.SELLING) && offer.getQuantitySold() == 0)
|
||||
{
|
||||
// new offer
|
||||
GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade();
|
||||
grandExchangeTrade.setBuy(state == GrandExchangeOfferState.BUYING);
|
||||
grandExchangeTrade.setItemId(offer.getItemId());
|
||||
grandExchangeTrade.setQuantity(0);
|
||||
grandExchangeTrade.setTotal(offer.getTotalQuantity());
|
||||
grandExchangeTrade.setPrice(0);
|
||||
grandExchangeTrade.setOffer(offer.getPrice());
|
||||
|
||||
log.debug("Submitting new trade: {}", grandExchangeTrade);
|
||||
grandExchangeClient.submit(grandExchangeTrade);
|
||||
return;
|
||||
}
|
||||
|
||||
if (savedOffer == null || savedOffer.getItemId() != offer.getItemId() || savedOffer.getPrice() != offer.getPrice() || savedOffer.getTotalQuantity() != offer.getTotalQuantity())
|
||||
{
|
||||
// desync
|
||||
return;
|
||||
}
|
||||
|
||||
if (savedOffer.getState() == offer.getState() && savedOffer.getQuantitySold() == offer.getQuantitySold())
|
||||
{
|
||||
// no change
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == GrandExchangeOfferState.CANCELLED_BUY || state == GrandExchangeOfferState.CANCELLED_SELL)
|
||||
{
|
||||
GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade();
|
||||
grandExchangeTrade.setBuy(state == GrandExchangeOfferState.CANCELLED_BUY);
|
||||
grandExchangeTrade.setCancel(true);
|
||||
grandExchangeTrade.setItemId(offer.getItemId());
|
||||
grandExchangeTrade.setQuantity(offer.getQuantitySold());
|
||||
grandExchangeTrade.setTotal(offer.getTotalQuantity());
|
||||
grandExchangeTrade.setPrice(offer.getQuantitySold() > 0 ? offer.getSpent() / offer.getQuantitySold() : 0);
|
||||
grandExchangeTrade.setOffer(offer.getPrice());
|
||||
|
||||
log.debug("Submitting cancelled: {}", grandExchangeTrade);
|
||||
grandExchangeClient.submit(grandExchangeTrade);
|
||||
return;
|
||||
}
|
||||
|
||||
final int qty = offer.getQuantitySold() - savedOffer.getQuantitySold();
|
||||
if (qty <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// getPrice() is the price of the offer, not necessarily what the item bought at
|
||||
int priceEach = offer.getSpent() / offer.getQuantitySold();
|
||||
// offer.getPrice() is the price of the offer, not necessarily what the item bought at, so we compute it
|
||||
// based on how much was spent & the qty
|
||||
final int dspent = offer.getSpent() - savedOffer.getSpent();
|
||||
final int price = dspent / qty;
|
||||
if (price <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade();
|
||||
grandExchangeTrade.setBuy(offer.getState() == GrandExchangeOfferState.BOUGHT || offer.getState() == GrandExchangeOfferState.CANCELLED_BUY);
|
||||
grandExchangeTrade.setBuy(state == GrandExchangeOfferState.BUYING);
|
||||
grandExchangeTrade.setItemId(offer.getItemId());
|
||||
grandExchangeTrade.setQuantity(offer.getQuantitySold());
|
||||
grandExchangeTrade.setPrice(priceEach);
|
||||
grandExchangeTrade.setQuantity(qty);
|
||||
grandExchangeTrade.setTotal(offer.getTotalQuantity());
|
||||
grandExchangeTrade.setPrice(price);
|
||||
grandExchangeTrade.setOffer(offer.getPrice());
|
||||
|
||||
log.debug("Submitting trade: {}", grandExchangeTrade);
|
||||
grandExchangeClient.submit(grandExchangeTrade);
|
||||
@@ -430,17 +479,6 @@ public class GrandExchangePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldUpdate(SavedOffer savedOffer, GrandExchangeOffer grandExchangeOffer)
|
||||
{
|
||||
if (savedOffer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only update offer if state has changed
|
||||
return savedOffer.getState() != grandExchangeOffer.getState();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
|
||||
@@ -24,14 +24,100 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.grandexchange;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GrandExchangeOffer;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import static net.runelite.client.plugins.grandexchange.GrandExchangePlugin.findFuzzyIndices;
|
||||
import static net.runelite.http.api.RuneLiteAPI.GSON;
|
||||
import net.runelite.http.api.ge.GrandExchangeClient;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GrandExchangePluginTest
|
||||
{
|
||||
@Inject
|
||||
private GrandExchangePlugin grandExchangePlugin;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private GrandExchangeConfig grandExchangeConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Notifier notifier;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private MouseManager mouseManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private GrandExchangeClient grandExchangeClient;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private RuneLiteConfig runeLiteConfig;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
when(client.getUsername()).thenReturn("adam");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindFuzzyIndices()
|
||||
{
|
||||
@@ -39,4 +125,94 @@ public class GrandExchangePluginTest
|
||||
// r<u>ob</u>e <u>b</u>ottom
|
||||
assertEquals(Arrays.asList(11, 12, 15), fuzzyIndices);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmitTrade()
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
|
||||
savedOffer.setQuantitySold(1);
|
||||
savedOffer.setTotalQuantity(10);
|
||||
savedOffer.setPrice(1000);
|
||||
savedOffer.setSpent(25);
|
||||
savedOffer.setState(GrandExchangeOfferState.BUYING);
|
||||
when(configManager.getConfiguration("geoffer.adam", "0")).thenReturn(GSON.toJson(savedOffer));
|
||||
|
||||
// buy 2 @ 10/ea
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(1 + 2);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
when(grandExchangeOffer.getSpent()).thenReturn(25 + 10 * 2);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.BUYING);
|
||||
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
|
||||
|
||||
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
|
||||
verify(grandExchangeClient).submit(captor.capture());
|
||||
|
||||
GrandExchangeTrade trade = captor.getValue();
|
||||
assertTrue(trade.isBuy());
|
||||
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
|
||||
assertEquals(2, trade.getQuantity());
|
||||
assertEquals(10, trade.getTotal());
|
||||
assertEquals(10, trade.getPrice());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateTrade()
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
|
||||
savedOffer.setQuantitySold(1);
|
||||
savedOffer.setTotalQuantity(10);
|
||||
savedOffer.setPrice(1000);
|
||||
savedOffer.setSpent(25);
|
||||
savedOffer.setState(GrandExchangeOfferState.BUYING);
|
||||
when(configManager.getConfiguration("geoffer.adam", "0")).thenReturn(GSON.toJson(savedOffer));
|
||||
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
lenient().when(grandExchangeOffer.getSpent()).thenReturn(25);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.BUYING);
|
||||
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
|
||||
|
||||
verify(grandExchangeClient, never()).submit(any(GrandExchangeTrade.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelTrade()
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
|
||||
savedOffer.setQuantitySold(1);
|
||||
savedOffer.setTotalQuantity(10);
|
||||
savedOffer.setPrice(1000);
|
||||
savedOffer.setSpent(25);
|
||||
savedOffer.setState(GrandExchangeOfferState.BUYING);
|
||||
when(configManager.getConfiguration("geoffer.adam", "0")).thenReturn(GSON.toJson(savedOffer));
|
||||
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
when(grandExchangeOffer.getSpent()).thenReturn(25);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.CANCELLED_BUY);
|
||||
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
|
||||
|
||||
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
|
||||
verify(grandExchangeClient).submit(captor.capture());
|
||||
|
||||
GrandExchangeTrade trade = captor.getValue();
|
||||
assertTrue(trade.isBuy());
|
||||
assertTrue(trade.isCancel());
|
||||
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
|
||||
assertEquals(1, trade.getQuantity());
|
||||
assertEquals(10, trade.getTotal());
|
||||
assertEquals(25, trade.getPrice());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user