rl-client: implement our pf4j plugins, extract pf4j out of net.runelite package. (#2883)
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package com.openosrs.client.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
public class DeferredDocumentChangedListener implements DocumentListener
|
||||
{
|
||||
private final Timer timer;
|
||||
private final List<ChangeListener> listeners;
|
||||
|
||||
public DeferredDocumentChangedListener()
|
||||
{
|
||||
listeners = new ArrayList<>(25);
|
||||
timer = new Timer(200, e -> fireStateChanged());
|
||||
timer.setRepeats(false);
|
||||
}
|
||||
|
||||
public void addChangeListener(ChangeListener listener)
|
||||
{
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
private void fireStateChanged()
|
||||
{
|
||||
if (!listeners.isEmpty())
|
||||
{
|
||||
ChangeEvent evt = new ChangeEvent(this);
|
||||
for (ChangeListener listener : listeners)
|
||||
{
|
||||
listener.stateChanged(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e)
|
||||
{
|
||||
timer.restart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e)
|
||||
{
|
||||
timer.restart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e)
|
||||
{
|
||||
timer.restart();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package com.openosrs.client.util;
|
||||
|
||||
import com.openosrs.client.OpenOSRS;
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import com.openosrs.client.config.OpenOSRSConfig;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ClientShutdown;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import com.openosrs.client.ui.OpenOSRSSplashScreen;
|
||||
import org.jgroups.Address;
|
||||
import org.jgroups.JChannel;
|
||||
import org.jgroups.Message;
|
||||
import org.jgroups.ObjectMessage;
|
||||
import org.jgroups.Receiver;
|
||||
import org.jgroups.View;
|
||||
import org.jgroups.util.Util;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class Groups implements Receiver
|
||||
{
|
||||
private final OpenOSRSConfig openOSRSConfig;
|
||||
private final JChannel channel;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private int instanceCount;
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private List<Address> members;
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private final Map<String, List<Address>> messageMap = new HashMap<>();
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private final PublishSubject<Message> messageStringSubject = PublishSubject.create();
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private final PublishSubject<Message> messageObjectSubject = PublishSubject.create();
|
||||
|
||||
@Inject
|
||||
public Groups(OpenOSRSConfig openOSRSConfig, EventBus eventBus) throws Exception
|
||||
{
|
||||
this.openOSRSConfig = openOSRSConfig;
|
||||
|
||||
try (final InputStream is = RuneLite.class.getResourceAsStream("/udp-openosrs.xml"))
|
||||
{
|
||||
this.channel = new JChannel(is)
|
||||
.setName(OpenOSRS.uuid)
|
||||
.setReceiver(this)
|
||||
.setDiscardOwnMessages(true)
|
||||
.connect("openosrs");
|
||||
}
|
||||
|
||||
eventBus.register(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onClientShutdown(ClientShutdown event)
|
||||
{
|
||||
Future<Void> f = close();
|
||||
event.waitFor(f);
|
||||
}
|
||||
|
||||
public void broadcastSring(String command)
|
||||
{
|
||||
send(null, command);
|
||||
}
|
||||
|
||||
public void sendConfig(Address destination, ConfigChanged configChanged)
|
||||
{
|
||||
if (!openOSRSConfig.localSync() || OpenOSRSSplashScreen.showing() || instanceCount < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
byte[] buffer = Util.objectToByteBuffer(configChanged);
|
||||
Message message = new ObjectMessage()
|
||||
.setDest(destination)
|
||||
.setObject(buffer);
|
||||
|
||||
channel.send(message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendString(String command)
|
||||
{
|
||||
String[] messageObject = command.split(";");
|
||||
String pluginId = messageObject[1];
|
||||
|
||||
messageMap.put(pluginId, new ArrayList<>());
|
||||
|
||||
for (Address member : channel.getView().getMembers())
|
||||
{
|
||||
if (member.toString().equals(OpenOSRS.uuid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
messageMap.get(pluginId).add(member);
|
||||
send(member, command);
|
||||
}
|
||||
}
|
||||
|
||||
public void send(Address destination, String command)
|
||||
{
|
||||
if (!openOSRSConfig.localSync() || OpenOSRSSplashScreen.showing() || instanceCount < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
channel.send(new ObjectMessage(destination, command));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viewAccepted(View view)
|
||||
{
|
||||
members = view.getMembers();
|
||||
instanceCount = members.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Message message)
|
||||
{
|
||||
if (OpenOSRSSplashScreen.showing())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.getObject() instanceof String)
|
||||
{
|
||||
messageStringSubject.onNext(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
messageObjectSubject.onNext(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> close()
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
try
|
||||
{
|
||||
channel.close();
|
||||
future.complete(null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
future.completeExceptionally(ex);
|
||||
}
|
||||
|
||||
return future;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.openosrs.client.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ImageUtil extends net.runelite.client.util.ImageUtil
|
||||
{
|
||||
/**
|
||||
* Recolors pixels of the given image with the given color based on a given recolor condition
|
||||
* predicate.
|
||||
*
|
||||
* @param image The image which should have its non-transparent pixels recolored.
|
||||
* @param color The color with which to recolor pixels.
|
||||
* @param recolorCondition The condition on which to recolor pixels with the given color.
|
||||
* @return The given image with all pixels fulfilling the recolor condition predicate
|
||||
* set to the given color.
|
||||
*/
|
||||
public static BufferedImage recolorImage(final BufferedImage image, final Color color, final Predicate<Color> recolorCondition)
|
||||
{
|
||||
final BufferedImage recoloredImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
for (int x = 0; x < recoloredImage.getWidth(); x++)
|
||||
{
|
||||
for (int y = 0; y < recoloredImage.getHeight(); y++)
|
||||
{
|
||||
final Color pixelColor = new Color(image.getRGB(x, y), true);
|
||||
if (!recolorCondition.test(pixelColor))
|
||||
{
|
||||
recoloredImage.setRGB(x, y, image.getRGB(x, y));
|
||||
continue;
|
||||
}
|
||||
|
||||
recoloredImage.setRGB(x, y, color.getRGB());
|
||||
}
|
||||
}
|
||||
return recoloredImage;
|
||||
}
|
||||
|
||||
public static BufferedImage recolorImage(BufferedImage image, final Color color)
|
||||
{
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
WritableRaster raster = image.getRaster();
|
||||
|
||||
for (int xx = 0; xx < width; xx++)
|
||||
{
|
||||
for (int yy = 0; yy < height; yy++)
|
||||
{
|
||||
int[] pixels = raster.getPixel(xx, yy, (int[]) null);
|
||||
pixels[0] = color.getRed();
|
||||
pixels[1] = color.getGreen();
|
||||
pixels[2] = color.getBlue();
|
||||
raster.setPixel(xx, yy, pixels);
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package com.openosrs.client.util;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
public class MiscUtils
|
||||
{
|
||||
private static final int[] abovePointsX = {2944, 3392, 3392, 2944};
|
||||
private static final int[] abovePointsY = {3523, 3523, 3971, 3971};
|
||||
private static final int[] belowPointsX = {2944, 2944, 3264, 3264};
|
||||
private static final int[] belowPointsY = {9918, 10360, 10360, 9918};
|
||||
|
||||
private static final Polygon abovePoly = new Polygon(abovePointsX, abovePointsY, abovePointsX.length);
|
||||
private static final Polygon belowPoly = new Polygon(belowPointsX, belowPointsY, belowPointsX.length);
|
||||
|
||||
private static final ChronoUnit[] ORDERED_CHRONOS = new ChronoUnit[]
|
||||
{
|
||||
ChronoUnit.YEARS,
|
||||
ChronoUnit.MONTHS,
|
||||
ChronoUnit.WEEKS,
|
||||
ChronoUnit.DAYS,
|
||||
ChronoUnit.HOURS,
|
||||
ChronoUnit.MINUTES,
|
||||
ChronoUnit.SECONDS
|
||||
};
|
||||
|
||||
//test replacement so private for now
|
||||
private static boolean inWildy(WorldPoint point)
|
||||
{
|
||||
if (point == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return abovePoly.contains(point.getX(), point.getY()) || belowPoly.contains(point.getX(), point.getY());
|
||||
}
|
||||
|
||||
public static int getWildernessLevelFrom(Client client, WorldPoint point)
|
||||
{
|
||||
if (client == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (point == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x = point.getX();
|
||||
|
||||
if (point.getPlane() == 0 && (x < 2940 || x > 3391))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int y = point.getY();
|
||||
//v underground //v above ground
|
||||
int wildernessLevel = clamp(y > 6400 ? ((y - 9920) / 8) + 1 : ((y - 3520) / 8) + 1, 0, 56);
|
||||
|
||||
if (point.getPlane() > 0 && y < 9920)
|
||||
{
|
||||
wildernessLevel = 0;
|
||||
}
|
||||
|
||||
if (client.getWorldType().stream().anyMatch(worldType -> worldType == WorldType.PVP || worldType == WorldType.HIGH_RISK))
|
||||
{
|
||||
wildernessLevel += 15;
|
||||
}
|
||||
|
||||
return Math.max(0, wildernessLevel);
|
||||
}
|
||||
|
||||
public static int clamp(int val, int min, int max)
|
||||
{
|
||||
return Math.max(min, Math.min(max, val));
|
||||
}
|
||||
|
||||
public static float clamp(float val, float min, float max)
|
||||
{
|
||||
return Math.max(min, Math.min(max, val));
|
||||
}
|
||||
|
||||
public static boolean inWilderness(Client client)
|
||||
{
|
||||
Player localPlayer = client.getLocalPlayer();
|
||||
|
||||
if (localPlayer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return inWildy(localPlayer.getWorldLocation());
|
||||
|
||||
//return getWildernessLevelFrom(client, localPlayer.getWorldLocation()) > 0;
|
||||
}
|
||||
|
||||
public static String formatTimeAgo(Duration dur)
|
||||
{
|
||||
long dA = 0, dB = 0, rm;
|
||||
ChronoUnit cA = null, cB = null;
|
||||
for (int i = 0; i < ORDERED_CHRONOS.length; i++)
|
||||
{
|
||||
cA = ORDERED_CHRONOS[i];
|
||||
dA = dur.getSeconds() / cA.getDuration().getSeconds();
|
||||
rm = dur.getSeconds() % cA.getDuration().getSeconds();
|
||||
if (dA <= 0)
|
||||
{
|
||||
cA = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i + 1 < ORDERED_CHRONOS.length)
|
||||
{
|
||||
cB = ORDERED_CHRONOS[i + 1];
|
||||
dB = rm / cB.getDuration().getSeconds();
|
||||
|
||||
if (dB <= 0)
|
||||
{
|
||||
cB = null;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (cA == null)
|
||||
{
|
||||
return "just now.";
|
||||
}
|
||||
|
||||
String str = formatUnit(cA, dA);
|
||||
|
||||
if (cB != null)
|
||||
{
|
||||
str += " and " + formatUnit(cB, dB);
|
||||
}
|
||||
|
||||
return str + " ago.";
|
||||
}
|
||||
|
||||
private static String formatUnit(ChronoUnit chrono, long val)
|
||||
{
|
||||
boolean multiple = val != 1;
|
||||
String str;
|
||||
if (multiple)
|
||||
{
|
||||
str = val + " ";
|
||||
}
|
||||
else
|
||||
{
|
||||
str = "a" + (chrono == ChronoUnit.HOURS ? "n " : " ");
|
||||
}
|
||||
str += chrono.name().toLowerCase();
|
||||
if (!multiple)
|
||||
{
|
||||
if (str.charAt(str.length() - 1) == 's')
|
||||
{
|
||||
str = str.substring(0, str.length() - 1);
|
||||
}
|
||||
}
|
||||
else if (str.charAt(str.length() - 1) != 's')
|
||||
{
|
||||
str += "s";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostly stolen from {@link java.net.URLStreamHandler#toExternalForm(URL)}
|
||||
*
|
||||
* @param url URL to encode
|
||||
* @return URL, with path, query and ref encoded
|
||||
*/
|
||||
public static String urlToStringEncoded(URL url)
|
||||
{
|
||||
String s;
|
||||
String path = url.getPath() != null ? Stream.of(url.getPath().split("/"))
|
||||
.map(s2 -> URLEncoder.encode(s2, StandardCharsets.UTF_8)).collect(Collectors.joining("/")) : "";
|
||||
return url.getProtocol()
|
||||
+ ':'
|
||||
+ (((s = url.getAuthority()) != null && s.length() > 0) ? "//" + s : "")
|
||||
+ (path)
|
||||
+ (((s = url.getQuery()) != null) ? '?' + urlEncode(s) : "")
|
||||
+ (((s = url.getRef()) != null) ? '#' + urlEncode(s) : "");
|
||||
}
|
||||
|
||||
private static String urlEncode(String s)
|
||||
{
|
||||
return URLEncoder.encode(s, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.openosrs.client.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import net.runelite.client.util.CallableExceptionLogger;
|
||||
import static net.runelite.client.util.RunnableExceptionLogger.wrap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
// Awkward name because plugins already referenced the ExecutorServiceExceptionLogger
|
||||
// (which only handles ScheduledExecutorServices) before this class was introduced
|
||||
public class NonScheduledExecutorServiceExceptionLogger implements ExecutorService
|
||||
{
|
||||
private final ExecutorService service;
|
||||
|
||||
public NonScheduledExecutorServiceExceptionLogger(ExecutorService service)
|
||||
{
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
service.shutdown();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Runnable> shutdownNow()
|
||||
{
|
||||
return service.shutdownNow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShutdown()
|
||||
{
|
||||
return service.isShutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTerminated()
|
||||
{
|
||||
return service.isTerminated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) throws InterruptedException
|
||||
{
|
||||
return service.awaitTermination(timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull Runnable command)
|
||||
{
|
||||
service.execute(wrap(command));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> Future<T> submit(@NotNull Callable<T> task)
|
||||
{
|
||||
return service.submit(CallableExceptionLogger.wrap(task));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> Future<T> submit(@NotNull Runnable task, T result)
|
||||
{
|
||||
return service.submit(wrap(task), result);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Future<?> submit(@NotNull Runnable task)
|
||||
{
|
||||
return service.submit(wrap(task));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>> tasks) throws InterruptedException
|
||||
{
|
||||
return service.invokeAll(tasks);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>> tasks, long timeout, @NotNull TimeUnit unit) throws InterruptedException
|
||||
{
|
||||
return service.invokeAll(tasks, timeout, unit);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> T invokeAny(@NotNull Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException
|
||||
{
|
||||
return service.invokeAny(tasks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T invokeAny(@NotNull Collection<? extends Callable<T>> tasks, long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
return service.invokeAny(tasks, timeout, unit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.openosrs.client.util;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class SwingUtil extends net.runelite.client.util.SwingUtil
|
||||
{
|
||||
public static void syncExec(final Runnable r) throws InvocationTargetException, InterruptedException
|
||||
{
|
||||
if (EventQueue.isDispatchThread())
|
||||
{
|
||||
r.run();
|
||||
}
|
||||
else
|
||||
{
|
||||
EventQueue.invokeAndWait(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user