Restructured player list loading to incorporate new data tags.

This commit is contained in:
StevenLawson 2014-08-22 23:00:33 -04:00
parent e8c146bca3
commit 467f6e47ea
6 changed files with 373 additions and 155 deletions

View file

@ -4,8 +4,9 @@ import java.awt.Color;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.*; import java.io.*;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Timer; import javax.swing.Timer;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
@ -14,6 +15,8 @@ import org.apache.commons.net.telnet.TelnetClient;
public class BTC_ConnectionManager public class BTC_ConnectionManager
{ {
private static final Pattern LOGIN_MESSAGE = Pattern.compile("\\[.+?@BukkitTelnet\\]\\$ Logged in as (.+)\\.");
private final TelnetClient telnetClient; private final TelnetClient telnetClient;
private Thread connectThread; private Thread connectThread;
private String hostname; private String hostname;
@ -168,11 +171,10 @@ public class BTC_ConnectionManager
String line; String line;
while ((line = reader.readLine()) != null) while ((line = reader.readLine()) != null)
{ {
String _loginName = null; String _loginName = null;
if (BTC_ConnectionManager.this.loginName == null) if (BTC_ConnectionManager.this.loginName == null)
{ {
_loginName = BTC_PlayerListDecoder.checkForLoginMessage(line); _loginName = checkForLoginMessage(line);
} }
if (_loginName != null) if (_loginName != null)
{ {
@ -182,10 +184,16 @@ public class BTC_ConnectionManager
} }
else else
{ {
final Map<String, PlayerInfo> playerList = BTC_PlayerListDecoder.checkForPlayerListMessage(line); final PlayerInfo selectedPlayer = btc.getSelectedPlayer();
if (playerList != null) String selectedPlayerName = null;
if (selectedPlayer != null)
{ {
btc.updatePlayerList(playerList); selectedPlayerName = selectedPlayer.getName();
}
if (BTC_PlayerListDecoder.checkForPlayerListMessage(line, btc.getPlayerList()))
{
btc.updatePlayerList(selectedPlayerName);
} }
else else
{ {
@ -214,6 +222,17 @@ public class BTC_ConnectionManager
this.connectThread.start(); this.connectThread.start();
} }
public static final String checkForLoginMessage(String message)
{
final Matcher matcher = LOGIN_MESSAGE.matcher(message);
if (matcher.find())
{
return matcher.group(1);
}
return null;
}
public final void updateTitle(final boolean isConnected) public final void updateTitle(final boolean isConnected)
{ {
final BTC_MainPanel mainPanel = BukkitTelnetClient.mainPanel; final BTC_MainPanel mainPanel = BukkitTelnetClient.mainPanel;

View file

@ -71,7 +71,7 @@
<EmptySpace type="separate" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="txtCommand" max="32767" attributes="0"/> <Component id="txtCommand" max="32767" attributes="0"/>
<Component id="txtServer" pref="428" max="32767" attributes="0"/> <Component id="txtServer" pref="431" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
@ -93,7 +93,7 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="mainOutputScoll" pref="360" max="32767" attributes="0"/> <Component id="mainOutputScoll" pref="365" max="32767" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="txtCommand" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="txtCommand" alignment="3" min="-2" max="-2" attributes="0"/>
@ -217,7 +217,15 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane2" pref="296" max="32767" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane2" pref="293" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="txtNumPlayers" min="-2" pref="65" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -226,7 +234,12 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane2" pref="395" max="32767" attributes="0"/> <Component id="jScrollPane2" pref="369" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtNumPlayers" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -243,13 +256,6 @@
<Component class="javax.swing.JTable" name="tblPlayers"> <Component class="javax.swing.JTable" name="tblPlayers">
<Properties> <Properties>
<Property name="autoCreateRowSorter" type="boolean" value="true"/> <Property name="autoCreateRowSorter" type="boolean" value="true"/>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="3" rowCount="0">
<Column editable="false" title="Name" type="java.lang.String"/>
<Column editable="false" title="Display Name" type="java.lang.String"/>
<Column editable="false" title="IP" type="java.lang.String"/>
</Table>
</Property>
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
<TableColumnModel selectionModel="1"> <TableColumnModel selectionModel="1">
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
@ -279,6 +285,16 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" value="# Players:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtNumPlayers">
<Properties>
<Property name="editable" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Container class="javax.swing.JPanel" name="jPanel1"> <Container class="javax.swing.JPanel" name="jPanel1">
@ -301,7 +317,7 @@
<Component id="chkShowChatOnly" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="chkShowChatOnly" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="chkIgnoreErrors" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="chkIgnoreErrors" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace pref="79" max="32767" attributes="0"/> <EmptySpace pref="76" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -316,7 +332,7 @@
<Component id="chkShowChatOnly" min="-2" pref="23" max="-2" attributes="0"/> <Component id="chkShowChatOnly" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="chkIgnoreErrors" min="-2" pref="23" max="-2" attributes="0"/> <Component id="chkIgnoreErrors" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace pref="318" max="32767" attributes="0"/> <EmptySpace pref="323" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>

View file

@ -1,20 +1,43 @@
package me.StevenLawson.BukkitTelnetClient; package me.StevenLawson.BukkitTelnetClient;
import java.awt.*; import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.StringSelection;
import java.awt.event.*; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL; import java.net.URL;
import java.util.*; import java.util.ArrayList;
import javax.swing.*; import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import javax.swing.JCheckBox;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.Timer; import javax.swing.Timer;
import javax.swing.table.DefaultTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.text.*; import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
public class BTC_MainPanel extends javax.swing.JFrame public class BTC_MainPanel extends javax.swing.JFrame
{ {
private final BTC_ConnectionManager connectionManager = new BTC_ConnectionManager(); private final BTC_ConnectionManager connectionManager = new BTC_ConnectionManager();
private final List<PlayerInfo> playerList = new ArrayList<>();
private final PlayerListTableModel playerListTableModel = new PlayerListTableModel(playerList);
public BTC_MainPanel() public BTC_MainPanel()
{ {
@ -47,6 +70,8 @@ public class BTC_MainPanel extends javax.swing.JFrame
this.connectionManager.updateTitle(false); this.connectionManager.updateTitle(false);
this.tblPlayers.setModel(playerListTableModel);
this.tblPlayers.getRowSorter().toggleSortOrder(0); this.tblPlayers.getRowSorter().toggleSortOrder(0);
this.setLocationRelativeTo(null); this.setLocationRelativeTo(null);
@ -159,99 +184,82 @@ public class BTC_MainPanel extends javax.swing.JFrame
public final PlayerInfo getSelectedPlayer() public final PlayerInfo getSelectedPlayer()
{ {
String name = null;
String ip = null;
String displayName = null;
final JTable table = BTC_MainPanel.this.tblPlayers; final JTable table = BTC_MainPanel.this.tblPlayers;
final DefaultTableModel model = (DefaultTableModel) table.getModel();
final int selectedRow = table.getSelectedRow(); final int selectedRow = table.getSelectedRow();
if (selectedRow < 0) if (selectedRow < 0 || selectedRow >= playerList.size())
{ {
return null; return null;
} }
for (int col = 0; col <= 2; col++) return playerList.get(table.convertRowIndexToModel(selectedRow));
}
public static class PlayerListTableModel extends AbstractTableModel
{
private final List<PlayerInfo> _playerList;
public PlayerListTableModel(List<PlayerInfo> playerList)
{ {
final int modelRow = table.convertRowIndexToModel(selectedRow); this._playerList = playerList;
final int modelCol = table.convertColumnIndexToModel(col); }
final String colName = model.getColumnName(modelCol); @Override
final Object value = model.getValueAt(modelRow, modelCol); public int getRowCount()
{
return _playerList.size();
}
if (null != colName) @Override
public int getColumnCount()
{
return PlayerInfo.numColumns;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
if (rowIndex >= _playerList.size())
{ {
switch (colName) return null;
{
case "Name":
{
name = value.toString();
break;
}
case "IP":
{
ip = value.toString();
break;
}
case "Display Name":
{
displayName = value.toString();
break;
}
}
} }
return _playerList.get(rowIndex).getColumnValue(columnIndex);
} }
if (name != null && ip != null & displayName != null) @Override
public String getColumnName(int columnIndex)
{ {
return new PlayerInfo(name, ip, displayName); return columnIndex < getColumnCount() ? PlayerInfo.columnNames[columnIndex] : "null";
} }
else
public List<PlayerInfo> getPlayerList()
{ {
return null; return _playerList;
} }
} }
public final void updatePlayerList(final Map<String, PlayerInfo> playerList) public final void updatePlayerList(final String selectedPlayerName)
{ {
EventQueue.invokeLater(new Runnable() EventQueue.invokeLater(new Runnable()
{ {
@Override @Override
public void run() public void run()
{ {
final JTable table = BTC_MainPanel.this.tblPlayers; playerListTableModel.fireTableDataChanged();
final DefaultTableModel model = (DefaultTableModel) table.getModel();
final PlayerInfo player = getSelectedPlayer(); BTC_MainPanel.this.txtNumPlayers.setText("" + playerList.size());
model.setRowCount(0); if (selectedPlayerName != null)
final Iterator<Map.Entry<String, PlayerInfo>> it = playerList.entrySet().iterator();
while (it.hasNext())
{ {
final Map.Entry<String, PlayerInfo> entry = it.next(); final JTable table = BTC_MainPanel.this.tblPlayers;
PlayerInfo playerInfo = entry.getValue(); final ListSelectionModel selectionModel = table.getSelectionModel();
model.addRow(new Object[] for (PlayerInfo player : playerList)
{ {
playerInfo.getName(), if (player.getName().equals(selectedPlayerName))
playerInfo.getDisplayName(),
playerInfo.getIp()
});
}
if (player != null)
{
final int modelCol = table.convertColumnIndexToModel(0);
final int rowCount = table.getRowCount();
for (int row = 0; row < rowCount; row++)
{
if (player.getName().equals(table.getValueAt(row, modelCol).toString()))
{ {
final ListSelectionModel selectionModel = table.getSelectionModel(); selectionModel.setSelectionInterval(0, table.convertRowIndexToView(playerList.indexOf(player)));
selectionModel.setSelectionInterval(0, row);
break;
} }
} }
} }
@ -365,6 +373,12 @@ public class BTC_MainPanel extends javax.swing.JFrame
BTC_MainPanel.this.writeToConsole(new BTC_ConsoleMessage("Copied name to clipboard: " + _player.getName())); BTC_MainPanel.this.writeToConsole(new BTC_ConsoleMessage("Copied name to clipboard: " + _player.getName()));
break; break;
} }
case "Copy UUID":
{
copyToClipboard(_player.getName());
BTC_MainPanel.this.writeToConsole(new BTC_ConsoleMessage("Copied UUID to clipboard: " + _player.getUuid()));
break;
}
} }
} }
} }
@ -389,6 +403,10 @@ public class BTC_MainPanel extends javax.swing.JFrame
item.addActionListener(popupAction); item.addActionListener(popupAction);
popup.add(item); popup.add(item);
item = new PlayerListPopupItem("Copy UUID", player);
item.addActionListener(popupAction);
popup.add(item);
popup.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); popup.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
} }
} }
@ -487,6 +505,8 @@ public class BTC_MainPanel extends javax.swing.JFrame
jPanel2 = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane(); jScrollPane2 = new javax.swing.JScrollPane();
tblPlayers = new javax.swing.JTable(); tblPlayers = new javax.swing.JTable();
jLabel3 = new javax.swing.JLabel();
txtNumPlayers = new javax.swing.JTextField();
jPanel1 = new javax.swing.JPanel(); jPanel1 = new javax.swing.JPanel();
chkIgnorePlayerCommands = new javax.swing.JCheckBox(); chkIgnorePlayerCommands = new javax.swing.JCheckBox();
chkIgnoreServerCommands = new javax.swing.JCheckBox(); chkIgnoreServerCommands = new javax.swing.JCheckBox();
@ -564,7 +584,7 @@ public class BTC_MainPanel extends javax.swing.JFrame
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtCommand) .addComponent(txtCommand)
.addComponent(txtServer, 0, 428, Short.MAX_VALUE)) .addComponent(txtServer, 0, 431, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
@ -582,7 +602,7 @@ public class BTC_MainPanel extends javax.swing.JFrame
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup() .addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(mainOutputScoll, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE) .addComponent(mainOutputScoll, javax.swing.GroupLayout.DEFAULT_SIZE, 365, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtCommand, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(txtCommand, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@ -601,54 +621,38 @@ public class BTC_MainPanel extends javax.swing.JFrame
splitPane.setLeftComponent(jPanel3); splitPane.setLeftComponent(jPanel3);
tblPlayers.setAutoCreateRowSorter(true); tblPlayers.setAutoCreateRowSorter(true);
tblPlayers.setModel(new javax.swing.table.DefaultTableModel(
new Object [][]
{
},
new String []
{
"Name", "Display Name", "IP"
}
)
{
Class[] types = new Class []
{
java.lang.String.class, java.lang.String.class, java.lang.String.class
};
boolean[] canEdit = new boolean []
{
false, false, false
};
public Class getColumnClass(int columnIndex)
{
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return canEdit [columnIndex];
}
});
tblPlayers.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); tblPlayers.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane2.setViewportView(tblPlayers); jScrollPane2.setViewportView(tblPlayers);
tblPlayers.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); tblPlayers.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jLabel3.setText("# Players:");
txtNumPlayers.setEditable(false);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout); jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup( jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE)
.addGroup(jPanel2Layout.createSequentialGroup()
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(txtNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap()) .addContainerGap())
); );
jPanel2Layout.setVerticalGroup( jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE) .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 369, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(txtNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap()) .addContainerGap())
); );
@ -689,7 +693,7 @@ public class BTC_MainPanel extends javax.swing.JFrame
.addComponent(chkIgnoreServerCommands) .addComponent(chkIgnoreServerCommands)
.addComponent(chkShowChatOnly) .addComponent(chkShowChatOnly)
.addComponent(chkIgnoreErrors)) .addComponent(chkIgnoreErrors))
.addContainerGap(79, Short.MAX_VALUE)) .addContainerGap(76, Short.MAX_VALUE))
); );
jPanel1Layout.setVerticalGroup( jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -702,7 +706,7 @@ public class BTC_MainPanel extends javax.swing.JFrame
.addComponent(chkShowChatOnly, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(chkShowChatOnly, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkIgnoreErrors, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(chkIgnoreErrors, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(318, Short.MAX_VALUE)) .addContainerGap(323, Short.MAX_VALUE))
); );
jTabbedPane1.addTab("Filters", jPanel1); jTabbedPane1.addTab("Filters", jPanel1);
@ -793,6 +797,7 @@ public class BTC_MainPanel extends javax.swing.JFrame
private javax.swing.JCheckBox chkShowChatOnly; private javax.swing.JCheckBox chkShowChatOnly;
private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel3;
@ -803,6 +808,7 @@ public class BTC_MainPanel extends javax.swing.JFrame
private javax.swing.JSplitPane splitPane; private javax.swing.JSplitPane splitPane;
private javax.swing.JTable tblPlayers; private javax.swing.JTable tblPlayers;
private javax.swing.JTextField txtCommand; private javax.swing.JTextField txtCommand;
private javax.swing.JTextField txtNumPlayers;
private javax.swing.JComboBox<ServerEntry> txtServer; private javax.swing.JComboBox<ServerEntry> txtServer;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ -860,4 +866,9 @@ public class BTC_MainPanel extends javax.swing.JFrame
{ {
return chkIgnoreErrors; return chkIgnoreErrors;
} }
public List<PlayerInfo> getPlayerList()
{
return playerList;
}
} }

