# \[Web] OTClient Redemption

## About the project:

OTClient Redemption adapted to run on web browsers (WebGL2), used to connect to OT Servers with websockets support (via proxy or native). Adapted by [OTArchive](https://otarchive.com/) / [OTServList Brasil](https://otservlist.com.br/).

## Servers already using the client:

First server to deploy: arm.skalski.pro - ThaisWar with bots 8.6 OTS (by Gesior.pl!)

Create account: <https://arm.skalski.pro/?subtopic=createaccount>

Client: <https://webclient.otarchive.com/?gameData=https://downloads-oracle.ots.me/data/MehahWeb860/otclient-otarchive_2024_10_16.zip&version=4eed1a1>

## Testing the demo:

To check if the base client opens in your browser, [go to the demo](https://demo.otarchive.com/). This version does not contain assets, so it is not suitable for connecting to servers.\
[Source of the demo](https://github.com/OTArchive/otclient-web-demo).

## Testing the modular version:

Ideally you will compile your own version with the necessary files preloaded as in the demo, including your assets. That said, you can quickly test the full OTClient Web using the modular version of OTArchive. With this version you can use your own assets and connect to a server.

### Prerequisites:

You will need a .zip file containing the **init.lua**, the **data**, **modules** and other folders that you will use. Use [OTClient Redemption](https://github.com/mehah/otclient) compatible files.

Change `g_game.loginWorld` in `modules/client_entergame/characterlist.lua` to point to the IP and port of the game world of the server you want to connect to, example:

```
g_game.loginWorld(G.account, G.password, charInfo.worldName, 'testserver.otarchive.com', 443,
                      charInfo.characterName, G.authenticatorToken, G.sessionKey)
```

**The default port of the game world is 7172, if it doesn't change, it will be automatically redirected to 443.**

There are two options:

* .zip local
* Remote .zip

For a quick test, use the zip stored on your computer to install the files and launch the client.

If you want to perform shared tests with more people, you can choose to make the .zip file available for download on your server, **through a direct link**. To use this option, it will be **necessary** for the server to use **HTTPS** and deliver the file with the Header **Access-Control-Allow-Origin:** [**https://webclient.otarchive.com**](https://webclient.otarchive.com/), so that OTArchive can download and install automatically. If your web server supports .htaccess files, you can create one with the following content:

```
Header set Access-Control-Allow-Origin "https://webclient.otarchive.com"
AddType application/zip .zip
```

Place the .htaccess file in the same folder as the .zip file.

### Installation:

1. Access [OTClient Web Modular](https://webclient.otarchive.com/)
2. Install the files using the desired method

   * **.zip location:** Click "Open" and select the file .zip on your computer.
   * **Remote .zip:** Add the **gameData** parameter pointing to the download link of the .zip file in the URL and go to. Example:

   ```
   https://webclient.otarchive.com/?gameData=https://dominio/pasta/otclient.zip
   ```

### Connection:

With the files installed, the "Play" option will appear. If your files are ok, the client will open and be ready for use.\
The modular version uses port 443 for connection (instead of 7172). In order for the client to connect, the login and game server must use SSL/TLS.<br>

A video showing the demo and then the modular version connecting: <https://www.youtube.com/watch?v=sGuYmr728eY>

## Compiling:

Compile your own version with your preloaded files for faster download and start!

**Warning: Development and testing carried out in a Windows environment. Adaptations to commands may be necessary.**

#### Steps:

1. Install [Emscripten (emsdk)](https://emscripten.org/docs/getting_started/downloads.html)
   * Use version `3.1.73`, which can be installed with `./emsdk install 3.1.7`
2. Install [vcpkg](https://github.com/microsoft/vcpkg)
   * Cloning the repository and running bootstrap-vcpkg is sufficient.
3. Install [CMake](https://cmake.org/download/)
4. Install [Ninja](https://ninja-build.org/)
   * Create the **NINJA** environment variable by pointing to the folder containing the ninja.exe
   * ![](https://1381914140-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzV9t92sKcMkphxwdvwZs%2Fuploads%2FELioMQdppQ8cktsd48Zw%2Fotclient_web_ninja_env.png?alt=media\&token=fafdf174-b883-4e22-b43c-3b20e26e0cb3)&#x20;
   * Include the variable in Path
   * ![](https://1381914140-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzV9t92sKcMkphxwdvwZs%2Fuploads%2Fm2HO3TZGDyLvFH3zbCpI%2Fotclient_web_ninja_env_path1.png?alt=media\&token=0d67e35c-296f-4ac4-b1fd-5c8e4be5e446)
   * ![](https://1381914140-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzV9t92sKcMkphxwdvwZs%2Fuploads%2FwtcSCEwMeImsdHwEr8G5%2Fotclient_web_ninja_env_path2.png?alt=media\&token=99b77656-04e5-4e3f-9a4e-053aff320004)
5. Clear the vcpkg builds that are cached, if you have used vcpkg before. This may be necessary to ensure that pthread patches apply correctly. So, if you have used vcpkg before, delete the folder `C:\Users\Usuario\AppData\Local\vcpkg`
6. Compile the **debug** version client

   * With the debug version, you will be able to test locally by accessing via `localhost` without SSL/TLS. Localhost is the only way to test without needing a certificate, as browsers require it.
   * Navigate to the OTClient folder
   * To compile, we need to combine vcpkg and emscripten settings, so modify the command to the correct paths on your PC:

   ```
   cmake -G Ninja -S . -B build "-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=C:\emsdk\upstream\emscripten\cmake\Modules\Platform\Emscripten.cmake" "-DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake" "-DVCPKG_TARGET_TRIPLET=wasm32-emscripten" "-DVCPKG_OVERLAY_PORTS=C:\otclient\browser\overlay-ports" "-DCMAKE_MAKE_PROGRAM=NINJA" "-DOPTIONS_ENABLE_IPO=OFF" "-DTOGGLE_BIN_FOLDER=ON" "-DCMAKE_BUILD_TYPE=Debug"
   ```

   * Then start the build:

   ```
   cmake --build build
   ```

   * The files will be available in , for testing run`build/bin`

   ```
   emrun build/bin/otclient.html
   ```
7. Build the **client release**
   * Change `"-DCMAKE_BUILD_TYPE=Debug"` to `"-DCMAKE_BUILD_TYPE=Release"` in the above command.
   * This version will only be able to communicate with servers via HTTPS and WSS.

## Testing locally:

With the debug version, you can test locally by connecting via localhost. In my tests I used MariaDB, [Canary](https://github.com/opentibiabr/canary) and [login-server with modification to send CORS headers](https://github.com/OTArchive/login-server-cors) (necessary).

> To send a request and get a response from a domain other than the originating one, you need to use CORS headers. For example, login-server-cors appends, among others, the header to allow requests from any source.`access-control-allow-origin: *`

The second thing you need is websockets support. Luckily, there are programs that automatically proxy websockets to posix sockets, like [Websockify](https://github.com/novnc/websockify).

By default, the port that the client will use to connect to the game will be `443`, if you do not change it in `characterlist.lua` as mentioned previously.

Change it to e.g. 7979 to test locally:

```
g_game.loginWorld(G.account, G.password, charInfo.worldName, localhost, 7979,
                      charInfo.characterName, G.authenticatorToken, G.sessionKey)
```

We can then configure Websockify to proxy websocket requests from port 7979 to 7172:

```
websockify -v localhost:7979 localhost:7172
```

Use the `emrun` command to test as mentioned in the build guide.

If you want to test your own web server to deliver `otclient.html` and other files, you will need to define some headers that `emrun` already does automatically:

```
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
```

These headers are required for the browser to allow access to `SharedArrayBuffers`, something the client needs to work with pthreads. If your server supports .htaccess, you can use the following configuration:

```
Header set Cross-Origin-Embedder-Policy "require-corp"
Header set Cross-Origin-Opener-Policy "same-origin"
Header set Cross-Origin-Resource-Policy "cross-origin"

AddType application/wasm .wasm
AddType application/octet-stream .data
AddType application/javascript .js
```

## Deploying the Release version:

When you make your client available on the web, it will need to open via HTTPS and use the headers mentioned above. Depending on your configuration, you will also need to serve the `.wasm` and `.data` files with the correct `Content-Type` header.

```
application/wasm para .wasm
application/octet-stream para .data
```

Remembering that connections will now only work through HTTPS and WSS, so your server needs to be supported.

### Websocket server example:

MariaDB + Canary + AAC + nginx + websockify + cloudflare **This option is not recommended for medium/large servers and should only be used for testing.**

> Cloudflare allows WSS connections, but can limit it depending on usage. (Free)

By using nginx to proxy and Cloudflare with Flexible SSL, we can easily set up secure connections for our endpoints.

Example nginx configuration to receive wss connections on port 443 and send to 7979 (which websockify will be listening to):

```
server {
        listen 80;
        listen [::]:80;
        server_name server.exemplo.com;
        location / {
          # redirect all HTTP traffic to localhost:7979
          proxy_pass http://localhost:7979;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          # WebSocket support
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
  }
}
```

If you are going to use this configuration, configure your client to use port 443 (example above, in the modular client section, characterlist.lua file).

Nginx configuration example for your AAC running on port 3000:

```
server {
        listen 80;
        listen [::]:80;
        server_name testaac.otarchive.com;
        location / {
          proxy_pass http://localhost:3000;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          if ($request_method = OPTIONS ) {
            add_header 'Access-Control-Allow-Origin'  '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, HEAD';
            add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept';
            return 200;
          }

          #if ($request_method ~* '(GET|POST)') {
            #add_header 'Access-Control-Allow-Origin' '*';
          #}
  }
}
```

You can also choose to configure headers using Cloudflare Transformation Rules.

### Alternatives:

You can use Let's Encrypt certificates and configure them on your web server and in Websockify so that they receive the connections directly.

## Customization:

Modify the `browser/shell.html` file to customize the html page that will be generated. Use mods and lua modules as usual.

## Web Category at OTServList Brazil:

Have you made a web client available to your players? Send an email to <contato@otservlist.com.br> and we'll add your server to the category with a "Play Now" button.

## Credits:

* OT Archive.
