package example;
import gdwNet.RESPONCECODES;
import gdwNet.client.BasicClient;
import gdwNet.client.IBasicClientListener;
import gdwNet.client.ServerInfo;
import gdwUtils.DefaultCharSet;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* Wieder so eine must-have Klasse, hier habe ich die Schnittstelle {@link IBasicClientListener} implementiert
* diese Schnittstelle sagt euch wie ihr momentan als Client verbunden seit, was so an Servern im Netzwerk
* rumläuft bietet einen Verbindungsstelle zum Server.
*
* Der Code ist haupstächlich für die Gui da, also nicht von Relevanz. Das was wichtig ist ist kommentiert.
*
* @author firen
*
*/
public class ChatClient extends JFrame implements IBasicClientListener
{
private static final long serialVersionUID = 1L;
private final JList<String> serverList;
private final ServerListModel myModel;
private final JTextArea chatArea;
private final JTextField nameField;
private final JTextField chatInputField;
private final JLabel connectionStatus;
private BasicClient clientSession;
private final JButton connectb;
private final JTextField ipaddressField;
private final JTextField portField;
private final JButton connectDirectButton;
// puffer
private String messageBuffer;
public ChatClient()
{
this.messageBuffer = "";
this.setTitle("ChatTestClient");
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.myModel = new ServerListModel();
this.clientSession = null;
JPanel topPanel = new JPanel();
topPanel.setLayout(new GridLayout(1, 0));
this.serverList = new JList<String>(this.myModel);
topPanel.add(this.serverList);
JPanel rightSubTop = new JPanel();
rightSubTop.setLayout(new GridLayout(0, 1));
JButton refresh = new JButton("Refresh");
refresh.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent arg0)
{
sendRefresh();
}
});
this.nameField = new JTextField();
this.nameField.setEditable(true);
rightSubTop.add(this.nameField);
this.connectb = new JButton("Connect");
connectb.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
try {
connect();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
rightSubTop.add(refresh);
rightSubTop.add(connectb);
topPanel.add(rightSubTop);
this.add(topPanel, BorderLayout.NORTH);
// bottom
JPanel botPanel = new JPanel();
botPanel.setLayout(new GridLayout(0, 1));
// direct connect
this.ipaddressField = new JTextField();
this.ipaddressField.setEditable(true);
this.portField = new JTextField();
this.portField.setEditable(true);
this.connectDirectButton = new JButton();
this.connectDirectButton.setText("Verbinde direkt");
this.connectDirectButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
try {
connectDirect();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
botPanel.add(new JLabel("Ipaddresse:"));
botPanel.add(this.ipaddressField);
botPanel.add(new JLabel("Port:"));
botPanel.add(this.portField);
botPanel.add(this.connectDirectButton);
this.connectionStatus = new JLabel("Sehr langes bla");
botPanel.add(this.connectionStatus);
this.chatArea = new JTextArea();
this.chatArea.setEditable(false);
JScrollPane jsPane = new JScrollPane(this.chatArea);
botPanel.add(jsPane);
this.chatInputField = new JTextField();
this.chatInputField.setEditable(true);
this.chatInputField.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent arg0)
{
chatInput();
}
});
this.add(botPanel);
this.add(this.chatInputField, BorderLayout.SOUTH);
this.setSize(500, 500);
this.setVisible(true);
//Man muss ich als Listener beim Client registieren
BasicClient.setListener(this);
}
/**
* Eine Beispielimplementierung, falls das finden der Server im Netzwerk nicht klappt.
* Ich lese einen IP-Addresse ein und einen Port verbinde mich.
* @throws Exception
*/
public void connectDirect() throws Exception
{
InetAddress address;
try
{
address = InetAddress.getByName(this.ipaddressField.getText());
int port = Integer.parseInt(this.portField.getText());
String name = this.nameField.getText();
if (name.equals(""))
{
JOptionPane.showMessageDialog(this, "Der Loginname ist leer!");
return;
}
ByteBuffer buf = ByteBuffer.allocate(50);
try
{
byte [] arr = name.getBytes(DefaultCharSet.getDefaultCharset());
buf.put((byte)arr.length);
buf.put(arr);
}catch (Exception e)
{
throw e;
}
BasicClient.connectToServer(address, port,buf);
} catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(this, e.getMessage());
return;
}
}
/**
* Ich möchte die Liste der sich im Netzwerk befindlichen Server haben.
* Falls man nicht schon beim Clientregistiert hat sollte man das hier spätestens tun.
*/
public void sendRefresh()
{
//gui sauber machen
this.myModel.clear();
//habe ich mich vergessen zu registrieren?
if (BasicClient.getListener() == null)
{
BasicClient.setListener(this);
}
//rufe die refreshMethode auf
BasicClient.refreshServerList();
}
public static void main(String[] args)
{
new ChatClient();
}
/**
* Eine Methode die von der Schnittstelle vorgeben wird.
* Sie wird aufgefufen, wenn der Client einen Server im Netzwerk findet.
*/
@Override
public void serverResponce(ServerInfo info)
{
this.myModel.addEntry(info);
this.invalidate();
}
/**
* Eine Methode die von der Schnittstelle vorgeben wird.
* Sie wird aufgerufen, wenn der Client euch über seinen Verbindungsstatus mitteilt.
*/
@Override
public void connectionUpdate(int msg)
{
String text = null;
switch (msg)
{
// Ok bin verbunden
case RESPONCECODES.OK:
text = "Verbunden";
break;
// er kommuniziert gerade mit dem Server über deinen Login
case RESPONCECODES.HANDSHAKE:
text = "Handshake läuft";
break;
// Verbindungsaufbau zum Server
case RESPONCECODES.CONNECTING:
text = "Verbinde...";
break;
default:
// ab hier ist was schlecht gelaufen
this.connectb.setEnabled(true);
switch (msg)
{
// wenn das auf tritt habe ich Mist gebaut nicht ihr
// oder die Netzwerkverbindung ist schrott
case RESPONCECODES.DATA_CORRUPTED:
text = "Wir senden Scheiße";
break;
// Der Nick den ihr gesendet wird nicht akzeptiert
case RESPONCECODES.NICK_CORRUPTED:
text = "Nickname ist Mist";
break;
// Nick bereits vergeben
case RESPONCECODES.NICK_TAKEN:
text = "Dein Nick ist unkreativ";
break;
// Er mag einen nicht haben, erblockt alle Verbindungsversuche
case RESPONCECODES.CONNECT_REFUSE:
text = "Er mag uns nicht";
break;
// Er ist voll
case RESPONCECODES.SERVER_FULL:
text = "Schon alles voll";
break;
// Die Antwort dauert zu lange, vielleicht Netzwerk nicht in Ordnung?
// Oder Kick?
case RESPONCECODES.TIMEOUT:
text = "Zu lange Leitung";
break;
// Kann nicht zum Server verbinden
case RESPONCECODES.UNREACHABLE:
text = "Kaputte Leitung";
break;
// Und weg
case RESPONCECODES.DISCONNECTED:
text = "Disconnect";
break;
default:
break;
}
break;
}
this.connectionStatus.setText(text);
this.invalidate();
}
/**
* Ich verbinde zum Server per Listeneintrag
* @throws Exception
*/
public void connect() throws Exception
{
if (this.serverList.isSelectionEmpty())
{
return;
}
//lese Nickname
String name = this.nameField.getText();
// check input
if (name.equals(""))
{
JOptionPane.showMessageDialog(this, "Der Loginname ist leer!");
return;
}
this.connectb.setEnabled(false);
//hole gespeicherte Daten
ServerInfo info = this.myModel.getServerInfoForIndex(this.serverList
.getSelectedIndex());
// und los gehts
ByteBuffer buf = ByteBuffer.allocate(50);
try
{
byte [] arr = name.getBytes(DefaultCharSet.getDefaultCharset());
buf.put((byte)arr.length);
buf.put(arr);
}catch (Exception e)
{
throw e;
}
BasicClient.connectToServer(info,buf);
}
public void chatInput()
{
this.messageBuffer = this.chatInputField.getText();
this.chatInputField.setText("");
}
/**
* Schnittstellen Methode.
*
* Die Verbindung wurde hergestellt. Hier ist deine Referenz zum Client, der mit dem Server verbunden
* ist.
*/
@Override
public void connectionEstablished(BasicClient clientRef)
{
this.clientSession = clientRef;
new ClientCoreLoop(this.clientSession, this);
}
/**
* Meine Beispielimplementierung vom Netzwerportokol.
* Haltet euch am besten daran und baut drauf auf.
*/
@Override
public void incommingMessage(ByteBuffer msg, boolean wasSafe)
{
switch (msg.get())
{
// Es kamen Chatnachrichten rein
case MyMessageConstants.ChatMessage:
encodeChatMessageInput(msg);
break;
//Es haben sich Leute verbunden
case MyMessageConstants.PlayerConnected:
encodePlayerConnected(msg);
break;
//Es haben sich Leute abgemeldet
case MyMessageConstants.PlayerDisconnected:
encodePlacerDisconned(msg);
break;
//Es wurde was gesendet, was ich nicht verstehe
default:
msg.position(msg.position() - 1);
unknownMessageCode(msg.get());
break;
}
}
public String getChatBuffer()
{
String result = this.messageBuffer;
this.messageBuffer = "";
return result;
}
private void unknownMessageCode(byte code)
{
this.chatArea.append("Unkown Messagecode: " + code);
}
private void encodeChatMessageInput(ByteBuffer msg)
{
byte amount = msg.get();
for (int i = 0; i < amount; ++i)
{
byte size = msg.get();
byte[] nameBytes = new byte[size];
msg.get(nameBytes);
String clearMsg = new String(nameBytes,
DefaultCharSet.getDefaultCharset());
this.chatArea.append(clearMsg + "\n");
this.invalidate();
}
}
private final static String CONNECTEDMSG = " lungert nun hier rum*\n";
private void encodePlayerConnected(ByteBuffer msg)
{
byte amount = msg.get();
for (int i = 0; i < amount; ++i)
{
byte size = msg.get();
byte[] nameBytes = new byte[size];
msg.get(nameBytes);
String name = new String(nameBytes,
DefaultCharSet.getDefaultCharset());
this.chatArea.append("*" + name + CONNECTEDMSG);
this.invalidate();
}
}
private final static String DISCONNECTEDMSG = " ist abgehauen*\n";
private void encodePlacerDisconned(ByteBuffer msg)
{
byte amount = msg.get();
for (int i = 0; i < amount; ++i)
{
byte size = msg.get();
byte[] nameBytes = new byte[size];
msg.get(nameBytes);
String name = new String(nameBytes,
DefaultCharSet.getDefaultCharset());
this.chatArea.append("*" + name + DISCONNECTEDMSG);
}
}
}