View file

@ -8,25 +8,13 @@ import org.json.*;
public class BTC_PlayerListDecoder public class BTC_PlayerListDecoder
{ {
private static final Pattern PLAYER_LIST_MESSAGE = Pattern.compile(":\\[.+@BukkitTelnet\\]\\$ playerList~(.+)"); private static final Pattern PLAYER_LIST_MESSAGE = Pattern.compile(":\\[.+@BukkitTelnet\\]\\$ playerList~(.+)");
private static final Pattern LOGIN_MESSAGE = Pattern.compile("\\[.+?@BukkitTelnet\\]\\$ Logged in as (.+)\\.");
private BTC_PlayerListDecoder() private BTC_PlayerListDecoder()
{ {
throw new AssertionError(); throw new AssertionError();
} }
public static final String checkForLoginMessage(String message) public static final boolean checkForPlayerListMessage(final String message, final List<PlayerInfo> playerList)
{
final Matcher matcher = LOGIN_MESSAGE.matcher(message);
if (matcher.find())
{
return matcher.group(1);
}
return null;
}
public static final Map<String, PlayerInfo> checkForPlayerListMessage(String message)
{ {
final Matcher matcher = PLAYER_LIST_MESSAGE.matcher(message); final Matcher matcher = PLAYER_LIST_MESSAGE.matcher(message);
if (matcher.find()) if (matcher.find())
@ -34,26 +22,48 @@ public class BTC_PlayerListDecoder
final String data = matcher.group(1); final String data = matcher.group(1);
try try
{ {
final Map<String, PlayerInfo> playerInfo = new HashMap<>(); playerList.clear();
final JSONObject json = new JSONObject(data); final JSONObject json = new JSONObject(data);
final JSONArrayIterable players = new JSONArrayIterable(json.getJSONArray("players")); final JSONArrayIterable players = new JSONArrayIterable(json.getJSONArray("players"));
for (JSONObject player : players) for (JSONObject player : players)
{ {
final String name = player.getString("name"); final String name = getStringSafe(player, "name");
final String ip = player.getString("ip"); playerList.add(new PlayerInfo(
final String displayName = player.getString("displayName"); name,
playerInfo.put(name, new PlayerInfo(name, ip, displayName)); getStringSafe(player, "ip"),
getStringSafe(player, "displayName"),
getStringSafe(player, "uuid"),
Boolean.valueOf(getStringSafe(player, "tfm.admin.isAdmin")),
Boolean.valueOf(getStringSafe(player, "tfm.admin.isTelnetAdmin")),
Boolean.valueOf(getStringSafe(player, "tfm.admin.isSeniorAdmin")),
getStringSafe(player, "tfm.playerdata.getTag"),
getStringSafe(player, "tfm.essentialsBridge.getNickname")
));
} }
return playerInfo; Collections.sort(playerList, PlayerInfo.getComparator());
return true;
} }
catch (JSONException ex) catch (JSONException ex)
{ {
} }
} }
return null; return false;
}
private static String getStringSafe(JSONObject player, String key)
{
try
{
return player.getString(key);
}
catch (JSONException ex)
{
return "null";
}
} }
public static final class JSONArrayIterable implements Iterable<JSONObject> public static final class JSONArrayIterable implements Iterable<JSONObject>

