Skip to content

Commit

Permalink
[WIP] Add bad varbit log-to-file
Browse files Browse the repository at this point in the history
This should be rebased into its own little class
  • Loading branch information
pajlada committed Oct 1, 2023
1 parent b4ad1b7 commit 8936077
Showing 1 changed file with 248 additions and 1 deletion.
249 changes: 248 additions & 1 deletion src/main/java/com/questhelper/QuestHelperPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
*/
package com.questhelper;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.google.common.primitives.Ints;
import com.google.inject.Binder;
import com.google.inject.Injector;
Expand All @@ -48,7 +51,14 @@
import com.questhelper.steps.playermadesteps.extendedruneliteobjects.RuneliteObjectManager;
import com.google.inject.Module;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -62,13 +72,15 @@
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.swing.SwingUtilities;
import javax.swing.*;
import javax.swing.border.CompoundBorder;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.IndexDataBase;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
Expand All @@ -78,6 +90,11 @@
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.QuestState;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr;
import net.runelite.api.VarPlayer;
import net.runelite.api.VarbitComposition;
import net.runelite.api.Varbits;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ChatMessage;
Expand All @@ -87,6 +104,8 @@
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.VarClientIntChanged;
import net.runelite.api.events.VarClientStrChanged;
import net.runelite.api.events.VarbitChanged;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.RuneLite;
Expand All @@ -105,6 +124,8 @@
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.bank.BankSearch;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.components.colorpicker.ColorPickerManager;
import net.runelite.client.ui.overlay.OverlayManager;
Expand All @@ -118,6 +139,76 @@
@Slf4j
public class QuestHelperPlugin extends Plugin
{
@Getter
private enum VarType
{
VARBIT("Varbit"),
VARP("VarPlayer"),
VARCINT("VarClientInt"),
VARCSTR("VarClientStr");

private final String name;

VarType(String name)
{
this.name = name;
}
}

private static final Map<Integer, String> VARBIT_NAMES;
private static final Map<Integer, String> VARCINT_NAMES;
private static final Map<Integer, String> VARCSTR_NAMES;
private static final Map<Integer, String> VARP_NAMES;

static
{
ImmutableMap.Builder<Integer, String> varbits = new ImmutableMap.Builder<>();
ImmutableMap.Builder<Integer, String> varcint = new ImmutableMap.Builder<>();
ImmutableMap.Builder<Integer, String> varcstr = new ImmutableMap.Builder<>();
ImmutableMap.Builder<Integer, String> varp = new ImmutableMap.Builder<>();

try
{
for (Field f : Varbits.class.getDeclaredFields())
{
varbits.put(f.getInt(null), f.getName());
}

for (Field f : VarClientInt.class.getDeclaredFields())
{
varcint.put(f.getInt(null), f.getName());
}

for (Field f : VarClientStr.class.getDeclaredFields())
{
varcstr.put(f.getInt(null), f.getName());
}

for (Field f : VarPlayer.class.getDeclaredFields())
{
varp.put(f.getInt(null), f.getName());
}
}
catch (IllegalAccessException ex)
{
log.error("error setting up var names", ex);
}

VARBIT_NAMES = varbits.build();
VARCINT_NAMES = varcint.build();
VARCSTR_NAMES = varcstr.build();
VARP_NAMES = varp.build();
}

private int lastTick = 0;

private int[] oldVarps = null;
private int[] oldVarps2 = null;

private Multimap<Integer, Integer> varbits;
private Map<Integer, Object> varcs = null;


private static final int[] QUESTLIST_WIDGET_IDS = new int[]
{
QuestWidgets.QUEST_CONTAINER.getId()
Expand Down Expand Up @@ -281,9 +372,42 @@ QuestHelperConfig getConfig(ConfigManager configManager)
return configManager.getConfig(QuestHelperConfig.class);
}

FileOutputStream varbitFileStream;

private static final File QH_DIR = new File(RuneLite.RUNELITE_DIR, "quest-helper");

@Override
protected void startUp() throws IOException
{
QH_DIR.mkdir();
this.varbitFileStream = new FileOutputStream(Path.of(QH_DIR.getPath()).resolve(String.format("%s-varbits.txt", Long.toString(System.currentTimeMillis()))).toString());
if (oldVarps == null)
{
oldVarps = new int[client.getVarps().length];
oldVarps2 = new int[client.getVarps().length];
}

System.arraycopy(client.getVarps(), 0, oldVarps, 0, oldVarps.length);
System.arraycopy(client.getVarps(), 0, oldVarps2, 0, oldVarps2.length);
// NOTE: client.getVarcMap can return a NPE sometimes on startup
varcs = new HashMap<>(client.getVarcMap());
varbits = HashMultimap.create();

clientThread.invoke(() ->
{
// Build varp index -> varbit id map
IndexDataBase indexVarbits = client.getIndexConfig();
final int[] varbitIds = indexVarbits.getFileIds(14);
for (int id : varbitIds)
{
VarbitComposition varbit = client.getVarbit(id);
if (varbit != null)
{
varbits.put(varbit.getIndex(), id);
}
}
});

bankTagService = new QuestHelperBankTagService(this, questBank);
bankTagsMain = new QuestBankTab(this);
bankTagsMain.startUp();
Expand Down Expand Up @@ -337,6 +461,15 @@ protected void startUp() throws IOException
@Override
protected void shutDown()
{
try
{
this.varbitFileStream.close();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
this.varbitFileStream = null;
eventBus.unregister(bankTagsMain);
bankTagsMain.shutDown();
runeliteObjectManager.shutDown();
Expand Down Expand Up @@ -452,14 +585,128 @@ public void onGameStateChanged(final GameStateChanged event)
}
}

@Subscribe
public void onVarClientIntChanged(VarClientIntChanged e)
{
int idx = e.getIndex();
int newValue = (Integer) client.getVarcMap().getOrDefault(idx, 0);
int oldValue = (Integer) varcs.getOrDefault(idx, 0);
varcs.put(idx, newValue);

if (oldValue != newValue)
{
final String name = VARCINT_NAMES.getOrDefault(idx, Integer.toString(idx));
addVarLog(VarType.VARCINT, name, oldValue, newValue);
}
}

@Subscribe
public void onVarClientStrChanged(VarClientStrChanged e)
{
int idx = e.getIndex();
String newValue = (String) client.getVarcMap().getOrDefault(idx, "");
String oldValue = (String) varcs.getOrDefault(idx, "");
varcs.put(idx, newValue);

if (!Objects.equals(oldValue, newValue))
{
final String name = VARCSTR_NAMES.getOrDefault(idx, Integer.toString(idx));
if (oldValue != null)
{
oldValue = "\"" + oldValue + "\"";
}
else
{
oldValue = "null";
}
if (newValue != null)
{
newValue = "\"" + newValue + "\"";
}
else
{
newValue = "null";
}
addVarLog(VarType.VARCSTR, name, oldValue, newValue);
}
}

private void addVarLog(VarType type, String name, int oldValue, int newValue)
{
addVarLog(type, name, Integer.toString(oldValue), Integer.toString(newValue));
}


private void addVarLog(VarType type, String name, String oldValue, String newValue)
{
int tick = client.getTickCount();
LocalDateTime now = LocalDateTime.now();
String body = String.format("[%s] [%s] %s %s changed: %s -> %s", now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")), tick, type.getName(), name, oldValue, newValue);
if (this.varbitFileStream != null) {
try
{
this.varbitFileStream.write(body.getBytes());
this.varbitFileStream.write('\n');
}
catch (IOException e)
{
log.warn("failed to write to varbit file", e);
}
}
}



@Subscribe
public void onVarbitChanged(VarbitChanged event)
{
int index = event.getIndex();
int[] varps = client.getVarps();

// Check varbits
for (int i : varbits.get(index))
{
int oldValue = client.getVarbitValue(oldVarps, i);
int newValue = client.getVarbitValue(varps, i);
if (oldValue != newValue)
{
// 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, newValue);

final String name = VARBIT_NAMES.getOrDefault(i, Integer.toString(i));
addVarLog(VarType.VARBIT, name, oldValue, newValue);
}
}

// Check varps
int oldValue = oldVarps2[index];
int newValue = varps[index];
if (oldValue != newValue)
{
String name = VARP_NAMES.get(index);
if (name != null)
{
name += "(" + index + ")";
}
else
{
name = Integer.toString(index);
}
addVarLog(VarType.VARP, name, oldValue, newValue);
}

System.arraycopy(client.getVarps(), 0, oldVarps, 0, oldVarps.length);
System.arraycopy(client.getVarps(), 0, oldVarps2, 0, oldVarps2.length);

if (!(client.getGameState() == GameState.LOGGED_IN))
{
return;
}

// log.debug(String.format("varbit changed: %s", event));

if (selectedQuest == null)
{
return;
Expand Down

0 comments on commit 8936077

Please sign in to comment.