Merge remote-tracking branch 'runelite/master' into 2308-merge
This commit is contained in:
@@ -53,13 +53,13 @@ public class LootTrackerClient
|
|||||||
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
|
|
||||||
public void submit(LootRecord lootRecord)
|
public void submit(Collection<LootRecord> lootRecords)
|
||||||
{
|
{
|
||||||
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||||
.addPathSegment("loottracker")
|
.addPathSegment("loottracker")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
RequestBody body = RequestBody.Companion.create(GSON.toJson(lootRecord), JSON);
|
RequestBody body = RequestBody.Companion.create(GSON.toJson(lootRecords), JSON);
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
.header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString())
|
||||||
.post(body)
|
.post(body)
|
||||||
|
|||||||
@@ -262,6 +262,8 @@ public class AccountService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth.invalidate(session.getUuid());
|
||||||
|
|
||||||
try (Connection con = sql2o.open())
|
try (Connection con = sql2o.open())
|
||||||
{
|
{
|
||||||
con.createQuery("delete from sessions where uuid = :uuid")
|
con.createQuery("delete from sessions where uuid = :uuid")
|
||||||
|
|||||||
@@ -24,14 +24,18 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.http.service.account;
|
package net.runelite.http.service.account;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.RemovalNotification;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import net.runelite.http.service.account.beans.SessionEntry;
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
|
import net.runelite.http.service.account.beans.SessionEntry;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -43,6 +47,12 @@ public class AuthFilter
|
|||||||
{
|
{
|
||||||
private final Sql2o sql2o;
|
private final Sql2o sql2o;
|
||||||
|
|
||||||
|
private final Cache<UUID, SessionEntry> sessionCache = CacheBuilder.newBuilder()
|
||||||
|
.maximumSize(10000L)
|
||||||
|
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||||
|
.removalListener(this::removalListener)
|
||||||
|
.build();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public AuthFilter(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
public AuthFilter(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
||||||
{
|
{
|
||||||
@@ -59,30 +69,48 @@ public class AuthFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
UUID uuid = UUID.fromString(runeliteAuth);
|
UUID uuid = UUID.fromString(runeliteAuth);
|
||||||
|
SessionEntry sessionEntry = sessionCache.getIfPresent(uuid);
|
||||||
|
if (sessionEntry != null)
|
||||||
|
{
|
||||||
|
return sessionEntry;
|
||||||
|
}
|
||||||
|
|
||||||
try (Connection con = sql2o.open())
|
try (Connection con = sql2o.open())
|
||||||
{
|
{
|
||||||
SessionEntry sessionEntry = con.createQuery("select user, uuid, created from sessions where uuid = :uuid")
|
sessionEntry = con.createQuery("select user, uuid, created, last_used as lastUsed from sessions where uuid = :uuid")
|
||||||
.addParameter("uuid", uuid.toString())
|
.addParameter("uuid", uuid.toString())
|
||||||
.executeAndFetchFirst(SessionEntry.class);
|
.executeAndFetchFirst(SessionEntry.class);
|
||||||
|
}
|
||||||
|
|
||||||
if (sessionEntry == null)
|
if (sessionEntry == null)
|
||||||
{
|
{
|
||||||
response.sendError(401, "Access denied");
|
response.sendError(401, "Access denied");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instant now = Instant.now();
|
sessionCache.put(uuid, sessionEntry);
|
||||||
|
|
||||||
|
return sessionEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removalListener(RemovalNotification<UUID, SessionEntry> notification)
|
||||||
|
{
|
||||||
|
UUID uuid = notification.getKey();
|
||||||
|
Instant now = Instant.now();
|
||||||
|
|
||||||
|
try (Connection con = sql2o.open())
|
||||||
|
{
|
||||||
con.createQuery("update sessions set last_used = :last_used where uuid = :uuid")
|
con.createQuery("update sessions set last_used = :last_used where uuid = :uuid")
|
||||||
.addParameter("last_used", Timestamp.from(now))
|
.addParameter("last_used", Timestamp.from(now))
|
||||||
.addParameter("uuid", uuid.toString())
|
.addParameter("uuid", uuid.toString())
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
|
|
||||||
sessionEntry.setLastUsed(now);
|
|
||||||
|
|
||||||
return sessionEntry;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void invalidate(UUID uuid)
|
||||||
|
{
|
||||||
|
// If we ever run multiple services, may need to publish something here to invalidate...
|
||||||
|
sessionCache.invalidate(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class LootTrackerController
|
|||||||
private AuthFilter auth;
|
private AuthFilter auth;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST)
|
@RequestMapping(method = RequestMethod.POST)
|
||||||
public void storeLootRecord(HttpServletRequest request, HttpServletResponse response, @RequestBody LootRecord record) throws IOException
|
public void storeLootRecord(HttpServletRequest request, HttpServletResponse response, @RequestBody Collection<LootRecord> records) throws IOException
|
||||||
{
|
{
|
||||||
SessionEntry e = auth.handle(request, response);
|
SessionEntry e = auth.handle(request, response);
|
||||||
if (e == null)
|
if (e == null)
|
||||||
@@ -62,7 +62,7 @@ public class LootTrackerController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
service.store(record, e.getUser());
|
service.store(records, e.getUser());
|
||||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class LootTrackerService
|
|||||||
|
|
||||||
// Queries for inserting kills
|
// Queries for inserting kills
|
||||||
private static final String INSERT_KILL_QUERY = "INSERT INTO kills (accountId, type, eventId) VALUES (:accountId, :type, :eventId)";
|
private static final String INSERT_KILL_QUERY = "INSERT INTO kills (accountId, type, eventId) VALUES (:accountId, :type, :eventId)";
|
||||||
private static final String INSERT_DROP_QUERY = "INSERT INTO drops (killId, itemId, itemQuantity) VALUES (LAST_INSERT_ID(), :itemId, :itemQuantity)";
|
private static final String INSERT_DROP_QUERY = "INSERT INTO drops (killId, itemId, itemQuantity) VALUES (:killId, :itemId, :itemQuantity)";
|
||||||
|
|
||||||
private static final String SELECT_LOOT_QUERY = "SELECT killId,time,type,eventId,itemId,itemQuantity FROM kills JOIN drops ON drops.killId = kills.id WHERE accountId = :accountId ORDER BY TIME DESC LIMIT :limit OFFSET :offset";
|
private static final String SELECT_LOOT_QUERY = "SELECT killId,time,type,eventId,itemId,itemQuantity FROM kills JOIN drops ON drops.killId = kills.id WHERE accountId = :accountId ORDER BY TIME DESC LIMIT :limit OFFSET :offset";
|
||||||
|
|
||||||
@@ -89,29 +89,49 @@ public class LootTrackerService
|
|||||||
/**
|
/**
|
||||||
* Store LootRecord
|
* Store LootRecord
|
||||||
*
|
*
|
||||||
* @param record LootRecord to store
|
* @param records LootRecords to store
|
||||||
* @param accountId runelite account id to tie data too
|
* @param accountId runelite account id to tie data too
|
||||||
*/
|
*/
|
||||||
public void store(LootRecord record, int accountId)
|
public void store(Collection<LootRecord> records, int accountId)
|
||||||
{
|
{
|
||||||
try (Connection con = sql2o.beginTransaction())
|
try (Connection con = sql2o.beginTransaction())
|
||||||
{
|
{
|
||||||
// Kill Entry Query
|
// Kill Entry Query
|
||||||
con.createQuery(INSERT_KILL_QUERY, true)
|
Query killQuery = con.createQuery(INSERT_KILL_QUERY, true);
|
||||||
.addParameter("accountId", accountId)
|
|
||||||
.addParameter("type", record.getType())
|
for (LootRecord record : records)
|
||||||
.addParameter("eventId", record.getEventId())
|
{
|
||||||
.executeUpdate();
|
killQuery
|
||||||
|
.addParameter("accountId", accountId)
|
||||||
|
.addParameter("type", record.getType())
|
||||||
|
.addParameter("eventId", record.getEventId())
|
||||||
|
.addToBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
killQuery.executeBatch();
|
||||||
|
Object[] keys = con.getKeys();
|
||||||
|
|
||||||
|
if (keys.length != records.size())
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Mismatch in keys vs records size");
|
||||||
|
}
|
||||||
|
|
||||||
Query insertDrop = con.createQuery(INSERT_DROP_QUERY);
|
Query insertDrop = con.createQuery(INSERT_DROP_QUERY);
|
||||||
|
|
||||||
// Append all queries for inserting drops
|
// Append all queries for inserting drops
|
||||||
for (GameItem drop : record.getDrops())
|
int idx = 0;
|
||||||
|
for (LootRecord record : records)
|
||||||
{
|
{
|
||||||
insertDrop
|
for (GameItem drop : record.getDrops())
|
||||||
.addParameter("itemId", drop.getId())
|
{
|
||||||
.addParameter("itemQuantity", drop.getQty())
|
insertDrop
|
||||||
.addToBatch();
|
.addParameter("killId", keys[idx])
|
||||||
|
.addParameter("itemId", drop.getId())
|
||||||
|
.addParameter("itemQuantity", drop.getQty())
|
||||||
|
.addToBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
insertDrop.executeBatch();
|
insertDrop.executeBatch();
|
||||||
|
|||||||
@@ -83,10 +83,10 @@ public class LootTrackerControllerTest
|
|||||||
lootRecord.setTime(Instant.now());
|
lootRecord.setTime(Instant.now());
|
||||||
lootRecord.setDrops(Collections.singletonList(new GameItem(4151, 1)));
|
lootRecord.setDrops(Collections.singletonList(new GameItem(4151, 1)));
|
||||||
|
|
||||||
String data = RuneLiteAPI.GSON.toJson(lootRecord);
|
String data = RuneLiteAPI.GSON.toJson(Collections.singletonList(lootRecord));
|
||||||
mockMvc.perform(post("/loottracker").content(data).contentType(MediaType.APPLICATION_JSON))
|
mockMvc.perform(post("/loottracker").content(data).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
verify(lootTrackerService).store(eq(lootRecord), anyInt());
|
verify(lootTrackerService).store(eq(Collections.singletonList(lootRecord)), anyInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,6 +49,7 @@ public interface Actor extends Entity
|
|||||||
*
|
*
|
||||||
* @return the name
|
* @return the name
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -342,6 +342,7 @@ public interface Client extends GameShell
|
|||||||
*
|
*
|
||||||
* @return the logged in player
|
* @return the logged in player
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
Player getLocalPlayer();
|
Player getLocalPlayer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -422,6 +423,7 @@ public interface Client extends GameShell
|
|||||||
*
|
*
|
||||||
* @return the selected tile
|
* @return the selected tile
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
Tile getSelectedSceneTile();
|
Tile getSelectedSceneTile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -436,6 +438,7 @@ public interface Client extends GameShell
|
|||||||
*
|
*
|
||||||
* @return the dragged widget, null if not dragging any widget
|
* @return the dragged widget, null if not dragging any widget
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
Widget getDraggedWidget();
|
Widget getDraggedWidget();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -446,6 +449,7 @@ public interface Client extends GameShell
|
|||||||
*
|
*
|
||||||
* @return the dragged on widget, null if not dragging any widget
|
* @return the dragged on widget, null if not dragging any widget
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
Widget getDraggedOnWidget();
|
Widget getDraggedOnWidget();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -290,9 +290,9 @@ public class ChatboxItemSearch extends ChatboxTextInput
|
|||||||
for (int i = 0; i < client.getItemCount() && results.size() < MAX_RESULTS; i++)
|
for (int i = 0; i < client.getItemCount() && results.size() < MAX_RESULTS; i++)
|
||||||
{
|
{
|
||||||
ItemDefinition itemComposition = itemManager.getItemDefinition(itemManager.canonicalize(i));
|
ItemDefinition itemComposition = itemManager.getItemDefinition(itemManager.canonicalize(i));
|
||||||
String name = itemComposition.getName();
|
String name = itemComposition.getName().toLowerCase();
|
||||||
// The client assigns "null" to item names of items it doesn't know about
|
// The client assigns "null" to item names of items it doesn't know about
|
||||||
if (!name.equals("null") && name.toLowerCase().contains(search))
|
if (!name.equals("null") && name.contains(search))
|
||||||
{
|
{
|
||||||
// This may already be in the map due to canonicalize mapping the item to something we've already seen
|
// This may already be in the map due to canonicalize mapping the item to something we've already seen
|
||||||
results.putIfAbsent(itemComposition.getId(), itemComposition);
|
results.putIfAbsent(itemComposition.getId(), itemComposition);
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
|||||||
new CrypticClue("More resources than I can handle, but in a very dangerous area. Can't wait to strike gold!", new WorldPoint(3183, 3941, 0), "Dig between the three gold ores in the Wilderness Resource Area."),
|
new CrypticClue("More resources than I can handle, but in a very dangerous area. Can't wait to strike gold!", new WorldPoint(3183, 3941, 0), "Dig between the three gold ores in the Wilderness Resource Area."),
|
||||||
new CrypticClue("Observing someone in a swamp, under the telescope lies treasure.", new WorldPoint(2221, 3091, 0), "Dig next to the telescope on Broken Handz's island in the poison wastes. (Accessible only through fairy ring DLR)"),
|
new CrypticClue("Observing someone in a swamp, under the telescope lies treasure.", new WorldPoint(2221, 3091, 0), "Dig next to the telescope on Broken Handz's island in the poison wastes. (Accessible only through fairy ring DLR)"),
|
||||||
new CrypticClue("A general who sets a 'shining' example.", "General Hining", new WorldPoint(2186, 3148, 0), "Talk to General Hining in Tyras Camp."),
|
new CrypticClue("A general who sets a 'shining' example.", "General Hining", new WorldPoint(2186, 3148, 0), "Talk to General Hining in Tyras Camp."),
|
||||||
new CrypticClue("Has no one told you it is rude to ask a lady her age?", "Lady Tangwen Trahaearn", new WorldPoint(3280, 6042, 0), "Talk to Lady Tangwen Trahaearn, SSE Prifddinas by the teleporter."),
|
new CrypticClue("Has no one told you it is rude to ask a lady her age?", "Mawrth", new WorldPoint(2333, 3165, 0), "Talk to Mawrth in Lletya."),
|
||||||
new CrypticClue("Elvish onions.", new WorldPoint(3303, 6092, 0), "Dig in the onion patch east of the Prifddinas allotments.")
|
new CrypticClue("Elvish onions.", new WorldPoint(3303, 6092, 0), "Dig in the onion patch east of the Prifddinas allotments.")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -158,13 +158,13 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll
|
|||||||
new SkillChallengeClue("Complete a lap of Rellekka's Rooftop Agility Course", "complete a lap of the rellekka rooftop agility course whilst sporting the finest amount of grace.", true,
|
new SkillChallengeClue("Complete a lap of Rellekka's Rooftop Agility Course", "complete a lap of the rellekka rooftop agility course whilst sporting the finest amount of grace.", true,
|
||||||
all("A full Graceful set",
|
all("A full Graceful set",
|
||||||
any("", item(ItemID.GRACEFUL_HOOD), item(ItemID.GRACEFUL_HOOD_11851), item(ItemID.GRACEFUL_HOOD_13579), item(ItemID.GRACEFUL_HOOD_13580), item(ItemID.GRACEFUL_HOOD_13591), item(ItemID.GRACEFUL_HOOD_13592), item(ItemID.GRACEFUL_HOOD_13603), item(ItemID.GRACEFUL_HOOD_13604), item(ItemID.GRACEFUL_HOOD_13615), item(ItemID.GRACEFUL_HOOD_13616), item(ItemID.GRACEFUL_HOOD_13627), item(ItemID.GRACEFUL_HOOD_13628), item(ItemID.GRACEFUL_HOOD_13667), item(ItemID.GRACEFUL_HOOD_13668), item(ItemID.GRACEFUL_HOOD_21061), item(ItemID.GRACEFUL_HOOD_21063)),
|
any("", item(ItemID.GRACEFUL_HOOD), item(ItemID.GRACEFUL_HOOD_11851), item(ItemID.GRACEFUL_HOOD_13579), item(ItemID.GRACEFUL_HOOD_13580), item(ItemID.GRACEFUL_HOOD_13591), item(ItemID.GRACEFUL_HOOD_13592), item(ItemID.GRACEFUL_HOOD_13603), item(ItemID.GRACEFUL_HOOD_13604), item(ItemID.GRACEFUL_HOOD_13615), item(ItemID.GRACEFUL_HOOD_13616), item(ItemID.GRACEFUL_HOOD_13627), item(ItemID.GRACEFUL_HOOD_13628), item(ItemID.GRACEFUL_HOOD_13667), item(ItemID.GRACEFUL_HOOD_13668), item(ItemID.GRACEFUL_HOOD_21061), item(ItemID.GRACEFUL_HOOD_21063)),
|
||||||
any("", item(ItemID.GRACEFUL_CAPE), item(ItemID.GRACEFUL_CAPE_11853), item(ItemID.GRACEFUL_CAPE_13581), item(ItemID.GRACEFUL_CAPE_13582), item(ItemID.GRACEFUL_CAPE_13593), item(ItemID.GRACEFUL_CAPE_13594), item(ItemID.GRACEFUL_CAPE_13605), item(ItemID.GRACEFUL_CAPE_13606), item(ItemID.GRACEFUL_CAPE_13617), item(ItemID.GRACEFUL_CAPE_13618), item(ItemID.GRACEFUL_CAPE_13629), item(ItemID.GRACEFUL_CAPE_13630), item(ItemID.GRACEFUL_CAPE_13669), item(ItemID.GRACEFUL_CAPE_13670), item(ItemID.GRACEFUL_CAPE_21064), item(ItemID.GRACEFUL_CAPE_21066)),
|
any("", item(ItemID.GRACEFUL_CAPE), item(ItemID.GRACEFUL_CAPE_11853), item(ItemID.GRACEFUL_CAPE_13581), item(ItemID.GRACEFUL_CAPE_13582), item(ItemID.GRACEFUL_CAPE_13593), item(ItemID.GRACEFUL_CAPE_13594), item(ItemID.GRACEFUL_CAPE_13605), item(ItemID.GRACEFUL_CAPE_13606), item(ItemID.GRACEFUL_CAPE_13617), item(ItemID.GRACEFUL_CAPE_13618), item(ItemID.GRACEFUL_CAPE_13629), item(ItemID.GRACEFUL_CAPE_13630), item(ItemID.GRACEFUL_CAPE_13669), item(ItemID.GRACEFUL_CAPE_13670), item(ItemID.GRACEFUL_CAPE_21064), item(ItemID.GRACEFUL_CAPE_21066), item(ItemID.AGILITY_CAPE), item(ItemID.AGILITY_CAPET), item(ItemID.MAX_CAPE)),
|
||||||
any("", item(ItemID.GRACEFUL_TOP), item(ItemID.GRACEFUL_TOP_11855), item(ItemID.GRACEFUL_TOP_13583), item(ItemID.GRACEFUL_TOP_13584), item(ItemID.GRACEFUL_TOP_13595), item(ItemID.GRACEFUL_TOP_13596), item(ItemID.GRACEFUL_TOP_13607), item(ItemID.GRACEFUL_TOP_13608), item(ItemID.GRACEFUL_TOP_13619), item(ItemID.GRACEFUL_TOP_13620), item(ItemID.GRACEFUL_TOP_13631), item(ItemID.GRACEFUL_TOP_13632), item(ItemID.GRACEFUL_TOP_13671), item(ItemID.GRACEFUL_TOP_13672), item(ItemID.GRACEFUL_TOP_21067), item(ItemID.GRACEFUL_TOP_21069)),
|
any("", item(ItemID.GRACEFUL_TOP), item(ItemID.GRACEFUL_TOP_11855), item(ItemID.GRACEFUL_TOP_13583), item(ItemID.GRACEFUL_TOP_13584), item(ItemID.GRACEFUL_TOP_13595), item(ItemID.GRACEFUL_TOP_13596), item(ItemID.GRACEFUL_TOP_13607), item(ItemID.GRACEFUL_TOP_13608), item(ItemID.GRACEFUL_TOP_13619), item(ItemID.GRACEFUL_TOP_13620), item(ItemID.GRACEFUL_TOP_13631), item(ItemID.GRACEFUL_TOP_13632), item(ItemID.GRACEFUL_TOP_13671), item(ItemID.GRACEFUL_TOP_13672), item(ItemID.GRACEFUL_TOP_21067), item(ItemID.GRACEFUL_TOP_21069)),
|
||||||
any("", item(ItemID.GRACEFUL_LEGS), item(ItemID.GRACEFUL_LEGS_11857), item(ItemID.GRACEFUL_LEGS_13585), item(ItemID.GRACEFUL_LEGS_13586), item(ItemID.GRACEFUL_LEGS_13597), item(ItemID.GRACEFUL_LEGS_13598), item(ItemID.GRACEFUL_LEGS_13609), item(ItemID.GRACEFUL_LEGS_13610), item(ItemID.GRACEFUL_LEGS_13621), item(ItemID.GRACEFUL_LEGS_13622), item(ItemID.GRACEFUL_LEGS_13633), item(ItemID.GRACEFUL_LEGS_13634), item(ItemID.GRACEFUL_LEGS_13673), item(ItemID.GRACEFUL_LEGS_13674), item(ItemID.GRACEFUL_LEGS_21070), item(ItemID.GRACEFUL_LEGS_21072)),
|
any("", item(ItemID.GRACEFUL_LEGS), item(ItemID.GRACEFUL_LEGS_11857), item(ItemID.GRACEFUL_LEGS_13585), item(ItemID.GRACEFUL_LEGS_13586), item(ItemID.GRACEFUL_LEGS_13597), item(ItemID.GRACEFUL_LEGS_13598), item(ItemID.GRACEFUL_LEGS_13609), item(ItemID.GRACEFUL_LEGS_13610), item(ItemID.GRACEFUL_LEGS_13621), item(ItemID.GRACEFUL_LEGS_13622), item(ItemID.GRACEFUL_LEGS_13633), item(ItemID.GRACEFUL_LEGS_13634), item(ItemID.GRACEFUL_LEGS_13673), item(ItemID.GRACEFUL_LEGS_13674), item(ItemID.GRACEFUL_LEGS_21070), item(ItemID.GRACEFUL_LEGS_21072)),
|
||||||
any("", item(ItemID.GRACEFUL_GLOVES), item(ItemID.GRACEFUL_GLOVES_11859), item(ItemID.GRACEFUL_GLOVES_13587), item(ItemID.GRACEFUL_GLOVES_13588), item(ItemID.GRACEFUL_GLOVES_13599), item(ItemID.GRACEFUL_GLOVES_13600), item(ItemID.GRACEFUL_GLOVES_13611), item(ItemID.GRACEFUL_GLOVES_13612), item(ItemID.GRACEFUL_GLOVES_13623), item(ItemID.GRACEFUL_GLOVES_13624), item(ItemID.GRACEFUL_GLOVES_13635), item(ItemID.GRACEFUL_GLOVES_13636), item(ItemID.GRACEFUL_GLOVES_13675), item(ItemID.GRACEFUL_GLOVES_13676), item(ItemID.GRACEFUL_GLOVES_21073), item(ItemID.GRACEFUL_GLOVES_21075)),
|
any("", item(ItemID.GRACEFUL_GLOVES), item(ItemID.GRACEFUL_GLOVES_11859), item(ItemID.GRACEFUL_GLOVES_13587), item(ItemID.GRACEFUL_GLOVES_13588), item(ItemID.GRACEFUL_GLOVES_13599), item(ItemID.GRACEFUL_GLOVES_13600), item(ItemID.GRACEFUL_GLOVES_13611), item(ItemID.GRACEFUL_GLOVES_13612), item(ItemID.GRACEFUL_GLOVES_13623), item(ItemID.GRACEFUL_GLOVES_13624), item(ItemID.GRACEFUL_GLOVES_13635), item(ItemID.GRACEFUL_GLOVES_13636), item(ItemID.GRACEFUL_GLOVES_13675), item(ItemID.GRACEFUL_GLOVES_13676), item(ItemID.GRACEFUL_GLOVES_21073), item(ItemID.GRACEFUL_GLOVES_21075)),
|
||||||
any("", item(ItemID.GRACEFUL_BOOTS), item(ItemID.GRACEFUL_BOOTS_11861), item(ItemID.GRACEFUL_BOOTS_13589), item(ItemID.GRACEFUL_BOOTS_13590), item(ItemID.GRACEFUL_BOOTS_13601), item(ItemID.GRACEFUL_BOOTS_13602), item(ItemID.GRACEFUL_BOOTS_13613), item(ItemID.GRACEFUL_BOOTS_13614), item(ItemID.GRACEFUL_BOOTS_13625), item(ItemID.GRACEFUL_BOOTS_13626), item(ItemID.GRACEFUL_BOOTS_13637), item(ItemID.GRACEFUL_BOOTS_13638), item(ItemID.GRACEFUL_BOOTS_13677), item(ItemID.GRACEFUL_BOOTS_13678), item(ItemID.GRACEFUL_BOOTS_21076), item(ItemID.GRACEFUL_BOOTS_21078)))),
|
any("", item(ItemID.GRACEFUL_BOOTS), item(ItemID.GRACEFUL_BOOTS_11861), item(ItemID.GRACEFUL_BOOTS_13589), item(ItemID.GRACEFUL_BOOTS_13590), item(ItemID.GRACEFUL_BOOTS_13601), item(ItemID.GRACEFUL_BOOTS_13602), item(ItemID.GRACEFUL_BOOTS_13613), item(ItemID.GRACEFUL_BOOTS_13614), item(ItemID.GRACEFUL_BOOTS_13625), item(ItemID.GRACEFUL_BOOTS_13626), item(ItemID.GRACEFUL_BOOTS_13637), item(ItemID.GRACEFUL_BOOTS_13638), item(ItemID.GRACEFUL_BOOTS_13677), item(ItemID.GRACEFUL_BOOTS_13678), item(ItemID.GRACEFUL_BOOTS_21076), item(ItemID.GRACEFUL_BOOTS_21078)))),
|
||||||
new SkillChallengeClue("Mix an anti-venom potion.", item(ItemID.ANTIDOTE4_5952), xOfItem(ItemID.ZULRAHS_SCALES, 20)),
|
new SkillChallengeClue("Mix an anti-venom potion.", item(ItemID.ANTIDOTE4_5952), xOfItem(ItemID.ZULRAHS_SCALES, 20)),
|
||||||
new SkillChallengeClue("Mine a piece of Runite ore", "mine a piece of runite ore whilst sporting the finest mining gear.", true, ANY_PICKAXE, all(item(ItemID.PROSPECTOR_HELMET), item(ItemID.PROSPECTOR_JACKET), item(ItemID.PROSPECTOR_LEGS), item(ItemID.PROSPECTOR_BOOTS))),
|
new SkillChallengeClue("Mine a piece of Runite ore", "mine a piece of runite ore whilst sporting the finest mining gear.", true, ANY_PICKAXE, all("Prospector kit", item(ItemID.PROSPECTOR_HELMET), item(ItemID.PROSPECTOR_JACKET), item(ItemID.PROSPECTOR_LEGS), item(ItemID.PROSPECTOR_BOOTS))),
|
||||||
new SkillChallengeClue("Steal a gem from the Ardougne market."),
|
new SkillChallengeClue("Steal a gem from the Ardougne market."),
|
||||||
new SkillChallengeClue("Pickpocket an elf."),
|
new SkillChallengeClue("Pickpocket an elf."),
|
||||||
new SkillChallengeClue("Bind a blood rune at the blood altar.", item(ItemID.DARK_ESSENCE_FRAGMENTS)),
|
new SkillChallengeClue("Bind a blood rune at the blood altar.", item(ItemID.DARK_ESSENCE_FRAGMENTS)),
|
||||||
@@ -173,8 +173,8 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll
|
|||||||
new SkillChallengeClue("Cremate a set of fiyr remains.", any("Magic or Redwood Pyre Logs", item(ItemID.MAGIC_PYRE_LOGS), item(ItemID.REDWOOD_PYRE_LOGS)), item(ItemID.TINDERBOX), item(ItemID.FIYR_REMAINS)),
|
new SkillChallengeClue("Cremate a set of fiyr remains.", any("Magic or Redwood Pyre Logs", item(ItemID.MAGIC_PYRE_LOGS), item(ItemID.REDWOOD_PYRE_LOGS)), item(ItemID.TINDERBOX), item(ItemID.FIYR_REMAINS)),
|
||||||
new SkillChallengeClue("Dissect a sacred eel.", item(ItemID.KNIFE), any("Fishing rod", item(ItemID.FISHING_ROD), item(ItemID.PEARL_FISHING_ROD)), item(ItemID.FISHING_BAIT)),
|
new SkillChallengeClue("Dissect a sacred eel.", item(ItemID.KNIFE), any("Fishing rod", item(ItemID.FISHING_ROD), item(ItemID.PEARL_FISHING_ROD)), item(ItemID.FISHING_BAIT)),
|
||||||
new SkillChallengeClue("Kill a lizardman shaman."),
|
new SkillChallengeClue("Kill a lizardman shaman."),
|
||||||
new SkillChallengeClue("Catch an Anglerfish.", "angle for an anglerfish in your finest fishing gear.", true, any("Fishing rod", item(ItemID.FISHING_ROD), item(ItemID.PEARL_FISHING_ROD)), item(ItemID.SANDWORMS), all(item(ItemID.ANGLER_HAT), item(ItemID.ANGLER_TOP), item(ItemID.ANGLER_WADERS), item(ItemID.ANGLER_BOOTS))),
|
new SkillChallengeClue("Catch an Anglerfish.", "angle for an anglerfish in your finest fishing gear.", true, any("Fishing rod", item(ItemID.FISHING_ROD), item(ItemID.PEARL_FISHING_ROD)), item(ItemID.SANDWORMS), all("Angler's outfit", item(ItemID.ANGLER_HAT), item(ItemID.ANGLER_TOP), item(ItemID.ANGLER_WADERS), item(ItemID.ANGLER_BOOTS))),
|
||||||
new SkillChallengeClue("Chop a redwood log.", "chop a redwood log whilst sporting the finest lumberjack gear.", true, ANY_AXE, all(item(ItemID.LUMBERJACK_HAT), item(ItemID.LUMBERJACK_TOP), item(ItemID.LUMBERJACK_LEGS), item(ItemID.LUMBERJACK_BOOTS))),
|
new SkillChallengeClue("Chop a redwood log.", "chop a redwood log whilst sporting the finest lumberjack gear.", true, ANY_AXE, all("Lumberjack outfit", item(ItemID.LUMBERJACK_HAT), item(ItemID.LUMBERJACK_TOP), item(ItemID.LUMBERJACK_LEGS), item(ItemID.LUMBERJACK_BOOTS))),
|
||||||
new SkillChallengeClue("Craft a light orb in the Dorgesh-Kaan bank.", item(ItemID.CAVE_GOBLIN_WIRE), item(ItemID.EMPTY_LIGHT_ORB)),
|
new SkillChallengeClue("Craft a light orb in the Dorgesh-Kaan bank.", item(ItemID.CAVE_GOBLIN_WIRE), item(ItemID.EMPTY_LIGHT_ORB)),
|
||||||
new SkillChallengeClue("Kill a reanimated Abyssal Demon.", "kill a reanimated abyssal.", xOfItem(ItemID.SOUL_RUNE, 4), xOfItem(ItemID.BLOOD_RUNE, 1), any("Nature Rune x4", xOfItem(ItemID.NATURE_RUNE, 4), item(ItemID.BRYOPHYTAS_STAFF)), item(ItemID.ENSOULED_ABYSSAL_HEAD)),
|
new SkillChallengeClue("Kill a reanimated Abyssal Demon.", "kill a reanimated abyssal.", xOfItem(ItemID.SOUL_RUNE, 4), xOfItem(ItemID.BLOOD_RUNE, 1), any("Nature Rune x4", xOfItem(ItemID.NATURE_RUNE, 4), item(ItemID.BRYOPHYTAS_STAFF)), item(ItemID.ENSOULED_ABYSSAL_HEAD)),
|
||||||
new SkillChallengeClue("Kill a Fiyr shade inside Mort'tons shade catacombs.", any("Any Silver Shade Key", item(ItemID.SILVER_KEY_RED), item(ItemID.SILVER_KEY_BROWN), item(ItemID.SILVER_KEY_CRIMSON), item(ItemID.SILVER_KEY_BLACK), item(ItemID.SILVER_KEY_PURPLE)))
|
new SkillChallengeClue("Kill a Fiyr shade inside Mort'tons shade catacombs.", any("Any Silver Shade Key", item(ItemID.SILVER_KEY_RED), item(ItemID.SILVER_KEY_BROWN), item(ItemID.SILVER_KEY_CRIMSON), item(ItemID.SILVER_KEY_BLACK), item(ItemID.SILVER_KEY_PURPLE)))
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ public class FishingPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
final NPC npc = (NPC) target;
|
final NPC npc = (NPC) target;
|
||||||
FishingSpot spot = FishingSpot.getSPOTS().get(npc.getId());
|
FishingSpot spot = FishingSpot.findSpot(npc.getId());
|
||||||
|
|
||||||
if (spot == null)
|
if (spot == null)
|
||||||
{
|
{
|
||||||
@@ -311,7 +311,7 @@ public class FishingPlugin extends Plugin
|
|||||||
|
|
||||||
for (NPC npc : fishingSpots)
|
for (NPC npc : fishingSpots)
|
||||||
{
|
{
|
||||||
if (FishingSpot.getSPOTS().get(npc.getId()) == FishingSpot.MINNOW && this.showMinnowOverlay)
|
if (FishingSpot.findSpot(npc.getId()) == FishingSpot.MINNOW && this.showMinnowOverlay)
|
||||||
{
|
{
|
||||||
final int id = npc.getIndex();
|
final int id = npc.getIndex();
|
||||||
final MinnowSpot minnowSpot = minnowSpots.get(id);
|
final MinnowSpot minnowSpot = minnowSpots.get(id);
|
||||||
@@ -336,7 +336,7 @@ public class FishingPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
final NPC npc = event.getNpc();
|
final NPC npc = event.getNpc();
|
||||||
|
|
||||||
if (!FishingSpot.getSPOTS().containsKey(npc.getId()))
|
if (FishingSpot.findSpot(npc.getId()) == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -448,8 +448,22 @@ public class FishingPlugin extends Plugin
|
|||||||
|
|
||||||
private void inverseSortSpotDistanceFromPlayer()
|
private void inverseSortSpotDistanceFromPlayer()
|
||||||
{
|
{
|
||||||
|
if (fishingSpots.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final LocalPoint cameraPoint = new LocalPoint(client.getCameraX(), client.getCameraY());
|
final LocalPoint cameraPoint = new LocalPoint(client.getCameraX(), client.getCameraY());
|
||||||
fishingSpots.sort(Comparator.comparing(npc -> -1 * npc.getLocalLocation().distanceTo(cameraPoint)));
|
fishingSpots.sort(
|
||||||
|
Comparator.comparing(
|
||||||
|
// Negate to have the furthest first
|
||||||
|
(NPC npc) -> -npc.getLocalLocation().distanceTo(cameraPoint))
|
||||||
|
// Order by position
|
||||||
|
.thenComparing(NPC::getLocalLocation, Comparator.comparing(LocalPoint::getX)
|
||||||
|
.thenComparing(LocalPoint::getY))
|
||||||
|
// And then by id
|
||||||
|
.thenComparing(NPC::getId)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConfig()
|
private void updateConfig()
|
||||||
|
|||||||
@@ -170,7 +170,6 @@ enum FishingSpot
|
|||||||
COMMON_TENCH("Common tench, Bluegill, Greater siren, Mottled eel", ItemID.COMMON_TENCH,
|
COMMON_TENCH("Common tench, Bluegill, Greater siren, Mottled eel", ItemID.COMMON_TENCH,
|
||||||
FISHING_SPOT_8523);
|
FISHING_SPOT_8523);
|
||||||
|
|
||||||
@Getter
|
|
||||||
private static final Map<Integer, FishingSpot> SPOTS;
|
private static final Map<Integer, FishingSpot> SPOTS;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
@@ -198,4 +197,9 @@ enum FishingSpot
|
|||||||
this.fishSpriteId = fishSpriteId;
|
this.fishSpriteId = fishSpriteId;
|
||||||
this.ids = ids;
|
this.ids = ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FishingSpot findSpot(int id)
|
||||||
|
{
|
||||||
|
return SPOTS.get(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class FishingSpotMinimapOverlay extends Overlay
|
|||||||
|
|
||||||
for (NPC npc : plugin.getFishingSpots())
|
for (NPC npc : plugin.getFishingSpots())
|
||||||
{
|
{
|
||||||
FishingSpot spot = FishingSpot.getSPOTS().get(npc.getId());
|
FishingSpot spot = FishingSpot.findSpot(npc.getId());
|
||||||
|
|
||||||
if (spot == null)
|
if (spot == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import net.runelite.api.NPC;
|
|||||||
import net.runelite.api.Perspective;
|
import net.runelite.api.Perspective;
|
||||||
import net.runelite.api.Point;
|
import net.runelite.api.Point;
|
||||||
import net.runelite.api.coords.LocalPoint;
|
import net.runelite.api.coords.LocalPoint;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
@@ -81,9 +82,11 @@ class FishingSpotOverlay extends Overlay
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FishingSpot previousSpot = null;
|
||||||
|
WorldPoint previousLocation = null;
|
||||||
for (NPC npc : plugin.getFishingSpots())
|
for (NPC npc : plugin.getFishingSpots())
|
||||||
{
|
{
|
||||||
FishingSpot spot = FishingSpot.getSPOTS().get(npc.getId());
|
FishingSpot spot = FishingSpot.findSpot(npc.getId());
|
||||||
|
|
||||||
if (spot == null)
|
if (spot == null)
|
||||||
{
|
{
|
||||||
@@ -95,7 +98,25 @@ class FishingSpotOverlay extends Overlay
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color color = npc.getSpotAnimation() == GraphicID.FLYING_FISH ? Color.RED : Color.CYAN;
|
// This relies on the sort order to keep identical npcs on the same tile adjacent to each other
|
||||||
|
if (previousSpot == spot && previousLocation.equals(npc.getWorldLocation()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color color;
|
||||||
|
if (npc.getSpotAnimation() == GraphicID.FLYING_FISH)
|
||||||
|
{
|
||||||
|
color = Color.RED;
|
||||||
|
}
|
||||||
|
else if (spot == FishingSpot.COMMON_TENCH && npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
||||||
|
{
|
||||||
|
color = Color.GREEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = Color.CYAN;
|
||||||
|
}
|
||||||
|
|
||||||
if (spot == FishingSpot.MINNOW && plugin.isShowMinnowOverlay())
|
if (spot == FishingSpot.MINNOW && plugin.isShowMinnowOverlay())
|
||||||
{
|
{
|
||||||
@@ -127,12 +148,6 @@ class FishingSpotOverlay extends Overlay
|
|||||||
{
|
{
|
||||||
Polygon poly = npc.getCanvasTilePoly();
|
Polygon poly = npc.getCanvasTilePoly();
|
||||||
|
|
||||||
if (spot == FishingSpot.COMMON_TENCH
|
|
||||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
|
||||||
{
|
|
||||||
color = Color.GREEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (poly != null)
|
if (poly != null)
|
||||||
{
|
{
|
||||||
OverlayUtil.renderPolygon(graphics, poly, color.darker());
|
OverlayUtil.renderPolygon(graphics, poly, color.darker());
|
||||||
@@ -164,17 +179,14 @@ class FishingSpotOverlay extends Overlay
|
|||||||
String text = spot.getName();
|
String text = spot.getName();
|
||||||
Point textLocation = npc.getCanvasTextLocation(graphics, text, npc.getLogicalHeight() + 40);
|
Point textLocation = npc.getCanvasTextLocation(graphics, text, npc.getLogicalHeight() + 40);
|
||||||
|
|
||||||
if (spot == FishingSpot.COMMON_TENCH
|
|
||||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
|
||||||
{
|
|
||||||
color = Color.GREEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textLocation != null)
|
if (textLocation != null)
|
||||||
{
|
{
|
||||||
OverlayUtil.renderTextLocation(graphics, textLocation, text, color.darker());
|
OverlayUtil.renderTextLocation(graphics, textLocation, text, color.darker());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
previousSpot = spot;
|
||||||
|
previousLocation = npc.getWorldLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ class TextureManager
|
|||||||
private static final float PERC_64 = 1f / 64f;
|
private static final float PERC_64 = 1f / 64f;
|
||||||
private static final float PERC_128 = 1f / 128f;
|
private static final float PERC_128 = 1f / 128f;
|
||||||
|
|
||||||
private static final int SMALL_TEXTURE_SIZE = 64;
|
|
||||||
private static final int TEXTURE_SIZE = 128;
|
private static final int TEXTURE_SIZE = 128;
|
||||||
|
|
||||||
int initTextureArray(TextureProvider textureProvider, GL4 gl)
|
int initTextureArray(TextureProvider textureProvider, GL4 gl)
|
||||||
@@ -130,8 +129,15 @@ class TextureManager
|
|||||||
|
|
||||||
++cnt;
|
++cnt;
|
||||||
|
|
||||||
int srcSize = srcPixels.length == 4096 ? SMALL_TEXTURE_SIZE : TEXTURE_SIZE;
|
if (srcPixels.length != TEXTURE_SIZE * TEXTURE_SIZE)
|
||||||
byte[] pixels = convertPixels(srcPixels, srcSize, srcSize, TEXTURE_SIZE, TEXTURE_SIZE);
|
{
|
||||||
|
// The texture storage is 128x128 bytes, and will only work correctly with the
|
||||||
|
// 128x128 textures from high detail mode
|
||||||
|
log.warn("Texture size for {} is {}!", textureId, srcPixels.length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] pixels = convertPixels(srcPixels, TEXTURE_SIZE, TEXTURE_SIZE, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||||
ByteBuffer pixelBuffer = ByteBuffer.wrap(pixels);
|
ByteBuffer pixelBuffer = ByteBuffer.wrap(pixels);
|
||||||
gl.glTexSubImage3D(gl.GL_TEXTURE_2D_ARRAY, 0, 0, 0, textureId, TEXTURE_SIZE, TEXTURE_SIZE,
|
gl.glTexSubImage3D(gl.GL_TEXTURE_2D_ARRAY, 0, 0, 0, textureId, TEXTURE_SIZE, TEXTURE_SIZE,
|
||||||
1, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, pixelBuffer);
|
1, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, pixelBuffer);
|
||||||
|
|||||||
@@ -299,7 +299,15 @@ public class GroundMarkerPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
if (hotKeyPressed && event.getOption().equals(WALK_HERE))
|
if (hotKeyPressed && event.getOption().equals(WALK_HERE))
|
||||||
{
|
{
|
||||||
|
final Tile selectedSceneTile = client.getSelectedSceneTile();
|
||||||
|
|
||||||
|
if (selectedSceneTile == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||||
|
|
||||||
int lastIndex = menuEntries.length;
|
int lastIndex = menuEntries.length;
|
||||||
menuEntries = Arrays.copyOf(menuEntries, lastIndex + 4);
|
menuEntries = Arrays.copyOf(menuEntries, lastIndex + 4);
|
||||||
|
|
||||||
|
|||||||
@@ -214,7 +214,10 @@ enum FixedPriceItem
|
|||||||
VERACS_FLAIL_25(ItemID.VERACS_FLAIL_25, 2500, ItemID.VERACS_FLAIL_0),
|
VERACS_FLAIL_25(ItemID.VERACS_FLAIL_25, 2500, ItemID.VERACS_FLAIL_0),
|
||||||
VERACS_FLAIL_50(ItemID.VERACS_FLAIL_50, 5000, ItemID.VERACS_FLAIL_0),
|
VERACS_FLAIL_50(ItemID.VERACS_FLAIL_50, 5000, ItemID.VERACS_FLAIL_0),
|
||||||
VERACS_FLAIL_75(ItemID.VERACS_FLAIL_75, 7500, ItemID.VERACS_FLAIL_0),
|
VERACS_FLAIL_75(ItemID.VERACS_FLAIL_75, 7500, ItemID.VERACS_FLAIL_0),
|
||||||
VERACS_FLAIL_100(ItemID.VERACS_FLAIL_100, 10000, ItemID.VERACS_FLAIL_0);
|
VERACS_FLAIL_100(ItemID.VERACS_FLAIL_100, 10000, ItemID.VERACS_FLAIL_0),
|
||||||
|
|
||||||
|
AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER, 4040000),
|
||||||
|
;
|
||||||
|
|
||||||
private final int itemId;
|
private final int itemId;
|
||||||
private final int offset;
|
private final int offset;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import java.io.FileReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -106,6 +107,7 @@ import net.runelite.client.plugins.PluginDescriptor;
|
|||||||
import net.runelite.client.plugins.loottracker.localstorage.LTItemEntry;
|
import net.runelite.client.plugins.loottracker.localstorage.LTItemEntry;
|
||||||
import net.runelite.client.plugins.loottracker.localstorage.LTRecord;
|
import net.runelite.client.plugins.loottracker.localstorage.LTRecord;
|
||||||
import net.runelite.client.plugins.loottracker.localstorage.LootRecordWriter;
|
import net.runelite.client.plugins.loottracker.localstorage.LootRecordWriter;
|
||||||
|
import net.runelite.client.task.Schedule;
|
||||||
import net.runelite.client.ui.ClientToolbar;
|
import net.runelite.client.ui.ClientToolbar;
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
import net.runelite.client.util.ImageUtil;
|
import net.runelite.client.util.ImageUtil;
|
||||||
@@ -218,6 +220,7 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
private Multiset<Integer> inventorySnapshot;
|
private Multiset<Integer> inventorySnapshot;
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private LootTrackerClient lootTrackerClient;
|
private LootTrackerClient lootTrackerClient;
|
||||||
|
private final List<LootRecord> queuedLoots = new ArrayList<>();
|
||||||
|
|
||||||
private Map<String, Integer> killCountMap = new HashMap<>();
|
private Map<String, Integer> killCountMap = new HashMap<>();
|
||||||
private boolean gotPet = false;
|
private boolean gotPet = false;
|
||||||
@@ -291,6 +294,7 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
|
|
||||||
private void onSessionClose(SessionClose sessionClose)
|
private void onSessionClose(SessionClose sessionClose)
|
||||||
{
|
{
|
||||||
|
submitLoot();
|
||||||
lootTrackerClient = null;
|
lootTrackerClient = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +335,6 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
addSubscriptions();
|
addSubscriptions();
|
||||||
|
|
||||||
ignoredItems = Text.fromCSV(config.getIgnoredItems());
|
ignoredItems = Text.fromCSV(config.getIgnoredItems());
|
||||||
@@ -421,6 +424,7 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
protected void shutDown()
|
protected void shutDown()
|
||||||
{
|
{
|
||||||
eventBus.unregister(this);
|
eventBus.unregister(this);
|
||||||
|
submitLoot();
|
||||||
|
|
||||||
clientToolbar.removeNavigation(navButton);
|
clientToolbar.removeNavigation(navButton);
|
||||||
lootTrackerClient = null;
|
lootTrackerClient = null;
|
||||||
@@ -528,9 +532,12 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
LootRecord lootRecord = new LootRecord(name, localUsername, LootRecordType.NPC,
|
LootRecord lootRecord = new LootRecord(name, localUsername, LootRecordType.NPC,
|
||||||
toGameItems(items), Instant.now());
|
toGameItems(items), Instant.now());
|
||||||
|
|
||||||
if (config.saveLoot() && lootTrackerClient != null)
|
if (config.saveLoot())
|
||||||
{
|
{
|
||||||
lootTrackerClient.submit(lootRecord);
|
synchronized (queuedLoots)
|
||||||
|
{
|
||||||
|
queuedLoots.add(lootRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.localPersistence)
|
if (this.localPersistence)
|
||||||
{
|
{
|
||||||
@@ -578,9 +585,12 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
SwingUtilities.invokeLater(() -> panel.add(name, localUsername, combat, entries));
|
SwingUtilities.invokeLater(() -> panel.add(name, localUsername, combat, entries));
|
||||||
LootRecord lootRecord = new LootRecord(name, localUsername, LootRecordType.PLAYER,
|
LootRecord lootRecord = new LootRecord(name, localUsername, LootRecordType.PLAYER,
|
||||||
toGameItems(items), Instant.now());
|
toGameItems(items), Instant.now());
|
||||||
if (lootTrackerClient != null && this.saveLoot)
|
if (this.saveLoot)
|
||||||
{
|
{
|
||||||
lootTrackerClient.submit(lootRecord);
|
synchronized (queuedLoots)
|
||||||
|
{
|
||||||
|
queuedLoots.add(lootRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (config.localPersistence())
|
if (config.localPersistence())
|
||||||
{
|
{
|
||||||
@@ -691,9 +701,12 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
|
|
||||||
final int killCount = killCountMap.getOrDefault(eventType.toUpperCase(), -1);
|
final int killCount = killCountMap.getOrDefault(eventType.toUpperCase(), -1);
|
||||||
|
|
||||||
if (lootTrackerClient != null && this.saveLoot)
|
if (this.saveLoot)
|
||||||
{
|
{
|
||||||
lootTrackerClient.submit(lootRecord);
|
synchronized (queuedLoots)
|
||||||
|
{
|
||||||
|
queuedLoots.add(lootRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (config.localPersistence())
|
if (config.localPersistence())
|
||||||
{
|
{
|
||||||
@@ -871,9 +884,12 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
client.getLocalPlayer().getCombatLevel(), entries));
|
client.getLocalPlayer().getCombatLevel(), entries));
|
||||||
LootRecord lootRecord = new LootRecord(name, client.getLocalPlayer().getName(), LootRecordType.DEATH,
|
LootRecord lootRecord = new LootRecord(name, client.getLocalPlayer().getName(), LootRecordType.DEATH,
|
||||||
toGameItems(itemsLost), Instant.now());
|
toGameItems(itemsLost), Instant.now());
|
||||||
if (lootTrackerClient != null && this.saveLoot)
|
if (this.saveLoot)
|
||||||
{
|
{
|
||||||
lootTrackerClient.submit(lootRecord);
|
synchronized (queuedLoots)
|
||||||
|
{
|
||||||
|
queuedLoots.add(lootRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.localPersistence)
|
if (this.localPersistence)
|
||||||
{
|
{
|
||||||
@@ -989,6 +1005,40 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schedule(
|
||||||
|
period = 5,
|
||||||
|
unit = ChronoUnit.MINUTES,
|
||||||
|
asynchronous = true
|
||||||
|
)
|
||||||
|
public void submitLootTask()
|
||||||
|
{
|
||||||
|
submitLoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submitLoot()
|
||||||
|
{
|
||||||
|
List<LootRecord> copy;
|
||||||
|
synchronized (queuedLoots)
|
||||||
|
{
|
||||||
|
if (queuedLoots.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy = new ArrayList<>(queuedLoots);
|
||||||
|
queuedLoots.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lootTrackerClient == null || !config.saveLoot())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Submitting {} loot records", copy.size());
|
||||||
|
|
||||||
|
lootTrackerClient.submit(copy);
|
||||||
|
}
|
||||||
|
|
||||||
private void takeInventorySnapshot()
|
private void takeInventorySnapshot()
|
||||||
{
|
{
|
||||||
final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY);
|
final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY);
|
||||||
@@ -1045,9 +1095,12 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
|
|
||||||
LootRecord lootRecord = new LootRecord(chestType, client.getLocalPlayer().getName(),
|
LootRecord lootRecord = new LootRecord(chestType, client.getLocalPlayer().getName(),
|
||||||
LootRecordType.EVENT, toGameItems(items), Instant.now());
|
LootRecordType.EVENT, toGameItems(items), Instant.now());
|
||||||
if (lootTrackerClient != null && config.saveLoot())
|
if (config.saveLoot())
|
||||||
{
|
{
|
||||||
lootTrackerClient.submit(lootRecord);
|
synchronized (queuedLoots)
|
||||||
|
{
|
||||||
|
queuedLoots.add(lootRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.localPersistence())
|
if (config.localPersistence())
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ package net.runelite.client.plugins.lowmemory;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.events.GameStateChanged;
|
||||||
import net.runelite.client.callback.ClientThread;
|
import net.runelite.client.callback.ClientThread;
|
||||||
|
import net.runelite.client.eventbus.EventBus;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
|
||||||
@@ -44,10 +47,18 @@ public class LowMemoryPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ClientThread clientThread;
|
private ClientThread clientThread;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EventBus eventBus;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startUp()
|
protected void startUp()
|
||||||
{
|
{
|
||||||
clientThread.invoke(() -> client.changeMemoryMode(true));
|
this.eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||||
|
|
||||||
|
if (client.getGameState() == GameState.LOGGED_IN)
|
||||||
|
{
|
||||||
|
clientThread.invoke(() -> client.changeMemoryMode(true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,4 +66,15 @@ public class LowMemoryPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
clientThread.invoke(() -> client.changeMemoryMode(false));
|
clientThread.invoke(() -> client.changeMemoryMode(false));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private void onGameStateChanged(GameStateChanged event)
|
||||||
|
{
|
||||||
|
// When the client starts it initializes the texture size based on the memory mode setting.
|
||||||
|
// Don't set low memory before the login screen is ready to prevent loading the low detail textures,
|
||||||
|
// which breaks the gpu plugin due to it requiring the 128x128px textures
|
||||||
|
if (event.getGameState() == GameState.LOGIN_SCREEN)
|
||||||
|
{
|
||||||
|
client.changeMemoryMode(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import net.runelite.api.Actor;
|
import net.runelite.api.Actor;
|
||||||
import net.runelite.api.ChatMessageType;
|
import net.runelite.api.ChatMessageType;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.ItemID;
|
import net.runelite.api.ItemID;
|
||||||
import net.runelite.api.MessageNode;
|
import net.runelite.api.MessageNode;
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
@@ -133,7 +134,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
|
|
||||||
private static final int GROTESQUE_GUARDIANS_REGION = 6727;
|
private static final int GROTESQUE_GUARDIANS_REGION = 6727;
|
||||||
|
|
||||||
private static final Set<Task> weaknessTasks = ImmutableSet.of(Task.DESERT_LIZARDS, Task.GARGOYLES,
|
private static final Set<Task> weaknessTasks = ImmutableSet.of(Task.LIZARDS, Task.GARGOYLES,
|
||||||
Task.GROTESQUE_GUARDIANS, Task.GROTESQUE_GUARDIANS, Task.MUTATED_ZYGOMITES, Task.ROCKSLUGS);
|
Task.GROTESQUE_GUARDIANS, Task.GROTESQUE_GUARDIANS, Task.MUTATED_ZYGOMITES, Task.ROCKSLUGS);
|
||||||
|
|
||||||
// Chat Command
|
// Chat Command
|
||||||
@@ -242,7 +243,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
private Task weaknessTask = null;
|
private Task weaknessTask = null;
|
||||||
|
|
||||||
private TaskCounter counter;
|
private TaskCounter counter;
|
||||||
private int cachedXp;
|
private int cachedXp = -1;
|
||||||
private int cachedPoints;
|
private int cachedPoints;
|
||||||
private Instant infoTimer;
|
private Instant infoTimer;
|
||||||
private List<String> targetNames = new ArrayList<>();
|
private List<String> targetNames = new ArrayList<>();
|
||||||
@@ -328,6 +329,11 @@ public class SlayerPlugin extends Plugin
|
|||||||
|
|
||||||
clientToolbar.addNavigation(navButton);
|
clientToolbar.addNavigation(navButton);
|
||||||
|
|
||||||
|
if (client.getGameState() == GameState.LOGGED_IN)
|
||||||
|
{
|
||||||
|
cachedXp = client.getSkillExperience(SLAYER);
|
||||||
|
}
|
||||||
|
|
||||||
chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit);
|
chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit);
|
||||||
|
|
||||||
chatCommandManager.registerCommandAsync(POINTS_COMMAND_STRING, this::pointsLookup); //here
|
chatCommandManager.registerCommandAsync(POINTS_COMMAND_STRING, this::pointsLookup); //here
|
||||||
@@ -348,6 +354,8 @@ public class SlayerPlugin extends Plugin
|
|||||||
chatCommandManager.unregisterCommand(TASK_COMMAND_STRING);
|
chatCommandManager.unregisterCommand(TASK_COMMAND_STRING);
|
||||||
chatCommandManager.unregisterCommand(POINTS_COMMAND_STRING);
|
chatCommandManager.unregisterCommand(POINTS_COMMAND_STRING);
|
||||||
clientToolbar.removeNavigation(navButton);
|
clientToolbar.removeNavigation(navButton);
|
||||||
|
|
||||||
|
cachedXp = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSubscriptions()
|
private void addSubscriptions()
|
||||||
@@ -376,6 +384,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
case HOPPING:
|
case HOPPING:
|
||||||
case LOGGING_IN:
|
case LOGGING_IN:
|
||||||
|
cachedXp = -1;
|
||||||
cachedPoints = 0;
|
cachedPoints = 0;
|
||||||
clearTrackedNPCs();
|
clearTrackedNPCs();
|
||||||
break;
|
break;
|
||||||
@@ -736,45 +745,47 @@ public class SlayerPlugin extends Plugin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cachedXp != 0)
|
if (cachedXp == -1)
|
||||||
{
|
{
|
||||||
final Task task = Task.getTask(taskName);
|
// this is the initial xp sent on login
|
||||||
|
cachedXp = slayerExp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (task == null)
|
final Task task = Task.getTask(taskName);
|
||||||
|
|
||||||
|
// null tasks are technically valid, it only means they arent explicitly defined in the Task enum
|
||||||
|
// allow them through so that if there is a task capture failure the counter will still work
|
||||||
|
final int taskKillExp = task != null ? task.getExpectedKillExp() : 0;
|
||||||
|
|
||||||
|
// Only count exp gain as a kill if the task either has no expected exp for a kill, or if the exp gain is equal
|
||||||
|
// to the expected exp gain for the task.
|
||||||
|
if (taskKillExp == 0 || taskKillExp == slayerExp - cachedXp)
|
||||||
|
{
|
||||||
|
killedOne();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is not the initial xp sent on login so these are new xp gains
|
||||||
|
int gains = slayerExp - cachedXp;
|
||||||
|
|
||||||
|
// potential npcs to give xp drop are current highlighted npcs and the lingering presences
|
||||||
|
List<NPCPresence> potentialNPCs = new ArrayList<>(lingeringPresences);
|
||||||
|
for (NPC npc : highlightedTargets)
|
||||||
{
|
{
|
||||||
return;
|
NPCPresence currentPresence = NPCPresence.buildPresence(npc);
|
||||||
|
potentialNPCs.add(currentPresence);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int taskKillExp = task.getExpectedKillExp();
|
int killCount = estimateKillCount(potentialNPCs, gains);
|
||||||
|
for (int i = 0; i < killCount; i++)
|
||||||
// Only count exp gain as a kill if the task either has no expected exp for a kill, or if the exp gain is equal
|
|
||||||
// to the expected exp gain for the task.
|
|
||||||
if (taskKillExp == 0 || taskKillExp == slayerExp - cachedXp)
|
|
||||||
{
|
{
|
||||||
killedOne();
|
killedOne();
|
||||||
}
|
int delta = slayerExp - cachedXp;
|
||||||
else
|
currentTask.setElapsedXp(currentTask.getElapsedXp() + delta);
|
||||||
{
|
|
||||||
// this is not the initial xp sent on login so these are new xp gains
|
|
||||||
int gains = slayerExp - cachedXp;
|
|
||||||
|
|
||||||
// potential npcs to give xp drop are current highlighted npcs and the lingering presences
|
|
||||||
List<NPCPresence> potentialNPCs = new ArrayList<>(lingeringPresences);
|
|
||||||
for (NPC npc : highlightedTargets)
|
|
||||||
{
|
|
||||||
NPCPresence currentPresence = NPCPresence.buildPresence(npc);
|
|
||||||
potentialNPCs.add(currentPresence);
|
|
||||||
}
|
|
||||||
|
|
||||||
int killCount = estimateKillCount(potentialNPCs, gains);
|
|
||||||
for (int i = 0; i < killCount; i++)
|
|
||||||
{
|
|
||||||
killedOne();
|
|
||||||
int delta = slayerExp - cachedXp;
|
|
||||||
currentTask.setElapsedXp(currentTask.getElapsedXp() + delta);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedXp = slayerExp;
|
cachedXp = slayerExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,6 @@ enum Task
|
|||||||
asList("Night beast"), Collections.emptyList()),
|
asList("Night beast"), Collections.emptyList()),
|
||||||
DARK_WARRIORS("Dark warriors", ItemID.BLACK_MED_HELM),
|
DARK_WARRIORS("Dark warriors", ItemID.BLACK_MED_HELM),
|
||||||
DERANGED_ARCHAEOLOGIST("Deranged Archaeologist", ItemID.ARCHAEOLOGISTS_DIARY),
|
DERANGED_ARCHAEOLOGIST("Deranged Archaeologist", ItemID.ARCHAEOLOGISTS_DIARY),
|
||||||
DESERT_LIZARDS("Desert lizards", ItemID.DESERT_LIZARD,
|
|
||||||
asList("Small lizard", "Lizard"), Collections.emptyList(), 4, ItemID.ICE_COOLER),
|
|
||||||
DOGS("Dogs", ItemID.GUARD_DOG, asList("Jackal"), Collections.emptyList()),
|
DOGS("Dogs", ItemID.GUARD_DOG, asList("Jackal"), Collections.emptyList()),
|
||||||
DRAKES("Drakes", ItemID.DRAKE),
|
DRAKES("Drakes", ItemID.DRAKE),
|
||||||
DUST_DEVILS("Dust devils", ItemID.DUST_DEVIL,
|
DUST_DEVILS("Dust devils", ItemID.DUST_DEVIL,
|
||||||
@@ -174,6 +172,8 @@ enum Task
|
|||||||
LESSER_DEMONS("Lesser demons", ItemID.LESSER_DEMON_MASK),
|
LESSER_DEMONS("Lesser demons", ItemID.LESSER_DEMON_MASK),
|
||||||
LIZARDMEN("Lizardmen", ItemID.LIZARDMAN_FANG,
|
LIZARDMEN("Lizardmen", ItemID.LIZARDMAN_FANG,
|
||||||
asList("Lizardman"), Collections.emptyList()),
|
asList("Lizardman"), Collections.emptyList()),
|
||||||
|
LIZARDS("Lizards", ItemID.DESERT_LIZARD,
|
||||||
|
asList("Desert lizard", "Sulphur lizard", "Small lizard", "Lizard"), Collections.emptyList(), 4, ItemID.ICE_COOLER),
|
||||||
MAGIC_AXES("Magic axes", ItemID.IRON_BATTLEAXE),
|
MAGIC_AXES("Magic axes", ItemID.IRON_BATTLEAXE),
|
||||||
MAMMOTHS("Mammoths", ItemID.ATTACKER_HORN,
|
MAMMOTHS("Mammoths", ItemID.ATTACKER_HORN,
|
||||||
asList("Mammoth"), Collections.emptyList()),
|
asList("Mammoth"), Collections.emptyList()),
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ enum GameTimer
|
|||||||
ICEBURST(SpriteID.SPELL_ICE_BURST, GameTimerImageType.SPRITE, "Ice burst", GraphicID.ICE_BURST, 10, ChronoUnit.SECONDS, true),
|
ICEBURST(SpriteID.SPELL_ICE_BURST, GameTimerImageType.SPRITE, "Ice burst", GraphicID.ICE_BURST, 10, ChronoUnit.SECONDS, true),
|
||||||
ICEBLITZ(SpriteID.SPELL_ICE_BLITZ, GameTimerImageType.SPRITE, "Ice blitz", GraphicID.ICE_BLITZ, 15, ChronoUnit.SECONDS, true),
|
ICEBLITZ(SpriteID.SPELL_ICE_BLITZ, GameTimerImageType.SPRITE, "Ice blitz", GraphicID.ICE_BLITZ, 15, ChronoUnit.SECONDS, true),
|
||||||
ICEBARRAGE(SpriteID.SPELL_ICE_BARRAGE, GameTimerImageType.SPRITE, "Ice barrage", GraphicID.ICE_BARRAGE, 20, ChronoUnit.SECONDS, true),
|
ICEBARRAGE(SpriteID.SPELL_ICE_BARRAGE, GameTimerImageType.SPRITE, "Ice barrage", GraphicID.ICE_BARRAGE, 20, ChronoUnit.SECONDS, true),
|
||||||
IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", GraphicID.IMBUED_HEART, 420, ChronoUnit.SECONDS),
|
IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", GraphicID.IMBUED_HEART, 420, ChronoUnit.SECONDS, true),
|
||||||
VENGEANCE(SpriteID.SPELL_VENGEANCE, GameTimerImageType.SPRITE, "Vengeance", 30, ChronoUnit.SECONDS),
|
VENGEANCE(SpriteID.SPELL_VENGEANCE, GameTimerImageType.SPRITE, "Vengeance", 30, ChronoUnit.SECONDS),
|
||||||
EXSUPERANTIFIRE(ItemID.EXTENDED_SUPER_ANTIFIRE4, GameTimerImageType.ITEM, "Extended Super AntiFire", 6, ChronoUnit.MINUTES),
|
EXSUPERANTIFIRE(ItemID.EXTENDED_SUPER_ANTIFIRE4, GameTimerImageType.ITEM, "Extended Super AntiFire", 6, ChronoUnit.MINUTES),
|
||||||
OVERLOAD_RAID(ItemID.OVERLOAD_4_20996, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true),
|
OVERLOAD_RAID(ItemID.OVERLOAD_4_20996, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true),
|
||||||
|
|||||||
@@ -48,11 +48,15 @@ class ClientConfigLoader
|
|||||||
|
|
||||||
final RSConfig config = new RSConfig();
|
final RSConfig config = new RSConfig();
|
||||||
|
|
||||||
try (final Response response = RuneLiteAPI.CLIENT.newCall(request).execute();
|
try (final Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||||
final BufferedReader in = new BufferedReader(new InputStreamReader(response.body().byteStream())))
|
|
||||||
{
|
{
|
||||||
String str;
|
if (!response.isSuccessful())
|
||||||
|
{
|
||||||
|
throw new IOException("Unsuccessful response: " + response.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
String str;
|
||||||
|
final BufferedReader in = new BufferedReader(new InputStreamReader(response.body().byteStream()));
|
||||||
while ((str = in.readLine()) != null)
|
while ((str = in.readLine()) != null)
|
||||||
{
|
{
|
||||||
int idx = str.indexOf('=');
|
int idx = str.indexOf('=');
|
||||||
|
|||||||
@@ -276,6 +276,14 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
if (overlayPosition == OverlayPosition.DYNAMIC || overlayPosition == OverlayPosition.TOOLTIP)
|
if (overlayPosition == OverlayPosition.DYNAMIC || overlayPosition == OverlayPosition.TOOLTIP)
|
||||||
{
|
{
|
||||||
safeRender(client, overlay, layer, graphics, new Point());
|
safeRender(client, overlay, layer, graphics, new Point());
|
||||||
|
|
||||||
|
// Restore graphics2d properties
|
||||||
|
graphics.setTransform(transform);
|
||||||
|
graphics.setStroke(stroke);
|
||||||
|
graphics.setComposite(composite);
|
||||||
|
graphics.setPaint(paint);
|
||||||
|
graphics.setRenderingHints(renderingHints);
|
||||||
|
graphics.setBackground(background);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -312,6 +320,14 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
|
|
||||||
safeRender(client, overlay, layer, graphics, location);
|
safeRender(client, overlay, layer, graphics, location);
|
||||||
|
|
||||||
|
// Restore graphics2d properties prior to drawing bounds
|
||||||
|
graphics.setTransform(transform);
|
||||||
|
graphics.setStroke(stroke);
|
||||||
|
graphics.setComposite(composite);
|
||||||
|
graphics.setPaint(paint);
|
||||||
|
graphics.setRenderingHints(renderingHints);
|
||||||
|
graphics.setBackground(background);
|
||||||
|
|
||||||
final Rectangle bounds = overlay.getBounds();
|
final Rectangle bounds = overlay.getBounds();
|
||||||
|
|
||||||
if (!bounds.isEmpty())
|
if (!bounds.isEmpty())
|
||||||
@@ -330,14 +346,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore graphics2d properties
|
|
||||||
graphics.setTransform(transform);
|
|
||||||
graphics.setStroke(stroke);
|
|
||||||
graphics.setComposite(composite);
|
|
||||||
graphics.setPaint(paint);
|
|
||||||
graphics.setRenderingHints(renderingHints);
|
|
||||||
graphics.setBackground(background);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ uniform float smoothBanding;
|
|||||||
uniform vec4 fogColor;
|
uniform vec4 fogColor;
|
||||||
|
|
||||||
in vec4 Color;
|
in vec4 Color;
|
||||||
in float fHsl;
|
centroid in float fHsl;
|
||||||
in vec4 fUv;
|
in vec4 fUv;
|
||||||
in float fogAmount;
|
in float fogAmount;
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ in vec4 vUv[];
|
|||||||
in float vFogAmount[];
|
in float vFogAmount[];
|
||||||
|
|
||||||
out vec4 Color;
|
out vec4 Color;
|
||||||
out float fHsl;
|
centroid out float fHsl;
|
||||||
out vec4 fUv;
|
out vec4 fUv;
|
||||||
out float fogAmount;
|
out float fogAmount;
|
||||||
|
|
||||||
|
|||||||
@@ -961,3 +961,7 @@ R 49 92 51 92
|
|||||||
// Iorwerth dungeon
|
// Iorwerth dungeon
|
||||||
#030A0A
|
#030A0A
|
||||||
R 49 193 51 194
|
R 49 193 51 194
|
||||||
|
|
||||||
|
// Braindeath Island
|
||||||
|
#8AD2DF
|
||||||
|
R 33 79 33 80
|
||||||
@@ -628,4 +628,29 @@ public class ItemsKeptOnDeathPluginTest
|
|||||||
final List<ItemStack> lost = deathItems.getLostItems();
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
assertTrue(lost.contains(new ItemStack(ItemID.DRAGON_DEFENDER, 1)));
|
assertTrue(lost.contains(new ItemStack(ItemID.DRAGON_DEFENDER, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void avernicDefenderPriceTest()
|
||||||
|
{
|
||||||
|
final Item defender = mItem(ItemID.AVERNIC_DEFENDER, 1, "Avernic defender", false, 0);
|
||||||
|
final int defenderOffset = FixedPriceItem.AVERNIC_DEFENDER.getOffset();
|
||||||
|
final Integer defenderBrokenPrice = BrokenOnDeathItem.getRepairPrice(ItemID.AVERNIC_DEFENDER);
|
||||||
|
final int defenderExpectedPrice = (defenderBrokenPrice == null ? 0 : defenderBrokenPrice) + defenderOffset;
|
||||||
|
assertEquals(defenderExpectedPrice, plugin.getDeathPrice(defender));
|
||||||
|
|
||||||
|
final Item[] inv = new Item[]
|
||||||
|
{
|
||||||
|
defender,
|
||||||
|
mItem(ItemID.BERSERKER_RING_I, 1, "Berserker Ring (i)", false, 3042579)
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin.isSkulled = true;
|
||||||
|
plugin.protectingItem = true;
|
||||||
|
plugin.wildyLevel = 21;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, new Item[0]);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
assertTrue(kept.contains(new ItemStack(ItemID.AVERNIC_DEFENDER, 1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -453,6 +453,49 @@ public class SlayerPluginTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCorrectlyCapturedTaskKill()
|
||||||
|
{
|
||||||
|
final Player player = mock(Player.class);
|
||||||
|
when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0));
|
||||||
|
when(client.getLocalPlayer()).thenReturn(player);
|
||||||
|
|
||||||
|
final ExperienceChanged experienceChanged = new ExperienceChanged();
|
||||||
|
experienceChanged.setSkill(Skill.SLAYER);
|
||||||
|
|
||||||
|
when(client.getSkillExperience(Skill.SLAYER)).thenReturn(100);
|
||||||
|
slayerPlugin.onExperienceChanged(experienceChanged);
|
||||||
|
|
||||||
|
slayerPlugin.setTask("Dagannoth", 143, 143, true, 0);
|
||||||
|
|
||||||
|
when(client.getSkillExperience(Skill.SLAYER)).thenReturn(110);
|
||||||
|
slayerPlugin.onExperienceChanged(experienceChanged);
|
||||||
|
|
||||||
|
assertEquals(142, slayerPlugin.getCurrentTask().getAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIncorrectlyCapturedTaskKill()
|
||||||
|
{
|
||||||
|
final Player player = mock(Player.class);
|
||||||
|
when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0));
|
||||||
|
when(client.getLocalPlayer()).thenReturn(player);
|
||||||
|
|
||||||
|
final ExperienceChanged experienceChanged = new ExperienceChanged();
|
||||||
|
experienceChanged.setSkill(Skill.SLAYER);
|
||||||
|
|
||||||
|
when(client.getSkillExperience(Skill.SLAYER)).thenReturn(100);
|
||||||
|
slayerPlugin.onExperienceChanged(experienceChanged);
|
||||||
|
|
||||||
|
slayerPlugin.setTask("Monster", 98, 98, true, 0);
|
||||||
|
assert Task.getTask("Monster") == null;
|
||||||
|
|
||||||
|
when(client.getSkillExperience(Skill.SLAYER)).thenReturn(110);
|
||||||
|
slayerPlugin.onExperienceChanged(experienceChanged);
|
||||||
|
|
||||||
|
assertEquals(97, slayerPlugin.getCurrentTask().getAmount());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testJadTaskKill()
|
public void testJadTaskKill()
|
||||||
{
|
{
|
||||||
@@ -508,4 +551,25 @@ public class SlayerPluginTest
|
|||||||
|
|
||||||
assertEquals(0, slayerPlugin.getCurrentTask().getAmount());
|
assertEquals(0, slayerPlugin.getCurrentTask().getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNewAccountSlayerKill()
|
||||||
|
{
|
||||||
|
final Player player = mock(Player.class);
|
||||||
|
when(player.getLocalLocation()).thenReturn(new LocalPoint(0, 0));
|
||||||
|
when(client.getLocalPlayer()).thenReturn(player);
|
||||||
|
|
||||||
|
final ExperienceChanged experienceChanged = new ExperienceChanged();
|
||||||
|
experienceChanged.setSkill(Skill.SLAYER);
|
||||||
|
|
||||||
|
slayerPlugin.setTask("Bears", 35, 35, true, 0);
|
||||||
|
|
||||||
|
when(client.getSkillExperience(Skill.SLAYER)).thenReturn(0);
|
||||||
|
slayerPlugin.onExperienceChanged(experienceChanged);
|
||||||
|
|
||||||
|
when(client.getSkillExperience(Skill.SLAYER)).thenReturn(27);
|
||||||
|
slayerPlugin.onExperienceChanged(experienceChanged);
|
||||||
|
|
||||||
|
assertEquals(34, slayerPlugin.getCurrentTask().getAmount());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user