@@ -173,8 +173,15 @@ public interface Client extends GameEngine
|
||||
|
||||
int[][] getXteaKeys();
|
||||
|
||||
@VisibleForDevtools
|
||||
int[] getVarps();
|
||||
|
||||
@VisibleForDevtools
|
||||
int[] getIntVarcs();
|
||||
|
||||
@VisibleForDevtools
|
||||
String[] getStrVarcs();
|
||||
|
||||
int getVar(VarPlayer varPlayer);
|
||||
|
||||
int getVar(Varbits varbit);
|
||||
@@ -187,10 +194,10 @@ public interface Client extends GameEngine
|
||||
void setSetting(Varbits varbit, int value);
|
||||
|
||||
@VisibleForDevtools
|
||||
int getVarbitValue(int varbit);
|
||||
int getVarbitValue(int[] varps, int varbitId);
|
||||
|
||||
@VisibleForDevtools
|
||||
void setVarbitValue(int varbit, int value);
|
||||
void setVarbitValue(int[] varps, int varbit, int value);
|
||||
|
||||
HashTable getWidgetFlags();
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.api.events;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class VarClientIntChanged
|
||||
{
|
||||
private int index;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.api.events;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class VarClientStrChanged
|
||||
{
|
||||
private int index;
|
||||
}
|
||||
@@ -41,21 +41,20 @@ public class DevToolsPanel extends PluginPanel
|
||||
private final Client client;
|
||||
private final DevToolsPlugin plugin;
|
||||
|
||||
private final VarTracker varTracker;
|
||||
|
||||
private WidgetInspector widgetInspector;
|
||||
private final WidgetInspector widgetInspector;
|
||||
private final VarInspector varInspector;
|
||||
|
||||
@Inject
|
||||
public DevToolsPanel(Client client, DevToolsPlugin plugin, WidgetInspector widgetInspector)
|
||||
public DevToolsPanel(Client client, DevToolsPlugin plugin, WidgetInspector widgetInspector, VarInspector varInspector)
|
||||
{
|
||||
super();
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.widgetInspector = widgetInspector;
|
||||
this.varInspector = varInspector;
|
||||
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
varTracker = new VarTracker(client);
|
||||
add(createOptionsPanel());
|
||||
}
|
||||
|
||||
@@ -137,14 +136,6 @@ public class DevToolsPanel extends PluginPanel
|
||||
});
|
||||
container.add(renderProjectilesBtn);
|
||||
|
||||
final JButton varSnapshotBtn = new JButton("Snapshot Vars");
|
||||
varSnapshotBtn.addActionListener(varTracker::snapshot);
|
||||
container.add(varSnapshotBtn);
|
||||
|
||||
final JButton varClearBtn = new JButton("Clear Vars");
|
||||
varClearBtn.addActionListener(varTracker::clear);
|
||||
container.add(varClearBtn);
|
||||
|
||||
final JButton renderLocationBtn = new JButton("Location");
|
||||
renderLocationBtn.addActionListener(e ->
|
||||
{
|
||||
@@ -153,7 +144,7 @@ public class DevToolsPanel extends PluginPanel
|
||||
});
|
||||
container.add(renderLocationBtn);
|
||||
|
||||
final JButton widgetInspectorBtn = new JButton("Inspector");
|
||||
final JButton widgetInspectorBtn = new JButton("Widget Tools");
|
||||
widgetInspectorBtn.addActionListener(e ->
|
||||
{
|
||||
widgetInspector.setVisible(true);
|
||||
@@ -162,6 +153,13 @@ public class DevToolsPanel extends PluginPanel
|
||||
});
|
||||
container.add(widgetInspectorBtn);
|
||||
|
||||
final JButton varInspectorBtn = new JButton("Var Tools");
|
||||
varInspectorBtn.addActionListener(e ->
|
||||
{
|
||||
varInspector.open();
|
||||
});
|
||||
container.add(varInspectorBtn);
|
||||
|
||||
final JButton chunkBordersBtn = new JButton("Chunk borders");
|
||||
chunkBordersBtn.addActionListener(e ->
|
||||
{
|
||||
|
||||
@@ -174,7 +174,7 @@ public class DevToolsPlugin extends Plugin
|
||||
case "getvar":
|
||||
{
|
||||
int varbit = Integer.parseInt(args[0]);
|
||||
int value = client.getVarbitValue(varbit);
|
||||
int value = client.getVarbitValue(client.getVarps(), varbit);
|
||||
client.addChatMessage(ChatMessageType.SERVER, "", "Varbit " + varbit + ": " + value, null);
|
||||
break;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public class DevToolsPlugin extends Plugin
|
||||
{
|
||||
int varbit = Integer.parseInt(args[0]);
|
||||
int value = Integer.parseInt(args[1]);
|
||||
client.setVarbitValue(varbit, value);
|
||||
client.setVarbitValue(client.getVarps(), varbit, value);
|
||||
client.addChatMessage(ChatMessageType.SERVER, "", "Set varbit " + varbit + " to " + value, null);
|
||||
eventBus.post(new VarbitChanged()); // fake event
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.plugins.devtools;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.AdjustmentEvent;
|
||||
import java.awt.event.AdjustmentListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.Objects;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.VarClientStr;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.VarClientIntChanged;
|
||||
import net.runelite.api.events.VarClientStrChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.DynamicGridLayout;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
|
||||
@Slf4j
|
||||
class VarInspector extends JFrame
|
||||
{
|
||||
@Getter
|
||||
private enum VarType
|
||||
{
|
||||
VARBIT("Varbit"),
|
||||
VARP("VarPlayer"),
|
||||
VARCINT("VarClientInt"),
|
||||
VARCSTR("VarClientStr");
|
||||
|
||||
private final String name;
|
||||
private final JCheckBox checkBox;
|
||||
|
||||
VarType(String name)
|
||||
{
|
||||
this.name = name;
|
||||
checkBox = new JCheckBox(name, true);
|
||||
}
|
||||
}
|
||||
|
||||
private final static int MAX_LOG_ENTRIES = 10_000;
|
||||
|
||||
private final Client client;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private final JPanel tracker = new JPanel();
|
||||
|
||||
private int lastTick = 0;
|
||||
|
||||
private final int[] oldVarps;
|
||||
private final int[] oldVarps2;
|
||||
private int numVarbits = 10000;
|
||||
|
||||
private final int[] oldIntVarcs;
|
||||
private final String[] oldStrVarcs;
|
||||
|
||||
@Inject
|
||||
VarInspector(Client client, EventBus eventBus)
|
||||
{
|
||||
this.eventBus = eventBus;
|
||||
this.client = client;
|
||||
oldVarps = new int[client.getVarps().length];
|
||||
oldVarps2 = new int[client.getVarps().length];
|
||||
oldIntVarcs = new int[client.getIntVarcs().length];
|
||||
oldStrVarcs = new String[client.getStrVarcs().length];
|
||||
|
||||
setTitle("RuneLite Var Inspector");
|
||||
setIconImage(ClientUI.ICON);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowAdapter()
|
||||
{
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e)
|
||||
{
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
tracker.setLayout(new DynamicGridLayout(0, 1, 0, 3));
|
||||
|
||||
final JPanel trackerWrapper = new JPanel();
|
||||
trackerWrapper.setLayout(new BorderLayout());
|
||||
trackerWrapper.add(tracker, BorderLayout.NORTH);
|
||||
|
||||
final JScrollPane trackerScroller = new JScrollPane(trackerWrapper);
|
||||
trackerScroller.setPreferredSize(new Dimension(400, 400));
|
||||
|
||||
final JScrollBar vertical = trackerScroller.getVerticalScrollBar();
|
||||
vertical.addAdjustmentListener(new AdjustmentListener()
|
||||
{
|
||||
int lastMaximum = actualMax();
|
||||
|
||||
private int actualMax()
|
||||
{
|
||||
return vertical.getMaximum() - vertical.getModel().getExtent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e)
|
||||
{
|
||||
if (vertical.getValue() >= lastMaximum)
|
||||
{
|
||||
vertical.setValue(actualMax());
|
||||
}
|
||||
lastMaximum = actualMax();
|
||||
}
|
||||
});
|
||||
|
||||
add(trackerScroller, BorderLayout.CENTER);
|
||||
|
||||
final JPanel trackerOpts = new JPanel();
|
||||
trackerOpts.setLayout(new FlowLayout());
|
||||
for (VarType cb : VarType.values())
|
||||
{
|
||||
trackerOpts.add(cb.getCheckBox());
|
||||
}
|
||||
add(trackerOpts, BorderLayout.SOUTH);
|
||||
|
||||
pack();
|
||||
}
|
||||
|
||||
private void addVarLog(VarType type, String name, int old, int neew)
|
||||
{
|
||||
addVarLog(type, name, Integer.toString(old), Integer.toString(neew));
|
||||
}
|
||||
|
||||
private void addVarLog(VarType type, String name, String old, String neew)
|
||||
{
|
||||
if (!type.getCheckBox().isSelected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int tick = client.getTickCount();
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (tick != lastTick)
|
||||
{
|
||||
lastTick = tick;
|
||||
JLabel header = new JLabel("Tick " + tick);
|
||||
header.setFont(FontManager.getRunescapeSmallFont());
|
||||
header.setBorder(new CompoundBorder(
|
||||
BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.LIGHT_GRAY_COLOR),
|
||||
BorderFactory.createEmptyBorder(3, 6, 0, 0)
|
||||
));
|
||||
tracker.add(header);
|
||||
}
|
||||
tracker.add(new JLabel(String.format("%s %s changed: %s -> %s", type.getName(), name, old, neew)));
|
||||
|
||||
// Cull very old stuff
|
||||
for (; tracker.getComponentCount() > MAX_LOG_ENTRIES; )
|
||||
{
|
||||
tracker.remove(0);
|
||||
}
|
||||
|
||||
tracker.revalidate();
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged ev)
|
||||
{
|
||||
int[] varps = client.getVarps();
|
||||
|
||||
// Check varbits
|
||||
for (int i = 0; i < numVarbits; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
int old = client.getVarbitValue(oldVarps, i);
|
||||
int neew = client.getVarbitValue(varps, i);
|
||||
if (old != neew)
|
||||
{
|
||||
// Set the varbit so it doesn't show in the varp changes
|
||||
// However, some varbits share common bits, so we only do it in oldVarps2
|
||||
// Example: 4101 collides with 4104-4129
|
||||
client.setVarbitValue(oldVarps2, i, neew);
|
||||
|
||||
String name = String.format("%d", i);
|
||||
for (Varbits varbit : Varbits.values())
|
||||
{
|
||||
if (varbit.getId() == i)
|
||||
{
|
||||
name = String.format("%s(%d)", varbit.name(), i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
addVarLog(VarType.VARBIT, name, old, neew);
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
// We don't know what the last varbit is, so we just hit the end, then set it for future iterations
|
||||
log.debug("Hit OOB at varbit {}", i);
|
||||
numVarbits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check varps
|
||||
for (int i = 0; i < varps.length; i++)
|
||||
{
|
||||
int old = oldVarps2[i];
|
||||
int neew = varps[i];
|
||||
if (old != neew)
|
||||
{
|
||||
String name = String.format("%d", i);
|
||||
for (VarPlayer varp : VarPlayer.values())
|
||||
{
|
||||
if (varp.getId() == i)
|
||||
{
|
||||
name = String.format("%s(%d)", varp.name(), i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
addVarLog(VarType.VARP, name, old, neew);
|
||||
}
|
||||
}
|
||||
|
||||
System.arraycopy(client.getVarps(), 0, oldVarps, 0, oldVarps.length);
|
||||
System.arraycopy(client.getVarps(), 0, oldVarps2, 0, oldVarps2.length);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarClientIntChanged(VarClientIntChanged e)
|
||||
{
|
||||
int idx = e.getIndex();
|
||||
int neew = client.getIntVarcs()[idx];
|
||||
int old = oldIntVarcs[idx];
|
||||
oldIntVarcs[idx] = neew;
|
||||
|
||||
if (old != neew)
|
||||
{
|
||||
String name = String.format("%d", idx);
|
||||
for (VarClientInt varc : VarClientInt.values())
|
||||
{
|
||||
if (varc.getIndex() == idx)
|
||||
{
|
||||
name = String.format("%s(%d)", varc.name(), idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
addVarLog(VarType.VARCINT, name, old, neew);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarClientStrChanged(VarClientStrChanged e)
|
||||
{
|
||||
int idx = e.getIndex();
|
||||
String neew = client.getStrVarcs()[idx];
|
||||
String old = oldStrVarcs[idx];
|
||||
oldStrVarcs[idx] = neew;
|
||||
|
||||
if (!Objects.equals(old, neew))
|
||||
{
|
||||
String name = String.format("%d", idx);
|
||||
for (VarClientStr varc : VarClientStr.values())
|
||||
{
|
||||
if (varc.getIndex() == idx)
|
||||
{
|
||||
name = String.format("%s(%d)", varc.name(), idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (old != null)
|
||||
{
|
||||
old = "\"" + old + "\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
old = "null";
|
||||
}
|
||||
if (neew != null)
|
||||
{
|
||||
neew = "\"" + neew + "\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
neew = "null";
|
||||
}
|
||||
addVarLog(VarType.VARCSTR, name, old, neew);
|
||||
}
|
||||
}
|
||||
|
||||
public void open()
|
||||
{
|
||||
System.arraycopy(client.getVarps(), 0, oldVarps, 0, oldVarps.length);
|
||||
System.arraycopy(client.getVarps(), 0, oldVarps2, 0, oldVarps2.length);
|
||||
System.arraycopy(client.getIntVarcs(), 0, oldIntVarcs, 0, oldIntVarcs.length);
|
||||
System.arraycopy(client.getStrVarcs(), 0, oldStrVarcs, 0, oldStrVarcs.length);
|
||||
|
||||
eventBus.register(this);
|
||||
setVisible(true);
|
||||
toFront();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
tracker.removeAll();
|
||||
eventBus.unregister(this);
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.devtools;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Arrays;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
|
||||
@Slf4j
|
||||
public class VarTracker
|
||||
{
|
||||
private final Client client;
|
||||
|
||||
private int[] varPs;
|
||||
|
||||
public VarTracker(Client client)
|
||||
{
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void snapshot(ActionEvent e)
|
||||
{
|
||||
if (varPs == null)
|
||||
{
|
||||
varPs = copy(client.getVarps());
|
||||
|
||||
log.info("Snapshotted VarPs");
|
||||
return;
|
||||
}
|
||||
|
||||
int[] newVarPs = client.getVarps();
|
||||
|
||||
for (int i = 0; i < Math.min(varPs.length, newVarPs.length); ++i)
|
||||
{
|
||||
int before = varPs[i];
|
||||
int after = newVarPs[i];
|
||||
|
||||
if (before == after)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("VarP index {} has changed from {} to {}: {} -> {}",
|
||||
i, before, after, prettyPrintInt(before), prettyPrintInt(after));
|
||||
}
|
||||
|
||||
varPs = copy(newVarPs);
|
||||
}
|
||||
|
||||
public void clear(ActionEvent e)
|
||||
{
|
||||
varPs = null;
|
||||
}
|
||||
|
||||
private static int[] copy(int[] array)
|
||||
{
|
||||
return Arrays.copyOf(array, array.length);
|
||||
}
|
||||
|
||||
private static String prettyPrintInt(int value)
|
||||
{
|
||||
String s = Integer.toBinaryString(value);
|
||||
while (s.length() < 32)
|
||||
{
|
||||
s = "0" + s;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 32; i += 8)
|
||||
{
|
||||
String substr = s.substring(i, i + 8);
|
||||
if (i > 0)
|
||||
{
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(substr);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package net.runelite.mixins;
|
||||
|
||||
import net.runelite.api.events.VarClientIntChanged;
|
||||
import net.runelite.api.events.VarClientStrChanged;
|
||||
import net.runelite.api.mixins.FieldHook;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
import net.runelite.api.mixins.Mixin;
|
||||
import net.runelite.client.callback.Hooks;
|
||||
import net.runelite.rs.api.RSVarcs;
|
||||
|
||||
@Mixin(RSVarcs.class)
|
||||
public abstract class RSVarcsMixin implements RSVarcs
|
||||
{
|
||||
@FieldHook("varCInts")
|
||||
@Inject
|
||||
public void onVarCIntChanged(int idx)
|
||||
{
|
||||
Hooks.eventBus.post(new VarClientIntChanged(idx));
|
||||
}
|
||||
|
||||
@FieldHook("varCStrings")
|
||||
@Inject
|
||||
public void onVarCStrChanged(int idx)
|
||||
{
|
||||
Hooks.eventBus.post(new VarClientStrChanged(idx));
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public abstract class VarbitMixin implements RSClient
|
||||
public int getVar(Varbits varbit)
|
||||
{
|
||||
int varbitId = varbit.getId();
|
||||
return getVarbitValue(varbitId);
|
||||
return getVarbitValue(getVarps(), varbitId);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@@ -65,12 +65,12 @@ public abstract class VarbitMixin implements RSClient
|
||||
public void setSetting(Varbits varbit, int value)
|
||||
{
|
||||
int varbitId = varbit.getId();
|
||||
setVarbitValue(varbitId, value);
|
||||
setVarbitValue(getVarps(), varbitId, value);
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getVarbitValue(int varbitId)
|
||||
public int getVarbitValue(int[] varps, int varbitId)
|
||||
{
|
||||
RSVarbit v = varbitCache.getIfPresent(varbitId);
|
||||
if (v == null)
|
||||
@@ -81,7 +81,11 @@ public abstract class VarbitMixin implements RSClient
|
||||
varbitCache.put(varbitId, v);
|
||||
}
|
||||
|
||||
int[] varps = getVarps();
|
||||
if (v.getIndex() == 0 && v.getLeastSignificantBit() == 0 && v.getMostSignificantBit() == 0)
|
||||
{
|
||||
throw new IndexOutOfBoundsException("Varbit " + varbitId + " does not exist");
|
||||
}
|
||||
|
||||
int value = varps[v.getIndex()];
|
||||
int lsb = v.getLeastSignificantBit();
|
||||
int msb = v.getMostSignificantBit();
|
||||
@@ -91,7 +95,7 @@ public abstract class VarbitMixin implements RSClient
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setVarbitValue(int varbitId, int value)
|
||||
public void setVarbitValue(int[] varps, int varbitId, int value)
|
||||
{
|
||||
RSVarbit v = varbitCache.getIfPresent(varbitId);
|
||||
if (v == null)
|
||||
@@ -102,7 +106,6 @@ public abstract class VarbitMixin implements RSClient
|
||||
varbitCache.put(varbitId, v);
|
||||
}
|
||||
|
||||
int[] varps = getVarps();
|
||||
int lsb = v.getLeastSignificantBit();
|
||||
int msb = v.getMostSignificantBit();
|
||||
int mask = (1 << ((msb - lsb) + 1)) - 1;
|
||||
@@ -113,13 +116,27 @@ public abstract class VarbitMixin implements RSClient
|
||||
@Override
|
||||
public int getVar(VarClientInt varClientInt)
|
||||
{
|
||||
return getVarcs().getIntVarcs()[varClientInt.getIndex()];
|
||||
return getIntVarcs()[varClientInt.getIndex()];
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public String getVar(VarClientStr varClientStr)
|
||||
{
|
||||
return getVarcs().getStrVarcs()[varClientStr.getIndex()];
|
||||
return getStrVarcs()[varClientStr.getIndex()];
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int[] getIntVarcs()
|
||||
{
|
||||
return getVarcs().getIntVarcs();
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public String[] getStrVarcs()
|
||||
{
|
||||
return getVarcs().getStrVarcs();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user