MMO mit Java – Charakter Auswahl

Nachdem die Schwierigkeiten mit FengGui ausgestanden sind, lief die Erstellung des Charakter Auswahlbildschirms deutlich schneller. Einzig die Liste zur Auswahl der einzelnen Charaktere verursachte zunächst einige Schwierigkeiten. Wird bei FengGui nicht explizit ein Theme ausgewählt, so bleiben Schriftarten und Hintergründe schwarz.

Das Setzen der Farbe und Hover-Farbe erfolgt folgendermaßen:


DecoratorLayer underlay = new DecoratorLayer();
PlainBackground plainBackground = new PlainBackground(new Color(0.97f, 0.89f, 0.52f, 0.5f));
RoundedBorder roundedBorder = new RoundedBorder(new Color(0.97f, 0.89f, 0.52f, 0.5f), 3, 3);
underlay.add(plainBackground, roundedBorder);
list.getAppearance().setHoverUnderlay(underlay);
list.getAppearance().setSelectionUnderlay(underlay);

Die erste Version des Auswahlbildschirms verfügt nur über ein statisches Hintergrundbild. Professionelle MMO’s verwenden hier entweder eine reine 3D Landschaft, eine 3D Landschaft kombiniert mit einer Skybox (z.B. GuildWars) oder ein Hintergrundbild, dessen Himmel animiert ist. Die einzelnen Gui’s sind mittels GameStates separiert, wichtig ist, dass aus den States sämtliche Widgets entfernt werden, damit diese nicht die nächste Maske beeinflussen. Hier nun das Ergebnis:

Charakter-Auswahlbildschirm

Eine erfreuliche Erkenntnis ergab sich noch: Der Text der GameButtons kann programmatisch eingefügt werden, damit erübrigen sich spezifische Bilder für jeden einzelnen Buttons und reduzieren die Malarbeit.

No Comments

MMO mit Java – Login Client mit FengGui

Nach dem ich jede Menge Inkompatibilitäten zwischen der JMonkeyEngine und FengGui beseitigt hatte und ich zweitweise dachte es funktioniert doch nicht ist die erste Version des Login Clients jetzt fertig. Schlussendlich ist es aber doch geschafft und alle Bibliotheken sind kompatibel im Maven Repository verstaut.

Nach einem Login mit den richtigen Daten werden die Account Informationen vom Server abgeholt. Fehlt also noch die Oberfläche zur Auswahl und Erstellung der Charaktere.

No Comments

MMO mit Java – JMonkeyEngine Client

Nachdem die Performance mit Java2D auf hohen Auflösungen zu wünschen übrig lies, ging ich über, den Client mit Java3D neu zu erstellen. Die Bücher Killer Game Programming in Java und Pro Java 6 3D Game Development sehr hilfreich.
Da Java3D aber nicht mehr weiterentwickelt wird, bzw. nur mehr im Rahmen für JavaFX war es sinnvoller auf eine für Spieleentwicklung spezialisierte Szene Graph API einzusetzen. Hier bot sich die JME – JmonkeyEngine 2 an. Die Ergebnisse können sich sehen lassen und die Einarbeitung fällt dank des umfangreichen Tutorials und der regen Forumaktivität – ganz im Gegensatz zu Java3D – ziemlich einfach aus.

Hier der erste Prototyp des Clients, der Avatar ist übrigens aus Neverwinter Nights, das Modell mit Hilfe eines eigenen Parsers,erzeugt mit antlr, eingelesen.

Impressionen einer virtuellen Welt

Hier ein weiteres Bild:

Impressionen einer virtuellen Welt

Auch wenn optisch schon ein ansprechendes Ergebnis da ist, so ist noch einiges zu tun, gerade hinsichtlich der Animationen, animiert Laufen kann der Avatar, aber es gibt noch einige Schwierigkeiten bei Sitzen und Aufstehen. Derzeit ist aber die Anbindung an den Application Server mit JMS interessanter.

No Comments

Transformation RSA Private Keys von PKCS#1 nach PKCS#8

Wird ein RSA Private Key mit openssl erzeugt, so wird der Key im PKCS#1 Format abgelegt:

Erzeugung:

openssl genrsa -outform PEM -out key.pem -des3

erzeugt einen 512 Bit langen Key, der anschließend folgendes Format aufweist:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,DF4786233111EACD

