Du bist nicht angemeldet.

Lieber Besucher, herzlich willkommen bei: Banana-Coding.com - Java Knuddels Emulator. Falls dies dein erster Besuch auf dieser Seite ist, lies bitte die Hilfe durch. Dort wird dir die Bedienung dieser Seite näher erläutert. Darüber hinaus solltest du dich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutze das Registrierungsformular, um dich zu registrieren oder informiere dich ausführlich über den Registrierungsvorgang. Falls du dich bereits zu einem früheren Zeitpunkt registriert hast, kannst du dich hier anmelden.

11

Montag, 21. Oktober 2013, 02:36

Hat er mir auch grad gezeigt, nicht schlecht :D
Gibt zwar beispielsweise beim Login noch Serverseitig eine ArrayIndexOutOfBoundsException weil die Tokens beim leeren nick/pw nicht gesplitted werden kann, aber des kann man ja fixxen. Und der Client müsste halt noch ausgebaut werden. KCode wird sicherlich noch spaßig, er meinte aber dass er da schon was fertiges hat, was er damals für die KF-Leute gemacht hatte.

Endlich mal jemand, der bei Git was comitted!

Schade dass er die Szene verlassen hatte. Hätten wirklich alle vernünftig miteinander was aufgebaut, dann sehe des heute garantiert anders aus :D

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jail O« (21. Oktober 2013, 02:41)


Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Chiller

12

Montag, 21. Oktober 2013, 14:58

Ich (Bizzi) habe das GitRepo von Banana geforked und dementsprechend nun einen Pull-Request gesendet. Fif müsste dies nur noch annehmen.
Ich habe die Inhaberschaft an Diebspiel abgegeben und bin auch gar kein Mitglied des GitHub-Teams mehr.

13

Dienstag, 22. Oktober 2013, 23:00

Gab noch ein kleinen Fehler beim schließen der Verbindung was den WebSocket-Server wieder durch der Exception beendet hatte. Adrian weiß schon bescheid, und updated das gleich auf Git.

Edit:
Wow, hat sogar den Clienten geupdated. Gefällt mir sehr :D

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jail O« (23. Oktober 2013, 00:11)


14

Mittwoch, 23. Oktober 2013, 01:50

So, hab mal etwas gefummelt gehabt, Der Webclient von Knuddels selbst funzt dabei auch - man muss nur dort die Passwort-Verschlüsselung rausnehmen.
Zieht euch alle CSS/JS Files von http://knuddels.de/htmlchat, nutzt als webchat.min.js folgendes: http://pastebin.com/4nUyMxTQ, und habt spaß ^^

Denkt dran, in der HTML die Serverdaten zu ändern (jenachdem wie ihr des benötigt):

PHP-Quelltext

1
2
3
4
5
<script>
            var hostIP 'localhost';
            var hostPort 2711;
            var forceLoginChannel 'Lobby';
        </script><

15

Mittwoch, 23. Oktober 2013, 17:48

Ich hab den Pull-Request erhalten und bedanke mich dafür!

Bislang konnte ich den Code nur überfliegen und sieht soweit gut aus, werde ihn mir noch einmal genau ansehen.

Was mir allerdings schon spontan aufgefallen ist:
Es wird ein zweiter Socket unter 2711 (neben 2710) geöffnet. Die Implementierung von KrT hooked direkt mit bei 2710, sodass man bei seiner nur auf einem Port listen muss. Ich glaube die Lösung von KrT ist somit etwas besser. Inwieweit, muss ich selbst noch abwägen.

16

Mittwoch, 23. Oktober 2013, 20:30

Hier noch was vom Adrian, er bat mich drum:

Zitat


Vielen Dank, Diebspiel.

Bezüglich des Portes:
Möglich ist es durchaus, ob das ganze aber Sinn macht ist eine andere Frage.
Immerhin muss auf einem einzigen Port dann entschieden werden, ob es sich um eine normale TCP Verbindung handelt, oder eben um einen WebSocket/Webserver-Request (WebSocket ist mit einem Webserver Protokoll zu vergleichen).

Und genau hier bestehen Konflikte:
a.) Man implementiert alles selbst, heiden Arbeit - "Nutzer" könnten dadurch Probleme haben
b.) Man nutzt die Source einer Lib muss sich aber um Updates komplett selbst kümmern
c.) man nutzt eine fertige Lib die alle gängigen WSS-Versionen/Handshakes unterstützen (ein Update ist umso einfacher)

Ich habe mich für letzeres Entschieden, schon alleine der Nutzerfreundlichkeit. Man weiß ja, welche Leute sich hier so herumtreiben - Das minimiert einfach den Support enorm.

Ich habe gestern angefangen gehabt, den KCode-Parser sowie den Popup-Parser aus dem HTMLClienten von Knuddels zu extrahieren. Hierbei spielt bei mir die wichtigste Rolle des verständnisses. "Wie funktioniert das ganze, was wird da überhaupt gemacht...?".
Geschätze 90% sind bereits fertig, ich habe auch weitgehend alle Variablen und Methoden "Humanisiert". Man kann also komplett nachvollziehen, wie das ganze funktioniert. Ist vielleicht auch interessant für so manch anderen der sich mit der Cliententwicklung beschäftigen möchte - Ob ich das ganze aber Zeitnahe veröffentliche kann ich noch nicht sagen.

