Skip to content

A Ragnarok online server implementation written in rust

License

Notifications You must be signed in to change notification settings

DanielHe4rt/rust-ro

 
 

Repository files navigation

build

Welcome to rust-ro!

rust-ro is a Ragnarok MMO Server implementation written in Rust.

While it is a from scratch implemention it is heavily inspired by herculesWS and rathena, for example this implementation support same scripting language for NPC meaning that existing scripts should work on this implementation and use the same database structure than rathena and some naming convention were kept.

Table of Content

1. Ambition

The project started on August 2021 with the ambition to being able to connect on the server and navigate across maps to see monsters.

Today February 2023 a lot of features have been added, see below. My ultimate goal would be to have a fully playable implementation for PRE-RE, supporting packet version 20120307.

I am working on this project for fun and also to provide a more accessible way than existing implementation to understand how Ragnarok game works for educational purpose. Each feature is covered with tests to provide internal documentation.

2. About Packet Version

The packet parser, builder and serializer are all taking packet version as parameter. The packet db also support condition around packet attributes and packet id

Although I mentioned above wanting to fully support packet version 20120307, this implementation can support any packet version, it is just I am testing exclusively with a robrowser client using this packet version and thus i am implementing only packet in this version.

3. Currently Working

Focus is now on Skills

Also see Meta issue

4. Implementation details

To understand what is going on at this project, check the architectures notes.

4.1 Project files structure

  • lib: contains either, proc-macro, reusable structure, generated code
    • lib/packets: Structure for packets generated by tools/packets from tools/packets_db file
    • lib/models: Plain old data structure to be reused in multiple modules
    • lib/configuration: Structure for configuration with serde deserializer implementation
    • lib/skills: Generated structures for skills from configuration and also manually implemented skills methods
  • server: server core
    • server/proxy: A proxy implementation to be use between a client and an emulator (rathena or hercules) in order to capture packets
    • server/repository: data access layer of the server, any access to dabase is written from this layer
    • server/server: global event loop, map instance event loop, persistence event loop
    • server/server/boot: any method require in order to boostrap server state (script loader, maploader, mob spawn...)
    • server/server/model: Plain old non-reusable data structure (queue, cells, etc..)
    • server/server/request_handler: controller layer, any packet receive from client pass to a controller first
    • server/server/script: interface between server and script virtual machine, provides hook implementation of the virtual machine
    • server/server/service: any logic of the game is implemented in this layer
    • server/server/state: Data structure containing game state (character session, character state, mob state)
    • server/util: Any utility methods
  • tools: code generator
    • tools/map-cache: generate map cache from map files
    • tools/packets: generate packets structure from database file
    • tools/skills: generate skills structure from configuration file
    • tools/stat-calc: A javascript/html stat calculator, cleaned up to better understand stats and combat calculation. Also added feature to generate test fixtures, to validate our implementation

5. Setup

Here's a list of pre-requisites to run rust-ro:

  • Docker OR PostgreSQL 12+ directly on your machine
  • Rust - nighly build

5.1 Config

First, make a copy from config.template.json to config.json:

cd rust-ro
cp config.template.json config.json

Inside this JSON, you will find database related variables and game related variables (exp_rate, drop_rate etc) as well. You can change in the way you want, but for now let's leave it with default values.

// config.json
[
  "game": {
    "default_char_speed": 150,
    "drop_rate": 1.0,
    "drop_rate_card": 1.0,
    "drop_rate_mvp": 1.0,
    "max_base_level": 99,
    "max_inventory": 100,
    "mob_density": 1.0,
    "max_stat_level": 99,
    "base_exp_rate": 1.0,
    "job_exp_rate": 1.0,
    "mob_dropped_item_locked_to_owner_duration_in_secs": 30,
    "player_dropped_item_locked_to_owner_duration_in_secs": 60
  }
]

TODO: make a small info for each variable, maybe a wiki?

5.2 Setup DB

The entire database structure was based on rAthena but instead of using MySQL, we decided to go with PostgreSQL. There's minor modifications so far but until we mapped some constraints.

Since there's features like ON CONFLICT (column) .. DO UPDATE, UNNEST(array) that is not provided by MySQL, PostgreSQL took place to leverage the project in the database aspect.

5.2.1 Setup DB: Docker

If you already have Docker installed in your machine, we prepared a docker-compose.yml with all configs ready for your ragnarok server.

Go to /docker and run:

docker-compose up -d

