M
Marco01_809
Gast
Hi Java-Forum,
es gibt ein bekanntes Rennspiel namens "Trackmania". Natürlich gibt es auch einen Online-Modus und dafür kann man sich "Tm Dedicated Server" einrichten. Diese sind aber langweilig, denn man kann nur fahren, keine Rekorde, etc.
Dazu hat der TmServer eine "Schnittstelle" - XML-RPC. Das nennt sich "gbxRemote".
Über dieses gbxRemote lässt sich der Server sehr stark erweitern - dazu gehört auch das anzeigen von UI's Ingame etc.
Für PHP liegt ein gbxRemote-Client beim Server dabei. Es gibt auch schon um die 10 Projekte in PHP, doch mit PHP kommt man von der Leistung her recht schnell an die Grenze. -> Bei 100 Spielern auf einem Server kommen die UI's u.s.w. nicht mehr hinterher...
Ich versuche nun, das ganze in Java zu realisieren. Das wurde ebenfalls schonmal realisiert,
aber ich finde das vorhandene Tool nicht so toll, es bekam 2009 das letzte mal ein Update.
Es gibt sonst noch keine derartigen Tools in Java/C/C++/C#/Python/Perl was es eben nicht alles gibt.
Ich habe damit angefangen diese gbxRemote für Java zu programmieren.
Habe ein Problem mit meinem Source;
Die IXR_Client_Gbx, also die wichtigste Klasse die die Verbindung etc. verwaltet:
Meine IXR_Exception, die ich bei jedem Fehler freudig durch die Gegend werfe:
Und zu letzt meine Testklasse:
(Ich weiß, die ist nicht gerade schön mit den System.exit()'s aber die ist nur schnell zum Testen gedacht
)
Dazu die Konsolenaudgabe:
Verbunden werde ich auf jedenfall, denn ich kann ja vom InputStream das Protokoll abfragen. (Natürlich läuft dazu der TmServer)
Hab die PHP-Beispiele mal angehängt;
basic.php = Anwendungsbeispiel der GbxRemote.*.php
GbxRemote.inc.php = Die besagte GbxRemote.
GbxRemote.bem.php = Dieselbe GbxRemote für Big Endian.
SpectatorUi.php und ListMethods.php = Weitere kleine Anwendungsbeispiele.
Bitte helft mir,
Gruß Marco.
es gibt ein bekanntes Rennspiel namens "Trackmania". Natürlich gibt es auch einen Online-Modus und dafür kann man sich "Tm Dedicated Server" einrichten. Diese sind aber langweilig, denn man kann nur fahren, keine Rekorde, etc.
Dazu hat der TmServer eine "Schnittstelle" - XML-RPC. Das nennt sich "gbxRemote".
Über dieses gbxRemote lässt sich der Server sehr stark erweitern - dazu gehört auch das anzeigen von UI's Ingame etc.
Für PHP liegt ein gbxRemote-Client beim Server dabei. Es gibt auch schon um die 10 Projekte in PHP, doch mit PHP kommt man von der Leistung her recht schnell an die Grenze. -> Bei 100 Spielern auf einem Server kommen die UI's u.s.w. nicht mehr hinterher...
Ich versuche nun, das ganze in Java zu realisieren. Das wurde ebenfalls schonmal realisiert,
aber ich finde das vorhandene Tool nicht so toll, es bekam 2009 das letzte mal ein Update.
Es gibt sonst noch keine derartigen Tools in Java/C/C++/C#/Python/Perl was es eben nicht alles gibt.
Ich habe damit angefangen diese gbxRemote für Java zu programmieren.
Habe ein Problem mit meinem Source;
Die IXR_Client_Gbx, also die wichtigste Klasse die die Verbindung etc. verwaltet:
Java:
package gbxRemote;
/*
* @package gbxRemote
* @author Marco01_809
* @copyright 2011
* @version 1
*/
import java.io.Closeable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class IXR_Client_Gbx extends Socket implements Closeable {
public final static byte VERSION = 1;
public final static int DEFAULT_CONNECT_TIMEOUT = 15000;
private byte GBXRemoteVersion;
private InetSocketAddress addr;
public IXR_Client_Gbx() {
super();
}
public void connect(String host, int port, int timeout) throws IXR_Exception, UnknownHostException, IOException {
addr = new InetSocketAddress(host, port);
super.connect(addr, timeout);
int length = getInputStream().read();
if (length != 11)
throw new IXR_Exception("Unknown lowlevel protocol with length: " + length, (short) -32300);
getInputStream().skip(3);
String protocolText = readString(length);
String protocolType = protocolText.substring(0, 9);
if (!protocolType.equals("GBXRemote"))
throw new IXR_Exception("Unknown lowlevel protocol type: " + protocolType, (short) -32301);
byte protocolVersion = Byte.parseByte(protocolText.substring(10));
if (protocolVersion != 1 && protocolVersion != 2)
throw new IXR_Exception("Unknown lowlevel protocol version: " + protocolVersion, (short) -32302);
GBXRemoteVersion = protocolVersion;
}
public void connect(int port, int timeout) throws IXR_Exception, UnknownHostException, IOException {
connect(InetAddress.getLocalHost().getHostName(), port, timeout);
}
public void connect(int port) throws IXR_Exception, UnknownHostException, IOException {
connect(InetAddress.getLocalHost().getHostName(), port, DEFAULT_CONNECT_TIMEOUT);
}
public void connect(String host, int port) throws IXR_Exception, UnknownHostException, IOException {
connect(host, port, DEFAULT_CONNECT_TIMEOUT);
}
@Override
public void close() throws IOException {
getOutputStream().flush();
super.close();
GBXRemoteVersion = 0;
}
public byte getGBXRemoteVersion() {
return GBXRemoteVersion;
}
public InetSocketAddress getAddr() {
return addr;
}
private String readString(int length) throws IOException {
String text = "";
for (int i = 0; i < length; i++)
text += (char) getInputStream().read();
return text;
}
private void writeString(String text) throws IOException {
char[] chars = text.toCharArray();
for (char c : chars)
getOutputStream().write(c);
}
public void query(String method, String... args) throws IOException {
String query = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><methodCall><methodName>" + method + "</methodName><params>";
for (String a : args)
query += "<param><value><int>" + System.currentTimeMillis() + "</int></value></param>"; // Nur provisorisch, natürlich sollen normalerweise die args mit dazugehörigem Datentypn übermittelt werden
query += "</params></methodCall>";
writeString(query);
System.out.println(getInputStream().read()); // HIER TRITT DER FEHLER AUF!
}
}
Meine IXR_Exception, die ich bei jedem Fehler freudig durch die Gegend werfe:
Java:
package gbxRemote;
/*
* @package gbxRemote
* @author Marco01_809
* @copyright 2011
* @version 1
*/
public class IXR_Exception extends Exception {
public static final long serialVersionUID = 1;
public final short code;
public IXR_Exception(String message, short code) {
super(message);
this.code = code;
}
public short getCode() {
return code;
}
}
Und zu letzt meine Testklasse:
Java:
package jManiaServ;
import gbxRemote.IXR_Client_Gbx;
import gbxRemote.IXR_Exception;
import java.io.IOException;
import java.net.UnknownHostException;
public final class Main {
private static IXR_Client_Gbx client;
public static void main(String[] args) {
try {
long timebefore = System.currentTimeMillis();
client = new IXR_Client_Gbx();
client.connect(5004);
long timeafter = System.currentTimeMillis();
System.out.println((timeafter - timebefore) + " ms");
System.out.println("GBXRemote Version: " + client.getGBXRemoteVersion());
client.query("GetServerName");
} catch (IXR_Exception e) {
// Catch IXR Exceptions
System.out.println("[IXR_Exception] " + e.getCode() + " \"" + e.getLocalizedMessage() + "\"! Execution aborted!");
e.printStackTrace();
System.exit(50);
} catch (UnknownHostException e) {
// Catch UnknownHostExceptions
System.out.println("[UnknownHostException] \"" + e.getLocalizedMessage() + "\"! Execution aborted!");
e.printStackTrace();
System.exit(101);
} catch (IOException e) {
// Catch all other IOExceptions
System.out.println("[IOException] \"" + e.getLocalizedMessage() + "\"! Execution aborted!");
e.printStackTrace();
System.exit(100);
} catch (Exception e) {
// Catch all other Exceptions
System.out.println("[Exception] \"" + e.getLocalizedMessage() + "\"! Execution aborted!");
e.printStackTrace();
System.exit(2);
}
}
}
Dazu die Konsolenaudgabe:
Konsole hat gesagt.:21 ms
GBXRemote Version: 2
[IOException] "Connection reset"! Execution aborted!
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at gbxRemote.IXR_Client_Gbx.query(IXR_Client_Gbx.java:93)
at jManiaServ.Main.main(Main.java:21)
Verbunden werde ich auf jedenfall, denn ich kann ja vom InputStream das Protokoll abfragen. (Natürlich läuft dazu der TmServer)
Hab die PHP-Beispiele mal angehängt;
basic.php = Anwendungsbeispiel der GbxRemote.*.php
GbxRemote.inc.php = Die besagte GbxRemote.
GbxRemote.bem.php = Dieselbe GbxRemote für Big Endian.
SpectatorUi.php und ListMethods.php = Weitere kleine Anwendungsbeispiele.
Bitte helft mir,
Gruß Marco.