Added rough, initial version of player list.

This commit is contained in:
StevenLawson 2014-08-16 23:11:55 -04:00
parent c3cbce870f
commit 2077e4ba33
6 changed files with 660 additions and 229 deletions

View file

@ -48,6 +48,11 @@
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View file

@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Map;
import java.util.logging.Level;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.telnet.TelnetClient;
@ -158,10 +159,21 @@ public class BTC_ConnectionManager
if (read == '\n')
{
final String line = consoleBuffer.toString();
if (!BTC_FormatHandler.skipLine(line))
final Map<String, BTC_PlayerListDecoder.PlayerInfo> playerList = BTC_PlayerListDecoder.decodePlayerListMessage(line);
if (playerList != null)
{
System.out.print(line);
btc.updatePlayerList(playerList);
}
else
{
if (!BTC_FormatHandler.skipLine(line))
{
System.out.print(line);
}
}
consoleBuffer.reset();
}
}

View file

@ -5,19 +5,27 @@ import java.util.regex.Pattern;
public class BTC_FormatHandler
{
private static final Color PURPLE = new Color(128, 0, 128);
private static final Color DARK_GREEN = new Color(86, 130, 3);
private static final Pattern CHAT_MESSAGE = Pattern.compile("^:\\[.+? INFO\\]: \\<");
private static final Pattern SAY_MESSAGE = Pattern.compile("^:\\[.+? INFO\\]: \\[Server:");
private static final Pattern ADMINSAY_MESSAGE = Pattern.compile("^:\\[.+? INFO\\]: \\[TotalFreedomMod\\] \\[ADMIN\\] ");
private static final Pattern CSAY_MESSAGE = Pattern.compile("^:\\[.+? INFO\\]: \\[CONSOLE\\]<");
private static final Pattern ADMINSAY_MESSAGE = Pattern.compile("^:\\[.+? INFO\\]: \\[TotalFreedomMod\\] \\[ADMIN\\] ");
private static final Pattern WORLD_EDIT = Pattern.compile("^:\\[.+? INFO\\]: WorldEdit: ");
private static final Pattern PREPROCESS_COMMAND = Pattern.compile("^:\\[.+? INFO\\]: \\[PREPROCESS_COMMAND\\] ");
private static final Color DARK_GREEN = new Color(86, 130, 3);
private static final Pattern ISSUED_SERVER_COMMAND = Pattern.compile("^:\\[.+? INFO\\]: .+? issued server command: ");
private static final Pattern PLAYER_COMMAND = Pattern.compile("^:\\[.+? INFO\\]: \\[PLAYER_COMMAND\\] ");
private BTC_FormatHandler()
{
throw new AssertionError();
}
public static final boolean skipLine(String line)
{
final BTC_MainPanel mainPanel = BukkitTelnetClient.mainPanel;
@ -50,10 +58,14 @@ public class BTC_FormatHandler
{
Color color = Color.BLACK;
if (CHAT_MESSAGE.matcher(text).find() || SAY_MESSAGE.matcher(text).find() || ADMINSAY_MESSAGE.matcher(text).find() || CSAY_MESSAGE.matcher(text).find())
if (CHAT_MESSAGE.matcher(text).find() || SAY_MESSAGE.matcher(text).find() || CSAY_MESSAGE.matcher(text).find())
{
color = Color.BLUE;
}
else if (ADMINSAY_MESSAGE.matcher(text).find())
{
color = PURPLE;
}
else if (WORLD_EDIT.matcher(text).find())
{
color = Color.RED;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="3"/>
<Property name="title" type="java.lang.String" value="BukkitTelnetClient"/>
@ -25,171 +25,323 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="chkIgnorePlayerCommands" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="chkIgnoreServerCommands" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="chkShowChatOnly" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="jScrollPane1" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="jLabel2" max="32767" attributes="0"/>
<Component id="jLabel1" max="32767" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtCommand" pref="680" max="32767" attributes="0"/>
<Component id="txtServer" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="btnConnect" linkSize="4" max="32767" attributes="0"/>
<Component id="btnSend" linkSize="4" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="btnDisconnect" linkSize="4" min="-2" max="-2" attributes="0"/>
<Component id="chkAutoScroll" linkSize="4" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="splitPane" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="338" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="chkIgnorePlayerCommands" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="chkIgnoreServerCommands" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="chkShowChatOnly" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtCommand" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnSend" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="chkAutoScroll" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnConnect" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnDisconnect" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtServer" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="splitPane" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Container class="javax.swing.JSplitPane" name="splitPane">
<Properties>
<Property name="dividerLocation" type="int" value="650"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextPane" name="mainOutput">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Courier New" size="12" style="0"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="jPanel3">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="left"/>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="jLabel2" max="32767" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtCommand" max="32767" attributes="0"/>
<Component id="txtServer" pref="378" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="btnConnect" linkSize="4" max="32767" attributes="0"/>
<Component id="btnSend" linkSize="4" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="btnDisconnect" linkSize="4" min="-2" max="-2" attributes="0"/>
<Component id="chkAutoScroll" linkSize="4" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="360" max="32767" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="txtCommand" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnSend" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="chkAutoScroll" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnConnect" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnDisconnect" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtServer" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextPane" name="mainOutput">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Courier New" size="12" style="0"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="btnDisconnect">
<Properties>
<Property name="text" type="java.lang.String" value="Disconnect"/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDisconnectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnSend">
<Properties>
<Property name="text" type="java.lang.String" value="Send"/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSendActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JComboBox" name="txtServer">
<Properties>
<Property name="editable" type="boolean" value="true"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="chkAutoScroll">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="AutoScroll"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkAutoScrollActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtCommand">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtCommandKeyPressed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnConnect">
<Properties>
<Property name="text" type="java.lang.String" value="Connect"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnConnectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value="Command:"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" value="Server:"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JTabbedPane" name="jTabbedPane1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="right"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel2">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Player List">
<Property name="tabTitle" type="java.lang.String" value="Player List"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane2" pref="346" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane2" pref="395" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="tblPlayers">
<Properties>
<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">
<TableColumnModel selectionModel="1">
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title/>
<Editor/>
<Renderer/>
</Column>
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title/>
<Editor/>
<Renderer/>
</Column>
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
<Title/>
<Editor/>
<Renderer/>
</Column>
</TableColumnModel>
</Property>
<Property name="columnSelectionAllowed" type="boolean" value="true"/>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jPanel1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Filters">
<Property name="tabTitle" type="java.lang.String" value="Filters"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="chkIgnorePlayerCommands" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="chkIgnoreServerCommands" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="chkShowChatOnly" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="chkIgnorePlayerCommands" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="chkIgnoreServerCommands" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="chkShowChatOnly" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace pref="341" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="chkIgnorePlayerCommands">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Ignore &quot;[PLAYER_COMMAND]&quot; messages"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="chkIgnoreServerCommands">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Ignore &quot;issued server command&quot; messages"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="chkShowChatOnly">
<Properties>
<Property name="text" type="java.lang.String" value="Show chat only"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkShowChatOnlyActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Component class="javax.swing.JTextField" name="txtCommand">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtCommandKeyPressed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnConnect">
<Properties>
<Property name="text" type="java.lang.String" value="Connect"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnConnectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value="Command:"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" value="Server:"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnDisconnect">
<Properties>
<Property name="text" type="java.lang.String" value="Disconnect"/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDisconnectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnSend">
<Properties>
<Property name="text" type="java.lang.String" value="Send"/>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSendActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JComboBox" name="txtServer">
<Properties>
<Property name="editable" type="boolean" value="true"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="chkAutoScroll">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="AutoScroll"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkAutoScrollActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="chkIgnorePlayerCommands">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Ignore &quot;[PLAYER_COMMAND]&quot; messages"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="chkIgnoreServerCommands">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Ignore &quot;issued server command&quot; messages"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="chkShowChatOnly">
<Properties>
<Property name="text" type="java.lang.String" value="Show chat only"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkShowChatOnlyActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View file

@ -1,5 +1,6 @@
package me.StevenLawson.BukkitTelnetClient;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
@ -10,10 +11,13 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.JCheckBox;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
@ -51,6 +55,8 @@ public class BTC_MainPanel extends javax.swing.JFrame
setIconImage(Toolkit.getDefaultToolkit().createImage(icon));
}
this.splitPane.setResizeWeight(1.0);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
@ -85,6 +91,34 @@ public class BTC_MainPanel extends javax.swing.JFrame
});
}
public final void updatePlayerList(final Map<String, BTC_PlayerListDecoder.PlayerInfo> playerList)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
final DefaultTableModel model = (DefaultTableModel) BTC_MainPanel.this.tblPlayers.getModel();
model.setRowCount(0);
final Iterator<Map.Entry<String, BTC_PlayerListDecoder.PlayerInfo>> it = playerList.entrySet().iterator();
while (it.hasNext())
{
final Map.Entry<String, BTC_PlayerListDecoder.PlayerInfo> entry = it.next();
BTC_PlayerListDecoder.PlayerInfo playerInfo = entry.getValue();
model.addRow(new Object[]
{
playerInfo.getName(),
playerInfo.getDisplayName(),
playerInfo.getIp()
});
}
}
});
}
public void updateConsole()
{
final String data = BukkitTelnetClient.CONSOLE.toString();
@ -181,16 +215,23 @@ public class BTC_MainPanel extends javax.swing.JFrame
private void initComponents()
{
splitPane = new javax.swing.JSplitPane();
jPanel3 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
mainOutput = new javax.swing.JTextPane();
txtCommand = new javax.swing.JTextField();
btnConnect = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
btnDisconnect = new javax.swing.JButton();
btnSend = new javax.swing.JButton();
txtServer = new javax.swing.JComboBox();
chkAutoScroll = new javax.swing.JCheckBox();
txtCommand = new javax.swing.JTextField();
btnConnect = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jTabbedPane1 = new javax.swing.JTabbedPane();
jPanel2 = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
tblPlayers = new javax.swing.JTable();
jPanel1 = new javax.swing.JPanel();
chkIgnorePlayerCommands = new javax.swing.JCheckBox();
chkIgnoreServerCommands = new javax.swing.JCheckBox();
chkShowChatOnly = new javax.swing.JCheckBox();
@ -198,32 +239,12 @@ public class BTC_MainPanel extends javax.swing.JFrame
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("BukkitTelnetClient");
splitPane.setDividerLocation(650);
mainOutput.setEditable(false);
mainOutput.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
jScrollPane1.setViewportView(mainOutput);
txtCommand.setEnabled(false);
txtCommand.addKeyListener(new java.awt.event.KeyAdapter()
{
public void keyPressed(java.awt.event.KeyEvent evt)
{
txtCommandKeyPressed(evt);
}
});
btnConnect.setText("Connect");
btnConnect.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnConnectActionPerformed(evt);
}
});
jLabel1.setText("Command:");
jLabel2.setText("Server:");
btnDisconnect.setText("Disconnect");
btnDisconnect.setEnabled(false);
btnDisconnect.addActionListener(new java.awt.event.ActionListener()
@ -256,6 +277,133 @@ public class BTC_MainPanel extends javax.swing.JFrame
}
});
txtCommand.setEnabled(false);
txtCommand.addKeyListener(new java.awt.event.KeyAdapter()
{
public void keyPressed(java.awt.event.KeyEvent evt)
{
txtCommandKeyPressed(evt);
}
});
btnConnect.setText("Connect");
btnConnect.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnConnectActionPerformed(evt);
}
});
jLabel1.setText("Command:");
jLabel2.setText("Server:");
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1)
.addGroup(jPanel3Layout.createSequentialGroup()
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel1))
.addGap(18, 18, 18)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtCommand)
.addComponent(txtServer, 0, 378, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.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(btnSend, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnDisconnect)
.addComponent(chkAutoScroll))))
.addContainerGap())
);
jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btnConnect, btnDisconnect, btnSend, chkAutoScroll});
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.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(jLabel1)
.addComponent(btnSend)
.addComponent(chkAutoScroll))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(btnConnect)
.addComponent(btnDisconnect)
.addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
);
splitPane.setLeftComponent(jPanel3);
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.setColumnSelectionAllowed(true);
jScrollPane2.setViewportView(tblPlayers);
tblPlayers.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 346, Short.MAX_VALUE)
.addContainerGap())
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
.addContainerGap())
);
jTabbedPane1.addTab("Player List", jPanel2);
chkIgnorePlayerCommands.setSelected(true);
chkIgnorePlayerCommands.setText("Ignore \"[PLAYER_COMMAND]\" messages");
@ -271,64 +419,48 @@ public class BTC_MainPanel extends javax.swing.JFrame
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(chkIgnorePlayerCommands)
.addComponent(chkIgnoreServerCommands)
.addComponent(chkShowChatOnly))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(chkIgnorePlayerCommands, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkIgnoreServerCommands, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkShowChatOnly, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(341, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Filters", jPanel1);
splitPane.setRightComponent(jTabbedPane1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(chkIgnorePlayerCommands)
.addGap(18, 18, 18)
.addComponent(chkIgnoreServerCommands)
.addGap(18, 18, 18)
.addComponent(chkShowChatOnly)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(jScrollPane1)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtCommand, javax.swing.GroupLayout.DEFAULT_SIZE, 680, Short.MAX_VALUE)
.addComponent(txtServer, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnSend, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnDisconnect)
.addComponent(chkAutoScroll))))
.addComponent(splitPane)
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btnConnect, btnDisconnect, btnSend, chkAutoScroll});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 338, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(chkIgnorePlayerCommands, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(chkIgnoreServerCommands, 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.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtCommand, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1)
.addComponent(btnSend)
.addComponent(chkAutoScroll))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(btnConnect)
.addComponent(btnDisconnect)
.addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(splitPane)
.addContainerGap())
);
@ -398,8 +530,15 @@ public class BTC_MainPanel extends javax.swing.JFrame
private javax.swing.JCheckBox chkShowChatOnly;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JTextPane mainOutput;
private javax.swing.JSplitPane splitPane;
private javax.swing.JTable tblPlayers;
private javax.swing.JTextField txtCommand;
private javax.swing.JComboBox txtServer;
// End of variables declaration//GEN-END:variables