The first time, along with postgresql initdb is run, our custom script init.sh will be execute, it will create ragnarok database and create ragnarok user using postgres user. Then it will create ragnarok table using ragnarok user.

It comes with a default player account with following credentials: admin/qwertz

5.2.2 Setup DB: Locally

If you have PostgreSQL installed in your machine, you will need to log-in into PSQL and create the user, dabase and give the necessary privilege for it:

sudo -u postgres psql

Run the queries below:

CREATE USER ragnarok WITH PASSWORD 'ragnarok';
CREATE DATABASE ragnarok;
GRANT ALL PRIVILEGES ON DATABASE ragnarok TO ragnarok;
ALTER DATABASE ragnarok OWNER TO ragnarok;

After that, exit pgsql and import our /rust-ro/db/pg.sql via cli with:

 sudo -u postgres psql -U ragnarok ragnarok < db/pg.sql

If you're using the local version, don't forget to change the database.port number to 5433 in your config.json file.

5.3 Building the Binaries

So far, we have a few executables being compiled together with the project:

  • maps: TODO description
  • maps-tool: TODO description
  • packets: TODO description
  • packets-tool: TODO description
  • server: TODO description
  • skills-enum-generator: TODO description

To build, just go on the project root and run:

cargo build

Simple like that! Now you're good to run your servers.

5.4 Running the Server

After we have everyting set-up (binaries and database), we should run server binary to turn on rust-ro.

To run the server binary, you will need a ENV variable called DATABASE_PASSWORD together with your command:

DATABASE_PASSWORD=ragnarok cargo run --bin=server

If everything goes right, you should receive something like this output:

INFO [server] load 39 scripts in 0.126 secs
INFO [server::server::boot::warps_loader] load 2781 warps in 0.007 secs
INFO [server::server::boot::mob_spawn_loader] load 3391 mob spawns in 0.022 secs
INFO [server] load 897 map-cache in 0.05 secs
INFO [server::proxy] Start proxy for Char proxy, 6123:6121
INFO [server::proxy] Start proxy for map proxy, 6124:5121
INFO [server::server] Server listen on 0.0.0.0:6901

5.5 Running the Game

Desktop Screenshot with Development Environment using RoBrowserLegacy

The goal of the project is to run all packages from packetver 20120307, we decided to use roBrowserLegacy.

If you have interest to contribute in a client with packetver 20120307, open a new issue and let's make it happen!

6. Developer Notes

  • All packets for account 2000000 are handle by this project.
  • All packets for any other account are proxied (and display in console) to hercules or rathena.
  • clientinfo.xml to be changed to target port 6901

In proxy mode:

  • login, char, map server to be running using default ports (6900, 6121, 6122)

7. Progress Showcase (Compilation)

A compilation of progress made so far, click on streamable video below

Compilation of features so far

Compilation of features so far

7.1 Integration of the VM (showing instance and class(npc) variable)

script.mp4

7.2 Visual debugger

visual-debugger Debug server state with a UI

7.3 Warps

warps warps

7.4 Mobs

mobs

7.5 Proxied packets

packets

8. What has been done? ✔️

Some list of features that was developed so far:

8.1 Tools

  • packet structure generator from packet db
  • packet parser generator
  • map cache generator

8.2 Server

  • proxy login, char and map request to hercules/rathena login, char and map servers
  • packet debug
  • login
  • char server features(create char, delete char, join game)
  • move character in a loaded map, synchronized with client side movement (no lag, or teleportation, movement is smooth)
  • character position calculation (implementation of client side path finding)
  • debug log in in-game chat
  • parse scripts (only warps and mobs at the moment)
  • warp (change map, reset states)
  • display scripts client side (only warps and mobs at the moment)
  • visual debugger
  • map instances (map are lazily loaded, an instance is created when a player join an non initialized map)
  • mob spawn
  • atcommand: @go, @warp
  • mob move
  • NPC scripts (partially: see nmeylan#3) via rathena script lang interpreter
  • basis for inventory management
  • basis for skills
  • basis for consumable item usage
  • basis for player attacking mob
  • mob drops item on death

9. Contribution

This project is currently half-open* to contribution. The reason is that all basis have not been put in place already and there are many thing to design yet.

However if you are motivated and want to contribute you can take a look to the contribution guide

* contribution can be made under certain condition

About

A Ragnarok online server implementation written in rust

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 70.7%
  • PLpgSQL 24.5%
  • JavaScript 4.2%
  • Other 0.6%