eRCD1pon6bRDOeDFgHhtdcTtlWzSM1KI78UG/OARE5b1xKM+BOxby1gp0yIqxQIw
Ai7360VvaRruFY/yUVf58JqwCL7pR6q9oiJZGW8PIFv3ATqcbrVGRrM9CuW6hDtL
NiC/Nfrj7ZWv5kMig+N8gTqt87MDefwRQG+F7SZMOJIBGdCI4kkcHtRm53gAan/u
nJKmDgeI5XZpFxG+n/6J30oSxS2NXT/TjGtLuBGIt+JF+YoK01v9USmjbyFVjxjG
fZLPN66iQdOxP/O2F+01rzoRfeDiZ5NM/q8AIdfcr9CVfnH/wV/xg/dL+44xhiuS
nmGz359MOw4Fng6reEoxilRCWB5ryyklxZvmD6zrZb5EBs58NFNRQJvGl/PDn7x3
A7kSInNYGDhcJdrPGekXtEulkaMrnvSpwMCH/jG1DQQ=
-----END RSA PRIVATE KEY-----

openssl bietet nun die Möglichkeit mit dem Parameter pkcs8 den Key umzuformen:

openssl pkcs8 -topk8 -in key.pem -out p8key.pem

Dies ergibt folgende Ausgabe:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIBgTAbBgkqhkiG9w0BBQMwDgQIhDFA40XfSycCAggABIIBYPjZuIFw8GxlCs9y
PEYRJPFNvLNlGglDWuY85deuxi+k/jTinjMyxRGmtnWlmly6xfjoptJDH+jmENxr
BwMEua4tthwUaJZOSU2UuN3q95kcE5YHyg9tLBvYMs3Jd/L6vOA73uiIflFgJ0yz
M3nEXqwNUKDlffVflhroRYAyWtQe9tLVaWnUZGFQeYoK7cjpnuzOPAa9QmeX3Ltf
4tkfzF8tfGM8+aoBGcO4eGmp32O0WVUE3HlcVY5Yv8XUzg7E/epB93c4bZDDGfkS
3fgr6rGb0ucL66jFqaSkJ6KVLoG1ui8ymXSmhZuzfgSWvtOnv2mM2FcpNA+dIwYp
k6cDkRWuKlZfN58axQVZ6wTWNgX/ts3aH3NmlTc50HOOGrvtqJ1jOJxzFgHmNWWS
nKCdcWAgaC43ivrbWxvgGarQuXe9lNWZt2fk4Lgukjix1Bqhakh9F5EfaiK1bXYq
ZQZotCg=
-----END ENCRYPTED PRIVATE KEY-----

Oberflächlich betrachtet ähnelt sich die Darstellung, jedoch handelt es sich bei der ASN.1 Repräsentation von PKCS#1 um eine Darstellung des Keys mittels dem CRT:

RSAPrivateKey ::= SEQUENCE {
  version Version,
  modulus INTEGER, -- n
  publicExponent INTEGER, -- e
  privateExponent INTEGER, -- d
  prime1 INTEGER, -- p
  prime2 INTEGER, -- q
  exponent1 INTEGER, -- d mod (p-1)
  exponent2 INTEGER, -- d mod (q-1)
  coefficient INTEGER -- (inverse of q) mod p
}

im PKCS#8 Format hingegen wird der Key in der Struktur PrivateKeyInfo dargestellt:

PrivateKeyInfo ::= SEQUENCE {
  version Version,
  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
  privateKey PrivateKey,
  attributes [0] IMPLICIT Attributes OPTIONAL
}

Version ::= INTEGER
PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
PrivateKey ::= OCTET STRING
Attributes ::= SET OF Attribute

Viele Applikationen oder Frameworks sind nicht in der Lage Schlüssel in der Form RSAPrivateKey zu verarbeiten, deshalb ist es ratsam, den Key in der Struktur PrivateKeyInfo abzuspeichern.

No Comments

MMO mit Java/J2EE? (Teil 3) – Action Kommunikation

