@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ge;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class GrandExchangeClient
|
||||
{
|
||||
private static final MediaType JSON = MediaType.parse("application/json");
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
|
||||
private final UUID uuid;
|
||||
|
||||
public void submit(GrandExchangeTrade grandExchangeTrade)
|
||||
{
|
||||
final HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||
.addPathSegment("ge")
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||
.post(RequestBody.create(JSON, GSON.toJson(grandExchangeTrade)))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.debug("unable to submit trade", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
log.debug("Submitted trade");
|
||||
response.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.api.ge;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GrandExchangeTrade
|
||||
{
|
||||
private boolean buy;
|
||||
private int itemId;
|
||||
private int quantity;
|
||||
private int price;
|
||||
private Instant time;
|
||||
}
|
||||
@@ -35,9 +35,9 @@ import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Slf4j
|
||||
public class GrandExchangeClient
|
||||
public class OSBGrandExchangeClient
|
||||
{
|
||||
public GrandExchangeResult lookupItem(int itemId) throws IOException
|
||||
public OSBGrandExchangeResult lookupItem(int itemId) throws IOException
|
||||
{
|
||||
final HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||
.addPathSegment("osb")
|
||||
@@ -59,7 +59,7 @@ public class GrandExchangeClient
|
||||
}
|
||||
|
||||
final InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), GrandExchangeResult.class);
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), OSBGrandExchangeResult.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
@@ -28,7 +28,7 @@ import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GrandExchangeResult
|
||||
public class OSBGrandExchangeResult
|
||||
{
|
||||
private int item_id;
|
||||
private int buy_average;
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import net.runelite.http.service.account.AuthFilter;
|
||||
import net.runelite.http.service.account.beans.SessionEntry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/ge")
|
||||
public class GrandExchangeController
|
||||
{
|
||||
private final GrandExchangeService grandExchangeService;
|
||||
private final AuthFilter authFilter;
|
||||
|
||||
@Autowired
|
||||
public GrandExchangeController(GrandExchangeService grandExchangeService, AuthFilter authFilter)
|
||||
{
|
||||
this.grandExchangeService = grandExchangeService;
|
||||
this.authFilter = authFilter;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public void submit(HttpServletRequest request, HttpServletResponse response, @RequestBody GrandExchangeTrade grandExchangeTrade) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
grandExchangeService.add(session.getUser(), grandExchangeTrade);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Collection<GrandExchangeTrade> get(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam(required = false, defaultValue = "1024") int limit,
|
||||
@RequestParam(required = false, defaultValue = "0") int offset) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return grandExchangeService.get(session.getUser(), limit, offset).stream()
|
||||
.map(GrandExchangeController::convert)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static GrandExchangeTrade convert(TradeEntry tradeEntry)
|
||||
{
|
||||
GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade();
|
||||
grandExchangeTrade.setBuy(tradeEntry.getAction() == TradeAction.BUY);
|
||||
grandExchangeTrade.setItemId(tradeEntry.getItem());
|
||||
grandExchangeTrade.setQuantity(tradeEntry.getQuantity());
|
||||
grandExchangeTrade.setPrice(tradeEntry.getPrice());
|
||||
grandExchangeTrade.setTime(tradeEntry.getTime());
|
||||
return grandExchangeTrade;
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
public void delete(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
SessionEntry session = authFilter.handle(request, response);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
grandExchangeService.delete(session.getUser());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import java.util.Collection;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@Service
|
||||
public class GrandExchangeService
|
||||
{
|
||||
private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS `ge_trades` (\n" +
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n" +
|
||||
" `user` int(11) NOT NULL,\n" +
|
||||
" `action` enum('BUY','SELL') NOT NULL,\n" +
|
||||
" `item` int(11) NOT NULL,\n" +
|
||||
" `quantity` int(11) NOT NULL,\n" +
|
||||
" `price` int(11) NOT NULL,\n" +
|
||||
" `time` timestamp NOT NULL DEFAULT current_timestamp(),\n" +
|
||||
" PRIMARY KEY (`id`),\n" +
|
||||
" KEY `user_time` (`user`, `time`),\n" +
|
||||
" KEY `time` (`time`),\n" +
|
||||
" CONSTRAINT `ge_trades_ibfk_1` FOREIGN KEY (`user`) REFERENCES `users` (`id`)\n" +
|
||||
") ENGINE=InnoDB;";
|
||||
|
||||
private final Sql2o sql2o;
|
||||
|
||||
@Autowired
|
||||
public GrandExchangeService(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
|
||||
// Ensure necessary tables exist
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery(CREATE_TABLE).executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(int userId, GrandExchangeTrade grandExchangeTrade)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("insert into ge_trades (user, action, item, quantity, price) values (:user," +
|
||||
" :action, :item, :quantity, :price)")
|
||||
.addParameter("user", userId)
|
||||
.addParameter("action", grandExchangeTrade.isBuy() ? "BUY" : "SELL")
|
||||
.addParameter("item", grandExchangeTrade.getItemId())
|
||||
.addParameter("quantity", grandExchangeTrade.getQuantity())
|
||||
.addParameter("price", grandExchangeTrade.getPrice())
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<TradeEntry> get(int userId, int limit, int offset)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
return con.createQuery("select id, user, action, item, quantity, price, time from ge_trades where user = :user limit :limit offset :offset")
|
||||
.addParameter("user", userId)
|
||||
.addParameter("limit", limit)
|
||||
.addParameter("offset", offset)
|
||||
.executeAndFetch(TradeEntry.class);
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(int userId)
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("delete from ge_trades where user = :user")
|
||||
.addParameter("user", userId)
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 60 * 60 * 1000)
|
||||
public void expire()
|
||||
{
|
||||
try (Connection con = sql2o.open())
|
||||
{
|
||||
con.createQuery("delete from ge_trades where time < current_timestamp - interval 1 month")
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
enum TradeAction
|
||||
{
|
||||
BUY,
|
||||
SELL;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.http.service.ge;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
class TradeEntry
|
||||
{
|
||||
private int id;
|
||||
private int user;
|
||||
private TradeAction action;
|
||||
private int item;
|
||||
private int quantity;
|
||||
private int price;
|
||||
private Instant time;
|
||||
}
|
||||
@@ -35,12 +35,12 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/osb/ge")
|
||||
public class GrandExchangeController
|
||||
public class OSBGrandExchangeController
|
||||
{
|
||||
private final GrandExchangeService grandExchangeService;
|
||||
private final OSBGrandExchangeService grandExchangeService;
|
||||
|
||||
@Autowired
|
||||
public GrandExchangeController(GrandExchangeService grandExchangeService)
|
||||
public OSBGrandExchangeController(OSBGrandExchangeService grandExchangeService)
|
||||
{
|
||||
this.grandExchangeService = grandExchangeService;
|
||||
}
|
||||
@@ -40,7 +40,7 @@ import org.sql2o.Sql2o;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class GrandExchangeService
|
||||
public class OSBGrandExchangeService
|
||||
{
|
||||
private static final String CREATE_GRAND_EXCHANGE_PRICES = "CREATE TABLE IF NOT EXISTS `osb_ge` (\n"
|
||||
+ " `item_id` int(11) NOT NULL,\n"
|
||||
@@ -56,7 +56,7 @@ public class GrandExchangeService
|
||||
private final Sql2o sql2o;
|
||||
|
||||
@Autowired
|
||||
public GrandExchangeService(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
||||
public OSBGrandExchangeService(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2017, Robbie <https://github.com/rbbi>
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* All rights reserved.
|
||||
@@ -46,6 +46,7 @@ import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GrandExchangeOffer;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
@@ -56,11 +57,15 @@ import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GrandExchangeOfferChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.SessionClose;
|
||||
import net.runelite.api.events.SessionOpen;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.account.AccountSession;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
@@ -73,8 +78,10 @@ import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.osbuddy.GrandExchangeClient;
|
||||
import net.runelite.http.api.osbuddy.GrandExchangeResult;
|
||||
import net.runelite.http.api.ge.GrandExchangeClient;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
|
||||
import net.runelite.http.api.osbuddy.OSBGrandExchangeResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Grand Exchange",
|
||||
@@ -86,7 +93,7 @@ public class GrandExchangePlugin extends Plugin
|
||||
{
|
||||
private static final int OFFER_CONTAINER_ITEM = 21;
|
||||
private static final int OFFER_DEFAULT_ITEM_ID = 6512;
|
||||
private static final GrandExchangeClient CLIENT = new GrandExchangeClient();
|
||||
private static final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient();
|
||||
private static final String OSB_GE_TEXT = "<br>OSBuddy Actively traded price: ";
|
||||
|
||||
private static final String BUY_LIMIT_GE_TEXT = "<br>Buy limit: ";
|
||||
@@ -134,10 +141,38 @@ public class GrandExchangePlugin extends Plugin
|
||||
@Inject
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
@Inject
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
private Widget grandExchangeText;
|
||||
private Widget grandExchangeItem;
|
||||
private Map<Integer, Integer> itemGELimits;
|
||||
|
||||
private GrandExchangeClient grandExchangeClient;
|
||||
|
||||
private SavedOffer getOffer(int slot)
|
||||
{
|
||||
String offer = configManager.getConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot));
|
||||
if (offer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return GSON.fromJson(offer, SavedOffer.class);
|
||||
}
|
||||
|
||||
private void setOffer(int slot, SavedOffer offer)
|
||||
{
|
||||
configManager.setConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot), GSON.toJson(offer));
|
||||
}
|
||||
|
||||
private void deleteOffer(int slot)
|
||||
{
|
||||
configManager.unsetConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot));
|
||||
}
|
||||
|
||||
@Provides
|
||||
GrandExchangeConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -167,6 +202,12 @@ public class GrandExchangePlugin extends Plugin
|
||||
mouseManager.registerMouseListener(inputListener);
|
||||
keyManager.registerKeyListener(inputListener);
|
||||
}
|
||||
|
||||
AccountSession accountSession = sessionManager.getAccountSession();
|
||||
if (accountSession != null)
|
||||
{
|
||||
grandExchangeClient = new GrandExchangeClient(accountSession.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,6 +219,27 @@ public class GrandExchangePlugin extends Plugin
|
||||
grandExchangeText = null;
|
||||
grandExchangeItem = null;
|
||||
itemGELimits = null;
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionOpen(SessionOpen sessionOpen)
|
||||
{
|
||||
AccountSession accountSession = sessionManager.getAccountSession();
|
||||
if (accountSession.getUuid() != null)
|
||||
{
|
||||
grandExchangeClient = new GrandExchangeClient(accountSession.getUuid());
|
||||
}
|
||||
else
|
||||
{
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionClose(SessionClose sessionClose)
|
||||
{
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -204,11 +266,79 @@ public class GrandExchangePlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent)
|
||||
{
|
||||
GrandExchangeOffer offer = offerEvent.getOffer();
|
||||
final int slot = offerEvent.getSlot();
|
||||
final GrandExchangeOffer offer = offerEvent.getOffer();
|
||||
|
||||
ItemComposition offerItem = itemManager.getItemComposition(offer.getItemId());
|
||||
boolean shouldStack = offerItem.isStackable() || offer.getTotalQuantity() > 1;
|
||||
BufferedImage itemImage = itemManager.getImage(offer.getItemId(), offer.getTotalQuantity(), shouldStack);
|
||||
SwingUtilities.invokeLater(() -> panel.getOffersPanel().updateOffer(offerItem, itemImage, offerEvent.getOffer(), offerEvent.getSlot()));
|
||||
SwingUtilities.invokeLater(() -> panel.getOffersPanel().updateOffer(offerItem, itemImage, offer, slot));
|
||||
|
||||
submitTrades(slot, offer);
|
||||
|
||||
updateConfig(slot, offer);
|
||||
}
|
||||
|
||||
private void submitTrades(int slot, GrandExchangeOffer offer)
|
||||
{
|
||||
if (grandExchangeClient == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only interested in offers which are fully bought/sold
|
||||
if (offer.getState() != GrandExchangeOfferState.BOUGHT && offer.getState() != GrandExchangeOfferState.SOLD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SavedOffer savedOffer = getOffer(slot);
|
||||
if (!shouldUpdate(savedOffer, offer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// getPrice() is the price of the offer, not necessarily what the item bought at
|
||||
int priceEach = offer.getSpent() / offer.getTotalQuantity();
|
||||
|
||||
GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade();
|
||||
grandExchangeTrade.setBuy(offer.getState() == GrandExchangeOfferState.BOUGHT);
|
||||
grandExchangeTrade.setItemId(offer.getItemId());
|
||||
grandExchangeTrade.setQuantity(offer.getTotalQuantity());
|
||||
grandExchangeTrade.setPrice(priceEach);
|
||||
|
||||
log.debug("Submitting trade: {}", grandExchangeTrade);
|
||||
grandExchangeClient.submit(grandExchangeTrade);
|
||||
}
|
||||
|
||||
private void updateConfig(int slot, GrandExchangeOffer offer)
|
||||
{
|
||||
if (offer.getState() == GrandExchangeOfferState.EMPTY)
|
||||
{
|
||||
deleteOffer(slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(offer.getItemId());
|
||||
savedOffer.setQuantitySold(offer.getQuantitySold());
|
||||
savedOffer.setTotalQuantity(offer.getTotalQuantity());
|
||||
savedOffer.setPrice(offer.getPrice());
|
||||
savedOffer.setSpent(offer.getSpent());
|
||||
savedOffer.setState(offer.getState());
|
||||
setOffer(slot, savedOffer);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -346,7 +476,7 @@ public class GrandExchangePlugin extends Plugin
|
||||
|
||||
try
|
||||
{
|
||||
final GrandExchangeResult result = CLIENT.lookupItem(itemId);
|
||||
final OSBGrandExchangeResult result = CLIENT.lookupItem(itemId);
|
||||
final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(result.getOverall_average());
|
||||
geText.setText(text);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.grandexchange;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
|
||||
@Data
|
||||
class SavedOffer
|
||||
{
|
||||
private int itemId;
|
||||
private int quantitySold;
|
||||
private int totalQuantity;
|
||||
private int price;
|
||||
private int spent;
|
||||
private GrandExchangeOfferState state;
|
||||
}
|
||||
Reference in New Issue
Block a user