Mfg

Bizzi

Es haben sich bereits 3 registrierte Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Diebspiel, Basti, Spectra

17

Freitag, 25. Oktober 2013, 23:18

Tutorial - Wie baue ich das WebSocket gedönse in meiner Version ein?


Schritt 1: Importieren der WebSocket Lib.
Diese wird genauso eingebunden wie der MySQL-Connector. Da das ganze relativ klar ist, brauche ich dazu auch nicht viel schreiben.

Download: https://github.com/hovida/BananaChat/blo…et.jar?raw=true

Schritt 2: Hinzufügen der Websocket.java
Diese wird einfach im Package "knuddels" abgelegt, genau da wo auch die Server.java vorhanden ist.

Download: https://raw.github.com/hovida/BananaChat…/Websocket.java

Schritt 3: Server.java abändern

Wegsocket importieren:

Java-Quelltext

1
import org.java_websocket.WebSocket;


Hier kommt folgende Methode hinzu:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        public Client getClient(WebSocket socket) {
                synchronized (clients) {
                        for(Client client : clients.values()) {
                                if(client.hasWebsocket(socket)) {
                                        return client;
                                }
                        }
                }
                
                return null;
        }

        public void removeClient(WebSocket socket) {
                synchronized (clients) {
                        String name = "";
                        
                        for(Client client : clients.values()) {
                                if(client.hasWebsocket(socket)) {
                                        name = client.getName();
                                        break;
                                }
                        }
                        
                        clients.remove(name.toLowerCase());
                }
        }


