diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index 0b4b04e..97cfe64 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -39,7 +39,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito new ConfigLoader(); - String version = "2.5.6"; + String version = "2.5.7"; callbacks.setExtensionName(String.format("HaE (%s) - Highlighter and Extractor", version)); // 定义输出 diff --git a/src/main/java/burp/ui/board/Databoard.java b/src/main/java/burp/ui/board/Databoard.java index 4f9a8de..7a11801 100644 --- a/src/main/java/burp/ui/board/Databoard.java +++ b/src/main/java/burp/ui/board/Databoard.java @@ -69,7 +69,7 @@ public class Databoard extends JPanel { String cleanedHost = StringHelper.replaceFirstOccurrence(host, "*.", ""); if (host.contains("*")) { - ConfigEntry.globalDataMap.keySet().removeIf(i -> i.contains(cleanedHost) || cleanedHost.equals("**")); + ConfigEntry.globalDataMap.keySet().removeIf(i -> i.contains(cleanedHost) || cleanedHost.contains("*")); } else { ConfigEntry.globalDataMap.remove(host); } diff --git a/src/main/java/burp/ui/board/DatatablePanel.java b/src/main/java/burp/ui/board/DatatablePanel.java index 881d46a..52c81d6 100644 --- a/src/main/java/burp/ui/board/DatatablePanel.java +++ b/src/main/java/burp/ui/board/DatatablePanel.java @@ -2,19 +2,32 @@ package burp.ui.board; import java.awt.BorderLayout; import java.awt.Color; +import java.awt.GridLayout; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.Comparator; import java.util.List; +import java.util.regex.Pattern; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; @@ -37,7 +50,10 @@ public class DatatablePanel extends JPanel { private List fullList; // 假设这是一个包含所有数据的列表 private JScrollPane scrollPane; private String tableName; - private final int SHOW_LENGTH = 3000; + private final int SHOW_LENGTH = 2; + private JCheckBox searchMode = new JCheckBox("Reverse search"); + private JCheckBox showMode = new JCheckBox("Show all data"); + private boolean scrollFlag = true; public DatatablePanel(String tableName, List list) { fullList = list; @@ -49,6 +65,13 @@ public class DatatablePanel extends JPanel { model = new DefaultTableModel(columnNames, 0); table = new JTable(model); sorter = new TableRowSorter<>(model); + // 设置ID排序 + sorter.setComparator(0, new Comparator() { + @Override + public int compare(Integer s1, Integer s2) { + return s1.compareTo(s2); + } + }); table.setRowSorter(sorter); TableColumn idColumn = table.getColumnModel().getColumn(0); @@ -56,6 +79,7 @@ public class DatatablePanel extends JPanel { String defaultText = "Search"; searchField = new JTextField(defaultText); + // 设置灰色默认文本Search searchField.setForeground(Color.GRAY); searchField.addFocusListener(new FocusListener() { @@ -93,18 +117,6 @@ public class DatatablePanel extends JPanel { performSearch(); } - private void performSearch() { - // 通过字体颜色来判断是否可以进行过滤 - if (searchField.getForeground() == Color.BLACK) { - String searchText = searchField.getText(); - if (sorter == null) { - sorter = new TableRowSorter<>(model); - table.setRowSorter(sorter); - } - RowFilter rowFilter = RowFilter.regexFilter(String.format("%s%s", "(?i)", searchText), 1); - sorter.setRowFilter(rowFilter); - } - } }); // 设置布局 @@ -118,7 +130,7 @@ public class DatatablePanel extends JPanel { }); // 添加滚动监听器,以加载更多数据 - scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { + AdjustmentListener scrollListener = new AdjustmentListener() { @Override public void adjustmentValueChanged(AdjustmentEvent e) { if (fullList.size() > SHOW_LENGTH) { @@ -132,17 +144,95 @@ public class DatatablePanel extends JPanel { } } } + }; + + scrollPane.getVerticalScrollBar().addAdjustmentListener(scrollListener); + + searchMode.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + performSearch(); + } + }); + + showMode.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + model.setRowCount(0); + if (e.getStateChange() == ItemEvent.SELECTED) { + scrollFlag = false; + loadPageData(); + showMode.setEnabled(false); + } + } }); setLayout(new BorderLayout(0, 5)); + + JPanel optionsPanel = new JPanel(); + optionsPanel.setBorder(BorderFactory.createEmptyBorder(2, 3, 5, 5)); + optionsPanel.setLayout(new BoxLayout(optionsPanel, BoxLayout.X_AXIS)); + + // 新增复选框要在这修改rows + JPanel menuPanel = new JPanel(new GridLayout(2, 1)); + menuPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); + JPopupMenu menu = new JPopupMenu(); + menuPanel.add(searchMode); + menuPanel.add(showMode); + menu.add(menuPanel); + + JButton settingsButton = new JButton("Settings"); + settingsButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + int x = settingsButton.getX(); + int y = settingsButton.getY() - menu.getPreferredSize().height; + menu.show(settingsButton, x, y); + } + }); + + optionsPanel.add(settingsButton); + optionsPanel.add(Box.createHorizontalStrut(5)); + optionsPanel.add(searchField); + add(scrollPane, BorderLayout.CENTER); - add(searchField, BorderLayout.SOUTH); + add(optionsPanel, BorderLayout.SOUTH); + loadPageData(); } + private void performSearch() { + // 检查文本字段的字体颜色是否为黑色,表示可以进行搜索 + if (searchField.getForeground().equals(Color.BLACK)) { + // 获取搜索文本 + String searchText = searchField.getText(); + + // 创建行过滤器 + RowFilter rowFilter; + + // 检查搜索模式是否为选中状态 + if (searchMode.isSelected()) { + // 反向搜索:创建一个过滤器以排除与正则表达式匹配的行 + rowFilter = new RowFilter() { + public boolean include(Entry entry) { + // 对每一行的第二列进行判断(假设第二列的索引是1) + String value = (String) entry.getValue(1); + // 如果该列的值不包含搜索文本,则返回true,否则返回false + return searchText.isEmpty() ? true : !value.toLowerCase().contains(searchText.toLowerCase()); + } + }; + } else { + // 正向搜索:创建一个过滤器以包含与正则表达式匹配的行 + rowFilter = RowFilter.regexFilter("(?i)" + Pattern.quote(searchText), 1); + } + + // 设置过滤器到排序器 + sorter.setRowFilter(rowFilter); + } + } + // 加载指定页的数据 private void loadPageData() { - if (fullList.size() > SHOW_LENGTH) { + if (fullList.size() > SHOW_LENGTH && scrollFlag) { int start = currentPage * pageSize; int end = Math.min((currentPage + 1) * pageSize, fullList.size()); int lastRow = model.getRowCount(); @@ -158,6 +248,16 @@ public class DatatablePanel extends JPanel { } } + private static void addRowToTable(DefaultTableModel model, Object[] data) { + // 获取当前ID + int rowCount = model.getRowCount(); + int id = rowCount > 0 ? (Integer) model.getValueAt(rowCount - 1, 0) + 1 : 1; + Object[] rowData = new Object[data.length + 1]; + rowData[0] = id; // 设置ID列的值 + System.arraycopy(data, 0, rowData, 1, data.length); // 拷贝其余数据 + model.addRow(rowData); // 添加行 + } + public void updatePageSize() { if (fullList.size() > SHOW_LENGTH && isShowing()) { int oldPageSize = pageSize; @@ -172,7 +272,7 @@ public class DatatablePanel extends JPanel { private int getDynamicSize() { int visibleHeight = scrollPane.getViewport().getViewRect().height; int rowHeight = table.getRowHeight(); - return Math.max(1, visibleHeight / rowHeight + 2); + return Math.max(1, visibleHeight / rowHeight + 5); } public void setTableListener(MessagePanel messagePanel) { @@ -185,7 +285,7 @@ public class DatatablePanel extends JPanel { if (e.getClickCount() == 2) { int selectedRow = table.getSelectedRow(); if (selectedRow != -1) { - String rowData = table.getValueAt(selectedRow, 0).toString(); + String rowData = table.getValueAt(selectedRow, 1).toString(); messagePanel.applyMessageFilter(tableName, rowData); } } @@ -218,16 +318,6 @@ public class DatatablePanel extends JPanel { return retData.toString(); } - private static void addRowToTable(DefaultTableModel model, Object[] data) { - // 获取当前ID - int rowCount = model.getRowCount(); - int id = rowCount > 0 ? (Integer) model.getValueAt(rowCount - 1, 0) + 1 : 1; - Object[] rowData = new Object[data.length + 1]; - rowData[0] = id; // 设置ID列的值 - System.arraycopy(data, 0, rowData, 1, data.length); // 拷贝其余数据 - model.addRow(rowData); // 添加行 - } - public JTable getTable() { return this.table; }