diff --git a/http-api/src/main/java/net/runelite/http/api/item/Item.java b/http-api/src/main/java/net/runelite/http/api/item/Item.java new file mode 100644 index 0000000000..6ec885d11c --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/item/Item.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017, Adam + * 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.item; + +public class Item +{ + private int id; + private String name; + private String description; + private ItemType type; + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public ItemType getType() + { + return type; + } + + public void setType(ItemType type) + { + this.type = type; + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemType.java b/http-api/src/main/java/net/runelite/http/api/item/ItemType.java new file mode 100644 index 0000000000..b1d38a06a2 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemType.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017, Adam + * 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.item; + +public enum ItemType +{ + DEFAULT +} diff --git a/http-service/src/main/java/net/runelite/http/service/JsonTransformer.java b/http-service/src/main/java/net/runelite/http/service/JsonTransformer.java index d6abb61459..b78c1c3d25 100644 --- a/http-service/src/main/java/net/runelite/http/service/JsonTransformer.java +++ b/http-service/src/main/java/net/runelite/http/service/JsonTransformer.java @@ -34,6 +34,13 @@ public class JsonTransformer implements ResponseTransformer @Override public String render(Object model) throws Exception { + if (model == null) + { + // gson turns a null object into "null" which + // causes spark to return http 200 instead of 404 + return null; + } + return gson.toJson(model); } } diff --git a/http-service/src/main/java/net/runelite/http/service/Service.java b/http-service/src/main/java/net/runelite/http/service/Service.java index 0190fc747f..472c28baa3 100644 --- a/http-service/src/main/java/net/runelite/http/service/Service.java +++ b/http-service/src/main/java/net/runelite/http/service/Service.java @@ -31,6 +31,7 @@ import net.runelite.http.service.account.AccountService; import net.runelite.http.service.account.AuthFilter; import net.runelite.http.service.config.ConfigService; import net.runelite.http.service.hiscore.HiscoreService; +import net.runelite.http.service.item.ItemService; import net.runelite.http.service.updatecheck.UpdateCheckService; import net.runelite.http.service.worlds.WorldsService; import net.runelite.http.service.xtea.XteaService; @@ -57,6 +58,9 @@ public class Service implements SparkApplication @Inject private HiscoreService hiscores; + @Inject + private ItemService item; + @Inject private UpdateCheckService updateCheck; @@ -78,6 +82,7 @@ public class Service implements SparkApplication xtea.init(); accounts.init(); config.init(); + item.init(); get("/version", (request, response) -> RuneliteAPI.getVersion()); get("/update-check", updateCheck::check, transformer); @@ -106,6 +111,12 @@ public class Service implements SparkApplication put("/:key", config::setKey); delete("/:key", config::unsetKey); }); + path("/item", () -> + { + get("/:id", item::getItem, transformer); + get("/:id/icon", item::getIcon); + get("/:id/icon_large", item::getIconLarge); + }); exception(Exception.class, (exception, request, response) -> logger.warn(null, exception)); } diff --git a/http-service/src/main/java/net/runelite/http/service/ServiceModule.java b/http-service/src/main/java/net/runelite/http/service/ServiceModule.java index 73bc1d3e1f..1d3ec9580d 100644 --- a/http-service/src/main/java/net/runelite/http/service/ServiceModule.java +++ b/http-service/src/main/java/net/runelite/http/service/ServiceModule.java @@ -38,6 +38,7 @@ import net.runelite.http.service.account.AccountService; import net.runelite.http.service.account.AuthFilter; import net.runelite.http.service.config.ConfigService; import net.runelite.http.service.hiscore.HiscoreService; +import net.runelite.http.service.item.ItemService; import net.runelite.http.service.updatecheck.UpdateCheckService; import net.runelite.http.service.worlds.WorldsService; import net.runelite.http.service.xtea.XteaService; @@ -121,6 +122,7 @@ public class ServiceModule extends AbstractModule bind(AccountService.class); bind(ConfigService.class); bind(HiscoreService.class); + bind(ItemService.class); bind(UpdateCheckService.class); bind(WorldsService.class); bind(XteaService.class); diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java index 5f265343e8..ec8a0685fa 100644 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java +++ b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java @@ -45,11 +45,12 @@ public class HiscoreService public HiscoreResult lookup(String username) throws IOException, URISyntaxException { - HttpUrl.Builder builder = url.newBuilder() - .addQueryParameter("player", username); + HttpUrl hiscoreUrl = url.newBuilder() + .addQueryParameter("player", username) + .build(); Request request = new Request.Builder() - .url(builder.build()) + .url(hiscoreUrl) .build(); Response response = RuneliteAPI.CLIENT.newCall(request).execute(); diff --git a/http-service/src/main/java/net/runelite/http/service/item/ItemEntry.java b/http-service/src/main/java/net/runelite/http/service/item/ItemEntry.java new file mode 100644 index 0000000000..f7edafede9 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/item/ItemEntry.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2017, Adam + * 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.item; + +import java.time.Instant; +import net.runelite.http.api.item.Item; +import net.runelite.http.api.item.ItemType; + +public class ItemEntry +{ + private int id; + private String name; + private String description; + private ItemType type; + private byte[] icon; + private byte[] icon_large; + private Instant timestamp; + + public Item toItem() + { + Item item = new Item(); + item.setId(id); + item.setName(name); + item.setDescription(description); + item.setType(type); + return item; + } + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public ItemType getType() + { + return type; + } + + public void setType(ItemType type) + { + this.type = type; + } + + public byte[] getIcon() + { + return icon; + } + + public void setIcon(byte[] icon) + { + this.icon = icon; + } + + public byte[] getIcon_large() + { + return icon_large; + } + + public void setIcon_large(byte[] icon_large) + { + this.icon_large = icon_large; + } + + public Instant getTimestamp() + { + return timestamp; + } + + public void setTimestamp(Instant timestamp) + { + this.timestamp = timestamp; + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java new file mode 100644 index 0000000000..099675d699 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2017, Adam + * 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.item; + +import com.google.gson.JsonParseException; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import net.runelite.http.api.RuneliteAPI; +import net.runelite.http.api.item.Item; +import net.runelite.http.api.item.ItemType; +import okhttp3.HttpUrl; +import okhttp3.ResponseBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sql2o.Connection; +import org.sql2o.Sql2o; +import spark.Request; +import spark.Response; + +public class ItemService +{ + private static final Logger logger = LoggerFactory.getLogger(ItemService.class); + + private static final HttpUrl RS_ITEM_URL = HttpUrl.parse("http://services.runescape.com/m=itemdb_oldschool/api/catalogue/detail.json"); + + private static final String CREATE_ITEMS = "CREATE TABLE IF NOT EXISTS `items` (\n" + + " `id` int(11) NOT NULL,\n" + + " `name` tinytext NOT NULL,\n" + + " `description` tinytext NOT NULL,\n" + + " `type` enum('DEFAULT') NOT NULL,\n" + + " `icon` blob NOT NULL,\n" + + " `icon_large` blob NOT NULL,\n" + + " `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n" + + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB"; + + private static final String RUNELITE_ITEM_CACHE = "Runelite-Item-Cache"; + + private final Sql2o sql2o; + + @Inject + public ItemService(@Named("Runelite SQL2O") Sql2o sql2o) + { + this.sql2o = sql2o; + } + + public void init() + { + try (Connection con = sql2o.open()) + { + con.createQuery(CREATE_ITEMS) + .executeUpdate(); + } + } + + public Item getItem(Request request, Response response) + { + int itemId = Integer.parseInt(request.params("id")); + + ItemEntry item = get(itemId); + if (item != null) + { + response.header(RUNELITE_ITEM_CACHE, "HIT"); + return item.toItem(); + } + + item = fetch(itemId); + if (item != null) + { + response.header(RUNELITE_ITEM_CACHE, "MISS"); + return item.toItem(); + } + + return null; + } + + public byte[] getIcon(Request request, Response response) + { + int itemId = Integer.parseInt(request.params("id")); + + ItemEntry item = get(itemId); + if (item != null) + { + response.type("image/gif"); + response.header(RUNELITE_ITEM_CACHE, "HIT"); + return item.getIcon(); + } + + item = fetch(itemId); + if (item != null) + { + response.type("image/gif"); + response.header(RUNELITE_ITEM_CACHE, "MISS"); + return item.getIcon(); + } + + return null; + } + + public byte[] getIconLarge(Request request, Response response) + { + int itemId = Integer.parseInt(request.params("id")); + + ItemEntry item = get(itemId); + if (item != null) + { + response.type("image/gif"); + response.header(RUNELITE_ITEM_CACHE, "HIT"); + return item.getIcon_large(); + } + + item = fetch(itemId); + if (item != null) + { + response.type("image/gif"); + response.header(RUNELITE_ITEM_CACHE, "MISS"); + return item.getIcon_large(); + } + + return null; + } + + private ItemEntry get(int itemId) + { + try (Connection con = sql2o.open()) + { + ItemEntry item = con.createQuery("select id, name, description, type, icon, icon_large from items where id = :id") + .addParameter("id", itemId) + .executeAndFetchFirst(ItemEntry.class); + + return item; + } + } + + private ItemEntry fetch(int itemId) + { + try + { + RSItem rsItem = fetchItem(itemId); + byte[] icon = fetchImage(rsItem.getIcon()); + byte[] iconLarge = fetchImage(rsItem.getIcon_large()); + + try (Connection con = sql2o.open()) + { + con.createQuery("insert into items (id, name, description, type, icon, icon_large) values (:id," + + " :name, :description, :type, :icon, :icon_large)") + .addParameter("id", itemId) + .addParameter("name", rsItem.getName()) + .addParameter("description", rsItem.getDescription()) + .addParameter("type", rsItem.getType()) + .addParameter("icon", icon) + .addParameter("icon_large", iconLarge) + .executeUpdate(); + } + + ItemEntry item = new ItemEntry(); + item.setId(itemId); + item.setName(rsItem.getName()); + item.setDescription(rsItem.getDescription()); + + try + { + item.setType(ItemType.valueOf(rsItem.getType().toUpperCase())); + } + catch (IllegalArgumentException ex) + { + logger.warn(null, ex); + } + + item.setIcon(icon); + item.setIcon_large(iconLarge); + return item; + } + catch (IOException ex) + { + logger.warn("unable to fetch item {}", itemId, ex); + return null; + } + } + + private RSItem fetchItem(int itemId) throws IOException + { + HttpUrl itemUrl = RS_ITEM_URL + .newBuilder() + .addQueryParameter("item", "" + itemId) + .build(); + + okhttp3.Request request = new okhttp3.Request.Builder() + .url(itemUrl) + .build(); + + okhttp3.Response response = RuneliteAPI.CLIENT.newCall(request).execute(); + + try (ResponseBody body = response.body()) + { + InputStream in = body.byteStream(); + RSItemResponse itemResponse = RuneliteAPI.GSON.fromJson(new InputStreamReader(in), RSItemResponse.class); + return itemResponse.getItem(); + } + catch (JsonParseException ex) + { + throw new IOException(ex); + } + } + + private byte[] fetchImage(String url) throws IOException + { + HttpUrl httpUrl = HttpUrl.parse(url); + + okhttp3.Request request = new okhttp3.Request.Builder() + .url(httpUrl) + .build(); + + okhttp3.Response response = RuneliteAPI.CLIENT.newCall(request).execute(); + + try (ResponseBody body = response.body()) + { + return body.bytes(); + } + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/item/RSItem.java b/http-service/src/main/java/net/runelite/http/service/item/RSItem.java new file mode 100644 index 0000000000..90ba053786 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/item/RSItem.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017, Adam + * 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.item; + +public class RSItem +{ + private int id; + private String name; + private String description; + private String type; + private String icon; + private String icon_large; + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public String getIcon_large() + { + return icon_large; + } + + public void setIcon_large(String icon_large) + { + this.icon_large = icon_large; + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/item/RSItemResponse.java b/http-service/src/main/java/net/runelite/http/service/item/RSItemResponse.java new file mode 100644 index 0000000000..6ac6cee980 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/item/RSItemResponse.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017, Adam + * 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.item; + +public class RSItemResponse +{ + private RSItem item; + + public RSItem getItem() + { + return item; + } + + public void setItem(RSItem item) + { + this.item = item; + } +}