Nachdem es notwendig war, die gesamte Clientdarstellung zu überarbeiten, um auf veschiedenen Rechnertypen akzeptable und gleichmäßig performante Darstellung zu erreichen bin ich nun endlich dazu gekommen, mir Gedanken über die Action-Kommunikation zu machen. Doch zunächst zur Begriffserklärung. In einem MMO Game wie es hier entwickelt wird folgendes unter Aktionen verstanden:

  • Flüchtige Aktionen: Sind Aktionen die eine Übertragung von sich schnell ändernden Statusinformationen zwischen Client und Server auslösen und keine oder nur eine periodische Persistierung benötigen. Zu derartigen Aktionen gehören z.B. die Bewegungen von Spielfiguren, die schnell und kontinuierlich zwischen Clients im Anzeige, bzw. Aktionsradius synchronisiert werden müssen. Der Verlust eines gewissen Prozentsatzes der Informationen kann bei dieser Informationsübertragung in Kauf genommen werden.
  • Transaktionsichere Aktionen: Sind Aktionen, die eine Übertragung von Statusinformationen zwischen Client und Server auslösen und dabei eine sichere Persistierung verlangen. Zu solchen Aktionen gehören z.B. Handelssitzungen zwischen Spielfiguren oder das Aufnehmen von Gegenständen in das Inventar der Spielfigur.
  • Action Kommunikation

    Action Kommunikation

    Der erste Ansatz einer solchen Informationsübertragung wird mit einem QueueRequestor durchgeführt, welcher einen request/reply Mechanismus via JMS zur Verfügung stellt. Das Senden einer Message erfolgt dabei über eine definierte Queue, während die Rückantwort über eine temporäre Queue verschickt wird. Ob sich dieser Ansatz als praktikabel und performant erweist, muss noch erprobt werden. Um die Datenbank nicht mit flüchtigen Statusinformationen zuzumüllen werden diese zunächst in einen Informationscache gespeichert und so für einen schnellen Zugriff vorgehalten. Die Überführung der Informationen in einen persistenten Zustand kann dann periodisch oder anhand einer geeigneten Eviction Policy erfolgen.

    No Comments

    MMO mit Java/J2EE? (Teil 2)

    Aktives Rendern zur Darstellung von Animationen

    Zur Darstellung der Clientgrafiken und Animationen für den MMO Prototyp verwende ich ein eigenes Canvas, welches mit einem Thread die Grafiken in kurzen Zeitabständen zyklisch neuzeichnet, dadurch lassen sich durch den Austausch der Grafiken animationen erzielen. Der Austausch kann an die Eingabe des Clients, oder an die Aktualisierung der Spieldaten des Servers für NSP’s (Nicht-Spieler Charaktere) gekoppelt sein.

    Exemplarische (nicht vollständige) Animationssequenz

    Exemplarische (nicht vollständige) Animationssequenz

    Mein bisheriges Canvas rief in run()-Methode des Threads periodisch repaint() auf. Da repaint() aber keinesfalls garantiert von der JVM aufgerufen wird, sondern in eine Queue eingestellt wird, ist eine reibungslose Animationsdarstellung nicht gewährleistet. Hier ergibt sich eine Verbesserung durch den Einsatz des sog. Active Rendering, die (vereinfachte) Implementierung dazu sieht folgendermaßen aus:


    1 private void activeRendering() {
    2   Graphics g = this.getGraphics();
    3   if (g != null) {
    4     g.drawImage(offscreenImage, 00null);
    5     Toolkit.getDefaultToolkit().sync();
    6     g.dispose();
    7   }
    8 }

    Toolkit.getDefaultToolkit().sync(); Stellt die Aktualisierung des Displays unter Linux sicher. (Quelle: Killer Game Programming, Andrew Davidson)

    No Comments

    Oracle XE: Ora-12638

    Gelegentlich kann es bei einer Oracle XE unter Windows zu folgendem Fehler kommen:


    UDI-00008: Vorgang hat ORACLE-Fehler generiert 12638
    ORA-12638: Abrufen der ID-Daten nicht erfolgreich



    In diesem Fall trat der Fehler im Zusammenhang mit einem Datenimport auf. Erfahrungsgemäß und durch Berichte anderer User kann das Problem mit einem Neustart des Datenbankservices behoben werden. Sollte dies jedoch nicht der Fall sein, so kann das Ändern der Einstellung SQLNET.AUTHENTICATION_SERVICES= (NTS) auf SQLNET.AUTHENTICATION_SERVICES= (NONE) in der Datei sqlnet.ora das Problem beseitigen. Die Änderung bewirkt, dass nicht mehr die native Windows Security beim Login verwendet wird, sondern nur mehr User und Passwort.

    No Comments

    MMO mit Java/J2EE? (Teil 1)

    MMO, oder Massively Multiplayer Online Games auf Basis von Java und J2EE? Die Antwort auf diese Frage werde ich in einer Reihe von Artikeln versuchen zu beantworten. Ziel ist eine Machbarkeitsstudie auf Basis eines Prototypen zu entwickeln.

    1.1 Einführung

    Ein Massively Multiplayer Online Game ist ein Computerspiel, welches ausschließlich über das Internet gespielt werden kann und bei dem gleichzeitig mehrere hundert oder tausend Spieler sich in einer persistenten Spielumgebung treffen und interagieren können. Vertreter bekannter Spiele sind z.B. World of Warcraft, Guildwars oder Warhammer Online.

    1.2. Architektur, Komponenten

    Ein MMO Game besteht grob aus den Schichten Präsentation (Client), Geschäftslogik (Server) und Datenhaltung (Server), also der klassischen Architektur die mit J2EE realisierbar ist. Folgende Grafik beschreibt die Architektur eines MMO Games:

    MMO Architektur

    MMO Architektur

    Clientseite
    Die Präsentationsschicht wird durch den Gameclient repräsentiert. Der Gameclient beinhaltet grob folgende Funktionen:

    • Login Funktionalität, zum Einloggen in die Spielwelt
    • Patch Funktionalität, zum automatischen Bezug und Installation von Softwareupdates
    • Darstellung der Spielwelt und der Interaktionen

    Serverseite
    Die Serverseite umfasst eine Reihe von Servern mit unterschiedlichen Aufgaben. Die folgende Trennung ist aufgrund der Lastverteilung üblich und wird bei den bekannten MMO’s so praktiziert:

    • Accountserver: Üblicherweise mit Web-basierter Oberfläche zur Verwaltung der Accountdaten, abgelegt in der Accountdatenbank
    • Loginserver: Server zum Überprüfen der Accountdaten und des Patchstandes
    • Sessionserver: Server zum Überprüfen der Gültigkeit der aktiven Session und zur Weiterleitung der Anfragen an den Patch- und Gameserver
    • Patchserver: Server zur Verteilung von Softwareupdates, hier sind mehrere Möglichkeiten denkbar, der Download von Patches über http oder ftp. Auch verteilte Ansätze sind denkbar, so benutzt World of Warcraft Bittorrent als Verteilungssystem.
    • Gameserver: Der eigentliche Spielserver, der die Spielewelt hostet und die Interaktionen der Spieler verwaltet und die Spielzustände in der Game-DB festhält.

    1.3. Ausblick

    Vorweg würde ich behaupten, dass sich J2EE für die Umsetzung eines MMO’s prinzipiell eignet, die entscheidende Frage stellt sich meines Erachtens, ob eine akzeptable Performance des Gameservers erreicht werden kann oder nicht. Von dieser Fragestellung ist die Anzahl der gleichzeitig bedienbaren Clients pro Server abhängig und damit beantwortet sich die Frage, ob ein MMO realisiert werden kann.

    No Comments

    jClaim – ICQ mit Java

    Freie ICQ Implementierungen gibt es mittlerweile einige, jedoch kaum welche in Java. Ein Vertreter ist jClaim, neben einer Bibliothek zum Erstellen einer eigenen Anwendung bietet jClaim auch einen fertigen Client, der direkt über Webstart gestartet werden kann. Ein simpler Client ist schnell realisiert:


    01 package messaging;
    02 
    03 import com.itbs.aimcer.commune.joscar.ICQConnection;
    04 import com.itbs.util.GeneralUtils;
    05 import controller.MessengerGroupFactory;
    06 import controller.MessengerContactFactory;
    07 import controller.LogEventHandler;
    08 
    09 public class JavaICQ {
    10 
    11   public static void main(String[] argsthrows Exception {
    12     try {
    13       ICQConnection conn = new ICQConnection();
    14       conn.assignGroupFactory(new MessengerGroupFactory());
    15       conn.assignContactFactory(new MessengerContactFactory());
    16       conn.setUserName("icqnumber");
    17       conn.setPassword("icqpass");
    18       conn.addEventListener(new LogEventHandler());
    19       conn.connect();
    20       while (true) {
    21         GeneralUtils.sleep(60 60 1000);
    22       }
    23     catch (Exception e) {
    24       throw new RuntimeException(e);
    25     }
    26   }
    27 
    28 }

    Statt des LogEventHandlers kann auch der BotEventHandler, der standardmäßig in der Bilbliothek enthalten ist, verwendet werden.
    Bei der Einfachheit dieser Implementierung bleibt es aber auch, so ist es z.B. mit der Bibliothek derzeit nur möglich vom Online Status auf den Away Status zu schalten. Die umfangreichen Funktionen, die der offizielle ICQ Client bietet, sind mit jClaim leider nicht zugänglich.

    No Comments

    Oracle XE: ORA-12519

    Gelegentlich kommt es beim Einsatz eines Oracle XE Datenbanksystems zu dem Fehler ORA-12519, dies kann sich mit Java folgendermaßen äußern:


    java.sql.SQLException: Listener refused the connection with the following error:
    ORA-12519, TNS:no appropriate service handler found
      at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
      at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:131)
      at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:197)
      at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:525)
      at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:413)



    Dies kann an der geringen Voreinstellung von üblicherweise 20 für die Anzahl an Sessions liegen. Das Problem kann dadurch gelöst werden, indem die Parameter sessions und processes erhöht werden. Um dies zu erreichen sind folgende Kommandos zu tätigen:


    alter system set processes=100 scope=spfile;
    alter system reset sessions scope=spfile sid='*';

    Die Kommandos können im Webinterface der Administrationsoberfläche unter dem User System ausgeführt werden. Nach einem Neustart der Datenbank sollte das Problem behoben sein. Trotz dieser Möglichkeit den Fehler zu umgehen sollte ein Blick in die Applikation geworfen werden, um die Ursache für den Sessionverbrauch festzustellen.

    No Comments