diff options
| author | Fuwn <[email protected]> | 2021-03-18 18:54:41 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2021-03-18 18:54:41 -0700 |
| commit | bc59a4b91b4f457f30356f31ad1a636774411470 (patch) | |
| tree | ec44109b9c72590e85d8d27750fe9cf6fa0de9b6 /src | |
| parent | chore: create contribution guidelines (diff) | |
| download | book-bc59a4b91b4f457f30356f31ad1a636774411470.tar.xz book-bc59a4b91b4f457f30356f31ad1a636774411470.zip | |
feat: many new pages
Diffstat (limited to 'src')
| -rw-r--r-- | src/SUMMARY.md | 16 | ||||
| -rw-r--r-- | src/introduction/contributing.md | 3 | ||||
| -rw-r--r-- | src/introduction/resources.md | 9 | ||||
| -rw-r--r-- | src/introduction/workflow.md | 24 | ||||
| -rw-r--r-- | src/jar/net/network/net_const.md | 187 | ||||
| -rw-r--r-- | src/jar/net/network/net_packet.md | 59 | ||||
| -rw-r--r-- | src/jar/net/network/obj_id.md | 66 | ||||
| -rw-r--r-- | src/jar/net/network/server_output_stream.md | 108 | ||||
| -rw-r--r-- | src/protocol/constants.md | 2 | ||||
| -rw-r--r-- | src/protocol/packet.md | 9 |
10 files changed, 483 insertions, 0 deletions
diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 0f52f44..4fb963b 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -2,3 +2,19 @@ - [Introduction](introduction.md) - [mdBook](./introduction/mdbook.md) + - [Resources](./introduction/resources.md) + - [Workflow](./introduction/workflow.md) + - [Contributing](./introduction/contributing.md) + +- [The WorldServer Protocol]() + - [Packet Information](./protocol/packet.md) + - [Network Constants](./protocol/constants.md) + +- [worlds.jar]() + - [NET.worlds]() + - [network]() + - [ObjID](./jar/net/network/obj_id.md) + - [ServerInputStream]() + - [ServerOutputStream](./jar/net/network/server_output_stream.md) + - [netConst](./jar/net/network/net_const.md) + - [netPacket](./jar/net/network/net_packet.md) diff --git a/src/introduction/contributing.md b/src/introduction/contributing.md new file mode 100644 index 0000000..0cb4775 --- /dev/null +++ b/src/introduction/contributing.md @@ -0,0 +1,3 @@ +# Contributing + +Please reference the [contribution guidelines](https://github.com/Whirlsplash/book/blob/master/CONTRIBUTING.md) of this repository. diff --git a/src/introduction/resources.md b/src/introduction/resources.md new file mode 100644 index 0000000..1a9c598 --- /dev/null +++ b/src/introduction/resources.md @@ -0,0 +1,9 @@ +# Resources +A few sources worth reading into when working with the WorldServer protocol. + +## The GammaDocs +- WorldServer v11 Administration Guide: http://dev.worlds.net/private/GammaDocs/WorldServer.html +- Worlds.com's Gamma Development Kit: http://dev.worlds.net/private/GammaDocs/Dev_Kit_Intro.html + +## The OpenWorlds (LibreWorlds) Wiki +https://github.com/Xyem/LibreWorlds/wiki diff --git a/src/introduction/workflow.md b/src/introduction/workflow.md new file mode 100644 index 0000000..592f653 --- /dev/null +++ b/src/introduction/workflow.md @@ -0,0 +1,24 @@ +# Workflow + +## Prerequisites +- A Java decompiler. I think [Java Decompiler](https://java-decompiler.github.io/) is a neat one. +- Setting the `netdebug` flag within your `worlds.ini` file to `255`. + +## Process +1. Run Worlds, login, walk around, just gather some sample data. +2. Open your `Gamma.log` file within a text editor. +3. Open Java Decompiler and drag your `worlds.jar` onto it; opening it. +4. Within your `Gamma.log`, find a network request, e.g +`[18803] test.3dcd.com:6650: send(BUDDYLISTUPDATE fuwn 1)`. +5. Note the command used, e.g. `BUDDYLUSTUPDATE`. +6. Within Java Decompiler, bring up the Search feature using `Ctrl+Shift+S` and tick all the search options. +7. Profit. + +### Extended +For `BUDDYLISTUPDATE`, I ended up in the `NET.worlds.network.BuddyListUpdateCmd` class. + +Here, I can review the methods which this class contains, and I notice that one happens to have +the name `send`. + +I can now reference the raw packet data from a network proxy like Wireshark with this +method and connect the dots. diff --git a/src/jar/net/network/net_const.md b/src/jar/net/network/net_const.md new file mode 100644 index 0000000..8fc38fa --- /dev/null +++ b/src/jar/net/network/net_const.md @@ -0,0 +1,187 @@ +# netConst + +## Class Type +`interface` + +## Fields +```java +public static final byte PROTOCOL_VERSION = 24; + +public static final byte STATECMD = 2; + +public static final int MAXCMD = 255; + +public static final int CURRENT_ROOM = 253; + +public static final int CLIENT = 1; + +public static final int CO = 254; + +public static final int PO = 255; + +public static final byte VAR_APPNAME = 1; + +public static final byte VAR_USERNAME = 2; + +public static final byte VAR_PROTOCOL = 3; + +public static final byte VAR_ERROR = 4; + +public static final byte VAR_CHANNEL = 5; + +public static final byte VAR_BITMAP = 5; + +public static final byte VAR_PASSWORD = 6; + +public static final byte VAR_AVATARS = 7; + +public static final byte VAR_UPDATETIME = 8; + +public static final byte VAR_CLIENT = 9; + +public static final int VAR_SERIAL = 10; + +public static final int VAR_EMAIL = 11; + +public static final int VAR_LOGONOFF = 12; + +public static final int VAR_DURATION = 13; + +public static final int VAR_GUEST = 14; + +public static final int VAR_SERVERTYPE = 15; + +public static final int VAR_BIZCARD = 16; + +public static final int VAR_NEW_PASSWD = 20; + +public static final int VAR_PRIV = 22; + +public static final byte VAR_ASLEEP = 23; + +public static final byte VAR_EXTERNAL_HTTP_SERVER = 24; + +public static final byte VAR_SCRIPT_SERVER = 25; + +public static final byte VAR_SMTP_SERVER = 26; + +public static final byte VAR_MAIL_DOMAIN = 27; + +public static final byte VAR_NEW_USERNAME = 28; + +public static final byte VAR_INTERNAL_HTTP_SERVER = 29; + +public static final byte VAR_INVENTORY = 32; + +public static final int ACK = 0; + +public static final int NAK_BAD_USER = 1; + +public static final int NAK_MAX_ORDINARY = 2; + +public static final int NAK_MAX_PRIORITY = 3; + +public static final int NAK_BAD_WORLD = 4; + +public static final int NAK_FATAL = 5; + +public static final int NAK_BAD_PROTOCOL = 6; + +public static final int NAK_BAD_CLIENTSW = 7; + +public static final int NAK_BAD_ROOM = 8; + +public static final int NAK_BAD_SERIAL = 9; + +public static final int NAK_TAKEN_SERIAL = 10; + +public static final int NAK_TAKEN_USER = 11; + +public static final int NAK_NO_SUCH_USER = 12; + +public static final int NAK_BAD_PASSWORD = 13; + +public static final int NAK_BAD_ACCOUNT = 14; + +public static final int NAK_NOT_LOGGEDON = 15; + +public static final int NAK_BAD_IPADDRESS = 16; + +public static final int NAK_LOGGEDON = 17; + +public static final int NAK_CRYPT_METHOD = 18; + +public static final int NAK_CRYPT_ERROR = 19; + +public static final int NAK_SESSIONINIT = 20; + +public static final int NAK_ROOM_FULL = 21; + +public static final int NAK_SHUTDOWN = 100; + +public static final int NAK_WRITE_ERROR = 101; + +public static final int NAK_READ_ERROR = 102; + +public static final int NAK_UNEXPECTED = 103; + +public static final int NAK_CONNECTION = 104; + +public static final int NAK_IOSTREAMS = 105; + +public static final int NAK_TIMEOUT = 106; + +public static final int NAK_UNREACHABLE = 107; + +public static final int STATUS_CONNECTED = 200; + +public static final int STATUS_DETACHING = 201; + +public static final int STATUS_WILLRETRY = 202; + +public static final int STATUS_DISCONNECTED = 203; + +public static final int STATUS_DEAD = 204; + +public static final int STATUS_OFFLINE = 205; + +public static final int STATUS_GALAXY_ONLINE = 206; + +public static final int STATUS_GALAXY_OFFLINE = 206; + +public static final int PROPFLAG_BINARY = 16; + +public static final int PROPFLAG_FINGER = 32; + +public static final int PROPFLAG_AUTOUPDATE = 64; + +public static final int PROPFLAG_DBSTORE = 128; + +public static final int PROPACCESS_POSSESS = 1; + +public static final int PROPACCESS_PRIVATE = 2; + +public static final int SERVER_UNKNOWN = 0; + +public static final int USER_SERVER_DB = 1; + +public static final int USER_SERVER_ANON = 2; + +public static final int ROOM_SERVER_US = 3; + +public static final int ROOM_SERVER_ANON = 4; + +public static final int PRIV_NONE = 0; + +public static final int PRIV_BUILD = 1; + +public static final int PRIV_BROADCAST = 2; + +public static final int PRIV_PROPERTY = 4; + +public static final int PRIV_VIP = 8; + +public static final int PRIV_VIP2 = 16; + +public static final int PRIV_SPECIALGUEST = 64; +``` diff --git a/src/jar/net/network/net_packet.md b/src/jar/net/network/net_packet.md new file mode 100644 index 0000000..27adfbb --- /dev/null +++ b/src/jar/net/network/net_packet.md @@ -0,0 +1,59 @@ +# netPacket + +## Imports +- `NET.worlds.console.StatNetMUNode` +- `java.io.IOException` + +## Class Type +`abstract` + +## Fields +### `protected ObjID _objID` + +### `protected int _commandType` + +## Constructors +```java +public netPacket(ObjID id, int cmd) { + if (id != null) { + this._objID = id; + } else { + this._objID = new ObjID(1); + } + this._commandType = cmd; +} + +public netPacket() { + this._objID = new ObjID(1); +} +``` + +## Methods +### `public int msgID()` +Returns [`this._commandType`](#protected-int-_commandtype). + +### `int packetSize()` +Returns `2 + `[`this._objID`](#protected-objid-_objid)[`.packetSize()`]() + +### `public String toString(WorldServer serv`) +Returns `new Integer(`[`this._commandType`](#protected-int-_commandtype)`).toString()` + +### `void send(`[`ServerOutputStream`](./server_output_stream.md)` o) throws IOException` +```java +int packetsize = packetSize(); +if (packetsize >= 256 && o.getVersion() <= 24) + throw new PacketTooLargeException(); +StatNetMUNode netStat = StatNetMUNode.getNode(); +netStat.addBytesSent(packetsize); +netStat.addPacketsSent(1); +assert this._commandType > 0; +if (packetsize >= 128 && o.getVersion() > 24) { + o.writeByte(128 + packetsize / 256); + o.writeByte(packetsize & 0xFF); +} else { + o.writeByte(packetsize); +} +this._objID.send(o); +o.writeByte(this._commandType); +} +``` diff --git a/src/jar/net/network/obj_id.md b/src/jar/net/network/obj_id.md new file mode 100644 index 0000000..a591366 --- /dev/null +++ b/src/jar/net/network/obj_id.md @@ -0,0 +1,66 @@ +# ObjID + +## Imports +- `java.io.IOException` + +## Fields +### `private int _shortObjID` + +### `private String _longObjID` + +## Constructors +```java +public ObjID(int id) { + this._shortObjID = id; + this._longObjID = null; +} + +public ObjID(String id) { + this._shortObjID = 0; + if (id.startsWith("!")) + id = id.substring(1); + this._longObjID = id; +} + +public ObjID() { + this._shortObjID = 0; + this._longObjID = null; +} +``` + +## Methods +### `public int shortID()` +Returns [`this._shortObjID`](#private-int-_shortobjid). + +### `public int longID()` +Returns [`this._longObjID`](#private-string-_longobjid). + +### `void parseNetData(`[`ServerOutputStream`](./server_output_stream.md)` o) throws IOException` +```java +if (this._longObjID != null) { + o.writeByte(0); + o.writeUTF(this._longObjID); +} else { + assert this._shortObjID == 1 || this._shortObjID >= 253; + o.writeByte(this._shortObjID); +} +``` + +TLDR; Returns the correct field? + +### `public String toString(WorldServer serv)` +```java +if (this._longObjID != null) + return this._longObjID; + +return String.valueOf(Integer.toString(this._shortObjID)) + + "[" + serv.getLongID(this) + "]"; +``` + +### `public String toString()` +```java +if (this._longObjID != null) + return this._longObjID; + +return "[#" + Integer.toString(this._shortObjID) + "]"; +``` diff --git a/src/jar/net/network/server_output_stream.md b/src/jar/net/network/server_output_stream.md new file mode 100644 index 0000000..9999529 --- /dev/null +++ b/src/jar/net/network/server_output_stream.md @@ -0,0 +1,108 @@ +# ServerOutputStream + +## Imports +- `java.io.FilterOutputStream` +- `java.io.IOException` +- `java.io.OutputStream` + +## Extends +[FilterOutputStream](https://docs.oracle.com/javase/7/docs/api/java/io/FilterOutputStream.html) + +## Fields +### `private int _version` +Purpose is to be determined. + +## Constructors +```java +public ServerOutputStream(OutputStream o) { + super(o); + setVersion(24); +} + +public ServerOutputStream(OutputStream o, int vers) { + super(o); + setVersion(vers); +} +``` + +## Methods +### `public void setVersion(int vers)` +Sets [`this._version`](#private-int-_version) to `vers`. + +### `public int getVersion()` +Returns [`this._version`](#private-int-_version). + +### `public final void write(int b) throws IOException` +Writes the singular byte; `b` to the output stream. + +```java +this.out.write(b); +``` + +### `public final void write(byte[] b, int off, len) throws IOException` +Writes `len` bytes from the specified byte array starting at the offset; `off` to the output stream. + +```java +this.out.write(b, off, len); +``` + +### `public final void writeByte(int v) throws IOException` +Clone of [`write(int b)`](#writeint-b). + +### `public final void writeShort(int v) throws IOException` +```java +OutputStream out = this.out; +out.write(v >>> 8 & 0xFF); +out.write(v >>> 0 & 0xFF); +``` + +### `public final void writeInt(int v) throws IOException` +```java +OutputStream out = this.out; +out.write(v >>> 24 & 0xFF); +out.write(v >>> 16 & 0xFF); +out.write(v >>> 8 & 0xFF); +out.write(v >>> 0 & 0xFF); +``` + +### `public final void utfLength(String str)` +```java +int strlen = str.length(); +int utflen = 0; +for (int i = 0; i < strlen; i++) { + int c = str.charAt(i); + if (c >= 1 && c <= 127) { + utflen++; + } else if (c > 2047) { + utflen += 3; + } else { + utflen += 2; + } +} +return utflen; +``` + +### `public final void writeUTF(String str) throws IOException` +```java +OutputStream out = this.out; +int strlen = str.length(); +int utflen = utfLength(str); +assert utflen < 256; +out.write(utflen >>> 0 & 0xFF); +for (int i = 0; i < strlen; i++) { + int c = str.charAt(i); + if (c >= 1 && c <= 127) { + out.write(c); + } else if (c > 2047) { + out.write(0xE0 | c >> 12 & 0xF); + out.write(0x80 | c >> 6 & 0x3F); + out.write(0x80 | c >> 0 & 0x3F); + } else { + out.write(0xC0 | c >> 6 & 0x1F); + out.write(0x80 | c >> 0 & 0x3F); + } +} +``` + +### Resources +- [https://docs.oracle.com/javase/7/docs/api/java/io/FilterOutputStream.html](https://docs.oracle.com/javase/7/docs/api/java/io/FilterOutputStream.html) diff --git a/src/protocol/constants.md b/src/protocol/constants.md new file mode 100644 index 0000000..97cb285 --- /dev/null +++ b/src/protocol/constants.md @@ -0,0 +1,2 @@ +# Network Constants +Refer to [netConst](../jar/net/network/net_const.md).
\ No newline at end of file diff --git a/src/protocol/packet.md b/src/protocol/packet.md new file mode 100644 index 0000000..20add95 --- /dev/null +++ b/src/protocol/packet.md @@ -0,0 +1,9 @@ +# Packet Information +Information about how Worlds send and handles packets. + +## External Resources +- [https://github.com/Xyem/LibreWorlds/wiki/Packet-types](https://github.com/Xyem/LibreWorlds/wiki/Packet-types) +- [https://github.com/Xyem/LibreWorlds/wiki/Packet-structure](https://github.com/Xyem/LibreWorlds/wiki/Packet-types) + +## References +Most of [NET.worlds.network](). |