View file

@ -0,0 +1,111 @@
package me.StevenLawson.BukkitTelnetClient;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class BTC_PlayerListDecoder
{
private static final Pattern PLAYER_LIST_MESSAGE = Pattern.compile(":\\[.+@BukkitTelnet\\]\\$ playerList~(.+)");
private BTC_PlayerListDecoder()
{
throw new AssertionError();
}
public static final Map<String, PlayerInfo> decodePlayerListMessage(String message)
{
final Matcher matcher = PLAYER_LIST_MESSAGE.matcher(message);
if (matcher.find())
{
final String data = matcher.group(1);
try
{
final Map<String, PlayerInfo> playerInfo = new HashMap<>();
final JSONObject json = new JSONObject(data);
final JSONArrayIterable players = new JSONArrayIterable(json.getJSONArray("players"));
for (JSONObject player : players)
{
final String name = player.getString("name");
final String ip = player.getString("ip");
final String displayName = player.getString("displayName");
playerInfo.put(name, new PlayerInfo(name, ip, displayName));
}
return playerInfo;
}
catch (JSONException ex)
{
}
}
return null;
}
public static final class PlayerInfo
{
private final String name;
private final String ip;
private final String displayName;
public PlayerInfo(String name, String ip, String displayName)
{
this.name = name;
this.ip = ip;
this.displayName = displayName;
}
public String getIp()
{
return ip;
}
public String getName()
{
return name;
}
public String getDisplayName()
{
return displayName;
}
}
public static final class JSONArrayIterable implements Iterable<JSONObject>
{
private final JSONArray array;
public JSONArrayIterable(JSONArray array)
{
this.array = array;
}
@Override
public Iterator<JSONObject> iterator()
{
return new Iterator<JSONObject>()
{
private int index = 0;
private final int length = array.length();
@Override
public boolean hasNext()
{
return index < length;
}
@Override
public JSONObject next()
{
return array.getJSONObject(index++);
}
};
}
}
}