Merge remote-tracking branch 'upstream/master' into master
This commit is contained in:
@@ -395,4 +395,16 @@ public final class ScriptID
|
|||||||
*/
|
*/
|
||||||
@ScriptArguments(integer = 14, string = 3)
|
@ScriptArguments(integer = 14, string = 3)
|
||||||
public static final int CHATBOX_BUILD_LINE_WITH_CLAN = 4483;
|
public static final int CHATBOX_BUILD_LINE_WITH_CLAN = 4483;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drag callback for the camera zoom slider in the options side panel.
|
||||||
|
*/
|
||||||
|
@ScriptArguments(integer = 3)
|
||||||
|
public static final int ZOOM_SLIDER_ONDRAG = 833;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drag callback for the camera zoom slider in the settings.
|
||||||
|
*/
|
||||||
|
@ScriptArguments(integer = 6)
|
||||||
|
public static final int SETTINGS_ZOOM_SLIDER_ONDRAG = 3896;
|
||||||
}
|
}
|
||||||
@@ -1584,6 +1584,7 @@ public final class SpriteID
|
|||||||
public static final int HEALTHBAR_DEFAULT_BACK_140PX = 2189;
|
public static final int HEALTHBAR_DEFAULT_BACK_140PX = 2189;
|
||||||
public static final int HEALTHBAR_DEFAULT_FRONT_160PX = 2190;
|
public static final int HEALTHBAR_DEFAULT_FRONT_160PX = 2190;
|
||||||
public static final int HEALTHBAR_DEFAULT_BACK_160PX = 2191;
|
public static final int HEALTHBAR_DEFAULT_BACK_160PX = 2191;
|
||||||
|
public static final int TAB_CLAN_CHAT = 2307;
|
||||||
public static final int WIKI_DESELECTED = 2420;
|
public static final int WIKI_DESELECTED = 2420;
|
||||||
public static final int WIKI_SELECTED = 2421;
|
public static final int WIKI_SELECTED = 2421;
|
||||||
public static final int FRIENDS_CHAT_RANK_SMILEY_FRIEND = 2825;
|
public static final int FRIENDS_CHAT_RANK_SMILEY_FRIEND = 2825;
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021, 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.api.events;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import lombok.Value;
|
||||||
|
import net.runelite.api.clan.ClanChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event fired when the local player joins or leaves a clan channel.
|
||||||
|
*/
|
||||||
|
@Value
|
||||||
|
public class ClanChannelChanged
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The clan channel
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private final ClanChannel clanChannel;
|
||||||
|
/**
|
||||||
|
* Whether or not this was the guest clan channel
|
||||||
|
*/
|
||||||
|
private boolean guest;
|
||||||
|
}
|
||||||
@@ -85,6 +85,7 @@ import net.runelite.http.api.worlds.World;
|
|||||||
import net.runelite.http.api.worlds.WorldResult;
|
import net.runelite.http.api.worlds.WorldResult;
|
||||||
import okhttp3.Cache;
|
import okhttp3.Cache;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Response;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -261,8 +262,8 @@ public class RuneLite
|
|||||||
|
|
||||||
OpenOSRS.preload();
|
OpenOSRS.preload();
|
||||||
|
|
||||||
OkHttpClient.Builder okHttpClientBuilder = RuneLiteAPI.CLIENT.newBuilder()
|
OkHttpClient.Builder okHttpClientBuilder = RuneLiteAPI.CLIENT.newBuilder();
|
||||||
.cache(new Cache(new File(CACHE_DIR, "okhttp"), MAX_OKHTTP_CACHE_SIZE));
|
setupCache(okHttpClientBuilder, new File(CACHE_DIR, "okhttp"));
|
||||||
|
|
||||||
final boolean insecureSkipTlsVerification = options.has("insecure-skip-tls-verification");
|
final boolean insecureSkipTlsVerification = options.has("insecure-skip-tls-verification");
|
||||||
if (insecureSkipTlsVerification || RuneLiteProperties.isInsecureSkipTlsVerification())
|
if (insecureSkipTlsVerification || RuneLiteProperties.isInsecureSkipTlsVerification())
|
||||||
@@ -496,6 +497,25 @@ public class RuneLite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static void setupCache(OkHttpClient.Builder builder, File cacheDir)
|
||||||
|
{
|
||||||
|
builder.cache(new Cache(cacheDir, MAX_OKHTTP_CACHE_SIZE))
|
||||||
|
.addNetworkInterceptor(chain ->
|
||||||
|
{
|
||||||
|
// This has to be a network interceptor so it gets hit before the cache tries to store stuff
|
||||||
|
Response res = chain.proceed(chain.request());
|
||||||
|
if (res.code() >= 400 && "GET".equals(res.request().method()))
|
||||||
|
{
|
||||||
|
// if the request 404'd we don't want to cache it because its probably temporary
|
||||||
|
res = res.newBuilder()
|
||||||
|
.header("Cache-Control", "no-store")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static void setupInsecureTrustManager(OkHttpClient.Builder okHttpClientBuilder)
|
private static void setupInsecureTrustManager(OkHttpClient.Builder okHttpClientBuilder)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ package net.runelite.client.game;
|
|||||||
|
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.inject.Inject;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
@@ -48,20 +48,23 @@ import net.runelite.client.util.ImageUtil;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class SpriteManager
|
public class SpriteManager
|
||||||
{
|
{
|
||||||
@Inject
|
private final Client client;
|
||||||
private Client client;
|
private final ClientThread clientThread;
|
||||||
|
private final InfoBoxManager infoBoxManager;
|
||||||
|
|
||||||
@Inject
|
private final Cache<Long, BufferedImage> cache = CacheBuilder.newBuilder()
|
||||||
private ClientThread clientThread;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private InfoBoxManager infoBoxManager;
|
|
||||||
|
|
||||||
public Cache<Long, BufferedImage> cache = CacheBuilder.newBuilder()
|
|
||||||
.maximumSize(128L)
|
.maximumSize(128L)
|
||||||
.expireAfterAccess(1, TimeUnit.HOURS)
|
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SpriteManager(Client client, ClientThread clientThread, InfoBoxManager infoBoxManager)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.clientThread = clientThread;
|
||||||
|
this.infoBoxManager = infoBoxManager;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public BufferedImage getSprite(int archive, int file)
|
public BufferedImage getSprite(int archive, int file)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -367,15 +367,23 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
|
|||||||
@Subscribe
|
@Subscribe
|
||||||
private void onScriptPreFired(ScriptPreFired ev)
|
private void onScriptPreFired(ScriptPreFired ev)
|
||||||
{
|
{
|
||||||
if (ev.getScriptId() == ScriptID.SETTINGS_SLIDER_CHOOSE_ONOP)
|
switch (ev.getScriptId())
|
||||||
{
|
{
|
||||||
int arg = client.getIntStackSize() - 7;
|
case ScriptID.SETTINGS_SLIDER_CHOOSE_ONOP:
|
||||||
int[] is = client.getIntStack();
|
|
||||||
|
|
||||||
if (is[arg] == SettingID.CAMERA_ZOOM)
|
|
||||||
{
|
{
|
||||||
addZoomTooltip(client.getScriptActiveWidget());
|
int arg = client.getIntStackSize() - 7;
|
||||||
|
int[] is = client.getIntStack();
|
||||||
|
|
||||||
|
if (is[arg] == SettingID.CAMERA_ZOOM)
|
||||||
|
{
|
||||||
|
addZoomTooltip(client.getScriptActiveWidget());
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case ScriptID.ZOOM_SLIDER_ONDRAG:
|
||||||
|
case ScriptID.SETTINGS_ZOOM_SLIDER_ONDRAG:
|
||||||
|
sliderTooltip = makeSliderTooltip();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,12 +398,14 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
|
|||||||
|
|
||||||
private void addZoomTooltip(Widget w)
|
private void addZoomTooltip(Widget w)
|
||||||
{
|
{
|
||||||
w.setOnMouseRepeatListener((JavaScriptCallback) ev ->
|
w.setOnMouseRepeatListener((JavaScriptCallback) ev -> sliderTooltip = makeSliderTooltip());
|
||||||
{
|
}
|
||||||
int value = client.getVar(VarClientInt.CAMERA_ZOOM_RESIZABLE_VIEWPORT);
|
|
||||||
int max = config.innerLimit() ? config.INNER_ZOOM_LIMIT : CameraPlugin.DEFAULT_INNER_ZOOM_LIMIT;
|
private Tooltip makeSliderTooltip()
|
||||||
sliderTooltip = new Tooltip("Camera Zoom: " + value + " / " + max);
|
{
|
||||||
});
|
int value = client.getVar(VarClientInt.CAMERA_ZOOM_RESIZABLE_VIEWPORT);
|
||||||
|
int max = config.innerLimit() ? config.INNER_ZOOM_LIMIT : CameraPlugin.DEFAULT_INNER_ZOOM_LIMIT;
|
||||||
|
return new Tooltip("Camera Zoom: " + value + " / " + max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -92,18 +92,6 @@ public interface ChatChannelConfig extends Config
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
|
||||||
keyName = "clanCounter",
|
|
||||||
name = "Members Counter",
|
|
||||||
description = "Show the amount of friends chat members near you.",
|
|
||||||
position = 3,
|
|
||||||
section = friendsChatSection
|
|
||||||
)
|
|
||||||
default boolean showCounter()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "chatsData",
|
keyName = "chatsData",
|
||||||
name = "",
|
name = "",
|
||||||
@@ -129,7 +117,7 @@ public interface ChatChannelConfig extends Config
|
|||||||
position = 4,
|
position = 4,
|
||||||
section = friendsChatSection
|
section = friendsChatSection
|
||||||
)
|
)
|
||||||
default boolean showJoinLeave()
|
default boolean showFriendsChatJoinLeave()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.util.concurrent.Runnables;
|
import com.google.common.util.concurrent.Runnables;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
@@ -53,9 +52,7 @@ import net.runelite.api.GameState;
|
|||||||
import net.runelite.api.Ignore;
|
import net.runelite.api.Ignore;
|
||||||
import net.runelite.api.MessageNode;
|
import net.runelite.api.MessageNode;
|
||||||
import net.runelite.api.NameableContainer;
|
import net.runelite.api.NameableContainer;
|
||||||
import net.runelite.api.Player;
|
|
||||||
import net.runelite.api.ScriptID;
|
import net.runelite.api.ScriptID;
|
||||||
import net.runelite.api.SpriteID;
|
|
||||||
import net.runelite.api.VarClientStr;
|
import net.runelite.api.VarClientStr;
|
||||||
import net.runelite.api.Varbits;
|
import net.runelite.api.Varbits;
|
||||||
import net.runelite.api.clan.ClanChannel;
|
import net.runelite.api.clan.ClanChannel;
|
||||||
@@ -71,8 +68,6 @@ import net.runelite.api.events.FriendsChatMemberJoined;
|
|||||||
import net.runelite.api.events.FriendsChatMemberLeft;
|
import net.runelite.api.events.FriendsChatMemberLeft;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
import net.runelite.api.events.GameStateChanged;
|
||||||
import net.runelite.api.events.GameTick;
|
import net.runelite.api.events.GameTick;
|
||||||
import net.runelite.api.events.PlayerDespawned;
|
|
||||||
import net.runelite.api.events.PlayerSpawned;
|
|
||||||
import net.runelite.api.events.ScriptCallbackEvent;
|
import net.runelite.api.events.ScriptCallbackEvent;
|
||||||
import net.runelite.api.events.ScriptPostFired;
|
import net.runelite.api.events.ScriptPostFired;
|
||||||
import net.runelite.api.events.VarClientStrChanged;
|
import net.runelite.api.events.VarClientStrChanged;
|
||||||
@@ -88,7 +83,6 @@ import net.runelite.client.config.ConfigManager;
|
|||||||
import net.runelite.client.eventbus.Subscribe;
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
import net.runelite.client.events.ConfigChanged;
|
import net.runelite.client.events.ConfigChanged;
|
||||||
import net.runelite.client.game.ChatIconManager;
|
import net.runelite.client.game.ChatIconManager;
|
||||||
import net.runelite.client.game.SpriteManager;
|
|
||||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
@@ -96,7 +90,6 @@ import static net.runelite.client.ui.JagexColors.CHAT_FC_NAME_OPAQUE_BACKGROUND;
|
|||||||
import static net.runelite.client.ui.JagexColors.CHAT_FC_NAME_TRANSPARENT_BACKGROUND;
|
import static net.runelite.client.ui.JagexColors.CHAT_FC_NAME_TRANSPARENT_BACKGROUND;
|
||||||
import static net.runelite.client.ui.JagexColors.CHAT_FC_TEXT_OPAQUE_BACKGROUND;
|
import static net.runelite.client.ui.JagexColors.CHAT_FC_TEXT_OPAQUE_BACKGROUND;
|
||||||
import static net.runelite.client.ui.JagexColors.CHAT_FC_TEXT_TRANSPARENT_BACKGROUND;
|
import static net.runelite.client.ui.JagexColors.CHAT_FC_TEXT_TRANSPARENT_BACKGROUND;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
|
||||||
import net.runelite.client.util.Text;
|
import net.runelite.client.util.Text;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
@@ -119,12 +112,6 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ChatChannelConfig config;
|
private ChatChannelConfig config;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private InfoBoxManager infoBoxManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private SpriteManager spriteManager;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientThread clientThread;
|
private ClientThread clientThread;
|
||||||
|
|
||||||
@@ -138,8 +125,6 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
private ChatMessageManager chatMessageManager;
|
private ChatMessageManager chatMessageManager;
|
||||||
|
|
||||||
private List<String> chats;
|
private List<String> chats;
|
||||||
private final List<Player> members = new ArrayList<>();
|
|
||||||
private MembersIndicator membersIndicator;
|
|
||||||
/**
|
/**
|
||||||
* queue of temporary messages added to the client
|
* queue of temporary messages added to the client
|
||||||
*/
|
*/
|
||||||
@@ -186,8 +171,6 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
chats = null;
|
chats = null;
|
||||||
clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE));
|
clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE));
|
||||||
members.clear();
|
|
||||||
resetCounter();
|
|
||||||
rebuildFriendsChat();
|
rebuildFriendsChat();
|
||||||
inputMode = null;
|
inputMode = null;
|
||||||
}
|
}
|
||||||
@@ -202,15 +185,6 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
rebuildFriendsChat();
|
rebuildFriendsChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.showCounter())
|
|
||||||
{
|
|
||||||
clientThread.invoke(this::addCounter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resetCounter();
|
|
||||||
}
|
|
||||||
|
|
||||||
Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE;
|
Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE;
|
||||||
clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor));
|
clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor));
|
||||||
}
|
}
|
||||||
@@ -221,29 +195,13 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
final FriendsChatMember member = event.getMember();
|
final FriendsChatMember member = event.getMember();
|
||||||
|
|
||||||
if (member.getWorld() == client.getWorld())
|
|
||||||
{
|
|
||||||
final Player local = client.getLocalPlayer();
|
|
||||||
final String memberName = Text.toJagexName(member.getName());
|
|
||||||
|
|
||||||
for (final Player player : client.getPlayers())
|
|
||||||
{
|
|
||||||
if (player != null && player != local && memberName.equals(Text.toJagexName(player.getName())))
|
|
||||||
{
|
|
||||||
members.add(player);
|
|
||||||
addCounter();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// members getting initialized isn't relevant
|
// members getting initialized isn't relevant
|
||||||
if (joinedTick == client.getTickCount())
|
if (joinedTick == client.getTickCount())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config.showJoinLeave() ||
|
if (!config.showFriendsChatJoinLeave() ||
|
||||||
member.getRank().getValue() < config.joinLeaveRank().getValue())
|
member.getRank().getValue() < config.joinLeaveRank().getValue())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -258,28 +216,7 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
final FriendsChatMember member = event.getMember();
|
final FriendsChatMember member = event.getMember();
|
||||||
|
|
||||||
if (member.getWorld() == client.getWorld())
|
if (!config.showFriendsChatJoinLeave() ||
|
||||||
{
|
|
||||||
final String memberName = Text.toJagexName(member.getName());
|
|
||||||
final Iterator<Player> each = members.iterator();
|
|
||||||
|
|
||||||
while (each.hasNext())
|
|
||||||
{
|
|
||||||
if (memberName.equals(Text.toJagexName(each.next().getName())))
|
|
||||||
{
|
|
||||||
each.remove();
|
|
||||||
|
|
||||||
if (members.isEmpty())
|
|
||||||
{
|
|
||||||
resetCounter();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.showJoinLeave() ||
|
|
||||||
member.getRank().getValue() < config.joinLeaveRank().getValue())
|
member.getRank().getValue() < config.joinLeaveRank().getValue())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -378,11 +315,6 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config.showJoinLeave())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeoutMessages();
|
timeoutMessages();
|
||||||
|
|
||||||
addActivityMessages();
|
addActivityMessages();
|
||||||
@@ -625,35 +557,10 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
|
|
||||||
if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.CONNECTION_LOST || gameState == GameState.HOPPING)
|
if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.CONNECTION_LOST || gameState == GameState.HOPPING)
|
||||||
{
|
{
|
||||||
members.clear();
|
|
||||||
resetCounter();
|
|
||||||
|
|
||||||
joinMessages.clear();
|
joinMessages.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onPlayerSpawned(PlayerSpawned event)
|
|
||||||
{
|
|
||||||
final Player local = client.getLocalPlayer();
|
|
||||||
final Player player = event.getPlayer();
|
|
||||||
|
|
||||||
if (player != local && player.isFriendsChatMember())
|
|
||||||
{
|
|
||||||
members.add(player);
|
|
||||||
addCounter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onPlayerDespawned(PlayerDespawned event)
|
|
||||||
{
|
|
||||||
if (members.remove(event.getPlayer()) && members.isEmpty())
|
|
||||||
{
|
|
||||||
resetCounter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onFriendsChatChanged(FriendsChatChanged event)
|
public void onFriendsChatChanged(FriendsChatChanged event)
|
||||||
{
|
{
|
||||||
@@ -661,11 +568,6 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
joinedTick = client.getTickCount();
|
joinedTick = client.getTickCount();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
members.clear();
|
|
||||||
resetCounter();
|
|
||||||
}
|
|
||||||
|
|
||||||
activityBuffer.clear();
|
activityBuffer.clear();
|
||||||
}
|
}
|
||||||
@@ -779,14 +681,9 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMembersSize()
|
|
||||||
{
|
|
||||||
return members.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertRankIcon(final ChatMessage message)
|
private void insertRankIcon(final ChatMessage message)
|
||||||
{
|
{
|
||||||
final FriendsChatRank rank = getRank(message.getName());
|
final FriendsChatRank rank = getRank(Text.removeTags(message.getName()));
|
||||||
|
|
||||||
if (rank != null && rank != FriendsChatRank.UNRANKED)
|
if (rank != null && rank != FriendsChatRank.UNRANKED)
|
||||||
{
|
{
|
||||||
@@ -879,24 +776,6 @@ public class ChatChannelPlugin extends Plugin
|
|||||||
config.chatsData(Text.toCSV(chats));
|
config.chatsData(Text.toCSV(chats));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetCounter()
|
|
||||||
{
|
|
||||||
infoBoxManager.removeInfoBox(membersIndicator);
|
|
||||||
membersIndicator = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addCounter()
|
|
||||||
{
|
|
||||||
if (!config.showCounter() || membersIndicator != null || members.isEmpty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final BufferedImage image = spriteManager.getSprite(SpriteID.TAB_FRIENDS_CHAT, 0);
|
|
||||||
membersIndicator = new MembersIndicator(image, this);
|
|
||||||
infoBoxManager.addInfoBox(membersIndicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void confirmKickPlayer(final String kickPlayerName)
|
private void confirmKickPlayer(final String kickPlayerName)
|
||||||
{
|
{
|
||||||
chatboxPanelManager.openTextMenuInput("Attempting to kick: " + kickPlayerName)
|
chatboxPanelManager.openTextMenuInput("Attempting to kick: " + kickPlayerName)
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import net.runelite.api.MessageNode;
|
|||||||
import net.runelite.api.Player;
|
import net.runelite.api.Player;
|
||||||
import net.runelite.api.clan.ClanChannel;
|
import net.runelite.api.clan.ClanChannel;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.GameStateChanged;
|
||||||
import net.runelite.api.events.OverheadTextChanged;
|
import net.runelite.api.events.OverheadTextChanged;
|
||||||
import net.runelite.api.events.ScriptCallbackEvent;
|
import net.runelite.api.events.ScriptCallbackEvent;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
@@ -139,6 +140,19 @@ public class ChatFilterPlugin extends Plugin
|
|||||||
client.refreshChat();
|
client.refreshChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||||
|
{
|
||||||
|
switch (gameStateChanged.getGameState())
|
||||||
|
{
|
||||||
|
// Login drops references to all messages and also resets the global message id counter.
|
||||||
|
// Invalidate the message id so it doesn't collide later when rebuilding the chatfilter.
|
||||||
|
case HOPPING:
|
||||||
|
case LOGGING_IN:
|
||||||
|
duplicateChatCache.values().forEach(d -> d.messageId = -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||||
{
|
{
|
||||||
@@ -205,7 +219,10 @@ public class ChatFilterPlugin extends Plugin
|
|||||||
if (!blockMessage && shouldCollapse)
|
if (!blockMessage && shouldCollapse)
|
||||||
{
|
{
|
||||||
Duplicate duplicateCacheEntry = duplicateChatCache.get(name + ":" + message);
|
Duplicate duplicateCacheEntry = duplicateChatCache.get(name + ":" + message);
|
||||||
if (duplicateCacheEntry != null)
|
// If messageId is -1 then this is a replayed message, which we can't easily collapse since we don't know
|
||||||
|
// the most recent message. This is only for public chat since it is the only thing both replayed and also
|
||||||
|
// collapsed. Just allow uncollapsed playback.
|
||||||
|
if (duplicateCacheEntry != null && duplicateCacheEntry.messageId != -1)
|
||||||
{
|
{
|
||||||
blockMessage = duplicateCacheEntry.messageId != messageId ||
|
blockMessage = duplicateCacheEntry.messageId != messageId ||
|
||||||
((chatMessageType == PUBLICCHAT || chatMessageType == MODCHAT) &&
|
((chatMessageType == PUBLICCHAT || chatMessageType == MODCHAT) &&
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import net.runelite.api.clan.ClanChannelMember;
|
|||||||
import net.runelite.api.clan.ClanRank;
|
import net.runelite.api.clan.ClanRank;
|
||||||
import net.runelite.api.clan.ClanSettings;
|
import net.runelite.api.clan.ClanSettings;
|
||||||
import net.runelite.api.clan.ClanTitle;
|
import net.runelite.api.clan.ClanTitle;
|
||||||
|
import net.runelite.client.util.Text;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class PlayerIndicatorsService
|
public class PlayerIndicatorsService
|
||||||
@@ -130,7 +131,7 @@ public class PlayerIndicatorsService
|
|||||||
return FriendsChatRank.UNRANKED;
|
return FriendsChatRank.UNRANKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
FriendsChatMember friendsChatMember = friendsChatManager.findByName(player.getName());
|
FriendsChatMember friendsChatMember = friendsChatManager.findByName(Text.removeTags(player.getName()));
|
||||||
return friendsChatMember != null ? friendsChatMember.getRank() : FriendsChatRank.UNRANKED;
|
return friendsChatMember != null ? friendsChatMember.getRank() : FriendsChatRank.UNRANKED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,32 +22,18 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.chatchannel;
|
package net.runelite.client.plugins.team;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||||
|
|
||||||
class MembersIndicator extends Counter
|
abstract class MembersIndicator extends InfoBox
|
||||||
{
|
{
|
||||||
private final ChatChannelPlugin plugin;
|
MembersIndicator(BufferedImage image, Plugin plugin)
|
||||||
|
|
||||||
MembersIndicator(BufferedImage image, ChatChannelPlugin plugin)
|
|
||||||
{
|
{
|
||||||
super(image, plugin, plugin.getMembersSize());
|
super(image, plugin);
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount()
|
|
||||||
{
|
|
||||||
return plugin.getMembersSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTooltip()
|
|
||||||
{
|
|
||||||
return plugin.getMembersSize() + " friends chat member(s) near you";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.teamcapes;
|
package net.runelite.client.plugins.team;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
@@ -41,12 +41,12 @@ import net.runelite.client.ui.overlay.components.ImageComponent;
|
|||||||
|
|
||||||
class TeamCapesOverlay extends OverlayPanel
|
class TeamCapesOverlay extends OverlayPanel
|
||||||
{
|
{
|
||||||
private final TeamCapesPlugin plugin;
|
private final TeamPlugin plugin;
|
||||||
private final TeamCapesConfig config;
|
private final TeamConfig config;
|
||||||
private final ItemManager manager;
|
private final ItemManager manager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TeamCapesOverlay(TeamCapesPlugin plugin, TeamCapesConfig config, ItemManager manager)
|
private TeamCapesOverlay(TeamPlugin plugin, TeamConfig config, ItemManager manager)
|
||||||
{
|
{
|
||||||
super(plugin);
|
super(plugin);
|
||||||
setPosition(OverlayPosition.TOP_LEFT);
|
setPosition(OverlayPosition.TOP_LEFT);
|
||||||
@@ -63,7 +63,7 @@ class TeamCapesOverlay extends OverlayPanel
|
|||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
Map<Integer, Integer> teams = plugin.getTeams();
|
Map<Integer, Integer> teams = plugin.getTeams();
|
||||||
if (teams.isEmpty())
|
if (teams.isEmpty() || !config.teamCapesOverlay())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Mathieu Bernier <https://github.com/Matsyir>
|
||||||
|
* 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.team;
|
||||||
|
|
||||||
|
import net.runelite.client.config.Config;
|
||||||
|
import net.runelite.client.config.ConfigGroup;
|
||||||
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
import net.runelite.client.config.ConfigSection;
|
||||||
|
|
||||||
|
@ConfigGroup(TeamConfig.GROUP)
|
||||||
|
public interface TeamConfig extends Config
|
||||||
|
{
|
||||||
|
String GROUP = "teamCapes";
|
||||||
|
|
||||||
|
@ConfigSection(
|
||||||
|
name = "Team",
|
||||||
|
description = "Configuration for teams",
|
||||||
|
position = 10
|
||||||
|
)
|
||||||
|
String teamSection = "teamSection";
|
||||||
|
|
||||||
|
@ConfigSection(
|
||||||
|
name = "Friends Chat",
|
||||||
|
description = "Configuration for friends chat",
|
||||||
|
position = 20
|
||||||
|
)
|
||||||
|
String friendsChatSection = "friendsChatSection";
|
||||||
|
|
||||||
|
@ConfigSection(
|
||||||
|
name = "Clan Chat",
|
||||||
|
description = "Configuration for clan chat",
|
||||||
|
position = 30
|
||||||
|
)
|
||||||
|
String clanChatSection = "clanChatSection";
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "teamCapesOverlay",
|
||||||
|
name = "Team cape overlay",
|
||||||
|
description = "Configures whether to show the team cape overlay.",
|
||||||
|
position = 0,
|
||||||
|
section = teamSection
|
||||||
|
)
|
||||||
|
default boolean teamCapesOverlay()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "minimumCapeCount",
|
||||||
|
name = "Minimum Cape Count",
|
||||||
|
description = "Configures the minimum number of team capes which must be present before being displayed.",
|
||||||
|
position = 1,
|
||||||
|
section = teamSection
|
||||||
|
)
|
||||||
|
default int getMinimumCapeCount()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "friendsChatMemberCounter",
|
||||||
|
name = "Friends Chat Members Counter",
|
||||||
|
description = "Show the amount of friends chat members near you.",
|
||||||
|
position = 0,
|
||||||
|
section = friendsChatSection
|
||||||
|
)
|
||||||
|
default boolean friendsChatMemberCounter()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "clanChatMemberCounter",
|
||||||
|
name = "Clan Chat Members Counter",
|
||||||
|
description = "Show the amount of clan chat members near you.",
|
||||||
|
position = 0,
|
||||||
|
section = clanChatSection
|
||||||
|
)
|
||||||
|
default boolean clanChatMemberCounter()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||||
|
* Copyright (c) 2021, 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.team;
|
||||||
|
|
||||||
|
import com.google.common.collect.BiMap;
|
||||||
|
import com.google.common.collect.HashBiMap;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.FriendsChatMember;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.Player;
|
||||||
|
import net.runelite.api.SpriteID;
|
||||||
|
import net.runelite.api.clan.ClanChannel;
|
||||||
|
import net.runelite.api.clan.ClanChannelMember;
|
||||||
|
import net.runelite.api.events.ClanChannelChanged;
|
||||||
|
import net.runelite.api.events.ClanMemberJoined;
|
||||||
|
import net.runelite.api.events.ClanMemberLeft;
|
||||||
|
import net.runelite.api.events.FriendsChatChanged;
|
||||||
|
import net.runelite.api.events.FriendsChatMemberJoined;
|
||||||
|
import net.runelite.api.events.FriendsChatMemberLeft;
|
||||||
|
import net.runelite.api.events.GameStateChanged;
|
||||||
|
import net.runelite.api.events.PlayerChanged;
|
||||||
|
import net.runelite.api.events.PlayerDespawned;
|
||||||
|
import net.runelite.api.events.PlayerSpawned;
|
||||||
|
import net.runelite.client.callback.ClientThread;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.events.ConfigChanged;
|
||||||
|
import net.runelite.client.game.SpriteManager;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
|
import net.runelite.client.util.Text;
|
||||||
|
|
||||||
|
@PluginDescriptor(
|
||||||
|
name = "Team",
|
||||||
|
description = "Shows how many team and clan mates are nearby",
|
||||||
|
tags = {"overlay", "players", "cape", "clan", "friend"},
|
||||||
|
configName = "TeamCapesPlugin", // the old plugin's name
|
||||||
|
enabledByDefault = false
|
||||||
|
)
|
||||||
|
@Slf4j
|
||||||
|
public class TeamPlugin extends Plugin
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ClientThread clientThread;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TeamConfig config;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TeamCapesOverlay overlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SpriteManager spriteManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private InfoBoxManager infoBoxManager;
|
||||||
|
|
||||||
|
// Team number -> Number of players
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private Map<Integer, Integer> teams = new LinkedHashMap<>();
|
||||||
|
// Player -> Team number
|
||||||
|
private final Map<Player, Integer> playerTeam = new HashMap<>();
|
||||||
|
|
||||||
|
private final BiMap<String, Player> players = HashBiMap.create();
|
||||||
|
private int friendsChatCount;
|
||||||
|
private int clanChatCount;
|
||||||
|
private MembersIndicator friendsChatIndicator;
|
||||||
|
private MembersIndicator clanChatIndicator;
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
TeamConfig provideConfig(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
return configManager.getConfig(TeamConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startUp() throws Exception
|
||||||
|
{
|
||||||
|
overlayManager.add(overlay);
|
||||||
|
|
||||||
|
clientThread.invokeLater(() -> client.getPlayers().forEach(this::updateTeam));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
overlayManager.remove(overlay);
|
||||||
|
teams.clear();
|
||||||
|
playerTeam.clear();
|
||||||
|
players.clear();
|
||||||
|
removeFriendsChatCounter();
|
||||||
|
removeClanChatCounter();
|
||||||
|
friendsChatCount = 0;
|
||||||
|
clanChatCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onConfigChanged(ConfigChanged configChanged)
|
||||||
|
{
|
||||||
|
if (configChanged.getGroup().equals(TeamConfig.GROUP))
|
||||||
|
{
|
||||||
|
if (config.friendsChatMemberCounter())
|
||||||
|
{
|
||||||
|
clientThread.invoke(this::addFriendsChatCounter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeFriendsChatCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.clanChatMemberCounter())
|
||||||
|
{
|
||||||
|
clientThread.invoke(this::addClanChatCounter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeClanChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameStateChanged(GameStateChanged state)
|
||||||
|
{
|
||||||
|
GameState gameState = state.getGameState();
|
||||||
|
|
||||||
|
if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.CONNECTION_LOST || gameState == GameState.HOPPING)
|
||||||
|
{
|
||||||
|
players.clear();
|
||||||
|
removeFriendsChatCounter();
|
||||||
|
removeClanChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onPlayerSpawned(PlayerSpawned event)
|
||||||
|
{
|
||||||
|
final Player local = client.getLocalPlayer();
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
|
||||||
|
if (player != local)
|
||||||
|
{
|
||||||
|
players.put(Text.removeTags(player.getName()), player);
|
||||||
|
|
||||||
|
if (player.isFriendsChatMember())
|
||||||
|
{
|
||||||
|
++friendsChatCount;
|
||||||
|
addFriendsChatCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.isClanMember())
|
||||||
|
{
|
||||||
|
++clanChatCount;
|
||||||
|
addClanChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onPlayerDespawned(PlayerDespawned playerDespawned)
|
||||||
|
{
|
||||||
|
Player player = playerDespawned.getPlayer();
|
||||||
|
Integer team = playerTeam.remove(player);
|
||||||
|
if (team != null)
|
||||||
|
{
|
||||||
|
teams.computeIfPresent(team, (key, value) -> value > 1 ? value - 1 : null);
|
||||||
|
sortTeams();
|
||||||
|
}
|
||||||
|
|
||||||
|
players.inverse().remove(player);
|
||||||
|
|
||||||
|
if (player.isFriendsChatMember())
|
||||||
|
{
|
||||||
|
if (friendsChatCount > 0)
|
||||||
|
{
|
||||||
|
if (--friendsChatCount == 0)
|
||||||
|
{
|
||||||
|
removeFriendsChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.isClanMember())
|
||||||
|
{
|
||||||
|
if (clanChatCount > 0)
|
||||||
|
{
|
||||||
|
if (--clanChatCount == 0)
|
||||||
|
{
|
||||||
|
removeClanChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onPlayerChanged(PlayerChanged playerChanged)
|
||||||
|
{
|
||||||
|
Player player = playerChanged.getPlayer();
|
||||||
|
updateTeam(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTeam(Player player)
|
||||||
|
{
|
||||||
|
int oldTeam = playerTeam.getOrDefault(player, 0);
|
||||||
|
if (oldTeam == player.getTeam())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("{} has changed teams: {} -> {}", player.getName(), oldTeam, player.getTeam());
|
||||||
|
|
||||||
|
if (oldTeam > 0)
|
||||||
|
{
|
||||||
|
teams.computeIfPresent(oldTeam, (key, value) -> value > 1 ? value - 1 : null);
|
||||||
|
playerTeam.remove(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.getTeam() > 0)
|
||||||
|
{
|
||||||
|
teams.merge(player.getTeam(), 1, Integer::sum);
|
||||||
|
playerTeam.put(player, player.getTeam());
|
||||||
|
}
|
||||||
|
|
||||||
|
sortTeams();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sortTeams()
|
||||||
|
{
|
||||||
|
// Sort teams by value in descending order and then by key in ascending order, limited to 5 entries
|
||||||
|
teams = teams.entrySet().stream()
|
||||||
|
.sorted(
|
||||||
|
Comparator.comparing(Map.Entry<Integer, Integer>::getValue, Comparator.reverseOrder())
|
||||||
|
.thenComparingInt(Map.Entry::getKey)
|
||||||
|
)
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onFriendsChatChanged(FriendsChatChanged event)
|
||||||
|
{
|
||||||
|
if (!event.isJoined())
|
||||||
|
{
|
||||||
|
removeFriendsChatCounter();
|
||||||
|
friendsChatCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onClanChannelChanged(ClanChannelChanged event)
|
||||||
|
{
|
||||||
|
if (!event.isGuest())
|
||||||
|
{
|
||||||
|
removeClanChatCounter();
|
||||||
|
clanChatCount = 0;
|
||||||
|
|
||||||
|
ClanChannel clanChannel = event.getClanChannel();
|
||||||
|
if (clanChannel != null)
|
||||||
|
{
|
||||||
|
for (ClanChannelMember member : clanChannel.getMembers())
|
||||||
|
{
|
||||||
|
final String memberName = Text.toJagexName(member.getName());
|
||||||
|
|
||||||
|
final Player player = players.get(memberName);
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
++clanChatCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addClanChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onFriendsChatMemberJoined(FriendsChatMemberJoined event)
|
||||||
|
{
|
||||||
|
final FriendsChatMember member = event.getMember();
|
||||||
|
|
||||||
|
if (member.getWorld() == client.getWorld())
|
||||||
|
{
|
||||||
|
final String memberName = Text.toJagexName(member.getName());
|
||||||
|
|
||||||
|
final Player player = players.get(memberName);
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
++friendsChatCount;
|
||||||
|
addFriendsChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onFriendsChatMemberLeft(FriendsChatMemberLeft event)
|
||||||
|
{
|
||||||
|
final FriendsChatMember member = event.getMember();
|
||||||
|
|
||||||
|
if (member.getWorld() == client.getWorld())
|
||||||
|
{
|
||||||
|
final String memberName = Text.toJagexName(member.getName());
|
||||||
|
final Player player = players.get(memberName);
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
if (friendsChatCount > 0)
|
||||||
|
{
|
||||||
|
if (--friendsChatCount == 0)
|
||||||
|
{
|
||||||
|
removeFriendsChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onClanMemberJoined(ClanMemberJoined clanMemberJoined)
|
||||||
|
{
|
||||||
|
final ClanChannelMember member = clanMemberJoined.getClanMember();
|
||||||
|
|
||||||
|
if (member.getWorld() == client.getWorld())
|
||||||
|
{
|
||||||
|
final String memberName = Text.toJagexName(member.getName());
|
||||||
|
|
||||||
|
final Player player = players.get(memberName);
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
++clanChatCount;
|
||||||
|
addClanChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onClanMemberLeft(ClanMemberLeft clanMemberLeft)
|
||||||
|
{
|
||||||
|
final ClanChannelMember member = clanMemberLeft.getClanMember();
|
||||||
|
|
||||||
|
if (member.getWorld() == client.getWorld())
|
||||||
|
{
|
||||||
|
final String memberName = Text.toJagexName(member.getName());
|
||||||
|
final Player player = players.get(memberName);
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
if (clanChatCount > 0)
|
||||||
|
{
|
||||||
|
if (--clanChatCount == 0)
|
||||||
|
{
|
||||||
|
removeClanChatCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFriendsChatCounter()
|
||||||
|
{
|
||||||
|
if (!config.friendsChatMemberCounter() || friendsChatIndicator != null || friendsChatCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BufferedImage image = spriteManager.getSprite(SpriteID.TAB_FRIENDS_CHAT, 0);
|
||||||
|
friendsChatIndicator = new MembersIndicator(image, this)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String getText()
|
||||||
|
{
|
||||||
|
return Integer.toString(friendsChatCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTooltip()
|
||||||
|
{
|
||||||
|
return friendsChatCount + " friends chat member(s) near you";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
infoBoxManager.addInfoBox(friendsChatIndicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFriendsChatCounter()
|
||||||
|
{
|
||||||
|
infoBoxManager.removeInfoBox(friendsChatIndicator);
|
||||||
|
friendsChatIndicator = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addClanChatCounter()
|
||||||
|
{
|
||||||
|
if (!config.clanChatMemberCounter() || clanChatIndicator != null || clanChatCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BufferedImage image = spriteManager.getSprite(SpriteID.TAB_CLAN_CHAT, 0);
|
||||||
|
clanChatIndicator = new MembersIndicator(image, this)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String getText()
|
||||||
|
{
|
||||||
|
return Integer.toString(clanChatCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTooltip()
|
||||||
|
{
|
||||||
|
return clanChatCount + " clan chat member(s) near you";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
infoBoxManager.addInfoBox(clanChatIndicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeClanChatCounter()
|
||||||
|
{
|
||||||
|
infoBoxManager.removeInfoBox(clanChatIndicator);
|
||||||
|
clanChatIndicator = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
|
||||||
* 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.teamcapes;
|
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.Player;
|
|
||||||
import net.runelite.api.events.PlayerChanged;
|
|
||||||
import net.runelite.api.events.PlayerDespawned;
|
|
||||||
import net.runelite.client.callback.ClientThread;
|
|
||||||
import net.runelite.client.config.ConfigManager;
|
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
|
||||||
import net.runelite.client.plugins.Plugin;
|
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
|
||||||
|
|
||||||
@PluginDescriptor(
|
|
||||||
name = "Team Capes",
|
|
||||||
description = "Show the different team capes in your area and the amount of each",
|
|
||||||
tags = {"overlay", "players"},
|
|
||||||
enabledByDefault = false
|
|
||||||
)
|
|
||||||
@Slf4j
|
|
||||||
public class TeamCapesPlugin extends Plugin
|
|
||||||
{
|
|
||||||
@Inject
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ClientThread clientThread;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private OverlayManager overlayManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private TeamCapesOverlay overlay;
|
|
||||||
|
|
||||||
// Team number -> Number of players
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private Map<Integer, Integer> teams = new LinkedHashMap<>();
|
|
||||||
// Player -> Team number
|
|
||||||
private final Map<Player, Integer> playerTeam = new HashMap<>();
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
TeamCapesConfig provideConfig(ConfigManager configManager)
|
|
||||||
{
|
|
||||||
return configManager.getConfig(TeamCapesConfig.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void startUp() throws Exception
|
|
||||||
{
|
|
||||||
overlayManager.add(overlay);
|
|
||||||
|
|
||||||
clientThread.invokeLater(() -> client.getPlayers().forEach(this::update));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void shutDown() throws Exception
|
|
||||||
{
|
|
||||||
overlayManager.remove(overlay);
|
|
||||||
teams.clear();
|
|
||||||
playerTeam.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onPlayerChanged(PlayerChanged playerChanged)
|
|
||||||
{
|
|
||||||
Player player = playerChanged.getPlayer();
|
|
||||||
update(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update(Player player)
|
|
||||||
{
|
|
||||||
int oldTeam = playerTeam.getOrDefault(player, 0);
|
|
||||||
if (oldTeam == player.getTeam())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("{} has changed teams: {} -> {}", player.getName(), oldTeam, player.getTeam());
|
|
||||||
|
|
||||||
if (oldTeam > 0)
|
|
||||||
{
|
|
||||||
teams.computeIfPresent(oldTeam, (key, value) -> value > 1 ? value - 1 : null);
|
|
||||||
playerTeam.remove(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player.getTeam() > 0)
|
|
||||||
{
|
|
||||||
teams.merge(player.getTeam(), 1, Integer::sum);
|
|
||||||
playerTeam.put(player, player.getTeam());
|
|
||||||
}
|
|
||||||
|
|
||||||
sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onPlayerDespawned(PlayerDespawned playerDespawned)
|
|
||||||
{
|
|
||||||
Player player = playerDespawned.getPlayer();
|
|
||||||
Integer team = playerTeam.remove(player);
|
|
||||||
if (team != null)
|
|
||||||
{
|
|
||||||
teams.computeIfPresent(team, (key, value) -> value > 1 ? value - 1 : null);
|
|
||||||
sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sort()
|
|
||||||
{
|
|
||||||
// Sort teams by value in descending order and then by key in ascending order, limited to 5 entries
|
|
||||||
teams = teams.entrySet().stream()
|
|
||||||
.sorted(
|
|
||||||
Comparator.comparing(Map.Entry<Integer, Integer>::getValue, Comparator.reverseOrder())
|
|
||||||
.thenComparingInt(Map.Entry::getKey)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,6 +29,7 @@ package net.runelite.client.plugins.xptracker;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -53,7 +54,6 @@ import net.runelite.api.Skill;
|
|||||||
import net.runelite.api.WorldType;
|
import net.runelite.api.WorldType;
|
||||||
import net.runelite.client.game.SkillIconManager;
|
import net.runelite.client.game.SkillIconManager;
|
||||||
import net.runelite.client.ui.ColorScheme;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
import net.runelite.client.ui.DynamicGridLayout;
|
|
||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.SkillColor;
|
import net.runelite.client.ui.SkillColor;
|
||||||
import net.runelite.client.ui.components.MouseDragEventForwarder;
|
import net.runelite.client.ui.components.MouseDragEventForwarder;
|
||||||
@@ -190,7 +190,7 @@ class XpInfoBox extends JPanel
|
|||||||
headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
headerPanel.setLayout(new BorderLayout());
|
headerPanel.setLayout(new BorderLayout());
|
||||||
|
|
||||||
statsPanel.setLayout(new DynamicGridLayout(2, 2));
|
statsPanel.setLayout(new GridLayout(2, 2));
|
||||||
statsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
statsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
statsPanel.setBorder(new EmptyBorder(9, 2, 9, 2));
|
statsPanel.setBorder(new EmptyBorder(9, 2, 9, 2));
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,10 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.ui.components;
|
package net.runelite.client.ui.components;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.GridLayout;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@@ -53,7 +53,7 @@ public class ProgressBar extends DimmableJPanel
|
|||||||
|
|
||||||
public ProgressBar()
|
public ProgressBar()
|
||||||
{
|
{
|
||||||
setLayout(new BorderLayout());
|
setLayout(new GridLayout(1, 3));
|
||||||
// The background color should be overridden
|
// The background color should be overridden
|
||||||
setBackground(Color.GREEN.darker());
|
setBackground(Color.GREEN.darker());
|
||||||
setForeground(Color.GREEN.brighter());
|
setForeground(Color.GREEN.brighter());
|
||||||
@@ -66,6 +66,7 @@ public class ProgressBar extends DimmableJPanel
|
|||||||
|
|
||||||
rightLabel.setFont(FontManager.getRunescapeSmallFont());
|
rightLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
rightLabel.setForeground(Color.WHITE);
|
rightLabel.setForeground(Color.WHITE);
|
||||||
|
rightLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
rightLabel.setBorder(new EmptyBorder(2, 0, 0, 5));
|
rightLabel.setBorder(new EmptyBorder(2, 0, 0, 5));
|
||||||
|
|
||||||
centerLabel.setFont(FontManager.getRunescapeSmallFont());
|
centerLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
@@ -74,9 +75,9 @@ public class ProgressBar extends DimmableJPanel
|
|||||||
centerLabel.setBorder(new EmptyBorder(2, 0, 0, 0));
|
centerLabel.setBorder(new EmptyBorder(2, 0, 0, 0));
|
||||||
|
|
||||||
// Adds components to be automatically redrawn when paintComponents is called
|
// Adds components to be automatically redrawn when paintComponents is called
|
||||||
add(leftLabel, BorderLayout.WEST);
|
add(leftLabel);
|
||||||
add(centerLabel, BorderLayout.CENTER);
|
add(centerLabel);
|
||||||
add(rightLabel, BorderLayout.EAST);
|
add(rightLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Abex
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.mockwebserver.MockResponse;
|
||||||
|
import okhttp3.mockwebserver.MockWebServer;
|
||||||
|
import okhttp3.mockwebserver.RecordedRequest;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
|
||||||
|
public class OkHttpCacheSanityTest
|
||||||
|
{
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder cacheFolder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public MockWebServer server = new MockWebServer();
|
||||||
|
|
||||||
|
private static final DateTimeFormatter TIME_FMT = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.US)
|
||||||
|
.withZone(ZoneId.of("GMT"));
|
||||||
|
|
||||||
|
private static final String BODY_404 = "<html>404 not found";
|
||||||
|
private static final String BODY_200 = "{success:true}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The specific thing we are trying to catch here is when a 404
|
||||||
|
* response is served by cloudflare after the upstream has gotten
|
||||||
|
* an updated document. CF serves the 404 response with a Date header,
|
||||||
|
* but no ETag or Last-Modified. OkHttp then uses the Date header, which
|
||||||
|
* is from after the upstream was edited, in a If-Modified-Since request,
|
||||||
|
* which does hit the upstream, returning 304 Not Modified. Since there
|
||||||
|
* is no body OkHttp serves the cached 404 as up-to-date. Better yet, since
|
||||||
|
* there is now an ETag in the 304 response it requests subsequent updates
|
||||||
|
* with the ETag, which will always 304 Not Modified, causing clients in
|
||||||
|
* this state to get incorrect 404s until the ETag changes.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCacheSanity() throws IOException, InterruptedException
|
||||||
|
{
|
||||||
|
OkHttpClient.Builder builder = RuneLiteAPI.CLIENT.newBuilder();
|
||||||
|
RuneLite.setupCache(builder, cacheFolder.getRoot());
|
||||||
|
OkHttpClient client = builder.build();
|
||||||
|
|
||||||
|
Instant lastModified = Instant.now().minusSeconds(20);
|
||||||
|
|
||||||
|
server.enqueue(new MockResponse()
|
||||||
|
.setResponseCode(404)
|
||||||
|
.setHeader("Content-Type", "text/html")
|
||||||
|
.setHeader("Date", TIME_FMT.format(Instant.now().minusSeconds(10)))
|
||||||
|
.setBody(BODY_404));
|
||||||
|
try (Response res = client.newCall(new Request.Builder()
|
||||||
|
.url(server.url("/manifest"))
|
||||||
|
.build()).execute())
|
||||||
|
{
|
||||||
|
Assert.assertEquals(404, res.code());
|
||||||
|
}
|
||||||
|
RecordedRequest req = server.takeRequest(1, TimeUnit.SECONDS);
|
||||||
|
Assert.assertNotNull("cache did not make a initial request", req);
|
||||||
|
|
||||||
|
server.enqueue(new MockResponse()
|
||||||
|
.setResponseCode(200)
|
||||||
|
.setHeader("Content-Type", "text/html")
|
||||||
|
.setHeader("Date", TIME_FMT.format(Instant.now().minusSeconds(5)))
|
||||||
|
.setHeader("Last-Modified", TIME_FMT.format(lastModified))
|
||||||
|
.setBody(BODY_200));
|
||||||
|
try (Response res = client.newCall(new Request.Builder()
|
||||||
|
.url(server.url("/manifest"))
|
||||||
|
.build()).execute())
|
||||||
|
{
|
||||||
|
Assert.assertEquals(200, res.code());
|
||||||
|
}
|
||||||
|
req = server.takeRequest(1, TimeUnit.SECONDS);
|
||||||
|
Assert.assertNotNull("cache did not make a request", req);
|
||||||
|
Assert.assertNull(req.getHeader("If-Modified-Since"));
|
||||||
|
|
||||||
|
server.enqueue(new MockResponse()
|
||||||
|
.setResponseCode(304)
|
||||||
|
.setHeader("Content-Type", "text/html")
|
||||||
|
.setHeader("Date", TIME_FMT.format(Instant.now()))
|
||||||
|
.setHeader("Last-Modified", TIME_FMT.format(lastModified)));
|
||||||
|
try (Response res = client.newCall(new Request.Builder()
|
||||||
|
.url(server.url("/manifest"))
|
||||||
|
.build()).execute())
|
||||||
|
{
|
||||||
|
Assert.assertEquals(200, res.code());
|
||||||
|
}
|
||||||
|
req = server.takeRequest(1, TimeUnit.SECONDS);
|
||||||
|
Assert.assertNotNull("cache did not make a conditional request", req);
|
||||||
|
Assert.assertNotNull(req.getHeader("If-Modified-Since"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Mathieu Bernier <https://github.com/Matsyir>
|
* Copyright (c) 2021, Jordan Atwood <nightfirecat@protonmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -22,23 +22,17 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.teamcapes;
|
package net.runelite.client.plugins.itemidentification;
|
||||||
|
|
||||||
import net.runelite.client.config.Config;
|
import net.runelite.api.ItemID;
|
||||||
import net.runelite.client.config.ConfigGroup;
|
import static org.junit.Assert.assertEquals;
|
||||||
import net.runelite.client.config.ConfigItem;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ConfigGroup("teamCapes")
|
public class ItemIdentificationTest
|
||||||
public interface TeamCapesConfig extends Config
|
|
||||||
{
|
{
|
||||||
@ConfigItem(
|
@Test
|
||||||
keyName = "minimumCapeCount",
|
public void testInit()
|
||||||
name = "Minimum Cape Count",
|
|
||||||
description = "Configures the minimum number of team capes which must be present before being displayed.",
|
|
||||||
position = 0
|
|
||||||
)
|
|
||||||
default int getMinimumCapeCount()
|
|
||||||
{
|
{
|
||||||
return 1;
|
assertEquals(ItemIdentification.YEW_SEED, ItemIdentification.get(ItemID.YEW_SEED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,6 +82,7 @@ import net.runelite.api.coords.LocalPoint;
|
|||||||
import net.runelite.api.coords.WorldPoint;
|
import net.runelite.api.coords.WorldPoint;
|
||||||
import net.runelite.api.events.CanvasSizeChanged;
|
import net.runelite.api.events.CanvasSizeChanged;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.ClanChannelChanged;
|
||||||
import net.runelite.api.events.ClientTick;
|
import net.runelite.api.events.ClientTick;
|
||||||
import net.runelite.api.events.DraggingWidgetChanged;
|
import net.runelite.api.events.DraggingWidgetChanged;
|
||||||
import net.runelite.api.events.FriendsChatChanged;
|
import net.runelite.api.events.FriendsChatChanged;
|
||||||
@@ -2264,5 +2265,25 @@ public abstract class RSClientMixin implements RSClient
|
|||||||
return ClanRank.CLAN_RANK_1;
|
return ClanRank.CLAN_RANK_1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@FieldHook("guestClanChannel")
|
||||||
|
public static void onGuestClanChannelChanged(int idx)
|
||||||
|
{
|
||||||
|
client.getCallbacks().post(new ClanChannelChanged(client.getGuestClanChannel(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@FieldHook("currentClanChannels")
|
||||||
|
public static void onCurrentClanChannelsChanged(int idx)
|
||||||
|
{
|
||||||
|
if (idx == -1)
|
||||||
|
{
|
||||||
|
// don't fire on array field itself being set
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.getCallbacks().post(new ClanChannelChanged(client.getClanChannel(), false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -285,6 +285,7 @@ public final class Client extends GameEngine implements Usernamed {
|
|||||||
@ObfuscatedSignature(
|
@ObfuscatedSignature(
|
||||||
descriptor = "[Ly;"
|
descriptor = "[Ly;"
|
||||||
)
|
)
|
||||||
|
@Export("currentClanChannels")
|
||||||
static ClanChannel[] currentClanChannels;
|
static ClanChannel[] currentClanChannels;
|
||||||
@ObfuscatedName("pi")
|
@ObfuscatedName("pi")
|
||||||
static int[] field867;
|
static int[] field867;
|
||||||
|
|||||||
Reference in New Issue
Block a user