aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/gammadocs/roomserver/userserver-configuration-options.md41
-rw-r--r--docs/introduction/basis.md16
-rw-r--r--docs/introduction/contributing.md5
-rw-r--r--docs/introduction/resources.md10
-rw-r--r--docs/introduction/workflow.md9
-rw-r--r--docs/tutorial/create-a-blog-post.md25
-rw-r--r--docs/tutorial/create-a-document.md38
-rw-r--r--docs/tutorial/create-a-page.md45
-rw-r--r--docs/tutorial/getting-started.md28
-rw-r--r--docs/tutorial/markdown-features.mdx.dev128
-rw-r--r--docs/tutorial/thank-you.md17
-rw-r--r--docs/worlds-jar/net-worlds/network/netconst.md189
-rw-r--r--docs/worlds-jar/net-worlds/network/netpacket.md61
-rw-r--r--docs/worlds-jar/net-worlds/network/objid.md68
-rw-r--r--docs/worlds-jar/net-worlds/network/serveroutputstream.md110
-rw-r--r--docs/worldserver-protocol/network-constants.md5
-rw-r--r--docs/worldserver-protocol/packet-information.md11
-rw-r--r--docs/worldserver-protocol/roomserver.md23
-rw-r--r--docs/worldserver-protocol/userserver.md26
19 files changed, 855 insertions, 0 deletions
diff --git a/docs/gammadocs/roomserver/userserver-configuration-options.md b/docs/gammadocs/roomserver/userserver-configuration-options.md
new file mode 100644
index 0000000..545f2bf
--- /dev/null
+++ b/docs/gammadocs/roomserver/userserver-configuration-options.md
@@ -0,0 +1,41 @@
+---
+title: UserServer Configuration Options
+---
+
+## Logging
+Inclusion of this keyword enables logging of every command that passes over the network (both
+input and output), as well as logging of various other information. It is primarily intended to be
+used for debugging. All of this debugging information is appended to the ".out" file not the ".log"
+file.
+
+Logging can also be toggled on and off while the UserServer is running by sending the server
+SIGUSR1: `kill -USR1 pid`
+
+Use logging carefully, it generates a very large amount of output to the UserServer output file.
+Logging functionality and these keywords are only available in UserServers that have been compiled
+for Worlds' internal use.
+
+This feature is disabled by default.
+
+### InternalHttpServer
+This is the base URL of the machine to use for handling HTTP requests for the internal version of
+Gamma. For example: http://dev.worlds.net
+
+### ExternalHttpServer
+This is the base URL of the machine to use for handling static HTTP requests for the release (i.e.
+external) version of Gamma. For example: http://www-static.us.worlds.net
+
+### ScriptServer
+Similar to ExternalHttpServer, this is the URL of the directory where server scripts should be
+executed. This is for things like the registration script and various other maintenance scripts.
+Example: http://www-dynamic.us.worlds.net/cgi-bin
+
+### BindAddr (UserServer only)
+Used when you wish to run two UserServers on a single multi-homed machine. This is really only
+useful for redirecting traffic on one of the UserServers to a set of remote RoomServers.
+
+### SmtpServer
+The SMTP server to used to connect to for sending WorldsMail.
+
+### MailDomain
+The DNS domain to use in the "from" address when sending WorldsMail.
diff --git a/docs/introduction/basis.md b/docs/introduction/basis.md
new file mode 100644
index 0000000..6520e0e
--- /dev/null
+++ b/docs/introduction/basis.md
@@ -0,0 +1,16 @@
+---
+title: Basis
+slug: /
+---
+
+Whirlsplash is a
+[WorldServer](http://dev.worlds.net/private/GammaDocs/WorldServer.html)
+implementation in [Go](https://golang.org/) which has a strong focus on speed,
+maintainability, and easy configuration.
+
+<a href="https://discord.com/invite/8hn6padWF6" title="Discord">
+ <img src="https://img.shields.io/discord/821938182274154506" />
+</a>&nbsp;
+<a href="https://github.com/Whirlsplash/whirl/blob/master/LICENSE" title="License">
+ <img src="https://img.shields.io/github/license/Whirlsplash/whirl" />
+</a>
diff --git a/docs/introduction/contributing.md b/docs/introduction/contributing.md
new file mode 100644
index 0000000..0e2e4ad
--- /dev/null
+++ b/docs/introduction/contributing.md
@@ -0,0 +1,5 @@
+---
+title: Contributing
+---
+
+Please reference the [contribution guidelines](https://github.com/Whirlsplash/site/blob/master/CONTRIBUTING.md) of this repository.
diff --git a/docs/introduction/resources.md b/docs/introduction/resources.md
new file mode 100644
index 0000000..0abd6fb
--- /dev/null
+++ b/docs/introduction/resources.md
@@ -0,0 +1,10 @@
+---
+title: Resources
+---
+
+## 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)
+
+## OpenWorlds (LibreWorlds) Wiki
+[https://github.com/Xyem/LibreWorlds/wiki](https://github.com/Xyem/LibreWorlds/wiki)
diff --git a/docs/introduction/workflow.md b/docs/introduction/workflow.md
new file mode 100644
index 0000000..e03b1d2
--- /dev/null
+++ b/docs/introduction/workflow.md
@@ -0,0 +1,9 @@
+---
+title: 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 2147483647.
+
+To be implemented.
diff --git a/docs/tutorial/create-a-blog-post.md b/docs/tutorial/create-a-blog-post.md
new file mode 100644
index 0000000..4485a8a
--- /dev/null
+++ b/docs/tutorial/create-a-blog-post.md
@@ -0,0 +1,25 @@
+---
+title: Create a Blog Post
+---
+
+This page will help you on how to create blog posts in Docusaurus.
+
+## Create a Blog Post
+
+Create a file at `blog/2021-02-28-greetings.md`:
+
+```md title="blog/2021-02-28-greetings.md"
+---
+title: Greetings!
+author: Steven Hansel
+author_title: Docusaurus Contributor
+author_url: https://github.com/ShinteiMai
+author_image_url: https://github.com/ShinteiMai.png
+---
+
+Congratulations, you have made your first post!
+
+Feel free to play around and edit this post as much you like.
+```
+
+A new blog post is now available at `http://localhost:3000/blog/greetings`.
diff --git a/docs/tutorial/create-a-document.md b/docs/tutorial/create-a-document.md
new file mode 100644
index 0000000..7922129
--- /dev/null
+++ b/docs/tutorial/create-a-document.md
@@ -0,0 +1,38 @@
+---
+title: Create a Document
+---
+
+Documents are pages with a **sidebar**, a **previous/next navigation** and many other useful features.
+
+## Create a Document
+
+Create a markdown file at `docs/my-doc.md`:
+
+```mdx title="docs/hello.md"
+---
+title: Hello, World!
+---
+
+## Hello, World!
+
+This is your first document in **Docusaurus**, Congratulations!
+```
+
+A new document is now available at `http://localhost:3000/docs/hello`.
+
+## Add your document to the sidebar
+
+Add `hello` to the `sidebars.js` file:
+
+```diff title="sidebars.js"
+module.exports = {
+ docs: [
+ {
+ type: 'category',
+ label: 'Docusaurus Tutorial',
+- items: ['getting-started', 'create-a-doc', ...],
++ items: ['getting-started', 'create-a-doc', 'hello', ...],
+ },
+ ],
+};
+```
diff --git a/docs/tutorial/create-a-page.md b/docs/tutorial/create-a-page.md
new file mode 100644
index 0000000..1056090
--- /dev/null
+++ b/docs/tutorial/create-a-page.md
@@ -0,0 +1,45 @@
+---
+title: Create a Page
+---
+
+Any React or Markdown file created under `src/pages` directory is converted into a website page:
+
+- `src/pages/index.js` -> `localhost:3000/`
+- `src/pages/foo.md` -> `localhost:3000/foo`
+- `src/pages/foo/bar.js` -> `localhost:3000/foo/bar`
+
+## Create a React Page
+
+Create a file at `src/pages/my-react-page.js`:
+
+```jsx title="src/pages/my-react-page.js"
+import React from 'react';
+import Layout from '@theme/Layout';
+
+function HelloWorld() {
+ return (
+ <Layout>
+ <h1>My React page</h1>
+ <p>This is a React page</p>
+ </Layout>
+ );
+}
+```
+
+A new page is now available at `http://localhost:3000/my-react-page`.
+
+## Create a Markdown Page
+
+Create a file at `src/pages/my-markdown-page.md`:
+
+```mdx title="src/pages/my-markdown-page.md"
+---
+title: My Markdown page
+---
+
+# My Markdown page
+
+This is a Markdown page
+```
+
+A new page is now available at `http://localhost:3000/my-markdown-page`.
diff --git a/docs/tutorial/getting-started.md b/docs/tutorial/getting-started.md
new file mode 100644
index 0000000..43df86a
--- /dev/null
+++ b/docs/tutorial/getting-started.md
@@ -0,0 +1,28 @@
+---
+title: Getting Started
+slug: /
+---
+
+## Step 1: Generate a new Docusaurus site
+
+If you haven't already, generate a new Docusaurus site using the classic template:
+
+```shell
+npx @docusaurus/init@latest init my-website classic
+```
+
+## Step 2: Start your Docusaurus site
+
+Run the development server in the newly created `my-website` folder:
+
+```shell
+cd my-website
+
+npx docusaurus start
+```
+
+Open `docs/getting-started.md` and edit some lines. The site reloads automatically and display your changes.
+
+## That's it!
+
+Congratulations! You've successfully run and modified your Docusaurus project.
diff --git a/docs/tutorial/markdown-features.mdx.dev b/docs/tutorial/markdown-features.mdx.dev
new file mode 100644
index 0000000..622391d
--- /dev/null
+++ b/docs/tutorial/markdown-features.mdx.dev
@@ -0,0 +1,128 @@
+---
+title: Markdown Features
+---
+
+Docusaurus supports the [Markdown](https://daringfireball.net/projects/markdown/syntax) syntax and has some additional features.
+
+## Front Matter
+
+Markdown documents can have associated metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/):
+
+```md
+---
+id: my-doc
+title: My document title
+description: My document description
+sidebar_label: My doc
+---
+
+Markdown content
+```
+
+## Markdown links
+
+Regular Markdown links are supported using url paths or relative file paths.
+
+```md
+Let's see how to [Create a page](/create-a-page).
+```
+
+```md
+Let's see how to [Create a page](./create-a-page.md).
+```
+
+Let's see how to [Create a page](./create-a-page.md).
+
+## Markdown images
+
+Regular Markdown images are supported.
+
+Add an image at `static/img/docusaurus.png` and use this Markdown declaration:
+
+```md
+![Docusaurus logo](/img/docusaurus.png)
+```
+
+![Docusaurus logo](/img/docusaurus.png)
+
+## Code Blocks
+
+Markdown code blocks are supported with Syntax highlighting.
+
+ ```jsx title="src/components/HelloDocusaurus.js"
+ function HelloDocusaurus() {
+ return (
+ <h1>Hello, Docusaurus!</h1>
+ )
+ }
+ ```
+
+```jsx title="src/components/HelloDocusaurus.js"
+function HelloDocusaurus() {
+ return <h1>Hello, Docusaurus!</h1>;
+}
+```
+
+## Admonitions
+
+Docusaurus has a special syntax to create admonitions and callouts:
+
+ :::tip My tip
+
+ Use this awesome feature option
+
+ :::
+
+ :::danger Take care
+
+ This action is dangerous
+
+ :::
+
+:::tip My tip
+
+Use this awesome feature option
+
+:::
+
+:::danger Take care
+
+This action is dangerous
+
+:::
+
+## React components
+
+Thanks to [MDX](https://mdxjs.com/), you can make your doc more interactive and use React components inside Markdown:
+
+```jsx
+export const Highlight = ({children, color}) => (
+ <span
+ style={{
+ backgroundColor: color,
+ borderRadius: '2px',
+ color: 'red',
+ padding: '0.2rem',
+ }}>
+ {children}
+ </span>
+);
+
+<Highlight color="#25c2a0">Docusaurus green</Highlight> and <Highlight color="#1877F2">Facebook blue</Highlight> are my favorite colors.
+```
+
+export const Highlight = ({children, color}) => (
+ <span
+ style={{
+ backgroundColor: color,
+ borderRadius: '2px',
+ color: '#fff',
+ padding: '0.2rem',
+ }}>
+ {children}
+ </span>
+);
+
+<Highlight color="#25c2a0">Docusaurus green</Highlight> and <Highlight color="#1877F2">
+ Facebook blue
+</Highlight> are my favorite colors.
diff --git a/docs/tutorial/thank-you.md b/docs/tutorial/thank-you.md
new file mode 100644
index 0000000..808847e
--- /dev/null
+++ b/docs/tutorial/thank-you.md
@@ -0,0 +1,17 @@
+---
+title: Thank you!
+---
+
+Congratulations on making it this far!
+
+You have learned the **basics of Docusaurus** and made some changes to the **initial template**.
+
+But Docusaurus has **much more to offer**!
+
+## What's next?
+
+- [Read the official documentation](https://v2.docusaurus.io/).
+- [Design and Layout your Docusaurus site](https://v2.docusaurus.io/docs/styling-layout)
+- [Integrate a search bar into your site](https://v2.docusaurus.io/docs/search)
+- [Find inspirations in Docusaurus showcase](https://v2.docusaurus.io/showcase)
+- [Get involved in the Docusaurus Community](https://v2.docusaurus.io/community/support)
diff --git a/docs/worlds-jar/net-worlds/network/netconst.md b/docs/worlds-jar/net-worlds/network/netconst.md
new file mode 100644
index 0000000..4210c5b
--- /dev/null
+++ b/docs/worlds-jar/net-worlds/network/netconst.md
@@ -0,0 +1,189 @@
+---
+title: 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/docs/worlds-jar/net-worlds/network/netpacket.md b/docs/worlds-jar/net-worlds/network/netpacket.md
new file mode 100644
index 0000000..1c134d3
--- /dev/null
+++ b/docs/worlds-jar/net-worlds/network/netpacket.md
@@ -0,0 +1,61 @@
+---
+title: 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`](./serveroutputstream)` 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/docs/worlds-jar/net-worlds/network/objid.md b/docs/worlds-jar/net-worlds/network/objid.md
new file mode 100644
index 0000000..c75bad3
--- /dev/null
+++ b/docs/worlds-jar/net-worlds/network/objid.md
@@ -0,0 +1,68 @@
+---
+title: 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(ServerInputStream 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/docs/worlds-jar/net-worlds/network/serveroutputstream.md b/docs/worlds-jar/net-worlds/network/serveroutputstream.md
new file mode 100644
index 0000000..888e71a
--- /dev/null
+++ b/docs/worlds-jar/net-worlds/network/serveroutputstream.md
@@ -0,0 +1,110 @@
+---
+title: 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)`](#public-final-void-writeint-b-throws-ioexception).
+
+### `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 static int 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/docs/worldserver-protocol/network-constants.md b/docs/worldserver-protocol/network-constants.md
new file mode 100644
index 0000000..365ac47
--- /dev/null
+++ b/docs/worldserver-protocol/network-constants.md
@@ -0,0 +1,5 @@
+---
+title: Network Constants
+---
+
+Refer to [NET.worlds.network.netConst](../worlds-jar/net-worlds/network/netconst)
diff --git a/docs/worldserver-protocol/packet-information.md b/docs/worldserver-protocol/packet-information.md
new file mode 100644
index 0000000..f3a3493
--- /dev/null
+++ b/docs/worldserver-protocol/packet-information.md
@@ -0,0 +1,11 @@
+---
+title: Packet Information
+---
+
+## External Resources
+- https://github.com/Xyem/LibreWorlds/wiki/Packet-structure
+- https://github.com/Xyem/LibreWorlds/wiki/Packet-types
+
+
+## Internal Resources
+A good majority of [NET.worlds.network](../worlds-jar/net-worlds/network/netpacket).
diff --git a/docs/worldserver-protocol/roomserver.md b/docs/worldserver-protocol/roomserver.md
new file mode 100644
index 0000000..89421a9
--- /dev/null
+++ b/docs/worldserver-protocol/roomserver.md
@@ -0,0 +1,23 @@
+---
+title: RoomServer
+---
+
+The following information is directly quoted from the [GammaDocs](http://dev.worlds.net/private/GammaDocs/Dev_Kit_Intro.html).
+
+The RoomServer can operate in stand-alone mode to handle an entire
+world when no user authentication is required. For larger worlds, or when user authentication and
+registration are required, multiple RoomServers can be used in conjunction with a UserServer. If
+shared state (shared objects) is desired, the RoomServer must run in conjunction with an Oracle
+database that will store persistent room data. The RoomServer performs the following tasks:
+
+- Listens on a given port to connections by clients.
+- Establishes and maintains TCP/IP client connections (when used in conjunction with a UserServer,
+ UserServer will establish the first TCP/IP connection with a client and then redirect users to the RoomServers).
+- Subscribes clients to any room the RoomServer is servicing
+- Processes client's avatar locations and properties.
+- Disseminates and provides client locations and properties information to other clients in the
+ vicinity. Performs crowd control calculations that determine how avatars are seen and heard by others.
+- Handles and distributes chat text, whispers and broadcast text. Whispers and other messages
+ targeted at users not on that RoomServer are forwarded to the UserServer for routing.
+- Acts as a database client for a properties database to query or modify Room properties, if any.
+ This includes accessing properties for any shared state or shared objects found in rooms.
diff --git a/docs/worldserver-protocol/userserver.md b/docs/worldserver-protocol/userserver.md
new file mode 100644
index 0000000..2749b08
--- /dev/null
+++ b/docs/worldserver-protocol/userserver.md
@@ -0,0 +1,26 @@
+---
+title: UserServer
+---
+
+The following information is directly quoted from the [GammaDocs](http://dev.worlds.net/private/GammaDocs/Dev_Kit_Intro.html).
+
+The UserServer is used for larger worlds that require more than one RoomServer, or when user
+registration and authentication are required. When user registration and authentication are not
+required, the UserServer is used in anonymous mode, and can handle large worlds with multiple
+RoomServers. When user registration and authentication are needed, the UserServer maintains a user
+database and is configured to provide the necessary user services. The UserServer performs the
+following tasks:
+
+- Listens on a port for connections from RoomServers. On startup, every RoomServer opens a TCP/IP
+ connection to the UserServer.
+- Maintains that TCP/IP connection with the RoomServers as long as the RoomServer is running.
+ UserServer - RoomServer communications fall into one of the following categories: user connection and privileges management, redirection, whisper forwarding, broadcast text, and miscellaneous properties management.
+- Listens on a designated port for new connections from clients.
+- Establishes "transactional" TCP/IP connections with clients for the purposes of logging in,
+ providing redirection to RoomServers, and other user queries. Transactional means that the client connection to the UserServer is maintained only as long as it takes to complete the desired transaction, then the client is either redirected to a RoomServer or dropped after a "grace period" of two minutes.
+- Provides registration and authentication services when registration and authentication are
+ required.
+- Acts as database client to query or maintain a user database when registration and
+ authentication services are required.
+- Acts as database client to query or maintain a World properties database when persistent
+ property changes are made by users or administrators.