Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-08-22 02:56:44 +02:00
10 changed files with 243 additions and 75 deletions

View File

@@ -25,9 +25,9 @@
object ProjectVersions {
const val launcherVersion = "2.2.0"
const val rlVersion = "1.7.19"
const val rlVersion = "1.7.20"
const val openosrsVersion = "4.9.10"
const val openosrsVersion = "4.9.11"
const val rsversion = 198
const val cacheversion = 165

View File

@@ -171,6 +171,8 @@ public interface Actor extends Renderable, Locatable
*/
int getIdleRotateLeft();
void setIdleRotateLeft(int animationID);
/**
* Animation used for rotating right if the actor is also not walking
*
@@ -179,6 +181,8 @@ public interface Actor extends Renderable, Locatable
*/
int getIdleRotateRight();
void setIdleRotateRight(int animationID);
/**
* Animation used for walking
*
@@ -187,6 +191,8 @@ public interface Actor extends Renderable, Locatable
*/
int getWalkAnimation();
void setWalkAnimation(int animationID);
/**
* Animation used for rotating left while walking
*
@@ -195,6 +201,8 @@ public interface Actor extends Renderable, Locatable
*/
int getWalkRotateLeft();
void setWalkRotateLeft(int animationID);
/**
* Animation used for rotating right while walking
*
@@ -203,6 +211,8 @@ public interface Actor extends Renderable, Locatable
*/
int getWalkRotateRight();
void setWalkRotateRight(int animationID);
/**
* Animation used for an about-face while walking
*
@@ -211,6 +221,8 @@ public interface Actor extends Renderable, Locatable
*/
int getWalkRotate180();
void setWalkRotate180(int animationID);
/**
* Animation used for running
*
@@ -219,6 +231,8 @@ public interface Actor extends Renderable, Locatable
*/
int getRunAnimation();
void setRunAnimation(int animationID);
/**
* Sets an animation for the actor to perform.
*

View File

@@ -27,7 +27,7 @@ package net.runelite.api;
/**
* Represents a chat entity that has a name.
*/
public interface Nameable extends Comparable
public interface Nameable extends Comparable<Nameable>
{
/**
* The name of the player.

View File

@@ -26,6 +26,7 @@
*/
package net.runelite.client.plugins.chatchannel;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
@@ -36,9 +37,9 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ListIterator;
import javax.inject.Inject;
import lombok.AllArgsConstructor;
import net.runelite.api.ChatLineBuffer;
@@ -101,7 +102,8 @@ public class ChatChannelPlugin extends Plugin
{
private static final int MAX_CHATS = 10;
private static final String RECENT_TITLE = "Recent FCs";
private static final int MESSAGE_DELAY = 10;
@VisibleForTesting
static final int MESSAGE_DELAY = 10;
@Inject
private Client client;
@@ -129,7 +131,7 @@ public class ChatChannelPlugin extends Plugin
* queue of temporary messages added to the client
*/
private final Deque<MemberJoinMessage> joinMessages = new ArrayDeque<>();
private final Map<ChatPlayer, MemberActivity> activityBuffer = new LinkedHashMap<>();
private final List<MemberActivity> activityBuffer = new LinkedList<>();
private int joinedTick;
private boolean kickConfirmed = false;
@@ -284,31 +286,38 @@ public class ChatChannelPlugin extends Plugin
private void queueJoin(ChatPlayer member, MemberActivity.ChatType chatType)
{
// attempt to filter out world hopping joins
if (!activityBuffer.containsKey(member))
for (ListIterator<MemberActivity> iter = activityBuffer.listIterator(); iter.hasNext(); )
{
MemberActivity joinActivity = new MemberActivity(ActivityType.JOINED, chatType,
member, client.getTickCount());
activityBuffer.put(member, joinActivity);
}
else
{
activityBuffer.remove(member);
MemberActivity activity = iter.next();
if (activity.getChatType() == chatType && activity.getMember().compareTo(member) == 0)
{
iter.remove();
return;
}
}
MemberActivity activity = new MemberActivity(ActivityType.JOINED, chatType,
member, client.getTickCount());
activityBuffer.add(activity);
}
private void queueLeave(ChatPlayer member, MemberActivity.ChatType chatType)
{
if (!activityBuffer.containsKey(member))
for (ListIterator<MemberActivity> iter = activityBuffer.listIterator(); iter.hasNext(); )
{
MemberActivity leaveActivity = new MemberActivity(ActivityType.LEFT, chatType,
member, client.getTickCount());
activityBuffer.put(member, leaveActivity);
}
else
{
activityBuffer.remove(member);
MemberActivity activity = iter.next();
if (activity.getChatType() == chatType && activity.getMember().compareTo(member) == 0)
{
iter.remove();
return;
}
}
MemberActivity activity = new MemberActivity(ActivityType.LEFT, chatType,
member, client.getTickCount());
activityBuffer.add(activity);
}
@Subscribe
@@ -386,32 +395,33 @@ public class ChatChannelPlugin extends Plugin
}
}
private void addActivityMessages()
@VisibleForTesting
void addActivityMessages()
{
if (activityBuffer.isEmpty())
{
return;
}
Iterator<MemberActivity> activityIt = activityBuffer.values().iterator();
while (activityIt.hasNext())
for (ListIterator<MemberActivity> iter = activityBuffer.listIterator(); iter.hasNext(); )
{
MemberActivity activity = activityIt.next();
if (activity.getTick() < client.getTickCount() - MESSAGE_DELAY)
MemberActivity activity = iter.next();
if (activity.getTick() >= client.getTickCount() - MESSAGE_DELAY)
{
activityIt.remove();
switch (activity.getChatType())
{
case FRIENDS_CHAT:
addActivityMessage((FriendsChatMember) activity.getMember(), activity.getActivityType());
break;
case CLAN_CHAT:
case GUEST_CHAT:
addClanActivityMessage((ClanChannelMember) activity.getMember(), activity.getActivityType(), activity.getChatType());
break;
}
// everything after this is older
return;
}
iter.remove();
switch (activity.getChatType())
{
case FRIENDS_CHAT:
addActivityMessage((FriendsChatMember) activity.getMember(), activity.getActivityType());
break;
case CLAN_CHAT:
case GUEST_CHAT:
addClanActivityMessage((ClanChannelMember) activity.getMember(), activity.getActivityType(), activity.getChatType());
break;
}
}
}

View File

@@ -322,7 +322,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
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("Dig by the Giant's Den entrance, looking out over Lake Molch.", new WorldPoint(1418, 3591, 0), "South-east of Lake Molch in Zeah, outside the cave entrance."),
new CrypticClue("Search the crates in the fruit store just east of the Hosidius town centre.", CRATES_27533, new WorldPoint(1798, 3612, 0), "Search the crates in the back room of the Hosidius fruit store."),
new CrypticClue("Search the crates in the fruit store just east of the Hosidius town centre.", CRATES_27533, new WorldPoint(1799, 3613, 0), "Search the crates in the back room of the Hosidius fruit store."),
new CrypticClue("A graceful man of many colours, his crates must be full of many delights.", "Hill Giant", CRATE_42067, new WorldPoint(1506, 3590, 2), "Kill any Hill Giant for a medium key. Then search the crate on the top floor of Osten's clothing shop in Shayzien."),
new CrypticClue("Search the basket of apples in an orchard, south of the unknown grave surrounded by white roses.", APPLE_BASKET, new WorldPoint(1718, 3626, 0), "Search the middle apple basket in the apple orchard north of Hosidius."),
new CrypticClue("Dig in the lair of red wings, within the temple of the Sun and Moon.", new WorldPoint(1820, 9935, 0), "Forthos Dungeon. In the center of the red dragons.")

View File

@@ -28,6 +28,7 @@ package net.runelite.client.plugins.xpupdater;
import com.google.inject.Provides;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Objects;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
@@ -132,53 +133,72 @@ public class XpUpdaterPlugin extends Plugin
private void update(String username)
{
String reformedUsername = username.replace(" ", "_");
EnumSet<WorldType> worldTypes = client.getWorldType();
username = username.replace(" ", "_");
updateCml(username, worldTypes);
updateTempleosrs(username, worldTypes);
updateWom(username, worldTypes);
}
if (config.cml())
private void updateCml(String username, EnumSet<WorldType> worldTypes)
{
if (config.cml()
&& !worldTypes.contains(WorldType.LEAGUE)
&& !worldTypes.contains(WorldType.DEADMAN)
&& !worldTypes.contains(WorldType.TOURNAMENT))
{
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host("crystalmathlabs.com")
.addPathSegment("tracker")
.addPathSegment("api.php")
.addQueryParameter("type", "update")
.addQueryParameter("player", reformedUsername)
.build();
.scheme("https")
.host("crystalmathlabs.com")
.addPathSegment("tracker")
.addPathSegment("api.php")
.addQueryParameter("type", "update")
.addQueryParameter("player", username)
.build();
Request request = new Request.Builder()
.header("User-Agent", "RuneLite")
.url(url)
.build();
.header("User-Agent", "RuneLite")
.url(url)
.build();
sendRequest("CrystalMathLabs", request);
}
}
if (config.templeosrs())
private void updateTempleosrs(String username, EnumSet<WorldType> worldTypes)
{
if (config.templeosrs()
&& !worldTypes.contains(WorldType.LEAGUE)
&& !worldTypes.contains(WorldType.DEADMAN)
&& !worldTypes.contains(WorldType.TOURNAMENT))
{
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host("templeosrs.com")
.addPathSegment("php")
.addPathSegment("add_datapoint.php")
.addQueryParameter("player", reformedUsername)
.build();
.scheme("https")
.host("templeosrs.com")
.addPathSegment("php")
.addPathSegment("add_datapoint.php")
.addQueryParameter("player", username)
.build();
Request request = new Request.Builder()
.header("User-Agent", "RuneLite")
.url(url)
.build();
.header("User-Agent", "RuneLite")
.url(url)
.build();
sendRequest("TempleOSRS", request);
}
}
if (config.wiseoldman())
private void updateWom(String username, EnumSet<WorldType> worldTypes)
{
if (config.wiseoldman()
&& !worldTypes.contains(WorldType.LEAGUE)
&& !worldTypes.contains(WorldType.DEADMAN)
&& !worldTypes.contains(WorldType.TOURNAMENT))
{
final boolean leagueWorld = client.getWorldType().contains(WorldType.LEAGUE);
final String host = leagueWorld ? "trailblazer.wiseoldman.net" : "wiseoldman.net";
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host(host)
.host("wiseoldman.net")
.addPathSegment("api")
.addPathSegment("players")
.addPathSegment("track")

View File

@@ -456,7 +456,7 @@
"rx2": 29,
"ry2": 35,
"z1": 0,
"z2": 0
"z2": 1
},
{
"rx1": 16,
@@ -464,7 +464,7 @@
"rx2": 19,
"ry2": 37,
"z1": 0,
"z2": 0
"z2": 1
}
],
"12854": [ // Varrock Castle

View File

@@ -0,0 +1,123 @@
/*
* 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.chatchannel;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import javax.inject.Inject;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.MessageNode;
import net.runelite.api.clan.ClanChannel;
import net.runelite.api.clan.ClanChannelMember;
import net.runelite.api.clan.ClanRank;
import net.runelite.api.clan.ClanSettings;
import net.runelite.api.events.ClanMemberJoined;
import net.runelite.api.events.ClanMemberLeft;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.game.ChatIconManager;
import net.runelite.client.game.chatbox.ChatboxPanelManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import org.mockito.Mock;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ChatChannelPluginTest
{
@Inject
private ChatChannelPlugin chatChannelPlugin;
@Mock
@Bind
private Client client;
@Mock
@Bind
private ChatIconManager chatIconManager;
@Mock
@Bind
private ChatChannelConfig config;
@Mock
@Bind
private ClientThread clientThread;
@Mock
@Bind
private ChatboxPanelManager chatboxPanelManager;
@Mock
@Bind
private ChatColorConfig chatColorConfig;
@Mock
@Bind
private ChatMessageManager chatMessageManager;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
}
@Test
public void testJoinLeave()
{
ClanChannel channel = mock(ClanChannel.class);
ClanSettings settings = mock(ClanSettings.class);
when(client.getClanChannel()).thenReturn(channel);
lenient().when(client.getClanSettings()).thenReturn(settings);
when(config.clanChatShowJoinLeave()).thenReturn(true);
lenient().when(client.addChatMessage(any(ChatMessageType.class), anyString(), anyString(), anyString())).thenAnswer(a -> mock(MessageNode.class));
ClanChannelMember member = mock(ClanChannelMember.class);
lenient().when(member.getRank()).thenReturn(ClanRank.OWNER);
chatChannelPlugin.onClanMemberLeft(new ClanMemberLeft(channel, member));
ClanChannelMember member2 = mock(ClanChannelMember.class);
lenient().when(member2.getRank()).thenReturn(ClanRank.OWNER);
chatChannelPlugin.onClanMemberJoined(new ClanMemberJoined(channel, member2));
lenient().when(client.getTickCount()).thenReturn(ChatChannelPlugin.MESSAGE_DELAY + 1);
chatChannelPlugin.addActivityMessages();
verify(client, never()).addChatMessage(any(ChatMessageType.class), anyString(), anyString(), anyString());
verify(member).compareTo(member2);
}
}

View File

@@ -24,6 +24,7 @@
*/
package net.runelite.mixins;
import net.runelite.api.Nameable;
import net.runelite.api.clan.ClanRank;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
@@ -39,9 +40,9 @@ public abstract class RSClanChannelMemberMixin implements RSClanChannelMember
@Inject
@Override
public int compareTo(Object other)
public int compareTo(Nameable other)
{
return getName().compareTo(((RSClanChannelMember) other).getName());
return getName().compareTo(other.getName());
}
@Inject

View File

@@ -3,7 +3,7 @@ package net.runelite.rs.api;
import net.runelite.api.Nameable;
import net.runelite.mapping.Import;
public interface RSUser extends Nameable, Comparable
public interface RSUser extends Nameable, Comparable<Nameable>
{
@Import("username")
RSUsername getRsName();