Die Listener-Methode wird verändert (siehe Kommentare:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        private void listen(int port, int wss_port) { // <<<<< Neuer Parameter "wss_port"
                try {
                        ServerSocket listener = new ServerSocket(port);
                        
                        try {// <<<<< 
                                new Websocket(wss_port).start();// <<<<< 
                        } catch (Exception e) {// <<<<< 
                                e.printStackTrace();// <<<<< 
                        }// <<<<< 
                        
                        System.out.println(String.format("Listening on port %s (Websocket: %s)", port, wss_port));// <<<<< veränderte Ausgabe
                        
                        while (true) {
                                Socket socket = listener.accept();
                                new SessionHandler(socket).start();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }


Und die main-Methode wird auch verändert:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        public static void main(String[] args) {
                int port;
                int wss_port; // <<<< Neue Variable
                
                if (args.length > 0) {
                        port = Integer.parseInt(args[0]);
                        wss_port = Integer.parseInt(args[1]); // <<< Neues Argument
                } else {
                        port = 2710; // default
                        wss_port = 2711; //<<<< Default WebSocket Port
                }

                instance.loadConfigs();
                instance.listen(port, wss_port); // Parameter hinzugefügt
        }


Schritt 4: Client.java abändern

Wieder WebSocket importieren:

Java-Quelltext

1
import org.java_websocket.WebSocket;


Neue Variable setzen:

Java-Quelltext

1
2
3
public class Client {
        private WebSocket websocket;
        //....


Konstruktor abändern:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
        public Client(Socket socket) {
                channels = new ArrayList<Channel>();
                this.socket = socket;
                this.websocket = null; // <<< Neu
                
                if (socket == null) {// <<< Neu
                        return;// <<< Neu
                }// <<< Neu

                try {
                        out = socket.getOutputStream();
                } catch (IOException e) {
                }
        }


Neue Methode hinzufügen:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
        public Client setToWebsocket(WebSocket socket) {
                channels = new ArrayList<Channel>();
                this.socket = null;
                this.websocket = socket;

                if(websocket == null) {
                        return null;
                }
                
                // temporary Name
                this.name = String.format("WebSocket Client #%s", socket.getLocalSocketAddress().hashCode());

                /*try {
                        out = websocket;
                } catch (IOException e) {
                }*/
                
                return this;
        }

        public boolean hasWebsocket(WebSocket socket) {
                if(socket != null && socket == this.websocket) {
                        return true;
                }
                
                return false;
        }


send-Methode verändern:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        public void send(String message) {
                if (socket != null && socket.isConnected()) {
                        try {
                                out.write(Protocol.encode(Huffman.getEncoder().encode(message, 0)));
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                }
                
                // Send over WebSocket
                if(websocket != null && websocket.isOpen()) { // << NEU
                        try { // << NEU
                                websocket.send(message); // << NEU
                        } catch (Exception e) { // << NEU
                                e.printStackTrace(); // << NEU
                        } // << NEU
                } // << NEU
        }


Schritt 4: SessionHandler.java abändern
Der Opcode-Handler wird in einer seperate Methode gesetzt, da diese nun mehrfach benötigt wird:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
        public void read(Client client, String decoded) {
                System.out.println("Receive: " + decoded);
                String[] tokens        = decoded.split("\0");
                String opcode        = tokens[0];

                if (opcode.equals(ReceiveOpcode.EXCEPTION.getValue())) {
                        /* Do Nothing */
                } else if (opcode.equals(ReceiveOpcode.DISCONNECT.getValue())) {
                        /* Do Nothing */
                } else if (opcode.equals(ReceiveOpcode.CHAT.getValue())) {
                        ChatHandler.handle(tokens, client);
                } else if (opcode.equals(ReceiveOpcode.PING.getValue())) {
                        PingHandler.handle(tokens, client);
                } else if (opcode.equals(ReceiveOpcode.POLL.getValue())) {
                        PollHandler.handle(tokens, client);
                } else if (opcode.equals(ReceiveOpcode.LINK_CLICKED.getValue())) {
                        /* Do Nothing */
                } else if (opcode.equals(ReceiveOpcode.JOIN_CHANNEL.getValue())) {
                        JoinChannelHandler.handle(tokens, client);
                } else if (opcode.equals(ReceiveOpcode.Q_TOKEN.getValue())) {
                        /* Do Nothing */
                } else if (opcode.equals(ReceiveOpcode.REQUEST_USER_LIST.getValue())) {
                        /* Do Nothing */
                } else if (opcode.equals(ReceiveOpcode.HANDSHAKE.getValue())) {
                        HandshakeHandler.handle(tokens, client);
                } else if (opcode.equals(ReceiveOpcode.REQUEST_HELP.getValue())) {
                        RequestHelpHandler.handle(tokens, client);
                } else if (opcode.equals(ReceiveOpcode.LEAVE_CHANNEL.getValue())) {
                        LeaveChannelHandler.handle(tokens, client);
                } else if (opcode.equals(ReceiveOpcode.WHOIS.getValue())) {
                        /* Do Nothing */
                } else {
                        System.out.println(String.format("Unhandled opcode: %s", opcode));
                }
        }


Run-Methode wird abgeändert:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        @Override
        public void run() {
                Client client = new Client(socket);

                try {
                        InputStream in = socket.getInputStream();
                        byte type = (byte) in.read();

                        if (type == 0x00) {
                                while (true) {
                                        byte[] buffer        = Protocol.decode(in);
                                        String decoded        = Huffman.getDecoder().decode(buffer);
                                        read(client, decoded); /// <<< Ist nun die "read-Methode"
                                }
                        } else if (type == 0x02) {
                                // registration
                        }
                } catch (IOException e) {
                        /* Do Nothing */
                } finally {
                        client.disconnect();
                }
        }


Das sollte es gewesen sein.

18

Samstag, 26. Oktober 2013, 00:19

Nachtrag:
Mir und Jörn ist aufgefallen, dass es Clientseitige Probleme mit Safari <= 5.1 gibt, da eben ab dieser Version erst seitens Apple angefangen wurde, Websockets zu implementieren.
Bizzi weiß auch schon bescheid, hat aber schon ein Workaround - Will er nachher auf GitHub updaten.

19

Samstag, 26. Oktober 2013, 12:14

Websocket einbindung

Alles Soweit in Ordnung bis auf die Protocol.java die geändert werden muss da Huffman nun anders gesendet wird ;)


PHP-Quelltext

1
2
3
4
5
6
7
8
 /* Banana-Chat - The first Open Source Knuddels Emulator * Copyright (C) 2011 - 2012 Flav <http://banana-coding.com> *  * Diese Dateien unterliegen dem Coprytight von Banana-Coding und * darf verändert, aber weder in andere Projekte eingefügt noch * reproduziert werden. *  * Der Emulator dient - sofern der Client nicht aus Eigenproduktion * stammt - nur zu Lernzwecken, das Hosten des originalen Knuddels Clients * ist auf eigene Gefahr und verstößt möglicherweise gegen Schutzrechte * der Knuddels.de GmbH & Co KG *  * Autoren: Flav (Grundversion), Localhost (Erweiterte Version), Kokos-Ice (Erweiterte Version) */
package netchat;
public class Protocol {    public static byte[] encode(byte[] message) {        int length message.length 1;        byte[] len;
        if (length 128) {            len = new byte[] { (bytelength };        } else {            int count 0;
            while (32 << (count << 3) <= length) {                count++;            }
            count++;            len = new byte[count 1];            len[0] = (byte) (count << 0x80 length 0x1F);
            for (int i 1len.lengthi++) {                len[i] = (byte) (length >>> * (1) + 5);            }        }
        byte[] buffer = new byte[len.length message.length];        System.arraycopy(len0buffer0len.length);        System.arraycopy(message0bufferlen.lengthmessage.length);        return buffer;    }}

20

Samstag, 26. Oktober 2013, 13:48

Nach dem Safari-Fix verbindet sich der Chat bei mir nurnoch Lokal.
Meine Grafikseite: http://chatsmileys.senzious.de/