View file

@ -37,35 +37,32 @@ public class BTC_TelnetMessage extends BTC_ConsoleMessage
private boolean isType(final BTC_LogMessageType checkType) private boolean isType(final BTC_LogMessageType checkType)
{ {
return this.messageType == checkType; return this.messageType != null ? this.messageType == checkType : false;
} }
public boolean skip() public boolean skip()
{ {
final BTC_MainPanel mainPanel = BukkitTelnetClient.mainPanel; final BTC_MainPanel mainPanel = BukkitTelnetClient.mainPanel;
if (mainPanel == null || this.messageType == null) if (mainPanel == null)
{ {
return false; return false;
} }
if (mainPanel.getChkShowChatOnly().isSelected()) if (mainPanel.getChkShowChatOnly().isSelected())
{ {
if (!isType(BTC_LogMessageType.CHAT_MESSAGE) return !isType(BTC_LogMessageType.CHAT_MESSAGE)
&& !isType(BTC_LogMessageType.CSAY_MESSAGE) && !isType(BTC_LogMessageType.CSAY_MESSAGE)
&& !isType(BTC_LogMessageType.SAY_MESSAGE) && !isType(BTC_LogMessageType.SAY_MESSAGE)
&& !isType(BTC_LogMessageType.ADMINSAY_MESSAGE)) && !isType(BTC_LogMessageType.ADMINSAY_MESSAGE);
{
return false;
}
} }
if (mainPanel.getChkIgnoreServerCommands().isSelected() && this.messageType == BTC_LogMessageType.ISSUED_SERVER_COMMAND) if (mainPanel.getChkIgnoreServerCommands().isSelected() && isType(BTC_LogMessageType.ISSUED_SERVER_COMMAND))
{ {
return true; return true;
} }
if (mainPanel.getChkIgnorePlayerCommands().isSelected() && this.messageType == BTC_LogMessageType.PLAYER_COMMAND) if (mainPanel.getChkIgnorePlayerCommands().isSelected() && isType(BTC_LogMessageType.PLAYER_COMMAND))
{ {
return true; return true;
} }

View file

@ -1,23 +1,84 @@
package me.StevenLawson.BukkitTelnetClient; package me.StevenLawson.BukkitTelnetClient;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
public class PlayerInfo public class PlayerInfo
{ {
public static int numColumns;
public static String[] columnNames;
private final String name; private final String name;
private final String ip; private final String ip;
private final String displayName; private final String displayName;
private final String uuid;
public PlayerInfo(String name, String ip, String displayName) // TFM tags:
private final boolean admin;
private final boolean telnetAdmin;
private final boolean seniorAdmin;
private final String tag;
private final String nickName;
static
{
final Map<Integer, String> columnNamesMap = new HashMap<>();
int _numColumns = 0;
final Method[] declaredMethods = PlayerInfo.class.getDeclaredMethods();
for (final Method method : declaredMethods)
{
final Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
for (final Annotation annotation : declaredAnnotations)
{
if (annotation instanceof PlayerTableColumn)
{
PlayerTableColumn playerInfoTag = (PlayerTableColumn) annotation;
columnNamesMap.put(playerInfoTag.column(), playerInfoTag.name());
_numColumns++;
}
}
}
final String[] _columnNames = new String[_numColumns];
for (int i = 0; i < _numColumns; i++)
{
_columnNames[i] = columnNamesMap.get(i);
}
columnNames = _columnNames;
numColumns = _numColumns;
}
public PlayerInfo(String name, String ip, String displayName, String uuid, boolean admin, boolean telnetAdmin, boolean seniorAdmin, String tag, String nickName)
{ {
this.name = name; this.name = name;
this.ip = ip; this.ip = ip;
this.displayName = displayName; this.displayName = displayName;
this.uuid = uuid;
this.admin = admin;
this.telnetAdmin = telnetAdmin;
this.seniorAdmin = seniorAdmin;
this.tag = tag;
this.nickName = nickName;
} }
@PlayerTableColumn(name = "Name", column = 0)
public String getName() public String getName()
{ {
return name; return name;
} }
@PlayerTableColumn(name = "IP", column = 1)
public String getIp() public String getIp()
{ {
return ip; return ip;
@ -28,9 +89,113 @@ public class PlayerInfo
return displayName; return displayName;
} }
@Override public String getUuid()
public String toString()
{ {
return String.format("%s[Name: %s, Display Name: %s, IP: %s]", this.getClass().toString(), name, displayName, ip); return uuid;
}
public boolean isAdmin()
{
return admin;
}
public boolean isTelnetAdmin()
{
return telnetAdmin;
}
public boolean isSeniorAdmin()
{
return seniorAdmin;
}
@PlayerTableColumn(name = "Tag", column = 2)
public String getTag()
{
return tag == null || tag.isEmpty() || tag.equalsIgnoreCase("null") ? "" : tag;
}
@PlayerTableColumn(name = "Nickname", column = 3)
public String getNickName()
{
return nickName == null || nickName.isEmpty() || nickName.equalsIgnoreCase("null") ? "" : nickName;
}
@PlayerTableColumn(name = "Admin Level", column = 4)
public String getAdminLevel()
{
if (isAdmin())
{
if (isSeniorAdmin())
{
return "Senior";
}
else if (isTelnetAdmin())
{
return "Telnet";
}
else
{
return "Super";
}
}
return "";
}
public String getColumnValue(int columnIndex)
{
final Method[] declaredMethods = this.getClass().getDeclaredMethods();
for (final Method method : declaredMethods)
{
final Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
for (final Annotation annotation : declaredAnnotations)
{
if (annotation instanceof PlayerTableColumn)
{
PlayerTableColumn playerInfoTag = (PlayerTableColumn) annotation;
if (playerInfoTag.column() == columnIndex)
{
try
{
final Object value = method.invoke(this);
if (value != null)
{
return value.toString();
}
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex)
{
BukkitTelnetClient.LOGGER.log(Level.SEVERE, null, ex);
}
return "null";
}
}
}
}
return "null";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PlayerTableColumn
{
public String name();
public int column();
}
public static Comparator<PlayerInfo> getComparator()
{
return new Comparator<PlayerInfo>()
{
@Override
public int compare(PlayerInfo a, PlayerInfo b)
{
return a.getName().compareTo(b.getName());
}
};
} }
} }